From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Panicz Maciej Godek Newsgroups: gmane.lisp.guile.user Subject: and-let* is not composable? Date: Mon, 9 Sep 2013 19:35:16 +0200 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=bcaec5016625bd177a04e5f6cf6e X-Trace: ger.gmane.org 1378748130 16402 80.91.229.3 (9 Sep 2013 17:35:30 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 9 Sep 2013 17:35:30 +0000 (UTC) To: "guile-user@gnu.org" Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Mon Sep 09 19:35:33 2013 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VJ5N7-0008Lz-79 for guile-user@m.gmane.org; Mon, 09 Sep 2013 19:35:33 +0200 Original-Received: from localhost ([::1]:52977 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJ5N6-0003SK-Od for guile-user@m.gmane.org; Mon, 09 Sep 2013 13:35:32 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37269) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJ5Mt-0003QT-D4 for guile-user@gnu.org; Mon, 09 Sep 2013 13:35:24 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VJ5Mr-0002Xk-Mj for guile-user@gnu.org; Mon, 09 Sep 2013 13:35:19 -0400 Original-Received: from mail-ve0-x22e.google.com ([2607:f8b0:400c:c01::22e]:44124) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VJ5Mr-0002XO-Gx for guile-user@gnu.org; Mon, 09 Sep 2013 13:35:17 -0400 Original-Received: by mail-ve0-f174.google.com with SMTP id jy13so3717003veb.33 for ; Mon, 09 Sep 2013 10:35:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=pzYG3tbyXZql+LTPKzvFM/O8yvb1br2t+cjNTSPqy6E=; b=eEINduWmEieEPxKcb4wyVNl/GjK+R1if2NxUhx+KplmZuFVRaHcIo0swk0qyp/Oojm N9JgiuCyOW9jTbrbcQB94uo8h/tcAIDiGe8HbPsmScN+L0Cb55nhhC/Kpp8/UuCu4vUU dDNzuaPUp21nRCO6gGJiQoqiQuLhU68JTY1cR2KK9RyisSTDhPvOKZv+lJtFbIYFbfPV rvit8IstkFyY+yzOJgECrG/TCp2tK0TDfZ/RNA0nSimiT9A8dh2wAbynAAdidgab6HGE 6GcdzycTrKruDGHxCug7P719xAdNbal5xlKPxTGQd1LcxkWJfGIRJE7mKMokyEJnYWOE ARGw== X-Received: by 10.52.74.100 with SMTP id s4mr947221vdv.35.1378748116830; Mon, 09 Sep 2013 10:35:16 -0700 (PDT) Original-Received: by 10.221.45.135 with HTTP; Mon, 9 Sep 2013 10:35:16 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400c:c01::22e X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:10774 Archived-At: --bcaec5016625bd177a04e5f6cf6e Content-Type: text/plain; charset=ISO-8859-1 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. --bcaec5016625bd177a04e5f6cf6e Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Hi,
some time ago I posted to comp.lang.scheme with th= e
following proposal of "define-curried" macro:

(define-macro (define-curried signature . body)
=A0 (match signature
=A0 =A0 ((name args ...)
=A0 = =A0 =A0`(define-syntax ,name
=A0 =A0 =A0 =A0 (syntax-rules ()
=A0 =A0 =A0 =A0 =A0 ((_ ,@args)
=A0 =A0 =A0 =A0 =A0 =A0(be= gin ,@body))
=A0 =A0 =A0 =A0 =A0 ,@(let loop ((args* args))
=A0 =A0 =A0 =A0 =A0 =A0 =A0 (match args*
=A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 (() '())
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ((first= ... last)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(cons `((_ ,@first = #;...)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(lambda= (,last)(,name ,@args*)))
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(loop first #;...))))))= ))))

The idea was to expand, e.g. (define-curried= (f a b c d) (list a b c d))
= to:=A0

<= span style=3D"font-family:Arial,Helvetica,sans-serif;font-size:13px">(defin= e-syntax f=A0
=A0 (= syntax-rules ()=A0
=A0 =A0 ((_ a b c d)=A0
=A0 = =A0 =A0(begin (list a b c d)))=A0
=A0 =A0 ((_ a b c)=A0
=A0 = =A0 =A0(lambda(d)=A0
=A0 =A0 =A0 =A0(f a b c d)))=A0
=A0 = =A0 ((_ a b)=A0
=A0 =A0 =A0(lambda(c)=A0
=A0 = =A0 =A0 =A0(f a b c)))=A0
=A0 =A0 ((_ a)=A0
=A0 = =A0 =A0(lambda(b)=A0
=A0 =A0 =A0 =A0(f a b)))=A0
=A0 = =A0 ((_)=A0
=A0 =A0 =A0(lambda(a)=A0
=A0 = =A0 =A0 =A0(f a)))))=A0

I asked whether = it would be possible to write that code using syntax-rules only, but I rece= ived no answer, not even a reprimend. I used that code to implement a quite= convinient macro (actually that urge was my inspiration):
=
(def= ine-curried (matches? pattern x)
=A0 (match x
=A0 =A0 (pattern #t)
=A0 =A0 (else #f)))=

so that I could write

(filt= er (matches? (two elements)) some-list)

Recently, I tried to write a nicer interface to string-mat= ch, that would allow me to extract parenthesized subexpressions easily. My = first guess was this:

(define-cur= ried (string-matches pattern string)
=A0 ;;CAUTION: buggy version
=A0 (and-let* ((match-struct (string-= match pattern string))
=A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 (count (match:count match-struct)))
=A0 =A0 =A0(map (lambda(n)(match:substring ma= tch-struct n))
=A0 =A0 =A0 =A0 (iota (1- = count) 1))))

and although it worked with a complete list of arguments,
(string-matches "([a-= z])" "a")
=3D=3D> ("a")
it failed to curry properly
((string-matche= s "([a-z])") "a")
=3D=3D> some strange error

It turned out, that the "strin= g" symbol doesn't get tied
with the lambda argument:

(expand (string-matches "([a-z= ])"))
=3D= =3D>
(lambda (string-12552= )
=A0 (let ((match-struct-12557 (string-match "([a-z])"= string)))
;; the reason of our tears and despair is right here^^= ^
=A0 =A0 (if match-struct-12557
=A0 =A0 =A0 =A0 (let ((count-= 12561 (match:count match-struct-12557)))
=A0 =A0 =A0 =A0 =A0 (if = count-12561
=A0 =A0 =A0 =A0 =A0 =A0 =A0 (map (lambda (n-12564)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(match:substring match-s= truct-12557 n-12564))
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(iota (#{1-}# count-12561) 1))<= /div>
=A0 =A0 =A0 =A0 =A0 =A0 =A0 #f))
=A0 =A0 =A0 =A0 #f)))<= /div>

This forced me to= write another definition of string-matches
that doesn't use the a= nd-let* macro and works as expected:

(define-curried (string-matches pattern s)
=A0 (let ((match-struc= t (string-match pattern s)))
=A0 =A0 (if match-struct
<= span class=3D"" style=3D"white-space:pre"> (let ((count (match:count= match-struct)))
=A0 =A0 =A0 =A0 =A0 (map (lambda(n)(match:substring match-struct n))
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(iota (1- count) 1)))
=A0= =A0 =A0 =A0 #f)))

Nevertheless I am a little worr= ied that either my macro,
or and-let* is not composable. Perhaps there's some wise
man here who knows what's going on.

Best rega= rds,
M.

--bcaec5016625bd177a04e5f6cf6e--