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

lambda { |a,| a } seems to parse incorrectly a unnamed rest arg #3214

Closed
eregon opened this issue Aug 3, 2015 · 7 comments
Closed

lambda { |a,| a } seems to parse incorrectly a unnamed rest arg #3214

eregon opened this issue Aug 3, 2015 · 7 comments
Assignees

Comments

@eregon
Copy link
Member

eregon commented Aug 3, 2015

bin/jruby -S bin/ast -e 'lambda { |a,| a }'
AST:
RootNode 0
  NewlineNode 0
    FCallNode:lambda 0, null
      IterNode 0
        ArgsNode 0
          ListNode 0
            ArgumentNode:a 0
          ListNode 0
          UnnamedRestArgNode:null 0
          ListNode 0
          ListNode 0
        NewlineNode 0
          DVarNode:a 0

And

p lambda { |a,| a }.arity
#1 on MRI
# -2 on JRuby

I think |a,| is just the same as |a|, is there any difference?

This could also be the cause more or less indirectly for the new truffle failures:
https://travis-ci.org/jruby/jruby/jobs/73873458

@chrisseaton
Copy link
Contributor

I don't think it is the same - I remember doing some work on this but that's all I remember.

@eregon
Copy link
Member Author

eregon commented Aug 3, 2015

@chrisseaton It is different at least in the case of

a, = 1, 2
a # => 1

# But
lambda { |a,| a }.call([1,2]) # => [1,2]

@headius
Copy link
Member

headius commented Aug 6, 2015

I swear this used to be equivalent to |a,*| but that does not appear to be the case back as far as 1.8.7:

1.8.7-head :002 > lambda {|a,|}.arity
 => 1 
1.8.7-head :003 > lambda {|a,*|}.arity
 => -2 

However it does appear to be equivalent in the case of multiple assignment, which may be where @enebo and I are confused (since masgn used to be used for block args too):

1.8.7-head :007 > a, = [1,2,3]; a
 => 1 
1.8.7-head :008 > a,* = [1,2,3]; a
 => 1

We do parse them the same in the lambda case, as a UnnamedRestNode.

In the masgn case, they parse differently:

[] ~/projects/jruby $ ast -e 'a,* = []'
AST:
RootNode 0
  NewlineNode 0
    MultipleAsgnNode 0
      ArrayNode 0
        LocalAsgnNode:a 0
      StarNode 0
      ZArrayNode 0


[] ~/projects/jruby $ ast -e 'a, = []'
AST:
RootNode 0
  NewlineNode 0
    MultipleAsgnNode 0
      ArrayNode 0
        LocalAsgnNode:a 0
, null
      ZArrayNode 0

@enebo
Copy link
Member

enebo commented Aug 7, 2015

@eregon There is in fact a difference and even a comment about the difference (although not a totally obvious comment). Both a,* and a, create an UnnamedRestArgNode. a, will give the name as null and a,* will give the name as "". So goofy I know but AST it able to differentiate the two cases.

@eregon
Copy link
Member Author

eregon commented Aug 7, 2015

@enebo Good to know, that's the way to differentiate :)

But should there be a rest arg in the first place if nothing exhibit its presence?
One cannot pass extra args for instance:

lambda { |a,| a }.call(1,2)
-e:1:in `block in <main>': wrong number of arguments (2 for 1) (ArgumentError)

(of course proc allows it, but without the , as well)

Arity reflects it as shown above, parameters as well, what is left?

eregon added a commit that referenced this issue Aug 7, 2015
@enebo
Copy link
Member

enebo commented Aug 7, 2015

As per irc discussion proc will destructure the array passed in and lambda will not. So there is a need to syntactically differentiate |a,| vs |a|.

@eregon
Copy link
Member Author

eregon commented Aug 29, 2015

And the way to check it from a * rest arg is with:

!((UnnamedRestArgNode) argsNode.getRestArgNode()).isStar()

So in the end it's just confusing because lambdas behave as if there was never a , but procs interpret it as ,* (and destructure)

@eregon eregon closed this as completed Aug 29, 2015
@enebo enebo added this to the Invalid or Duplicate milestone Sep 2, 2015
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

4 participants