unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Define works different when Compile and Eval
@ 2024-06-19  9:04 Andrew Tropin
  2024-06-19  9:53 ` Attila Lendvai
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Tropin @ 2024-06-19  9:04 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 947 bytes --]

Here is a snippet of code, which I expect to produce the same result
with both eval and compile, but the results are different.

When compile is used (define a a) sets a to #<undefined>.

Is it a bug?

--8<---------------cut here---------------start------------->8---
(define-module (2024-06-18-define-bug))

(use-modules (system base compile))

(define (peval e)
  (compile
   e
   #:to 'value
   #:env (resolve-module
          '(2024-06-18-define-bug))))

(define (test-eval teval)
  (teval '(define a 1))
  (teval '(define a a))
  (format #t "a value with ~a is ~a\n" teval (teval 'a)))

(test-eval peval)
(test-eval primitive-eval)

(exit 0)

;; guile -l 2024-06-18-define-bug.scm # output is:
;; a value with #<procedure peval (e)> is #<unspecified>
;; a value with #<procedure primitive-eval (exp)> is 1
--8<---------------cut here---------------end--------------->8---

-- 
Best regards,
Andrew Tropin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

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

* Re: Define works different when Compile and Eval
  2024-06-19  9:04 Define works different when Compile and Eval Andrew Tropin
@ 2024-06-19  9:53 ` Attila Lendvai
  2024-06-21 12:33   ` Andrew Tropin
  2024-06-21 14:40   ` Maxime Devos
  0 siblings, 2 replies; 6+ messages in thread
From: Attila Lendvai @ 2024-06-19  9:53 UTC (permalink / raw)
  To: Andrew Tropin; +Cc: guile-devel

