Skip to content

Instantly share code, notes, and snippets.

#lang racket/base
(require racket/port
(only-in syntax/module-reader lang-reader-module-paths)
syntax/readerr)
(provide make-extension-reader)
(define default-read-spec
(lambda (in)
#lang turnstile/lang
(provide (rename-out [app #%app])
Integer String Maybe)
(require (postfix-in - racket/base))
(define-syntax-category kind)
(define-base-kind ★)
#lang curly-fn racket/base
(provide λ +
(rename-out [hash-percent-app #%app]
[hash-percent-datum #%datum]
[hash-percent-module-begin #%module-begin]))
(require (for-syntax racket/hash
syntax/id-table)
(except-in macrotypes/typecheck #%module-begin)

Racket #langs and the REPL

The Racket platform provides a robust set of tools for developing languages, mostly centered around the macro system and the #lang protocol, which allows providing arbitrary readers to convert text input to syntax objects representing Racket modules. The REPL is a bit more complicated, however, because it has different rules—each expression needs to be dynamically read, assigned lexical context, expanded, compiled, evaluated, and printed, all in real time. (In that sense, perhaps the phrase “REPL” oversimplifies what Racket is doing, but that’s a separate conversation.)

So how does Racket accommodate this in the face of completely arbitrary user-defined languages, some of which may not even support interactive evaluation in a traditional sense? Racket mostly solves this problem by having a related but distinct set of protocols for managing runtime interactions that operates alongside #lang.

Modules and the top level

Racket’s evaluation model divides pretty much ev

#!/usr/bin/env racket
#lang racket/base
(require racket/cmdline
racket/function
racket/match
racket/port
racket/system)
(define paths '())
#lang racket
(module combinator racket
(require racket/dict
syntax/location
syntax/parse/define)
(provide with-contracted-expressions)
(struct bare-string (str)
#lang racket
(module combinator racket
(require (for-syntax racket/syntax
(only-in syntax/parse/private/residual this-role))
racket/dict
syntax/location
syntax/parse/define)
(provide (for-syntax wrap-expr/c expr/c))
{-# LANGUAGE FlexibleInstances #-}
-- | An implementation of Section 3, Local Type Argument Synthesis, from the
-- paper /Local Type Inference/ by Pierce and Turner.
module Infer where
import Control.Monad (foldM, join, zipWithM)
import Data.Function (on)
import Data.List (foldl', groupBy, intercalate, intersect, nub)
@lexi-lambda
lexi-lambda / Main.hs
Last active July 5, 2023 18:01
Minimal Haskell implementation of Complete and Easy Bidirectional Typechecking for Higher-Rank Polymorphism
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Language.HigherRank.Main
( Expr(..)
, EVar(..)
, Type(..)
, TVar(..)
, TEVar(..)
, runInfer
) where
#lang curly-fn racket/base
(require (for-syntax racket/base
racket/contract
racket/function
racket/list
racket/match
racket/syntax
(only-in macrotypes/stx-utils make-variable-like-transformer)
threading)