Putting the fun in functional since 2012
16
3
0

# akira

Functional language that transpiles to JavaScript.

## Installing

with nodejs and npm

``````npm install akira
``````

git

``````git clone git://github.com/goatslacker/akira.git
``````

## Usage

``````ast [file]               - output the Mozilla Parse API for that file
compile [file] [target]  - compile to JavaScript
help                     - dis
output [file]            - compile to JS and output
repl                     - start the repl
run [file]               - compile and interpret said file
tokens [file]            - output the lexer tokens for that file
version                  - akira version
``````

## Overview

### Literals

String

``````'i am a string'
``````

Numbers

``````42
2.0
9,000
-3
``````

Boolean

``````true
false
``````

Maps

``````cat = {
:name 'Luna'
:age 2
}
``````

Vectors

``````[1 2 3 4]
[true false]
``````

Regular Expressions

``````/[A-Z]+/g
``````

### Operators

Math

``````1 + 2
4 - 1
3 * 1
9 / 3
``````

Exponents

akira javascript
3 ** 3 Math.pow(3, 3)

Equality

``````true == true
false != true
3 > 2
2 < 3
3 >= 3
3 <= 3
``````

Logical

``````false || true
true && true
``````

Concat and Cons

akira javascript
 ++  .concat(2)
'hello' ++ 'world' 'hello'.concat('world')
1 +: [2 3] .concat(2, 3)

Property Access

akira javascript
{ :key 'value' } !! 'key' { key: 'value' }['key']
{ :key 'value' }.key { key: 'value' }.key
[1 2 3 4] !! 2 [1, 2, 3, 4]
[1 2 3].1 [1, 2, 3]

### Functions

Defining functions

``````sum = fn [a b]
a + b

sub = fn [a b]
a - b
``````

Invoking

``````sum 1 2
``````

Invoking with no arguments

``````| 'hello-world'.to-string
``````

IIFE/Beta-redex

``````| ->
number-of-balloons = 99
``````

Anonymous functions

``````fn [x] x * x
``````

### Pipes

Functions can also be invoked or chained with pipes

``````sum 1 2 | print        -- print(sum(1, 2))
``````

Multiple expressions can be piped together

``````1 | id | print           -- print(id(1))
``````

Previous arguments are carried over into the next function call...

``````1 | sum 2 | (== 3)   -- sum(2, 1) === 3
``````

...and you can use _ (underscore) to place your argument

``````2 | sub _ 1 | (== 1)    -- sub(2, 1) === 1
``````

### Scope

In akira you may not redeclare a variable, so in reality variables are not really variables, they are symbols; you can also think of them as constants.

``````a = 1
b = true
c = [1 2 3]
b = false    -- throws a ReferenceError at compile time
``````

So this prevents you from shadowing symbols and misusing scope. You also don't need to include the 'var' as there are no globals.

``````a = 1        -- outter `a`
b = 2
c = fn []
a = 2      -- creates a local `a`
b          -- `b` can be accessed in here
``````

### Conditionals

If statements

``````n = 4
is-n-four = if n == 4
then true
else false
``````

Multiple conditions

``````cond
n == 4 ? n
n == 2 ? n + 2
else ? 0
``````

### Pattern Matching

Factorial implemented using pattern matching

``````fact = match
 1
[n] n * (fact n - 1)
``````

This splits up the list into x = head(list) and xs = tail(list)

``````sort-even-odd = fn [[x, & xs]]
cond
not x ? []
odd x ? (sort-even-odd xs) ++ [x]
else ? x +: (sort-even-odd xs)

[1 2 3 4 5 6] | sort-even-odd | assert-deep [2 4 6 5 3 1]
``````

### Exceptions

``````try
| some-function-that-may-crash
catch err
raise err
``````

### Async/Await

For handling async functions there are a few tools you can use

get-file = async [filepath] file = path.join process.env.PWD filepath data = await fs.read-file-async file new File filepath (show data)

do get-file 'README.md' then fn [x] print x catch fn [err] print err