Keep writing.

Calvin Rose 2018-07-04 01:33:09 -04:00
parent 3286bff406
commit 23e5cdbbf4
1 changed files with 70 additions and 6 deletions

@ -12,12 +12,12 @@ should immediately exit. You now have a working dst program!
Alternatively, run the program `./dst` without any arguments to enter a REPL,
or read eval print loop. This is a mode where Dst functions like a calculator,
reading some input from stdin, evaluating it, and printing out the result, all
reading some input from the user, evaluating it, and printing out the result, all
in an inifinte loop. This is a useful mode for exploring or prototyping in Dst.
This hello world program is about the simplest program one can write, and consists of only
a few pieces of syntax. This first element is the `print` symbol. This is a function
that simply prints its arguments to standard out. The second argument is the
that simply prints its arguments to the console. The second argument is the
string literal "Hello, world!", which is the one and only argument to the
print function. Lastly, the print symbol and the string literal are wrapped
in parentheses, forming a tuple. In Dst, parentheses and brackets are interchangeable,
@ -40,7 +40,7 @@ and supports the basic arithemtic operators
```
Just like the print function, all arithmetic operators are entered in
prefix notation. Dst also supports the modulo operator, or `%`, which returns
prefix notation. Dst also supports the remainder operator, or `%`, which returns
the remainder of division. For example, `(% 10 3)` is 1, and `(% 10.5 3)` is
1.5. The lines that begin with `#` are comments.
@ -55,7 +55,7 @@ real numbers and integers in your program. If you are using a number to index in
you probably want integers. Otherwise, you may want to use reals (this is only a rule of thumb).
Arithmetic operator will convert integers to real numbers if needed, but real numbers
will not be converted to integers, as not all real numbers can be safely convert to integers.
will not be converted to integers, as not all real numbers can be safely converted to integers.
## Numeric literals
@ -74,7 +74,9 @@ notation with a radix besides 10, use the `&` symbol to indicate the exponent ra
Besides the 5 main arithmetic functions, dst also supports a number of math functions
taken from the C libary `<math.h>`, as well as bitwise operators that behave like they
do in C or Java. Functions like `sin`, `cos`, `log`, and `exp` will behave as expected to a C programmer.
do in C or Java. Functions like `math.sin`, `math.cos`, `math.log`, and `math.exp` will
behave as expected to a C programmer. They all take either 1 or 2 numeric arguments and
return a real number (never an integer!)
# Strings, Keywords and Symbols
@ -362,6 +364,26 @@ itself, and the second parameter is the key.
(get @"hello, world" 1) # -> 101
(get "hello, world" 0) # -> 104
```
In many cases, however, you do not need the `get` function at all. Dst supports destructuring, which
means both the `def` and `var` special forms can extract values from inside structures themselves.
```lisp
# Before, we might do
(def my-array @[:mary :had :a :little :lamb])
(def lamb (get my-array 4))
(print lamb) # Prints :lamb
# Now, with destructuring,
(def [_ _ _ _ lamb] my-array)
(print lamb) # Again, prints :lamb
# Destructuring works with tables as well
(def person @{:name "Bob Dylan" :age 77}
(def
{:name person-name
:age person-age} person)
```
To update a mutable data structure, use the `put` function. It takes 3 arguments, the data structure,
the key, and the value, and returns the data structure. The allowed types keys and values
depend on what data structure is passed in.
@ -381,7 +403,49 @@ values in a data structure (the number of keys in a dictionary type).
# Flow Control
:)
Dst has only two built in primitives to change program while inside a function. The first if the
`if` special form, which behaves as expected in most functional languages. It takes two or three parameters:
a condition, an expression to evaluate to if the condition is true (not nil or false),
and an optional condition to evaluate to when the condition is nil or false. If the optional parameter
is omitted, the if form evaluates to nil.
```lisp
(if (> 4 3)
"4 is greater than 3"
"4 is not greater then three") # Evaluates to the first statement
(if true
(print "Hey")) # Will print
(if false
(print "Oy!")) # Will not print
```
The second primitive control flow construct is the while loop. The while behaves much the same
as in many other programming languages, including C, Java, and Python. The while loop takes
two or more parameters: the first is a condition (like in the `if` statement), that is checked before
every iteration of the loop. If it is nil or false, the while loop ends and evaluates to nil. Otherwise,
the rest of the parameters will be evaluated sequentially and then the program will return to the beginning
of the loop.
```
# Loop from 100 down to 1 and print each time
(var i 100)
(while (pos? i)
(print "the number is " i)
(-- i))
# Print ... until a random number in range [0, 1) is >= 0.9
# (math.random evaluates to a value between 0 and 1)
(while (> 0.9 (math.random))
(print "..."))
```
Besides these special forms, Dst has many macros for both conditional testing and looping
that are much better for the majority of cases. For conditional testing, the `cond`, `switch`, and
`when` macros can be used to great effect. `cond` can be used for making an if-else chain, where using
just raw if forms would result in many parentheses. `switch` For looping, the `loop` and `for` macro implement
list comprehension, as in Python, Clojure.
# Combinators