Hello, I've been trying to figure out why the following code needs to

be thus:

(define curry

(lambda (f . x)

(lambda (y)

(apply f (append x (list y))))))

RATHER THAN (note the signature of the first lambda):

(define curry

(lambda (f x)

(lambda (y)

(apply f (append x (list y))))))

It's frustrating, because I feel like the understanding is *almost

there*. The answer must be simple, yet it remains elusive. The

feeling is most powerful when contemplating http://www.yqcomputer.com/ #./binding:h2

(the section immediately before 4.3), yet enlightenment is not

forthcoming. Finally, I have swallowed my pride, and come here asking

for a clue. Can you provide? My eternal gratitude goes to you if you

can :)

Joe Ardent writes:

This lets you call a procedure of at least one argument with all the

arguments but last, and then to supply the last one to the result:

(curry * 3 2 1) ==> (lambda (y) (* 3 2 1 y))

((curry * 3 2 1) 0) ==> (* 3 2 1 0)

This lets you call a procedure of at least one argument with a list of

all but last, and then to supply the last one to the result:

(curry * (list 3 2 1)) ==> (lambda (y) (* 3 2 1 y))

((curry * (list 3 2 1)) 0) ==> (* 3 2 1 0)

If you knew the number of arguments, you wouldn't play with the dot,

apply and append at all:

(define curry

(lambda (f x y z)

(lambda (w)

(f x y z w))))

(curry * 3 2 1) ==> (lambda (w) (* 3 2 1 w))

((curry * 3 2 1) 0) ==> (* 3 2 1 0)

(curry * 3 2) ==> ???

This lets you call a procedure of at least one argument with all the

arguments but last, and then to supply the last one to the result:

(curry * 3 2 1) ==> (lambda (y) (* 3 2 1 y))

((curry * 3 2 1) 0) ==> (* 3 2 1 0)

This lets you call a procedure of at least one argument with a list of

all but last, and then to supply the last one to the result:

(curry * (list 3 2 1)) ==> (lambda (y) (* 3 2 1 y))

((curry * (list 3 2 1)) 0) ==> (* 3 2 1 0)

If you knew the number of arguments, you wouldn't play with the dot,

apply and append at all:

(define curry

(lambda (f x y z)

(lambda (w)

(f x y z w))))

(curry * 3 2 1) ==> (lambda (w) (* 3 2 1 w))

((curry * 3 2 1) 0) ==> (* 3 2 1 0)

(curry * 3 2) ==> ???

On Feb 26, 11:35 pm, Jussi Piitulainen < XXXX@XXXXX.COM >

Ah, ha! The vague notion I had was a low-level muttering along the

lines of,

"It automatically list-i-fies the formal arguments and allows you to

use the car (f)

and cdr (x) without having to say so." Which I suppose is one way to

look at it,

even if it's not the most correct way?

There's the money; thank you for reformulating the function to point

out how you'd

make it simpler (less functional), highlighting the reasoning behind

using a

dotted pair in the original version. Jussi Piitulainen, you have my

eternal

gratitude! As does "pbwig", who replied in private, and also pointed

out the

utility of "reverse curry", which enables you to say:

(define halve (rev-curry / 2))

AND/OR

(define 2x (rev-curry * 2))

and have it work as you'd naively expect. Thank you both!

Ah, ha! The vague notion I had was a low-level muttering along the

lines of,

"It automatically list-i-fies the formal arguments and allows you to

use the car (f)

and cdr (x) without having to say so." Which I suppose is one way to

look at it,

even if it's not the most correct way?

There's the money; thank you for reformulating the function to point

out how you'd

make it simpler (less functional), highlighting the reasoning behind

using a

dotted pair in the original version. Jussi Piitulainen, you have my

eternal

gratitude! As does "pbwig", who replied in private, and also pointed

out the

utility of "reverse curry", which enables you to say:

(define halve (rev-curry / 2))

AND/OR

(define 2x (rev-curry * 2))

