There are quite a few interesting computer science artefacts in Drupal. I'm going to try to highlight a few of them. Sorry, this is unfinished, and might not be finished ever, but I'm just trying to capture a snapshot of confused meandering thoughts.
Late binding came to popular life with the advent of object oriented languages. Essentially it means binding of values, for example functions, to names at object creation, as opposed to compile or link time. In drupal, this can happen at any time, more even, it is algorithmic - that is you can change at runtime what is to be executed at a specific control point. The hook system is one of the ways to do it.
After months of work between hunmonk, myself, and chx, we've finalized some substantial progress on multipart forms. A multipart form is a form that is spread across multiple pages (like a wizard), but doesn't truly "submit" until the final page.
Morbus Iff on the drupal development mailing list
That is a cool functionality. While it shows the capability of the forms api to handle multi-page forms via the #pre_render function, which is good, the approach is only the beginning of multi-page form handling.
Some time ago I was writing about a proposed method for resolving application state across multi-page forms. The sceme applies directly.
For a while I've been looking at some interesting techniques for improved state tracking for web applications. Seaside and plt scheme webserver are using continuations to improve session handling, and have a nice clean code while at it. What does this mean? Continuations are a functional goto. They allow you to capture and save the state of an application, and possibly to return to it at any time. You could think of it as a snapshot of the current state of the application. Well, not exactly, but for the current discussion this will suffice.
In a previous short post Idescribe a way to emulate closures in php. Using that technique execution environment, otherwise known as a call stack can be saved for future use. This can be put to good use. A couple of patterns or programming techniques could be useful in practice.
A closure represents a state => implemenation of a state pattern. This is a bit rich. Usually in OO programming the state pattern is implemented by encapsulating different protocols, for denoted states. This is simple to implement by substituting your protocol specification with a different name. Drupal hooks are a good example implementation of this. The following is a simplisting example implementation of a state pattern based on closures. The last argument of the deduced function is the closure itself.
class function_object {
var $scope;
function __get($name) {
return $this->$scope->$name;
}
function __call($name,$args) {
$func =$this->$state."_$name";
$args[]=$this;
return call_user_func_args($func,$args);
}
function __constructor($scope) {
$this->scope=$scope;
}
function __clone() {
$this->scope = clone($this->scope);
}
function state($state) {
$this->state=$state;
}
function call() {
//the function body - do some work
}
}
To save the state for future use, for example as part of an undo cycle:
$saved = clone($closure);
Closure effectively represent the future of computation. This means that we can say what we want to do, by where we are. Since php doesn't implement any call stack optimisation, the call/cc style of programming makes sense in a limited number of cases. To use this style of programming we need to redefine our functions to use the continuation
f(x,c) : c(f,x);
(var, continuation) -> continuation
and in php
//the function closure call method
...
function call($x, $continuation) {
$this->scope=$continuation; // emulate c(f,x)
...
do whatever you want here
}
...
OK, this is rather crude. In reality this is very limited - it is assumed that the function is defined in a 'global' scope, so we are putting it in some exhisting stack. It will be cleaner if the continuation implements the stack assignment, rather than rely on the function.
In programming languages, a closure is an abstraction that combines a function and a special lexical environment bound to that function (scope). The variables in the lexical environment are designed to retain state information between function calls. Unlike garden-variety functions which retain no memory of what happened in previous calls, closures are capable of storing information across function calls.closulres in computer science (wikipedia)
PHP doesn't have closures as an element of the language. What can we do to emulate it?
We need to be able to encapsulate in one entity scope, state and execution. The most obvious candidate will be a PHP object.
With the introduction of the __get(), __set() and __call() magic functions for PHP classes, something the manual calls overloading, PHP opens the gate to transparently enhance a class to add variables and methods to an object's body. We can abuse the __get() to implemet nested scopes. The state is preserved as part of the object body. The default function (call()) is a protocol to add a uniformity of execution between different function objects.
class function_object {
var $scope;
function __get($name) {
return $this->$scope->$name;
}
function __constructor($scope) {
$this->scope=$scope;
}
function call() {
//the function body - do some work
}
}
If all $scope objects are function objects we get a closure emulation in PHP. This opens the doors to such fancy ideas as namespaces, modules et.al. This technique opens the possibilities for functional style programming techniques and idioms as delayed evaluation, continuation, ...
Update: I've added closures to my design patterns collection