Is it possible to use rackunit in DrRacket with language set to sicp, and if so, how? - racket

I'm starting to work through SICP using DrRacket. I installed the sicp package, and declared #lang sicp at the top of the unit test file and then (require rackunit "xxx.scm"), but I get an unbound identifier error. Is there a mistake, or is it not possible to use rackunit with the sicp package in this way?

You need to use #%require.
#%require is actually a primitive type in the lowest level of racket and it is slightly different than require:
#lang sicp
(#%require rackunit "xxx.scm")
The file you want to test becomes a module so you can use it from other code by providing the identifiers you want to expose:
(#%provide procedure-name)
You can also just require a few needed forms. eg. error and time from racket/base:
(#%require (only racket/base error time))
A hint on finding out where they are is to search the online manuals or from Help > Racket documentation in DrRacket. Eg. here is an example of searching error where you have many choices, but the racket prefixed ones are the ones you're looking for.
NB: Not all forms are compatible across languages. Eg. R5RS has different pair implementation than #lang racket

Related

How to figure out the minimal set of provides from a racket expander module

I am working through the exercises in Matthew Flatt's Creating Languages in Racket. I am currently at step 3, where #lang s-exp "txtadv.rkt top line for a language "client" (world.rkt) is used. In this case, I am assuming that the reader is the s-exp racket reader and that the expander is "txtadv.rkt". Per the text:
"The exports of txtadv.rkt completely determine the bindings that are available in world.rkt—not
only the functions, but also syntactic forms such as require or lambda. For example, txtadv.rkt could
supply a lambda binding to world.rkt that implements a different kind of function than the usual
lambda, such as functions with lazy evaluation."
I see then that txtadv.rkt has this:
(except-out (all-from-out racket) #%module-begin)
I understand by this: re-export (provide) all the imports I got from racket, except for #%module-begin.
What I want: I would like to figure out a proccess to further trim-down this provide list as I do not want to export all of racket.
Things I have tried so far:
I changed at the top of txtadv.rkt to require racket/base and then put this:
(except-out (all-from-out racket/base) #%module-begin)
That worked, but it's still too coarse and fails at the next step with no clue other than revert to require racket.
I started trying to figure out (guess) what s-exps were in "world.rkt" the client, that would require extra syntax:
I commented out the (except-out (all-from-out racket)..)
started "guessing" exports:
that were missing, i.e. define-one-verb
racket functions/forms that are used in macros like symbol->string, list
For all I have tried, the expander txtadv.rkt passes Ctrl-R / syntax-chek, but in the client world.rkt I keep getting:
txtadv.rkt:84:4: define-one-verb: bad syntax in: (define-one-verb north (= n) "go north")

How to find which module to require for a racket symbol?

When encountering an unbound identifier error for a racket symbol, how should one find out which module to require for the symbol?
For example, I encountered the following error while execute a racket file (as of 8.6):
....rkt:39:17: symbol=?: reference to an unbound identifier
; at phase: 1; the transformer environment
I tried (help symbol=?), which correctly led me to its documentation page, on "Section 4.2 Booleans". But how can I tell which module to import so that I can have symbol=??
I tried
(require (for-meta 1 racket/base))
but the error remains.
You can get that information from DrRacket Docs- when you search for any symbol, you will see a list of packages/ libraries that provide it.
Look at the results for symbol=?. The most straightforward solution is to use #lang racket (at the beginning of the code) or (require racket/bool).
This is even written in "Section 4.2 Booleans"- there are symbols boolean?, not and immutable?, followed by "4.2.1 Boolean Aliases":
(require racket/bool)
package: base
The bindings documented in this section are provided by the racket/bool and racket libraries, but not racket/base.

Usage of "define-type" in Racket gives an error

Lately I'm learning Racket, and I'm having some difficulties with understanding the "define-type" syntax. I've tried the following code:
#lang racket
(define-type Num Number)
but it outputs the following error message:
define-type: unbound identifier in module in: define-type
May anyone help me dealing this error? I have read all possible documentation and it seems like it should be working.
There is a reason every Racket program starts with a line beginning with #lang: Racket is not just a programing language, but an ecosystem of programming languages. Every file (and more specifically, every module) can be in its own programming language, and they can all talk to each other with ease.
By default, Dr. Racket creates new files with a #lang racket line at the top. This is the “Racket language”, but it is not the only language provided by the “Racket system”, which actually includes dozens of languages, some not too different from #lang racket, others almost entirely unrelated.
When you want to use Typed Racket, you need to opt in to using that language instead of ordinary #lang racket, which is dynamically typed. You can do this by writing #lang typed/racket at the top of your program.
#lang typed/racket
(define-type Num Number)
Now all the features of Typed Racket will be available to you within that module.

Portable load/include of define-syntax in R5RS Scheme?

I'm trying to write something that works in both DrRacket/plt-r5rs and Gambit/gsi.
The problem I'm having is that (load "foo.scm") in Gambit does not load define-syntax-blocks. Using (include "foo.scm") in Gambit works, but of course results in a syntax error in DrRacket.
Is there any way to solve this so that I can write portable R5RS code?
Things I've tried:
Redefining (include "foo.scm") to (load "foo.scm") and vice versa. Problem: Illegal to redefine macros in Gambit.
Wrapping said redefinitions in an (if gambit ...). Problem: Illegal to put define inside if(unless inside another define).
Passing string with filename to an include in the library file instead. Problem: Includes in Gambit seem to happen before interpretation starts.
In case it helps: In Racket you can use include in r5rs files:
#lang r5rs
(#%require (only racket include))
(include "foo.scm")
If you define #%require to do nothing in Gambit, then you can use the same source file in both implementations.
It's very hard to write a module that's compatible with both Gambit and Racket.
There are indeed ways you can test for a specific implementation and define things conditionally. There are, in fact, two systems for doing this: SRFI 0 and SRFI 7. Most implementations support one or the other. Not very many support both.
Gambit supports SRFI 0. Racket supports SRFI 7.

Why am I getting an unbound error for "atom?"

I'm trying to go through "The Little Lisper" and already running into snags in the first chapter. I'm relatively new to Emacs (which has fueled my interest in learning Lisp and clojure). I downloaded the Mit-scheme app, and am working the exercises on Edwin.
I'm trying:
(atom? (cons a l))
where a is an atom and l is a list already defined. I get the following error:
;Unbound variable: atom?
Why? I have no problems using the "null?" function. I thought "atom?" is an internal function checking to see if the value returned is an atom.
Any explanation would be much appreciated. I still haven't set up my emacs to run scheme, and the minor differences between all the lisp dialects is testing my patience.
In "The Little Schemer" ("The Little Lisper"'s updated version) the atom? procedure is defined as follows (because atom? doesn't exist in Scheme):
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
If you're following an old version of the book, I advise you to either look for a newer version or use the same programming language used in the book: Common Lisp for The Little Lisper, Scheme for The Little Schemer - and Racket is a great Scheme IDE to work with! take a look at this answer for some tips when going through The Little Schemer using Racket.
I'm trying to go through "The Little Lisper"...
I downloaded the Mit-scheme
Common Lisp and Scheme are very different languages.
You have to either use a different book (e.g., SICP) to match your language implementation or a different language implementation (e.g., clisp or sbcl) to match your book.
Take a look at the Scheme R5RS specification; it includes a list of functions and syntactic keywords. Although not part of the Scheme standard, mit-scheme has a function apropos that will find functions (other stuff) with a given name. try:
(apropos "atom")
(but it won't show anything, :-).
An atom is something that is not a 'cons cell' (generally, if I remember my CommonLisp). In Scheme you could implement one as:
(define (atom? thing) (not (pair? thing)))
Note: this definition of atom? is consistent with CommonLisp atom.