4 ms·
People have posted a lot of examples in a lot of different programming languages. What they show is that all you really need to build this idiom is first class
by sdevlin 15y ago
People have posted a lot of examples in a lot of different programming languages. What they show is that all you really need to build this idiom is first class functions (or some approximation thereof). (It also shows that the title is not correct; many, many people are familiar with this idiom.)
When you need to wrap up a common block of code, you use a function. This lets you call the same block in a number of different contexts. When you need to fix the context in place and let the block in the middle vary, you write a function that takes another function as a parameter. An example in JavaScript (might be a little off):
var withFile = function (path, action) {
var f;
try {
f = File.open(path);
action(f);
} finally {
File.close(f);
}
};
withFile('foo.txt', function (f) { ... });
This can be generalized (to some extent and depending on language) so you don't need to write the same structures every time:
var context = function (prolog, epilog) {
return function (action, ...args) {
var o;
try {
o = prolog.apply(args);
action(o);
} finally {
epilog(o);
}
};
};
var withFile = context(File.open, File.close);
This example uses JavaScript' hypothetical future "rest" parameters, but there are other ways to manage the same goal.
(Other comments have mentioned the author conflates context management with applying reversible functions. I've only dealt with one of those things here, but similar techniques apply in solving both problems.)
- dwc 15y agoI think that few people are actually aware of this as an idiom. Rather, many people are aware of just a few special cases, but have not considered this in the more general form. All the examples of various languages providing this for open files also kind of misses it. The point is not whether a particular language supports this for open files, but whether people recognize the idiom and the language supports doing this yourself wherever it fits. For a pattern this incredibly common it's a point well worth making.
- sdevlin 15y agoYeah, you may be right that the full generality of the pattern is not appreciated. For what it's worth, I think most commonly used languages can implement some form of the context function in my example.
- masklinn 15y ago> People have posted a lot of examples in a lot of different programming languages. What they show is that all you really need to build this idiom is first class functions (or some approximation thereof). Or macros. Your `context` is called `unwind-protect` in common-lisp. There's a difference in that `unwind-protect` does not take an "opening form" (which you call `prolog`), and this makes your `context` implementation broken: you're executing the epilog if the prolog blows up, which is not correct as you have an `o` of `undefined` at this point (and your epilog likely awaits some sort of valid resource). Side-note, your javascript code also looks incorrect, `apply` takes a context (a `this`) as its first parameter, so you're not applying arguments you're taking the `args` array as the `this` of your prolog. You probably wanted to write `prolog.apply(null, args)`.