Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploding an expression: interpretation of the ‘@’ modifier #1626

Open
hanche opened this issue Nov 26, 2022 · 6 comments
Open

Exploding an expression: interpretation of the ‘@’ modifier #1626

hanche opened this issue Nov 26, 2022 · 6 comments

Comments

@hanche
Copy link
Contributor

hanche commented Nov 26, 2022

To set the stage, for a variable v, the meaning of $@v and set @v = value … is clear:

⬥ var @v = a b c
⬥ put $@v
⮕ a
⮕ b
⮕ c

Note that $@v returns what we gave to set @v.

But involve some array references, and things are not as clear:

⬥ var @v = [a b c] [d e f] [g h i]
⬥ set @v[1] = x y z
⬥ put $v     # produces expected result:
⮕ [[a b c] [x y z] [g h i]]
⬥ put $@v[1] # surprise (to me at least):
⮕ b
⮕ y
⮕ h

This breaks two reasonable expectations, IMO:

  • Expanding $⟨something⟩ should reflect the RHS of a previous set ⟨something⟩ = …
  • The construct $@⟨something⟩ acts like syntactic sugar for (all $⟨something⟩)

Of course, this depends on what you see as the ⟨something⟩ in a compound expression. What is most jarring is the lack of symmetry between the assignment and the expansion.

So this is my suggestion:

Change the meaning of $@variable[⟨index-expression⟩]… to evaluate the whole expression without the @, then explode the result(s).

Of course this is breaking change, so it needs to considered carefully. But I doubt there is much code out there that relies on the current behaviour.

  • After such a change, replacing any $@variable[⟨index-expression⟩]… by {$@variable}[⟨index-expression⟩]… will result in the old behaviour. This should be fairly easy to automate. Also, since the result of such an expression is a bit tricky to figure out, I think the extra curly braces will help to make clear that something funny is going on.
@xiaq
Copy link
Member

xiaq commented Nov 26, 2022

This breaks two reasonable expectations, IMO:

  • Expanding $⟨something⟩ should reflect the RHS of a previous set ⟨something⟩ = …

This is a great point.

  • The construct $@⟨something⟩ acts like syntactic sugar for (all $⟨something⟩)

As you said this is debatable.

Change the meaning of $@variable[⟨index-expression⟩]… to evaluate the whole expression without the @, then explode the result(s).

This will need to be handled as a special case and not as a result of precedence rules so I am not quite inclined to do that.

(Edit: not quite inclined)


My takeaway from this is that the entire $@x construct is really only good for one-dimensional lists, and becomes unintuitive when you go higher dimension. Rather than creating special cases for higher dimension cases, I'm more inclined to just treat them as syntax errors (so both $@x[1] and set @x[1] will be syntax errors).

I am also considering just removing the $@x syntax entirely in favor of the the POSIX syntax $x[@], which is actually superior since there is no confusion around what $x[1][@] means. What makes me hesitate a bit is that seeing x[@] on the left side of var or in function signature feels kind of wrong:

# This looks fine: $x is already a list and this is setting its content
set x[@] = a b c
 # This can work but feels wrong; $x doesn't exist yet, why is it getting indexed?
var x[@] = a b c
# One might expect this to work out of analogy, but what should it do?
var x[1] = a

# This also feels wrong...
fn {|a b rest[@]| ... }

@hanche
Copy link
Contributor Author

hanche commented Nov 26, 2022

Hmm. I also feel a bit uncomfortable with $x[@], also because @ is a perfectly fine key for a map. Sure, lists and maps are different things, but indexing them looks the same, and it feels disturbing not to know for sure what $x[@] means.

If we're investigating alternate syntaxes, I was wondering if just using $x[] might work as well? That is a syntax error currently, so it wouldn't clash with present usage. Also, it would make your two “wrong feeling” examples feel less wrong:

var x[] = a b c
fn {|a b rest[]| … }

The main argument against, perhaps, is that $x[ ] (with the space) currently has a meaning: Curiously, it expands to nothing at all, no matter what kind of value $x is. (Is that intentional, BTW?) But OTOH, spaces or the lack thereof is already significant in many places, so perhaps that is not such an important objection.

Whatever the syntax, one advantage is that this could be applied to several levels at the same time: $x[@][2][@] with or without the @.

@hanche
Copy link
Contributor Author

hanche commented Nov 26, 2022

Change the meaning of $@variable[⟨index-expression⟩]… to evaluate the whole expression without the @, then explode the result(s).

This will need to be handled as a special case and not as a result of precedence rules so I am not quite inclined to do that.

Aye, there's the rub. That is so because the @ is prefixed rather than appended, doesn't it? It took me a bit too long to figure that out.

xiaq added a commit that referenced this issue Nov 26, 2022
$x[ ] is already allowed. Neither is useful, but allowed for consistency.

This came up in a comment from @hanche in #1626.
@xiaq
Copy link
Member

xiaq commented Nov 26, 2022

Hmm. I also feel a bit uncomfortable with $x[@], also because @ is a perfectly fine key for a map. Sure, lists and maps are different things, but indexing them looks the same, and it feels disturbing not to know for sure what $x[@] means.

Lists already support slices too, which are also valid map keys.

The main argument against, perhaps, is that $x[ ] (with the space) currently has a meaning: Curiously, it expands to nothing at all, no matter what kind of value $x is. (Is that intentional, BTW?) But OTOH, spaces or the lack thereof is already significant in many places, so perhaps that is not such an important objection.

It means indexing $x with zero values, like how $x[a b] is the same as $x[a] $x[b]. $x[] is not useful but it shouldn't be a syntax error; that is now fixed.

Aye, there's the rub. That is so because the @ is prefixed rather than appended, doesn't it? It took me a bit too long to figure that out.

Not just that; @ is not an operator, it is part of the variable use syntax. To make $@x[y] have the semantics that you described, it is not sufficient to change the precedence. The change will be "if the indexee of an indexing expression is a variable use with @, suppress explosion of the variable and explode the value of the whole indexing expression instead".

@hanche
Copy link
Contributor Author

hanche commented Nov 28, 2022

Now that I had time to let it sink in a bit, I think I could at least get used to the $x[@] syntax. Don't know yet if I like it better than the old syntax, but it does help with the problem that got me to raise this issue.

Perhaps, though, it might even be desirable to support both syntaxes? They don't clash with each other, but it does violate a language purist's principles to have two ways to say the same thing.

In any case, I think that using explosion and indexing both on the LHS of an assignment should be made illegal, as the meaning of @x[1] changes in such a radical fashion if you put a dollar sign in front of it.

@dunsany
Copy link
Contributor

dunsany commented Dec 11, 2022

I am also considering just removing the $@x syntax entirely in favor of the the POSIX syntax $x[@], which is actually superior since there is no confusion around what $x[1][@] means. What makes me hesitate a bit is that seeing x[@] on the left side of var or in function signature feels kind of wrong:

What if setting and getting had different syntaxes? Would that feel too weird?

var @x = a b c
var @x_copy = $x[@]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants