heapwolf / blog Goto Github PK
View Code? Open in Web Editor NEWpersonal blog
Home Page: https://hx.ht
personal blog
Home Page: https://hx.ht
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}`)
}
}
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
Hi @hxoht, your SSL certificate expired last Saturday. :)
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 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 and most of its ceremony 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...
To create an async class, just implement a then
method on it!
class Foo {
then (resolve, reject) {
resolve(42)
}
}
async function main () {
const answer = await new Foo
// answer === 42
}
main()
You can just do the same thing with an object. You can name the callback functions whatever you want. Also, you aren't required to use or care about the rejection
callback.
const Foo = {
then (done) {
setTimeout(() => done(42), 1024)
}
}
async function main () {
const answer = await Foo
// answer === 42
}
main()
const Foo = num => ({
then (done) {
setTimeout(() => done(num), 1024)
}
})
async function main () {
const answer = await Foo(42)
}
main()
Object and class methods can use the async keyword, just like functions.
const Foo = {
async then (done) {
done(await request('https://foo.com'))
}
}
You don't need to wrap everything in a try/catch
blocks if you want to inform the caller about failures. Destructuring assignments provide a way to return multiple values…
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
// More than one err? Remember, const and let are block-scoped!
{
const { err, res } = await new Foo
}
}
main()
Sure some people might argue that C-style error passing is subject to mishandling. But so is error-bubbling. Choose your poison.
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...
CNAME
file to include the correct domain (and obviously your DNS settings to add a CNAME record).config.json
file to reflect the correct username and repository. Also make sure you add yourself to the authors array!Happy writing and if you have any questions feel free to ask them on twitter or here in the comments section. Ciao. ℙ
Recently i cleaned up my .vimrc file. I stopped using some plugins and made my setup a little simpler. Here's how i got NERDTree looking so good.
Plugin 'ryanoasis/vim-devicons'
Plugin 'Xuyuanp/nerdtree-git-plugin'
I get this error (after running npm install):
Gizur-Laptop-5:blog jonas$ node server/index.js
events.js:66
throw arguments[1]; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:782:11)
at Server._listen2.self._handle.onconnection (net.js:906:28)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
Gizur-Laptop-5:blog jonas$ npm --version
1.1.62
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)
})
})
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.