and have it work as you'd naively expect. Thank you both!

n Feb 26, 5:35am, Jussi Piitulainen < XXXX@XXXXX.COM >

wrote:

I have looked before at many different definitions of "curry"

in Scheme and I must admit that I am confused: they all seem to

be something entirely different from what I know from Haskell.

The confusion is, I think, in mixing curry/uncurry terminology.

To explain what I mean, please indulge me and follow my line of

reasoning for a while...

I will show that currying in Scheme can be made almost as painless

as in Haskell and that a fully curried Scheme function "f" behaves

exactly

as a Haskell function - some stylistic differences notwithstanding.

Curried expressions will be given in one of two versions:

parenthesized (in Scheme tradition) and juxtaposed (almost as in

Haskell).

I will start the discussion with the following two definitions, taken

from

Haskell's Prelude, but decorated with extra parentheses for clarity:

curry :: ((a b) -> c) -> (a -> (b -> c))

uncurry :: (a -> (b -> c)) -> ((a b) -> c)

[Arrows associate to the right, so we could have saved some

parentheses

by representing (a -> (b -> c)) as (a -> b -> c)]

What it means is this: curry takes an input function to an output

function, where the input function::((a b) -> c) accepts a tuple of

arguments (a b) producing result of type c, and the output

function::(a -> (b -> c)) accepts one argument of type a producing a

funtion of type (b -> c). Uncurry provides the reverse conversion.

Let's extend those Haskell-like definitions by admiting tuples longer

than two: (a b c), (a b c d), (a b c d e) up to some artificial limit

of tuple length, six say.

Formally, we are defining here several families of curry

(Haskell defines just curry-2):

curry-2 :: ((a b) -> c) -> (a -> (b -> c))

curry-3 :: ((a b c) -> d) -> (a -> (b -> (c -> d)))

curry-4 :: ((a b c d) -> e) -> (a -> (b -> (c -> (d -> e)))), etc.

Let's call them "curry" of rank 2, 3, 4, etc. The macro "curry n f"

accepts such rank "n" as the first argument. Note however that all

functions curried this way have arity 1; that is, they accept only one

argument.

As could be seen from the implementation of macro "curry" below, the

macro "(curry n f)" wraps an ordinary Scheme function "f" of any

arity in "n" layers of lambdas -- thus converting it to a curried

function of arity "1" and rank "n". This is not the same as a

partial application of a number "n" to a function "f", as some

definitions of curry found in some other sources might imply.

;; syntax: (curry n f)

;; Convert a function "f" of arity "m" into a function

;; accepting one argument a time, where "n" specifies a curry rank.

;; If f is finite (no optional arguments) then "n" must be equal "m",

;; otherwise it can be any natural number. In either case, however,

;; "n" should not exceed the (artificial) limit of 6, supported by

this macro.

;; --------

;; I am positive that this macro can be generalized to any arity,

;; but I present it here with such limitation (of 6) just for clarity.

;;

