guile-user
[Top][All Lists]
Advanced

[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 09:21:02 +0100

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]