There are 6 general value types, which are referred to as lvals. They are: numbers, strings, errors, functions, S-Expressions, and Q-Expressions.
You can define all of them (except errors and functions) using the following syntax:
dagger> set {myFavoriteNumber} 6 # myFavoriteNumber is an integer
()
dagger> myFavoriteNumber
6
dagger> set {myFavoriteNumberToThePowerOfNegativeOne} 0.166666 # A decimal, of course
()
dagger> myFavoriteNumberToThePowerOfNegativeOne
0.166666
dagger> set {myFavoriteWord} "hello" # A string
()
dagger> myFavoriteWord
hello
dagger> set {firstTenNumbers} {1 2 3 4 5 6 7 8 9 10} # A Q-Expression
()
dagger> firstTenNumbers
{1 2 3 4 5 6 7 8 9 10}
Numbers can be either integers or decimals. They respect the same upper and lower ranges as "long" and "double" in C.
dagger> / 10 3
3
dagger> / 10.0 3.0 # Decimals are always printed with 6 digits after the point
3.333333
A string is a number of characters inside double quotes:
dagger> "Hello World"
Hello World
dagger> join "Hello" "World"
Hello World
dagger> print "Hi"
Hi
()
dagger> / 10 0
Error: Division by Zero!
dagger> error "my error"
Error: my error
S-Expressions are just code that will be evaluated by the interpreter. By working with the interpreter's prompt, everything is an S-Expression by default. But if you want to evaluate external files, you must wrap your code in parentheses to make it an S-Expression. Nesting is also important for the correct order of evaluation of your code. The interpreter always starts from the innermost S-Expresssion.
dagger> print + 7 3
<builtin> 7 3 # What in the world is this?!?!?
()
dagger> print (+ 7 3)
10 # Much Better xD
()
Q-Expressions are blocks of code that are not meant to be executed. They can be used like arrays in C or lists in Python. However, Dagger more powerful list manipulation functions than both C and Python. For example, the "eval" function converts a Q-Expression into an S-Expression, and the "head" function returns the first item of a Q-Expression.
dagger> {+ 1 2}
{+ 1 2}
dagger> eval {+ 1 2}
3
dagger> head 1 2 3
Error: Function 'head' passed incorrect number of arguments. Got 3, Expected 1.
dagger> head {1 2 3}
{1}
dagger> eval (head {1 2 3})
1
Functions are a type of value bound to a symbol. When called, a function will perform some action on the arguments it was called with.
dagger> * 3 6 # '*' is the symbol bound to the multiplication function
18
dagger> head "hello" # Head returns the first character of the string
h
dagger> tail "hello" # Tail returns all characters except the first one
ello
dagger> head "abc" "def" # Head only supports one argument
Error: Function 'head' passed incorrect number of arguments. Got 2, Expected 1.
You can also make custom functions with the "\" symbol. The following syntax is confusing, but there is a function in the standard library which can help. (Yeah, in dagger we have functions that define functions ;) )
dagger> / 12 (* 2 3)
2
dagger> (\ {x y} {/ 12 (* x y)}) 2 3
2
You start by opening a parenthesis with a lambda (\, then, you write a Q-Expression containing all the arguments to the function. Then, another Q-Expression containing the code that the function will execute. For example, the addition function (of two numbers) can be written as (\ {x y} {+ x y})
The before example can also be written by using the "fun" function in the std library:
dagger> load "std.dgr"
()
dagger> fun {myfunction x y} {/ 12 (* x y)}
()
dagger> myfunction 2 3
2