Log in

entries friends calendar profile Elf Sternberg's Pendorwright Projects Previous Previous
Elf M. Sternberg

“If you can’t explain it simply, you don’t understand it well enough.” – Albert Einstein

This quote annoys me. I’ve spent the last year trying to understand functional programming and this deep, mathematical concept called the monad. It turns out that monads are simple to explain: if you’re mathematically inclined and know your category theory, they’re a monoid in the category of endofunctors. If you’re a programmer, they’re a pattern for the augmentation of function composition.

Since I’m a programmer, the latter explanation appeals to me. (I’m also a mathematician, and I know what all the words mean in the theoretical explanation, but I don’t understand them well enough to use them effectively.) For your basic Python, Ruby, or Javascript developer (nevermind, shudder, PHP), you have to start with explain what function composition is, how you already do it without having a word or even a concept for it, why you want to do it more, how you work around problems involving collections and sequences, and then you have to explain what you mean by “augmentation,” and what it buys you, and how it fits into your existing mental framework of designing and writing software. I’ve been working my way through a series of exercises that have helped me understand what “augmented function composition” is and does for me.

But it took work. It took a lot of work. Even with twenty years of software engineering experience, it took hours of hammering away at the problem, day in and day out, for me to even start to see the benefits of using this pattern. I’ve now got a fairly solid understanding; I’m hoping to apply it to some personal projects in the hopes of reducing my error rate and speeding up delivery.

Lots of people have tried to “simply” explain monads to me. But to understand them, I had to put in the effort. I had to put in the hours. I had to do the work. Sometimes, no matter how well you understand “it”, no matter how simply you explain “it”, your audience simply doesn’t have the knowledge, the mental framework, necessary to understand what you’re talking about.

And some people, no matter how hard they try, will never have that framework. They don’t have a mind capable of grasping it. We would never ask Sarah Palin to try and understand multi-dimensional vector maths; she hasn’t got the mind or temperance for it. It’s not even that she won’t, it’s that she can’t. By nature or nurture, she hasn’t got the headaround for it, and never will.

It’s not about understanding or simplicity; it’s about your audience’s capability and willingness to comprehend.

Leave a comment

Yep, I’ve definitely gone down the wrong path with my current research project, which means I’ve probably wasted at least a day or two on it, which I find deeply frustrating.

As I’ve been working my way through Lisp In Small Pieces, I’ve been trying to push the boundaries of what the interpreter does in order to make it seem more, well, “modern” to me. The target language is Javascript, both in the interpreter and in the transpiler; I ultimately want to end up with something similar to Gazelle or Pixie, but with even more facility. The laundry list is very long.

The problem I have right now is Sourcemaps. Sourcemaps are a tool supported by all major browsers and Node/Iojs, that translate error conditions that occur in the running code into near-equivalent locations in the original source files. This was meant to support minimizing features like uglify or Google Closure, but it turns out to work just fine for transpilers.

The problem is three-fold: (1) the original Lisp syntax doesn’t support the carriage of metadata along with processing the the source, (2) Lisp macros mangle the source in unhealthy ways, (3) including the metadata necessary to support Sourcemaps makes the reader unsuitable to use as a general-purpose list-processing (i.e. “LISP”) utility for users.

I thought I had a solution using Javascript’s non-primitives for String and Number; that would have let me carry the values forward successfully. Unfortunately, the Javascript non-primitives are not automatically self-evaluating; (new String("foo")) != (new String("foo")), so comparisons and utility at run-time are severely impacted. Expectations are not being met. I know why this is the case, I’m just not happy with it.

An alternative is to encode the reader to pass back the sourcemap as a second AST, and have the reader traverse that as needed to report on state of the compilation.

The problem is that this is a cross-cutting concern, an aspect-oriented problem. Tracking which branch of the AST you just went down, or how far along the linked list that represents that branch, is not easily instrumented in Javascript. I want the evaluate core to operate as McCarthy described in 1959, but if run in a different context (oh, look, a monad!) also returns me optional sourcemap details about the evaluation pass.

I’m going to spend some of today reading through other folks’ solutions. The non-Lispy javascripts are no help; they have their own paradigms for ASTs that don’t involve the self-modifying capacities of Lisp.

Leave a comment

In a recent, great article in the New York Review of Books, “The Key to Rereading,” Tim Parks takes the usual metaphor of reading as “the mind is a key unlocking the meaning of the text” and turns it around:

