mirror of
https://github.com/carp-lang/Carp.git
synced 2024-11-05 04:44:12 +03:00
25839de02d
Extends Carp's support for type reflection by returning types for values as well as bindings. `type` now also returns a valid Carp expression/s-expression and so its output can be used as input to dynamic functions and macros (prior to this commit, `type` printed the type to the REPL but did not return a meaningful expression in Carp). Here are a few illustrations of the behavior: ``` (def x 1) ;; type now returns an s-expression/symbol (type x) => Int ;; It also works on values (type 1) => Int (type 2b) => Byte (type "foo") => (Ref String <StaticLifetime>) ;; It works on more complex values as well (type Maybe) => Module (type Maybe.Just) (Fn [a] (Maybe a) <StaticLifetime>) ;; reports honestly about polymorphism (type (Maybe.Nothing)) => (Maybe a) (type (Pair.init 1 2)) => (Pair Int Int) ;; What about the type of types? (type (type 2)) => Type ;; Or the type of types of types? (type (type (type 2))) => () ;; One more time! (type (type (type (type 2)))) => () ;; so, () is the fixpoint of type, and is reached after two applications (type zero) ;; the type of an interface is all of its implementations => (((Fn [] (Array a) <StaticLifetime>) (Fn [] Bool <StaticLifetime>) (Fn [] Byte <StaticLifetime>) (Fn [] Char <StaticLifetime>) (Fn [] Double <StaticLifetime>) (Fn [] Float <StaticLifetime>) (Fn [] Int <StaticLifetime>) (Fn [] Int16 <StaticLifetime>) (Fn [] Int32 <StaticLifetime>) (Fn [] Int64 <StaticLifetime>) (Fn [] Int8 <StaticLifetime>) (Fn [] Long <StaticLifetime>) (Fn [] (Maybe a) <StaticLifetime>) (Fn [] (Pair a b) <StaticLifetime>) (Fn [] (Quadruple a b c d) <StaticLifetime>) (Fn [] String <StaticLifetime>) (Fn [] (Triple a b c) <StaticLifetime>) (Fn [] Uint16 <StaticLifetime>) (Fn [] Uint32 <StaticLifetime>) (Fn [] Uint64 <StaticLifetime>) (Fn [] Uint8 <StaticLifetime>))) ``` As shown in the example above, this change also includes a cosmetic update to the representation of lifetime variables, which are surrounded in <> to distinguish them from type variables. This commit also adds a new `kind` primitive that reports on the kind of a binding or value: ``` (def x 3) (kind x) => Base (kind 2) => Base (kind Maybe.Just) => Higher (kind (Maybe.Just 2)) => Higher ``` `kind` and `type` both support interactive development in the repl, for example, a user can rely on `kind` to check the kind of a type they plan on using in an interface that demands a higher-kinded argument. Likewise, they both also support developing macros based on type information. |
||
---|---|---|
.. | ||
Main.hs |