GNU bug report logs - #36682
Error in Guile scripting examples

Previous Next

Package: guile;

Reported by: Hans-Werner Roitzsch <hwroitzsch <at> posteo.net>

Date: Mon, 15 Jul 2019 23:20:02 UTC

Severity: normal

To reply to this bug, email your comments to 36682 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#36682; Package guile. (Mon, 15 Jul 2019 23:20:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Hans-Werner Roitzsch <hwroitzsch <at> posteo.net>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Mon, 15 Jul 2019 23:20:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Hans-Werner Roitzsch <hwroitzsch <at> posteo.net>
To: bug-guile <at> gnu.org
Subject: Error in Guile scripting examples
Date: Tue, 16 Jul 2019 00:39:43 +0200
[Message part 1 (text/plain, inline)]
Hello GNU Team!

I wish to report a bug in either Guile's documentation or Guile's code
with regard to running scripts.

There are some examples of that given in Guile's documentation at:

https://www.gnu.org/software/guile/manual/html_node/Scripting-Examples.html#Scripting-Examples

In the following I will describe the problem.


I have the file `modules.scm` with the following code:

----8<----start-of-code---->8----
#!/usr/bin/env sh
exec guile -l fact.scm -e '(@ (my-module) main)' -s "$0" "$@"
!#

;; Explanation:
;; -e (my-module)
;; If run as a script run the `my-module` module's `main`.
;; (Use `@@` to reference not exported procedures.)
;; -s
;; Run the script.

