Syntax-rules generate symbol
Hello! Here is my implementation of for loop. I found lisp really extremely flexible, but there is one problem --- more often then not I do not need var part, so I do not care how it would be named --- all I care is that it will not shadow any other bindings. I think I can do it(did not tryed it) with `define-macro` and uninterned symbols, but it mean give up beauty of syntax-rules. Masters of syntax-rules and syntax-case, please give me peace of advice. (define-syntax for (syntax-rules (in => as) ([_ (pattern as var in list) exp ...] [for-each (lambda (var) (match var (pattern exp ...))) list]))) PS. Please, keep in CC, I am not subscribed. -- Best regards, Dmitry Bogatov , Free Software supporter and netiquette guardian. git clone git://kaction.name/rc-files.git --depth 1 GPG: 54B7F00D Html mail and proprietary format attachments are forwarded to /dev/null. pgpOAGXg6Eqpa.pgp Description: PGP signature
Re: Syntax-rules generate symbol
2013/9/9 Dmitry Bogatov > > Hello! > > Here is my implementation of for loop. I found lisp really extremely > flexible, but there is one problem --- more often then not I do not need > var part, so I do not care how it would be named --- all I care is that > it will not shadow any other bindings. > > I think I can do it(did not tryed it) with `define-macro` and uninterned > symbols, but it mean give up beauty of syntax-rules. > > Masters of syntax-rules and syntax-case, please give me peace of advice. > > (define-syntax for > (syntax-rules (in => as) > ([_ (pattern as var in list) exp ...] > [for-each (lambda (var) (match var (pattern exp ...))) list]))) Actually, the whole point of hygienic (syntax-rules) macros is that you don't need to worry about the names of variables. I often use a very similar python-like for loop macro in my projects: http://hg.gnu.org.ua/hgweb/slayer/file/554a63bd3c6c/guile-modules/extra/common.scm#l420 That code works just perfectly fine. IMO a bigger problem would be to break the referential transparency, so e.g. the definition like (define-syntax for (syntax-rules (in => break) ((_ pattern in list body ...) (call/cc (lambda(break) (for-each (match-lambda pattern body ...) list)) won't work as one might expect (i.e. you won't be able to write (break) inside a loop, because the "break" label gets renamed). The workaround is possible somehow, but I never had time to figure that out, so currently I just don't do breaks ;] Best regards, M.
Re: and-let* is not composable?
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-cur
and-let* is not composable?
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.
Re: Syntax-rules generate symbol
Panicz Maciej Godek writes: > Actually, the whole point of hygienic (syntax-rules) macros > is that you don't need to worry about the names of variables. > > I often use a very similar python-like for loop macro in my projects: > > http://hg.gnu.org.ua/hgweb/slayer/file/554a63bd3c6c/guile-modules/extra/common. > scm#l420 > > That code works just perfectly fine. > > IMO a bigger problem would be to break the referential > transparency, so e.g. the definition like > > (define-syntax for > (syntax-rules (in => break) > ((_ pattern in list body ...) > (call/cc (lambda(break) > (for-each (match-lambda pattern body ...) list)) > > won't work as one might expect (i.e. you won't be able to write > (break) inside a loop, because the "break" label gets renamed). > The workaround is possible somehow, but I never had time to > figure that out, so currently I just don't do breaks ;] > > Best regards, > M. For anyone who didn't know, "breaking" to arbitrary places is made simple (and efficient) with `let/ec' from the module (ice-9 control), a wrapper around `call-with-escape-continuation': (let/ec break (display "foo\n") (break) (display "bar\n")) displays only foo. One can return any number of values of course: (let-values (((foo bar baz) (let/ec return (display "what should I return?\n") (return 1 2 3 (+ foo bar baz)) ;=> 6 (`let-values' is in SRFI 11.) An "escape" continuation cannot be "re-entered" after it returns once, making the following usage invalid, but thus the implementation very efficient: (let ((re-enter #f)) (display (let/ec display-this (set! re-enter display-this) (display-this "foo\n))) (re-enter "infinite foos!\n")) If we used call/cc, that would loop infinitely displaying "infinite foos!" (after the first "foo"), but with the escape continuation we just get an error after displaying the first "foo", because once we return from the escape continuation we can't call it anymore even if we store it somewhere.
Re: and-let* is not composable?
Stefan Israelsson Tampe writes: > (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! The problem is one that occurs when hygienic and non-hygienic macros are mixed. Here, and-let* is the non-hygienic one. Basically, in a hygienic macro, you carry around a bunch of context to allow you to refer to the right variable names. Then defmacro comes along, strips all that away, and uses the raw symbol names. We can fix and-let* to be hygienic, that's pretty easy, but I'm not sure what you can do about this in general. It's not like you can pass in the gensymed name, because that will break the way people who for some reason still right defmacros expect them to work. Dunno, maybe I'm just missing some insight here. -- Ian Price -- shift-reset.com "Programming is like pinball. The reward for doing it well is the opportunity to do it again" - from "The Wizardy Compiled"
is (web client) ready for use even for the simplest task?
(use-modules (web client)) (http-post "http://www.google.com/";) the POST request is sent without the Content-Length header OK, let's add something to the body (http-post "http://www.google.com/"; #:body "") Howcome the request now becomes an http GET request: GET / HTTP/1.1 Content-Type: text/plain;charset=utf-8 Host: www.google.com Connection: close This is really ridiculous.
Re: is (web client) ready for use even for the simplest task?
I have used (web client) in both guile-oauth (with a twitter client example) and guile-xmlrpc. So, yes, I think it is ready for the simplest task and much more. This doesn't mean it might have bugs, as every software does. Aleix On Mon, Sep 9, 2013 at 9:13 PM, Darren Hoo wrote: > > (use-modules (web client)) > > (http-post "http://www.google.com/";) > > the POST request is sent without the Content-Length header > > OK, let's add something to the body > > (http-post "http://www.google.com/"; #:body "") > > Howcome the request now becomes an http GET request: > > GET / HTTP/1.1 > Content-Type: text/plain;charset=utf-8 > Host: www.google.com > Connection: close > > This is really ridiculous. > >
Re: Syntax-rules generate symbol
2013/9/9 Taylan Ulrich B. > > For anyone who didn't know, "breaking" to arbitrary places is made > simple (and efficient) with `let/ec' from the module (ice-9 control), a > wrapper around `call-with-escape-continuation': > [...] I assume that the main reason for using this is efficiency (rather than simplicity), because allegedly guile's continuations are rather inefficient. On one hand, it's good to know that (and would be even better to be able to find it out by skimming section 6.13 of the manual), but on the other it would be nicer if the compiler could trace the usages of continuations and figure out whether a given one is ever being re-entered, and optimize accordingly.
Re: is (web client) ready for use even for the simplest task?
This bug had a fix but didn't push, I think it's in master now. On Tue, 2013-09-10 at 12:13 +0800, Darren Hoo wrote: > (use-modules (web client)) > > (http-post "http://www.google.com/";) > > the POST request is sent without the Content-Length header > > OK, let's add something to the body > > (http-post "http://www.google.com/"; #:body "") > > Howcome the request now becomes an http GET request: > > GET / HTTP/1.1 > Content-Type: text/plain;charset=utf-8 > Host: www.google.com > Connection: close > > This is really ridiculous. > >