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

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.

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

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

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

how can I create a new language in racket?

I would like to create a new language that has the same syntax as typed racket, but when executed will do two things:
run the given program as typed racket
if type checks, then translates the input into another language (say python). I am planning to write a translator from typed racket forms to python syntax.
Any suggestions on how to start or pointers to some skeleton code? I have read this tutorial but it mostly talks about creating new syntax which I don't need in my case.
I understand how I can write racket code to translate from one language to another, what I don't get is how I can do both of the above, i.e., first run it as another language, and then do something else with the same input.
It sounds like you want to make a language with a new #%module-begin form. This form is either inserted by the reader (when you do a #lang .... line at the top of your file, or by the language if you wrote the module out by hand. Either way, its generally associated with your language definition. This macro has full access to the entire module's unexpanded syntax. So for example, a macro like this:
(provide (rename-out [-module-begin #%module-begin]))
(define-simple-macro (-module-begin body ...)
(#%module-begin
(writeln '(body ...))
body ...))
Would create a language that does two things:
Print out the body of the code (as an s-expression), and
Run the body with the #%module-begin that the language definition was written in.
You can see how you can use this technique to grab the body of your program twice, and do two different things with it. So let's try running this example. First, lets take the sample from above, and put it in a file "mylang.rkt":
#lang racket
(provide (rename-out [-module-begin #%module-begin])
(except-out (all-from-out racket) #%module-begin))
(require syntax/parse/define)
(define-simple-macro (-module-begin body ...)
(#%module-begin
(writeln '(body ...))
body ...))
And now we can write a program in mylang like this:
#lang s-exp "mylang.rkt"
(+ 1 2)
And when you run it, you'll get something like this:
((+ 1 2))
3
First its printing out the program text, then running it.
You can read more about this process in a paper I wrote discussing this aspect of the Video language. You might also find the book Beautiful Racket to have some examples you might find useful.

"Define" is undefined in my lisp compiler (Steel Bank Common Lisp)

I am studying the book on SICP (Structure and Interpretation of Computer Programs) which require me to learn lisp so i installed a lisp compiler called SBCL (Steel Bank Common Lisp) for windows. The thing is i came across this code from the book:
(define pi 3.14159)
(define radius 10)
(* pi (* radius radius))
Saved it on notepad++ as filename.lisp and run it.
An Error occurred which says:
"The function COMMON-LISP-USER::DEFINE is undefined."
Why is this so? How do i make this work?
SICP is a book about a programming language called "Scheme". It says so in the foreword of the book. In fact, here's the website of the book: http://mitpress.mit.edu/sicp/
SBCL is an implementation of a programming language called "Common Lisp". define is not a predefined function (or other form) in Common Lisp.
The solution is either for you to learn Common Lisp from a book about that, or to get an implementation of Scheme.

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.