to read or debug code with them in it one
has to understand them
Perhaps I'm missing some subtlety to the post, but when was that last time that you were able to take a pass on understanding while debugging?
I think what the author is looking for is better compile-time checking and error reporting in the the with-* macros. I'm not sure how to respond to the "understanding" points. Is the need to understand your language constructs considered a sign of leakiness? I would say no.
> when was that last time that you were able to take a pass on understanding while debugging?
When I run a program I've written in C or Python, the only program that's really running is written in x64 machine code, because that's the only language the processor understands. But I can debug my program without having to understand the x86 instruction set, because high level languages abstract it out.
But if the abstraction was leaky, OTOH, I would still have to understand the details of what's being purportedly abstracted out, so the abstraction wouldn't be properly doing the job of an abstraction.
You don't need to know how it's implemented, you just need to know that you have to pass an object that can be closed. You can get that simply by reading the docs.
The exception that's thrown in your first example above certainly makes it blatantly obvious what you did wrong, which is nice. but you still have to know that the addition operator doesn't let you concatenate numbers and symbols in order to use it effectively, or your program will crash once you run it. That's on you.
I can feel a bit of his pain, though. I think some of the trouble is that there are things that should be closable, but the (.close x) isn't enough. A Closable protocol could help with some of this.
Granted, laziness still makes this issue very, very tricky.
Hm I do not agree with you re: `->` and `->>`, and have had no problems with Clojure's context-managing fns (though my experience is limited). Not sure how they're "leaky" at all. They do require a little getting used to but once you understand what's happening they're great.
I say that mostly as someone who is very picky about how his code looks, especially with regard to whitespace, keeping line length under 80 columns, and so forth. The threading macros are great for presenting code in a very readable way.
Yes, and I also think that this discussion needs to mention the facilities Clojure provides to help you with macros.
For example, with simpler macros like -> and ->>, I recommend that curious people macroexpand them, to get a feel for what they mean. Your GUI can make this even easier, like if I put the cursor at the beginning of the following and hit M-x slime-macroexpand-all:
Or if I do M-. , I get to see the sourcecode. This of course is daunting to beginners, but they can easily mess with the sourcecode, tear it apart, and get to the level where they can just kind of scan smaller macros and get a rough idea of how it's doing its job.
(I realize the author probably knows these things. But I definitely consider -> and ->> to be such a readability win, and hope that people like them.)
user> (doc with-open)
-------------------------
clojure.core/with-open
([bindings & body])
Macro
bindings => [name init ...]
Evaluates body in a try expression with names bound to the values
of the inits, and a finally clause that calls (.close name) on each
name in reverse order.
The documentation for with-open explicitly states that the expanded form calls .close on the provided names in reverse order. I'm not sure I get how this is a leaky abstraction. Would the author simply prefer to not have to read the docs before using a macro?
Just to state the obvious. With-open respects the close pattern, not the Closeable interface. Plenty of java resources observe the former but not the latter e.g. jdbc Connection interfaces.
I was hoping the article would be about legitimate problems with macros. They do exist...
I think what the author is looking for is better compile-time checking and error reporting in the the with-* macros. I'm not sure how to respond to the "understanding" points. Is the need to understand your language constructs considered a sign of leakiness? I would say no.