You know what gets things done and makes things easy to maintain? Boring ass code. IF statements. FOR loops. I mostly use Perl today. It doesn't get in the way. But getting things done is not trendy. That's where we are today.
You know what gets things done and makes things easy to maintain? Boring ass code. IF statements. FOR loops. I mostly use Perl today. It doesn't get in the way. But getting things done is not trendy. That's where we are today.
When you have a lot of wordy, boring code to maintain, you have to make coordinated changes in more similarly boring places. A human's brain can only keep that many lines of context. So it becomes easier to make a mistake.
I understand that abstraction astronautics can leave you with puzzling, convoluted, hard-to-maintain code full of leaky unintuitive abstractions. This problem is not unique to Lisp macros; languages like C++ and even Java are known to be widely used by perpetrators of the above-mentioned atrocities.
What makes code easier to maintain is clear separation of concerns and low impedance between code's abstractions and the subject area. This is, again, attainable in a number of languages (though expressive power and minimalism help make it even nicer), given the right mindset and skills. I suppose John Carmack possesses both.
I'm beginning to use a phrase that I'd rather deal with poorly written code than well planned architecture. Obviously by well planned architecture I'm referring to overly architected solutions.
You know, the ideal device is that which is not even there, but its function gets executed. This ideal is rarely attainable, but it's something to crave for.
On a side note... Uncle Bob is my hero.
The only problem I'm having with this tack is that it reveals all the technical debt at once, which produces an enormous amount of pain early on. My friends smirked at my woes today of trying to make a clickable button, which has to piece together stuff from the graphics layer, input events, text fields, and internal button state. An enormous variety of data, altogether, with the debt usually hidden from view at some level. It all makes sense, it's all decoupled, the lifetime of the state is automatically managed, any configuration you want will just be a matter of making the data for it. But making that first button is quite a headache.
http://www.erictimmons.com/node/18
I don't know if it qualifies for serious, I'd say challenging enough, but it was great to revisit with another university material.
Code may also be boring simply because it is unsurprising for someone familiar with the subject matter.
When you have a lot of wordy, boring code to maintain, you have to make coordinated changes in more similarly boring places. A human's brain can only keep that many lines of context. So it becomes easier to make a mistake.
A problem nicely summarized by Yaron Minsky (of Jane Street): "You can’t pay people enough to carefully debug boring boilerplate code. I’ve tried."
It's surprising that a philosophy that tries to promote simplicity also manages to come across as so elitist at the same time.
By the way, FOR loops invite off-by-one errors and worse. Use a combinator like map, or filter or foldr etc, to keep things boring.
map { $_ + 1 } (@list); sub sum_of_squared_pairs {
reduce { $a + $b } map { $_ * $_ } grep { $_ % 2 == 0 } @_
}
sub schwartzian_transform {
map { $_->[0] }
sort { $a->[1] <=> $b->[1] } # use numeric comparison
map { [$_, length $_] } # calculate the length of the string
@_
}http://docs.racket-lang.org/reference/for.html
eg. fizzbuzz using for, match:
-> (for ([i (range 1 16)])
(match (list (modulo i 3) (modulo i 5))
[(list 0 0) (displayln "fizzbuzz")]
[(list 0 _) (displayln "fizz")]
[(list _ 0) (displayln "buzz")]
[_ (displayln i)]))
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzzhttp://docs.racket-lang.org/reference/sequences.html?q=in-ra...
An in-range application can provide better performance for number iteration when it appears directly in a for clause.
-> (for ([i (in-range 1 16)])
(match (list (modulo i 3) (modulo i 5))
[(list 0 0) (displayln "fizzbuzz")]
[(list 0 _) (displayln "fizz")]
[(list _ 0) (displayln "buzz")]
[_ (displayln i)]))I do not think Perl is a pretty language, but I have come to appreciate how useful it is. If all you want is a smallish application (roughly, less than 1 KLOC), especially if you're only going to use it once or maybe a handful of times, no other language I have met can keep up.
And for the kind of problem I typically use Perl for - reading, say, a CSV file or an Excel spreadsheet, filtering the data according to some criterion, fetching and adding data from an external source, say, an LDAP directory or a relational database, then inserting the result into a database or emitting another CSV file - it is also surprisingly hard to beat Perl's runtime performance, especially its regex engine. I'm not saying it can't be done, but for a program you're essentially throwing away after a week or so, it's usually not worth the hassle.
I don't think that's been true for a while. Boost went a long way towards making C++ much more productive, and now that's gone even further with C++11 and 14.
Things are improving in C++-land, but I'd still place it near last.
I can only assume you have not seen 300+ deep stack traces in lasagna java programs. Or GWT.