cur/scribblings/reflection.scrbl
2015-09-22 18:18:26 -04:00

103 lines
3.4 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"
(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.
@(require racket/sandbox scribble/eval)
@(define curnel-eval
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string]
[sandbox-eval-limits #f]
[sandbox-memory-limit #f])
(make-module-evaluator "#lang cur (require cur/stdlib/bool) (require 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[#'(Π (x : (Unv 0)) (Unv 0))] "" ""))
(eval:alts (type-infer/syn #'Type)
(eval:result @racket[#'(Unv 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-infer/syn #'(lambda (x : Type) x))
(eval:result @racket[#'(Π (x : (Unv 0)) (Unv 0))] "" ""))
(eval:alts (type-infer/syn #'Type)
(eval:result @racket[#'(Unv 1)] "" ""))
]
}
@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)] "" ""))
]
}
@defform[(run syn)]{
Like @racket[normalize/syn], but is a syntactic form which allows a Cur term to be written by
computing part of the term from another Cur term.
@margin-note{This one is a real working example, assuming the @racketmodname[cur/stdlib/bool] and
@racketmodname[cur/stdlib/nat] are loaded. Also, could be moved outside the privileged code.}
@examples[#:eval curnel-eval
(lambda (x : (run (if btrue bool nat))) x)]
}
@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] "" ""))
]
}