caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Infix function composition operator
@ 2010-11-10  3:19 Arlen Christian Mart Cuss
  2010-11-10  3:45 ` [Caml-list] " Yaron Minsky
  2010-11-10 13:23 ` Michael Ekstrand
  0 siblings, 2 replies; 14+ messages in thread
From: Arlen Christian Mart Cuss @ 2010-11-10  3:19 UTC (permalink / raw)
  To: caml-list

Hi all,

I know this was asked at least 12 years ago[1], but is there any
consensus or reason for there not being a "compose" function in standard
OCaml, nor an infix operator?

At the moment I tend to "let compose" or "let (<<-) f g x = f (g x)",
but I wish I didn't have to!

Thanks,
Arlen

[1]
http://webcache.googleusercontent.com/search?q=cache:TcqI7o37il8J:pauillac.inria.fr/caml/caml-list/0720.html+ocaml+function+compose&cd=2&hl=en&ct=clnk&client=ubuntu


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [Caml-list] Infix function composition operator
@ 2010-11-10  6:59 mark
  2010-11-10 12:51 ` Jon Harrop
  0 siblings, 1 reply; 14+ messages in thread
From: mark @ 2010-11-10  6:59 UTC (permalink / raw)
  To: yminsky, arlen; +Cc: caml-list

on 10/11/10 3:45 AM, yminsky@gmail.com wrote:

> This is probably a minority opinion, but I have written and read quite a
lot
> of OCaml code over the years, and I've seen surprisingly few effective
uses
> of the composition operator.  Somehow, I usually find that code that
avoids
> it is simpler and easier to read.

I agree that using a composition operator can make the code obtuse, and so
should not be overused.  But it's incredibly useful for certain situations:

1) If you are performing a long chain of composed operations, it avoids
nested bracketing piling up.

For example:
      (op5 <<- op4 <<- op3 <<- op2 <<- op1) x
Instead of:
      op5 (op4 (op3 (op2 (op1 x))))

This sort of thing happens quite a lot in certain applications, e.g. in
language processing, to get at subexpressions.

2) Creating an anonymous function to be passed as an argument, it avoids
explicitly mentioning arguments of that function.

This sort of thing can happen a lot in functional programming generally.

For example:
      List.map (op2 <<- op1) xs
Instead of:
      List.map (fun x -> op2 (op1 x)) xs

Mark Adams


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [Caml-list] Infix function composition operator
@ 2010-11-10 13:44 mark
  2010-11-10 14:13 ` Jon Harrop
  0 siblings, 1 reply; 14+ messages in thread
From: mark @ 2010-11-10 13:44 UTC (permalink / raw)
  To: jonathandeanharrop, yminsky, arlen; +Cc: caml-list

So how does value restriction affect things here?  (excuse my lack of
knowledge)

One thing about using a pipeline like this is that it relies on '|>' being
left-associative (which it is due to OCaml's convention on operators that
start with "|").

Mark.


on 10/11/10 12:52 PM, Jon Harrop <jonathandeanharrop@googlemail.com> wrote:

> A pipeline operator is usually preferred over function composition in
impure
> languages like OCaml and F# due to the value restriction. For example,
your
> example would be written in F# as:
>
> x |> op1 |> op2 |> op3 |> op4 |> op5
>
> This style is very common in F#, particularly when dealing with
collections.
>
> Cheers,
> Jon.
>
>> -----Original Message-----
>> From: caml-list-bounces@yquem.inria.fr [mailto:caml-list-
>> bounces@yquem.inria.fr] On Behalf Of mark@proof-technologies.com
>> Sent: 10 November 2010 07:00
>> To: yminsky@gmail.com; arlen@noblesamurai.com
>> Cc: caml-list@inria.fr
>> Subject: Re: [Caml-list] Infix function composition operator
>>
>> on 10/11/10 3:45 AM, yminsky@gmail.com wrote:
>>
>> > This is probably a minority opinion, but I have written and read
>> quite a
>> lot
>> > of OCaml code over the years, and I've seen surprisingly few
>> effective
>> uses
>> > of the composition operator.  Somehow, I usually find that code that
>> avoids
>> > it is simpler and easier to read.
>>
>> I agree that using a composition operator can make the code obtuse, and
>> so
>> should not be overused.  But it's incredibly useful for certain
>> situations:
>>
>> 1) If you are performing a long chain of composed operations, it avoids
>> nested bracketing piling up.
>>
>> For example:
>>       (op5 <<- op4 <<- op3 <<- op2 <<- op1) x
>> Instead of:
>>       op5 (op4 (op3 (op2 (op1 x))))
>>
>> This sort of thing happens quite a lot in certain applications, e.g. in
>> language processing, to get at subexpressions.
>>
>> 2) Creating an anonymous function to be passed as an argument, it
>> avoids
>> explicitly mentioning arguments of that function.
>>
>> This sort of thing can happen a lot in functional programming
>> generally.
>>
>> For example:
>>       List.map (op2 <<- op1) xs
>> Instead of:
>>       List.map (fun x -> op2 (op1 x)) xs
>>
>> Mark Adams
>>
>> _______________________________________________
>> Caml-list mailing list. Subscription management:
>> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
>> Archives: http://caml.inria.fr
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [Caml-list] Infix function composition operator
@ 2010-11-10 15:18 mark
  0 siblings, 0 replies; 14+ messages in thread
