-
Notifications
You must be signed in to change notification settings - Fork 26
Typed Exprs
- Drasil is a system of knowledge-oriented programming languages, and a compiler for said languages.
- Drasil is bootstrapped in Haskell.
- Eventually, Drasil will be built in Drasil.
Expressions should be well-typed, and expose information about their resultant types.
Specifically, we would like the terms of the Expression language to be "safe" in usage, so that we can reliably generate well-formed and well-behaved programs.
In order to ensure that all terms of the expression language are "valid"/well-formed, we must define what it means for any term to be "valid"/well-formed. We will define "validity"/well-formedness here through defining a system of inference rules that dictate when we're able to form terms of the expressions abstract syntax tree.
TODO: inference rules & syntax chart as done in "Practical foundations for Programming Languages" (e.g., Harper, pg. 34). Export to SVG(?) and link here.
Omitted for now, many are "obvious", but I will write them out properly soon™.
An important thing to remember is that, ultimately, Drasil is a compiler on its own. Presently, Drasil and the ASTs of Drasil programs are bootstrapped in Haskell as a host language. In the future, Drasil might become a self-hosted compiler (and likely would need to be for Drasil in Drasil).
Since Drasil is bootstrapped in Haskell, we might find ourselves (as I have) looking to advanced Haskell tools to build Drasil. This might be great, and work great, but it would pose a problem later when trying to build Drasil in Drasil.
Here, we define the expression languages using an Algebraic Data Type in Haskell. In order for us to impose typing restrictions in Haskell, we may lean on Haskell's type system (e.g., leveraging GADTs), or we can roll our own type system for the expressions using .
var1 :: QuantityDict Int
var1 = mkQuantityDict (Proxy @Int) (mkUid "var1") "a1" "b1"
var2 :: QuantityDict Bool
var2 = mkQuantityDict (Proxy @Bool) (mkUid "var2") "a2" "b2"
func1 :: QuantityDict (Int -> Int)
func1 = mkQuantityDict (Proxy @(Int -> Int)) (mkUid "func1") "c1" "d1"
func2 :: QuantityDict (Bool -> Int -> Int -> Int)
func2 = mkQuantityDict (Proxy @(Bool -> Int -> Int -> Int)) (mkUid "func2") "c2" "d2"
varDef1 :: QDefinition Expr Int
varDef1 = mkQDefinition (mkUid "varDef1") var1 (int 1) "e1" "f1"
varDef2 :: QDefinition Expr Bool
varDef2 = mkQDefinition (mkUid "varDef2") var2 (not_ $ bool False) "e2" "f2"
funcDef1 :: QDefinition Expr (Int -> Int)
funcDef1 = mkQDefinition (mkUid "funcDef1") func1 (lam $ \x -> add x (int 1)) "g1" "h1"
funcDef2 :: QDefinition Expr (Bool -> Int -> Int -> Int)
funcDef2 = mkQDefinition (mkUid "funcDef2") func2 (lam $ \b -> lam $ \x -> lam $ \y -> ifTE b x y) "g2" "h2"
funcDef3 :: QDefinition Expr (Int -> Int)
funcDef3 = mkQDefinition (mkUid "funcDef3") func1 (lam (\x -> add x (int 1))) "g3" "h3"
- Traceability of errors: Haskell reported errors are very descriptive and easy to read, showing the specific line numbers and files that a problem occurs.
- Readability: Types of Quantities, Definitions, etc. are displayed elegantly through the type arguments of the Haskell variables.
- Named arguments in function calls do not play well statically.
- Relies heavily on "upgraded" ChunkDBs.
- Types of the literals show up with Haskell names, instead of the preferred names (the ones used in the
Space
ADT). - Dictating the space/type of a quantity relies on either
Type Applications
or onProxy
. Either way, it relies on something that is very deep in Haskell.
var1 :: QuantityDict
var1 = mkQuantityDict S.Integer (mkUid "var1") "a1" "b1"
var2 :: QuantityDict
var2 = mkQuantityDict S.Boolean (mkUid "var2") "a2" "b2"
func1 :: QuantityDict
func1 = mkQuantityDict (S.Function (S.Integer NE.:| []) S.Integer) (mkUid "func1") "c1" "d1"
func2 :: QuantityDict
func2 = mkQuantityDict (S.Function (NE.fromList [S.Boolean, S.Integer, S.Integer]) S.Integer) (mkUid "func2") "c2" "d2"
varDef1 :: QDefinition Expr
varDef1 = mkQDefinition (mkUid "varDef1") var1 (int 1) "e1"
varDef2 :: QDefinition Expr
varDef2 = mkQDefinition (mkUid "varDef2") var2 (not_ $ bool False) "e2"
- As rules are explicitly written, we have generally more flexibility in our type system.
- Allows for named arguments in function calls.
- This prototype can likely be implemented directly in existing Drasil infrastructure.
- Additionally, at a glance, looks like it would work without the "upgraded" ChunkDBs. However, having Typed UID references is a large bonus, we can likely make this an aside issue bringing discussion of chunk formation into question as well.
- Giving quantities a type/space is done normally through
QuantityDict
s.
- If an expression is ill-formed, and since Haskell is lazy-evaluated, we will likely only find out at some point during the runtime (Drasil's compile-time). In other words, we would not be able to leverage Haskell Language Server to statically find errors as we write expressions (though, we could write our own LSP if we really wanted it later [/largely down the road]).
- Haskell's type system is very rich and works well for most things.
- Readability in Haskell is a bit difficult to trace.
- Traceability of errors (due to errors only being thrown at runtime, we would need to display UIDs to be able to locate problematic areas).
- "error" usage might make things a bit difficult, perhaps we can switch to using more
Either Expr Error
(withtype Error = String/Text
)? - Add support for higher order expressions functions (doesn't look too difficult with this style!)
- Dummy variables instead of using registered QuantityDicts for parameters
- Types and type constraints might be better to be written as ideas in Drasil as well, using a Haskell stub as the runtime.
- Should symbol references be to specific implementations of a symbol? As of right now, we are going against this.
- Home
- Getting Started
- Documentation (of Drasil specifics)
- Design
-
Readings
- Drasil Papers and Documents
- Related Work and Inspiration
- Writing Documentation
- Compression as a Means to Learn Structure
- Glossary, Taxonomy, Ontology
- Grounded Theory
- Model Driven Scrapbook
- Model Transformation Languages
- ODE Definitions
- The Code Generator
- Suggested Reading
- Sustainability
- Productivity
- Reuse
- Formal Concept Analysis
- Generative Programming
- Software Documentation
- Units and Quantities
- Misc.
- WIP Projects