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.
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.
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.
That's a great way to put it. I'll steal this one.
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.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).
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.)
Quickly searching, I found https://www.emacswiki.org/emacs/FoldingMode, which seems to be a large start to this. There were also some other ideas that seem to get close.
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: (let ((o (overlays-at 5)))
(mapcar 'delete-overlay o))
So, the basic task that will need to be completed is finding the point position for the start and end of make-overlay.// Find the first foo with bar foos.map(f => f.bar).uniq().orderBy(f => f.baz)[0]
does the same basic thing, the ability to collapse and display intent is incredibly rad for lack of a better word
I agree with you, but seeing the number of proponents of Enterprise Java there are, it's clear that there are a significant number of programmers who prefer verbosity and extra abstractions --- although IMHO not necessarily because it's actually better.
In fact a trend I'm seeing with a lot of programming languages is more verbosity and unnecessary abstraction, leading me to wonder whether programmers actually know the languages they're using or are barely scraping by with the very minimal basics (and in the case of some languages, a bit of OOP cargo-cult dogmatism.)
Although I'm not really familiar with Python, and the order of the clauses its conditional expression syntax is unusual and a little surprising, I think that second line probably took longer to write than it did for me to read.
Even Enterprise Java wasn't verbose for the sake of it (I say "wasn't" because modern enterprise Java can be more like modern functional style than Go).
It was more verbose because it added tons of options and flexibility while keeping with the OO style, so everything was pluggable and configurable and factorable. But that's something else than Go style verbosity.
That's the point. Reading is far more important.
Say, with Scala implicit parameters, you get to remove code from call-site. Does it make the code better? Depends on the case, in my opinion. So I don't get the point to say some people categorically want verbosity. They may prefer explicitness and unsurprising code which may require verbosity. Or perhaps the removal of verbosity requires code that allocates more memory -- in that regard Kotlin seems to be a good citizen. It has ways to make code concise without making the byte code entirely different.
It is more that they have good abstract thinking, so abstraction is not an issue for them. Abstractions are issue only for some people.
> I think that second line probably took longer to write than it did for me to read.
If it takes more time to read then write, then it is not done yet needs to be refactored. Good code is as obvious to read as possible.
The author could have brought the examples forward, instead of just providing links to urllib3 and the Set type.
You can iteratively change a smaller, terser code, must faster. There's a reason prototypes are often written in languages like Python.
In C++, would you write the same structure using a single line for-loop and ternary operators?
The first is that somebody else will eventually have to work with it, decipher what the heck I was trying to achieve, and generally get tripped up and slowed down by it.
The second is that eventually I may have to work with it again, and sit there scratching my head and wondering what I'd been smoking when I wrote instead of focussing on the changes I need to make.
The point is to code for maximum clarity to humans whilst still achieving the desired functional and non-functional outcomes on the machine. You will use varying terseness as part of doing this because terseness isn't the point: it's just one of many means to your end.
for(i=0,total=0;i<resultlen;i++) {
int price = results[i].price;
total += results[i].selected && (price&1) ? price : 0;
}
In C++, someone would probably do the same using the standard library functional programming templates etc., approaching the conciseness of the Python (and coincidentally, likely generating even more code than the simple loop above.)It's not "cleverness", but rather the ability to express the intent as succinctly and clearly as possible. Higher level languages allow you to do that, lower level languages don't. Obviously, Go is not a very high level language because it forces you to write explicit loops instead of using comprehensions or functional algorithms. Loop is a primitive concept. All other factors being equal (i.e. performance) you should always prefer comprehensions or algorithms over explicit loops.
Objective thinkers tend to go looking for existing, established boilerplate or frameworks because of the immediate leverage that is provided. They may think of too much subjective thought or originality as ridiculous NIH or wheel-reinvention. Their struggle is in the weighty task of grokking and maintaining third-party resources.
Scott Adams has kind of unwittingly uncovered this dichotomy with his own inventive, subjective thinking. He considers more objective thinkers as "word thinkers" or some name like that, because they go looking up the established names of things rather than understanding the things themselves.
Also Chris Langan similarly trashed Jeopardy contestants in a news interview, because they aren't subjective thinkers like he is; their minds are just filled with objective facts about various things. Well, true for him; his bias dictated the way he developed his own unique universal model--he prefers and has a gift for subjective thought.
Really though, we need both kinds of approaches.
The thing with code is that you can take those existing patterns and make them a first-class concept in your program. You're still in "objectively thinking" - still reusing existing code - just in a more compact and safe way.
And words are amazing. All these complex and nuanced concepts we're talking about can be expressed and shared almost instantly because of the words we share. If we had to invent words as we communicated, or worse yet, had no words, there would be no discourse because the sun would go down before we got anywhere.
It is true that words are set in their definitions and intuitions, much in the way that scientific models are and common sense is. These can be considered objective facts.
But challenging these facts and inventing new words is just an important part of the process. Some have more success with it than others, but not looking up what is already known is just wasting your time. Same with not using words that already mean what you mean.
Subjective thought leads to objective facts with fact checking. Objective facts are then better shared, and better learned, because learning is far easier than arriving at them yourself. Learning just takes communication, which is proportional to the complexity of the information. Inventing or discovering new facts requires the entire lengthy and laborious process which is will inevitably include experiments and fact checking and evidence validation if we are to be scientific. If the problem can be solved with pure thought, chances are it was a philosophical one, although philosophy too highly relies on existing language.