(define-syntax curry

(syntax-rules()

((curry 0 f) f)

((curry 1 f) ((x1)

(f x1)))

((curry 2 f) ((x1)((x2)

(f x1 x2))))

((curry 3 f) ((x1)((x2)((x3)

(f x1 x2 x3)))))

((curry 4 f) ((x1)((x2)((x3)((x4)

(f x1 x2 x3 x4))))))

((curry 5 f) ((x1)((x2)((x3)((x4)((x5)

(f x1

wrote:

I have looked before at many different definitions of "curry"

in Scheme and I must admit that I am confused: they all seem to

be something entirely different from what I know from Haskell.

The confusion is, I think, in mixing curry/uncurry terminology.

To explain what I mean, please indulge me and follow my line of

reasoning for a while...

I will show that currying in Scheme can be made almost as painless

as in Haskell and that a fully curried Scheme function "f" behaves

exactly

as a Haskell function - some stylistic differences notwithstanding.

Curried expressions will be given in one of two versions:

parenthesized (in Scheme tradition) and juxtaposed (almost as in

Haskell).

I will start the discussion with the following two definitions, taken

from

Haskell's Prelude, but decorated with extra parentheses for clarity:

curry :: ((a b) -> c) -> (a -> (b -> c))

uncurry :: (a -> (b -> c)) -> ((a b) -> c)

[Arrows associate to the right, so we could have saved some

parentheses

by representing (a -> (b -> c)) as (a -> b -> c)]

What it means is this: curry takes an input function to an output

function, where the input function::((a b) -> c) accepts a tuple of

arguments (a b) producing result of type c, and the output

function::(a -> (b -> c)) accepts one argument of type a producing a

funtion of type (b -> c). Uncurry provides the reverse conversion.

Let's extend those Haskell-like definitions by admiting tuples longer

than two: (a b c), (a b c d), (a b c d e) up to some artificial limit

of tuple length, six say.

Formally, we are defining here several families of curry

(Haskell defines just curry-2):

curry-2 :: ((a b) -> c) -> (a -> (b -> c))

curry-3 :: ((a b c) -> d) -> (a -> (b -> (c -> d)))

curry-4 :: ((a b c d) -> e) -> (a -> (b -> (c -> (d -> e)))), etc.

Let's call them "curry" of rank 2, 3, 4, etc. The macro "curry n f"

accepts such rank "n" as the first argument. Note however that all

functions curried this way have arity 1; that is, they accept only one

argument.

As could be seen from the implementation of macro "curry" below, the

macro "(curry n f)" wraps an ordinary Scheme function "f" of any

arity in "n" layers of lambdas -- thus converting it to a curried

function of arity "1" and rank "n". This is not the same as a

partial application of a number "n" to a function "f", as some

definitions of curry found in some other sources might imply.

;; syntax: (curry n f)

;; Convert a function "f" of arity "m" into a function

;; accepting one argument a time, where "n" specifies a curry rank.

;; If f is finite (no optional arguments) then "n" must be equal "m",

;; otherwise it can be any natural number. In either case, however,

;; "n" should not exceed the (artificial) limit of 6, supported by

this macro.

;; --------

;; I am positive that this macro can be generalized to any arity,

;; but I present it here with such limitation (of 6) just for clarity.

;;

(define-syntax curry

(syntax-rules()

((curry 0 f) f)

((curry 1 f) ((x1)

(f x1)))

((curry 2 f) ((x1)((x2)

(f x1 x2))))

((curry 3 f) ((x1)((x2)((x3)

(f x1 x2 x3)))))

((curry 4 f) ((x1)((x2)((x3)((x4)

(f x1 x2 x3 x4))))))

((curry 5 f) ((x1)((x2)((x3)((x4)((x5)

(f x1

Are you aware of SRFI-26, "Notation for Specializing Parameters

without Currying"? It's not currying, but serves a similar purpose.

http://www.yqcomputer.com/

Graham

Yes, I am -- as I am aware about its goals and its critique ("not

general enough") on the related mailing list. It is hard to make

everyone happy. :-)

My post here was not a SRFI proposal, just a pedagogical attempt to

explain what I understand by "true" function curry in the simplest

possible terms: a transformation from the uncurried representation to

the curried one.

I do not expect anyone to use "curry" the way I have shown. But I use

it, often in combination with a "place holder operator" ? as a

shortcut when supplying operators to higher order function, such as

filter, map, sum, etc.

Jan

1. How do I only get valid "answers" in a VLOOKUP function (no #N/A's

2. Printing report b after report a prints using report a's variables

3. Capture image of App#A's window from App#B

4. using "if" but omitting the #n/a's

10. how do u invoke Tag b's Tag Handler from within Tag a's tag Handler?

11. Count A's

12. Try Again / VLOOKUP without N/A's

13. Conditional count in range w/#N?A's

14. Host would occasionally fail to resolve A's rec.Help!

15. CAnnot type lowercAse 'A's Anymore

6 post • Page:**1** of **1**