unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Syntax-rules generate symbol
@ 2013-09-09 16:19 Dmitry Bogatov
  2013-09-09 16:59 ` Panicz Maciej Godek
  2013-09-10 10:33 ` Ian Price
  0 siblings, 2 replies; 7+ messages in thread
From: Dmitry Bogatov @ 2013-09-09 16:19 UTC (permalink / raw)
  To: guile-user@gnu.org

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


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 <KAction@gnu.org>,
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.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

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

* Re: Syntax-rules generate symbol
  2013-09-09 16:19 Syntax-rules generate symbol Dmitry Bogatov
@ 2013-09-09 16:59 ` Panicz Maciej Godek
  2013-09-09 20:03   ` Taylan Ulrich B.
  2013-09-10 10:33 ` Ian Price
  1 sibling, 1 reply; 7+ messages in thread
From: Panicz Maciej Godek @ 2013-09-09 16:59 UTC (permalink / raw)
  To: Dmitry Bogatov; +Cc: guile-user@gnu.org

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

2013/9/9 Dmitry Bogatov <KAction@gnu.org>

>
> 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.

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

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

* Re: Syntax-rules generate symbol
  2013-09-09 16:59 ` Panicz Maciej Godek
@ 2013-09-09 20:03   ` Taylan Ulrich B.
  2013-09-10  6:11     ` Panicz Maciej Godek
  0 siblings, 1 reply; 7+ messages in thread
From: Taylan Ulrich B. @ 2013-09-09 20:03 UTC (permalink / raw)
  To: Panicz Maciej Godek; +Cc: guile-user@gnu.org, Dmitry Bogatov

Panicz Maciej Godek <godek.maciek@gmail.com> 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.



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

* Re: Syntax-rules generate symbol
  2013-09-09 20:03   ` Taylan Ulrich B.
@ 2013-09-10  6:11     ` Panicz Maciej Godek
  2013-09-10  9:16       ` Taylan Ulrich B.
  2013-09-10 10:38       ` Ian Price
  0 siblings, 2 replies; 7+ messages in thread
From: Panicz Maciej Godek @ 2013-09-10  6:11 UTC (permalink / raw)
  To: Taylan Ulrich B.; +Cc: guile-user@gnu.org, Dmitry Bogatov

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

2013/9/9 Taylan Ulrich B. <taylanbayirli@gmail.com>

>
> 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.

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

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

* Re: Syntax-rules generate symbol
  2013-09-10  6:11     ` Panicz Maciej Godek
@ 2013-09-10  9:16       ` Taylan Ulrich B.
  2013-09-10 10:38       ` Ian Price
  1 sibling, 0 replies; 7+ messages in thread
From: Taylan Ulrich B. @ 2013-09-10  9:16 UTC (permalink / raw)
  To: Panicz Maciej Godek; +Cc: guile-user@gnu.org, Dmitry Bogatov

Panicz Maciej Godek <godek.maciek@gmail.com> writes:

> 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.

Delimited/composable continuations don't have the efficiency problems of
call/cc (some of which are inherent, and not related to Guile, from what
I know), and I'd urge anyone to read the following critique of call/cc
revealing other problems with it as well. :)

http://okmij.org/ftp/continuations/against-callcc.html

Guile supports "prompts" as the primitive behind higher-level delimited
continuation operators, escape continuations, exceptions, etc.  The
relevant manual section is a nice read, though it might require more
than a quick skim:  (info "(guile) Prompts")

The compiler might be able to optimize some usages of call/cc into the
more efficient use of a delimited continuation, but after reading about
call/cc and delimited continuations, it becomes a rather blurry line
(IMO) which generalizes which, and on the meanwhile I find it most nice
to use the abstraction that expresses the actual idea as directly as
possible.  And since breaking from a loop or returning from a block are
inherently escape-only actions, I think it's actually nicer to use
`let/ec' for those cases even in terms of code clarity etc.



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

