guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: with-syntax return error in Guile, not in Kawa or Racket


From: Damien Mattei
Subject: Re: with-syntax return error in Guile, not in Kawa or Racket
Date: Fri, 10 May 2024 15:52:46 +0200

i re-test all, and your are right this working:

(define-syntax  foo

  (syntax-rules ()
    ((foo . args) (display 'args))))

(define-syntax  bar

  (syntax-rules ()
    ((bar . args) (foo . args))))

(foo 1 2 3)
(1 2 3)
(bar 1 2 3)
(1 2 3)
(foo 1)
(1)
(bar 1)
(1)


(define-syntax  my-macro

  (syntax-rules ()
    ((my-macro arg ...) (begin (display arg) ...))))

(define-syntax  bar-my-macro

  (syntax-rules ()
    ((bar-my-macro . args) (my-macro . args))))

still working:
(my-macro 1 2 3)
123
 (bar-my-macro 1 2 3)
123

but there should be something different with my macro and code because if
i  put:

(define-syntax ←
  (syntax-rules ()
    ((← . args)
     (<- . args))))

in my code i get again the warnings at compilation:

;;; /Users/mattei/library-FunctProg/guile/logiki+.scm:2526:19: warning:
possibly unbound variable `lin'
;;; /Users/mattei/library-FunctProg/guile/logiki+.scm:2546:18: warning:
possibly unbound variable `col'
;;; /Users/mattei/library-FunctProg/guile/logiki+.scm:2554:13: warning:
possibly unbound variable `lin-pos-epi'

and the error at runtime:
scheme@(guile-user)> (logic-test)
test 1
(or (and (not a) (not b) (not c) (not d)) (and (not a) (not b) (not c) d)
(and (not a) (not b) c (not d)) (and (not a) b (not c) d) (and (not a) b c
(not d)) (and (not a) b c d) (and a (not b) (not c) (not d)) (and a (not b)
(not c) d) (and a (not b) c (not d)) (and c (not d))) =
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Unbound variable: lin

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]>

so strictly talking it is not the same thing as calling ← defined like this:

(define-syntax ←
  (syntax-rules ()
    ((← . args)
     (<- . args))))

and not the same as calling ← defined like this:

(define-syntax ←

  (lambda (stx)

    (syntax-case stx ()


      ;; silly case
      ((_ ( ) expr)
       #'(void)) ;; void is not portable ;'())

      ;; one value in values !
      ;; > {(x) ← (values 7)}
      ;; > x
      ;; 7
      ((_ (var) expr)

       #'(set!-values-plus (var) expr))



      ;; example: {a[4] ← 7}
      ;; $bracket-apply$ is from SRFI 105  bracket-apply is an argument of
the macro

      ((_ (brket-applynext container index ...) expr)  ; possible to have
NO index :
; minimal form is (_ (brket-applynext container) expr)

       ;; We will let the second $bracket-apply$ be executed and forbid the
execution of first $bracket-apply$.
       (cond ((equal? (quote $bracket-apply$next) (syntax->datum
#'brket-applynext))  ;; already parsed and optimised by parser

     #'(assignmentnext container expr index  ...)) ; possible to have NO
index


    ;; integrated curly-infix of guile (no parsing) at REPL
    ((equal? (quote $bracket-apply$) (syntax->datum #'brket-applynext))

     (display "← : #'(index ...) = ") (display #'(index ...)) (newline)
     (display "← : (syntax->datum #'(index ...)) = ") (display
(syntax->datum #'(index ...))) (newline)

     ;;(display "← : (number? (car (syntax->datum #'(index ...)))) = ")
(display (number? (car (syntax->datum #'(index ...))))) (newline)

     ;; parse arguments at posteriori here:
     (with-syntax ((parsed-args (datum->syntax stx ; #f
      (cons #'list
           (optimizer-parse-square-brackets-arguments-lister
      (syntax->datum #'(index ...)))))))

     ;; (with-syntax ((parsed-args
     ;;     (cons #'list ;; otherwise:Wrong type to apply: 0 ,list will be
interpreted as code !
     ;;   (optimizer-parse-square-brackets-arguments-lister #'(index
...)))))

  (display "← : #'parsed-args=") (display #'parsed-args) (newline)
  (display "← :  (syntax->datum #'parsed-args)=") (display (syntax->datum
#'parsed-args)) (newline)

  (case (length (cdr (syntax->datum #'parsed-args)))
  ;;(case (length (cdr #'parsed-args))
  ;;(case (length #'parsed-args)

    ;; 0 argument in []
    ;; T[]
    ;; {v[] ← #(1 2 3)}
    ;; > v
    ;;'#(1 2 3)
    ((0)
     #'(assignment-argument-0 container expr))  ; possible to have NO index

    ;; 1 argument in [ ]
    ;; T[index]
    ((1)
     #'(assignment-argument-1 container
      (first parsed-args)
      expr))

    ;; 2 arguments in [ ]
    ;; ex: T[i1 :] , T[: i2], T[i1 i2] , T[: :]
    ;; {#(1 2 3 4 5)[inexact->exact(floor(2.7)) :]}
    ;; '#(3 4 5)
    ((2)
     #'(assignment-argument-2 container
      (first parsed-args)
      (second parsed-args)
      expr))

    ;; 3 arguments in [ ]
    ;; T[i1 : i2] , T[i1 i2 i3] , T[: : s]
    ((3)
     #'(assignment-argument-3 container
      (first parsed-args)
      (second parsed-args)
      (third parsed-args)
      expr))

    ;; 4 arguments in [ ]
    ;; T[: i2 : s] , T[i1 : : s] , T[i1 : i3 :] , T[i1 i2 i3 i4]
    ((4)
     #'(assignment-argument-4 container
      (first parsed-args)
      (second parsed-args)
      (third parsed-args)
      (fourth parsed-args)
      expr))

    ;; 5 arguments in [ ]
    ;; T[i1 : i3 : s] , T[i1 i2 i3 i4 i5]
    ((5)
     #'(assignment-argument-5 container
      (first parsed-args)
      (second parsed-args)
      (third parsed-args)
      (fourth parsed-args)
      (fifth parsed-args)
      expr))

    ;; more than 5 arguments in [ ]
    ;; T[i1 i2 i3 i4 i5 i6 ...]
    (else ; case
     #'(assignment-argument-6-and-more container parsed-args expr)))))

    (else ; cond
     #'(set!-values-plus (brket-applynext container index ...) expr)))) ;
warning: the argument's names does not match the use



      ;;(← x 5)
      ((_ var expr)

       #'(set! var expr))


      ;; (declare x y z t)
      ;; {x ← y ← z ← t ← 7}
      ;; 7
      ;; (list x y z t)
      ;; (7 7 7 7)

      ;; > (require srfi/25)
      ;; > {I ← (make-array (shape 0 4 0 4))}
      ;; #<array:srfi-9-record-type-descriptor>
      ;; > {I[0 0] ← I[1 1] ← I[2 2] ← I[3 3] ← 1}
      ;; 1
      ;; > {I[0 0]}
      ;; 1
      ;; > {I[0 1]}
      ;; 0
      ;; > I
      ;; #<array:srfi-9-record-type-descriptor>

      ;; > (declare a b c d)
      ;; > {(a b) ← (c d) ← (values 5 7)}
      ;; > a
      ;; 5
      ;; > b
      ;; 7
      ;; > c
      ;; 5
      ;; > d
      ;; 7

      ;; without declare:
      ;; > {(a b) ← (c d) ← (values 5 7)}
      ;; > (list a b c d)
      ;; '(5 7 5 7)
      ((_ var var1 ... expr)


       #'(begin ;; i do not do what the syntax says (assignation not in the
good order) but it gives the same result
  ;;(display "← : case (_ var var1 ... expr)") (newline)

  (define return-values-of-expr (create-return-values expr))
  (← var (return-values-of-expr))
  ;;(display "← : case : passed (← var expr)") (newline)
  ;;(display "← : case : var=") (display var) (newline)

  (← var1 (return-values-of-expr))
  ...))


      )))

even if the version above of ← is the same as <- ,i just replaced at any
place <- by ←

i have no explains. I suppose there is something hard too understand with
the macro syntax system.

i even tried this :

(define-syntax ←
   (syntax-rules ()

     ((_ ( ) expr) (<- ( ) expr))

     ((_ (var) expr) (<- (var) expr))

     ((_ (brket-applynext container index ...) expr) (<- (brket-applynext
container index ...) expr))
     ((_ var expr) (<- var expr))

     ((_ var var1 ... expr) (<- var var1 ... expr))))


to better respect the pattern of <- it fails too when call from ←

when i will port this version of scheme+ to kawa or racket i will check all
this again to see if it is a problem related to guile or scheme (but with
kawa or racket i will have no support for curly-infix so the problem could
be different...)

On Fri, May 10, 2024 at 12:33 PM Jean Abou Samra <jean@abou-samra.fr> wrote:

>
> > sorry, but this can not works because my macro is defined this way:
> > (define-syntax <-
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       ;; silly case
> >       ((_ ( ) expr)
> >        #'(void)) ;; void is not portable ;'())
> >       ;; one value in values !
> >       ;; > {(x) <- (values 7)}
> >       ;; > x
> >       ;; 7
> >       ((_ (var) expr)
> >        #'(set!-values-plus (var) expr))
> >
> > etc... other case continues
> >
> > so my arguments are not put in a list as in your definition.
>
>
> That has no influence whatsoever. The macro ← just replaces
> itself with <- and then <- does its job as usual.
>
> For example, this works perfectly:
>
> (define-syntax <-
>   (syntax-rules ()
>     ((<- foo bar) (set! foo bar))
>     ((<- foo) (set! foo #f))))
>
> (define-syntax-rule (← . args) (<- . args))
>
> (define a 5)
> (← a 7)
> (display a) (newline)
> (← a)
> (display a) (newline)
>
>
> It is similar to how you can alias a procedure with
>
> (define alias (lambda args (apply old-procedure args)))
>
>
> >
> > ok i see it is not define-syntax but define-syntax-rules, first not in
> R6RS,
> > so not portable ,does not exist in Kawa:
> > #|kawa:1|# define-syntax-rules
> > /dev/tty:1:1: warning - no declaration seen for define-syntax-rules
> > /dev/tty:1:1: unbound location: define-syntax-rules
>
>
> OK, make that
>
> (define-syntax ←
>   (syntax-rules ()
>     ((← . args)
>      (<- . args))))
>
> define-syntax-rule is merely a shortcut for syntax-rules
> macros with just one rule like this (but it's indeed no
> standard).
>
>
> > but i test it with my guile code,fails too at run-time:
> > scheme@(guile-user)> (logic-test)
> > test 1
> > (or (and (not a) (not b) (not c) (not d)) (and (not a) (not b) (not c) d)
> > (and
> > (not a) (not b) c (not d)) (and (not a) b (not c) d) (and (not a) b c
> (not
> > d))
> > (and (not a) b c d) (and a (not b) (not c) (not d)) (and a (not b) (not
> c)
> > d)
> > (and a (not b) c (not d)) (and c (not d))) = ice-9/boot-9.scm:1685:16: In
> > procedure raise-exception:
> > Unbound variable: lin
> >
> > Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> > scheme@(guile-user) [1]> ,bt
> > In /Users/mattei/library-FunctProg/guile/logiki+.scm:
> >   2848:18  5 (_ #<continuation 101c6a500>)
> >    743:23  4 (infix-symb-min-dnf _)
> >   1777:41  3 (minimal-dnf _)
> >   2707:38  2 (_ _)
> >   2526:19  1 (identify-essential-prime-implicants _ _)
> > In ice-9/boot-9.scm:
> >   1685:16  0 (raise-exception _ #:continuable? _)
> >
> > the offending code is here:
> >
> > ;; construction of the array
> >   ;; set the left column containing prime implicants
> >   (for-basic (lin 0 {lgt-pi - 1})
> >      ;;(display "lin=") (display lin) (newline)
> >      ;;(display "{vct-prime-implicants[lin]}=") (display
> > {vct-prime-implicants[lin]}) (newline)
> >      ;;(display "{iepi[{lin + 1} 0]}=") (display {iepi[{lin + 1} 0]})
> > (newline)
> >      {iepi[{lin + 1} 0] ← vct-prime-implicants[lin]})
> >      ;;{iepi[{lin + 1} 0] <- vct-prime-implicants[lin]})
> >
> >   ;(display "iepi after") (newline)
> >
> > exactly here, just in the macro:
> > {iepi[{lin + 1} 0] ← vct-prime-implicants[lin]})
> > in the macro lin is not more binded, so i suppose there is a problem of
> > hygiene, the macro wipe out the binding of lin
> >
> > but it works at REPL,strange ... :
> >
> >   1685:16  0 (raise-exception _ #:continuable? _)
> > scheme@(guile-user) [1]> ,q
> > scheme@(guile-user)> {v <+ (vector 1 2 3 4)}
> > scheme@(guile-user)> {v[1 : 3] <- #(-1 -2 -3 -4 -5 -6 -7)[2 : 4]}
> > <- : #'(index ...) = (#<syntax:unknown file:6:3 1> #<syntax:unknown
> file:6:5
> > :> #<syntax:unknown file:6:7 3>)
> > <- : (syntax->datum #'(index ...)) = (1 : 3)
> > <- : #'parsed-args=#<syntax (#<syntax:assignment.scm:116:64 list> 1 : 3)>
> > <- :  (syntax->datum #'parsed-args)=(list 1 : 3)
> > $bracket-apply$ : parsed-args=#<syntax
> > (#<syntax:apply-square-brackets.scm:107:57 list> 2 : 4)>
> > scheme@(guile-user)> v
> > $1 = #(1 -3 -4 4)
> > scheme@(guile-user)> {v[1 : 3] ← #(-1 -2 -3 -4 -5 -6 -7)[2 : 4]}
> > <- : #'(index ...) = (#<syntax:unknown file:8:3 1> #<syntax:unknown
> file:8:5
> > :> #<syntax:unknown file:8:7 3>)
> > <- : (syntax->datum #'(index ...)) = (1 : 3)
> > <- : #'parsed-args=#<syntax (#<syntax:assignment.scm:116:64 list> 1 : 3)>
> > <- :  (syntax->datum #'parsed-args)=(list 1 : 3)
> > $bracket-apply$ : parsed-args=#<syntax
> > (#<syntax:apply-square-brackets.scm:107:57 list> 2 : 4)>
> > scheme@(guile-user)> v
> > $2 = #(1 -3 -4 4)
> > scheme@(guile-user)> (define lin 1)
> > scheme@(guile-user)> {v[lin : 3] ← #(-1 -2 -3 -4 -5 -6 -7)[2 : 4]}
> > <- : #'(index ...) = (#<syntax:unknown file:11:3 lin> #<syntax:unknown
> > file:11:7 :> #<syntax:unknown file:11:9 3>)
> > <- : (syntax->datum #'(index ...)) = (lin : 3)
> > <- : #'parsed-args=#<syntax (#<syntax:assignment.scm:116:64 list> lin :
> 3)>
> > <- :  (syntax->datum #'parsed-args)=(list lin : 3)
> > $bracket-apply$ : parsed-args=#<syntax
> > (#<syntax:apply-square-brackets.scm:107:57 list> 2 : 4)>
> > scheme@(guile-user)> v
> > $3 = #(1 -3 -4 4)
> >
> > and even with a variable ,i defined lin in the example
>
>
> Hard to tell with so much code and without context on what
> you're trying to do, but this might be caused precisely by
> stripping identifier annotations. Consider:
>
> (define-syntax mac
>   (lambda (sintax)
>     (syntax-case sintax ()
>       ((mac arg)
>        (datum->syntax #f (syntax->datum #'arg))))))
>
> ;; Works:
> ;; (define lin 6)
> ;; (display (mac lin))
>
> ;; Fails (as expected):
> (let ((lin 5))
>   (display (mac lin)))
>
>
> yes frightening... the variable just disappeared...

note in Racket the 2 examples fails:

Welcome to DrRacket, version 8.12 [cs].
Language: racket, with debugging; memory limit: 8192 MB.
> (define lin 6)
> (display (mac lin))
lin: unbound identifier;
 also, no #%top syntax transformer is bound in: lin
> (let ((lin 5))
  (display (mac lin)))
lin: unbound identifier;
 also, no #%top syntax transformer is bound in: lin
>

in Guile the 2 examples works:

scheme@(guile-user)> (define-syntax mac
  (lambda (sintax)
    (syntax-case sintax ()
      ((mac arg)
       (datum->syntax #f (syntax->datum #'arg))))))
scheme@(guile-user)> (define lin 6)
scheme@(guile-user)> (display (mac lin))
6scheme@(guile-user)> (let ((lin 5))
  (display (mac lin)))
6scheme@(guile-user)>

about my code , as i said it earlier, if i remove the datum->syntax #f
(syntax->datum from my <- macro then your solution for ← works prefectly in
the logic code but it then fails in the backpropagation deep learning code
where + is overloaded with GOOPS so as i want the most compatible system i
can not use it.But of course that would be better to understand what really
happens. I'm not sure my code is well written but i can not clone this
macro this way.

About my code , i use a parser in command line and a macro system to extend
the syntax of scheme, with macro doing the job in guile of parser in
pre-compil time this is better because transparent for a guile coder that
want to use scheme+.

It is important to have pre-compil parsing of infix expression because the
infix to prefix parsing is done one time before run time as it does not
change after at runtime it is something that can be done before.(unless
that the parsing is done at run time and if the calulus is in a loop this
could be a big penalty about time)


reply via email to

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