Scheme R5RS define-syntax ignored? - scheme

Just started learning Scheme.
I'm using Dr. Racket as my compiler/interpreter.
I need some String functions (string-replace to be exact), so I copied from SRFI 13.
When I test it, it shows..
reference to undefined identifier: let-string-start+end
That's defined with
define-syntax let-string-start+end
It seems that it's being ignored? What's actually happening?

You don't need to manually copy and paste items from SRFI 13: it is built into Racket. In fact, most of the major SRFI libraries are bundled with Racket: http://docs.racket-lang.org/srfi/index.html
If you are using the r5rs language in Racket, you can pull in SRFI 13 with the following line:
(#%require srfi/13)
The strange-looking #%require is a Racket-specific hook that allows an r5rs program to load library modules from Racket.
So an r5rs program in Racket would be something like this:
(#%require srfi/13)
(display (string-replace "foo world" "hello" 0 3))
(newline)
If, instead of using the basic r5rs language, you use the full-fledged #lang racket instead, importing SRFI 13 would look similar. Here's a small program in #lang racket that does the same as the previous program:
#lang racket
(require srfi/13)
(string-replace "foo world" "hello" 0 3)
Unfortunately, the error you're reporting doesn't have enough information to accurately diagnose the problem. I suspect an incomplete copy-and-pasting somewhere, since you mention that you copied from SRFI 13. One reason why I think you may have mis-copied the code is that you mention defining it with:
define-syntax let-string-start+end
and that line is actually missing some crucial parentheses; in the original source, there's a leading paren at the front of that line.
But you shouldn't try to cull bits and pieces out of the SRFI implementation by hand, at least not until you're more familiar with Scheme. Simplify by loading the entire library.

Related

Implementation dependent code in Scheme

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

Little Schemer - IDE [duplicate]

I'm starting to read the Little Schemer and now instead of PLT Scheme we have Racket. I would like to know if Racket is suitable for doing the exercises in the book or do I need to get another true Scheme compiler. Before I forgot to tell you, my OS is Windows x64.
The book, language and paradigm is complex enough, I would love to avoid struggling with a compiler.
DrRacket is the (r)evolution of DrScheme; DrRacket will work perfectly for the exercises in "The Little Schemer". Just don't forget to:
In the Language dialog, choose "Use the language declared in the source"
Write #lang racket at the top of each file you create
Implement the atom? predicate in each file as explained at the very beginning of the book
If you're going to re-implement an existing procedure, do so in a separate tab or window, because trying to rewrite a procedure in the edit window will result in a duplicate definition for identifier error. If necessary, use several files for saving the procedure definitions
You really just need the atom? function. What’s described in the book's preface is essentially:
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
As mentioned, it should satisfy this test:
(atom? '()) ;=> #f
Note that there is also a definition in Racklog that will not satisfy that test.
A more detailed discussion on atom? is here.
Despite the book's suggestion to implement add1 and sub1, Racket does already provide them.
BTW, I use Vim for editing Racket, but a few other editors are capable.
I have had the author of the book as a professor. He now uses Racket himself, but he uses Emacs as a text editor.
Racket/Scheme are interchangeable. You should be able to answer any exercise with it. Good luck.
Also, I recommend downloading Dr. Racket as your interpreter.

Little Schemer and Racket

I'm starting to read the Little Schemer and now instead of PLT Scheme we have Racket. I would like to know if Racket is suitable for doing the exercises in the book or do I need to get another true Scheme compiler. Before I forgot to tell you, my OS is Windows x64.
The book, language and paradigm is complex enough, I would love to avoid struggling with a compiler.
DrRacket is the (r)evolution of DrScheme; DrRacket will work perfectly for the exercises in "The Little Schemer". Just don't forget to:
In the Language dialog, choose "Use the language declared in the source"
Write #lang racket at the top of each file you create
Implement the atom? predicate in each file as explained at the very beginning of the book
If you're going to re-implement an existing procedure, do so in a separate tab or window, because trying to rewrite a procedure in the edit window will result in a duplicate definition for identifier error. If necessary, use several files for saving the procedure definitions
You really just need the atom? function. What’s described in the book's preface is essentially:
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
As mentioned, it should satisfy this test:
(atom? '()) ;=> #f
Note that there is also a definition in Racklog that will not satisfy that test.
A more detailed discussion on atom? is here.
Despite the book's suggestion to implement add1 and sub1, Racket does already provide them.
BTW, I use Vim for editing Racket, but a few other editors are capable.
I have had the author of the book as a professor. He now uses Racket himself, but he uses Emacs as a text editor.
Racket/Scheme are interchangeable. You should be able to answer any exercise with it. Good luck.
Also, I recommend downloading Dr. Racket as your interpreter.

Differences between Guile Scheme and Standard Scheme (in Racket IDE)?

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

Do you have to use display to output stuff using r6rs?

Background: I am new to scheme, and am using DrScheme to write my programs.
The following program outputs 12345 when I run the program as r5rs:
12345
However the following program outputs nothing (it's an r6rs program):
#!r6rs
(import (rnrs))
12345
That being said, I can get it to output 12345 by doing this:
#!r6rs
(import (rnrs))
(display 1235)
Is that something new with r6rs, where output only occurs when specifically specified using display? Or am I just doing something else wrong
This is a subtle issue that you're seeing here. In PLT, the preferred mode of operation is to write code in a module, where each module has a specification of the language it is written it. Usually, the default language is #lang scheme (and #! is short for #lang). In this language, the behavior is for all toplevel non-definition expressions to display their values (unless they're void -- as in the result of most side-effects). But the #lang r5rs and #lang r6rs don't do the same -- so these toplevel expressions are evaluated but never displayed.
The reason you did see some output with the R5RS language is that you didn't use it as a "module" (as in #lang r5rs), but instead used the specific R5RS "language level". This language level is more compatible to the R5RS, but for various subtle reasons this is not a good idea in general. Using #lang is therefore generally better, and if you want to save yourself some additional redundant headaches, it'll be easier if you stick with #lang scheme for now, and worry about standards later. (But YMMV, of course.)

Resources