Daniel Patterson
Daniel Patterson

Reputation: 92

How do I make a modified version of a Racket #lang? (adding / removing a few definitions)

I'd like to take an existing language, say, htdp/isl, and add a few definitions that aren't included by default. I can (require blah) at the top of every file, but I want to just be able to write #lang my-modified-isl at the top, and get those definitions along with the rest of the language. It's okay if this only works for languages that are "close" to Racket (i.e., have a boring reader).

Upvotes: 2

Views: 134

Answers (1)

Leif Andersen
Leif Andersen

Reputation: 22332

In Racket, a #lang is basically just any module that provides #%module-begin (and optionally a reader/parser). As an example, you can check out my SML package (no relation to Standard ML), which is almost vanilla Racket, but a few custom tweaks to make it really good for describing data (like YAML).

Let's say you want to make a version of vanilla Racket, but that includes the function standard-fish, and lacks a divide (/) function. You could make your file:

#lang racket ; custom-racket.rkt
(require pict)
(provide (except-out (all-from-out racket) /)
         standard-fish)

And now you can use s-exp to put your new language in the #lang line:

#lang s-exp "custom-racket.rkt"
(standard-fish) ; A fish
(/ 10 2) ; Error, `/` undefined

(Note that if you want to get rid of S-Expressions entirely and replace the reader, you would use #lang reader instead.)

Finally, you can package your file into a custom Racket package to use directly. Rename custom-racket.rkt from above to custom-racket/main.rkt, add an info.rkt file, and install the package:

$ mkdir custom-racket
$ cd custom-racket
$ vim main.rkt
  #lang racket ; custom-racket.rkt
  (require pict)
  (provide (except-out (all-from-out racket) /)
           standard-fish)
  (module reader syntax/module-reader
    custom-lang)
$ vim info.rkt
  #lang info
  (define collection "custom-racket")
$ raco pkg install

And now you can use custom-racket directly in the #lang line:

#lang custom-racket
(standard-fish) ; A fish
(/ 10 2) ; Error, `/` undefined

Upvotes: 3

Related Questions