JavaScript Programming Swift

Swift for Javascripters: Lambda Capture

Sometimes you want to capture the state of a variable in a function's closure for later use. In JavaScript you could do that like this...

let a = 0
let b = 0

const closure = (a => () => {
  console.log(a, b)
})(a)

a = 10
b = 10
closure()
0 10

In Swift, a closure (or lambda function) looks like this (and here's a nice troll; Swift's let is JavaScript's const and Swift's var is JavaScript's let. And Swift has no equivalent of JavaScript's var)...

let closure = {
  print("hello")
}

closure()
hello

Simple! But it has more features. You can pass it a list of parameters. You can optionally specify a return type. And if your lambda function contains a single expression, it will implicitly return that value, just like JavaScript.

{ (parameters) -> returntype in
    statements
}

Here's a more concrete example of a function that takes two strings and joins them. In many cases, Swift can figure out the return type for you. But in this case we specify the return type to avoid ambiguity with the + operator.

let fn = { (a, b) -> String in
  a + b
}

fn("hello", "world")
"helloworld"

If we want, we can also tell Swift what kinds of parameters the lambda function will receive!

let fn = { (a: Int, b: Int) -> Int in
  a + b
}

fn(100, 1)
101

You can also pass what is called a capture list. A capture list can contain multiple values separated by commas. It's also not limited to values, it can contain expressions.

{ [captures] (parameters) -> returntype in
    statements
}

And finally, here is an example of how a variable in your program might change, but the lambda can capture its value so it is retained for later use.

var a = 0
var b = 0

let closure = { [a] in
  print(a, b)
}

a = 10
b = 10
closure()
0 10
JavaScript Programming Swift

Swift for Javascripters: Super powered If statements (Part 1)

First, a little bit about nothing... In JavaScript, you have the primitive type: undefined which indicates that a variable has never been initialized (or simply does not exist). You also have an entirely different type: null, which can be used to communicate intent: a value has been intentionally set to nothing.

To handle the absence of a value, Swift has the type Optional. It either contains a value and has a specific type or it will be nil.

Swift also has a feature called optional binding. This is like an if statement, but with more features. As with normal if statements, you can check that boolean expressions evaluate to true. But this syntax will also allow you to declare variables (and/or constants) that must result in non-nil values before the statement will execute the associated code block. If the block is executed, the variables that are declared can be used, but only inside that block.

Consider a hypothetical function that takes an array of numbers and returns their min and max values...

if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
  print("min is \(bounds.min) and max is \(bounds.max)")
}

The JS equivalent…

{
  const bounds = mixMax([8, -6, 2, 109, 3, 71])

  if (bounds) {
    console.log(`min is ${bounds.min} and max is ${bounds.max}`)
  }
}

It is also possible to check multiple values and/or booleans at once...

if let a = Int("1"), let b = Int("1"), a == b {
  print("a: \(a) is equal to b: \(b)")
}

The JS equivalent…

