Generalisation is always[tm] a bad idea. Taken to illogical extremes, at the other end of the spectrum we have the monstrocities of old Perl. After all, with Perl it was often said that you could fit most solutions to a oneliner.
In fact, I would go as far as to claim that using Python for n-tuple iterators inside branched comprehensions are getting awfully close to the worst aspects of what Perl scripts were commonly criticised for.
Perl golf is certainly an extreme example, but more commonplace is the convention-over-configuration in Ruby on Rails. Mostly this is useful in avoiding boilerplate and increasing "programmer happiness", but (in my opinion) the C-over-C is slightly overcooked. I believe a small amount of boilerplate declaration goes a long way towards assisting with debugging and production correctness. Two examples from Rails to illustrate:
1. RESTful routes leading to implied controller actions that render a view without any controller declaration at all. I've seen more than one codebase with routes that could be invoked by users despite being never linked in production and having no test coverage. It's basically undocumented code due to a total absence of declaration, and a case of needing to know the implied framework behaviour to understand a program.
2. I have an issue with ActiveRecord's schema behaviour. By avoiding attribute declaration in models and just defining ORM methods by asking the database for column names, it only takes one poorly handled migration or a DBA oops to lead to some very strange production behaviour. Situation is only partially offset via the (new) attributes API and/or a schema cache dump during CI but one can never fully do away with the hazard. Philosophically speaking, sometimes Rails thinks it is dictating the database schema, sometimes Rails accepts what the database tells it, and out-of-the-box rails has no model boilerplate that bridges the gap to guarantee a specific DB schema.
In both cases I add my own safeguards for production environments, but that's a matter of programmer discipline rather than mandatory declaration.
Convention most of the time doesn't reduce boilerplate at all while it increases exponentially the headaches for anyone reading the code.
A typical example is using the awful Prism way to display a view in a WPF application.
For some reason completely alien to me the people at Microsoft practices, or whatever it was called at the time, explicitly suggested to use the IOC container directly (or with a kind of service locator) to create a view that automatically will try to load a view model with the same name if it existed, without throwing any error if it wasn't found.
This is the worst possible suggestion ever.
It is much easier and much more readable to just get your view model as a parameter in your main viewmodel, the IoC container will create it for you, you assign it to a public property and the view defined in a template is automatically shown in a content presenter.
This is extremely easy, much easier to do than to explain, there is no whatsoever connection to the container, if the viewmodel is not found you receive a runtime error, the view model has no relation at all with the view, it can be called whatever you like and the view has an explicit connection with the viewmodel.
So in this case the removal of convention based loading not only makes everything explicit, but also removes all the boilerplate needed to get a view from the container.
I don't particularly like ROR exactly for the same reason for which I don't like this convention driven way just explained.
And as you can see removing conventions and using different techniques can actually reduce the boilerplate if done properly.
Perl's terseness is about ripping meaning away from the code's symbolic representation to save a few characters. That's a related issue to boilerplate, but it's not the same thing at all.
Boilerplate is usually maximized in projects which try to give users a huge amount of flexibility that they don't need or want.
This is partly why minimizing boilerplate is so hard - one thing that continually surprises me is what users want flexibility over and what they don't. I've lost count of the number of times I've given users flexibility to do something they don't give a shit about and not given them the flexibility to do something they really wanted.
You can code golf in any language and it will probably result in less comprehensible code. If there's one thing I think I agree with the original author on, it's that terseness is not an end unto itself. But I think the overall point that terseness can sometimes be bad so therefore we shouldn't work at a higher level of abstraction is really at odds with everything we've learned about programming in the last century.
On a related note: The single thing I absolutely love in Visual Studio is how it handles C#'s #region statements. While they traditionally seem to be used mostly to group class members (which doesn't really benefit the reader much, IMHO), one can use them to hide the fact that C# still has the tendency to be a bit verbous by reducing complicated methods to pseudo code.
I tend to use this pattern quite a lot:
#region Find the first Foo with Bar
var foo =
foos.Where(f => f.Bar)
.Distinct()
.OrderBy(f => f.Baz)
.FirstOrDefault();
#endregion
I still miss a similar feature in Emacs and Vim. There are similar folding markers one could use (say {{{ }}}), but they don't seem to work together with syntax-based folding.
If you know how to do this, I would indeed be interested.
I already pondered if it wouldn't be possible to merge multiple "folding strategies" if one would build some kind of interface with which multiple routines could basically communicate folds in a buffer.
Say you have one routine scanning the syntax of the according language, one looking for folding markers and one for manual (Vim-style) folds. I guess it technically should be trivial to use all of them provided they are nested and don't intersect in weird ways (the latter could be resolved with some simple priorities).
I wound up not getting the computer out. Looking at it right now to see if it would be as easy as I was thinking.
Simply put, knowing how advanced org-mode can get with folds, this is likely trivial to do. (If you haven't played with it, I'd recommend taking a look. I don't have perfect examples, but http://taeric.github.io/DancingLinks.org is an example. Open that in emacs with org-mode and you will see that all of the source blocks can be folded together. For me, the source blocks are correctly colored, as well.)
The basic idea I had was to just make a few functions that would:
- Fold from current location to next #endregion
- List all region/endregion's in the current buffer
- Fold all region/endregion's in the current buffer
The second of those felt trivial, since it is basically M-x occur #region\|#endregion. On top of that, I just need to learn how to actually make overlays and then the rest feels like it would fall into place easily enough.
Edit: It occurs to me that I didn't show how to actually hide text, which I think is your question. Fastest way I can see is this (run this in your scratch buffer to see it in action):
(let ((o (make-overlay 5 120)))
(overlay-put o 'display "---hidden---"))
To easily delete this particular overlay, if you make it, use:
Generalisation is always[tm] a bad idea. Taken to illogical extremes, at the other end of the spectrum we have the monstrocities of old Perl. After all, with Perl it was often said that you could fit most solutions to a oneliner.
In fact, I would go as far as to claim that using Python for n-tuple iterators inside branched comprehensions are getting awfully close to the worst aspects of what Perl scripts were commonly criticised for.