The mind is not devising a key to decipher the text, it is disposing itself in such a way as to allow the text to become a key that unlocks sensation and “meaning” in the mind.

Parks also asserts that this unlocking process isn’t achieved upon a first read, but upon re-reading. Once, again, and again, and again.

The astonishing thing to me at least is that anyone actually needed to say this. Every person who lives in the world of mathematics (and computer science is a branch of mathematics, although if homotopy theory is correct every branch of mathematics is in fact a subset of computer science theory) knows this beyond any shadow of a doubt. I hinted at this earlier is my article “A-hah! Learning and Grind Learning,” after which someone said to me that the “A-hah!” moment only comes after the grind, that you’ve spent all the intellectual energy necessary to push the neurons into the right pattern, after you’ve felt those neurons reaching out to each other, after the whole of the pattern coheres after hours and hours of study and research and experimentation, there’s this sudden “Oh! That’s how it works!” moment.

Reading papers, writing code that does what those papers describe, tracing the meaning of that code as it does what it does, all leads to that moment when the key turns in the lock. When you get it. I liken it more to knowledge beating down the doors inside my head, relentlessly creating meaning where once there was none. That’s a slightly more violent metaphor than Parks’s, but it comes down to the same thing. The knowledge isn’t really in either the book or in your head. It’s when you’ve done the same exercise twice and in different ways that the noise of syntax and source code fades into the background, and the glittering beauty of the lambda calculi, or the sheer messiness of ad-hoc continuations like try/catch/finally, become utterly clear.

Leave a comment

The other day, Jim Bird wrote a pretty good article on why there’s so much bad software out that, and the article laid the blame on bad managers. While I think Bird’s approach is correct, he’s actually missing one critical detail.

It’s not always that managers are “bad.” Bird’s list of badness include poor planning, failure to test at each level of development, failure to talk to customers or put prototypes and minimum viable products in front of them, failing to follow best practices, and ignoring warning signs.

Bird concludes with: “As a Program Manager or Product Owner or a Business Owner you don’t need to be an expert in software engineering, but you can’t make intelligent trade-off decisions without understanding the fundamentals of how the software is built, and how software should be built.” Which is completely contradictory advice, because I think you do need to be, or hire, someone who can deep dive into the engineering production pipeline.

The practice of the “five whys” says that asking “Why did this happen?” through five layers of reasoning will bring you to the actual root cause of the problem. There’s an old joke that states that the fifth why is always some variant of, “Because we were lazy.” The Wikipedia article linked to actually ends with an example of that!

But I think laziness is the second most common problem in software management. The most common problem is fear.

This is most obvious in the high-tech corridors of San Francisco and Seattle, but it’s true everywhere. We’ve created a perverse incentive structure where the best way to move up is to move on: the quickest way to get a raise in this business is to leave your job and move on to a different job. Poaching is widespread and pernicious.

On the other hand, managers are terrified of losing people. Hiring well is hard,and losing an employee means losing whatever institutional memory they had built up before they left. Along with the pressure of producing software, they have to know that their developers could flee at any moment. So managers are willing to let some things slide if it means they’re able to hand onto their “10X” developers: they’ll ignore standards and allow redundant, dead, unrefactored, cut-and-paste, poorly abstracted, globally defined, untyped (or worse, “Any” typed), uncontracted, YAGNI, lacking test coverage code. Managers who have been out of the coding loop too long or who are unsure of their position lack the backbone necessary to tell developers, “Make it better.” It’s not enough if the code “passes quality assurance” if QA doesn’t know the ranges each level of abstraction is expected to honor.

But this is the kind of code 10X programmers develop. It’s mostly junk: it’s held together with baling wire and its interactions exist only as a terrible map hidden away in the developer’s brain. It only becomes useful after 10 other developers have cleaned up all its rough edges and applied its cruft to more enviroments than the 10X guy’s laptop.

But because that code does what the spec says it should do, provided the “just right” environment and the “just right” amount of babysitting, upper management thinks he’s a genius and his line managers are terrified that he might leave. Everyone seems to think the 10 people actually making his code saleable are overhead.

It’s not enough if the code “sells well” in its first few months if future maintainers can’t read what’s later presented to them– especially after the original developer has left company. It’s not enough to have a VCS (Version Control System) if the manager doesn’t have or won’t enforce standards of communication and etiquette in commit messages, code review requests, or code review responses.

