ivy icon indicating copy to clipboard operation
ivy copied to clipboard

ivy: binding precedence of "1 (f 2)[1]" vs "1 x[1]"

Open rsc opened this issue 2 months ago • 8 comments

I wrote 1 (f 2)[1] earlier and was surprised that the [1] applies to 1 (f 2) not just to (f 2). This is however consistent with TryAPL, so I suppose it is correct. But if you replace (f 2) with just 'x' then Ivy becomes inconsistent: 1 x[1] applies the [1] only to x, not to 1 x.

% ivy -prompt '# '
# x = 3 4

# 1 x[1]
1 3

# op f x = 3 4

# 1 (f 2)[1]
1

# 

TryAPL:

      f ← {3 4}
      f 2
3 4
      x ← 3 4
      x
3 4
      1 x[1]
1
      1 (f 2)[1]
1

rsc avatar Nov 07 '25 15:11 rsc

Yes, the grammar predates some of the fancy indexing analysis. Parser.number binds the indexing too tightly. That's where the issue happens, and it's easy to just delete the call to index there, but that triggers other problems (try it). The fix will be more complex.

Also consider this behavior from dyalog:

        x←1 2
        y←3 4
        x[1]
   1
        y[1]
   3
        x[1] y[1]
   1

That's what they want, and it's consistent, but ouch. Ivy is definitely inconsistent, in any case.

robpike avatar Nov 07 '25 22:11 robpike

I sent #241 to make (f x)[1] like x[1] but leave 1 2 3 4[2] alone. It only broke one test case, although I'm still not sure it's right.

I tried putting the index call in all the expr cases, but of course that broke

1 3 2 4[up 1 3 2 4]

Maybe it would be okay to have to write

(1 3 2 4)[up 1 2 3 4]

instead?

rsc avatar Nov 10 '25 22:11 rsc

Also sent #242 to apply the tighter [x] precedence uniformly as an alternative. To me it seems okay to restore consistency by losing 1 3 2 4[up 1 3 2 4]. Either PR needs test cases before being landed. They're just posted for discussion for now.

rsc avatar Nov 11 '25 00:11 rsc

This is the current behavior

1 2 3[3] 3

x=4 5 6

1 2 x[3] 1 2 6

The inconsistency is galling and likely the reason APL goes the other way.

  1 2 3[3]

3 x←4 5 6 1 2 x[3] 4 5 6

I believe ivy should work the way APL does.

robpike avatar Nov 16 '25 21:11 robpike

I believe ivy should work the way APL does.

I agree.

APL is deliberately simple: Parentheses bind first. Stranding (juxtaposition) binds next. Everything else is evaluated right-to-left, i.e. there is no precedence among functions. This includes indexing; it is in the same precedence category as +, ×, ⍳, ⊂, etc.

fzipp avatar Nov 16 '25 22:11 fzipp

Interesting. It looks like ca8e403cb1 is the culprit here and is relatively new (2023).

rsc avatar Nov 18 '25 00:11 rsc

Good catch.

I pushed out 76424f8d33db18669997e662a568ffcb50f5e3af

I won't tag it just now, and give people a chance to look at the consequences. I think it's good, if a little surprising, and now does seem to agree with Dyalog.

robpike avatar Nov 18 '25 05:11 robpike

Sounds good to me. Happy to close this.

rsc avatar Nov 23 '25 14:11 rsc