From: mark @ 2010-11-10 15:18 UTC (permalink / raw)
  To: jonathandeanharrop, jonathandeanharrop, yminsky, arlen; +Cc: caml-list

Fascinating!  I do use parser combinators myself, and find myself having to
use the eta-expanded form, like you say.  Thanks for that explanation.

Mark.


on 10/11/10 2:20 PM, Jon Harrop <jonathandeanharrop@googlemail.com> wrote:

> In OCaml, the value restriction leads to non-generalized type variables
('_a
> etc.) if you try to define functions like:
>
> # let ( << ) f g x = f(g x);;
> val ( << ) : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
>
> # let cons h t = h::t;;
> val cons : 'a -> 'a list -> 'a list = <fun>
>
> # cons << cons;;
> - : '_a -> ('_a list -> '_a list) list -> ('_a list -> '_a list) list =
> <fun>
>
> This is a silly example but you are most likely to hit this problem in
> practice in the context of parser combinators. Due to JIT compilation, F#
> cannot relax the value restriction so that does not even compile.
>
> In MLs, you usually want the eta-expanded form:
>
> # let cons2 x = (cons << cons) x;;
> val cons2 : 'a -> ('a list -> 'a list) list -> ('a list -> 'a list) list =
> <fun>
>
> But a pipeline is prettier:
>
> # let ( |> ) x f = f x;;
> val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
>
> # let cons2 x = x |> cons |> cons;;
> val cons2 : 'a -> ('a list -> 'a list) list -> ('a list -> 'a list) list =
> <fun>
>
> This is one advantage of Haskell over OCaml/F#. However, I don't see it as
a
> useful advantage in practice because parser combinators are so tedious
> during development (they require constant attention as types evolve): you
> want code generation like ocamlyacc or camlp4. OCaml is a very strong
> contender here, of course.
>
> Cheers,
> Jon.
>
>> -----Original Message-----
>> From: mark@proof-technologies.com [mailto:mark@proof-technologies.com]
>> Sent: 10 November 2010 13:44
>> To: jonathandeanharrop@googlemail.com; yminsky@gmail.com;
>> arlen@noblesamurai.com
>> Cc: caml-list@inria.fr
>> Subject: Re: [Caml-list] Infix function composition operator
>>
>> So how does value restriction affect things here?  (excuse my lack of
>> knowledge)
>>
>> One thing about using a pipeline like this is that it relies on '|>'
>> being
>> left-associative (which it is due to OCaml's convention on operators
>> that
>> start with "|").
>>
>> Mark.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-11-14 18:21 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-10  3:19 Infix function composition operator Arlen Christian Mart Cuss
2010-11-10  3:45 ` [Caml-list] " Yaron Minsky
2010-11-10  4:37   ` Arlen Christian Mart Cuss
2010-11-10 10:06   ` DS
2010-11-10 13:23 ` Michael Ekstrand
2010-11-10  6:59 mark
2010-11-10 12:51 ` Jon Harrop
2010-11-14 18:20   ` Till Varoquaux
2010-11-10 13:44 mark
2010-11-10 14:13 ` Jon Harrop
2010-11-10 16:10   ` Stephan Tolksdorf
2010-11-10 17:41     ` Jon Harrop
2010-11-10 18:52       ` Stephan Tolksdorf
2010-11-10 15:18 mark

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).