The problem is ubiquitous, and it’s exacerbated by the external realities of the peripheral price spirals caused by this environment: the insane housing prices in SF and Seattle create an awareness in the developers that the grass may be greener elsewhere, that affording that next residence or next toy is just a job hop away.

There is no job loyalty, sadly. The closest companies can do is offer stock options, in a golden handcuffs pattern that keeps only the most dedicated, or most desperate, or least ambitious. And keep re-offering them to valuable employees. (True story: my tenure at Isilon ended in 2008 with the mass layoffs of the recession and Isilon’s buyout by EMC. In March 2009 my Palm Pilot, which had been silently sitting in its cradle for years, beeped suddenly. Curious, I read the message: Your last options award from Isilon has matured. Submit your resignation. A little late, but I had cashed everything I could already.)

But if companies want to stop spinning their wheels, they need to get things right the first time. Yes, that means slow down. Yes, that means, plan ahead. But most important of all, have a spine. A culture of excellent requires a culture of courage.

Leave a comment

I’ve been working my way through a Lisp textbook, Lisp In Small Pieces, by Christian Quinnec. It was originally written in French and is not that well known among English-speaking Lisperati, not in comparison to the Wizard book or Paul Graham’s On Lisp, but what caught my attention was how it really was in small pieces. Each chapter ended with an interpreter described, sometimes in code, sometimes in text; if you were smart enough, you could actually piece the whole thing together and see how it worked.

I decided to make things hard for myself. Since I’m not a Lisperati (although I may well and truly be seduced by Hy), I decided to make things hard for myself by writing the interpreter in Coffeescript. Most Lisp books assume you have a Lisp handy, and Quinnec’s examples are fine and dandy on many variants of Scheme, but for a fun time I decided to write it in something else. Raganwald claims Javascript “is a Lisp,” and if that’s so it ought to be good enough to write a Lisp in it.

I mean, it’s obviously been done before. I tried once before but got lost. LiSP does me the favor of keeping me on track.

You can see all my sourcecode at Github: Lisp In Small Pieces.

Chapter 1 contains the base interpreter. It also contains a hand-written Lisp reader, and refers to another project I have on GitHub, cons-lists, which is exactly what it sounds like, a singly-linked list implementation in Javascript, using nested Javascript arrays as the base. The base interpreter is very primitive– you can’t even create new variable names in the global namespace! Although you can shadow them using lambdas, so it’s pretty much bog standard Lambda Calculus.

Chapter “Lambda 1″ contains a continuation-passing variant of the interpreter from Chapter 1. It’s basically a facile reading of Lisperator’s λ-language intepreter, with my own parser front-end and some CPS style. It passes all the tests, but it’s a distraction.

Chapter 3 contains the same interpreter, only using the architecture Quinnec describes in Chapter 3 of his book.

Chapter 2 describes a number of different methodologies for binding, scoping, and namespaces. The material is interesting but I didn’t pursue writing the various interpreters. I “got” what Quinnec was saying, and if I’m ever interested in writing something with scoping rules outside of the lexical scopes with which I’m familiar, I might revisit the material.

The next step will be to add functions to the Chapter 3 interpreter to do the various continuation management games, like call/cc, throw/catch, and so forth. Because those, I feel I need to understand.

How far will I take this project?  I’m not sure.  Chapter 4 is “Assignment and Side Effects,” so I’ll do that.  Chapter 5 is theory, and 6 implementation, of a “fast interpreter” of the kind French programming language guys apparently love to study.  I’ll read them, but I’m not sure what code I’ll generate out of that.  Chapter 7, “Compilation,” is interesting in that he starts by defining a VM that on top of which our bytecode will run, and implement both the VM and the compiler in Scheme.  I think I want to do that chapter, and then re-write the compiler to create LLVM-compatible code instead, just to learn LLVM.  Chapter 8 implements EVAL, chapter 9 has Macros, and chapter 10 has Object-Oriented Lisp.  So I’ll probably do those as well.

And then… we’ll see.  I surprised myself by doing Chapter 3 in less than two weeks.

3 comments or Leave a comment

I don’t have much experience with Windows, but I have to work in it for ${EMPLOYER} now and then.  I had this weird problem today where the output of a PowerShell script was pre-formatted, but the consumer of that output (namely, a Splunk server) wanted raw numbers.  To force raw numbers on output, PowerShell provides the Format CmdLet.

