A fun, productive, and simple functional language that compiles to JavaScript.
intro | running | types | built-ins | standard library | using eth for a project | developing
intro
eth is a small in surface, small in code, easy to master, easy to adopt, functional language that will bring productivity and joy to your day programming.
simple
I tries really hard to have a unified interface, and a small amount of primitives keeping JavaScript's awesome core and avoid all the new reserved words and doubtedly useful features recent versions of JavaScript are rapidly adding.
close to JavaScript
eth remains very close to JavaScript, except for the lispyier syntax primitives are almost all written the same way, it's compatible with the whole JS exosystem, and it support all of ES5 features so, we could bet you wont feel lost when writing your first bits of eth code.
lethttp lethostname "127.0.0.1"letport 3000 letserver http server
running
You'll want to start by installing eth
using npm
:
npm install --global eth
There a repl you can start with:
$ eth repl
eth> +(3 5)
8
eth>
You can compile files to JavaScript using:
$ eth <file.eth
// ... eth prelude ...
sum(3, 5);
Or run them right away using (for production use it's better to compile & run with node
):
$ eth eval file.eth
8
In summary:
Usage: eth [command] [arguments]
Commands:
h, help prints this message
v, version prints eth's version
r, repl starts the repl
e, eval runs given file or code
b, build builds the given file
eth also works using stdin & stdout like so: eth <app.eth >app.js
Documentation can be found at http://eth-lang.com
language types
name | example | description |
---|---|---|
nil | nil |
translates to undefined |
boolean | true |
same as JS booleans |
number | 1.23 |
same as JS numbers |
string | "xyz" |
same as JS strings |
keyword | :xyz |
similar to ruby keywords, translates to a string |
symbol | x |
translates to the symbol itself but supports special characters disallowed in JS |
array | [1 2 3] |
same as JS arrays, but, you drop the commas |
object | {:a 1 :b 2} |
same as JS objects, but, you drop the commas and colons |
language built-ins
get -> a[b]
set -> a = b
let -> var a = b
delete -> delete a.b
fn fn(a b {+(a b)}) -> function (a, b) { return a + b; }
cond cond(==(a b) a :else b) -> if (a == b) { return a } else { return b }
loop -> TODO use recursion!
package -> TODO use set(module.exports { ... })
import -> TODO use let(fs require("fs"))
standard library
The standard library is, at it's core, composed of all the functions in Ramda.js.
ramda
is a really neat library packed with small utility functions that all have a well designed
functional api.
Similar to lodash
and underscore
you might say but there is a fundamental difference in how ramda
orders the arguments it's functions take that makes it especially suitable for currying, composing
and functional programming in general.
If you are interested in functional programming and using eth
I then strongly encourage you pass by
ramda's awesome documentation and read the introductory post
Why Ramda?.
In addition to the functions from ramda
, eth
defined a few more useful function like to-json
,
print
, assert
and more. They are all listed below.
print assert
toJson fromJson
string type isOfType
isOdd isEven
regexp regexpMatch regexpFind regexpReplace
getIn setIn updateIn
using eth for your next project
browser
Eth compiles down to plain JavaScript so you could simply run eth <app.eth >app.js
and load
app.js
in a browser but that only hic is that you won't have access to the nice import
statements
any more.
To be able to use import
s (really require
s) you need to use a module loader / system to bundle
your code for browsers. This implies that there needs to be an integration written for the tool you
are going to choose.
For Browserify users there is no eth
integration yet but if you are up for it this soloify
project should be a good example to look at.
If you are using webpack you can install the eth-loader
package and use it like so:
// webpack.config.js
module.exports = {
entry: './src/app.eth',
output: {path: './build', filename: 'app.js'},
module: {
loaders: [{test: /\.eth$/, loader: 'eth-loader'}]
}
};
node
The story here is similar that that of CoffeeScript or TypeScript, you have mainly two option:
compiling all files and running those with node
or using node.js require.extensions
to register
a handler for files with a specific extension, .eth
in our case (this is clearly not production
worthy).
Option 1: Compiling and running
Here, a simple Makefile
that looks like the following can come in super handy:
ETH := node_modules/.bin/eth FILES = models.js routes.js server.jsTEST_FILES = test/models.js test/routes.js default: run %.js: %.eth $(ETH) <$< >$@ build: $(FILES) $(TEST_FILES) run: build node server.js test: build node -r ./test/models.js ./test/routes.js clean: @rm -rf *.js @rm -rf test/*.js
Option 2: Require extension
This version of getting .eth
files to run on node.js is by far the easiest, it consists in having
a .js
file the simply requires eth/register
followed by your server.eth
, from that point on
all require
s resolving to .eth
file will get compiled first, then ran.
// bootstrap.js;;
library
You will probably want to have two directories, say src
for .eth
source files and a lib
or
build
folder for compiled javascript.
That way people consuming your library don't even need to know it is written in eth
and still use
it. To get there you'll simply have to make sure that you build all necessary .js
files before
commiting changes and have a line that looks like "main": "build/index.js"
in your package.json
.
developing
The compiler for the language is all in eth.js
and is still way under 1000 lines.
The repl/cli tool is implemented in bin/eth
.
The standard library is written in eth
and is located in the core.js
file.
To run the test suite simply run:
make test
license
MIT, see license
file.