This library provides a Racket kernel for Jupyter, enabling interactive notebook-style programming with Racket.
After installing the iracket package, you must register the IRacket kernel with Jupyter. Kernel registration can be done either through the raco iracket install command or by using the iracket/install module.
If the jupyter command is not in your executable search path, you must tell the installer the absolute path to the jupyter executable using the --jupyter-exe flag or #:jupyter-exe keyword argument. The installer runs jupyter --data-dir to find the directory where it should install the IRacket kernel.
If the racket command is not in your executable search path, or if you
want to register a kernel that uses a specific version of Racket, then you must
tell the installer the path to the executable to use. The executable must
support the same command-line interface that the racket executable
supports, but it does not have to be named racket—
Note that if you register the kernel with a non-version-specific Racket command (the default) and then change that command to run a different version of Racket (for example, by changing your PATH or by installing a new version of Racket over the old one), then Jupyter will try to use the new version of Racket to run the IRacket kernel. If the iracket package is not installed in the new version, this typically results in an error like “collection not found for module path: (lib "iracket/iracket")”. The same error will occur if you try to run the kernel after removing the iracket package.
Changed in version 1.1: Added raco iracket command.
|(require iracket/install)||package: iracket|
(install-iracket! [ #:jupyter-exe jupyter-exe #:racket-exe racket-exe]) → void?
jupyter-exe : (or/c (and/c path-string? complete-path?) #f) = #f racket-exe : (or/c path-string? 'auto 'this-version) = #f
Added in version 1.1 of package iracket.
The IRacket kernel does not support Racket’s #lang syntax for selecting languages, for the same reason that syntax doesn’t work at the Racket REPL. That is, #lang is a syntax for whole modules, whereas both the REPL and Jupyter work with top-level forms and generally receive them one at a time. See also The Top Level (REPL) Is Hopeless.
Instead of general #lang support, IRacket recognizes #lang iracket/lang as a special declaration for adjusting the notebook’s language.
#lang iracket/lang #:require lang-mod maybe-reader
| #:reader reader-mod
Creates a new empty namespace, populates it by requiring lang-mod (a module path), and installs it as the kernel’s current namespace, used for evaluation. The namespace shares the module instances of the kernel’s original namespace, but it does not include previous top-level definitions.
If reader-mod is given, the kernel’s reader is set to the read-syntax export of reader-mod (a module path); otherwise the kernel’s reader is set to Racket’s read-syntax.
Warning: If reader-mod is given, its read-syntax export must be suitable for reading top-level forms. For example, scribble/reader is suitable, but at-exp/lang/reader is not suitable, because it provides a whole-module meta-reader.
If a cell contains #lang iracket/lang, it must be the first thing in the cell; no other forms, comments, or even whitespace can appear before it. The declaration does not have to appear in the first cell in the notebook; in fact, multiple cells may contain language declarations. The declaration takes effect when it is evaluated, and it affects the rest of the current cell and subsequent evaluations, until the kernel is restarted or until the next #lang iracket/lang declaration is evaluated.
#lang iracket/lang #:require racket/base #:reader scribble/reader
Added in version 1.2.
Due to the combination of Racket’s macro system, its recursive top-level environment, and the fact that the REPL receives and processes forms one at a time, the Racket REPL occasionally produces unexpected behavior. These problems are known in the Racket community as “the top level is hopeless”. The same problems occur in Jupyter notebooks.
For example, consider the following program:
; range : Real Real -> Real ; Compute the size of the given interval. (define (range x y) (cond [(<= x y) (- y x)] [else ; swap to normalize, try again (range y x)])) (range 5 10) (range 10 5)
The problem is that when the REPL receives the definition of range, it compiles the definition in an environment where range is still bound to range from racket (which re-provides the exports of racket/list). So the “recursive” call to range gets compiled as a call to racket/list’s range, not to the top-level range function that has not yet been defined.
Racket’s module system mainly avoids such problems by detecting defined names before expanding the right-hand sides of definitions.
To avoid this problem, avoid redefining names.
(An alternative is to put (define-syntaxes (range) (values)) before the definition above. This form of define-syntaxes is only allowed at the top level, and it changes range to resolve as a binding in the top-level environment without giving it a value.)
2.2 #lang iracket/lang
|#lang iracket/lang||package: iracket|
In addition to being interpreted specially by the IRacket kernel (see IRacket and Languages), iracket/lang can be used as a language in Racket code. The purpose of the language is for testing how code should work in a Jupyter notebook; the iracket/lang language is not useful for developing normal Racket libraries and programs.
As a language, it behaves similarly to racket/load. Like racket/load, it evaluates body forms one by one in a top-level namespace. Unlike racket/load, it allows controlling the reader, and it delays reading the module body until run time, so that if one expression dynamically changes the reader, it affects the reading of the rest of the module body.
IRacket allows multiple #lang iracket/lang declarations in a notebook, but a Racket module does not (unless you change reader parameters, but then it still means something different).
Notebook cell boundaries can affect reader behavior, because the reader stops at the end of each cell. Thus a module formed by simply concatenating cell contents might behave differently.
When IRacket processes a #lang iracket/lang declaration, it does not reset parameters like current-readtable, read-accept-dot, etc. In contrast, Racket generally uses a fixed set of parameter values for reading modules (see syntax/modread).
Added in version 1.2 of package iracket.