From: Matthew Kerwin Date: 2012-11-10T13:00:52+09:00 Subject: [ruby-core:49184] Re: [ruby-trunk - Feature #6284] Add composition for procs --047d7b10d18531d77904ce1c1d12 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I agree that (f =E2=88=98 g)(x) is g(f(x)) is more intuitive from a purely programmatic point of view. It is "natural" for the operations to be applied left to right, exactly like method chaining. On 10 November 2012 13:06, duerst (Martin D=C3=BCrst) wrote: > > Issue #6284 has been updated by duerst (Martin D=C3=BCrst). > > > marcandre (Marc-Andre Lafortune) wrote: > > +1 for #* > > > > The symbol used in mathematics for function composition is a circle (= =E2=88=98); > the arrows are for the definitions of functions (like lambdas) only, so #= <- > or whatever make no sense to me. > > Very good point. > > > Finally, the f =E2=88=98 g(x) is defined as f(g(x)), so there is no arg= ument > there either. > > Not true. Depending on which field of mathematics you look at, either (f = =E2=88=98 > g)(x) is either f(g(x)), or it is g(f(x)). The later is in particular tru= e > in work involving relations, see e.g. > http://en.wikipedia.org/wiki/Composition_of_relations#Definition. > > Speaking from a more programming-related viewpoint, f(g(x)) is what is > used e.g. in Haskell, and probably in many other functional languages, an= d > so may be familiar with many programmers. > > However, we should take into account that a functional language writes > e.g. reverse(sort(array)), so it makes sense to define revsort =3D revers= e * > sort (i.e. (f =E2=88=98 g)(x) is f(g(x))). But in Ruby, it would be > array.sort.reverse, so revsort =3D sort * reverseve may feel much more > natural (i.e. (f =E2=88=98 g)(x) is g(f(x))). > > ---------------------------------------- > Feature #6284: Add composition for procs > https://bugs.ruby-lang.org/issues/6284#change-32728 > > Author: pabloh (Pablo Herrero) > Status: Feedback > Priority: Normal > Assignee: matz (Yukihiro Matsumoto) > Category: > Target version: 2.0.0 > > > =3Dbegin > It would be nice to be able to compose procs like functions in functional > programming languages: > > to_camel =3D :capitalize.to_proc > add_header =3D ->val {"Title: " + val} > > format_as_title =3D add_header << to_camel << :strip > > instead of: > > format_as_title =3D lambda {|val| "Title: " + val.strip.capitalize } > > > It's pretty easy to implement in pure ruby: > > class Proc > def << block > proc { |*args| self.call( block.to_proc.call(*args) ) } > end > end > =3Dend > > > -- > http://bugs.ruby-lang.org/ > > --=20 Matthew Kerwin, B.Sc (CompSci) (Hons) http://matthew.kerwin.net.au/ ABN: 59-013-727-651 "You'll never find a programming language that frees you from the burden of clarifying your ideas." - xkcd --047d7b10d18531d77904ce1c1d12 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I agree that=C2=A0(f =E2=88=98 g)(x) is g(f(x)) is more intuitive from a purely programmat= ic point of view. =C2=A0It is "natural" for the operations to be = applied left to right, exactly like method chaining.


On 10 November 2012 13:06, duerst (Marti= n D=C3=BCrst) <duerst@it.aoyama.ac.jp> wrote:

Issue #6284 has been updated by duerst (Martin D=C3=BCrst).


marcandre (Marc-Andre Lafortune) wrote:
> +1 for #*
>
> The symbol used in mathematics for function composition is a circle (= =E2=88=98); the arrows are for the definitions of functions (like lambdas) = only, so #<- or whatever make no sense to me.

Very good point.

> Finally, the f =E2=88=98 g(x) is defined as f(g(x)), so there is no ar= gument there either.

Not true. Depending on which field of mathematics you look at, either= (f =E2=88=98 g)(x) is either f(g(x)), or it is g(f(x)). The later is in pa= rticular true in work involving relations, see e.g. htt= p://en.wikipedia.org/wiki/Composition_of_relations#Definition.

Speaking from a more programming-related viewpoint, f(g(x)) is what is used= e.g. in Haskell, and probably in many other functional languages, and so m= ay be familiar with many programmers.

However, we should take into account that a functional language writes e.g.= reverse(sort(array)), so it makes sense to define revsort =3D reverse * so= rt (i.e. (f =E2=88=98 g)(x) is f(g(x))). But in Ruby, it would be array.sor= t.reverse, so revsort =3D sort * reverseve may feel much more natural (i.e.= (f =E2=88=98 g)(x) is g(f(x))).

----------------------------------------
Feature #6284: Add composition for procs
https://bugs.ruby-lang.org/issues/6284#change-32728

Author: pabloh (Pablo Herrero)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version: 2.0.0


=3Dbegin
It would be nice to be able to compose procs like functions in functional p= rogramming languages:

=C2=A0 =C2=A0 to_camel =3D :capitalize.to_proc
=C2=A0 =C2=A0 add_header =3D ->val {"Title: " + val}

=C2=A0 =C2=A0 format_as_title =3D add_header << to_camel << :st= rip

instead of:

=C2=A0 =C2=A0 format_as_title =3D lambda {|val| "Title: " + val.s= trip.capitalize }


It's pretty easy to implement in pure ruby:

=C2=A0 class Proc
=C2=A0 =C2=A0 def << block
=C2=A0 =C2=A0 =C2=A0 proc { |*args| self.call( block.to_proc.call(*args) ) = }
=C2=A0 =C2=A0 end
=C2=A0 end
=3Dend


--
http://bugs.ruby-l= ang.org/




--
= =C2=A0 Matthew Kerwin, B.Sc (CompSci) (Hons)
=C2=A0 http://matthew.kerwin.net.au/=C2=A0 ABN: 59-013-727-651

=C2=A0 "You'll never find a programming language that frees=C2=A0 you from the burden of clarifying your ideas." - xkcd
--047d7b10d18531d77904ce1c1d12--