Details

    • Number of attachments :
      0

      Description

      Trying to use a curried proc and/or lambda with a Array.map() function does not work as expected.

      It does work on MRI Ruby 1.9.3.

      To replicate, see the following examples:

      Jruby Version
      >> array = [1, 2, 3, 4, 5]
      => [1, 2, 3, 4, 5]
      >> add = lambda { |a, b| a + b }
      => #<Proc:0x44981fe9@(irb):2 (lambda)>
      >> add.(2, 3)
      => 5
      >> currying = add.curry
      => #<Proc:0x1d29109e@file:/opt/jruby/jruby-1.7.0.preview1/lib/jruby.jar!/jruby/kernel19/proc.rb:22 (lambda)>
      >> one = currying[1]
      => #<Proc:0x1d29109e@file:/opt/jruby/jruby-1.7.0.preview1/lib/jruby.jar!/jruby/kernel19/proc.rb:22 (lambda)>
      >> one.(4)
      => 5
      >> array.map(&one)
      ArgumentError: wrong number of arguments (3 for 2)
              from org/jruby/RubyProc.java:254:in `call'
              from file:/opt/jruby/jruby-1.7.0.preview1/lib/jruby.jar!/jruby/kernel19/proc.rb:25:in `curry'
              from org/jruby/RubyArray.java:2350:in `map'
              from (irb):7:in `evaluate'
              from org/jruby/RubyKernel.java:1037:in `eval'
              from org/jruby/RubyKernel.java:1353:in `loop'
              from org/jruby/RubyKernel.java:1146:in `catch'
              from org/jruby/RubyKernel.java:1146:in `catch'
              from /opt/jruby/jruby-1.7.0.preview1/bin/jirb:13:in `(root)'
              from org/jruby/RubyKernel.java:1017:in `load'
              from -e:1:in `(root)'
      
      Ruby MRI 1.9.3 (Works correctly)
      irb(main):002:0> array = [1, 2, 3, 4, 5]
      => [1, 2, 3, 4, 5]
      irb(main):003:0> add = lambda { |a, b| a + b }
      => #<Proc:0x0000000210d9c8@(irb):3 (lambda)>
      irb(main):004:0> add.(2, 3)
      => 5
      irb(main):005:0> currying = add.curry
      => #<Proc:0x000000020df460 (lambda)>
      irb(main):006:0> one = currying[1]
      => #<Proc:0x000000020c3a30 (lambda)>
      irb(main):007:0> one.(4)
      => 5
      irb(main):008:0> array.map(&one)
      => [2, 3, 4, 5, 6]
      

      Doing the same thing with a Proc doesn't fail, but produces some strange results:

      Jruby Version
      >> array = [1, 2, 3, 4, 5]
      => [1, 2, 3, 4, 5]
      >> add = Proc.new {|a,b| a + b}
      => #<Proc:0x5f571d2d@(irb):2>
      >> add.(1, 2)
      => 3
      >> currying = add.curry
      => #<Proc:0x95660e7@file:/opt/jruby/jruby-1.7.0.preview1/lib/jruby.jar!/jruby/kernel19/proc.rb:22>
      >> one = currying[1]
      => #<Proc:0x95660e7@file:/opt/jruby/jruby-1.7.0.preview1/lib/jruby.jar!/jruby/kernel19/proc.rb:22>
      >> one.(4)
      => 5
      >> array.map(&one)
      => [5, 5, 5, 5, 5]
      
      Ruby MRI 1.9.3 (Works correctly)
      
      irb(main):001:0> array = [1, 2, 3, 4, 5]
      => [1, 2, 3, 4, 5]
      irb(main):002:0> add = Proc.new {|a,b| a + b}
      => #<Proc:0x0000000227b3f0@(irb):2>
      irb(main):003:0> add.(1, 2)
      => 3
      irb(main):004:0> currying = add.curry
      => #<Proc:0x0000000225e548>
      irb(main):005:0> one = currying[1]
      => #<Proc:0x00000002241470>
      irb(main):006:0> one.(4)
      => 5
      irb(main):007:0> array.map(&one)
      => [2, 3, 4, 5, 6]
      

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        Yuck. Investigating.

        Show
        Charles Oliver Nutter added a comment - Yuck. Investigating.
        Hide
        Charles Oliver Nutter added a comment -

        We share Proc#curry logic with Rubinius, and it appears they fail the same way:

        system ~/projects/jruby $ jruby test.rb
        ArgumentError: wrong number of arguments (3 for 2)
            call at org/jruby/RubyProc.java:254
           curry at file:/Users/headius/projects/jruby/lib/jruby.jar!/jruby/kernel19/proc.rb:25
             map at org/jruby/RubyArray.java:2358
          (root) at test.rb:7
        
        system ~/projects/jruby $ ../rubinius/bin/rbx -X19 test.rb
        An exception occurred running test.rb
            method '__block__': given 3, expected 2 (ArgumentError)
        
        Backtrace:
                         { } in Proc#curry at kernel/common/proc19.rb:31
                                 Array#map at kernel/bootstrap/array19.rb:18
                         Object#__script__ at test.rb:7
          Rubinius::CodeLoader#load_script at kernel/delta/codeloader.rb:68
          Rubinius::CodeLoader.load_script at kernel/delta/codeloader.rb:110
                   Rubinius::Loader#script at kernel/loader.rb:614
                     Rubinius::Loader#main at kernel/loader.rb:817
        
        Show
        Charles Oliver Nutter added a comment - We share Proc#curry logic with Rubinius, and it appears they fail the same way: system ~/projects/jruby $ jruby test.rb ArgumentError: wrong number of arguments (3 for 2) call at org/jruby/RubyProc.java:254 curry at file:/Users/headius/projects/jruby/lib/jruby.jar!/jruby/kernel19/proc.rb:25 map at org/jruby/RubyArray.java:2358 (root) at test.rb:7 system ~/projects/jruby $ ../rubinius/bin/rbx -X19 test.rb An exception occurred running test.rb method '__block__': given 3, expected 2 (ArgumentError) Backtrace: { } in Proc#curry at kernel/common/proc19.rb:31 Array#map at kernel/bootstrap/array19.rb:18 Object#__script__ at test.rb:7 Rubinius::CodeLoader#load_script at kernel/delta/codeloader.rb:68 Rubinius::CodeLoader.load_script at kernel/delta/codeloader.rb:110 Rubinius::Loader#script at kernel/loader.rb:614 Rubinius::Loader#main at kernel/loader.rb:817
        Hide
        Charles Oliver Nutter added a comment -

        Easier than I expected!

        commit e309d2ca5415c7f968a13cd47fe25a75e9fab9be
        Author: Charles Oliver Nutter <headius@headius.com>
        Date:   Tue Jul 24 15:17:45 2012 -0500
        
            Fix JRUBY-6769
            
            Curried lambda/proc does not work correctly with Array.map
            
            The args should only be curried if arity does not match.
        
        :100644 100644 afa9c35... 5a8a9ba... M	src/jruby/kernel19/proc.rb
        
        Show
        Charles Oliver Nutter added a comment - Easier than I expected! commit e309d2ca5415c7f968a13cd47fe25a75e9fab9be Author: Charles Oliver Nutter <headius@headius.com> Date: Tue Jul 24 15:17:45 2012 -0500 Fix JRUBY-6769 Curried lambda/proc does not work correctly with Array.map The args should only be curried if arity does not match. :100644 100644 afa9c35... 5a8a9ba... M src/jruby/kernel19/proc.rb
        Hide
        Charles Oliver Nutter added a comment -

        The problem here was that all arguments passed to () were getting added to the curried args, rather than only adding them when arity did not match.

        Could you please submit a test case for this to MRI's test suite (preferred) or to RubySpec?

        Show
        Charles Oliver Nutter added a comment - The problem here was that all arguments passed to () were getting added to the curried args, rather than only adding them when arity did not match. Could you please submit a test case for this to MRI's test suite (preferred) or to RubySpec?
        Hide
        Mark Mandel added a comment -

        No Problem.

        Just to confirm, this would be the place to write the test?
        https://github.com/ruby/ruby/blob/trunk/test/ruby/test_proc.rb

        (Very new to J/Ruby)

        Show
        Mark Mandel added a comment - No Problem. Just to confirm, this would be the place to write the test? https://github.com/ruby/ruby/blob/trunk/test/ruby/test_proc.rb (Very new to J/Ruby)

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Mark Mandel
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: