unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* local eval
@ 2023-04-24  9:29 Damien Mattei
  2023-04-24 14:19 ` Robby Zambito
  0 siblings, 1 reply; 9+ messages in thread
From: Damien Mattei @ 2023-04-24  9:29 UTC (permalink / raw)
  To: guile-user

hello,
i need to local eval some vars for an infix evaluator but i can not find a
way to use local eval in my context,here is an example that illustrate my
problem:

;; file Scheme+.scm
(define-module (Scheme+)

  #:use-module (ice-9 local-eval)
  #:export (eval-var))

(include-from-path "test-local-eval.scm"))

;; file test-local-eval.scm
(define-syntax eval-var
  (syntax-rules ()

    ((_ var) (let ((env (the-environment)))
      (local-eval (quote var) env)))))

when i test it i get an error because it can not evaluate the variable:
(use-modules (Scheme+))
scheme@(guile-user)> (define i 3)
scheme@(guile-user)> i
3
scheme@(guile-user)> (eval-var i)
ice-9/boot-9.scm:1669:16: In procedure raise-exception:
Unbound variable: i

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]>
scheme@(guile-user) [1]> ,bt
In ice-9/eval.scm:
   223:20  2 (proc #(#(#<directory (Scheme+) 7ff0327b20a0>)))
In unknown file:
           1 (%resolve-variable (7 . i) #<directory (Scheme+) 7ff0327b20a0>)
In ice-9/boot-9.scm:
  1669:16  0 (raise-exception _ #:continuable? _)

Regards,

Damien


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-24  9:29 local eval Damien Mattei
@ 2023-04-24 14:19 ` Robby Zambito
       [not found]   ` <87mt2x1hp8.fsf@robbyzambito.me>
  0 siblings, 1 reply; 9+ messages in thread
From: Robby Zambito @ 2023-04-24 14:19 UTC (permalink / raw)
  To: Damien Mattei; +Cc: guile-user


Hi Damien

The issue you are running into is related to macro hygiene. If you
implement eval-var using the non-hygienic define-macro, it works how you
want.

(define-module (Scheme+)
  #:use-module (ice-9 local-eval)
  #:re-export (local-eval the-environment)
  #:export (eval-var eval-var))

(define-macro (eval-var var)
  `(local-eval ',var (the-environment)))

Robby



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
       [not found]   ` <87mt2x1hp8.fsf@robbyzambito.me>
@ 2023-04-24 16:24     ` Damien Mattei
  2023-04-26 12:42       ` Damien Mattei
  0 siblings, 1 reply; 9+ messages in thread
From: Damien Mattei @ 2023-04-24 16:24 UTC (permalink / raw)
  To: Robby Zambito, guile-user

thank you, i will try the old macro form.
Damien

On Mon, Apr 24, 2023 at 4:24 PM Robby Zambito <contact@robbyzambito.me>
wrote:

>
> Whoops I had a duplicate export from when I was testing with things, but
> you get the idea :)
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-24 16:24     ` Damien Mattei
@ 2023-04-26 12:42       ` Damien Mattei
  2023-04-26 12:46         ` Robby Zambito
  0 siblings, 1 reply; 9+ messages in thread
From: Damien Mattei @ 2023-04-26 12:42 UTC (permalink / raw)
  To: Robby Zambito, guile-user

i can not make it run i always have something unbound , not reach the var i
but local-eval is unbound now?


On Mon, Apr 24, 2023 at 6:24 PM Damien Mattei <damien.mattei@gmail.com>
wrote:

> thank you, i will try the old macro form.
> Damien
>
> On Mon, Apr 24, 2023 at 4:24 PM Robby Zambito <contact@robbyzambito.me>
> wrote:
>
>>
>> Whoops I had a duplicate export from when I was testing with things, but
>> you get the idea :)
>>
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-26 12:42       ` Damien Mattei
@ 2023-04-26 12:46         ` Robby Zambito
  2023-04-26 17:20           ` Mikael Djurfeldt
  0 siblings, 1 reply; 9+ messages in thread
From: Robby Zambito @ 2023-04-26 12:46 UTC (permalink / raw)
  To: Damien Mattei; +Cc: guile-user


Damien Mattei <damien.mattei@gmail.com> writes:

> i can not make it run i always have something unbound , not reach the var i but local-eval is unbound now?

I added this line to the module definition

  #:re-export (local-eval the-environment)

Did you also add that? The way the unhygienic macros work, it
essentially just replaces the call to the macro with the S-exp returned
by the macro. Bindings referenced inside the macro (such as local-eval
and the-environment in this case) must be available in the environment
that the macro is expanding into. I did this by using re-export, but
there may be other more elegant ways. That was just the easiest way for
me to solve that :)



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-26 12:46         ` Robby Zambito
@ 2023-04-26 17:20           ` Mikael Djurfeldt
  2023-04-26 17:25             ` Mikael Djurfeldt
  0 siblings, 1 reply; 9+ messages in thread
