[nem-bug] [Nemerle 0000870]: Function composition operator & Pipeline operator

feedback at nemerle.org feedback at nemerle.org
Mon Feb 5 17:37:56 CET 2007


A NOTE has been added to this issue.
======================================================================
<http://nemerle.org/bugs/view.php?id=870> 
======================================================================
Reported By:                iae
Assigned To:                
======================================================================
Project:                    Nemerle
Issue ID:                   870
Category:                   Language Feature
Reproducibility:            N/A
Severity:                   feature
Priority:                   normal
Status:                     new
======================================================================
Date Submitted:             02-05-2007 06:16 CET
Last Modified:              02-05-2007 17:37 CET
======================================================================
Summary:                    Function composition operator & Pipeline operator
Description: 
A lot of functional languages has a function composition operator. For
example in Haskell such operator is '.':

(.) :: (b -> c) -> (a -> b) -> (a -> c)
so "f.g" is equivalent to "\x -> f (g x)"

F# has the similar operator '>>':

val >>: ('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)
so "g>>f" is equivalent to "fun x -> f (g x)"

It'll be a nice to have such operator in Nemerle. As for me, I prefer
Haskell style, but we can't use '.'. So, there is two way: 
1. use '>>' and F# style, i.e. "g>>f" will be "f of g", nor [Haskell
style] "g of f".
2. use own operator sign and Haskell style.


Other feature I want suggest is a pipeline operator.
Haskell:
($) :: (a -> b) -> a -> b
f $ g x = f (g x)

F#:
val |>: 'a -> ('a -> 'b) -> 'b
g x |> f = f (g x)

If we planing to add both oparetors (not only function composition),
possible we should use F# style for both of them.

What do you think about these two oparators? 
F# style oparators implemented in attached patch. Should I commit them?
======================================================================

----------------------------------------------------------------------
 iae - 02-05-07 06:21 
----------------------------------------------------------------------
Pipeline usage:

WriteLine(Sqrt(1235432) |> Floor);

Unfortunately, this way will not work propertly:

// typing fails on ambiguity between overloads
Sqrt(1235432) |> Floor |> WriteLine;

----------------------------------------------------------------------
 VladD2 - 02-05-07 12:25 
----------------------------------------------------------------------
In my option, Extension methods more intuitive than pipline:
1235432.Sqrt().Floor().WriteLine()

----------------------------------------------------------------------
 iae - 02-05-07 12:36 
----------------------------------------------------------------------
But there are a lot of methods not marked with extension attribute. Also,
as I know, local functions can't be an extensions.

----------------------------------------------------------------------
 VladD2 - 02-05-07 13:11 
----------------------------------------------------------------------
Maybe, it's better to allow to m&http://nemerle.org/bugs/view.php?id=1072;ke
ordinar methods as Extension
methods?
For example, it's can be done by blobale castom attributes:
[assembly: MakeMethodsAsExtention(Match.Sqrt, Console.WriteLine)]

----------------------------------------------------------------------
 iae - 02-05-07 13:20 
----------------------------------------------------------------------
Hmmm... It is a quite good idea. But, I'm not sure is it easy to implement.

----------------------------------------------------------------------
 nazgul - 02-05-07 17:37 
----------------------------------------------------------------------
I think that composition should be an instance method of function:

WriteLine(tup.Compose (t2str)());

WriteLine(tup.Compose (t2str).Compose(strlen)());

WriteLine(t2str.Compose (strlen)(1,2));

def isqrt = Sqrt.Compose (Ceiling); // instead of x => Ceiling(Sqrt(x))
WriteLine(isqrt(1235432));


As for the pipeline... I don't really see how this is useful... The only
thing it does is to move function name from beginning to the end:

x |> f   ===  f (x)    

For me, the second one is much cleaner. And if you really like to write
down the  operations applied in left-to-right order, then maybe use macro
to get:

pipe (343, Sqrt, Ceil, Sqrt, Sqr, Abs)
--->
Abs (Sqr, Sqrt, Ceil, Sqrt, 343)))))

Issue History
Date Modified  Username       Field                    Change              
======================================================================
02-05-07 06:16 iae            New Issue                                    
02-05-07 06:16 iae            File Added: funccomp.patch                    
02-05-07 06:21 iae            Note Added: 0001677                          
02-05-07 12:25 VladD2         Note Added: 0001678                          
02-05-07 12:36 iae            Note Added: 0001679                          
02-05-07 13:11 VladD2         Note Added: 0001680                          
02-05-07 13:20 iae            Note Added: 0001681                          
02-05-07 17:37 nazgul         Note Added: 0001688                          
======================================================================




More information about the bugs mailing list