Spider is a brand new language to avoid JavaScript’s bad side while embracing its good side. It takes the best ideas of Go, Swift, Python, C# and CoffeeScript, and targets ES5 and ES6.

It was introduced two weeks ago, and since then, it got almost 700 stars in GitHub, 84 issues and dozens of new features and bugfixes. If you haven’t heard of it yet, take a look at “Why Spider?”.

In this post, I want to highlight some of the new features that might excite you.

Channels

Channels are an easy way to communicate between sequential processes. They can be used anywhere: from UI abstraction in the browser to complex Node.js services.

Channels were highly inspired (or, more accurately, stolen) from Google’s Go programming language.

var channel = new Channel(); fn sendMail(title, body) { var message = { title, body }; channel <- message; console.log("Message added to queue."); } go { while true { smtp.send(<-channel); } };

Async/Await

With async functions, you can await on a promise. This halts the function in a non-blocking way, waits for the promise to resolve & returns the value.

Yet again, the concept was stolen from another language. This time it’s C#, though.

async fn loadStory() { try { var story = await getJSON('story.json'); addHtmlToPage(story.heading); for chapter in story.chapterURLs.map(getJSON) { addHtmlToPage((await chapter).html); } addTextToPage("All done"); } catch err { addTextToPage("Argh, broken: \(err.message)"); } }

With a little help from the bluebird library, await can also be used on Node.js-style callbacks to get rid of callback hell:

var fs = Promise.promisifyAll(require("fs")); async fn readFiles() { var file1 = await fs.readFileAsync("file1.json"); var file2 = await fs.readFileAsync("file2.json"); var file3 = await fs.readFileAsync("file3.json"); var file4 = await fs.readFileAsync("file4.json"); console.log(file1, file2, file3, file4); }

Parallel version:

var fs = Promise.promisifyAll(require("fs")); async fn readFiles() { var [file1, file2, file3, file4] = await Promise.all([ fs.readFileAsync("file1.json"), fs.readFileAsync("file2.json"), fs.readFileAsync("file3.json"), fs.readFileAsync("file4.json") ]); console.log(file1, file2, file3, file4); }

Pattern Matching

Pattern matching is a powerful technique that allows you to use a switch statement on multiple variables or expressions.

fn fizzbuzz(i) { var result = [i % 3, i % 5]; switch result { case [0, 0]: { return "FizzBuzz" } case [0, ]: { return "Fizz" } case [, 0]: { return "Buzz" } default: { return "\(i)" } } } for number in [1...100] { console.log(fizzbuzz(number)) }

Curried Functions

Currying is a technique of transforming a function which takes multiple arguments in such a way that it can be called as a chain of functions.

Curried functions work extremely well in functional-style programming.

fn sortBy(key, array) { return array.sort((a, b) -> a[key] - b[key]); } var sortById = sortBy^("id"); var sortByAge = sortBy^("age"); var people = [ { id: 1, name: "Daniel", age: 27 }, { id: 5, name: "John", age: 18 }, { id: 2, name: "Robot", age: 70 } ]; var peopleById = sortById(people); var peopleByAge = sortByAge(people);

Among the new features that were added: ES6 Compilation Target, Modules, Destructring Assignments, Shorthand Notations, Multi-line Strings and Fallthrough Statement.

And that’s just the beginning. Some of the upcoming features are: macros, optional typing and generators.

Spider is still extremely new, but it is advancing fast. If you’re interested in it, make sure to star the repo and join the IRC channel (#spiderlang on Freenode).