Language Specification
LambdaCube 3D is specified as Haskell98 plus various language extensions.
Haskell98 language features
- algebraic data types (ADTs)
- special syntax for tuples and lists
case
,let
,if
statements- lambda expressions
- list comprehensions
- operators, operator fixity declarations
- pattern matching; wildcard patterns
- function alternatives
- value definitions (pattern = expression)
- where-blocks
- simple recursion
- type synonyms
Work in progress:
- type classes
- module imports and export lists
- type signatures
- dot-dot expressions
TODO:
- mutual recursion
- irrefutable patterns
- at-patterns
- type class defaulting
- type instance deriving
- newtype declarations
- do syntax
There are some diversions from Haskell98. Our plan is to keep this list very short.
- Different
Prelude
: look at the API documentation.
Extentions to Haskell98
These extensions are automatically enabled.
Known extensions
NoMonomorphismRestriction
NoNPlusKPatterns
TypeApplication
KindSignatures
EmptyDataDecls
PolyKinds
&DataKinds
RankNTypes
NoImplicitPrelude
language pragma
Work in progress:
GADTs
(includesExistentialQuantification
)TypeFamilies
PartialTypeSignatures
ScopedTypeVariables
PatternGuards
ViewPatterns
PatternSynonyms
Planned:
- Typed holes
LambdaCase
TupleSections
Custom extensions
- Tuples as heterogeneous lists
- Row polymorphism
- Swizzling
ImplicitParams
Homogeneous and heterogeneous lists
Homogeneous lists
List
has the standard definition:
data List a
= Nil
| Cons a (List a)
Lists has special syntax like in Haskell:
desugared form (in expr. ctx) | type context | expression/pattern context |
---|---|---|
'List |
[] |
'[] |
'List a |
[ a] |
'[ a] |
Nil |
'[] |
[] |
Cons a Nil |
'[ a] |
[ a] |
Cons a b |
'( a: b) or ( a: b) |
( a: b) |
Cons a (Cons b Nil) |
'[ a, b] or [ a, b] |
[ a, b] |
Cons a (Cons b (Cons c Nil)) |
'[ a, b, c] or [ a, b, c] |
[ a, b, c] |
… | … | … |
Examples with sytactic sugar:
[] :: [Int]
[] :: [Bool]
[True] :: [Bool]
[True, False] :: [Bool]
[1, 23, 4] :: [Int]
[[1], [], [23, 4]] :: [[Int]]
Heterogeneous lists
Heterogeneous lists has special syntax like tuples in Haskell.
The only difference is that LambdaCube 3D has special syntax for one element tuples: ((
element ))
.
Examples with syntactic sugar:
() :: ()
((True)) :: ((Bool))
(3, True) :: (Int, Bool)
[(3, True), (4, False)] :: [(Int, Bool)]
(((3)), [True, False]) :: (((Int)), [Bool])
Details:
The HList
data type is defined as a GADT:
data HList :: [Type] -> Type where
HNil :: HList 'Nil
HCons :: x -> HList xs -> HList ('Cons x xs)
Some of the previous examples without syntactic sugar:
HNil :: HList 'Nil
HCons True HNil :: HList ('Cons Bool 'Nil)
HCons 3 (HCons True HNil) :: HList ('Cons Int ('Cons Bool 'Nil)
General rules for desugaring:
desugared form (in expression ctx) | type context | expression/pattern context |
---|---|---|
'HList Nil |
() |
'() |
'HList (Cons a Nil) |
(( a)) |
'(( a)) |
'HList (Cons a (Cons b Nil) |
( a, b) |
'( a, b) |
… | … | … |
HNil |
'() |
() |
HCons a HNil |
'(( a)) |
(( a)) |
HCons a (HCons b HNil) |
'( a, b) |
( a, b) |
… | … | … |
Row polymorphism
A.k.a. structural records.
Row polymorphism is implemented following Edward Kmett’s presentation on Ermine.
v1 = {x: 1.0, y: 2.0, z: 3.0}
v2 = {x: 1.0, y: 2.0, z: 3.0, a: 4.0}
f v = v.x + v.y
r = f v1 + f v2 -- this is valid
Swizzling
Swizzling means rearranging the elements of a vector.[^swizzling]
(V3 1.0 2.0 3.0)%xxzy == V4 1.0 1.0 3.0 2.0
The letters x
, y
, z
and w
refers to the 1st, 2nd, 3rd and 4th element of a record, respectively.
It is also possible to use the letters r
, g
, b
and a
instead of x
, y
, z
and w
.