This document specify the core syntax rules for the language.
- no inheritance - this is made with composition (Rusty like)
- named parameters (based on OCalm link)
- case sensitive
- LISP like syntax
Simple comments (ELM):
-- Comments are markdown by default
Multiline comments (ELM) are Markdown by default:
{- a multiline comment based on ELM
{- can be nested -}
-}
Multiline typed comments (Light) gives information about how comments are rendered:
{-xml The `let` keyword defines an (immutable) value -} -- rendered as XML
{-sql select * from table -} -- rendered as SQL
{-md select * from table -} -- rendered as Markdown
Type annotations (CoffeeScript):
{-# This comment will be transpiled together #-} -- for Zig will be transpiled to // This comment will be transpiled together
i8 i16 i32 i64 i128 i256 -- i integers (Zig)
u8 u16 u32 u64 u128 u256 -- u unsigned integers (Zig)
f32 f64 -- float numbers (Zig)
f32.31 -- signed float number with 32 bits and 31 bits for mantissa -- TODO How many bits mantissa can use? (Light)
f64.32 -- signed float number with 64 bits and 32 bits for mantissa (Light)
uf32.31 -- unsigned float number with 32 bits and 31 bits for mantissa (Light)
uf64.32 -- unsigned float number with 64 bits and 32 bits for mantissa (Light)
c8 c16 -- c chars -- TODO
s8 s16 -- s strings -- TODO
b1 b8 -- b boolean -- TODO Do booleans always have 8 bits?
:a :b -- atoms (Elixir, LISP)
binary -- something like userdata on Fennel
"hello" -- or ["hello"] one string value
["hello" "world"] -- two string values
3.14 -- or [3.14] one float value
[3.14 4.15] -- two float values (tuple)
[3.14 4.15 5.15] -- three float values (tuple)
date 2023 12 3 -- dates are always in the order year, month, day
(let my_name) ; default value
(let my_name "Adelar") ; custom value
(let my_name _) ; no initialization
(let "my name") ; default value
(let "my name" "Adelar") ; custom value
(let "my name" _) ; no initialization
Operators as functions. Predefined operators:
Comparation:
(== 2 2)
(!= 2 3)
(< 2 3 5)
-- incresing operator(> 2 3 5)
-- decreasing operator(<= 2 3 5)
-- incresing operator(>= 2 3 5)
-- decreasing or equal operator
Aritmetic:
(+ 1)
,(+ 1 3)
,(+ 1 3 4)
(- 3)
,(- 3 2)
,(- 3 2 4)
(/ 4)
,(/ 4 2)
,(/ 4 2 4)
(* 2)
,(* 2 4)
,(* 2 4 6)
(% 2)
,(% 2 4)
,(% 2 4 5)
-- remainder(%% 2 4)
-- canonical modulus operation
Logical:
(and true true)
(or false true)
(not false)
(nand true true)
(nor true true)
(xor true false)
(xnor true true)
(mux true true)
(demux true true true)
Binaries:
-
(& 3 2)
-
(| 3 2)
-
(^ 3 2)
-
(>> 3 2)
-
(<< 3 2)
-
(>>> 3 2)
-- Closures are defined with ->
(-> [x y]
(x + y))
-- Functions are defined with fn
(fn sum [x y]
(x + y))
-- Defined return type
(: sum i32 i32 i32)
(fn sum [x y]
(x + y))
-- Multiple return types (confirm)
(: sumOrSub i32 i32 [i32 i32])
(fn sumOrSub [x y]
(x + y)
(x - y))
-- Defining new operators
(fn * [x y]
(100))
-- Defining function names as strings
-- ? defines a test
(test "returns a sum"
(let s = sum 10 20)
(assert = 30 s))
Default values:
(: sum i32 i32 i32)
(fn sum [(x 10) y]
(x + y))
(: (list i32) (?))
(fn array2list [(list [10,10,10])]
(...))
Most of the cases there is no need to specify types. Something like F# uses.
Closures are funcions without name:
// Closures are defined with ->
(-> [x y] (+ x y))
(: _ _ i32)
(fn * [x y]
(100))
(: a a a)
(fn * [x y]
(100))
-- Generic record, with the type parameter in angle brackets
(: a a a)
(type MyRecord
(Field1)
(Field2))
-- Generic discriminated union
(: a a a*a) -- TODO
(type MyUnion =
(| (Choice1)
(Choice2)))
(tuple [1 2])
A raw array that can be acessed by an integer index
(array [1 3 4 5])
A linked list:
(list [1 3 4 5])
Itens are generated by demand:
(seq [1 2 3 4])
(if (> a 11)
("> 11") -- true
("<= 11")) -- false
(case maybeList
(Just xs xs)
(Nothing []))
(case xs
([] Nothing)
(first :: rest (Just (first, rest))))
(case n
(0 1)
(1 1)
(_ fib (n-1) + fib (n-2)))
(for ((i 0) (< i 10) (++ i))
(print i)
(print "...")
)
(for (i (.. 0 10 ))
(print i)
(print "...")
)
(let a 1)
(let pointer ^a)
(let reference a^)
-
len
- give value lenght -
try
- same astry
from Zig link
(try calculate result) ; same as `const result = try calculate();`
map
(map myfunction values)
reduce
(reduce myfunction values)
|>
- same as|>
operator on F#
(|> values
f1
f2)
.
- fluent function. Call a number of functions for the value, returning a tupple
(. value
f1
f2)
..
- generate sequence
(.. 1 10) ; 1 2 3 4 5 6 7 8 9 10
- / - string split link
(/ "first line\nsecond line" "\n")
- cast - convert one type to another
(cast int32 int64 9)
- ? - returns first non error/empty value. Something like ternary operators, but for multiple values
(? none error "value")
- ?. - conditional member access
(?. level1 level2 level3 value)
if(level1 != null && level1.level2 != null && level1.level2.level3 != null){ ... }