What does the following Guile scheme code do?
(eq? y '.)
(cons x '.)
The code is not valid in MzScheme, is there a portable equivalent across scheme implementations?
I am trying to port this code written by someone else. Guile seems to respond to '. with #{.}#, but I'm not sure what it means or how to do this in another scheme.
Okay, it seems that '. is valid syntax for (string->symbol ".") in Guile, whereas MzScheme at least requires |.| for the period as a symbol.
#{.}# is Guile specific way to define the symbol contains some delimiters of Scheme.
http://www.gnu.org/software/guile/manual/html_node/Symbol-Read-Syntax.html
For other Scheme dialect, there should be another way.
I'm surprised any Scheme system will accept a dot symbol at all. My advice is to use another symbol as (I'm sure you're aware) the dot is a shorthand to represent a pair, and even if you can find a Scheme that will take your code you will likely confuse anyone that has the unfortunate task of actually reading your code.
Related
In Common Lisp, when I want to use different pieces of code depending on Common Lisp implementations, I can use *features* and the provided notation of #+ and #- to check the availability of a given feature and proceed accordingly. So for example (taken from Peter Seibel's PCL):
(defun foo ()
#+allegro (do-one-thing)
#+sbcl (do-another-thing)
#+clisp (something-else)
#+cmu (yet-another-version)
#-(or allegro sbcl clisp cmu) (error "Not implemented"))
Is anyone aware of a similar mechanism for Scheme? There are sometimes subtle differences between different implementations of Scheme, which, when you're trying to be portable, would be nice to abstract away. One such case that comes to my mind is Racket not providing mutable pairs by default. Instead of writing e.g. (set-cdr! lst '(1 2 3)) you would have to use set-mcdr! and only after you ran (require racket/mpair). Of course, such things could be abstracted by functions and/or macros, but I think the Common Lisp approach is neat in this aspect.
The closest thing there is, is cond-expand (aka SRFI 0), which is available on some Schemes but not others (Racket, for example, doesn't have it, and your code won't compile if you try to use it). For those Schemes that do have it, it looks like a cond form, except you test for booleans that tell you things about the compiler/interpreter. On some Schemes you can detect which Scheme you're running on, while on others you can only check for SRFIs:
(cond-expand (chicken
'bok-bok-bok!)
((and guile srfi-3432)
'this-guile-is-full-of-SRFI!)
(else
'(might be MIT Scheme, whose cond-expand only tests for SRFIs)))
I am confused about eval. I looked at the specification of eval in schemers.org. It says
procedure: (eval expression environment-specifier)
It indicates to me that environment-specifier is mandatory requirement. However, when I tested eval using two interpreters -- the one at repl.it and Elk Scheme -- both of them work without environment-specifier. My question is: Are they both non-conformant interpreters or did I read the documentation at schmers.org wrong?
And then..
Elk Scheme has no problem evaluating (eval 5) and (eval (list + 5 6)) but the Scheme interpreter at repl.it is not able to evaluate them. The later will evaluate (eval `(+ 5 6)) fine but not the first two expressions. My question is: Is the behavior of the repl.it interpreter conformant?
How do other Scheme interpreters deal with the first two expressions?
The Scheme report is what you need to follow to write compatible programs. Other than that the implementations themselves can have their own syntax and procedures and it won't interfere since a standard conforming program wouldn't use them. Not all Scheme reports had eval mandatory so you need to find out which report it should conform to and if it needs some switch to follow the standard. eg. ikarus needs --r6rs-script as a switch to run R6RS programs correctly. I think Elk is R4RS so eval is not specified in that report and BiwaScheme seems to have references to R6RS in it's source so it should take a second argument. that it works is no proof it's conformant so you should dig a little in their documentation.
Also, everything defined as undefined in the report you might actually choose something and it's still according to report. E.g. I've seen define return the object that was bound and all the ! procedures return the object it mutated and it's all according to the report since any value is equal to the reports undefined value.
Also, very few errors in the report actually demands a error being signaled. Since it's not mandatory to signal errors its up to the developer to make sure they do not do anything that is considered an error. The implementations can actually return something like a incredibly wrong value, crash or if it's a nice implementation it signals an error. Any one of those are equally fine for the report. In fact this is one of them:
(define (test) "hello")
(string-set! (test) 0 #\H) ; might signal an error
(test) ; might evaluate to "hello", "Hello"
In most Scheme implementations you won't get any error and it will probably make test return "Hello". The report states this specifically to be an error so I guess it means you should never make a program like this to any Scheme interpreter since the outcome is undefined.
I've got a bunch of "legacy" Guile Scheme code that I want to get running in the Racket Scheme IDE. There appear to be enough differences to make this a non-trivial exercise. (My level of Scheme knowledge is the level to complete the The Little Schemer).
My question is:
What are the differences between Guile Scheme and Standard Scheme (in the Racket IDE)?
In light of these differences, in general, what are the steps I'll need to take to convert some Guile Scheme Code to standard Scheme?
Additional: (happy with divergence between Racket Scheme and R5RS/R6RS) - what I want is to get 'something' to run in the Racket IDE - rather than the Racket language.
If by "Standard Scheme (in the Racket IDE)," you mean the Racket language, i.e., what you get when you prefix your code with #lang racket, then the top four differences to look out for are:
a different module system
a different macro system (depending on how old your code is)
immutable cons-cells (unless you import mutable ones)
no one-armed ifs in Racket (use when)
To port code from Guile to Racket, find out which files are "at the bottom" of your dependencies, i.e., find the files that do not depend on other files.
Open such a file in Racket, add the line #lang racket at the top, and try to run it.
You will most likely encounter some "unbound identifier" errors.
If you are lucky, the function is present in Racket, but not included in the "racket" language. Search for the name in the Racket documentation, and if you find it, then use (require ...) to import the name into your program.
Then run the program again to find the next error.
Some function are named differently in Guile and Racket, so look up the name in the Guile documentation and see what it does. Then open the Racket documentation on the same subject, and see what it is called in Racket.
In some cases you may have to make bigger changes. If you can't find some piece of functionality in the Racket documentation, then try asking the mailing list. It could be that it simply has a different name, or that somebody implemented it and put it on PLaneT (thus it will no appear in the documentation until you have installed the package).
Example of importing srfi/1 into the R5RS language.
#lang r5rs
(#%require srfi/1)
(xcons 1 2)
Differences from R4RS code to modern Scheme?
One thing to look out for is that in R4RS the empty list '() counted as false, not it is interpreted as true.
See this question for more things to look out for:
Running SICP Pattern Matching Rule Based Substitution Code
See also this list of changes from the R5RS standard:
List of changes from R4RS to R5RS
I came across the following piece of syntax in Racket, could anyone tell me what it means? I tried Googling it to no avail.
symbol=?
If you're using DrRacket, then hit F1 to find this documentation:
(symbol=? symbol1 symbol2 symbol3 ...) procedure
Returns #t if the symbols are the same, i.e., if their names are spelled the same.
I think that the confusion here is that symbol=? looks like some syntax for some weird expression. Racket follows Scheme and Lisp tradition where the syntax is pretty minimal: identifiers are very permissive, so this whole thing is just a name of a function. (And see rm's answer for what the function actually does.)
I'm trying to work my way through Compilers: Backend to Frontend (and Back to Front Again) by Abdulaziz Ghuloum. It seems abbreviated from what one would expect in a full course/seminar, so I'm trying to fill in the pieces myself.
For instance, I have tried to use his testing framework in the R5RS flavor of DrScheme, but it doesn't seem to like the macro stuff:
src/ghuloum/tests/tests-driver.scm:6:4: read: illegal use of open square bracket
I've read his intro paper on the course, An Incremental Approach to Compiler Construction, which gives a great overview of the techniques used, and mentions a couple of Schemes with features one might want to implement for 'extra credit', but he doesn't mention the Scheme he uses in the course.
Update
I'm still digging into the original question (investigating options such as Petit Scheme suggested by Eli below), but found an interesting link relating to Gholoum's work, so I am including it here.
[Ikarus Scheme](http://en.wikipedia.org/wiki/Ikarus_(Scheme_implementation)) is the actual implementation of Ghuloum's ideas, and appears to have been part of his Ph.D. work. It's supposed to be one of the first implementations of R6RS. I'm trying to install Ikarus now, but the configure script doesn't want to recognize my system's install of libgmp.so, so my problems are still unresolved.
Example
The following example seems to work in PLT 2.4.2 running in DrEd using the Pretty Big
(require lang/plt-pretty-big)
(load "/Users/donaldwakefield/ghuloum/tests/tests-driver.scm")
(load "/Users/donaldwakefield/ghuloum/tests/tests-1.1-req.scm")
(define (emit-program x)
(unless (integer? x) (error "---"))
(emit " .text")
(emit " .globl scheme_entry")
(emit " .type scheme_entry, #function")
(emit "scheme_entry:")
(emit " movl $~s, %eax" x)
(emit " ret")
)
Attempting to replace the require directive with #lang scheme results in the error message
foo.scm:7:3: expand: unbound identifier in module in: emit
which appears to be due to a failure to load tests-driver.scm. Attempting to use #lang r6rs disables the REPL, which I'd really like to use, so I'm going to try to continue with Pretty Big.
My thanks to Eli Barzilay for his patient help.
The language he uses is most likely Chez Scheme. Regardless, the R5RS language in PLT is a pretty strict version of R5RS, with extensions like square brackets throwing errors -- and you may get more mileage using the default #lang scheme language. (Or, if that fails, try and see if you can work with Petit -- the free version of Chez.)
You can see setup instructions for running it here on Ubuntu x86.
The installation download for Petite Scheme are here.