[nem-bug] [Nemerle 0000870]: Function composition operator &
Pipeline operator
feedback at nemerle.org
feedback at nemerle.org
Tue Feb 6 08:28:52 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-06-2007 08:28 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)))))
----------------------------------------------------------------------
iae - 02-06-07 08:28
----------------------------------------------------------------------
> I think that composition should be an instance method of function:
> def isqrt = Sqrt.Compose (Ceiling); // instead of x => Ceiling(Sqrt(x))
I tried to find the shortest way. And I will never use Compose method
instead of 'x => ...' form. Using the operator '>>' will make the code
shorter and clearer. Also, function composition usually is used usually in
functional programming, so using an imperative style to make function
composition isn't a good idea.
> As for the pipeline... I don't really see how this is useful...
I don't really see how this can be much of use in Nemerle either... But,
if you look at any F# or Haskell codes, you will see many places where
such operator is used. As I see, F# and Haskell programmers use them to
avoid flooding of code with parentheses.
Also, we can use pipeline when we can't use extension methods. Let's look
at the piece of code bellow:
def types : list[Type] =
AppDomain.CurrentDomain.GetAssemblies()
.ToList()
.FoldLeft([], (x,y) => x.GetTypes().ToList() + y);
This code is quite easy to understand. And now imagine that ToList and
FoldLeft are local functions. So, our code will be very ugly:
def types : list[Type] =
FoldLeft(ToList(AppDomain.CurrentDomain.GetAssemblies()),
[],
(x,y) => ToList(x.GetTypes()) + y);
Isn't it? But, we can use pipeline to avoid such ugliness:
def types : list[Type] =
AppDomain.CurrentDomain.GetAssemblies()
|> ToList
|> FoldLeft(_, [], (x,y) => (x.GetTypes() |> ToList) + y);
This code is almost like our first version with extension methods.
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
02-06-07 08:28 iae Note Added: 0001702
======================================================================
More information about the bugs
mailing list