Open dominictarr opened 9 years ago
I could have sworn that there was some reference to time signatures in jsig, either in the spec or in an issue somewhere, but I can't find it after a couple minutes' search. In any event, I first heard this terminology from you, and I think it's an interesting way to communicate programmer intent.
Is it within scope for jsig? I think so, conceptually. Is it currently addressed? No- current signatures are concerned with the point-in-time structure of an object or value.
If we are to introduce new syntax to the jsig grammar, we must be clear about what it is that we're expressing. One way to think about callbacks is that they are functions which may be called at most once- and that the function itself is declaring that requirement. From the other end, the caller is a function which takes an argument that is a callback, and it is making the contract that it will call that function at most once. This restraint-requirement pair is needed if we are to prove a strong guarantee that the assumptions are the same from both the caller and the callee - what we informally use as "node callbacks". Should this be annotated both on the caller and callee?
These are also useful constraint-primitives for describing distributed systems! Having common semantic and syntactic constructs for systems ranging from two functions to thousands of cores strikes me as useful.
There's another orthogonal property of functions that could be described (I don't intend to explore it fully in this post, but for the sake of considering the limits of jsig's expressivity): event-loop ordering. Is it possible for a callback to be invoked in the same stackframe? Or is it guaranteed to be delayed until the current stack is unwound, either as a microtask or on a future turn of the event loop.
I don't know if any one other than me has used the term "time signatures" this way (outside of music theory, of course). In a evented runtime it feels to me that asyncness is a much more challenging aspect of programming than type errors.
I've heard related notions expressed regarding distributed systems, e.g. by Peter Alvaro and work on bloom and in describing properties of message delivery, notably at-most-once, at-least-once, exactly-once. I'm also reminded of a conversation we had at nodeconf one year where you were expressing state machines in regex notation; in particular, the cardinality notation of ?, +, and *.
To be a correct node.js callback a callback must be called back exactly once. If it's to be called back many times (+), or 0 - many times () or maybe once (?) then that is a listener. There are some unfortunate things in node event emitters, for example, being used to represent events that are called \ times or ? times. (am using regexp repeat symbols here)
You could write this as
(args...)? => void
for a function that is called at most once. etc