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