Skip to content

Instantly share code, notes, and snippets.

@rektide
Last active December 15, 2015 13:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rektide/5266090 to your computer and use it in GitHub Desktop.
Save rektide/5266090 to your computer and use it in GitHub Desktop.
Promises are about Getting Rid of a Phase Distinction - A crude guide to what makes Promises Actually Different than every other tool.

A promise is a value, and values are by definition not machines.

Phase Distinctions, Machines, Higher Order Functions,

Tools for composing systems

In CS: a phase distinction is a boundary code goes through on it's way to being run. We write the prime artifact, "the code," but to run a machine, this code is transformed by machines, often many machines transforming, taking whatever the current code is, making decisions about what that code looks like, what it represents, and outputting a new code closer to the final execution target. This is the compilation pipeline goes go through to get executed on the target machine. Phase distinction is applied to types, as types change as code goes through the pipeline, but in general all aspects of the code are going through phasal distinctions as they become closer to being run.

Higher order functions: composing complexity

Async- the most popular library on the planet for helping to deal with functional programming- is a library dedicated to composing functions, it is a worker of higher order systems-

async.parallel([
	function(){ 1; },
	function(){ 2; }
], function() { "done"; });

Is an example async program of a trivial nature. Calling this function is a kind of metaprogramming- it's a function which accepts functions and triggers whatever their program is in a meta way. If we didn't exact value from it's metaprogramming, we'd do it ourselves, but we find metaprogramming more convenient- we like the higher order operations it's doing, how it's helping us to run the processes the we're passing to it-

var ref= 2;
function refDec(done){
	if(!--ref) done()
}
function done(){
	"done";
}
setTimeout(function(){1;refDec(done)}, 0) 
setTimeout(function(){2;refDec(done)}, 0)

Async is a library that executes something alike this second example. There's nothing but async running, the code is just async, but that code that it's executing is to exact a purpose: it's a transformation we're asking of Async here, to take data in, our arguments, the functions we pass it, and to produce a code that will run something alike this stand in example output.

Calling an Async function is a reworking of code you pass in, to get them executed in an outputted fashion you've requested: that's the core concept of a Phase Distinction. It's functional: data in, data out. Code in, execution out. It's a single incident, and we can find very clearly where the transform happens: when we call .parallel.

Promises are none of this-

a negative declaration.

Promises have no such set phase distinction.

We do not set up elaborate machines ahead of time to produce a more specialized executing machine. Higher order functions can only compose, only create more complexity: it's higher order complexity always being added as you pass function into function (whether there is a syntactical pyramid of doom or no): more specialized functions are always being built from one's lower in the order. Libraries like Async are kind at giving us convenience methods to wrap all our existing complexity in more complexity to hide how much complexity we're already doing.

A promise is a value

And a value is for making machines with, writing code about

Promises are none of this. They are values, values signifying a thing, in this case the "thing" is something- anything- from the future: these are first class constructs, values, sitting around, that we can reason with and build processing around.

Promises will retain it's essential property throughout, and is not the cause of nor is it a phase distinction- the promise you have now will demarcate the same future or present value you have latter. There is nothing lost, no process, no machine inherent to this concurrency construct: a promise is a free and pure signifier, and not a thing more. It is a first class signifier of the future, in the same way an interest is a thing we can ask about and reason about, or a string is a thing we can ask about or reason about.

When we practice using promises, we practice using values. We ask, when we have this, and when we have that too, then run this block. This models existing imperative languages closely, and as programmers there is no phase distinction we have to guide our usage of: we are masked from having to deal with concurrency, because the promise creates no phase distinction.

A promise is not code in, code out: a promise is not a machine. A promise's most notable feature is that it does nothing, it is only a value, and values have no Phase Distinctions.

Writing Code

Code aggregates the things in the local scope.

OO

If you write OO code, you compose, you remaster those things to be your own thing. You take ownership and hide away the value, and you become the new value.

Fragile.

Machines for making machines

Functional programming also composes complexity; it's about execution, about passing of processors and values into other processors to compose a desired behavior: machines making machines.

Concurrency

Dealing with multiple things going on requires coordination. We have to sequence and order execution, chain processes on to one another.

Most libraries are compositional in how they attempt to do this: the concurrency library composes a solution to access inputs to compose a new machine based off your inputs that will exact the desired behavior.

Promises

Promises suggest that we keep aggregating, keep having values signifying the future to be. When we need to create a chain, when A then B, we have the values available to aggregate a new processor out of.

Intermediary values are represented as their own value

By aggregating promises, by having each processor return it's own intermediary promise value, we do not build fixed, specialized machines. We can at any point take whatever intermediary machine's future value's we become interested in and hook into that.

There is no phase distinction between the building of our processors and their wiring together, and the runtime. Promises are continual, always just values, and we can always stem from that value to begin to add new computing around it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment