Haskell's "currying" versus Business Objects Gem Cutter's "burning"

In Haskell, currying can only be done on the last (rightmost) function arguments. So foo x y can be curried as foo x but not as foo ? y where ? would be a "wilcard" for the x parameter. In Haskell, one must write a new function foo2 y x = foo x y and then one can curry the x parameter like foo2 y In Gem Cutter - which is a visual programming language - on can "burn" any input argument (which is like putting the ? for any argument in the foo function). See http://resources.businessobjects.com/labs/cal/gemcutter-techpaper.pdf This burning looks more general to me, but cannot be done using the textual approach? Does this reasoning make any sense? Thanks, Peter

On 03/07/07, peterv
In Haskell, currying can only be done on the last (rightmost) function arguments.
So
foo x y
can be curried as
foo x
but not as
foo ? y
where ? would be a "wilcard" for the x parameter.
The function flip can be used in two-argument functions, if you only have second argument but not the first:
function ??? arg2 -- this is what you mean flip function arg2 -- this is how you write it
So for example
let nums = flip map [1..10] nums (*2) [2,4,6,8,10,12,14,16,18,20] nums (subtract 1) [0,1,2,3,4,5,6,7,8,9]
For the general situation of N arguments, I don't think there are any predefined functions to help you. (After all, as N increases, the number of variations of argument order gets rather silly.) cheers D.

peterv wrote:
In Haskell, currying can only be done on the last (rightmost) function arguments.
You are talking about partial application, not currying.
foo x y
can be curried as
foo x
but not as
foo ? y
where ? would be a “wilcard” for the x parameter.
(\x -> foo x y) [snip]
This burning looks more general to me, but cannot be done using the textual approach?
Well, it can be done, but basically there are two issues: 1. You need to demarquate the 'scope' of the ?. What 'lump' of expression is the partially evaluated part. An obvious way to do this is with parentheses, but you have to be careful. 2. If you have more than one ?, you need to remember which is which. Think of nested expressions, nested ?s. What if you want to use the 'same' ? more than once? The solution that haskell chooses to (2) is to 'label' the ?s with names. The solution to (1) is to mark the scope with a \, and the list of names bound: \x z -> foo (foo x y) z Jules

Hi Jules Your explanation of lambda-abstraction, dealing in full generality with both scope and multiplicity, is a good one. But it's still interesting to investigate the possibility of a privileged notation for linear abstraction, based on leaving holes in things, by way of illustrating the design space. I seem to remember this topic coming up before (on Haskell Prime?), but I can't find the archival references just now. On 3 Jul 2007, at 11:19, Jules Bean wrote:
peterv wrote:
In Haskell, currying can only be done on the last (rightmost) function arguments.
[..]
This burning looks more general to me, but cannot be done using the textual approach?
Well, it can be done, but basically there are two issues:
Dead right.
1. You need to demarquate the 'scope' of the ?. What 'lump' of expression is the partially evaluated part. An obvious way to do this is with parentheses, but you have to be careful.
Let me borrow braces {..} for purposes of discussion. One might imagine a form of abstraction where one simply writes an expression in braces, replacing some subexpressions with ?, like Haskell Emmental {? * 10 + ?} Of course...
2. If you have more than one ?, you need to remember which is which. Think of nested expressions, nested ?s. What if you want to use the 'same' ? more than once?
...we need a convention to handle this. The obvious convention is that each ? is distinct and that they (and only they!) are abstracted from a brace in left-to-right order. That's to say, the above means \x y -> x * 10 + y hence {? * 10 + ?} 4 2 = 42 It can make sense to allow nested applications inside braces, using parentheses. {f ? (g ? x)} It can even make sense to allow nested braces, provided we adopt the convention that a ? is bound by its most local brace. {foldr {? : ?} ? ?} = flip (++) For expressions with no ?s, {..} and (..) coincide. {f ? ... ?} means f. All sorts of compositions, not just {f (g ?)}, are readily expressed, without resorting either to naming or to lurid ascii-art. [Local notational speculation: use (..) for {..} One might well wonder: if ?-less {..} are like (..) and ?-ful (..) are currently meaningless, why not overload (..) ? This can be done, but it gives a rather peculiar semantics to previously innocent syntax---you lose the ability to add extra parentheses to clarify grouping, so (f a) b is not necessarily the same as f a b and you also lose the ability to nest expressions, except via precedence (f (g ?)) means f g and not f . g (? * 10 + ?) may work, but ((? * 10) + ?) causes trouble. End local speculation] Oddly, to my mind, this is exactly the approach that the Gem Cutter crew take, but pictorially. On the one hand, they use tree diagrams for expressions, so they don't need parentheses for grouping. On the other hand, they explicitly choose only to allow the abstraction of "burnt" arguments from the very application in which they occur. Correspondingly {foo ? y} is expressible, but {? * 10 + ?} has to be expanded. This seems like a missed opportunity to me. What should Haskell take away from this? (1) You know where you are with lambda-abstraction. You can even do some sorts of "fast and loose" reasoning under binders, with some hope of preserving the meaning of your expressions. By comparison, computing inside {..} is very dangerous: {0 * ?} is not {0} {const ? ?} is not {?} {flip f ? ?} is not {f ? ?} {(\x -> (x, x)) ?} is not {(?, ?)} (2) Even so, it might be a useful feature. Something of the sort *has* been proposed before. I just found it http://hackage.haskell.org/trac/haskell-prime/wiki/ FlexiblePartialApplication but without the special {..} bracket, it's a nightmare. Brackets are always at a premium in syntax design. What would we do? (3) Exercise for readers: implement constructors P v for embedding pure values v O for holes f :$ a for application, left-associative and an interpreting function emmental such that emmental (P (+) :$ (P (*) :$ O :$ P 10) :$ O) 4 2 = 42 I think the question of whether to support linear abstractions other than of an argument suffix is an interesting one. The flip answer is a bad answer; lambda abstraction is a good answer, but sometimes feels too heavy for this job. I really don't have a strong opinion about whether it's worth supporting a lighter notation for the linear case, but I thought I'd at least try to inform the debate. All the best Conor

