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.
Related
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
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.
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.
Can someone please explain what the specific issues are with using the cl package in elisp? As a new coder in emacs I feel as though I'm making a mistake whenever I reach for the (require 'cl) option. I have read and understood the byte-compilation issue with the cl package. I have looked at the old arguments and have no wish to revive them. I am also not looking for any generalist comment on whether common-lisp is better than x brand lisp.
What I would like to know is practically how to use common-lisp so that any elisp I write will have a good chance of being accepted by the majority of elisp coders. Specifically, should I avoid using common lisp entirely, or are there some parts of the language that are acceptable to everyone and some parts where a good majority of coders would snigger and scoff at?
Without wishing to limit the breadth of the answer, is this:
(mapcar (lambda(x) (* x x)) '(1 2 3))
much more acceptable than this:
(require 'cl)
(loop for el in '(1 2 3) collect (* el el))
While using a lot of third-party libraries and writing some of my own eLisp code, I never encountered the situation when using CL package resulted in a name conflict. So, I'd be tempted to say that the argument against using CL is nothing but puritanism (in the original sense of the word, not meaning the religious side of things).
But, if you are planning on a very long time support and you want to have some sort of a backup, here's what I would do (but I'm not doing that myself, because fixing things once they are broken seems to be a better tactic). For the functions in CL package that you are using, create a special file, where you defalias all of them to have a cl- prefix. So, for example, instead of having a (position ...) you would have (cl-position ...). Theoretically will save you the problem of forward compatibility. However functions don't get removed instantly, you'll get a warning ahead of time of them being deprecated, and will have a lot of time to update. Up to you, really.
Loop macro in Common Lisp is a controversy all by itself, it is not a typical construct for the language and that's why, for example, the iterate library exists. It also requires that you learn "the loop mini-language" to use it well, which is sort of a small domain-specific language, and there's really no requirement that this kind of construct use one. BUT, loop has its strong sides. List processing functions such as mapcar or reduce will serve you well in more trivial cases, like the one you have in your example, but in the less trivial cases loop is going to be a better and also less verbose way of doing the same thing.
Have you read the macros section of the manual? Using macros such as your loop example is perfectly okay.
But you would use eval-when-compile around the require.
In fact (eval-when-compile (require 'cl)) appears 66 times just in the root lisp folder in my Emacs.
Unless you plan to integrate your code in Emacs use the CL package, and put this snippet in your .emacs to disable the warnings.
(byte-compile-disable-warning 'cl-functions)
Note: You can find some advices on elisp programming on nicferrier's blog.
Is it any analogies to Scheme define-syntax in ELisp?
In define-syntax I can specify some keywords and in elisp defmacro seems I cant.
EDIT: Seems I either do not understand you well, or my question is not clear.
In scheme it is possible to define macro with reserved words like
(loop for a in some-list
(loop while …
In Emacs Lisp I found not way to introduce such sugar.
At most, I can make for macro, that must be called like
(loop-for a list
(do-a lot of stuff…)
Readability matters
Both Scheme and Elisp have macro systems.
The "keywords" define-syntax and defmacro both introduce a name for a user defined macro.
At the time a macro, foo, is used in actual code, say (foo 1 bar) the macro expander must determine how to rewrite the given form, (foo 1 bar), into a simpler form that do not contain user macros. The macro expander calls the function that was defined at the time the macro foo was defined. I.e. it calls the function you specified with define-syntax or defmacro with an representation of the form, (foo 1 bar). The representation can be as "syntax objects" or plain lists (this differs in different macro systems).
This is my take on the similarities between define-syntax and defmacro.
The macro systems of R5RS Scheme and Elisp are different though.
The macro expander associated with foo can in R5RS Scheme be specified with the help of syntax-rules. This allows you to use pattern matching to specify the rewrite rules (internally the syntax-rules form will evaluate to function).
Other differences: The macro expansion algorithm will in R5RS Scheme help you agains inadvertently introduce names clashing with names from other parts of your program (say from a library, you did not write your self). Historically
Due to the way namespaces works in Lisp, this problem is not that big a deal in Lisp, but it is possible to make mistakes.
Historically Scheme and Elisp both used the same macro expansion algorithm, but then Schemers started experimenting with other algorithms. The "syntax-rules" systems was introduced in R5RS, but the evolution didn't stop there. These days all modern Scheme implementation have (variants of) the "syntax-case" system.
Some implementation have done work to make this expansion algorithm work with modules (Racket, R6RS-implementations, and others).
In short when you read about Scheme macro systems, take care to examine precisely which variant you are reading about. If you are reading about restrictions, then most likely you have found a text on the (now rather old) syntax-rules system.