Forum: Ruby-core [ruby-trunk - Feature #7939][Open] Alternative curry function creation

Posted by drKreso (Kresimir Bojcic) (Guest)
on 2013-02-24 12:39
(Received via mailing list)
Issue #7939 has been reported by drKreso (Kresimir Bojcic).

----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939

Author: drKreso (Kresimir Bojcic)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


I really like the new "assuming" method used for currying in Perl 6.

For example if I loose my mind and implement fizzbuzz via currying I can 
do it like this:

fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 }
fizzbuzz = fb.curry[15,"FizzBuzz"]
fizz = fb.curry[3, "Fizz"]
buzz = fb.curry[5, "Buzz"]
(1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use [] for function invoking...
If we had something similar to this:

class Proc
  def assuming(*args)
    curry.call *args
  end
end

It could be written more naturally IMO:

fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 }
fizzbuzz = fb.assuming(15,"FizzBuzz")
buzz = fb.assuming(5, "Buzz")
fizz = fb.assuming(3,"Fizz")

(1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
Posted by Nobuyoshi Nakada (nobu)
on 2013-02-24 14:35
(Received via mailing list)
Issue #7939 has been updated by nobu (Nobuyoshi Nakada).


It's Partial Application, not currying.
----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939#change-36922

Author: drKreso (Kresimir Bojcic)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


I really like the new "assuming" method used for currying in Perl 6.

For example if I loose my mind and implement fizzbuzz via currying I can 
do it like this:

fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 }
fizzbuzz = fb.curry[15,"FizzBuzz"]
fizz = fb.curry[3, "Fizz"]
buzz = fb.curry[5, "Buzz"]
(1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use [] for function invoking...
If we had something similar to this:

class Proc
  def assuming(*args)
    curry.call *args
  end
end

It could be written more naturally IMO:

fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 }
fizzbuzz = fb.assuming(15,"FizzBuzz")
buzz = fb.assuming(5, "Buzz")
fizz = fb.assuming(3,"Fizz")

(1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
Posted by Nobuyoshi Nakada (nobu)
on 2013-02-24 15:20
(Received via mailing list)
Issue #7939 has been updated by nobu (Nobuyoshi Nakada).

Description updated
Status changed from Open to Rejected

=begin
 fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}.curry(3)
 fizzbuzz = fb[15,"FizzBuzz"]
 fizz = fb[3, "Fizz"]
 buzz = fb[5, "Buzz"]
 (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
=end

----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939#change-36936

Author: drKreso (Kresimir Bojcic)
Status: Rejected
Priority: Normal
Assignee:
Category:
Target version:


=begin
I really like the new "(({assuming}))" method used for currying in Perl 
6.

For example if I loose my mind and implement ((%fizzbuzz%)) via currying 
I can do it like this:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.curry[15,"FizzBuzz"]
  fizz = fb.curry[3, "Fizz"]
  buzz = fb.curry[5, "Buzz"]
  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use (({[]})) for function invoking...
If we had something similar to this:

  class Proc
    def assuming(*args)
      curry.call *args
    end
  end

It could be written more naturally IMO:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.assuming(15,"FizzBuzz")
  buzz = fb.assuming(5, "Buzz")
  fizz = fb.assuming(3,"Fizz")

  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
=end
Posted by naruse (Yui NARUSE) (Guest)
on 2013-02-24 15:31
(Received via mailing list)
Issue #7939 has been updated by naruse (Yui NARUSE).

Category set to core
Status changed from Rejected to Assigned
Assignee set to matz (Yukihiro Matsumoto)
Target version set to next minor

> nobu
It can't be reason to reject this.
And describe the reason by English
----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939#change-36937

Author: drKreso (Kresimir Bojcic)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
I really like the new "(({assuming}))" method used for currying in Perl 
6.

For example if I loose my mind and implement ((%fizzbuzz%)) via currying 
I can do it like this:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.curry[15,"FizzBuzz"]
  fizz = fb.curry[3, "Fizz"]
  buzz = fb.curry[5, "Buzz"]
  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use (({[]})) for function invoking...
If we had something similar to this:

  class Proc
    def assuming(*args)
      curry.call *args
    end
  end

It could be written more naturally IMO:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.assuming(15,"FizzBuzz")
  buzz = fb.assuming(5, "Buzz")
  fizz = fb.assuming(3,"Fizz")

  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
=end
Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2013-02-24 22:45
(Received via mailing list)
Issue #7939 has been updated by marcandre (Marc-Andre Lafortune).


From http://bugs.ruby-lang.org/projects/ruby/wiki/HowTo..., 
I believe this FR fails point (1) "Ensure it's a meaningful improvement" 
and (2) "what's a good name".

It's pretty clear Nobu's example is more concise and nicer than what 
`assuming` would provide. BTW, the `.curry(3)` part can simply be 
`.curry`.

I second Nobu in rejecting this FR, but Matz can do it if you prefer.
----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939#change-36960

Author: drKreso (Kresimir Bojcic)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
I really like the new "(({assuming}))" method used for currying in Perl 
6.

For example if I loose my mind and implement ((%fizzbuzz%)) via currying 
I can do it like this:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.curry[15,"FizzBuzz"]
  fizz = fb.curry[3, "Fizz"]
  buzz = fb.curry[5, "Buzz"]
  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use (({[]})) for function invoking...
If we had something similar to this:

  class Proc
    def assuming(*args)
      curry.call *args
    end
  end

It could be written more naturally IMO:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.assuming(15,"FizzBuzz")
  buzz = fb.assuming(5, "Buzz")
  fizz = fb.assuming(3,"Fizz")

  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
=end
Posted by Matthew Kerwin (mattyk)
on 2013-02-25 01:19
(Received via mailing list)
Issue #7939 has been updated by phluid61 (Matthew Kerwin).


marcandre (Marc-Andre Lafortune) wrote:
> It's pretty clear Nobu's example is more concise and nicer than what `assuming` 
would provide. BTW, the `.curry(3)` part can simply be `.curry`.

As a philosophical question, would a name like #curry_with or #apply be 
more appropriate?  There is a small amount of utility added by such a 
method:  at first glance I didn't see the .curry on the end of the first 
line of Nobu's example, and it took a bit of effort on my part to parse 
the code (or its intent);  however the call to .assuming made it clear 
that something different was intended and happening at that point.

The square-bracket invocation falls somewhere in between, in terms of 
readability.  It may just be me, but sometimes I temporarily fail to 
grasp that foo.bar[baz] is actually two chained method calls.  In this 
case it was counfounded by the fact that I forgot that Proc#curry has an 
optional arity parameter.  I know that those are my issues, that it is 
up to me to overcome, but having such hints in the code can help.
----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939#change-36967

Author: drKreso (Kresimir Bojcic)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
I really like the new "(({assuming}))" method used for currying in Perl 
6.

For example if I loose my mind and implement ((%fizzbuzz%)) via currying 
I can do it like this:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.curry[15,"FizzBuzz"]
  fizz = fb.curry[3, "Fizz"]
  buzz = fb.curry[5, "Buzz"]
  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use (({[]})) for function invoking...
If we had something similar to this:

  class Proc
    def assuming(*args)
      curry.call *args
    end
  end

It could be written more naturally IMO:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.assuming(15,"FizzBuzz")
  buzz = fb.assuming(5, "Buzz")
  fizz = fb.assuming(3,"Fizz")

  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
=end
Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2013-02-25 02:32
(Received via mailing list)
Issue #7939 has been updated by marcandre (Marc-Andre Lafortune).


phluid61 (Matthew Kerwin) wrote:
> As a philosophical question, would a name like #curry_with or #apply be more 
appropriate?  There is a small amount of utility added by such a method:  at first 
glance I didn't see the .curry on the end of the first line of Nobu's example, and 
it took a bit of effort on my part to parse the code (or its intent);  however the 
call to .assuming made it clear that something different was intended and 
happening at that point.
>
> The square-bracket invocation falls somewhere in between, in terms of 
readability.  It may just be me, but sometimes I temporarily fail to grasp that 
foo.bar[baz] is actually two chained method calls.  In this case it was 
counfounded by the fact that I forgot that Proc#curry has an optional arity 
parameter.  I know that those are my issues, that it is up to me to overcome, but 
having such hints in the code can help.

There are many different ways to write the given example. You seem to be 
willing to use [] since your last line also has [] in it. But you can 
use .call or even .():

fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 }
       .curry  # <---- difficult to miss if it's at the beginning of a 
