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.mat...@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.mat...@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 <vijaymarup...@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 >>> >>