The Lisp crowd was right, as usual.
The Lisp crowd was right, as usual.
40 years ago.
Fortunately we’re getting there, feature by feature. Maybe 2030 will be the decade yaml goes away.
Such "contexts" are somewhat ad hoc in Lisp, whereas Ruby and Python have built-in language support and special syntax for them. The traditional Lisp idea is that you don't need special language support when you have macros and higher-order functions, but the special language support also means that all context managers follow the same protocols, whereas ad hoc contexts introduced by CALL-WITH-FOO/WITH-FOO are more like a common loose convention than a standardized system.
Functional programmers have also understood this idea of structured contexts for a very long time, giving us Functor, Applicative, and Monad.
https://en.wikipedia.org/wiki/Advice_(programming)
> all context managers follow the same protocols
Lisp is an old language with lots of dialects and systems. Thus people had different needs for context management and different facilities available to implement it.
Absolutely, my first thought was `dynamic-wind`.
https://www.gnu.org/software/guile/manual/html_node/Dynamic-...
A big part is those good solutions are those little lambda-receiving functions that do all the heavy lifting without imposing a lot of boilerplate. Not too many of them, of course.
IMO this kind of thing is where the “getting things done” and “good architecture” meet.
Declaring data imperatively is quite a contradiction. You need a lot of effort and misguided design to create it. You don't need first class code blocks to avoid it.
(But, of course, first class code blocks help in many other ways.)
with open('file') as myfile:
process(myfile.read())
When control leaves that context, `file.close()` is always called. You don't have to remember to close it. Even if `process()` raises an exception, the `with open` context will close it before passing the exception upward. You never have to remember to clean up the file yourself.It's not that you can't do all that without context managers, obviously. People have done it for a long time. It's just that the `with open...` pattern is effectively bulletproof and removes just one more potential footgun.
open('file', (myfile) => process(myfile.read()))
It would be on the implementer of `open` to call `file.close()`, but presumably that's true of python as well? def open_context_manager(filename):
try:
f = open(filename)
yield f
finally:
f.close()