Others have written on the virtues of what we might call 'expressive terseness' in a language, which stems from the ability to do a lot with just a few operations. But another form of terseness whose virtues are more subtle is what we might call 'epigrammatic terseness' -- the ideal of having short, intelligible functions that only do one thing and do it perfectly. These two tend to go together insofar as expressive terseness facilitates epigrammatic terseness, but they're distinct insofar as you can fail to write epigrammatically in an expressively terse language (though you'd have to be stupid to do so) and can write epigrammatically in a non-terse language (though you'd have to be clever to do so).
'Functional style' tends to be epigrammatic by default, because only the value of the last expression in the function is ever returned -- so there's no point in cramming more than one expression into a function. This is one reason why it's nice to adhere to functional style even if you're writing in a language, like Common Lisp, that affords you all kinds of opportunities to violate that style with side-effects. Ideally, I try to segregate my programs into clean functional wings where all is carved in shiny marble, and dirty side-effect wings that are nailed together with planks of wood -- these wings adjoining each other but never overlapping. Admittedly it's a purely aesthetic preference: I just hate having to look at an ugly format expression on the same screen as a beautifully crafted lexical closure. But it helps keep my functions epigrammatic, which keeps them legible and memorable.
... and then I look at the macros, which are clearly all wood, and I think that perhaps the classical aesthetic enshrined in the marble wings is the one that's wrong. Most of the power of macros comes from their systematic violation of good functional style, and there is some deep wizardry available to anyone who's willing to do strange and unnatural things to their lexical closures. Macros at their best are all very wabi-sabi, which sits weirdly with the hygienic perfectionism of functional programming. This tension confuses me philosophically, but I appreciate the fact that CL is tolerant of both design attitudes.
Can you write good, clean code epigrams without the straightjacket of functional style? Yes, but further you depart from functional style and the more you embrace the intricacies of macros, the more the code starts to take on a queerly cryptic and holistic quality: the syntax tree of the individual expressions may be perfectly intelligible at a glance, but what semantics to assign it becomes unclear until you've figured out how all the bits splice together at runtime. Worse, deliberate ambiguities arise: the same unit of code may have a totally different interpretation when called in one context versus another. What is sacrificed is easy intelligibility; you have to feel your way into familiarity with the total codebase before it all starts to make sense. Manifest beauty gives way to what we might charitably call 'acquired taste', and code becomes profound and idiosyncratic.
I do not know if this left-hand path is good or not, but discovering that it's available at all poses a pretty firm challenge to my notions of good style. You have to be pretty smart to use it, and as someone who was attracted to Lisp because I'm a little stupid, it gives me a little frisson of numinous terror. And yet ...
functional abstraction
'. . . one should only generalize in order to individualize better.' (Don Colacho)
Wednesday, 1 April 2015
Tuesday, 13 January 2015
Bash Considered Hopeless
In 'Bash Considered Pointless', Chad Perrin considers a few obvious points about bash:
1) That if you care about maximum portability across Unix-like systems, you shouldn't use bash. (Use sh.)
2) That if you care about maximum simplicity of code, you shouldn't use bash. (Use sh. Or better yet, rc!)
3) That if you care about maximum customizability of the shell environment, you shouldn't use bash. (Use zsh. Never use fish, however.)
4) That if you care about maximum performance, you shouldn't use bash. (Use (m)ksh or (d)ash.)
And given the recent discovery that there's been a veritable termite mound just underneath the floorboards of bash all this time, we can add: if you care about security, you shouldn't use bash.
That said, what principled reason could anyone possibly have to use bash? I can't think of any, which makes it look like a classic case of arbitrary market lockin -- somebody decided that bash was the standard shell for Linux distros, and bash is not so obviously awful as to foster great discontent among any but the most picky of operators. Until now, anyway: in light of the bashdoor discovery, there have been some murmurings that Fedora might move away from bash to mksh or dash, which would hopefully be the beginning of a stampede. One can dream, anyway.
Anyway, Chad makes another, more philosophical point that I find interesting: he thinks an interactive shell should be optimized to be an interactive shell and a programming language should be optimized to be a programming language, and that bash scripting falls rather inelegantly between these two stools -- or rather, is frequently abused to do things that should be done in a proper programming language. This point made me think of two things at once.
The first thing was Erik Naggum's infamous take on Perl: 'it's not that perl programmers are idiots, it's that the language rewards idiotic behavior'. But since Perl was pretty much made to 'correct' the deficiencies of shell scripting, it strikes me that all of Naggum's criticism applies in a suitably weaker form to that domain, as well. I don't have quite the same raging hate-on for Perl, but I see his point and think that any script that gets longer that a dozen lines or so should probably be redone in a proper programming language. It may in fact be a bad idea to make the shell too powerful, in which case anything more featureful than rc is probably harmful in the long run. (Seeing people seriously suggest patching bash with Perl is a confirmation of Naggum's worldview, and would be comical if it wasn't tragic.)
The second thing it made me think of is, of course, the Lisp REPL, which I think is a good counterexample to Chad's general thesis -- in an old Symbolics Lisp machine, there was no shell because there was no distinction between the command interface and the language the OS was written in. This strikes me as nirvana for the intelligent operator. Sadly, the last remnant of this principle still in use today is ... Emacs. Which, for other arbitrary historical reasons, is not a particularly inspiring exemplar.
In any case, please, whatever you do, stop using bash. Use zsh if you like big and baroque, use mksh/dash if you like small and snappy, or use sh/rc if you're truly hardcore. Just migrate to something else. Do it today. Do it now. You might like it!
1) That if you care about maximum portability across Unix-like systems, you shouldn't use bash. (Use sh.)
2) That if you care about maximum simplicity of code, you shouldn't use bash. (Use sh. Or better yet, rc!)
3) That if you care about maximum customizability of the shell environment, you shouldn't use bash. (Use zsh. Never use fish, however.)
4) That if you care about maximum performance, you shouldn't use bash. (Use (m)ksh or (d)ash.)
And given the recent discovery that there's been a veritable termite mound just underneath the floorboards of bash all this time, we can add: if you care about security, you shouldn't use bash.
That said, what principled reason could anyone possibly have to use bash? I can't think of any, which makes it look like a classic case of arbitrary market lockin -- somebody decided that bash was the standard shell for Linux distros, and bash is not so obviously awful as to foster great discontent among any but the most picky of operators. Until now, anyway: in light of the bashdoor discovery, there have been some murmurings that Fedora might move away from bash to mksh or dash, which would hopefully be the beginning of a stampede. One can dream, anyway.
Anyway, Chad makes another, more philosophical point that I find interesting: he thinks an interactive shell should be optimized to be an interactive shell and a programming language should be optimized to be a programming language, and that bash scripting falls rather inelegantly between these two stools -- or rather, is frequently abused to do things that should be done in a proper programming language. This point made me think of two things at once.
The first thing was Erik Naggum's infamous take on Perl: 'it's not that perl programmers are idiots, it's that the language rewards idiotic behavior'. But since Perl was pretty much made to 'correct' the deficiencies of shell scripting, it strikes me that all of Naggum's criticism applies in a suitably weaker form to that domain, as well. I don't have quite the same raging hate-on for Perl, but I see his point and think that any script that gets longer that a dozen lines or so should probably be redone in a proper programming language. It may in fact be a bad idea to make the shell too powerful, in which case anything more featureful than rc is probably harmful in the long run. (Seeing people seriously suggest patching bash with Perl is a confirmation of Naggum's worldview, and would be comical if it wasn't tragic.)
The second thing it made me think of is, of course, the Lisp REPL, which I think is a good counterexample to Chad's general thesis -- in an old Symbolics Lisp machine, there was no shell because there was no distinction between the command interface and the language the OS was written in. This strikes me as nirvana for the intelligent operator. Sadly, the last remnant of this principle still in use today is ... Emacs. Which, for other arbitrary historical reasons, is not a particularly inspiring exemplar.
In any case, please, whatever you do, stop using bash. Use zsh if you like big and baroque, use mksh/dash if you like small and snappy, or use sh/rc if you're truly hardcore. Just migrate to something else. Do it today. Do it now. You might like it!
Tuesday, 16 December 2014
'It's not about you.'
Amidst a hardnosed assessment of just what an ineffective figleaf PGP is over the hairy, ugly, naked information-leak that is SMTP, I find this sharp little response to the 'I've got nothing to hide' defense:
This rationale allowed me to hit the snooze button on an intimidatingly enormous problem -- to wit, increasingly vast asymmetries in the access to information between corporations and stakeholders (a.k.a. governments and citizens). If I believe the information they have access to can't be used to harm me, I can justify ignoring it.
The most obvious weakness of this position is that you can only hold it if you're living a completely conventional existence. It presumes an improbably fortuitous harmony between individual integrity and social mores -- the conflict between which has been the subject of so much dramatic art (especially Ayn Rand's!) that to presume their alignment is to postulate the proverbial spherical cow.
It is, in fact, entirely possible for the hive mind to turn on you for arbitrary and atrocious reasons no matter how clean your conscience is, and a prudent simian is forewarned and forearmed against this possibility. A little education in the internal political history of the CCCP (or better yet, Geneva under Calvin), should be enough to inoculate you against the notion that being a good comrade is any insurance policy whatsoever against chistka. Or if that's too distant for you -- who didn't like Martha Stewart? But she makes one little prudent financial decision that just happens to violate federal finance law, and all of a sudden she's a figure of public disgrace. I have watched news of a complicated domestic dispute spread a miasma over someone's entire social life. It can happen to you -- never doubt it.
Of course there's also a less obvious weakness to this ethos, which is that even if you're quite protected the people you care about may not be. The knee-bone is connected to the thigh-bone, and when your nephew is arrested for buying an 8x11" of LSD it's not just his life that gets upset. Weren't you two quite close? Didn't you take him out on a little trip across the border just last month? Could you pop your trunk for me, sir?
Or, on a completely different tack: how comfortable are you with marketers having an ever more precise idea of how to nudge you into making purchases? Again, if you believe you cannot be gamed and suckered by somebody who knows what you like, you are precisely the person they're looking for. It can be as simple as seeing a book recommendation pop up on your F******k feed for something you were just browsing earlier on A****n, which pushes you over the edge into buying it: sheer generation of coincidence can drive fads and fashions because we unreflectively and automatically interpret them as meaningful, and it does not take a lot of effort to generate artificial coincidences when your main information sources are colluding to sell you shit. It's just con artistry 101 on a vast scale. Even if you're a 9th dan blackbelt in the arts of eluding marketing, your friends and family mostly aren't, and do you want to live in a society that's so easily manipulable? For real fun: do you think politicians won't use this stuff, too?
This nexus of influence can be expanded ever further, but you get the idea: the principle is that observation facilitates control, and systematic obfuscation can make control prohibitively expensive to exercise. If you make yourself hard to observe, you make yourself hard to control, thereby retarding the accumulation of vast imbalances of power. Julian Assange quite explicitly used the converse principle in his little bit of information warfare -- if you make secrecy costly, it gets used less, and a transparent government is easier to control.
This all has very sharp, pointy teeth to it for anyone already living in a regime where the government is actively and explicitly malevolent. But even for those of us in constitutional democracies, there is nothing but a thin tissue of legal precedent separating us from, say, Iran. That tissue may hold out in the end, but I don't want to bet anyone's life on it.
'It's not about you, it's about your civic duty not to be a member of a predictable populace. If somebody is able to know all your preferences, habits and political views, you are causing severe damage to democratic society.'Ouch! This one hit home for me. It's a strategy I've taken refuge in: my attitude toward secrecy in my early 20s owed a little too much to Ayn Rand -- namely the notion that if you act with integrity you can't be blackmailed, so the important thing was to own your actions and never do anything that could be used against you. This meshed well with the blase attitude I pretended to have about taboos -- I actually would 'do it in the road' if it wouldn't disturb anyone else, I thought, and my understanding of privacy mostly revolved around considerations of relevance and propriety. If you see me naked, I thought, then that's your problem, not mine.
This rationale allowed me to hit the snooze button on an intimidatingly enormous problem -- to wit, increasingly vast asymmetries in the access to information between corporations and stakeholders (a.k.a. governments and citizens). If I believe the information they have access to can't be used to harm me, I can justify ignoring it.
The most obvious weakness of this position is that you can only hold it if you're living a completely conventional existence. It presumes an improbably fortuitous harmony between individual integrity and social mores -- the conflict between which has been the subject of so much dramatic art (especially Ayn Rand's!) that to presume their alignment is to postulate the proverbial spherical cow.
It is, in fact, entirely possible for the hive mind to turn on you for arbitrary and atrocious reasons no matter how clean your conscience is, and a prudent simian is forewarned and forearmed against this possibility. A little education in the internal political history of the CCCP (or better yet, Geneva under Calvin), should be enough to inoculate you against the notion that being a good comrade is any insurance policy whatsoever against chistka. Or if that's too distant for you -- who didn't like Martha Stewart? But she makes one little prudent financial decision that just happens to violate federal finance law, and all of a sudden she's a figure of public disgrace. I have watched news of a complicated domestic dispute spread a miasma over someone's entire social life. It can happen to you -- never doubt it.
Of course there's also a less obvious weakness to this ethos, which is that even if you're quite protected the people you care about may not be. The knee-bone is connected to the thigh-bone, and when your nephew is arrested for buying an 8x11" of LSD it's not just his life that gets upset. Weren't you two quite close? Didn't you take him out on a little trip across the border just last month? Could you pop your trunk for me, sir?
Or, on a completely different tack: how comfortable are you with marketers having an ever more precise idea of how to nudge you into making purchases? Again, if you believe you cannot be gamed and suckered by somebody who knows what you like, you are precisely the person they're looking for. It can be as simple as seeing a book recommendation pop up on your F******k feed for something you were just browsing earlier on A****n, which pushes you over the edge into buying it: sheer generation of coincidence can drive fads and fashions because we unreflectively and automatically interpret them as meaningful, and it does not take a lot of effort to generate artificial coincidences when your main information sources are colluding to sell you shit. It's just con artistry 101 on a vast scale. Even if you're a 9th dan blackbelt in the arts of eluding marketing, your friends and family mostly aren't, and do you want to live in a society that's so easily manipulable? For real fun: do you think politicians won't use this stuff, too?
This nexus of influence can be expanded ever further, but you get the idea: the principle is that observation facilitates control, and systematic obfuscation can make control prohibitively expensive to exercise. If you make yourself hard to observe, you make yourself hard to control, thereby retarding the accumulation of vast imbalances of power. Julian Assange quite explicitly used the converse principle in his little bit of information warfare -- if you make secrecy costly, it gets used less, and a transparent government is easier to control.
This all has very sharp, pointy teeth to it for anyone already living in a regime where the government is actively and explicitly malevolent. But even for those of us in constitutional democracies, there is nothing but a thin tissue of legal precedent separating us from, say, Iran. That tissue may hold out in the end, but I don't want to bet anyone's life on it.
Friday, 28 November 2014
Ignoratio elenchi
What is it, to make a mistake? To commit to a false analogy. Most human error is a matter of tacitly importing presuppositions into a situation where they're irrelevant; most confusions are covert equivocations, where some slippage of meaning has occurred between the major and minor premises of a practical syllogism. The result is the equivalent of making a chess move in checkers: you've inadvertantly imported abstractions from one domain into another, and the result is nonsense. A well-designed interface does everything it can to prevent this; a poorly designed one encourages it.
Monday, 17 November 2014
Finding Snowden
I saw Citizenfour at the theatre recently; it's a suberbly minimalist documentary which is less art than political act. As a rule I hate political docs because most of them are hamfisted attempts to cajole you into a belief; this one is exceptional insofar as it's simply showing the true story of one guy following his concscience against terrible existential threats. The emotional resonance of that is reason enough to see it: it will, if you're a thinking, feeling human being of any sensitivity, nudge you in the direction of being a better person.
One thing the film indicated in passing rather than hammering on was that we're living in a perilous situation where the only thing keeping a monstrous apparatus of intrusive surveillance from being unleashed on us all is sheer legal tradition; all it will take is a couple of rulings that go the wrong way and set the wrong precedents and we will in fact find ourselves very rapidly in a very scary world. There are known technical fixes to help prevent this world from coming about; all that's actually lacking is enough people who appreciate their importance enough to implement them. I could hate on Apple and Google all day long, but the fact that they're actually moving in the direction of automatically encrypting everything in their OSes, in part due to the cultural influence of the Snowden leaks, is enormously to their credit.
One thing the film crystallized for me is that, while I'm used to thinking of tech from the standpoint of aesthetics and power, the ethical dimensions of it loom very large in the background and should be more often discussed. It doesn't take a lot of acuity -- just a sprinkle of cynicism -- to see that you keep people from being oppressed not by reciting pious mantras but by making them hard to oppress, and that any tech that makes it easier to oppress people is evil. The problem is that a lot of things that get foisted on us in the name of 'efficiency' also make oppression efficient by creating single points of control. They also make disruptions efficient -- oppressors here can be governments or rogues, and what makes us safe from both is an infrastructure that lacks such privileged nodes to be manipulated in the first place.
I've found it easy to be fatalist about a lot of things over the years, but the film helped awaken my inner Snowden -- realizing that it actually is possible to stop a lot of this insanity, if enough people wake the fuck up and do something intelligent about it.
Friday, 19 September 2014
Don't cross the streams
One of the rudest things any program can do is to unpredictably jam its output stream into the operator's input stream. It sounds like such a basic and obvious no-no, but it is astonishing how many pieces of software fail this basic etiquitte test. 'Stealing focus' is just the most common example, but in general anything that breaks your flow is a candidate. The machine should only alter your behavior in cases where something critical depends on it, and so the fault here is that whoever designed the program has an inaccurate sense of what's actually important to you, and when it's important.
This is one argument for radically reconfigurable computing systems, but leaving that aside I often cannot fathom what thought process somebody went through to decide that it was worth interrupting my flow for something. Or maybe they just didn't test the damned thing enough -- programmers should always have to eat their own cooking every day for a month before they even think about releasing it on an unsuspecting public.
The point is that output alters the user's behavior, and you only want to do that if the user is currently behaving inappropriately. Superfluous output is wasted cycles on both the machine and user side, and the further sin of shoving that output directly in the user's active input stream is shitting where you eat.
(Addendum: A more insidious version of this is anything that assumes you want information dumped in your face, rather than waiting for you to tell it so. This is why google.com is a nice interface while facebook.com is a rude one. Also why all phones should come with a person-by-person ring setting, i.e. I want my phone to ring when my sister calls but not when my creditors call.)
This is one argument for radically reconfigurable computing systems, but leaving that aside I often cannot fathom what thought process somebody went through to decide that it was worth interrupting my flow for something. Or maybe they just didn't test the damned thing enough -- programmers should always have to eat their own cooking every day for a month before they even think about releasing it on an unsuspecting public.
The point is that output alters the user's behavior, and you only want to do that if the user is currently behaving inappropriately. Superfluous output is wasted cycles on both the machine and user side, and the further sin of shoving that output directly in the user's active input stream is shitting where you eat.
(Addendum: A more insidious version of this is anything that assumes you want information dumped in your face, rather than waiting for you to tell it so. This is why google.com is a nice interface while facebook.com is a rude one. Also why all phones should come with a person-by-person ring setting, i.e. I want my phone to ring when my sister calls but not when my creditors call.)
Friday, 12 September 2014
Beauty and the Beast
I'm not the first to gripe about this, but one more voice in the chorus never hurts: it is an absolutely insane state of affairs that the conventional environment for something as nice and relatively ageless as Common Lisp is something as hoary and archaic as Emacs. Forcing somebody to get used to the arcane and arbitrary keybindings in Emacs before they can enjoy Lisp is like making them learn to type with their toes in order to use a laptop. It's utterly senseless, and I'm pretty sure the only reason it is this way is that once you've invested the months it takes to feel at home in Emacs, you have no incentive to create a more natural environment.
I'm currently playing around with Sublime Text with the SublimeREPL add-on, modded out to run CLISP. As an environment it's cloying in its own way -- no, ST, I don't actually want you to insert that close-paren or quote mark for me, thanks anyway you interfering smartarse -- but the fact that I don't have to get a repetitive stress injury in my pinky or remember entirely un-mnemonic commands is a major plus. Lack of a simple, standardized, intuitive environment that just works (like Racket has) makes CL substantially less 'approachable' -- Emacs-hate was precisely the reason I didn't bother diving deep into CL years ago, and if a more accessable environment had existed back then I might be a CL guru by now.
Sadly, this is indicative of the mindset of the CL community, which has a very 'eat your fucking vegetables' attitude -- not necessarily a bad thing, but certainly an impediment to widespread Lisp dominance. You can have your elitism and complain about how brain-dead the rest of the world is, or you can work to enlighten the commoners and fill the world with beautiful things -- pick one.
I'm currently playing around with Sublime Text with the SublimeREPL add-on, modded out to run CLISP. As an environment it's cloying in its own way -- no, ST, I don't actually want you to insert that close-paren or quote mark for me, thanks anyway you interfering smartarse -- but the fact that I don't have to get a repetitive stress injury in my pinky or remember entirely un-mnemonic commands is a major plus. Lack of a simple, standardized, intuitive environment that just works (like Racket has) makes CL substantially less 'approachable' -- Emacs-hate was precisely the reason I didn't bother diving deep into CL years ago, and if a more accessable environment had existed back then I might be a CL guru by now.
Sadly, this is indicative of the mindset of the CL community, which has a very 'eat your fucking vegetables' attitude -- not necessarily a bad thing, but certainly an impediment to widespread Lisp dominance. You can have your elitism and complain about how brain-dead the rest of the world is, or you can work to enlighten the commoners and fill the world with beautiful things -- pick one.
Subscribe to:
Posts (Atom)