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

Splat operator doesn't work outside parameter list. #1573

Closed
tioteath opened this issue Sep 23, 2015 · 7 comments
Closed

Splat operator doesn't work outside parameter list. #1573

tioteath opened this issue Sep 23, 2015 · 7 comments

Comments

@tioteath
Copy link

Ruby:

b = *7
=> [7]

Crystal:

b = *6
Syntax error in ./run.cs:1: unexpected token: *

b = *6

I believe, splat operator must behave exactly like in Ruby (outside parameters), or absent at all, as no need to do the same stuff using different syntax constructions.

@tioteath tioteath changed the title Splat operator doesn't work outsid parameter list. Splat operator doesn't work outside parameter list. Sep 23, 2015
@refi64
Copy link
Contributor

refi64 commented Sep 23, 2015

...so all it does is construct a one-element list?

@jhass
Copy link
Member

jhass commented Sep 24, 2015

In Crystal splat operates on tuples, not arrays and it's strictly limited to the call and argument list syntax.

This one may be fixable, though it's already quite debatable whether it should create an array or a tuple. However the above gives a quite clear scope to the splat operator in Crystal and there are many places where it's valid in Ruby that Crystal simply can't support (see #1464 for example). So that would just make its definition less clear.

@tioteath
Copy link
Author

@kirbyfan64, Actually it can do a lot more http://www.monkeyandcrow.com/blog/the_strange_ruby_splat/
@jhass, Personally, I don't like spat operator at all. It would be better to replace its functionality with a method call, for example, but since Crystal already has it, it would be nice that it behave the same fashion like in Ruby.

@jhass
Copy link
Member

jhass commented Sep 24, 2015

But it's not possible.

@asterite
Copy link
Member

I'm closing this as a kind of duplicate of #132. Basically, allow the splat operator to be used in more ways and more places.

@HertzDevil
Copy link
Contributor

HertzDevil commented Feb 14, 2021

We shouldn't close this because #132 deals exclusively with splat collections on the LHS and this one is about splat expansions on the RHS.

In Ruby, these:

... = *exp1
... = exp1, exp2
... = *exp1, exp2
... = exp1, *exp2

behave identically to:

... = [*exp1]
... = [exp1, exp2]
... = [*exp1, exp2]
... = [exp1, *exp2]

We could do a similar syntactic transformation whenever the RHS consists of anything but a single non-splat expression:

... = ::Tuple.new(*exp1)
... = ::Tuple.new(exp1, exp2)
... = ::Tuple.new(*exp1, exp2)
... = ::Tuple.new(exp1, *exp2)

With #3718, we can also express this in terms of the tuple literal:

... = {*exp1}
... = {exp1, exp2}
... = {*exp1, exp2}
... = {exp1, *exp2}

Note that if we transform the RHS like this then many-to-many assignments must be interpreted differently:

# in the same way we allow:
x, y = {1, 2, 3}
{1, 2, 3}.try { |x, y| }

# we should also permit:
x, y = 1, 2, 3

# it will expand to:
__temp = ::Tuple.new(1, 2, 3) # or tuple literal
x = __temp[0]
y = __temp[1]
__temp

# the following still errors, but the message won't be "Multiple assignment count mismatch":
x, y, z = 1, 2 # Error: index out of bounds for Tuple(Int32, Int32) (2 not in -2..1)

The trailing __temp illustrates one additional benefit to this: we can now define the return value of a multi-assign expression properly, since we need this tuple here anyway.

We still won't allow splat expansions of non-Tuple types (in the same way we can't do that for method calls, including #1464), so b = *7 is a compile error.

@asterite
Copy link
Member

It's true that it's different from the other issue. But this feature is just being able to omit curly braces for tuples. I don't think that's very useful. I prefer to keep the language smaller. I'm pretty sure, if you ask most rubyists, what the splat operator does in these cases, they will not know and they will be confused. In fact the splat operator alone might already be confusing for a lot of programmers.

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

5 participants