unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* and-let* is not composable?
@ 2013-09-09 17:35 Panicz Maciej Godek
  2013-09-09 20:26 ` Stefan Israelsson Tampe
  2013-09-10 17:57 ` Ian Price
  0 siblings, 2 replies; 14+ messages in thread
From: Panicz Maciej Godek @ 2013-09-09 17:35 UTC (permalink / raw)
  To: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 3025 bytes --]

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.

[-- Attachment #2: Type: text/html, Size: 8543 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-11-02 19:01 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-09 17:35 and-let* is not composable? Panicz Maciej Godek
2013-09-09 20:26 ` Stefan Israelsson Tampe
2013-09-09 21:34   ` Ian Price
2013-09-10 13:42     ` Stefan Israelsson Tampe
2013-09-10 13:51       ` Ian Price
2013-11-02  2:39     ` Ian Price
2013-11-02 19:01       ` Ian Price
2013-09-10 17:57 ` Ian Price
2013-09-11 12:25   ` Panicz Maciej Godek
2013-09-11 14:05     ` Ian Price
2013-09-13 18:40       ` Panicz Maciej Godek
2013-09-14  8:19         ` Stefan Israelsson Tampe
2013-10-04 22:27       ` Panicz Maciej Godek
2013-10-05  8:00         ` Ian Price

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).