## LispTick Syntax

### Atoms

LispTick has nine types of Atoms: ints, floats, strings, chars, bools, datetimes, durations, datafields, and symbols. The following are different kinds of literal syntax for these atoms.

```
3 ; an int
-21 ; a negative int
0x41 ; int in hexadecimal
0o755 ; int in octal
0b1110 ; int in binary
4.1 ; a float
-2.3 ; a negative float
1.3e20 ; a float in scientific notation
#c ; the character 'c'
#\n ; the newline character
"asdfsd" ; a string
asdfsd ; a symbol
true ; the "true" boolean
false ; the "false" boolean
T10:30 ; a simple time without date and timezone
2017-10-18 ; a simple date without time
2017-10-18T09:30:01.123456789 ; a full datetime with nanoseconds
10h ; a duration of 10 hours
30m ; a duration of 30 minutes
59s ; a duration of 59 seconds
100ms ; a duration of 100 milliseconds
70us ; a duration of 70 microseconds
90ns ; a duration of 90 nanoseconds
1h30m40.561s ; a duration of 1 hour 30 minutes 40 seconds and 561 milliseconds
1D ; a duration of exactly one day, as one day can be 23, 24 or 25h depending on daylight saving
1M ; a duration of exactly one month
1Y ; a duration of exactly one year
@trade-price ; a data field used when requesting a timeserie
```

Note that semicolons are used for single-line comments. The syntax for symbols
is quite flexible. Any non-whitespace character other than `'`

or `#`

can be
used in a symbol.

### Lists

Lists are just cons-cell lists like in other LISP dialects and are delimited by parentheses

```
(a-function arg1 arg2
(another-function arg1 arg2))
```

You can also just describe plain pairs (cons-cells in which the tail is not necessarily a list) using the dotted syntax.

```
(a . b)
```

### Arrays

Arrays correspond to Go slices and are delimited by square braces.

```
[1 2 3 4]
```

#### Hashes

LispTick has mutable hashmaps which use Go maps internally. The literal syntax uses curly braces

```
{'a 3
'b 2}
```

The hash above maps `a`

to 3 and `b`

to 2. Hash keys can only be integers, strings, chars, or symbols.

#### Quoting

The quote symbol `'`

indicates that the following expression should be
interpreted literally. This is useful for declaring symbols and lists.

```
'(1 2 3 4)
'a-symbol
```

## Functions

An anonymous function can be declared in LispTick like so

```
(fn [a b] (+ a b))
```

A function can be declared with a name using `defn`

.

```
(defn add3 [a] (+ a 3))
```

Note that like in Clojure, the argument list is given in an array instead of a list.

### Bindings

A binding can be added in the current scope using `def`

. You can also create
a new scope and declare bindings in it using `let`

or `let*`

.

```
(def a 3)
(let [a 3
b 4]
(* a b))
; returns 12
(let* [a 2
b (+ a 1)]
(+ a b))
; returns 5
```

The difference between `let`

and `let*`

is that `let`

creates bindings all at
once, so you will not be able to access earlier bindings in later bindings.
The `let*`

form creates bindings one by one, so each binding can access
bindings declared before it.

### Calling functions

Functions can be called in the regular way.

```
(defn add3 [a] (+ a 3))
(add3 2) ; returns 5
```

They can also be called indirectly using apply.

```
(apply + [1 2 3]) ; returns 6
(apply + '(1 2 3)) ; same as above
```

This works exactly the same with anonymous functions

```
((fn [a b] a) 2 3) ; returns 2
(apply (fn [a b] a) [2 3]) ; same as above
```

### Conditionals

LispTick has only a single conditional statement, `cond`

.
The syntax is as follows.

```
(cond
first-condition first-expression
second-condition second-expression
...
default-expression)
```

The `cond`

statement will check the conditions in order. If the condition is
true, it will return the result of the corresponding expression. If not, it
will move on the next condition. If none of the conditions are true, it will
return the result of the default expression. The default expression is the
only required portion of this statement. The way to think of this is that the
first condition/expression pair is an `if`

statement, the second is an
`else if`

statement, and the default is the `else`

statement.

LispTick also provides the short-circuit boolean operators `and`

and `or`

.
The `and`

expression will return the first “falsy” sub-expression or, if all
sub-expressions are “truthy”, the last sub-expression is returned. The `or`

expression is the opposite, returning the first “truthy” expression or the
last expression.