From: Mikael Djurfeldt @ 2023-04-26 17:20 UTC (permalink / raw)
  To: Robby Zambito; +Cc: Damien Mattei, guile-user, Mikael Djurfeldt

How about:

(define-syntax eval-var
  (syntax-rules ()
    ((_ var) var)))

?

Then you don't need to import (ice-9 local-eval) and re-export things from
there.

Just for elucidation:

The reason why we chose the syntax-case macro system for Guile was that it
*both* gives you hygiene *and* quite a lot of control. The reason why the
original code didn't work (your first post in this thread) is that
"(the-environment)" was expanded in the lexical context where it was
written (the Scheme+ module),

However, syntax-case gives you the ability to insert that identifier into
the context of the expansion instead:

(define-syntax eval-var
  (lambda (x)
    (syntax-case x ()
      ((_ var)
       (with-syntax ((the-environment (datum->syntax #'var
'the-environment)))
         #'(let ((env (the-environment)))
              (local-eval (quote var) env)))))))

(It's the datum->syntax form which gives the lexical context of var to
the-environment.)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-26 17:20           ` Mikael Djurfeldt
@ 2023-04-26 17:25             ` Mikael Djurfeldt
  2023-04-26 19:27               ` Damien Mattei
  0 siblings, 1 reply; 9+ messages in thread
From: Mikael Djurfeldt @ 2023-04-26 17:25 UTC (permalink / raw)
  To: Robby Zambito; +Cc: Damien Mattei, guile-user

(However, I suspect that you didn't *really* mean (quote var) in your
original code, or? If you didn't, then of course my simpler syntax-rules
macro isn't what you want.)

On Wed, Apr 26, 2023 at 7:20 PM Mikael Djurfeldt <mikael@djurfeldt.com>
wrote:

> How about:
>
> (define-syntax eval-var
>   (syntax-rules ()
>     ((_ var) var)))
>
> ?
>
> Then you don't need to import (ice-9 local-eval) and re-export things from
> there.
>
> Just for elucidation:
>
> The reason why we chose the syntax-case macro system for Guile was that it
> *both* gives you hygiene *and* quite a lot of control. The reason why the
> original code didn't work (your first post in this thread) is that
> "(the-environment)" was expanded in the lexical context where it was
> written (the Scheme+ module),
>
> However, syntax-case gives you the ability to insert that identifier into
> the context of the expansion instead:
>
> (define-syntax eval-var
>   (lambda (x)
>     (syntax-case x ()
>       ((_ var)
>        (with-syntax ((the-environment (datum->syntax #'var
> 'the-environment)))
>          #'(let ((env (the-environment)))
>               (local-eval (quote var) env)))))))
>
> (It's the datum->syntax form which gives the lexical context of var to
> the-environment.)
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-26 17:25             ` Mikael Djurfeldt
@ 2023-04-26 19:27               ` Damien Mattei
  2023-04-27  9:45                 ` Damien Mattei
  0 siblings, 1 reply; 9+ messages in thread
From: Damien Mattei @ 2023-04-26 19:27 UTC (permalink / raw)
  To: mikael; +Cc: Robby Zambito, guile-user

hello Mikael,
hello Robby,

yes my infix evaluator _with_ precedence is more complex than evaluating a
single var. What became your macro Mikael in case of an expression? , in my
original code ,now, i'm passing all vars quoted, so i need to evaluate the
whole expression, because evaluating special form would fail (even if i can
remove special form) ok it all start with $nfx$ from SRFI 105 that i have
to define for operator precedence so there is some procedures  call by the
$nfx$ macro, i skip the details,it looks like that:

(define-syntax $nfx$
  (syntax-rules ()

    ((_ sexpr ...) (let ((env (the-environment)))

    (compute (infix-with-precedence2prefix (! (quote sexpr) ...)) env)))))

basically infix-with-precedence2prefix and ! and other procedures not
listed do the infix precedence conversion to prefix scheme and 'compute' do
the evaluation

(define (compute expr env)
  (display "evaluate : expr =") (display expr) (newline)
  ;;(eval expr2eval (interaction-environment)))
  (local-eval expr2eval env))

i just need the good macro that finally replace the last line:
(local-eval expr2eval env)

evaluate the expression expr2eval in the environment env, example of
expr2eval:
(<+ x (<- y (+ (* 3 5) 2)))   ( was in infix SRFI 105: {x <+ y <- 3 * 5 +
2}  and in srfi 105 this expression is converted by the reader in: ($nfx$ x
<+ y <- 3 * 5 + 2)  )

so $nfx$ is here a macro that quote all the arguments to pass it to the
procedures and finally the result is evaluated. (there is other strategies
and version in my code that do only partial 'quoting or no 'quoting at all
but the more powerful (can deal special form and easily operator
overload,will be to quote all)

Damien


On Wed, Apr 26, 2023 at 7:25 PM Mikael Djurfeldt <mikael@djurfeldt.com>
wrote:

> (However, I suspect that you didn't *really* mean (quote var) in your
> original code, or? If you didn't, then of course my simpler syntax-rules
> macro isn't what you want.)
>
> On Wed, Apr 26, 2023 at 7:20 PM Mikael Djurfeldt <mikael@djurfeldt.com>
> wrote:
>
>> How about:
>>
>> (define-syntax eval-var
>>   (syntax-rules ()
>>     ((_ var) var)))
>>
>> ?
>>
>> Then you don't need to import (ice-9 local-eval) and re-export things
>> from there.
>>
>> Just for elucidation:
>>
>> The reason why we chose the syntax-case macro system for Guile was that
>> it *both* gives you hygiene *and* quite a lot of control. The reason why
>> the original code didn't work (your first post in this thread) is that
>> "(the-environment)" was expanded in the lexical context where it was
>> written (the Scheme+ module),
>>
>> However, syntax-case gives you the ability to insert that identifier into
>> the context of the expansion instead:
>>
>> (define-syntax eval-var
>>   (lambda (x)
>>     (syntax-case x ()
>>       ((_ var)
>>        (with-syntax ((the-environment (datum->syntax #'var
>> 'the-environment)))
>>          #'(let ((env (the-environment)))
>>               (local-eval (quote var) env)))))))
>>
>> (It's the datum->syntax form which gives the lexical context of var to
>> the-environment.)
>>
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: local eval
  2023-04-26 19:27               ` Damien Mattei
@ 2023-04-27  9:45                 ` Damien Mattei
  0 siblings, 0 replies; 9+ messages in thread
From: Damien Mattei @ 2023-04-27  9:45 UTC (permalink / raw)
  To: mikael; +Cc: Robby Zambito, guile-user

finally i arrive to this solution that works:

;; now quoting all the operators ... so we are no more annoyed with macro
'bad syntax' error and also this  keep the 'and and 'or short-circuited
functionalities.

(define-macro (quote-all . Largs)
  (if (null? Largs)
      `(quote ,Largs)
      `(cons (quote ,(car Largs)) (quote-all ,@(cdr Largs)))))

;; but we then have to eval-uate all the expression at end

(define-macro ($nfx$ . Largs)
  `(local-eval (infix-with-precedence2prefix (! (quote-all ,@Largs)))
(the-environment)))

and with the magic re-export in module:

;; (use-modules (Scheme+))



(define-module (Scheme+)

  #:use-module (growable-vector)
  #:use-module (ice-9 local-eval)
  #:use-module (srfi srfi-1) ;; any,every
  #:use-module (srfi srfi-69) ;; Basic hash tables
  #:use-module (srfi srfi-31) ;; rec
  #:export (infix-with-precedence2prefix ! quote-all overload
overload-procedure overload-operator overload-function $nfx$ def
$bracket-apply$ <- ← -> → <+ ⥆ +> ⥅ declare $ $>  condx <> ≠ ** <v v> ⇜ ⇝
repeat % << >> & |)
  #:re-export (local-eval the-environment)
  #:replace (do when unless))



(include-from-path "def.scm")
(include-from-path "array.scm")
(include-from-path "set-values-plus.scm")
(include-from-path "apply-square-brackets.scm")
(include-from-path "assignment.scm")
(include-from-path "declare.scm")
(include-from-path "condx.scm")
(include-from-path "block.scm")
(include-from-path "not-equal.scm")
(include-from-path "exponential.scm")
(include-from-path "while-do-when-unless.scm")
(include-from-path "repeat-until.scm")
(include-from-path "scheme-infix.scm")
(include-from-path "overload.scm")
(include-from-path "modulo.scm")
(include-from-path "bitwise.scm")


but define-macro is not so much portable

Damien




On Wed, Apr 26, 2023 at 9:27 PM Damien Mattei <damien.mattei@gmail.com>
wrote:

> hello Mikael,
> hello Robby,
>
> yes my infix evaluator _with_ precedence is more complex than evaluating a
> single var. What became your macro Mikael in case of an expression? , in my
> original code ,now, i'm passing all vars quoted, so i need to evaluate the
> whole expression, because evaluating special form would fail (even if i can
> remove special form) ok it all start with $nfx$ from SRFI 105 that i have
> to define for operator precedence so there is some procedures  call by the
> $nfx$ macro, i skip the details,it looks like that:
>
> (define-syntax $nfx$
>   (syntax-rules ()
>
>     ((_ sexpr ...) (let ((env (the-environment)))
>
>     (compute (infix-with-precedence2prefix (! (quote sexpr) ...)) env)))))
>
> basically infix-with-precedence2prefix and ! and other procedures not
> listed do the infix precedence conversion to prefix scheme and 'compute' do
> the evaluation
>
> (define (compute expr env)
>   (display "evaluate : expr =") (display expr) (newline)
>   ;;(eval expr2eval (interaction-environment)))
>   (local-eval expr2eval env))
>
> i just need the good macro that finally replace the last line:
> (local-eval expr2eval env)
>
> evaluate the expression expr2eval in the environment env, example of
> expr2eval:
> (<+ x (<- y (+ (* 3 5) 2)))   ( was in infix SRFI 105: {x <+ y <- 3 * 5 +
> 2}  and in srfi 105 this expression is converted by the reader in: ($nfx$ x
> <+ y <- 3 * 5 + 2)  )
>
> so $nfx$ is here a macro that quote all the arguments to pass it to the
> procedures and finally the result is evaluated. (there is other strategies
> and version in my code that do only partial 'quoting or no 'quoting at all
> but the more powerful (can deal special form and easily operator
> overload,will be to quote all)
>
> Damien
>
>
> On Wed, Apr 26, 2023 at 7:25 PM Mikael Djurfeldt <mikael@djurfeldt.com>
> wrote:
>
>> (However, I suspect that you didn't *really* mean (quote var) in your
>> original code, or? If you didn't, then of course my simpler syntax-rules
>> macro isn't what you want.)
>>
>> On Wed, Apr 26, 2023 at 7:20 PM Mikael Djurfeldt <mikael@djurfeldt.com>
>> wrote:
>>
>>> How about:
>>>
>>> (define-syntax eval-var
>>>   (syntax-rules ()
>>>     ((_ var) var)))
>>>
>>> ?
>>>
>>> Then you don't need to import (ice-9 local-eval) and re-export things
>>> from there.
>>>
>>> Just for elucidation:
>>>
>>> The reason why we chose the syntax-case macro system for Guile was that
>>> it *both* gives you hygiene *and* quite a lot of control. The reason why
>>> the original code didn't work (your first post in this thread) is that
>>> "(the-environment)" was expanded in the lexical context where it was
>>> written (the Scheme+ module),
>>>
>>> However, syntax-case gives you the ability to insert that identifier
>>> into the context of the expansion instead:
>>>
>>> (define-syntax eval-var
>>>   (lambda (x)
>>>     (syntax-case x ()
>>>       ((_ var)
>>>        (with-syntax ((the-environment (datum->syntax #'var
>>> 'the-environment)))
>>>          #'(let ((env (the-environment)))
>>>               (local-eval (quote var) env)))))))
>>>
>>> (It's the datum->syntax form which gives the lexical context of var to
>>> the-environment.)
>>>
>>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-04-27  9:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-24  9:29 local eval Damien Mattei
2023-04-24 14:19 ` Robby Zambito
     [not found]   ` <87mt2x1hp8.fsf@robbyzambito.me>
2023-04-24 16:24     ` Damien Mattei
2023-04-26 12:42       ` Damien Mattei
2023-04-26 12:46         ` Robby Zambito
2023-04-26 17:20           ` Mikael Djurfeldt
2023-04-26 17:25             ` Mikael Djurfeldt
2023-04-26 19:27               ` Damien Mattei
2023-04-27  9:45                 ` Damien Mattei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).