Now, I really don’t like PowerShell.  It has all the syntax of Perl, all the sensibility of Smalltalk, and all the verbosity of Donald Trump.  But if the client wants it, that’s what you work with.  I did Perl for six years and Smalltalk for two, so PowerShell is rather easy for me.  It’s just knowing what’s available in the library that’s hard, like number format commands.

The Format CmdLet is an in-line operation activated with the -f command.  Its operations have the syntax {0:C}.. For example:

$money = "Total paid: {0:C}" -f $paid

All objects in PowerShell are arrays of some kind. The zero in the snippet {0:C} means “use the first (zeroeth) item”, which is almost always what you want. The “C” indicates that we’re going to use currency. Which currency symbol will be used depends upon your localization settings. The letter may be followed by a number in some cases; this translates to different things (leading zeros for integers, for example; precision for fixed-point reals).

And that’s it. The CmdLet supports the following formatting translations: “C”: Currency; “D”: Decimal; “E”: Exponential; “F”: Fixed Point; “G”: General; “N”: Number; “P”: Percentages; “R”: Round-Trip, a number that precisely matches the format of its input with special considerations for culture-specific notation; “X”: Hexadecimal.

More can be found at MSDN Standard Numeric Format Strings.

In a lot of ways, these look like Python’s old numeric formatting operations.  If you’re familiar with those, these should be straightforward.  It’s just a slightly different syntax, like everything Microsoft does.  I think it’s an attempt by Microsoft to crowd out the open source alternatives by cognitive overload.

Leave a comment
That Edsall article is the gift that keeps on giving. Here's another observation:
The differing consequences for those at the top and those at the bottom are visible in the class-based responses to a key element of individualization: changing sexual mores. After a period of turbulence and high divorce rates in the 1960s, ’70s and ’80s, the well educated are coming to terms with the sexual revolution by postponing marriage and delaying fertility as divorce rates for this class have stabilized or declined. The children of the affluent are, in turn, prospering. Conversely, the less well off – from all backgrounds — have struggled with high levels of family dissolution, father absence and worklessness, leaving their own prospects, and those of their children, bleak.
Edsall curiously keeps referring to "class" when the paper off of which his thoughts pivot very deliberately says that class is outmoded in an "individualized" society.

I could go into another rant about how this is the classic Red Sex/Blue Sex dichotomy, but there's something else in that paragraph that makes me take notice.

The unbearable whiteness of the New York Times.

Go take a look at the hand-wringing throughout the 1970s and all the way through the present about "inner city" familial turbulence, and all the finger pointing by white editorialists when accusing the black communities they supposedly served of failing their moral and familial duties. Suddenly, issues of family instability and dissolution due to economic pressures is something the NY Times wants urgently to talk about, and they do because it's happening to white people.

The risk that Frum gleefully talked about (see previous post) has now revealed its ugly downside: the demoralization and de-legitimization of the very cultural values the conservatives love to talk about. David Brooks loves to finger point this way; it's one of his signature topics. And every time he does it, the counterpunditocracy points out that Brooks is still one of the five stupidest men alive for claiming that moral training will overcome and organize any socioeconomic hardship. Brooks, Frum, Edsall-- ineed the entire NY Times opinion pool-- regards with alarm the rising chaos within white families, because suddenly the problem is on their doorstep, may affect their children. Brooks' latest is literally a "if only poor people had rich people's values, then they could be rich too." Not really, though; they'd just be less troubling to Brooks and his peers.

It's not genetic. It's not cultural. It's purely economic. And it's been caused by people who accepted aid and comfort from Frum, and Brooks, and Douthat. The poor didn't have to be victimized; they didn't have to become rabble. But the New York Times never really spoke truth to power, never really cared that much about the rabble. And now they have to live in fear of the rabble. Their rabble. Pitchforks and all.

Current Mood: grateful grateful

Leave a comment
Thomas Edsall's NY Times opinion piece, Why Don't the Poor Rise Up?, is a great thinkpiece on the way "individuation," the way we have all been atomized, step by step, into being "individuals," discouraged from recognizing our collective destiny or responsibility, has led to the psychopaths taking charge. But it has other thoughs as well, including this quote from Jacob Hacker's book

The Great Risk Shift: "Up until the 1950s, American society and government combined a faith in economic opportunity with a commitment to economic security. Today that message is starkly different: You are on your own."