> (define (test-eval teval)
> (teval '(define a 1))

if you want this^ to be actually defined while compilation is
happening (i.e. in the compilation stage; see staged computing), then you need to use an (eval-when (expand) ...) wrapper
around it.

https://www.gnu.org/software/guile/manual/guile.html#Eval-When

compile does not evaluate (aka load) the definitions, it only compiles them.

alternatively, you yourself can explicitly call the lambda returned by compile.

--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“A politician is someone asking you to trust them more with power than they trust you with freedom...”
	— Kelly Diamond




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

* Re: Define works different when Compile and Eval
  2024-06-19  9:53 ` Attila Lendvai
@ 2024-06-21 12:33   ` Andrew Tropin
  2024-06-22 12:57     ` Attila Lendvai
  2024-06-21 14:40   ` Maxime Devos
  1 sibling, 1 reply; 6+ messages in thread
From: Andrew Tropin @ 2024-06-21 12:33 UTC (permalink / raw)
  To: Attila Lendvai; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1898 bytes --]

On 2024-06-19 09:53, Attila Lendvai wrote:

>> (define (test-eval teval)
>> (teval '(define a 1))
>
> if you want this^ to be actually defined while compilation is
> happening (i.e. in the compilation stage; see staged computing), then
> you need to use an (eval-when (expand) ...) wrapper around it.

Thank you for the reply!  Not sure what you mean.  The following code
defines `a`:

--8<---------------cut here---------------start------------->8---
(define (test-eval teval)
  (teval '(define a 1))
  (format #t "a value with ~a is ~a\n" teval (teval 'a)))

(test-eval peval)
(test-eval primitive-eval)

(exit 0)
;; a value with #<procedure peval (e)> is 1
;; a value with #<procedure primitive-eval (exp)> is 1
--8<---------------cut here---------------end--------------->8---

The problem and the difference is in how `(define a a)` is evaluated by
compile.

>
> https://www.gnu.org/software/guile/manual/guile.html#Eval-When
>
> compile does not evaluate (aka load) the definitions, it only compiles them.

compile returns value by default, which is probably means that
everything is loaded as well.

> alternatively, you yourself can explicitly call the lambda returned by compile.

--8<---------------cut here---------------start------------->8---
(use-modules (system base compile)
             (system vm loader))

(define (peval e)
  ((load-thunk-from-memory
    (compile
     e
     #:to 'bytecode
     #:env (resolve-module
            '(2024-06-18-define-bug))))))
--8<---------------cut here---------------end--------------->8---

It works the same way as the original code :(

>
> --
> • attila lendvai
> • PGP: 963F 5D5F 45C7 DFCD 0A39
> --
> “A politician is someone asking you to trust them more with power than they trust you with freedom...”
> 	— Kelly Diamond
>
>
>

-- 
Best regards,
Andrew Tropin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

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

* RE: Define works different when Compile and Eval
  2024-06-19  9:53 ` Attila Lendvai
  2024-06-21 12:33   ` Andrew Tropin
@ 2024-06-21 14:40   ` Maxime Devos
  1 sibling, 0 replies; 6+ messages in thread
From: Maxime Devos @ 2024-06-21 14:40 UTC (permalink / raw)
  To: Attila Lendvai, Andrew Tropin; +Cc: guile-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 946 bytes --]

>compile does not evaluate (aka load) the definitions, it only compiles them.

Usually, sure, but in the code ‘#:to ‘value” was set. From the manual:
>As discussed before (see Object File Format), bytecode is in ELF format, ready to be serialized to disk. But when compiling Scheme at run time, you want a Scheme value: for example, a compiled procedure. For this reason, so as not to break the abstraction, Guile defines a fake language at the bottom of the tower:
> * Value
Now, as example it compiled a lambda expression into a procedure, but it can be done for Scheme expressions that don’t evaluate to procedures as well. The definition ‘(define a whatever)’ strictly speaking isn’t an expression, but it appears the compilation stack doesn’t care.

>alternatively, you yourself can explicitly call the lambda returned by compile.

In this particular case, no lambdas are returned.

Best regards,
Maxime Devos.

[-- Attachment #2: Type: text/html, Size: 5478 bytes --]

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

* Re: Define works different when Compile and Eval
  2024-06-21 12:33   ` Andrew Tropin
@ 2024-06-22 12:57     ` Attila Lendvai
  2024-06-22 16:45       ` Maxime Devos
  0 siblings, 1 reply; 6+ messages in thread
From: Attila Lendvai @ 2024-06-22 12:57 UTC (permalink / raw)
  To: Andrew Tropin; +Cc: guile-devel

> > if you want this^ to be actually defined while compilation is
> > happening (i.e. in the compilation stage; see staged computing), then
> > you need to use an (eval-when (expand) ...) wrapper around it.
> 
> 
> Thank you for the reply! Not sure what you mean. The following code
> defines `a`:


i ran with some ungrounded assumptions, and i basically explained how it works in CL, not in Guile.

sorry about that!

i played a little with your test now.

maybe i'm stating the obvious here, but its behavior is in harmony with the hypothesis that the compilation of DEFINE (wrongly) evaluates the value in the newly updated environment (as opposed to the "parent" environment, i.e. the one before the definition has been added/set).

i briefly tired to find the place where DEFINE is compiled to check this hypothesis in the code, but i couldn't find it.

-- 
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“I find television very educating: Every time somebody turns on the set, I go into the other room and read a book.”
	— Groucho Marx




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

* RE: Define works different when Compile and Eval
  2024-06-22 12:57     ` Attila Lendvai
@ 2024-06-22 16:45       ` Maxime Devos
  0 siblings, 0 replies; 6+ messages in thread
From: Maxime Devos @ 2024-06-22 16:45 UTC (permalink / raw)
  To: Attila Lendvai, Andrew Tropin; +Cc: guile-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1418 bytes --]

> > > if you want this^ to be actually defined while compilation is
> > > happening (i.e. in the compilation stage; see staged computing), then
> > > you need to use an (eval-when (expand) ...) wrapper around it.
> 
> 
> > Thank you for the reply! Not sure what you mean. The following code
> > defines `a`:
>i ran with some ungrounded assumptions, and i basically explained how it works in CL, not in Guile.

It works like that in (Guile) Scheme too. Though, to be precise, ‘expand’ refers to the macro expansion phase, whether compiling or not. ‘compile’ is for “evaluate during macro expansion, but not only when compiling”.

>[...]
>i briefly tired to find the place where DEFINE is compiled to check this hypothesis in the code, but i couldn't find it.

In macro-expansion:
• https://git.savannah.gnu.org/cgit/guile.git/tree/module/ice-9/psyntax.scm#n1370  (also see mentions of ‘define-form’)

Evaluation:
• Probably somewhere in https://git.savannah.gnu.org/cgit/guile.git/tree/module/ice-9/eval.scm
• Perhaps somewhere in https://git.savannah.gnu.org/cgit/guile.git/tree/libguile/eval.c as well

In Tree-IL:
* https://git.savannah.gnu.org/cgit/guile.git/tree/module/language/tree-il.scm#n220
* https://git.savannah.gnu.org/cgit/guile.git/tree/module/language/tree-il.scm#n310

Also maybe see relevant optimisation code and other layers of the compilation tower.

[-- Attachment #2: Type: text/html, Size: 7248 bytes --]

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

end of thread, other threads:[~2024-06-22 16:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-19  9:04 Define works different when Compile and Eval Andrew Tropin
2024-06-19  9:53 ` Attila Lendvai
2024-06-21 12:33   ` Andrew Tropin
2024-06-22 12:57     ` Attila Lendvai
2024-06-22 16:45       ` Maxime Devos
2024-06-21 14:40   ` Maxime Devos

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