Comments on: Curried Scheme http://comonad.com/reader/2009/curried-scheme/ types, (co)monads, substructural logic Sat, 29 Dec 2012 15:18:06 -0800 http://wordpress.org/?v=2.8.4 hourly 1 By: Gary Ballin http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-41360 Gary Ballin Thu, 03 Mar 2011 17:14:43 +0000 http://comonad.com/reader/?p=145#comment-41360 Thanks for sharing, I`ll come back and check one of the other posts you have written. See ya. Thanks for sharing, I`ll come back and check one of the other posts you have written. See ya.

]]>
By: Yi DAI http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-17384 Yi DAI Mon, 07 Jun 2010 10:37:05 +0000 http://comonad.com/reader/?p=145#comment-17384 A cleaned version: (define-syntax curried-lambda (syntax-rules () ((_ () exp exps ...) (lambda as (cond ((null? as) exp exps ...) (else (apply (begin exp exps ...) as))))) ((_ (arg args ...) exp exps ...) (letrec ((papp (lambda as (cond ((null? as) papp) (else (let ((arg (car as))) (apply (curried-lambda (args ...) exp exps ...) (cdr as)))))))) papp)))) A cleaned version:

(define-syntax curried-lambda
(syntax-rules ()
((_ () exp exps …)
(lambda as
(cond ((null? as) exp exps …)
(else (apply (begin exp exps …) as)))))
((_ (arg args …) exp exps …)
(letrec ((papp (lambda as
(cond ((null? as) papp)
(else (let ((arg (car as)))
(apply (curried-lambda (args …) exp exps …) (cdr as))))))))
papp))))

]]>
By: Edward Kmett http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11379 Edward Kmett Mon, 31 Aug 2009 19:01:10 +0000 http://comonad.com/reader/?p=145#comment-11379 Hi Dan, The code above provides both. (define id (curried (x) x)) uses the lambda form (perhaps 'curried' should be renamed 'curried-lambda' ?) On the other hand, (define-curried (id x) x) provides a definition with a curried argument list in the same fashion that (define (id x) x) desugars to (define id (lambda (x) x)) -- a convenience that I seem to recall you don't like using. ;) Hi Dan,

The code above provides both.

(define id (curried (x) x))

uses the lambda form (perhaps ‘curried’ should be renamed ‘curried-lambda’ ?)

On the other hand,

(define-curried (id x) x)

provides a definition with a curried argument list in the same fashion that (define (id x) x) desugars to (define id (lambda (x) x)) — a convenience that I seem to recall you don’t like using. ;)

]]>
By: Dan Friedman http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11378 Dan Friedman Mon, 31 Aug 2009 18:10:07 +0000 http://comonad.com/reader/?p=145#comment-11378 Ed, I noticed that one of the comments mentioned using a curried lambda. I think that having a curried lambda instead of a curried define makes much more sense, given that the define is like let/letrec/ etc., but it is lambda that absorbs values. ... Dan Ed,

I noticed that one of the comments mentioned using a curried lambda. I think that having
a curried lambda instead of a curried define
makes much more sense, given that the define
is like let/letrec/ etc., but it is lambda that absorbs values.

… Dan

]]>
By: Edward Kmett http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11358 Edward Kmett Sun, 30 Aug 2009 19:13:45 +0000 http://comonad.com/reader/?p=145#comment-11358 @Anthony: It looks like my parametricity concern was a bit of a misapprehension. I wasn't able to concoct a scenario where it led to a problem. ;) If we ignore the existence of nullary functions the new version works really well, as would, I suppose, your fix. @Anthony:

It looks like my parametricity concern was a bit of a misapprehension. I wasn’t able to concoct a scenario where it led to a problem. ;)

If we ignore the existence of nullary functions the new version works really well, as would, I suppose, your fix.

]]>
By: Anthony Cowley http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11343 Anthony Cowley Sun, 30 Aug 2009 03:42:59 +0000 http://comonad.com/reader/?p=145#comment-11343 Edward, I like your fix; a definite improvement! Can you offer more detail on your parametricity concern, though? Like many others, I, too, have a toy monad library in my collection, but it's not obvious to me how this situation with my proposed patch raises a problem in that area. Edward,

