* return macro @ 2021-06-27 23:10 Damien Mattei 2021-06-28 1:15 ` Taylan Kammer 0 siblings, 1 reply; 8+ messages in thread From: Damien Mattei @ 2021-06-27 23:10 UTC (permalink / raw) To: guile-user 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 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro 2021-06-27 23:10 return macro Damien Mattei @ 2021-06-28 1:15 ` Taylan Kammer 2021-06-28 8:53 ` Damien Mattei 2021-09-30 3:37 ` adriano 0 siblings, 2 replies; 8+ messages in thread From: Taylan Kammer @ 2021-06-28 1:15 UTC (permalink / raw) To: Damien Mattei, guile-user On 28.06.2021 01:10, Damien Mattei wrote: > 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? Hi Damien, This is because of the "hygiene" rule of Scheme, where the notion of "lexical scope" is taken very seriously: for an identifier to be bound, it must be visible in the lexical (textual) surroundings where it has been bound. So for instance, in the following example code: (def (test x) (cond ((= x 3) (return 7)) ((= x 2) (return 5)))) We can't see a binding for "return" anywhere in the text, therefore it cannot be bound. This is good "default" behavior because it makes code more flexible and easier to understand. An easy way of overcoming this issue is to let the user explicitly name the return identifier however they like: (define-syntax def (syntax-rules () ((_ (name ret arg ...) body body* ...) (define (name arg ...) (call/cc (lambda (ret) body body* ...)))))) Now you could define: (def (test return x) (cond ((= x 3) (return 7)) ((= x 2) (return 5)))) Or for instance: (def (test blubba x) (cond ((= x 3) (blubba 7)) ((= x 2) (blubba 5)))) However, sometimes you're sure that you want to make an implicit binding for an identifier, and for those cases you need to write an "unhygienic" macro which can be achieved with the more complex macro system "syntax-case". Here's how your desired macro could be defined. I will use identifiers like "<foo>" just for easier readability; they don't have any special meaning: (define-syntax def (lambda (stx) (syntax-case stx () ((_ (<name> <arg> ...) <body> <body>* ...) (let ((ret-id (datum->syntax stx 'return))) #`(define (<name> <arg> ...) (call/cc (lambda (#,ret-id) <body> <body>* ...)))))))) There's a few things here to take note of: - Unlike with syntax-rules, the syntax-case is contained in a lambda which takes a single argument: a "syntax object" which is passed to syntax-case - Unlike with syntax-rules, the "body" of the macro (where it begins with a 'let') is not immediately part of the generated code; that 'let' is actually executed during compile-time. The body of the macro must result in an object of the type "syntax object" that represents the generated code. - You see that I define a variable called "ret-id" which I bind to the result of the expression: (datum->syntax stx 'return) which means "create a syntax object in the same lexical environment as stx, and is represented by the symbol 'return'." - The actual code generation begins within the #`(...) which is a shorthand for (quasisyntax (...)) just like '(...) is short for (quote (...)). The result of a quasisyntax expression is a syntax object. Basically, it's the most convenient way of creating a syntax object, but like syntax-rules it's also hygienic by default and you need to insert "unhygienic" syntax objects into it explicitly. - Within the quasisyntax, I use #,ret-id which is short for (unsyntax ret-id) to inject the unhygienic syntax object that holds the symbol 'return' into the generated code. For someone used to macros in the Common Lisp or Elisp style, this may seem over-complicated. It's the cost of the "hygienic by default" behavior. By the way I assume that you're just toying around with the language to learn. If you were thinking of using a 'def' macro like this in real code, I would discourage it because there's already a built-in mechanism that allows the programmer something very similar, called 'let/ec': (import (ice-9 control)) (define (test x) (let/ec return (cond ((= x 3) (return 7)) ((= x 2) (return 5))))) As you see it allows you to define a "return" keyword anywhere, and it doesn't need to be part of a function definition, it can appear anywhere. -- Taylan ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro 2021-06-28 1:15 ` Taylan Kammer @ 2021-06-28 8:53 ` Damien Mattei 2021-09-30 3:37 ` adriano 1 sibling, 0 replies; 8+ messages in thread From: Damien Mattei @ 2021-06-28 8:53 UTC (permalink / raw) To: Taylan Kammer; +Cc: guile-user thank Taylan 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 ,past 1h00 and i forget it, and it was not compatible with R5RS thank for your long and clear explainations... i did not use let/ec because the problem was not with let/ec or call/cc but with the macro hygiene and i wanted to stay compatible with other scheme,let/ec should be guile only and i suppose let/ec made with call/cc . regards, damien On Mon, Jun 28, 2021 at 3:15 AM Taylan Kammer <taylan.kammer@gmail.com> wrote: > On 28.06.2021 01:10, Damien Mattei wrote: > > 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? > > Hi Damien, > > This is because of the "hygiene" rule of Scheme, where the notion of > "lexical > scope" is taken very seriously: for an identifier to be bound, it must be > visible in the lexical (textual) surroundings where it has been bound. > > So for instance, in the following example code: > > (def (test x) > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5)))) > > We can't see a binding for "return" anywhere in the text, therefore it > cannot > be bound. > > This is good "default" behavior because it makes code more flexible and > easier > to understand. > > An easy way of overcoming this issue is to let the user explicitly name the > return identifier however they like: > > (define-syntax def > (syntax-rules () > ((_ (name ret arg ...) body body* ...) > (define (name arg ...) > (call/cc (lambda (ret) body body* ...)))))) > > Now you could define: > > (def (test return x) > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5)))) > > Or for instance: > > (def (test blubba x) > (cond > ((= x 3) (blubba 7)) > ((= x 2) (blubba 5)))) > > However, sometimes you're sure that you want to make an implicit binding > for > an identifier, and for those cases you need to write an "unhygienic" macro > which can be achieved with the more complex macro system "syntax-case". > > Here's how your desired macro could be defined. I will use identifiers > like > "<foo>" just for easier readability; they don't have any special meaning: > > (define-syntax def > (lambda (stx) > (syntax-case stx () > ((_ (<name> <arg> ...) <body> <body>* ...) > (let ((ret-id (datum->syntax stx 'return))) > #`(define (<name> <arg> ...) > (call/cc (lambda (#,ret-id) <body> <body>* ...)))))))) > > There's a few things here to take note of: > > - Unlike with syntax-rules, the syntax-case is contained in a lambda which > takes a single argument: a "syntax object" which is passed to syntax-case > > - Unlike with syntax-rules, the "body" of the macro (where it begins with a > 'let') is not immediately part of the generated code; that 'let' is > actually > executed during compile-time. The body of the macro must result in an > object of the type "syntax object" that represents the generated code. > > - You see that I define a variable called "ret-id" which I bind to the > result > of the expression: > > (datum->syntax stx 'return) > > which means "create a syntax object in the same lexical environment as > stx, > and is represented by the symbol 'return'." > > - The actual code generation begins within the #`(...) which is a shorthand > for (quasisyntax (...)) just like '(...) is short for (quote (...)). The > result of a quasisyntax expression is a syntax object. Basically, it's > the > most convenient way of creating a syntax object, but like syntax-rules > it's > also hygienic by default and you need to insert "unhygienic" syntax > objects > into it explicitly. > > - Within the quasisyntax, I use #,ret-id which is short for (unsyntax > ret-id) > to inject the unhygienic syntax object that holds the symbol 'return' > into > the generated code. > > For someone used to macros in the Common Lisp or Elisp style, this may seem > over-complicated. It's the cost of the "hygienic by default" behavior. > > By the way I assume that you're just toying around with the language to > learn. > If you were thinking of using a 'def' macro like this in real code, I would > discourage it because there's already a built-in mechanism that allows the > programmer something very similar, called 'let/ec': > > (import (ice-9 control)) > > (define (test x) > (let/ec return > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5))))) > > As you see it allows you to define a "return" keyword anywhere, and it > doesn't need to be part of a function definition, it can appear anywhere. > > -- > Taylan > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro 2021-06-28 1:15 ` Taylan Kammer 2021-06-28 8:53 ` Damien Mattei @ 2021-09-30 3:37 ` adriano 2021-09-30 8:46 ` Damien Mattei 1 sibling, 1 reply; 8+ messages in thread From: adriano @ 2021-09-30 3:37 UTC (permalink / raw) To: guile-user Il giorno lun, 28/06/2021 alle 03.15 +0200, Taylan Kammer ha scritto: > On 28.06.2021 01:10, Damien Mattei wrote: > > 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? > > Hi Damien, > > This is because of the "hygiene" rule of Scheme, where the notion of > "lexical > scope" is taken very seriously: for an identifier to be bound, it > must be > visible in the lexical (textual) surroundings where it has been > bound. > > So for instance, in the following example code: > > (def (test x) > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5)))) > > We can't see a binding for "return" anywhere in the text, therefore > it cannot > be bound. > > This is good "default" behavior because it makes code more flexible > and easier > to understand. > > An easy way of overcoming this issue is to let the user explicitly > name the > return identifier however they like: > > (define-syntax def > (syntax-rules () > ((_ (name ret arg ...) body body* ...) > (define (name arg ...) > (call/cc (lambda (ret) body body* ...)))))) > > Now you could define: > > (def (test return x) > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5)))) > > Or for instance: > > (def (test blubba x) > (cond > ((= x 3) (blubba 7)) > ((= x 2) (blubba 5)))) > > However, sometimes you're sure that you want to make an implicit > binding for > an identifier, and for those cases you need to write an "unhygienic" > macro > which can be achieved with the more complex macro system "syntax- > case". > > Here's how your desired macro could be defined. I will use > identifiers like > "<foo>" just for easier readability; they don't have any special > meaning: > > (define-syntax def > (lambda (stx) > (syntax-case stx () > ((_ (<name> <arg> ...) <body> <body>* ...) > (let ((ret-id (datum->syntax stx 'return))) > #`(define (<name> <arg> ...) > (call/cc (lambda (#,ret-id) <body> <body>* ...)))))))) > > There's a few things here to take note of: > > - Unlike with syntax-rules, the syntax-case is contained in a lambda > which > takes a single argument: a "syntax object" which is passed to > syntax-case > > - Unlike with syntax-rules, the "body" of the macro (where it begins > with a > 'let') is not immediately part of the generated code; that 'let' is > actually > executed during compile-time. The body of the macro must result in > an > object of the type "syntax object" that represents the generated > code. > > - You see that I define a variable called "ret-id" which I bind to > the result > of the expression: > > (datum->syntax stx 'return) > > which means "create a syntax object in the same lexical environment > as stx, > and is represented by the symbol 'return'." > > - The actual code generation begins within the #`(...) which is a > shorthand > for (quasisyntax (...)) just like '(...) is short for (quote > (...)). The > result of a quasisyntax expression is a syntax object. Basically, > it's the > most convenient way of creating a syntax object, but like syntax- > rules it's > also hygienic by default and you need to insert "unhygienic" syntax > objects > into it explicitly. > > - Within the quasisyntax, I use #,ret-id which is short for (unsyntax > ret-id) > to inject the unhygienic syntax object that holds the symbol > 'return' into > the generated code. > > For someone used to macros in the Common Lisp or Elisp style, this > may seem > over-complicated. It's the cost of the "hygienic by default" > behavior. > > By the way I assume that you're just toying around with the language > to learn. > If you were thinking of using a 'def' macro like this in real code, I > would > discourage it because there's already a built-in mechanism that > allows the > programmer something very similar, called 'let/ec': > > (import (ice-9 control)) > > (define (test x) > (let/ec return > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5))))) What does this return (defined with let/ec) do ? In the orevious versions I could see the call to call/cc so I could (somewhat) figure out the "jump" imlpied by calling return But in this last case, where is the return behaviour defined ? ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro 2021-09-30 3:37 ` adriano @ 2021-09-30 8:46 ` Damien Mattei 2021-09-30 9:18 ` Stefan Israelsson Tampe 0 siblings, 1 reply; 8+ messages in thread From: Damien Mattei @ 2021-09-30 8:46 UTC (permalink / raw) To: adriano; +Cc: guile-user i do not remember well the technic of this commented code, in this case note that it is 'break' keyword that cause the current continuation being called and escaping from the loop to the continuing code... there is no 'return' here but 'break'. Damien On Thu, Sep 30, 2021 at 5:38 AM adriano <randomlooser@riseup.net> wrote: > Il giorno lun, 28/06/2021 alle 03.15 +0200, Taylan Kammer ha scritto: > > On 28.06.2021 01:10, Damien Mattei wrote: > > > 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? > > > > Hi Damien, > > > > This is because of the "hygiene" rule of Scheme, where the notion of > > "lexical > > scope" is taken very seriously: for an identifier to be bound, it > > must be > > visible in the lexical (textual) surroundings where it has been > > bound. > > > > So for instance, in the following example code: > > > > (def (test x) > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5)))) > > > > We can't see a binding for "return" anywhere in the text, therefore > > it cannot > > be bound. > > > > This is good "default" behavior because it makes code more flexible > > and easier > > to understand. > > > > An easy way of overcoming this issue is to let the user explicitly > > name the > > return identifier however they like: > > > > (define-syntax def > > (syntax-rules () > > ((_ (name ret arg ...) body body* ...) > > (define (name arg ...) > > (call/cc (lambda (ret) body body* ...)))))) > > > > Now you could define: > > > > (def (test return x) > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5)))) > > > > Or for instance: > > > > (def (test blubba x) > > (cond > > ((= x 3) (blubba 7)) > > ((= x 2) (blubba 5)))) > > > > However, sometimes you're sure that you want to make an implicit > > binding for > > an identifier, and for those cases you need to write an "unhygienic" > > macro > > which can be achieved with the more complex macro system "syntax- > > case". > > > > Here's how your desired macro could be defined. I will use > > identifiers like > > "<foo>" just for easier readability; they don't have any special > > meaning: > > > > (define-syntax def > > (lambda (stx) > > (syntax-case stx () > > ((_ (<name> <arg> ...) <body> <body>* ...) > > (let ((ret-id (datum->syntax stx 'return))) > > #`(define (<name> <arg> ...) > > (call/cc (lambda (#,ret-id) <body> <body>* ...)))))))) > > > > There's a few things here to take note of: > > > > - Unlike with syntax-rules, the syntax-case is contained in a lambda > > which > > takes a single argument: a "syntax object" which is passed to > > syntax-case > > > > - Unlike with syntax-rules, the "body" of the macro (where it begins > > with a > > 'let') is not immediately part of the generated code; that 'let' is > > actually > > executed during compile-time. The body of the macro must result in > > an > > object of the type "syntax object" that represents the generated > > code. > > > > - You see that I define a variable called "ret-id" which I bind to > > the result > > of the expression: > > > > (datum->syntax stx 'return) > > > > which means "create a syntax object in the same lexical environment > > as stx, > > and is represented by the symbol 'return'." > > > > - The actual code generation begins within the #`(...) which is a > > shorthand > > for (quasisyntax (...)) just like '(...) is short for (quote > > (...)). The > > result of a quasisyntax expression is a syntax object. Basically, > > it's the > > most convenient way of creating a syntax object, but like syntax- > > rules it's > > also hygienic by default and you need to insert "unhygienic" syntax > > objects > > into it explicitly. > > > > - Within the quasisyntax, I use #,ret-id which is short for (unsyntax > > ret-id) > > to inject the unhygienic syntax object that holds the symbol > > 'return' into > > the generated code. > > > > For someone used to macros in the Common Lisp or Elisp style, this > > may seem > > over-complicated. It's the cost of the "hygienic by default" > > behavior. > > > > By the way I assume that you're just toying around with the language > > to learn. > > If you were thinking of using a 'def' macro like this in real code, I > > would > > discourage it because there's already a built-in mechanism that > > allows the > > programmer something very similar, called 'let/ec': > > > > (import (ice-9 control)) > > > > (define (test x) > > (let/ec return > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5))))) > > > > What does this return (defined with let/ec) do ? > > In the orevious versions I could see the call to call/cc so I could > (somewhat) figure out the "jump" imlpied by calling return > > But in this last case, where is the return behaviour defined ? > > > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro 2021-09-30 8:46 ` Damien Mattei @ 2021-09-30 9:18 ` Stefan Israelsson Tampe 0 siblings, 0 replies; 8+ messages in thread From: Stefan Israelsson Tampe @ 2021-09-30 9:18 UTC (permalink / raw) To: Damien Mattei; +Cc: guile-user used write a lambda using it prepending a ,opt and you will see what the macros expand to like ,opt (lambda (x) (let/ec ret (when x (ret x)) (+ x x))) On Thu, Sep 30, 2021 at 10:46 AM Damien Mattei <damien.mattei@gmail.com> wrote: > i do not remember well the technic of this commented code, in this case > note that it is 'break' keyword that cause the current continuation being > called and escaping from the loop to the continuing code... > there is no 'return' here but 'break'. > Damien > > On Thu, Sep 30, 2021 at 5:38 AM adriano <randomlooser@riseup.net> wrote: > > > Il giorno lun, 28/06/2021 alle 03.15 +0200, Taylan Kammer ha scritto: > > > On 28.06.2021 01:10, Damien Mattei wrote: > > > > 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? > > > > > > Hi Damien, > > > > > > This is because of the "hygiene" rule of Scheme, where the notion of > > > "lexical > > > scope" is taken very seriously: for an identifier to be bound, it > > > must be > > > visible in the lexical (textual) surroundings where it has been > > > bound. > > > > > > So for instance, in the following example code: > > > > > > (def (test x) > > > (cond > > > ((= x 3) (return 7)) > > > ((= x 2) (return 5)))) > > > > > > We can't see a binding for "return" anywhere in the text, therefore > > > it cannot > > > be bound. > > > > > > This is good "default" behavior because it makes code more flexible > > > and easier > > > to understand. > > > > > > An easy way of overcoming this issue is to let the user explicitly > > > name the > > > return identifier however they like: > > > > > > (define-syntax def > > > (syntax-rules () > > > ((_ (name ret arg ...) body body* ...) > > > (define (name arg ...) > > > (call/cc (lambda (ret) body body* ...)))))) > > > > > > Now you could define: > > > > > > (def (test return x) > > > (cond > > > ((= x 3) (return 7)) > > > ((= x 2) (return 5)))) > > > > > > Or for instance: > > > > > > (def (test blubba x) > > > (cond > > > ((= x 3) (blubba 7)) > > > ((= x 2) (blubba 5)))) > > > > > > However, sometimes you're sure that you want to make an implicit > > > binding for > > > an identifier, and for those cases you need to write an "unhygienic" > > > macro > > > which can be achieved with the more complex macro system "syntax- > > > case". > > > > > > Here's how your desired macro could be defined. I will use > > > identifiers like > > > "<foo>" just for easier readability; they don't have any special > > > meaning: > > > > > > (define-syntax def > > > (lambda (stx) > > > (syntax-case stx () > > > ((_ (<name> <arg> ...) <body> <body>* ...) > > > (let ((ret-id (datum->syntax stx 'return))) > > > #`(define (<name> <arg> ...) > > > (call/cc (lambda (#,ret-id) <body> <body>* ...)))))))) > > > > > > There's a few things here to take note of: > > > > > > - Unlike with syntax-rules, the syntax-case is contained in a lambda > > > which > > > takes a single argument: a "syntax object" which is passed to > > > syntax-case > > > > > > - Unlike with syntax-rules, the "body" of the macro (where it begins > > > with a > > > 'let') is not immediately part of the generated code; that 'let' is > > > actually > > > executed during compile-time. The body of the macro must result in > > > an > > > object of the type "syntax object" that represents the generated > > > code. > > > > > > - You see that I define a variable called "ret-id" which I bind to > > > the result > > > of the expression: > > > > > > (datum->syntax stx 'return) > > > > > > which means "create a syntax object in the same lexical environment > > > as stx, > > > and is represented by the symbol 'return'." > > > > > > - The actual code generation begins within the #`(...) which is a > > > shorthand > > > for (quasisyntax (...)) just like '(...) is short for (quote > > > (...)). The > > > result of a quasisyntax expression is a syntax object. Basically, > > > it's the > > > most convenient way of creating a syntax object, but like syntax- > > > rules it's > > > also hygienic by default and you need to insert "unhygienic" syntax > > > objects > > > into it explicitly. > > > > > > - Within the quasisyntax, I use #,ret-id which is short for (unsyntax > > > ret-id) > > > to inject the unhygienic syntax object that holds the symbol > > > 'return' into > > > the generated code. > > > > > > For someone used to macros in the Common Lisp or Elisp style, this > > > may seem > > > over-complicated. It's the cost of the "hygienic by default" > > > behavior. > > > > > > By the way I assume that you're just toying around with the language > > > to learn. > > > If you were thinking of using a 'def' macro like this in real code, I > > > would > > > discourage it because there's already a built-in mechanism that > > > allows the > > > programmer something very similar, called 'let/ec': > > > > > > (import (ice-9 control)) > > > > > > (define (test x) > > > (let/ec return > > > (cond > > > ((= x 3) (return 7)) > > > ((= x 2) (return 5))))) > > > > > > > > What does this return (defined with let/ec) do ? > > > > In the orevious versions I could see the call to call/cc so I could > > (somewhat) figure out the "jump" imlpied by calling return > > > > But in this last case, where is the return behaviour defined ? > > > > > > > > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro @ 2021-09-30 20:55 dsmich 2021-10-01 8:37 ` adriano 0 siblings, 1 reply; 8+ messages in thread From: dsmich @ 2021-09-30 20:55 UTC (permalink / raw) To: 'adriano'; +Cc: 'guile-user' From: "adriano" > (import (ice-9 control)) > > (define (test x) > (let/ec return > (cond > ((= x 3) (return 7)) > ((= x 2) (return 5))))) > What does this return (defined with let/ec) do ? > In the orevious versions I could see the call to call/cc so I could > (somewhat) figure out the "jump" imlpied by calling return > But in this last case, where is the return behaviour defined ? See https://www.gnu.org/software/guile/manual/guile.html#index-let_002fec -Dale ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: return macro 2021-09-30 20:55 dsmich @ 2021-10-01 8:37 ` adriano 0 siblings, 0 replies; 8+ messages in thread From: adriano @ 2021-10-01 8:37 UTC (permalink / raw) To: 'guile-user' Il giorno gio, 30/09/2021 alle 20.55 +0000, dsmich@roadrunner.com ha scritto: > From: "adriano" > > > (import (ice-9 control)) > > > > (define (test x) > > (let/ec return > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5))))) > > > What does this return (defined with let/ec) do ? > > > In the orevious versions I could see the call to call/cc so I > could > > (somewhat) figure out the "jump" imlpied by calling return > > > But in this last case, where is the return behaviour defined ? > > See https://www.gnu.org/software/guile/manual/guile.html#index- > let_002fec > > -Dale > thank you ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-10-01 8:37 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-06-27 23:10 return macro Damien Mattei 2021-06-28 1:15 ` Taylan Kammer 2021-06-28 8:53 ` Damien Mattei 2021-09-30 3:37 ` adriano 2021-09-30 8:46 ` Damien Mattei 2021-09-30 9:18 ` Stefan Israelsson Tampe -- strict thread matches above, loose matches on Subject: below -- 2021-09-30 20:55 dsmich 2021-10-01 8:37 ` adriano
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).