line
fizzbuzz = fb.(15,"FizzBuzz")
fizz = fb.(3, "Fizz")
buzz = fb.(5, "Buzz")
(1..100).each { |i| puts fizzbuzz.(i) || fizz.(i) || buzz.(i) || i }

You can use all of them if you want...

fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 }
fizzbuzz = fb.curry.(15,"FizzBuzz")
fizz = fb.curry.call(3, "Fizz")
buzz = fb.curry[5, "Buzz"]
(1..100).each { |i| puts fizzbuzz.(i) || fizz.call(i) || buzz[i] || i }

I feel that each of these variations is easier to understand than your 
proposition. Moreover, I use `curry` very rarely, so I see no use in 
adding a new method.

As for the name, I feel the one proposed was quite bad, but I don't 
think there is a really good one. The only name that would really fit is 
"curry_call", which is exactly what it is doing. I see no point in 
exchanging "curry.call" with "curry_call"...
----------------------------------------
Feature #7939: Alternative curry function creation
https://bugs.ruby-lang.org/issues/7939#change-36972

Author: drKreso (Kresimir Bojcic)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
I really like the new "(({assuming}))" method used for currying in Perl 
6.

For example if I loose my mind and implement ((%fizzbuzz%)) via currying 
I can do it like this:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.curry[15,"FizzBuzz"]
  fizz = fb.curry[3, "Fizz"]
  buzz = fb.curry[5, "Buzz"]
  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }

Here the first hurdle is that curry is somewhat mathematical, and the 
secons is that you need to use (({[]})) for function invoking...
If we had something similar to this:

  class Proc
    def assuming(*args)
      curry.call *args
    end
  end

It could be written more naturally IMO:

  fb = ->(modulo_number, message, x) { message if x % modulo_number == 0 
}
  fizzbuzz = fb.assuming(15,"FizzBuzz")
  buzz = fb.assuming(5, "Buzz")
  fizz = fb.assuming(3,"Fizz")

  (1..100).each { |i| puts fizzbuzz[i] || fizz[i] || buzz[i] || i }
=end
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.