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

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

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

Related

read-syntax function for postfix interpreter in racket

I write a read-syntax function but ı get this error. my read-syntax function is this:
(define (read-syntax path port)
(for([line (port->lines port)])
(parse-line line)))
The error is this:
Module Language: only a module expression is allowed, either
#lang <language-name>
or
(module <name> <language> ...)
Each racket file is a module.
The file must start with defining the module.
The easy starting way is to have
#lang racket
as the first line of your module.
Description of this is in the Racket Guide https://docs.racket-lang.org/guide/intro.html

Racket Not Loading Module File

I am trying to load my racket file so that I can test it interactively similar to what DrRacket allows.
test.rkt:
#lang racket
(define blah 1)
I am trying to run it using this command:
racket -it test.rkt
Which works and I get the usual output:
Welcome to Racket v6.6.
>
But when I try to get the value of blah it doesnt work:
> blah
blah: undefined;
cannot reference undefined identifier
context...:
/usr/share/racket/collects/racket/private/misc.rkt:88:7
How can I run this program interactively?
The easiest way is probably to use xrepl: (require xrepl) (or add the require to your .racketrc), then use the ,enter command to “move inside” the module:
$ racket
Welcome to Racket v6.6.0.4.
> ,enter test.rkt
> blah
1
You are very close. You just need to provide blah so that it can be used from the repl.
#lang racket
(provide blah)
(define blah 1)
And then when you run it with racket -it test.rkt, you get:
Welcome to Racket v6.6.0.4.
> blah
1

Geiser and Racket variable have been defined previously and cannot be redefined

I'm trying to use geiser-mode in emacs to run racket code.
I've been able to install geiser-mode and launched racket.
Yet when I run a definition twice I got the following error.
this name was defined previously and cannot be re-defined
here is simple example
(define a (* 1 4))
a
run twice
In the debugger
#a: this name was defined previously and cannot be re-defined
#in: a
racket appears to behave differently in a file and the REPL. This file will throw an error:
#lang racket
(define a 5)
(define a 6)
And this REPL session will not:
> (define a 5)
> a
5
> (define a 6)
> a
6
The behavior is because of the way modules work. When working in a file, there is an implicit module. Once the symbol a has been defined in that module another symbol with the same name cannot be defined within that module. The REPL simply expands forms without all the ceremony of modules.

How do I get the program name in Racket?

I would like to programmatically detect the program name within Racket code. This can be done in Chicken Scheme with:
#!/bin/sh
#|
exec csi -ss $0 ${1+"$#"}
exit
|#
(define (main)
(display (format "Program: ~a\n" (program-name)))
(exit))
(if (not (equal? (program-name) "csi"))
(main))
How could I emulate this in Racket?
Is this what you want?
(find-system-path 'run-file)
See also racket/cmdline for how to parse the commandline.
http://docs.racket-lang.org/reference/Command-Line_Parsing.html
Note: for this particular pattern of execution, to have a library module that can also be run as a main, use a submodule named main. See Main and Test Submodules, which shows how to do this.

mit-scheme vim slimv: " read-error: no dispatch function defined for #\F"

It's a very easy scheme function
(define member?
(lambda (a lat)
(cond
((null? lat) #f)
(else (or (eq? (car lat) a)
(member? a (cdr lat))
))
)
)
)
However, when I pressed ,d or ,F in vim to run this function, there is an error
/home/oo/tmp/t.scm:64 read-error: no dispatch function defined for
#\F
Line: 4, Column: 21, File-Position: 64
Stream: #<SB-SYS:FD-STREAM for "file /home/oo/tmp/t.scm" {AC84DA9}>
Chris already pointed out that you tried to use Scheme code with a Common Lisp swank server.
You need to run a Scheme swank server (e.g. swank-mit-scheme.scm, also included in Slimv).
Normally Slimv should autodetect MIT scheme on Linux without any tweaking in the .vimrc. For the autodetection to work properly you need MIT Scheme installed and the scheme command be available.
I suggest that you remove any Slimv related settings from your .vimrc. Then load the .scm in Vim and type this command:
:echo SlimvSwankCommand()
If Scheme was autodetected then this should print the command that runs the Scheme swank server (search for swank-mit-scheme.scm in the output). If the autodetection was unsuccessful then either you don't have the scheme command or Slimv did not find swank-mit-scheme.scm. In this case you need to tell Slimv the command to run the Scheme swank server. You can do in by adding a similar command to your .vimrc:
let g:slimv_swank_cmd = '! xterm -e scheme --load /your-path-to/slime/contrib/swank-mit-scheme.scm &'
But do this only if autodetection fails. If you need some more assistance, please feel free to contact me, I'm the author of Slimv.