cur/scribblings/reflection.scrbl
2015-11-10 16:16:33 -05:00

113 lines
3.6 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#lang scribble/manual
@(require
"defs.rkt"
scribble/eval
(for-label (only-in racket local-expand)))
@title{Reflection}
To support the addition of new user-defined language features, @racketmodname[cur] provides access to
various parts of the language implementation as Racket forms at @gtech{phase} 1.
The reflection features are @emph{unstable} and may change without warning.
Many of these features are extremely hacky.
@(define curnel-eval (curnel-sandbox "(require cur/stdlib/bool cur/stdlib/nat)"))
@defproc[(cur-expand [syn syntax?] [id identifier?] ...)
syntax?]{
Expands the Cur term @racket[syn] until the expansion reaches a either @tech{Curnel form} or one of
the identifiers @racket[id]. See also @racket[local-expand].
@todo{Figure out how to get evaluator to pretend to be at phase 1 so these examples work properly.}
@margin-note{The examples in this file do not currently run in the REPL, but should work if used at
phase 1 in Cur.}
@examples[
(eval:alts (define-syntax-rule (computed-type _) Type) (void))
(eval:alts (cur-expand #'(lambda (x : (computed-type bla)) x))
(eval:result @racket[#'(lambda (x : Type) x)] "" ""))
]
}
@defproc[(type-infer/syn [syn syntax?])
(or/c syntax? #f)]{
Returns the type of the Cur term @racket[syn], or @racket[#f] if no type could be inferred.
@examples[
(eval:alts (type-infer/syn #'(lambda (x : Type) x))
(eval:result @racket[#'(forall (x : (Type 0)) (Type 0))] "" ""))
(eval:alts (type-infer/syn #'Type)
(eval:result @racket[#'(Type 1)] "" ""))
]
}
@defproc[(type-check/syn? [syn syntax?])
boolean?]{
Returns @racket[#t] if the Cur term @racket[syn] is well-typed, or @racket[#f] otherwise.
@examples[
(eval:alts (type-check/syn? #'(lambda (x : Type) x))
(eval:result @racket[#t] "" ""))
(eval:alts (type-check/syn? #'Type)
(eval:result @racket[#t] "" ""))
(eval:alts (type-check/syn? #'x)
(eval:result @racket[#f] "" ""))
]
}
@defproc[(normalize/syn [syn syntax?])
syntax?]{
Runs the Cur term @racket[syn] to a value.
@examples[
(eval:alts (normalize/syn #'((lambda (x : Type) x) Bool))
(eval:result @racket[#'Bool] "" ""))
(eval:alts (normalize/syn #'(sub1 (s (s z))))
(eval:result @racket[#'(s z)] "" ""))
]
}
@defproc[(step/syn [syn syntax?])
syntax?]{
Runs the Cur term @racket[syn] for one step.
@examples[
(eval:alts (step/syn #'((lambda (x : Type) x) Bool))
(eval:result @racket[#'Bool] "" ""))
(eval:alts (step/syn #'(sub1 (s (s z))))
(eval:result @racket[#'(((((elim Nat (Type 0))
(lambda (x2 : Nat) Nat)) z)
(lambda (x2 : Nat) (lambda (ih-n2 : Nat) x2)))
(s (s z)))] "" ""))
]
}
@defproc[(cur-equal? [e1 syntax?] [e2 syntax?])
boolean?]{
Returns @racket[#t] if the Cur terms @racket[e1] and @racket[e2] and equivalent according to
equal modulo α and β-equivalence.
@examples[
(eval:alts (cur-equal? #'(lambda (a : Type) a) #'(lambda (b : Type) b))
(eval:result @racket[#t] "" ""))
(eval:alts (cur-equal? #'((lambda (a : Type) a) Bool) #'Bool)
(eval:result @racket[#t] "" ""))
(eval:alts (cur-equal? #'(lambda (a : Type) (sub1 (s z))) #'(lambda (a : Type) z))
(eval:result @racket[#f] "" ""))
]
}
@defproc[(cur->datum [s syntax?])
(or/c symbol? list?)]{
Converts @racket[s] to a datum representation of the @tech{curnel form}, after expansion.
@examples[
(eval:alts (cur-?datum #'(lambda (a : Type) a))
(eval:result @racket['(λ (a : (Unv 0) a))] "" ""))
]
}