First of all define-macro is asking for trouble. don't use it is the general recomendation for guile.
If you look into the kanren soures you will find, (define-syntax lambda@ (syntax-rules () ((_ (formal) body0 body1 ...) (lambda (formal) body0 body1 ...)) ((_ (formal0 formal1 formal2 ...) body0 body1 ...) (lambda (formal0) (lambda@ (formal1 formal2 ...) body0 body1 ...))))) (define-syntax @ (syntax-rules () ((_ rator rand) (rator rand)) ((_ rator rand0 rand1 rand2 ...) (@ (rator rand0) rand1 rand2 ...)))) That is currying where lambda@ is your define-curried and @ is the application of curried functions in a convinient way e.g. (test-check 'test-@-lambda@ (@ (lambda@ (x y z) (+ x (+ y z))) 1 2 3) 6) It's not what you wnt but this gives you a good pattern to maybe base your work on. If you still wan't to design defined curried ontop of syntax-rules I would recoment to use the ck macro e.g. (define-syntax ck (syntax-rules (quote) ((ck () 'v) v) ; yield the value on empty stack ((ck (((op ...) ea ...) . s) 'v) ; re-focus on the other argument, ea (ck-arg s (op ... 'v) ea ...)) ((ck s (op ea ...)) ; Focus: handling an application; (ck-arg s (op) ea ...)))) ; check if args are values (define-syntax ck-arg (syntax-rules (quote) ((ck-arg s (op va ...)) ; all arguments are evaluated, (op s va ...)) ; do the redex ((ck-arg s (op ...) 'v ea1 ...) ; optimization when the first ea (ck-arg s (op ... 'v) ea1 ...)) ; was already a value ((ck-arg s (op ...) ea ea1 ...) ; focus on ea, to evaluate it (ck (((op ...) ea1 ...) . s) ea)))) 1) define a partitioner, (a b c) -> (() a) ((a) b) ((a b) c)) with (define-syntax ck-partition (syntax-rules (quote) ((_ s '(a ... b) 'l) (ck-partition s '(a ...) '(((a ...) b) . l))) ((_ s '() 'l) (ck s 'l)))) 2) compile the pieces together (define-syntax compile-curried (syntax-rules (quote) ((_ s 'name '(a ...) 'body '(((b ...) c) ...)) (ck () '(define-syntax name (syntax-rules () ((_ a ...) (begin . body)) ((_ b ...) (lambda (c) (name b ... c))) ...)))))) 3) The overall macro (define-syntax-rule (define-curried (name a ...) . body) (ck () (compile-curried 'name '(a ...) 'body (ck-partition '(a ...) '())))) Now we need the definition of the ck macro, http://okmij.org/ftp/Scheme/macros.html We have it in guile also in master. So lets try it, ... scheme@(guile-user)> (define-curried (f a b c d) (list a b c d)) scheme@(guile-user)> (((f 1 2) 3) 4) $5 = (1 2 3 4) it works, lets try out the problematic vode you have, (use-modules (srfi srfi-2)) (use-modules (srfi srfi-1)) (define-curried (string-matches pattern string) (and-let* ((match-struct (string-match pattern string)) (count (match:count match-struct))) (map (lambda(n)(match:substring match-struct n)) (iota (1- count) 1)))) scheme@(guile-user)> (string-matches "([a-z])" "a") $4 = ("a") ,exp ((string-matches "([a-z])") "a") $5 = ((lambda (string-871) (let ((match-struct-876 (string-match "([a-z])" string))) (if match-struct-876 (let ((count-880 (match:count match-struct-876))) (if count-880 (map (lambda (n-883) (match:substring match-struct-876 n-883)) (iota (#{1-}# count-880) 1)) #f)) #f))) "a") And we see that string is not managed correctly. Is this a bug? I can't understand why this is not treated as intended! > On Monday, September 09, 2013 07:35:16 PM Panicz Maciej Godek wrote: > Hi, > some time ago I posted to comp.lang.scheme with the > following proposal of "define-curried" macro: > > (define-macro (define-curried signature . body) > (match signature > ((name args ...) > `(define-syntax ,name > (syntax-rules () > ((_ ,@args) > (begin ,@body)) > ,@(let loop ((args* args)) > (match args* > (() '()) > ((first ... last) > (cons `((_ ,@first #;...) > (lambda(,last)(,name ,@args*))) > (loop first #;...)))))))))) > > The idea was to expand, e.g. (define-curried (f a b c d) (list a b c > d)) to: > > (define-syntax f > (syntax-rules () > ((_ a b c d) > (begin (list a b c d))) > ((_ a b c) > (lambda(d) > (f a b c d))) > ((_ a b) > (lambda(c) > (f a b c))) > ((_ a) > (lambda(b) > (f a b))) > ((_) > (lambda(a) > (f a))))) > > I asked whether it would be possible to write that code using > syntax-rules only, but I received no answer, not even a reprimend. I > used that code to implement a quite convinient macro (actually that > urge was my inspiration): > > (define-curried (matches? pattern x) > (match x > (pattern #t) > (else #f))) > > so that I could write > > (filter (matches? (two elements)) some-list) > > Recently, I tried to write a nicer interface to string-match, that > would allow me to extract parenthesized subexpressions easily. My > first guess was this: > > (define-curried (string-matches pattern string) > ;;CAUTION: buggy version > (and-let* ((match-struct (string-match pattern string)) > (count (match:count match-struct))) > (map (lambda(n)(match:substring match-struct n)) > (iota (1- count) 1)))) > > and although it worked with a complete list of arguments, > (string-matches "([a-z])" "a") > ==> ("a") > it failed to curry properly > ((string-matches "([a-z])") "a") > ==> some strange error > > It turned out, that the "string" symbol doesn't get tied > with the lambda argument: > > (expand (string-matches "([a-z])")) > ==> > (lambda (string-12552) > (let ((match-struct-12557 (string-match "([a-z])" string))) > ;; the reason of our tears and despair is right here^^^ > (if match-struct-12557 > (let ((count-12561 (match:count match-struct-12557))) > (if count-12561 > (map (lambda (n-12564) > (match:substring match-struct-12557 n-12564)) > (iota (#{1-}# count-12561) 1)) > #f)) > #f))) > > This forced me to write another definition of string-matches > that doesn't use the and-let* macro and works as expected: > > (define-curried (string-matches pattern s) > (let ((match-struct (string-match pattern s))) > (if match-struct > (let ((count (match:count match-struct))) > (map (lambda(n)(match:substring match-struct n)) > (iota (1- count) 1))) > #f))) > > Nevertheless I am a little worried that either my macro, > or and-let* is not composable. Perhaps there's some wise > man here who knows what's going on. > > Best regards, > M.