Skip to content

Instantly share code, notes, and snippets.

@wavebeem
Created December 2, 2015 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wavebeem/f47626f2529cee0636ce to your computer and use it in GitHub Desktop.
Save wavebeem/f47626f2529cee0636ce to your computer and use it in GitHub Desktop.
### Imports
let {JSON, document, console} = global
### Basic data
let namedConstants = [true, false, null, undefined]
let numbers = [1, 2, 1_000, 3.14, NaN, -Infinity]
let strings = ["hello,\n", "\u{20}", "\"world\"\u{2757}"]
let arrays = [[], [1, 2], [3, [[4]], [5]]]
let objects = [
{},
{a: "b"},
{key: 400, "first name": "Fatima"},
{("a" ++ "b"): "ab"}
]
### Trivial functions
let alwaysFourA = fn() 4
let incrementA = fn(x) x + 1
def alwaysFourB() = 4
def incrementB(x) = x + 1
def curriedAddThree(a) =
fn(b) fn(c) a + b + c
### First multi-line example
def addStringsAsNumbers(x, y) =
let x = Number(x)
let y = Number(y)
in x + y
### Named this example
def methodShowXLater(@this) =
setTimeout(fn() console.log(this.x), 300)
### Variadic function
def max(...xs) =
Math.max.apply(null, xs)
### Basic recursive function, obligatory factorial
def factorialA(n) =
if n < 0 then
error "cannot factorial of " ++ n.toString()
else if n == 0 or n == 1 then
1
else
n * factorialA(n - 1)
def factorialB(n) =
match n
case 0 => 1
case n => n * factorialB(n - 1)
### Working with a custom data type using just functions
def makePointA(x, y) = {x, y}
def pointAdd(a, b) =
let {x: ax, y: ay} = a
let {x: bx, y: by} = b
in makePointA(ax + bx, ay + by)
### Working with a custom data type using prototypes and methods
let pointProto = {
add: fn(@this, that)
makePointB(this.x + that.x, this.y + that.y),
scale: fn(@this, n)
let _ = console.log("DEBUG: scaling by", n)
in makePointB(this.x * n, this.y * n)
}
def makePointB(x, y) =
# This will be frozen and have the right prototype thanks to the `~` op
Object.create(pointProto) ~ {x, y}
### Working with updating objects
def updateNameA(person, name) =
if not person has "name" then
error "person didn't alreay have a name field"
else
person ~ {name}
def updateNameB(person, name) =
match person
case {name: _} =>
person ~ {name}
### Pattern match heavy algorithms
def sort(items) =
match items
case [] => []
case [x, ...xs] =>
let lt = xs.filter(fn(y, _, _) y < x)
let gt = xs.filter(fn(y, _, _) y >= x)
in sort(lt) ++ [x] ++ sort(gt)
def map(f, xs) =
match xs
case [] => []
case [x, ...xs] => [f(x)] ++ map(f, xs)
### Sneaky log stuff
def sneakyLogA(x) =
let _ = console.log(x)
in x
def tap(f, x) =
let _ = f(x)
in x
def sneakyLogB(x) =
tap(console::log, x)
### Lots of cases
def numberToEnglishA(n) =
if n == 1 then "one"
else if n == 2 then "two"
else if n == 3 then "three"
else if n == 4 then "four"
else "some other number"
def numberToEnglishB(n) =
match n
case 1 => "one"
case 2 => "two"
case 3 => "three"
case 4 => "four"
case _ => "some other number"
### Try example
def safeParse(text) =
match try JSON.parse(text)
case ["ok", obj] => obj
case ["fail", _] => {}
### Await example
def saveProfilePic(userId) =
await profile = httpGet("/user/" ++ userId) in
await image = httpGet(profile.imageUrl) in
await _ = writeFile(profile.userName ++ ".jpg", image.data) in
console.log("Saved image for " ++ profile.userName)
### Node.js HTTP server example
let http = require "http"
let port = 1337
let host = "127.0.0.1"
let url = "http://" ++ host ++ ":" ++ port.toString() ++ "/"
def handler(res, res) =
let headers = {"Content-Type": "text/plain"}
let _ = res.writeHead(200, headers)
let _ = res.end("Hello world\n")
in undefined
def start() =
http.createServer(handler).listen(port, host)
in console.log("Server running at " ++ url)
### Example app from http://mithril.js.org/
let Page = {
list: fn()
m.request({method: "GET", url: "pages.json"})
}
let Demo = {
controller: fn() {
pages: Page.list(),
rotate: fn()
pages().push(pages().shift())
},
view: fn(ctrl)
m("div", [
ctrl.pages().map(fn(page, _, _)
m("a", {href: page.url}, page.title)
),
m("button", {onclick: ctrl.rotate}, "Rotate links")
])
}
let _ = m.mount(document.getElementById("example"), Demo)
### Example Squiggle app using virtual-dom
let H = require "virtual-dom/h"
let diff = require "virtual-dom/diff"
let patch = require "virtual-dom/patch"
let createElement = require "virtual-dom/create-element"
let {Object, setInterval, document} = global
let {assign} = Object
def render(state) =
H("div", {className: "box"}, [state.count.toString()])
let app = Object()
def start() =
let _ = assign(app, {
state: {count: 0},
tree: render(app.state),
root: createElement(app.tree)
})
let _ = document.body.appendChild(app.root)
let _ = setInterval(update, 1000)
in undefined
def update() =
let state = app.state ~ {count: app.state.count + 1}
let tree = render(state)
let patches = diff(app.tree, tree)
let root = patch(app.root, patches)
in assign(app, {state, root, tree})
let _ = start()
### CSV parsing example
let papa = require "papaparse"
let fs = require "fs"
let {Object, console} = global
let csv = fs.readFileSync("data.tsv", "utf8")
let result = papa.parse(csv, {header: true})
let indexToName = [
"day",
"time",
"length",
"type",
"novdec"
]
def explode(x) =
x.trim().split(SOME_REGEX)
let counts = {
day: Object(),
time: Object(),
length: Object(),
type: Object(),
novdec: Object()
}
def inc(obj, key) =
let n =
if obj has key
then 1 + obj[key]
else 1
in assign(obj, {key: n})
result.data.forEach(fn(obj, _, _)
let fields = result.meta.fields
let n = fields.length
in fields.slice(1, n - 1).forEach(fn(k, i, _)
let name = indexToName[i]
let choices = explode(obj[k])
in choices.forEach(fn(choice)
inc(counts[name], choice)
)
)
)
in console.log(counts)
### END ###
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment