Cannot work out how to run .scm (using guile or scm) files
Asked Answered
D

3

6

I have created a abc.scm file and tried to compile it to a binary (or whatever guile scheme compiles to) using "guild compile", "scm" and "guile" commands in terminal in Ubuntu.

For "guild compile abc.scm", I get the output "wrote `/home/tarunmaganti/.cache/guile/ccache/2.0-LE-8-2.0/home/tarunmaganti/abc.scm.go'" I find the file and run like this - "./abc.scm.go" which says permission denied.
When I give the necessary permissions using "chmod 755" or "chmod 777", I get an error like - "bash: ./abc.scm.go: cannot execute binary file: Exec format error".

The "scm whatever-file-name.scm" just opens up the scm interpreter.

The "guile whatever-file-name.scm does nothing.

The link of official GNU/Guile Scheme isn't very helpful.

Please, help me. I would like to create a guile scheme script file. Compile it and run it as C/C++ program. Is it possible? If compilation isn't possible, I would like to know, how to at least run the script file of GNU/guile scheme or MIT-Scheme.

{Step-by-step is highly appreciated, I'm still a beginner in using Ubuntu and also in Scheme.}

Thanks in advance.

Doerrer answered 12/6, 2016 at 10:11 Comment(1)
I have years of Lisp and Linux experience and have the exact same problem so don't feel bad for being a beginner :) Some things are just confusing.Canvas
C
5

You can use the shebang notation to create a Guile script (the -s is optional in newer versions of Guile):

#!/usr/bin/guile -s
!#
(display "Hello, world!\n")

Notice the !# on the second line. Guile treats the #! as the start of a block comment (similar to what #| is in standard Scheme), which has to be terminated using !# (similar to |# in standard Scheme).

If you want your script to pass any command-line options to Guile itself, then read about the meta switch. Here's an example of such:

#!/usr/bin/guile \
-e main -s
!#
(define (main args)
  (if (null? (cdr args))
      (format #t "Hello, world!~%")
      (for-each (lambda (name)
                  (format #t "Hello, ~a!~%" name))
                (cdr args))))
Cornstarch answered 12/6, 2016 at 16:9 Comment(3)
I have followed the convention of top lines. What I asked was how do I run that script using Guile or SCM interpreters or How do I compile the script file and run an executable.Doerrer
@TarunMaganti You can't create a standalone binary in Guile, at least not in 2.0 or below. With the shebang lines I recommended, you can simply make the script file executable and run it.Cornstarch
Thank you! But then, what is guild compile used for? It says that .scm files are automatically compiled. Also, could you give me a reference on how to run scripts.Doerrer
C
3

Apparently guile foo assumes that foo is a Scheme source file. If foo is a precompiled binary .go file it tries to treat it as a text file anyway and compile it a second time, which fails. I could not find any equivalent command line syntax for executing a pre-compiled .go file.

However, you can get almost the same effect as follows:

  • Write a source file foo.scm that exports a main procedure:
(define-module (foo)
  #:export (main))

(define (main)
  (display "Hello world!")
  (newline))
  • Pre-compile it with guild compile -o foo.go foo.scm
  • Write a shell script that runs guile -C "$PWD" -c "(use-modules (foo)) (main)". The -C dir flag (capital C) tells it to load pre-compiled files from the directory dir. The -c expr flag (lowercase c) tells it to evaluate the Scheme code expr which in this case just does use-module to load the pre-compiled module and then calls our main procedure.
Canvas answered 21/5, 2019 at 21:27 Comment(0)
T
2

Guile's compiler is like Java's compiler: it produces bytecode that is then run in Guile's VM. I don't know of any way to go straight from Guile Scheme code to native code. Guile is really meant to be an extension language that allows you to add Scheme scripting to your C/C++ program.

I don't know much about MIT Scheme, but from what I can tell it also does not compile to a standalone executable. Feel free to correct me on that.

There's a way around all this, though. As long as you don't mind a dependency on libguile, you can write a wrapper in C/C++ and hand libguile a string containing your Scheme code. There's a basic example given in the Guile manual for Dia here. Create your script in a header file and wrap it in a null-terminated C string, then (after a bit of boilerplate and whatnot) evaluate it with scm_eval_string().

If you want to write Scheme and output native binaries, I've heard good things about Chicken.

Tercet answered 21/8, 2016 at 19:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.