[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: reserved-keyword in macro
From: |
Damien Mattei |
Subject: |
Re: reserved-keyword in macro |
Date: |
Fri, 4 Feb 2022 17:24:54 +0100 |
even with $nfx$ it does not seem to be possible without set!-values:
https://docs.racket-lang.org/reference/set_.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._set%21-values%29%29
does someone know how to implement set!-values in Scheme for Guile?
with set!-values things are really easy:
(define-syntax <+
(syntax-rules ()
((_ (var1 ...) expr) (begin
(define var1 '())
...
(display "<+ multiple") (newline)
(set!-values (var1 ...) expr)))
((_ var expr) (begin
(display "<+ single") (newline)
(define var expr)
(display var) (newline)))))
Welcome to DrRacket, version 8.2 [cs].
Language: reader "../SRFI/SRFI-105.rkt", with debugging; memory limit: 128
MB.
> (define (foo) (values 1 2 3))
> {(x y z) <+ (foo)}
<+ multiple
> x
1
> y
2
(define-syntax </
(syntax-rules ()
((</ (x ...) expr) (set!-values (x ...) expr))))
> (declare x y z)
> {(x y z) </ (foo)}
> x
1
> y
2
> z
3
On Fri, Feb 4, 2022 at 9:21 AM Damien Mattei <damien.mattei@gmail.com>
wrote:
> definitely i do not think it is possible to have a macro doing this:
> {(x y z) <- (foo)} ;; foo is a function that return 3 values (ex: (values
> 1 2 3))
> or this :
> {(x y z ...) <- (bar)} ;; bar return an arbitrary (known in advance )
> number of values
> and also have a compatibility with:
> {T[2] <- T[1]} that deal with arrays
>
> $bracket-apply$ and syntax-rules is not enough i think i will have to use
> $nfx$ overloading from SRFI-105 for doing almost the same:
> {x y z <- (foo)} which i admit is more Haskell style than Scheme
>
> On Thu, Feb 3, 2022 at 11:09 AM Damien Mattei <damien.mattei@gmail.com>
> wrote:
>
>> oh :-O yes it is the behavior expected : assign the 2nd element of an
>> array T with value 1 :
>> prefix notation of : (<- ($bracket-apply$ T 2) 1) is equivalent in Curly
>> Infix syntax to : {T[2] <- 1}
>> as expected when $bracket-apply$ is not bound we have the good result.
>> Thanks for this result.
>> Of course in this case {T[2] <- 1} it is not a problem to have not
>> $bracket-apply$
>> bound,
>> things became harder when doing : {T[2] <- T[4]} for example because then
>> i want to assign the result value of T[4] to T[2] and so i need to
>> evaluate T[4] before which is exactly
>> ($bracket-apply$ T 4) and at this point $bracket-apply$ is bind to:
>> (define-syntax $bracket-apply$
>> (syntax-rules ()
>>
>> ((_ container index)
>> ;(begin ;;(display "$bracket-apply$") (newline)
>> (cond ((vector? container) (vector-ref container index))
>> ((hash-table? container) (hash-table-ref container index))
>> (else (array-ref container index))));)
>>
>> ((_ array index1 index2 ...)
>> ;(begin ;;(display "$bracket-apply$") (newline)
>> (if (vector? array)
>> (array-n-dim-ref array index1 index2 ...)
>> (array-ref array index1 index2 ...)))));)
>>
>> and is used in the RHS (right-hand side) of:
>> {T[2] <- T[4]} which expand in Curly Infix SRFI-105 to:
>> (<- ($bracket-apply$ T 2) ($bracket-apply$ T 4))
>> and then is expanded in Scheme+ in two phases:
>> first the RHS expr is evaluate in :
>> ((_ ($bracket-apply$ container index) expr)
>> (let ((value expr)) ;; to avoid compute it twice
>> in : (array-ref T 4)
>> but the LHS (Left hand side) is not evaluated with $bracket-apply$ but
>> with the macro <-
>> in the body of let :
>> (cond ((vector? container) (vector-set! container index value))
>> which give :
>> (vector-set! T 2 value) where value is the value of expr, previously
>> expanded and evaluated.
>> And we get the good result.
>> But for this we need to have sometimes $bracket-apply$ as a bound macro
>> (or procedure) and sometimes not, being a reserved keyword NOT bound.
>> This for me obscure WHY the keyword in syntax-rules MUST not be bound to
>> behave correctly but this is like that in Scheme standarts and we have to
>> deal with.
>> I already faced this problem earlier and the solution is in the
>> previously commented code:
>> ;; (if (equal? (quote $bracket-apply$) (quote funct-or-macro)) ;; test
>> funct-or-macro equal $bracket-apply$
>> which can only be understood knowing that the macro was in the past
>> declared like this and commented code does not match present code,here is
>> the previous definition of <- :
>> (syntax-rules ()
>>
>> ;; special form like : (<- ($bracket-apply$ T 3) ($bracket-apply$ T
>> 4))
>>
>> ;; one dimension array, example: {a[4] <- 7}
>> ;; $bracket-apply$ of SRFI 105
>> ((_ (funct-or-macro container index) expr)
>> (let ((value expr)) ;; to avoid compute it twice
>>
>> ;; (if (equal? (quote $bracket-apply$) (quote funct-or-macro)) ;;
>> test funct-or-macro equal $bracket-apply$
>>
>> ;; normal case
>> ;; {T[2] <- 4}
>> ;; {T[3] <- T[2]}
>>
>> (cond ((vector? container) (vector-set! container index value))
>> ((hash-table? container) (hash-table-set! container
>> index value))
>> (else (array-set! container index value)))
>> value))
>>
>> so the solution will be to remove $bracket-apply$ as literal in:
>> (define-syntax <-
>> (syntax-rules ($bracket-apply$)
>>
>> and some check manually in the macro with:
>> (if (equal? (quote $bracket-apply$) (quote funct-or-macro)) ;; test
>> funct-or-macro equal $bracket-apply$
>> to branch instead of using pattern matching.
>> i will code this later but this was of great help,thanks again all.
>>
>> Damien
>>
>> On Thu, Feb 3, 2022 at 1:52 AM Vijay Marupudi <vijaymarupudi@gatech.edu>
>> wrote:
>>
>>> Hi Damien,
>>>
>>> I tried to run the code you provided. I ran
>>>
>>> -----------------------------------------------------------------
>>>
>>> (define-syntax <-
>>> (syntax-rules ($bracket-apply$)
>>> ((_ ($bracket-apply$ container index) expr)
>>> (let ((value expr)) ;; to avoid compute it twice
>>> (cond ((vector? container) (vector-set! container index value))
>>> ((hash-table? container) (hash-table-set! container index
>>> value))
>>> (else (array-set! container index value)));)
>>> value))
>>> ((_ ($bracket-apply$ array index1 index2 ...) expr)
>>> (let ((value expr))
>>> (if (vector? array)
>>> (array-n-dim-set! array value index1 index2 ...)
>>> (array-set! array index1 index2 ... value));)
>>> (newline)
>>> value))
>>> ((_ (var ...) expr)
>>> (begin
>>> (display expr) (newline)
>>> (let ((expr-list (call-with-values (lambda () expr) list)))
>>> (assign-var (var ...) expr-list)
>>> expr-list)))
>>> ((_ var expr)
>>> (begin
>>> (set! var expr)
>>> var))
>>> ((_ var var1 var2 ...)
>>> (<- var (<- var1 var2 ...)))))
>>>
>>> (define T (make-vector 5))
>>> (<- ($bracket-apply$ T 2) 1)
>>>
>>> -----------------------------------------------------------------
>>>
>>> After I ran that, T was
>>>
>>> #(#<unspecified> #<unspecified> 1 #<unspecified> #<unspecified>)
>>>
>>> Is that was you are looking for?
>>>
>>> > "A literal matches an input expression if the input expression is an
>>> > identifier with the same name as the literal, and both are unbound13
>>> > <
>>> https://www.gnu.org/software/guile/manual/html_node/Syntax-Rules.html#FOOT13
>>> >.
>>> > " as $bracket-apply$ is already bind to a definition the pattern will
>>> > not be matched:
>>>
>>> It's possible, as in my case, I did not have it bound, and it seems to
>>> have worked the way you expected?
>>>
>>> ~ Vijay
>>>
>>
- reserved-keyword in macro, Damien Mattei, 2022/02/02
- Re: reserved-keyword in macro, Maxime Devos, 2022/02/02
- Message not available
- Fwd: reserved-keyword in macro, Damien Mattei, 2022/02/02
- Re: reserved-keyword in macro, Damien Mattei, 2022/02/02
- Re: reserved-keyword in macro, Damien Mattei, 2022/02/02
- Re: reserved-keyword in macro, Vijay Marupudi, 2022/02/02
- Re: reserved-keyword in macro, Damien Mattei, 2022/02/03
- Re: reserved-keyword in macro, Damien Mattei, 2022/02/04
- Re: reserved-keyword in macro,
Damien Mattei <=
- Re: reserved-keyword in macro, Maxime Devos, 2022/02/04