A puzzling result with a simple calculation

On the topic of juxtaposition but with strings, the following are all known behaviors

“Hello” * ” world” # -> “Hello world”

h = “Hello”
h” world” # -> UndefVarError: `@h_str` not defined 

w = “ world”
“Hello”w # -> ParseError:
#       └ ── cannot juxtapose string literal

However, this one is puzzling

h[1:end]w # -> “Hello world”

I’d expect that to throw a parser error as well but instead the * is correctly inferred

@show h[1:end]w # -> h[1:end] * w = "hello world"

"foo"b being an error is good because it would be confusing if it meant multiplication when a"foo"b is a nonstandard string literal with b as an extra argument.

Totally agree, but also the last one should be an error (or not?)

I don’t see what the confusion would be?

It’s nice to have very uniform syntax where strings and arrays behave similarly but we don’t always get that.

That appears to be a general parsing behavior. (The parser doesn’t know that h is a string.)

julia> :(A()w)
:(A() * w)

julia> :([1]w)
:([1] * w)
3 Likes

I know that (it’s in the OP, too). I just meant it’s not unavoidable that accepting 2x means one has to accept 2(2+1).

1 Like

I’m a physicist, and this is entirely expected behavior for me. If I mean 6/2*(2+1) I will write it like that.

same feeling here, I think if people accept 2x in Julia is (2 \times x), it is intuitive that 6/2(2+1) = 6 \div 2(2+1) and 6/2*(2+1) = 6 \div 2\times (2+1)

But it wouldn’t be inconsistent (but of course breaking) to disallow 2(2+1), since it can be interpreted as function call syntax. I find 2x to be very nice syntax, but dislike 2(2+1).

The reason I make this point is that it was argued that one cannot have the former without the latter.

3 Likes

I think that if you want to use Julia that if you write

  1. 2x
  2. 2(3)
  3. 2(3.1415926+4)

You have to think of the whole thing as a single indivisible number.

Then you can write 1/2pi meaning 1/(2*pi)

Yes, that is the current situation. But I was saying that it is possible to like 2x without liking 2(2+1). The language didn’t have to have both. It does have both, but it didn’t have to.

Wolfram language uses square brackets for function calls, apparently to distinguish from the implicit multiplication syntax. Julia chooses not to use a function call syntax that’s alien to programmers from other languages, though this pragmatic compromise makes the syntax a little bit more ambiguous. Personally, I prefer to explicitly type out * operators when using either language.

Julia already uses square brackets for another purpose, though, namely getindex, so this would anyway not solve anything:

julia> 2[1]
2

julia> 2[2]
ERROR: BoundsError: attempt to access Int64 at index [2]

It would make sense to me if 2[x] is getindex, 2x is multiplication, and 2(x) were function call syntax.

That’s exactly why Wolfram Language uses double square brackets for array indexing: a(2) means a*2, a[2] means calling function a with argument 2, and a[[2]] means the 2nd element of the array a. Fully avoiding syntax ambiguities related to implicit multiplication has caused a chain reaction which produces a LOT of strange syntax in Wolfram.

That’s odd, and certainly not unambiguous. This looks like it should mean ‘calling function a with input argument [2]

But do you see ambiguities in this:

?

Yeah, a[[2]] would have been ambiguous in Wolfram Lang if [2] means a vector of one element 2, but Wolfram actually uses curly brackets instead for vectors, making its syntax even more unfamiliar to most people. By allowing syntax like 2(x+y) in a fully unambiguous way, it’s surprising how much the rest of the syntax choices become constrained in Wolfram Lang.

This looks consistent to me, if you are willing to forgo the convenience of things like 2(x+y). I don’t mind typing 2*(x+y), and in fact, 2*x either.

2 Likes

You would actually need (2*x) to use it under the /, which the main reason I prefer 2x.

1 Like