4 ms·
The word 'reification' is a beautiful one that means to make something hidden visible or accessible, or to give concrete form to an abstract thing. The first t
by cryptonector 8y ago
The word 'reification' is a beautiful one that means to make something hidden visible or accessible, or to give concrete form to an abstract thing.
The first time I happened on that word was when reading about Scheme continuations. The simplest way to describe continuations is: reification of return addresses.
In a language like C every function call has a hidden argument: a return closure that consists of a text address and a value to restore the frame pointer to upon return.
Reifying the return address closure requires giving it a name, and that name is simply "continuation" -- it refer to what follows when this function returns by... calling its continuation.
Because returns (now: calls to continuation functions) are always done in the tail position by definition, the caller's stack frame can be reused. This is a key point.
There's only one other mystery needed to fully explain Scheme continuations. Namely, that function frames have to be allocated on the heap in order to get full Scheme semantics. Add delineated continuations and you can have function frame stacks again at the price of a bit more ceremony so that the run-time can know when to call a function on a new stack.
- _old_dude_ 8y agoThe name reification comes from the latin res, thing, so it's the processus that transform something into a thing. For a language runtime, it's the way to transform a language artifact to a runtime object. By example, in Java, apart the reification of the type argument, the transformation of a lambda to a proxy that implement the functional interface is also a reification.
- talaketu 8y agoThanks for the latin! I'd only heard reification in the context of data modelling, where it's often meant to model the meta-model. For example, RDF reification. RFD involves statements in the triple form (subject, predicate, object). The triple (Mary, enrolled, UCSF) corresponds to the statement that "Mary is enrolled at UCSF". A reification might be to turn that statement into a subject, and to make a statement about the statement. Eg. ((Mary, enrolled, USCF), created, 2018-12-06) - the statement that Mary is enrolled at USCF was created on 2018-12-06.
- dfabulich 8y agoThis explanation of continuations obfuscates more than it reveals. You say that a continuation is a reification of return addresses. But what's reification? Never mind that, what's a return address? It's a return closure that consists of a text address? You mean, text, like, a string, an array of bytes? Oh, uh, no. And, if you're really trying to explain this to a C programmer: what's a closure? Who are you imagining talking to that already understands what a closure is but doesn't know what a continuation is? Closures are at least as confusing as continuations; arguably more so. What's "the tail position"? What does it mean to reuse a stack frame? ("This is a key point.") Are they different from function frames? Who does this explanation serve? Certainly not a JS programmer trying to learn for the first time how to use function* and yield. Not a C programmer. I think this explanation is for a Scheme programmer playing Ockham's razor to define things in terms of the smallest possible number of other things. This behavior can entertaining, but it's not educational, not explanatory. You can define arithmetic in terms of set theory, but that's not how we teach arithmetic to children. Similarly, we shouldn't explain continuations in terms of implicit return closures. Try this: Continuations allow you to pause and resume functions. The paused functions fold up into "continuation" values, which you use to resume the function where it left off.
- vostok61 8y agoI disagree with your statement that grandparent's explanation was not educational. The explanation helped me, a primarily C programmer who has done some work in higher level languages. When I read "reification of return addresses" that helped the concept click in a way it has not before.
- nothrabannosir 8y agoI disagree. Parent's comment was crystal clear and actually had me thinking; "I gotta start using that." I've been struggling with explaining continuations for a long time. Passing a return address is a great explanation.
- naasking 8y agoIt's more than a return address though, since those are stateless. It's more like a return context since it can encapsulate state.
- todd8 8y agoThere is a little nugget here that I've always found illuminating: the mention of the text address and frame pointer, sometimes called the ip-ep pair, short for instruction pointer and the environment pointer. The environment that a function executes in is important if, as in most interesting languages, there can be any free variables within the body of the function. What is the environment of a running function? Usually, its a collection of variable-name binding frames that determine the value of a programs variables at any point in time. The ep stands for the pointer into the data-structure (e.g. stack and its back links) that determine how variables are attached to values at a particular moment. Lots of languages use stacks to hold these frames. In dynamic scoping languages, for example some Lisps like Emacs Lisp, a free variable's value is found in the stack frames determined by the run-time order of calls. Most modern languages use static scoping and the frames that determine a function's free variables values are based on the static nesting of functions or modules as they appear in the source code. In either case, a stack is usually where these frames that bind names to values are found. Dynamic vs static scope just changes which frames are searched for the binding of a variable at runtime (optimizations make this faster enough to be practical). The text address is the reference to the next instruction (symbolic, virtual, or machine level) to be executed in a text segment (or code segment), the part of an object file that holds executable instructions ; I think of it as the IP of assembly language. These two elements form a pair that in a simplified view represent a program in execution at a specific moment in time. So, this (ip, ep) pair is like a frozen program that can be brought back to life by simply loading two values into the basic execution machinery, the instruction pointer and the environment pointer. They need to be stored somewhere when a function is invoked and reloaded so that the caller is resumed upon return of the called function. When narrowly interpreted as parts of a call stack it's easy to lose sight of the power of the (ip, ep) pair. Part of Scheme's beauty was the expicit embrace of continuations as first class objects that can be flexibly manipulated by a running program and reified to put the program into a previously frozen state and awakened to continue there. The Borrough's 5700 was designed to support a specific model of computation (Algol 60) and it's hardware description in [1] has pretty diagrams of the interaction of the ip,ep pair and the hardware (although the book is quite dated now). [1] E. Organick, Computer System Organization: The B5700/B6700 Series, 1973, https://www.amazon.com/Computer-System-Organization-B5700-B6700/dp/1483205614 https://www.amazon.com/Computer-System-Organization-B5700-B6...
- cryptonector 8y agoI was in a hurry. I forgot to add where the reification comes in! Scheme's call/cc is just taking the current function frame's return address closure and passing it as a function argument to the function given to call/cc -- this is the reification of the current function frame's return address closure.