The boolean `false`

, the null value (empty list), the integer 0, and the null
character are considered “falsy”. All other values are considered “truthy”.

#### Sequencing

The `begin`

statement is used to sequence expressions. It will run all
sub-expressions and return the result of the final expression. The top-level,
function bodies, and let-statement bodies have implicit `begin`

statements.

### Builtin Functions

The following builtin functions are provided by the language runtime.

#### Integer shift operations, applicable on timeseries

`sll`

(shift-left logical)`sra`

(shift-right arithmetic)`srl`

(shift-right logical)

#### Bitwise operations, applicable on timeseries (expect bit-not)

`bit-and`

`bit-or`

`bit-xor`

`bit-not`

(one’s complement, use (map not ts) to apply on timeseries)

#### Boolean operations, applicable on timeseries

`not`

#### Arithmetic, applicable on timeseries

Function name | Description |
---|---|

`+` |
addition |

`-` |
subtraction |

`*` |
multiplication |

`mat*` |
matrix multiplication |

`/` |
division |

`mat/` |
matrix division (multiplication by inversed matrix) |

`abs` |
absolute value |

`acos` |
arccosine, in radians |

`acosh` |
inverse hyperbolic cosine |

`asin` |
arcsine, in radians |

`asinh` |
inverse hyperbolic sine |

`atan` |
arctangent, in radians |

`atanh` |
inverse hyperbolic tangent |

`cbrt` |
cube root |

`cos` |
cosine, in radians |

`cosh` |
hyperbolic cosine |

`exp` |
base-e exponential |

`int` |
int part, if true -> 1, false -> 0 or decimal string |

`ln` or `log` |
natural logarithm |

`log10` |
decimal logarithm |

`max` |
maximum |

`min` |
minimum |

`mod` |
modulo |

`round` |
can have a second argument n, rounded to nearest 10^n, default is 0 so rounded to int |

`pow` |
x^{y}, the base-x exponential of y. |

`sigmoid` |
Sigmoid function |

`sign` |
>0 -> 1, <0 -> -1, =0 -> 0 |

`sin` |
sine, in radians |

`sinh` |
hyperbolic sine |

`sqr` |
square |

`sqrt` |
square root |

`tan` |
tangent, in radians |

`tanh` |
hyperbolic tangent |

#### Comparisons

`<`

`>`

`<=`

`>=`

`=`

`not=`

or`!=`

#### Type Introspection

`array?`

`char?`

`duration?`

(returns true for difference of time for example)`empty?`

(returns true only for (), [], and {})`float?`

`hash?`

`int?`

`list?`

`null?`

(returns true only for ())`number?`

(int, char, or float)`string?`

`symbol?`

`time?`

(returns true if date or time)`timeserie?`

(returns true for any timeserie)`zero?`

(returns true only for 0, 0.0, and null character)

#### Printing

`println`

`print`

#### Pseudo-random number generators

Function name | Arguments | Description |
---|---|---|

`rand-u` |
low high {optional-seed} | Uniformly distributed in [low, high). |

`rand-g` |
mean stddev {optional-seed} | Normally distributed around mean with stddev as standard deviation (Box-Muller transform used internally). |

### Array Functions

The `array`

function can be used to construct an array. It is identical to
the square brace literal syntax.

The `make-array`

function creates an array of a given length. By default, the
items in the array are intialized to null.

```
(make-array 3) ; => [() () ()]
(make-array 3 0) ; => [0 0 0]
```

The `get`

function indexes into an array.

```
(get [0 1 2] 1) ; returns 1
```

The `set!`

function modifies the value in the array at the given index

```
(def arr [0 1 2])
(set! arr 1 3)
; arr should now be [0 3 2]
```

So yes, arrays are mutable in LispTick and can me manipulated

```
(append [1 2] 3) ; => [1 2 3]
(concat [1 2] [3 4]) ; => [1 2 3 4]
(len [1 2 3]) ; => 3
```

#### List Functions

The `list`

, `cons`

, `first`

, and `rest`

functions operate the same as in
other LISP dialects. Note, however, that `first`

and `rest`

can also work on
arrays.

### String Functions

The functions `contains`

, `has-prefix`

and `has-suffix`

allows to check if a susbtring is part, start or end of a string.