Hacker and Ulrich Beck together make the claim that the successes of the modern welfare state, by assigning individual claims to its benefits as well as individual contributions to its well-being, has sown its own destruction. Pointing to individual egregious abuses, the anti-collectivist crowd has successfully clawed their way into a transnational economic structure that allows them to assign risk away.

"Risk" has always been something that the capitalists talk about. The economic opportunity of 1950s capitalism (which most people agree was pretty damned good capitalism, at least for the dominant socioeconomic group, namely white dudes) came with a safety net. But that net no longer exists. Instead, profits are socialized and risks are privatized. This creates risk asymmetry, where some groups take risks and other groups suffer the "unforseen side effects." The most trenchant example is of course the bailout of the banks, where millions of retirees suffered the "unforseen side effects" of the quasi-legal corruption of Wall Street (now completely legalized by our failure to prosecute anyone), but the most commonplace examples of corporations going bankrupt to leave behind toxic waste dumps has been ongoing for decades.

Edsall doesn't mention it, but his article stands in opposition to David Frum's infamous Dead Right (1995) in which Frum's opening sentence reads "Since it’s formation in the early 1950’s, the intellectual movement known as American conservatism has stood for two overarching principles: anticommunism abroad and radical reduction in the size, cost, and bossiness of the federal government at home." Note that Frum's agenda is pure individualization. But Frum goes on to ice the cake:
The great, overwhelming fact of a capitalist economy is risk. Everyone is at constant risk of the loss of his job, or of the destruction of his business by a competitor, or of the crash of his investment portfolio. Risk makes people circumspect. It disciplines them and teaches them self-control. Without a safety net, people won’t try to vault across the big top. Social security, student loans, and other government programs make it far less catastrophic than it used to be for middle-class people to dissolve their families. Without welfare and food stamps, poor people would cling harder to working-class respectability than they do not.
So not only is that whole, vicious "You're on your own" not unwanted, it's actually a desired feature. Capitalism isn't a glorious promise of economic opportunity, it's a mechanism for keeping the hoi polloi in their place, cowed and compliant.

Here we are, twenty years after Frum's book, and the general trend is exactly as Frum (and David Brooks, and Ross Douthat, and the New York Times) wanted it.

Current Mood: annoyed annoyed

Leave a comment
The one thing that gets me when watching all the debating going on over the "Confederate Flag" (which is really the jack flag of the CSA Navy; the Battle Flag of Virginia was square) is that people keep using terms like "hate" and "ignorance" to describe the people who fly the flag.

Sorry, I lived in the south for the first twenty-five years of my life and Southerners are neither hateful nor ignorant.

Instead, they view themselves as the rightful masters of the universe, held down by vicious circumstance. They believe in their hearts that there is a power law to the universe, that some men do rise to the top, and that the natural way to determine this is by skin color. It's neither hate nor ignorance, but it is a love of power, and a deathly fear that those they have abused for so long will rise up. Their greatest fear is that they will lose power: that they'll no longer have anyone to piss on, and the rain on their heads won't be water.

Current Mood: awake awake
Current Music: Behind the Line, Screw Jay

1 comment or Leave a comment
I've often wondered if C.S. Lewis didn't read just a bit too much Buddhist literature in his time. The Great Divorce is one of those books that reads like a Buddhist tract. It starts with a premise of universalism, if not a reincarnate one: We all awaken in the Hell we deserve, and there we are given one (or more) chances to make it into Heaven. The unnamed narrator accompanies a party on an expedition to the edge of Heaven, where he witnesses several people make (and fail) the attempt to acheive a Christian notion of Grace.

But every example is one of those things that makes a Buddhist smile. In every example, the person failing to reach grace does so because of his or her attachment to something. More to the point, that attachment causes great suffering! Lewis manages to circle back to a Christian viewpoint with his emphasis that every attachment is associated with another person in each seeker's narrative: it is not that we are attached to things, but that we are attached to (and suffer by) our refusal to see other individuals as people rather than things. (Which, in the current discourse, immediately brings to mind Mad Max: Fury Road and its underlying theme that women, indeed all human beings, are not things to be used by the powerful, but other souls worthy of respect and compassion.) Most of the seekers in The Great Divorce simply cannot forgive or reconcile their feelings with their beliefs that some other agent has the responsibility to "see it his (or her) way."

Tags: ,
Current Mood: thoughtful thoughtful
Current Music: Aftermath #3, Aes Dana

Leave a comment