betaveros / noulith

*slaps roof of [programming language]* this bad boy can fit so much [syntax sugar] into it
1.13k stars 20 forks source link

Another precedence question #10

Closed max-sixty closed 1 year ago

max-sixty commented 1 year ago

(not expecting support, feel free to skip — adding some issues as I come across them)


Generally I would expect:

X = foo bar;
print baz (X);

to be equivalent to

print (baz (foo bar));

...i.e. extracting something into a variable doesn't change the semantics[^1].

But here it doesn't seem to be. This works:

X := {"foo"}.keys;
print pop X;

But this doesn't:

print (pop ({"foo"}.keys));
PARSE ERROR: can't to_lvalue
print (pop ({"foo"}.keys));

    (expr 22:13-22:20)
    at first expr in call arg list (22:8)
    at first expr in assign LHS (22:1)

Is my mental model wrong for what's going on? I didn't completely understand the error message either.

Thank you!

[^1]: I realize that languages like rust occasionally don't honor this, since the assignment can avoid temporary values, but I'm guessing that's not the issue here...

betaveros commented 1 year ago

I think your first examples work when baz is a function, but pop is a special keyword that expects an lvalue and mutates it, not a function (and it can't be implemented as one due to the immutability semantics). So it's no more surprising than the fact that this works

X := {"foo"}.keys;
X = [];

but this doesn't:

{"foo"}.keys = [];

When you don't need the mutation, last should work just as well.

max-sixty commented 1 year ago

Great, that makes sense

When you don't need the mutation, last should work just as well.

Yes, I was trying to extract an item from a single-item dict, so those funcs don't work. In the end I found day 3 in AoC uses [c] = foo to extract it, so went with that.

Maybe only could work on those?