exercise done. :D there is still a problem with the functional dependencies. see last line of code. - marc Am Mittwoch, 4. Juli 2007 14:22 schrieb Conor McBride:
{? * 10 + ?} 4 2 = 42 http://hackage.haskell.org/trac/haskell-prime/wiki/FlexiblePartialApplicatio...
(3) Exercise for readers:
implement constructors P v for embedding pure values v O for holes f :$ a for application, left-associative and an interpreting function emmental such that emmental (P (+) :$ (P (*) :$ O :$ P 10) :$ O) 4 2 = 42
I think the question of whether to support linear abstractions other than of an argument suffix is an interesting one. The flip answer is a bad answer; lambda abstraction is a good answer, but sometimes feels too heavy for this job. I really don't have a strong opinion about whether it's worth supporting a lighter notation for the linear case, but I thought I'd at least try to inform the debate.
All the best
Conor
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hi Marc Thanks for giving it a go! On 4 Jul 2007, at 17:33, Marc A. Ziegert wrote:
exercise done. :D there is still a problem with the functional dependencies. see last line of code. - marc
Looks like a good start. Quite different from the way I did it. I can assure you that it's possible to be less explicit about the types of the pieces. You might think about computing a typed context for the holes, rather than just counting them. I should add that my solution is here, if/when you feel like looking: http://www.e-pig.org/idle/ctm/Emmental.lhs I'm still fiddling with it in odd moments, hoping for something neater. I don't like the explicit P, or the explicit :$. I have another slightly clunky, non-nesting version which works like idiom brackets hH elem O (P "aeiou") Hh 'x' = False but I don't really like it much. The connection with idiom brackets isn't an accident, but that's another story. All the best Conor

Hello peterv, Tuesday, July 3, 2007, 1:40:11 PM, you wrote:
This burning looks more general to me, but cannot be done using the textual approach?
it's just a matter of syntax :) "foo ? bar" may be replaced with "\x -> foo x bar" although i agree that "burning" syntax is useful. one problem that arrives with it is where we should insert lambda -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

In this case, I usually use _flip_ function. flip :: (a -> b -> c) -> b -> a -> c flip f x y = f y x ------------------ L.Guo 2007-07-04 ------------------------------------------------------------- From: peterv At: 2007-07-03 17:40:35 Subject: [Haskell-cafe] Haskell's "currying" versus Business Objects GemCutter's "burning" In Haskell, currying can only be done on the last (rightmost) function arguments.
participants (9)
-
Bulat Ziganshin
-
Conor McBride
-
Conor McBride
-
Dougal Stanton
-
Jules Bean
-
L.Guo
-
Marc A. Ziegert
-
peterv
-
Salvatore Insalaco