• macro return

    From damien.mattei@gmail.com@21:1/5 to All on Sun Jun 27 16:01:51 2021
    hi,

    i wanted to create a macro that is used like a function definition and allow return using call/cc:

    (define-syntax def
    (syntax-rules (return)
    ((_ (name args ...) body body* ...)
    (define name (lambda (args ...)
    (call/cc (lambda (return) body body* ...)))))
    ((_ name expr) (define name expr))))

    unfortunaly i got error:

    scheme@(guile-user)> (def (test x) (cond ((= x 3) 7) ((= x 2) (return 5)) (else 3)))
    ;;; <stdin>:2:42: warning: possibly unbound variable `return' scheme@(guile-user)> (test 2)
    ice-9/boot-9.scm:1685:16: In procedure raise-exception:
    Unbound variable: return


    any idea?

    Damien

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Marc_Nieper=2DWi=C3=9Fkir@21:1/5 to damien...@gmail.com on Sun Jun 27 22:45:22 2021
    Hi Damien,

    first, a preliminary remark: that you have added the identifier `return' to the list of literals of the `syntax-rules' instance is useless; this would only be useful if `return' appeared in the patterns of the left-hand side of the `syntax-rules' rules.

    Now to the problem: When a `syntax-rules' macro writes its output, identifiers not coming from the macro call are "renamed" so that they don't interfere with identifiers bound at the macro use site by accident. This is called "macro hygiene". For example,

    (let ((return (lambda (x) 42)))
    (def (test) (return 52))
    (test))

    evaluates to 42.

    To write a macro like yours, you can either drop hygiene by injecting `return' in the syntactic environment of the macro call, or you can make `return' a syntax parameter.

    The first solution is:

    (define-syntax def
    (lambda (x)
    (syntax-case x ()
    ((k (name . arg*) body body* ...)
    (identifier? #'name)
    (with-syntax ((return (datum->syntax #'k 'return)))
    #'(define (name . arg*) (call/cc (lambda (return) body body* ...)))))
    ((_ name expr)
    (identifier? #'name)
    #'(define name expr)))))

    The second solution is hygienic but needs syntax parameters. You can find a full solution here: https://www.gnu.org/software/guile/manual/html_node/Syntax-Parameters.html.

    Note that the semantics are different. In the first solution, `return' is lexically bound; in the second solution, `return' is not rebound, but its meaning changes during the expansion of the procedure body. Moreover, in the first solution, `return' is
    an ordinary procedure (a continuation, to be more precise); in the second, it is a syntactic keyword.

    When the Scheme system has syntax parameters (like Guile), the second solution is probably the better one.

    Marc

    damien...@gmail.com schrieb am Montag, 28. Juni 2021 um 01:01:53 UTC+2:
    hi,

    i wanted to create a macro that is used like a function definition and allow return using call/cc:

    (define-syntax def
    (syntax-rules (return)
    ((_ (name args ...) body body* ...)
    (define name (lambda (args ...)
    (call/cc (lambda (return) body body* ...)))))
    ((_ name expr) (define name expr))))

    unfortunaly i got error:

    scheme@(guile-user)> (def (test x) (cond ((= x 3) 7) ((= x 2) (return 5)) (else 3)))
    ;;; <stdin>:2:42: warning: possibly unbound variable `return' scheme@(guile-user)> (test 2)
    ice-9/boot-9.scm:1685:16: In procedure raise-exception:
    Unbound variable: return


    any idea?

    Damien

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From damien.mattei@gmail.com@21:1/5 to marc....@gmail.com on Mon Jun 28 00:52:35 2021
    thank Marc

    i already use all that in the past ( https://github.com/damien-mattei/library-FunctProg/blob/master/syntactic-sugar.scm#L133 )
    but it was late and i forget it

    On Monday, June 28, 2021 at 7:45:24 AM UTC+2, marc....@gmail.com wrote:
    Hi Damien,

    first, a preliminary remark: that you have added the identifier `return' to the list of literals of the `syntax-rules' instance is useless; this would only be useful if `return' appeared in the patterns of the left-hand side of the `syntax-rules' rules.


    right i have tested the two case wit or without return added to the list of literals ,it does not change, and thereislittle litterature about the use of literals in syntax-rules

    Now to the problem: When a `syntax-rules' macro writes its output, identifiers not coming from the macro call are "renamed" so that they don't interfere with identifiers bound at the macro use site by accident. This is called "macro hygiene". For
    example,

    (let ((return (lambda (x) 42)))
    (def (test) (return 52))
    (test))

    evaluates to 42.

    To write a macro like yours, you can either drop hygiene by injecting `return' in the syntactic environment of the macro call, or you can make `return' a syntax parameter.

    The first solution is:

    (define-syntax def
    (lambda (x)
    (syntax-case x ()
    ((k (name . arg*) body body* ...)
    (identifier? #'name)
    (with-syntax ((return (datum->syntax #'k 'return)))
    #'(define (name . arg*) (call/cc (lambda (return) body body* ...)))))
    ((_ name expr)
    (identifier? #'name)
    #'(define name expr)))))

    The second solution is hygienic but needs syntax parameters. You can find a full solution here: https://www.gnu.org/software/guile/manual/html_node/Syntax-Parameters.html.

    Note that the semantics are different. In the first solution, `return' is lexically bound; in the second solution, `return' is not rebound, but its meaning changes during the expansion of the procedure body. Moreover, in the first solution, `return' is
    an ordinary procedure (a continuation, to be more precise); in the second, it is a syntactic keyword.

    When the Scheme system has syntax parameters (like Guile), the second solution is probably the better one.


    i will use the second solution,
    thanks again

    Damien

    Marc
    damien...@gmail.com schrieb am Montag, 28. Juni 2021 um 01:01:53 UTC+2:
    hi,

    i wanted to create a macro that is used like a function definition and allow return using call/cc:

    (define-syntax def
    (syntax-rules (return)
    ((_ (name args ...) body body* ...)
    (define name (lambda (args ...)
    (call/cc (lambda (return) body body* ...)))))
    ((_ name expr) (define name expr))))

    unfortunaly i got error:

    scheme@(guile-user)> (def (test x) (cond ((= x 3) 7) ((= x 2) (return 5)) (else 3)))
    ;;; <stdin>:2:42: warning: possibly unbound variable `return' scheme@(guile-user)> (test 2)
    ice-9/boot-9.scm:1685:16: In procedure raise-exception:
    Unbound variable: return


    any idea?

    Damien

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)