{
  const a = parseInt("1", 10)

  if (a) { // ...don't evaluate `b` if `a` is not valid.
   const b = parseInt("1", 10)

   if (b && a === b) {
    console.log(`a: ${a} is equal to b: ${b}`)
  }
}
idea Programming

Async/await without Promises

A while ago I posted about using generators and destructuring assignments for flow control. Now that async has landed and its usable everywhere, I almost always use async/await.

I've never really liked promises. In many ways, they are just as bad as callbacks but with more moving parts. Luckily, promises aren't really a requirement for using async/await. In fact, you can bypass the promise constructor entirely. Just create a then-able. A then-able is any function, object or class that implements a then function (or member, respectively). For example...

Await-able Classes

To create an async class, just implement a then method on it!

class Foo {
  then (success, fail) {
    success(42)
  }
}

async function main () {
  const answer = await new Foo
}
main()

Awaitable Objects

You can just do the same thing with an object.

const Foo = {
  then (done) {
    done (await request('https://foo.com'))
  }
}

Await inside then-ables

Object and class methods can use the async keyword, just like functions.

const Foo = {
  async then (done) {
    done(await request('https://foo.com'))
  }
}

And finally here is something really contentious for all you dare devils out there. You can use destructuring assignments to return multiple values, which could be handy when you are doing async things…

class Foo {
  then (done) {
    request('https://foo.com', (err, res) => done([err, res]))
  }
}

async function main () {
  const [err, res] = await new Foo
}
main()

And, there is of course more than one way to return more than one value!

class Foo {
  then (done) {
    request('https://foo.com', (err, res) => done({ err, res }))
  }
}

async function main () {
  const { err, res } = await new Foo
}
main()

Sure some people might argue that C-style error passing is error-prone. But, bubbling is just as susceptible to mishandling. Choose your poison.

Programming

Data Modeling in Javascript

image Working on Voltra Co., I’ve needed to validate a lot of data. I’ve tried some pretty clever solutions for validating and describing data. But after working daily with these libraries, I’ve found that the javascript just gets in the way. Too much syntax, too much boiler plate, etc. 50+ models with 30+ entities can become a nightmare to read and maintain.

Anyway, after much GTD I took a break to put together DML. DML is a simple language with the goal of making your data models readable and maintainable. The javascript implementation is only a few hundred lines. The documentation is a work in progress at the moment but the syntax looks like this…

//
// An example data model
//

Date created
Number id

String name
  require true "a name is required" // this is a comment
  gt 2 "Must be greater than 2 characters"
  lte 256 "Must be less than or equal to 256 characters"

String bio
  lte 140 "A bio must fit into a tweet"

Boolean accountType

Visit the project on Github.

Photography

Photo Sharing

image

Instagram has a cool hidden feature that will render your photo as ascii art. If you inspect the url of an image and add .html or .txt to the filename you get something like what you're seeing in this picture.

Travel

Amsterdam

If you are in Amsterdam...

image

I'm living in the city. So if you are in town, message me on twitter or comment here on github. Let's ride bikes, write code or play music!

idea

Github is a CMS

Github is basically a big content management system. So, here is an attempt to leverage it as a writing and publishing platform! Issues allow any number of authorized users to publish to the same page, hello painless collaborative blogging!

This project, the blog you are reading, was co-designed and co-developed by @aprileelcich and myself. If you like it, it's MIT licensed, so fork it if you want to! There are only a few things you need to do in order to get it working for yourself...

  • Change the CNAME file to include the correct domain (and obviously your DNS settings to add a CNAME record).
  • Change the config.json file to reflect the correct username and repository. Also make sure you add yourself to the authors array!
  • Edit the static HTML, some of this is specific to me and you will want to change that.

Happy writing and if you have any questions feel free to ask them on twitter or here in the comments section. Ciao. ℙ

idea Programming

Asynchronous flow control using generators and destructuring

Two of my favorite things to come out of es6 were destructuring, an expression that makes it possible to extract data from arrays or objects into distinct variables 1 and generators, functions which can be exited and later re-entered 2. Together these two features can flatten asynchronous flow control.

const { run, wrap } = require('yl')
const fs = wrap(require('fs'))
const assert = require('assert')

run(function* () {

  const [statError, s] = yield fs.stat('./index.js')
  const [readError, f] = yield fs.readFile('./index.js')

  assert.equal(f.length, s.size)
})

The above code uses a tiny library called yl. You could write this yourself easily in under 15 lines of code. If you can make it smaller, send me a pull request! The really nice thing about this code is that you can use it today without the need for a massive tool chain or huge compiler like babel.

You already know about calback hell. But for context, here is the es5 version.

var yl = require('yl')
var run = yl.run
var wrap = yl.wrap
var fs = wrap(require('fs'))
var assert = require('assert')

fs.stat('./index.js', function (statError, s) {
  fs.readFile('./index.js', function (readError, f) {
    assert.equal(f.length, s.size)
  })
})