```
(str "t" 5) ; => "t5"
(str 3.14 "J" 0xf) ; => "3.14J15"
(str "ab" #c) ; => "abc"
(slice "abcd" 1 3) ; => "bc"
(get "abcd" 2) ; => #c
(len "abc") ; => 3
(contains "abcdef" "cd") ; => true
(has-prefix "abcdef" "ab") ; => true
(has-suffix "abcdef" "def") ; => true
```

### Time & Date functions

As seen in Atoms date and time can be “hardcoded” with:

```
T10:30 ; a simple time without date and timezone
2017-10-18 ; a simple date without time
2017-10-18T09:30:01.123456789 ; a full datetime with nanoseconds
```

#### (day)

Get the day part of a date, in the range [1 31], 1 is for 1st day of the month.

```
(day a-date)
```

#### (hour)

Get the hour part of a date, in the range [0 23], 0 is for midnight.

```
(hour a-date)
```

#### (make-bd)

Transform a duration into a businessday duration, allowing to jump holidays when applying to a date.

```
(make-bd d cal)
```

*parameter*

- d: a duration
- cal: a function with a date as argument return true if holidays

*example*

Add 2 business days to a date using week-end calendar.

```
;true is date is saturday or sunday
(defn is-closed[d] (= 0 (mod (weekday d) 6)))
;add 2 business days
(+ 2017-10-19 (make-bd 2D is-closed))
```

#### (make-date)

You can also use the `make-date`

function to create a time or a date.

```
(make-date year {month {day {hour {min {sec {nsec}}}}}})
```

The month, day, hour, min, sec, and nsec values may be outside their usual ranges and will be normalized during the conversion. For example, October 32 converts to November 1.

All arguments are int, if not it is rounded down to int.

*parameters*

- year: the year of the date
- month: optional, default is 1 for January
- day: optional, default is 1 for 1st day of the month
- hour: optional, default is 0 for midnight
- min: option, default is 0 for 0 minute
- sec: optional, default is 0 for 0 secoond
- nsec: optional, default is 0 for 0 nanosecond

*examples*

```
(make-date 2017 10 18) ;same as 2017-10-18
```

```
(make-date 2017 10 18 9 30 1 123456789) ;same as 2017-10-18T09:30:01.123456789
```

#### (minute)

Get the minute part of a date, in the range [0 59]

```
(minute a-date)
```

#### (month)

Get the month part of a date, in the range [1 12], 1 is January

```
(month a-date)
```

#### (nanosecond)

Get the nanosecond part of a date, in the range [0 999999999]

```
(nanosecond a-date)
```

#### (second)

Get the second part of a date, in the range [0 59].

```
(second a-date)
```

#### (time-truncate)

Return the result of rounding t or each timeserie t down to a multiple of d (since the zero time).

```
(time-truncate d t|ts)
```

*parameter*

- d: a duration
- t|ts: input time or timeserie

#### (weekday)

Get the weekday of a date. 0 is for Sunday 1 Monday… 6 Saturday

```
(weekday a-date)
```

#### (year)

Get the year part of a date.

```
(year a-date)
```

#### (yearday)

Get the day of the year of a date, in the range [1 365] for non-leap years, and [1 366] in leap years.

```
(year a-date)
```

### Hashmap functions

The `get`

function also retrieves a value from the hashmap by key.

```
(def h {'a 2 'b 3})
(get h 'a) ; => 2
```

You can give the `get`

function a third argument, which is the default value that will be returned if the key is not found. If no default is given and the key is not found, a runtime error will occur.

```
(get {'a 3} 'b 0) ; => 0
```

The `set!`

function for hashmap works similar to `set!`

for array but using a key instead of an index.

```
(def h {'a 3})
(set! h 'a 2) ; h is now {'a 2}
```

The `del!`

function takes a hash and a key and deletes the given key from the hash.

```
(def h {'a 3 'b 2})
(del! h 'a) ; h is now {'b 2}
```

### Generic Container Operations

The `append`

function can append an expression to the end of an array or
a character onto the end of a list.

```
(append [0 1] 2) ; => [0 1 2]
(append "ab" #c) ; => "abc"
```

The `concat`

function can concatenate two arrays, two strings, or two lists

```
(concat [0 1] [2 3]) ; => [0 1 2 3]
(concat "ab" "cd") ; => "abcd"
(concat '(1 2) '(3 4)) ; => (1 2 3 4)
```

The `len`

function returns the number of elements in an array or number of
characters in a string.