I like your fix; a definite improvement! Can you offer more detail on your parametricity concern, though? Like many others, I, too, have a toy monad library in my collection, but it’s not obvious to me how this situation with my proposed patch raises a problem in that area.

]]>
By: Edward Kmett http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11341 Edward Kmett Sun, 30 Aug 2009 02:46:29 +0000 http://comonad.com/reader/?p=145#comment-11341 @Phil: Nice macro. =) While, alas, it doesn't handle over or null application, it is really succinct! @Phil:

Nice macro. =) While, alas, it doesn’t handle over or null application, it is really succinct!

]]>
By: Phil http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11340 Phil Sun, 30 Aug 2009 01:27:44 +0000 http://comonad.com/reader/?p=145#comment-11340 There is a curried lambda at http://programmingpraxis.com/standard-prelude. There is a curried lambda at http://programmingpraxis.com/standard-prelude.

]]>
By: Edward Kmett http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11336 Edward Kmett Sat, 29 Aug 2009 20:24:09 +0000 http://comonad.com/reader/?p=145#comment-11336 @Anthony: Good point. I was trying to avoid discriminating, so I could just work parametrically, but a quick procedure? check isn't such a high price to pay to handle the base case more gracefully. I have two concerns with this proposed fix though. <ol> <li>One is that this will silently eat the remaining arguments when you try to handle a non-procedure. Perhaps it should do the null? check on args rather than swallow them in the non-procedure case.</li> <li>The other is more subtle and has to do with parametricity. Since we now may or may not invoke the result, I might not be able to use this in a number of situations inside of my toy monad library.</li> </ol> By redefining (define-curried name body) to just use a define and migrating its current behavior to (define-curried (name) body) this obtains, perhaps a more pleasing result. Patching it thus: <pre lang="scheme"> ((_ () body) (lambda args (if (null? args) body (apply body args)))) </pre> yields a result that is identical to the handling of the other two cases in behavior. Then (define-curried x 5) does the right thing, and just gives you 5. and (define-curried (x) 5) gives you a nullary function that when invoked will give you back 5, but will try to pass any superfluous over-applied arguments to 5 and crash. @Anthony:

Good point. I was trying to avoid discriminating, so I could just work parametrically, but a quick procedure? check isn’t such a high price to pay to handle the base case more gracefully.

I have two concerns with this proposed fix though.

  1. One is that this will silently eat the remaining arguments when you try to handle a non-procedure. Perhaps it should do the null? check on args rather than swallow them in the non-procedure case.
  2. The other is more subtle and has to do with parametricity. Since we now may or may not invoke the result, I might not be able to use this in a number of situations inside of my toy monad library.

By redefining (define-curried name body) to just use a define and migrating its current behavior to (define-curried (name) body) this obtains, perhaps a more pleasing result. Patching it thus:

((_ () body)
     (lambda args
         (if (null? args)
             body
             (apply body args))))

yields a result that is identical to the handling of the other two cases in behavior.

Then (define-curried x 5) does the right thing, and just gives you 5.
and (define-curried (x) 5) gives you a nullary function that when invoked will give you back 5, but will try to pass any superfluous over-applied arguments to 5 and crash.

]]>
By: Anthony Cowley http://comonad.com/reader/2009/curried-scheme/comment-page-1/#comment-11333 Anthony Cowley Sat, 29 Aug 2009 18:27:57 +0000 http://comonad.com/reader/?p=145#comment-11333 I don't know if this is a concern, but the define-curried form isn't quite right for suspended non-lambda value bindings. For instance, if you have (define-curried x 5), then it's rather hard to get the 5 out. One option for the first case of the curried macro is to check that "body" evaluates to a procedure, and then apply it to whatever args you're given (living with arity errors), while returning its normal form otherwise. One has to be careful to not evaluate "body" twice in case it's the side effect that matters. One option might be, ((_ () body) (λ args (let ((r body)) (if (procedure? r) (apply r args) r)))) Then I can have something like, (define-curried x (begin (printf "hi~n") 5)) that does the right thing, afaict. I don’t know if this is a concern, but the define-curried form isn’t quite right for suspended non-lambda value bindings. For instance, if you have (define-curried x 5), then it’s rather hard to get the 5 out. One option for the first case of the curried macro is to check that “body” evaluates to a procedure, and then apply it to whatever args you’re given (living with arity errors), while returning its normal form otherwise. One has to be careful to not evaluate “body” twice in case it’s the side effect that matters.

One option might be,
((_ () body)
(λ args (let ((r body))
(if (procedure? r)
(apply r args)
r))))

Then I can have something like,
(define-curried x (begin (printf “hi~n”) 5))
that does the right thing, afaict.

]]>