* Re: Syntax-rules generate symbol
  2013-09-09 16:19 Syntax-rules generate symbol Dmitry Bogatov
  2013-09-09 16:59 ` Panicz Maciej Godek
@ 2013-09-10 10:33 ` Ian Price
  1 sibling, 0 replies; 7+ messages in thread
From: Ian Price @ 2013-09-10 10:33 UTC (permalink / raw)
  To: Dmitry Bogatov; +Cc: guile-user@gnu.org

Dmitry Bogatov <KAction@gnu.org> writes:

> 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, it couldn't be simpler, just add an extra pattern that passes
in a dummy name. No (explicit) gensym needed.

(define-syntax for
  (syntax-rules (in => as)
    [(_ (pattern as var in list) exp ...)
     (for-each (lambda (var) (match var (pattern exp ...))) list)]
    [(_ (pattern in list) exp ...)
     (for (pattern as var in list) exp ...)]))

Now we get

scheme@(guile-user)> (for (a in '(1 2 3)) (pk a))

;;; (1)

;;; (2)

;;; (3)
scheme@(guile-user)> (for (a in '(1 2 3)) (pk var))
;;; <stdin>:52:21: warning: possibly unbound variable `var'
<unnamed port>:52:0: In procedure #<procedure a90f4d0 at <current input>:52:0 (var)>:
<unnamed port>:52:0: In procedure module-lookup: Unbound variable: var

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.

,expand (for (a in '(1 2 3)) (pk var))
$4 = (for-each
  (lambda (var-1)
    (let* ((v var-1)
           (failure
             (lambda ()
               (((@@ (ice-9 match) error)
                 'match
                 "no matching pattern"
                 v))))
           (a v))
      (pk var)))
  '(1 2 3))

Var is unbound as expected. Though this is not obvious if you use
,expand on an example that doesn't use 'var', since Guile tries to clean
up the names for readability.

The reason it's okay to just pass in the dummy is because of how
syntax-case and syntax-rules work. If a name is not passed explicitly
into the macro, and it is not a reference to a top-level function or
macro, then syntax-case or syntax-rules will rename it automatically.

I took the liberty of fixing up the indentation, and changing the use of
[] to a more idiomatic one, but there is still one obvious issue with
your macro. "exp ..." means 0 or more expressions. If you had intended
one or more, as is more usual in this type of macro, you'll want to say
so explicitly with something like "exp exps ...".

Cheers
-- 
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"



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

* Re: Syntax-rules generate symbol
  2013-09-10  6:11     ` Panicz Maciej Godek
  2013-09-10  9:16       ` Taylan Ulrich B.
@ 2013-09-10 10:38       ` Ian Price
  1 sibling, 0 replies; 7+ messages in thread
From: Ian Price @ 2013-09-10 10:38 UTC (permalink / raw)
  To: Panicz Maciej Godek; +Cc: guile-user@gnu.org

Panicz Maciej Godek <godek.maciek@gmail.com> writes:

> I assume that the main reason for using this is efficiency (rather
> than simplicity), because allegedly guile's continuations are rather
> inefficient.
Primarily, it's an efficiency hack, but you can also make a case that it
better if you can tell at a glance that the continuation will never be
stored, similar to how we have conventions for predicates and so forth.

> 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),
It is documented in section 13.5.1.

> 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.
Well, it can sometimes, but it's a hard analysis in general.

-- 
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"



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

end of thread, other threads:[~2013-09-10 10:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-09 16:19 Syntax-rules generate symbol Dmitry Bogatov
2013-09-09 16:59 ` Panicz Maciej Godek
2013-09-09 20:03   ` Taylan Ulrich B.
2013-09-10  6:11     ` Panicz Maciej Godek
2013-09-10  9:16       ` Taylan Ulrich B.
2013-09-10 10:38       ` Ian Price
2013-09-10 10:33 ` 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).