Syntax-rules generate symbol

2013-09-09 Thread 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])))

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-09-09 Thread Panicz Maciej Godek
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?

2013-09-09 Thread Stefan Israelsson Tampe
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?

2013-09-09 Thread Panicz Maciej Godek
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

2013-09-09 Thread Taylan Ulrich B.
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?

2013-09-09 Thread Ian Price
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?

2013-09-09 Thread Darren Hoo

(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?

2013-09-09 Thread Aleix Conchillo FlaquƩ
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-09-09 Thread Panicz Maciej Godek
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?

2013-09-09 Thread Nala Ginrut
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.
> 
>