(define-module (my-module)
  #:export (main))

;; Create a module named `fac`.
;; Export the `main` procedure as part of `fac`.

(define (n-choose-k n k)
  (/ (fact n)
     (* (fact k)
        (fact (- n k)))))

(define (main args)
  (let ((n (string->number (cadr args)))
        (k (string->number (caddr args))))
    (display (n-choose-k n k))
    (newline)))
----8<----end-of-code---->8----

And I have the following `fact.scm`:

----8<----start-of-code---->8----
#!/usr/local/bin/guile \
-e main -s
!#

;; How to run this program?
;; Example:
;; guile -e main -s factorial-script.scm 50
;; Explanation:
;; -e specifies the procedure to run
;; -s specifies to run this as a script
;; 50 is the number we take as input to the script

(define (fact n)
  (if (zero? n) 1
      (* n (fact (- n 1)))))

(define (main args)
  (display (fact (string->number (cadr args))))
  (newline))
----8<----end-of-code---->8----

The script is made executable by doing:

chmod +x modules.scm

Then I call the script as follows:

./modules.scm 10 3

This results in the error:

----8<----start-of-code---->8----
Backtrace:
           4 (apply-smob/1 #<catch-closure 119cb80>)
In ice-9/boot-9.scm:
    705:2  3 (call-with-prompt ("prompt") #<procedure 11aa8e0 at ice-9/eval.scm:330:13 ()> #<procedure default-prom…>)
In ice-9/eval.scm:
    619:8  2 (_ #(#(#<directory (guile-user) 1233140>)))
In /home/xiaolong/development/Guile/scripting/./modules.scm:
    26:13  1 (main _)
     18:0  0 (n-choose-k _ _)

/home/xiaolong/development/Guile/scripting/./modules.scm:18:0: In procedure n-choose-k:
In procedure module-lookup: Unbound variable: fact
----8<----end-of-code---->8----

According to my understanding of the tutorial in the Guile documentation
that I linked to above this code should work.

I also described the problem some time ago at:

https://stackoverflow.com/questions/50272618/guile-scheme-scripting-tutorial-loading-scripts

My Guile version is:

guile (GNU Guile) 2.2.4

Best regards,

Hans-Werner Roitzsch

[Message part 2 (text/html, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#36682; Package guile. (Mon, 15 Jul 2019 23:46:02 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Arne Babenhauserheide <arne_bab <at> web.de>
To: bug-guile <at> gnu.org
Cc: 36682 <at> debbugs.gnu.org
Subject: Re: bug#36682: Error in Guile scripting examples
Date: Tue, 16 Jul 2019 01:44:39 +0200
[Message part 1 (text/plain, inline)]
Hello Hans-Werner Roitzsch,

It looks like you’re mixing up two concepts: the fac creates a module
and loads the fact which is not a module, so basically main and choose
live in another namespace than fact (define-module starts a new
namespace).

And it seems that this is indeed a bug in the documentation, because
https://www.gnu.org/software/guile/manual/html_node/Scripting-Examples.html#Scripting-Examples
jumps to defining fac as a module but does not at the same time define
and import fact as a module, too.

Hans-Werner Roitzsch <hwroitzsch <at> posteo.net> writes:
> I have the file `modules.scm` with the following code:
>
> ----8<----start-of-code---->8----
> #!/usr/bin/env sh
> exec guile -l fact.scm -e '(@ (my-module) main)' -s "$0" "$@"
> !#
>
> ;; Explanation:
> ;; -e (my-module)
> ;; If run as a script run the `my-module` module's `main`.
> ;; (Use `@@` to reference not exported procedures.)
> ;; -s
> ;; Run the script.
>
> (define-module (my-module)
>   #:export (main))

At this point you need

(use-modules (fact))

> ;; Create a module named `fac`.
> ;; Export the `main` procedure as part of `fac`.
>
> (define (n-choose-k n k)
>   (/ (fact n)
>      (* (fact k)
>         (fact (- n k)))))
>
> (define (main args)
>   (let ((n (string->number (cadr args)))
>         (k (string->number (caddr args))))
>     (display (n-choose-k n k))
>     (newline)))
> ----8<----end-of-code---->8----
>
> And I have the following `fact.scm`:
>
> ----8<----start-of-code---->8----
> #!/usr/local/bin/guile \
> -e main -s
> !#
>
> ;; How to run this program?
> ;; Example:
> ;; guile -e main -s factorial-script.scm 50
> ;; Explanation:
> ;; -e specifies the procedure to run
> ;; -s specifies to run this as a script
> ;; 50 is the number we take as input to the script

To be usable as module, this needs to be defined as module:

(define-module (fact)
  #:export (fact))

> (define (fact n)
>   (if (zero? n) 1
>       (* n (fact (- n 1)))))
>
> (define (main args)
>   (display (fact (string->number (cadr args))))
>   (newline))
> ----8<----end-of-code---->8----
…
> chmod +x modules.scm
> ./modules.scm 10 3

Does it work with the added module definition and import?

If yes, then this looks like a bug in the documentation.

> Best regards,
>
> Hans-Werner Roitzsch

Best wishes, and thank you for reporting!
Arne
--
Unpolitisch sein
heißt politisch sein
ohne es zu merken
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#36682; Package guile. (Mon, 15 Jul 2019 23:46:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-guile <at> gnu.org:
bug#36682; Package guile. (Mon, 12 Dec 2022 21:19:03 GMT) Full text and rfc822 format available.

Message #14 received at 36682 <at> debbugs.gnu.org (full text, mbox):

From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To: Arne Babenhauserheide <arne_bab <at> web.de>
Cc: 36682 <at> debbugs.gnu.org, Hans-Werner Roitzsch <hwroitzsch <at> posteo.net>
Subject: Re: bug#36682: Error in Guile scripting examples
Date: Mon, 12 Dec 2022 16:17:55 -0500
Hello,

Arne Babenhauserheide <arne_bab <at> web.de> writes:

> Hello Hans-Werner Roitzsch,
>
> It looks like you’re mixing up two concepts: the fac creates a module
> and loads the fact which is not a module, so basically main and choose
> live in another namespace than fact (define-module starts a new
> namespace).
>
> And it seems that this is indeed a bug in the documentation, because
> https://www.gnu.org/software/guile/manual/html_node/Scripting-Examples.html#Scripting-Examples
> jumps to defining fac as a module but does not at the same time define
> and import fact as a module, too.
>
> Hans-Werner Roitzsch <hwroitzsch <at> posteo.net> writes:
>> I have the file `modules.scm` with the following code:
>>
>> ----8<----start-of-code---->8----
>> #!/usr/bin/env sh
>> exec guile -l fact.scm -e '(@ (my-module) main)' -s "$0" "$@"
>> !#
>>
>> ;; Explanation:
>> ;; -e (my-module)
>> ;; If run as a script run the `my-module` module's `main`.
>> ;; (Use `@@` to reference not exported procedures.)
>> ;; -s
>> ;; Run the script.
>>
>> (define-module (my-module)
>>   #:export (main))
>
> At this point you need
>
> (use-modules (fact))
>
>> ;; Create a module named `fac`.
>> ;; Export the `main` procedure as part of `fac`.
>>
>> (define (n-choose-k n k)
>>   (/ (fact n)
>>      (* (fact k)
>>         (fact (- n k)))))
>>
>> (define (main args)
>>   (let ((n (string->number (cadr args)))
>>         (k (string->number (caddr args))))
>>     (display (n-choose-k n k))
>>     (newline)))
>> ----8<----end-of-code---->8----
>>
>> And I have the following `fact.scm`:
>>
>> ----8<----start-of-code---->8----
>> #!/usr/local/bin/guile \
>> -e main -s
>> !#
>>
>> ;; How to run this program?
>> ;; Example:
>> ;; guile -e main -s factorial-script.scm 50
>> ;; Explanation:
>> ;; -e specifies the procedure to run
>> ;; -s specifies to run this as a script
>> ;; 50 is the number we take as input to the script
>
> To be usable as module, this needs to be defined as module:
>
> (define-module (fact)
>   #:export (fact))
>
>> (define (fact n)
>>   (if (zero? n) 1
>>       (* n (fact (- n 1)))))
>>
>> (define (main args)
>>   (display (fact (string->number (cadr args))))
>>   (newline))
>> ----8<----end-of-code---->8----
> …
>> chmod +x modules.scm
>> ./modules.scm 10 3
>
> Does it work with the added module definition and import?

Thank you for the above explanations.  I got confused by the this in the
documentation as well.  Trying the above suggestions, I still have a
problem.

I have the following two files:

fact:
--8<---------------cut here---------------start------------->8---
#!/run/current-system/profile/bin/guile \
-e main -s
!#
(define-module (fact)
 #:export (fact))

(define (fact n)
  (if (zero? n) 1
    (* n (fact (- n 1)))))

(define (main args)
  (display (fact (string->number (cadr args))))
  (newline))
--8<---------------cut here---------------end--------------->8---

fac:
--8<---------------cut here---------------start------------->8---
#!/run/current-system/profile/bin/guile \
-e (@@ (fac) main) -s
!#
(define-module (fac)
  #:export (main))

(use-modules (fact))

(define (choose n m)
  (/ (fact m) (* (fact (- m n)) (fact n))))

(define (main args)
  (let ((n (string->number (cadr args)))
        (m (string->number (caddr args))))
    (display (choose n m))
    (newline)))
--8<---------------cut here---------------end--------------->8---

But with Guile 3.0.8, this gives me:
--8<---------------cut here---------------start------------->8---
./fac 5 20
ice-9/read.scm:126:4: In procedure lp:
#<unknown port>:1:4: unexpected end of input while searching for: )
--8<---------------cut here---------------end--------------->8---

Which I don't understand.

-- 
Thanks,
Maxim




Information forwarded to bug-guile <at> gnu.org:
bug#36682; Package guile. (Tue, 13 Dec 2022 01:09:01 GMT) Full text and rfc822 format available.

Message #17 received at 36682 <at> debbugs.gnu.org (full text, mbox):

From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To: Arne Babenhauserheide <arne_bab <at> web.de>
Cc: 36682 <at> debbugs.gnu.org, Hans-Werner Roitzsch <hwroitzsch <at> posteo.net>
Subject: Re: bug#36682: Error in Guile scripting examples
Date: Mon, 12 Dec 2022 20:08:28 -0500
Hi,

Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes:

[...]

> I have the following two files:
>
> fact:
>
> #!/run/current-system/profile/bin/guile \
> -e main -s
> !#
> (define-module (fact)
>  #:export (fact))
>
> (define (fact n)
>   (if (zero? n) 1
>     (* n (fact (- n 1)))))
>
> (define (main args)
>   (display (fact (string->number (cadr args))))
>   (newline))
>
>
> fac:
>
> #!/run/current-system/profile/bin/guile \
> -e (@@ (fac) main) -s
> !#
> (define-module (fac)
>   #:export (main))
>
> (use-modules (fact))
>
> (define (choose n m)
>   (/ (fact m) (* (fact (- m n)) (fact n))))
>
> (define (main args)
>   (let ((n (string->number (cadr args)))
>         (m (string->number (caddr args))))
>     (display (choose n m))
>     (newline)))
>
>
> But with Guile 3.0.8, this gives me:
>
> ./fac 5 20
> ice-9/read.scm:126:4: In procedure lp:
> #<unknown port>:1:4: unexpected end of input while searching for: )
>
> Which I don't understand.

OK, so what is apparently problematic with modules is the use of '-e (@@
(module-name) proc-name)' with Guil modules.  For the 'fac' file above,
modifying it like this:

--8<---------------cut here---------------start------------->8---
 #!/run/current-system/profile/bin/guile \
 -e (fac) -s
 !#
 (define-module (fac)
   #:export (main))

 (use-modules (fact))

 (define (choose n m)
   (/ (fact m) (* (fact (- m n)) (fact n))))

 (define (main args)
   (let ((n (string->number (cadr args)))
         (m (string->number (caddr args))))
     (display (choose n m))
     (newline)))
--8<---------------cut here---------------end--------------->8---

works.  This relies on 'main' being defined and public.  I hope that
helps!

-- 
Thanks,
Maxim




This bug report was last modified 2 years and 183 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.