|
0 |
Production Programming Languages
|
|
1 |
================================
|
|
2 |
|
|
3 |
This is a collection of mini-screeds on commonly-used programming
|
|
4 |
languages, written between (let's say) 2007 and (let's say) 2013,
|
|
5 |
with varying levels of snark and high-mindedness. (Which, reading
|
|
6 |
over them again today, induce varying levels of self-cringeyness.)
|
|
7 |
|
|
8 |
They used to be strewn about my website. I decided to collect them
|
|
9 |
in one place.
|
|
10 |
|
|
11 |
### C++
|
|
12 |
|
|
13 |
For any software project, it's important that you choose the right
|
|
14 |
language to develop it in. That's why you'll always choose C++, no
|
|
15 |
matter what the project is!
|
|
16 |
|
|
17 |
Why will you choose C++? Because it's popular, so a lot of programmers
|
|
18 |
know it. And a lot of programmers means a lot of competition, and that
|
|
19 |
means you'll be able to hire programmers at the lowest rate! This will
|
|
20 |
surely offset whatever costs might be incurred from choosing an
|
|
21 |
ill-suited programming language and hiring programmers who work at the
|
|
22 |
lowest rate.
|
|
23 |
|
|
24 |
And why *is* C++ such a popular programming language?
|
|
25 |
|
|
26 |
Is it because it's a good programming language? Hardly. That's like
|
|
27 |
saying that coffee is a popular beverage because it's healthful.
|
|
28 |
|
|
29 |
No, C++ is popular because C++ is popular. Hey, Google is a big,
|
|
30 |
successful company, and I hear they use C++... it must be *why* they're
|
|
31 |
successful! You should use C++ too!
|
|
32 |
|
|
33 |
But that's not the only reason. C++ is popular because programmers
|
|
34 |
*like* it. I suppose the question then is, *why* do programmers like it?
|
|
35 |
|
|
36 |
Is it because C++ makes it easy to write correct, maintainable code? Is
|
|
37 |
it because C++ is easy to learn? Is it because there are things you can
|
|
38 |
do in C++ that you can't do in any other language? Is it that C++ lets
|
|
39 |
your programs run as fast as they possibly can?
|
|
40 |
|
|
41 |
Anyone who has ever used C++ can tell you the answer to all of those
|
|
42 |
questions: No. (No, not even when it comes to making your program run as
|
|
43 |
fast as it can. C++ allows so much control over the low-level workings
|
|
44 |
of the program that the compiler cannot make optimizations that it
|
|
45 |
otherwise could, if the programmer were constrained to working at a
|
|
46 |
higher level of abstraction.)
|
|
47 |
|
|
48 |
So what is it about C++ that makes programmers like it?
|
|
49 |
|
|
50 |
Well, I have a theory. While most "normal" people feel that their lives
|
|
51 |
are too complicated, too full of arbitrary rules and boring details and
|
|
52 |
essentially meaningless things to remember, there's a certain strain of
|
|
53 |
psychology that actually *thrives* on complexity like this, because such
|
|
54 |
complexity *generates gratuitous expertise*.
|
|
55 |
|
|
56 |
What I mean by this is that if a system is easy to master, then there's
|
|
57 |
no opportunity to show off your mastery of it. There's no way to display
|
|
58 |
your dominance through your command of minutiae and knowledge of trivia.
|
|
59 |
And if that's what really motivates you, then, well, you're going to
|
|
60 |
avoid that system, because it doesn't provide you anything to work with
|
|
61 |
in the social game you want to play. Instead, you'll look for something
|
|
62 |
with a lot of nooks and crannies and bells and whistles and jargon and
|
|
63 |
buzzwords that you can familiarize yourself with, and you'll take every
|
|
64 |
opportunity to demonstrate that you are More Familiar with It than Thou.
|
|
65 |
You'll look for something like... well, like C++.
|
|
66 |
|
|
67 |
And if it so happens that programmers with this general personality type
|
|
68 |
*also* like the idea of *total control over their program* — and while
|
|
69 |
I'm no expert on psychology, somehow that seems likely — C++'ll have'em
|
|
70 |
downright hooked.
|
|
71 |
|
|
72 |
### CSS
|
|
73 |
|
|
74 |
If I, as a programmer, were to tell you that CSS is the ultimate hacking
|
|
75 |
language, would you be surprised? After all, it's not even a
|
|
76 |
programming language, really. But that doesn't really
|
|
77 |
matter, does it? It meets the only possible criterion there could be for
|
|
78 |
the ultimate hacking language: in order to achieve the effect that what
|
|
79 |
you want, you have to hack and hack and hack...
|
|
80 |
|
|
81 |
So, I have a question. If CSS is so superior to [those awful tables
|
|
82 |
which should never ever be used for
|
|
83 |
layout](http://phrogz.net/CSS/HowToDevelopWithCSS.html#tables), how come
|
|
84 |
a simple and much desired three-column layout, so trivial to construct
|
|
85 |
with a table, is considered [one of the holy grails of
|
|
86 |
CSS](http://www.alistapart.com/articles/holygrail)?
|
|
87 |
|
|
88 |
Seems that the real solution to this would be to have some set of
|
|
89 |
elements that has the layout behaviour of tables but without the "treat
|
|
90 |
this as tabular data, would you please" semantics. I suppose that's what
|
|
91 |
`display: table-cell` *et al* is for — if only more browsers supported
|
|
92 |
it.
|
|
93 |
|
|
94 |
I kvetch, but there *is* one very nice thing about CSS: unlike
|
|
95 |
[Javascript](#javascript), it's declarative, and not actually
|
|
96 |
as powerful as a Turing machine. So, it might make
|
|
97 |
your page look ugly in nine out of ten browsers six out of seven days of
|
|
98 |
the week, but at least it probably won't hang, or crash, or corrupt the
|
|
99 |
browser's state.
|
|
100 |
|
|
101 |
### Haskell
|
|
102 |
|
|
103 |
In theory, Haskell is the perfect language for writing reference
|
|
104 |
implementations of programming languages. It, itself, has semantics
|
|
105 |
which are specified reasonably formally. It's purely functional
|
|
106 |
(does not permit side-effects), and these two things bring it much
|
|
107 |
closer to being like mathematics than other languages.
|
|
108 |
Additionally, Haskell programs are lazily evaluated (expressions
|
|
109 |
are only evaluated if they are needed), so, basically, Haskell is
|
|
110 |
denotational semantics. Except it's also a program, so you can
|
|
111 |
run it. It's executable denotational semantics.
|
|
112 |
|
|
113 |
Pretty sweet, right? Well... yes, except for the small fact that
|
|
114 |
denotational semantics may not be the best way to describe your language
|
|
115 |
in the first place. You might have to describe I/O and concurrency,
|
|
116 |
for example, and denotational semantics doesn't make that easy.
|
|
117 |
|
|
118 |
But I hear you say, well, Haskell has I/O and concurrency features.
|
|
119 |
|
|
120 |
OK, look. It's a pretty profound thing to show that you can encode I/O
|
|
121 |
or concurrency or really, any feature of an imperative language that you
|
|
122 |
want, into a lazy functional language using monads, *but*, that doesn't
|
|
123 |
necessarily mean that it's always a beautiful thing to actually *do* so.
|
|
124 |
|
|
125 |
Yes you can do it, but no, it's not one of Haskell's strengths. I've
|
|
126 |
accepted that.
|
|
127 |
|
|
128 |
Using Haskell for other purposes, though? Well, I've already accepted
|
|
129 |
that, when going outside the "batch processing" world, Haskell is a little
|
|
130 |
out of its element, so I would not jump at the opportunity.
|
|
131 |
Armchair category theorists might enjoy writing a multithreaded
|
|
132 |
webserver with shared transactional memory monads or whatever, but I
|
|
133 |
have trouble imagining anyone except a category theorist enjoying
|
|
134 |
maintaining such a beast, so I wouldn't recommend it for most
|
|
135 |
"operational" projects. Choose carefully.
|
|
136 |
|
|
137 |
Maybe functional reactive programming, or other techniques, will
|
|
138 |
change this. Or maybe Haskell will simply continue to be the academic
|
|
139 |
playground for type theory research. Or maybe both.
|
|
140 |
|
|
141 |
### Java
|
|
142 |
|
|
143 |
No comment.
|
|
144 |
|
|
145 |
### Javascript
|
|
146 |
|
|
147 |
Javascript, now there's a programming language rags-to-riches story.
|
|
148 |
Well, it still wears rags, but you know what I mean.
|
|
149 |
|
|
150 |
In the beginning, the World Wide Web was just a bunch of interlinked
|
|
151 |
static documents, which was just fine. Hypertext, they called it. Then
|
|
152 |
immediately it grew fill-out forms and queries which were sent to web
|
|
153 |
servers, which could respond with dynamically-generated content, like
|
|
154 |
the results of a web search, which was great.
|
|
155 |
|
|
156 |
And then along the way, the Web succumbed to the inviolable law of
|
|
157 |
software engineering that states "Any sufficiently complex
|
|
158 |
program contains a buggy, half-implemented, undocumented
|
|
159 |
version of [Lisp](#lisp)". If you've ever been on the receiving side of
|
|
160 |
requirements, you might also know this as, "Can we add a scripting
|
|
161 |
language? That'd be awesome." (Because taking a nice, predictable
|
|
162 |
system and making it Turing-complete is [always awesome](http://esolangs.org/).)
|
|
163 |
|
|
164 |
So, even though web pages at the time hardly justified being scripted,
|
|
165 |
Javascript was born. And, to be fair, it's really not such a bad language
|
|
166 |
for having been designed in two weeks. Of course, the name was pure
|
|
167 |
marketing; it shares almost nothing with [Java](#java) except curly braces.
|
|
168 |
|
|
169 |
And so the Web went through a painful period where Javascript
|
|
170 |
was used to make sites that tried to stand out from the crowd by
|
|
171 |
annoying the user in more advanced and petulant and irritating ways.
|
|
172 |
And during Javascript's childhood, every vendor implemented it
|
|
173 |
slightly differently, with different bugs and different reckonings of
|
|
174 |
the DOM (the API that refers to the parts of a web page).
|
|
175 |
|
|
176 |
And then, Ajax happened, which meant, in essence, that, you
|
|
177 |
could now use Javascript and XML to reload part of a page without
|
|
178 |
reloading the whole thing. Which meant, in essence, that web pages
|
|
179 |
started to look a lot more like traditional user interfaces. Which meant,
|
|
180 |
in essence, that there was actually a (somewhat) justifiable reason for
|
|
181 |
using Javascript.
|
|
182 |
|
|
183 |
And then a standard was written for Javascript (sort of) and jQuery
|
|
184 |
was developed (which handled some of the discrepancies between
|
|
185 |
browsers for you) and JSON took over from XML (but we
|
|
186 |
still call it Ajax, not Ajaj) and vendors' Javascript implementations
|
|
187 |
started to do JIT compiling and got reasonably performant and some
|
|
188 |
clever wag coined the term "web app" and *at that very moment* it
|
|
189 |
became an acceptable fact of life for a web page to hang or crash.
|
|
190 |
(Because it's now an "app", you see.)
|
|
191 |
|
|
192 |
And then it got even weirder. Developers decided they wanted to
|
|
193 |
run Javascript *outside* of the browser. Which, for the purposes of
|
|
194 |
automated testing of the scripts used on web pages, makes some sense.
|
|
195 |
But *then* some exceedingly clever people decided
|
|
196 |
it should [run on servers](http://nodejs.org/) and that
|
|
197 |
new, back-end software should be developed in it. And the next
|
|
198 |
thing you know, it has an
|
|
199 |
[ncurses binding](https://github.com/mscdex/node-ncurses). I give up.
|
|
200 |
|
|
201 |
### Lisp
|
|
202 |
|
|
203 |
I'm one of those people who wonders why anyone bothers programming in,
|
|
204 |
talking about, or thinking about Lisp anymore, since [Scheme](#scheme) exists.
|
|
205 |
That's just me, though.
|
|
206 |
|
|
207 |
### Perl
|
|
208 |
|
|
209 |
Perl is what happens when you play [Katamari Damacy](https://en.wikipedia.org/wiki/Katamari_Damacy)
|
|
210 |
with the Unix toolchain.
|
|
211 |
|
|
212 |
Ah, but the world should thank Perl for being the experiment that
|
|
213 |
demonstrated the effect of [designing a programming language around
|
|
214 |
natural-language principles](http://www.wall.org/~larry/natural.html)
|
|
215 |
(because for some reason, we learned so little from COBOL.) And of
|
|
216 |
course we should thank the experimenters for being so candid and
|
|
217 |
unbiased about their results. Finally, we have data that shows us what
|
|
218 |
we already knew, namely that [programming, no, "scripting" is really a
|
|
219 |
fuzzy endeavour](http://www.perl.com/pub/a/2007/12/06/soto-11.html) —
|
|
220 |
much like talking, or thinking. This is why Perl scripts, and by
|
|
221 |
extension all computer programs, have so few bugs.
|
|
222 |
|
|
223 |
But if you can psychologically overcome all of that — perhaps with the
|
|
224 |
aid of some sort of nuclear-powered ninja weaponry — Perl's not *that*
|
|
225 |
bad. Unlike [C++](#c), it has garbage collection. It has
|
|
226 |
anonymous function closures (unlike [PHP](#php),)
|
|
227 |
and they can consist of more than one expression (unlike [Python](#python).) And
|
|
228 |
things like `use strict` at least smell like an attempt to approach some
|
|
229 |
sort of trying to permit, I don't know, enforcing discipline, or
|
|
230 |
something, if you think that would help.
|
|
231 |
|
|
232 |
### PHP
|
|
233 |
|
|
234 |
PHP is language defined by a tool built by some guys who saw a
|
|
235 |
[Perl](#perl) interpreter once and thought it was really neat. They
|
|
236 |
thought that it would just *rock* to make a similar tool that lived in a
|
|
237 |
webserver and whose default operation was `print`.
|
|
238 |
|
|
239 |
> "One of the most interesting aspects [of PHP version 2] included the
|
|
240 |
> way `while` loops were implemented. The hand-crafted lexical scanner
|
|
241 |
> would go through the script and when it hit the `while` keyword it
|
|
242 |
> would remember its position in the file. At the end of the loop, the
|
|
243 |
> file pointer sought back to the saved position, and the whole loop was
|
|
244 |
> reread and re-executed."
|
|
245 |
>
|
|
246 |
> — [PHP 5 Power
|
|
247 |
> Programming](http://ptgmedia.pearsoncmg.com/images/013147149X/downloads/013147149X_book.pdf)
|
|
248 |
> by Andi Gutmans, Stig Sæther Bakken, and Derick Rethans
|
|
249 |
|
|
250 |
'Nuff said, I guess.
|
|
251 |
|
|
252 |
No, no — you can *never* say enough about PHP!
|
|
253 |
|
|
254 |
I would have to say the single greatest software engineering
|
|
255 |
achievement of PHP is how it taught us all that
|
|
256 |
programming should never be done without having constantly within arm's
|
|
257 |
reach a book with a photo of the author's face on it. Preferably on the
|
|
258 |
cover, and preferably amidst the [photos of his or her 8
|
|
259 |
co-authors](https://www.amazon.com/dp/0470055200/). Even more preferably
|
|
260 |
described as a ["Cookbook"](https://www.amazon.com/dp/0672323257/), or a
|
|
261 |
collection of ["Hacks"](https://www.amazon.com/dp/0596101392/) — hey, if
|
|
262 |
it didn't save me from having to understand what I'm doing, I wouldn't
|
|
263 |
have spent the \$30 on it.
|
|
264 |
|
|
265 |
However, this is not to diminish the other great advance that PHP has
|
|
266 |
brought us. Truly, the shortest path from point A to point B is to slap
|
|
267 |
some B-coloured paint onto point A and put up a sign next to it saying
|
|
268 |
"Welcome to Point B, Population: You!" And does not PHP help us achieve
|
|
269 |
such a software development style — so *effective*, so *powerful*, so
|
|
270 |
downright worthy of this maxim?
|
|
271 |
|
|
272 |
**Fatal error**: require\_once() [[function.require](function.require)]:
|
|
273 |
Failed opening required 'config.php'
|
|
274 |
(include\_path='.:/usr/local/share/pear') in
|
|
275 |
**/internal/directory/structure/home/website/include/oh\_drat.php** on
|
|
276 |
line **444**
|
|
277 |
|
|
278 |
### Python
|
|
279 |
|
|
280 |
Mostly harmless.
|
|
281 |
|
|
282 |
Hah, I say that and it makes it sound like I *like* Python. That can't
|
|
283 |
be right. All languages are crap. I'm a language designer — why else
|
|
284 |
would I be a language designer if it were not for the fact that all
|
|
285 |
languages are crap?
|
|
286 |
|
|
287 |
But I am weary. I urge you to consider that Python may be pretty on
|
|
288 |
the surface, but go on, scratch that surface. See what you find. Tell
|
|
289 |
me if it's pretty. Go on, do it.
|
|
290 |
|
|
291 |
Here, I'll get you started.
|
|
292 |
|
|
293 |
>>> a = 200
|
|
294 |
>>> b = 200
|
|
295 |
>>> c = 300
|
|
296 |
>>> d = 300
|
|
297 |
>>> a is b
|
|
298 |
True
|
|
299 |
>>> c is d
|
|
300 |
False
|
|
301 |
>>> 300 is 300
|
|
302 |
True
|
|
303 |
|
|
304 |
But wait, there's more!
|
|
305 |
|
|
306 |
>>> True = 4
|
|
307 |
>>> True
|
|
308 |
4
|
|
309 |
>>> 4 == True
|
|
310 |
True
|
|
311 |
|
|
312 |
### R
|
|
313 |
|
|
314 |
[R IS THE LANGUAGE OF THE FUTURE](http://www.inside-r.org/blogs/2011/03/31/revolutions-chief-scientist-r-language-future).
|
|
315 |
|
|
316 |
WHY, IT'S SO FUTURE, IT EVEN HAS AN ISBN: 3-900051-07-0
|
|
317 |
|
|
318 |
No seriously, to cite R in a research paper you're supposed to type `citation()` within R,
|
|
319 |
and [that ISBN is what it responds with](https://www.software.ac.uk/blog/2016-09-30-oh-research-software-how-shalt-i-cite-thee).
|
|
320 |
|
|
321 |
### Scheme
|
|
322 |
|
|
323 |
Scheme is often looked at historically, and described as a variant of
|
|
324 |
[Lisp](#lisp). While useful, this historical viewpoint frequently gets in the way
|
|
325 |
of thinking about Scheme's significance *today*. In brief, if you are
|
|
326 |
evaluating Scheme for your own needs, evaluate *Scheme*, and don't worry
|
|
327 |
about Lisp or functional programming.
|
|
328 |
|
|
329 |
That said, let's go ahead and examine Scheme historically. Its history
|
|
330 |
has been one of shedding baggage from its Lisp heritage: it has lexical
|
|
331 |
(instead of dynamic) scoping, guaranteed (rather than
|
|
332 |
if-your-vendor-supports-it) tail-recursive behaviour at execution time,
|
|
333 |
hygenic (instead of textual) macros, and continuations as first-class
|
|
334 |
objects. These are generally considered significant improvements, and we
|
|
335 |
fully agree.
|
|
336 |
|
|
337 |
But there's one thing of Lisp's that Scheme hasn't shed: its syntax...
|
|
338 |
or lack thereof!
|
|
339 |
|
|
340 |
Whether you love it or hate it, you have to admit that Scheme's
|
|
341 |
S-expression syntax is extremely — no, *pathologically* — regular. Just
|
|
342 |
about as orthogonal as syntax can get.
|
|
343 |
|
|
344 |
As far as we know, the reason Lisp has such a mind-bogglingly minimal
|
|
345 |
syntax is that it's a consequence of how it approached higher-order
|
|
346 |
functions: *represent functions as lists*. You can already pass lists to
|
|
347 |
and return lists from functions, so if functions "are" lists, then
|
|
348 |
problem solved, right? And there's no sense having two different
|
|
349 |
syntaxes for the same kind of data.
|
|
350 |
|
|
351 |
But that didn't turn out too happily, and times have changed. In Scheme,
|
|
352 |
function values are *not* lists: they're closures. This
|
|
353 |
is overall a nice thing — it avoids the ugliness of trying to determine
|
|
354 |
which list is the "right" representation, and allows free variables to
|
|
355 |
be captured in function values instead using the crutch of dynamic
|
|
356 |
binding.
|
|
357 |
|
|
358 |
But that syntax is still there, like some kind of vestigial organ. What
|
|
359 |
purpose does it serve now?
|
|
360 |
|
|
361 |
Well, the interesting thing about it is that it makes it impossible to
|
|
362 |
syntactically distinguish between code and data. Depending on the
|
|
363 |
circumstance, this can be a horror or a delight.
|
|
364 |
|
|
365 |
Here's the horror: say you're looking at a snippet of a Scheme program.
|
|
366 |
You can't tell what `(+ 1 2)` is supposed to be — code, or data? —
|
|
367 |
without looking at what context it's in. This can be as confusing as all
|
|
368 |
git-out. (And don't get me started on `quasiquote`.)
|
|
369 |
|
|
370 |
Here's the delight: it makes it trivial to read and write Scheme
|
|
371 |
programs from other Scheme programs. No parsing, no backpatching. No
|
|
372 |
blood, sweat, *or* tears. In fact, we wonder why this holdover from Lisp
|
|
373 |
has not driven Scheme on to become *the* program-analysis language.
|