Log in

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

I can’t remember where I found it, but there was a brilliant explanation of how functional code maps value. Remember, in a functional program, the basic notation is x → y, that is, for every function, it maps value x to another value y. Things like map() map an array to another array, while reduce() maps a single thing (an array) to another single thing (a value). How does functional programming encode other things?

Well, there’s

x → y

x is mapped to y

x → y∪E

x is mapped to y or Error (Maybe)

x → P(y)

x is mapped to all possible values of y (Random Number Generators)

x → (S -> y ⨯ S)

x is mapped to a function that takes a state and returns a value and a new state (State)

x → Σy

x is mapped to the set of all real-world consequences (IO)

The other day I realized that there’s one missing from this list:

x → ♢y

x is mapped to y eventually (Promises)

I’m not sure what to do with this knowledge, but it’s fun to realize I actually knew one more thing than my teacher.  Note that the first case, x → y, really does cover all sum (union) and product (struct) types, which tells me that the ML-style languages’ internal type discrimination features are orthogonal to their encapsulation of non-linear mappings.

The really weird thing is to realize that the last four are all order-dependent.  They’re all about making sure things happen in the correct sorted order (and temporal order, if that matters).  That leads me to think more about compiler design…

Leave a comment
Andrea Goulet is giving me an existential crisis. The CEO of a software development consultation shop, she recently wrote an article called Menders vs. Makers, and something happened this week that makes me think, maybe I'm in the wrong line of work. I'm starting to suspect I'm a mender in a business that only values makers.

This week, I was working on a code base that provided a hierarchical tag editor for an inventory system. I had recently added a new feature that made it possible to see individual elements of the tag system on the Collection page; you not longer had to go visit a single object to see if it had, for example, a location tag; you could just say on the Collection page, "Show me all the objects that have a location tag, and add a new column, location."

Now that we were able to see the tags, a new problem was found: it wasn't possible to delete tags. Odd nobody had noticed that before. Since I was the last person in that code base, it was my duty to fix it. Down into the legacy code I went.

The tagging code was, well, intermingled. Validating the tags, determining the changes between the version on the client and the version on the server, writing those changes back, were all in a single gigantic Backbone sync method involving empty arrays, for loops, and concat methods. I spent about four hours, during which I:

  • Replaced all for loops with map / reduce / filter

  • Separated the model validation into its own method

  • Used underscores's intersection / union / difference functions to create instruction sets for deleting and adding to the tag system

  • Used Backbone's set([_], (void 0), {unset: true}) method to delete the tags, rather than hammer the event bus with a series of change events in a each loop.

. I struggled a lot to make sure I was using names that explained what each thing did.

In short, I did with my code what I did with my writing: try to make every line a pleasure to read, something that told a story about what was happening and what was going to happen next. I hope when someone sees overlappingTags = _.intersection(newTags, restrictedTagNames), it's obvious what's happening, and it should create anticipation that soon there will be a line that checks to see if overlappingTags has anything in it and, if it does, reports an error with the offending tags.

I've always had fun doing stuff like that, turning unreadable mash into clarity. Even my recent bragging project, Polyloader, is actually a fix for the "All Python on the filesystem ends in .py" bug that sorta firewalls.

I've found this industry doesn't really like menders. Code editors, people who go in after the fact and apply measures both aesthetic and qualitative to the code they see, are often seen as nothing but agency overhead by managers.

On the other hand, I've yet to meet another developer who resented menders. They like menders; they want to learn from menders how make code better. Menders tend to be older, tend to know more, tend to be broadly learned and strongly opinionated. Nothing "just gets thrown there." It has to be fixed, it has to work, it has to be right. And I've yet to meet a software developer who didn't want to get it right. Often, they just don't know how, or nobody's ever told them how.

Let's show them how.
2 comments or Leave a comment

Sometimes it’s a little hilarious to read the back-and-forth of academics. My favorite is this exchange from Roman R. Redziejowski and Brian Ford over packrat parsing. Redziejowski writes

PEG is not good as a language specification tool. The most basic property of a specification is that one can clearly see what it specifies. And this is, unfortunately, not true for PEG.

To which Ford responds,

Such permissiveness can create unexpected syntactic subtleties, of course, and caution and good taste are in order: a powerful syntax description paradigm also means more rope for the careless language designer to hang himself with.

No points for complaining that Ford ends his sentence with a preposition.

This exchange highlights an issue in the programming language community that stands out for me. There’s a debate raging between two camps, with Google Go at one pole and Haskell at the other. Google Go is fundamentally an ugly language, one the designers admit up front is meant to make mediocre programmers productive, to constrain them from hurting themselves while making them capable of producing working code. And while it’s fine for that, consider the Microsoft “wizards” of the mid-1990s that pumped out huge blocks of C++ that nobody, not even the template designers, could understand; when it comes to Go, that’s where we’re headed. On the other hand, Haskell is fundamentally a beautiful language that’s really, really hard to understand; you have to immerse yourself in decisions where you, yourself describe the constraints with precision, with care, with taste.

Ira Glass has a speech, On Storytelling, in which he says, about being creative,

We get into it because we have good taste, but there’s like a gap.

The first couple years that you’re making stuff, what you’re making isn’t so good, It’s trying to be good, it has ambition to be good, but it’s not quite that good.

But your taste, the thing that got you into the game, your taste is still killer. And your taste is so good that you can tell that what you’re making is kind of a disappointment to you, you know what I mean?

The thing is, this is true of storytelling, of drawing, of any creative endeavor. A lot of programmers don’t get into programming because they view it as a creative endeavor. They view it as puzzle solving. They view it as engineering. They view it as a way to make money fast.

They have no taste.

Often, they don’t want to have taste. They want to get the job done and get paid. “Taste” slows them down and gets in the way. Aesthetic decisions about code layout and arrangement, they believe, are irrelevant to getting the job done.

This isn’t true, of course; Tasteless Go is still as unmaintainable as tasteless C++. It’s possible to write aesthetically horrifying Haskell. Let’s not even talk about Perl.

I believe this is the fundamental dividing line betnween Go, C, and C++ on the one side, and Rust, Clojure, and Haskell on the other. The whole point of Go is make programmers with no interest in taste or aesthetics write programs that work. Maintainability is secondary.

Which goes back to my tweet above. Java and Go programmers want to write the first kind. Haskell and Lisp programmers and their descendents love to write the second type. But my experience with reading and writing in a variety of lanugages convinces me we frequenty end up at the third with no help for it.

The solution is to teach aesthetics. To teach people that readability and maintainability matter more than just getting the job done.  That if it doesn’t make you feel good the day after you wrote it, re-write it.

After all, sometimes your code will live much longer than you expect.

Leave a comment
An hour before dusk on friday night, Omaha, Raen (nee' Kouryou-chan) and I all piled into the car and headed out for Rattlesnake Lake to watch the Pereid Meteor Shower. The weather promised to be exquisite, and as we drove up through the valley it looked like it was going to stay clear through the night.

The park's parking lot was expected to be closed at 9:00pm, so when we got there we chose to park on the side of the road outside the park. A

lot of people made the same decision. There were almost forty cars on the side leading to the park, and there were just as many on the other side of the road.

We walked into the park to discover that the lots were open, the bathrooms unlocked, and the grass along the waterfront already teeming with people. We lay down on the grass, in the dark, and waited.

Humans are rude. Rattlesnake Lake Park was the "recommended" site for watching the meteor shower, according to the UW Astronomy department website, as well as the Seattle Times, because it was just on the fringe of the "no light pollution" zone from the urban cores of King County, but apparently some people didn't get the memo that "no light" means "no light," as in turn off your goddamn flashlights, and there's no 3G out here anyway. The smell of marijuana filled the air (of course it did).

The moon was the worst offender, but there's not much to be done about that. It occupied the southeastern sky, drowning out all the stars around it. Someone high up on Tiger Mountain ocassionally flashed bright strobes for reasons that must have been positively Nightvalian.

And yet as we watched the sky for an hour or more, we saw the meteors fall. Just a couple, but at least two were spectacularly bright and left trails of distintegration in their wake that lasted for a second or more. Ane seemed to come right at us, a bright burst of light that drilled its way toward us before fading completely.

We decided to leave. The swarm of humanity coming in to see the peak around 2:30am was huge; there were now hundreds of cars everywhere, with three or four people per car, out for a "sanctioned" late night party watching the shower. It was surprisingly peaceful and social. There was giggling and laughter and the ocassional crack of a beer can, and then we got into our car and left.

We got home around 12:30am and poured ourselves into bed.

Current Mood: happy happy

Leave a comment

This feels like something that deserves clarification. It’s not that I fear any and all of my projects becoming popular. I would love for some of them to become very popular. Polyloader would be awesome, as would Tumble. But I draw a distinction between tools, products, and examples. Catalogia is a product, and I don’t want to be tech support. There’s a huge difference between getting something right, and teaching the average user about the cupholder that came with his desktop machine. Tumble and Polyloader are tools: I want them to reach the widest possible audience and make that audience, my fellow developers, smarter and happier and more effective. The Backbone Store is an example, but examples are just examples. If they’re inadequate to the state of the art, it’s my duty to revise or remove them, or at least comment on their deprecation, but I’m not going to help individual users understand what’s going on.

Leave a comment

After publishing The Semantics of Python Import and explicating on the history and internals of how Python turns source code into running operations, I thought I had a pretty clear idea of what to do next. I extended Hy such that it was now possible to write an entire Django application in a Lisp dialect, which was cool, and started on Catalogia, a program that would help me index, search, clean up and organize my music collection. The idea behind Catalogia was to demonstrate that writing an entire Django application in Hy was possible. I’ve done that, even going so far as to demonstrate that it’s possible to replace the boilerplate of generic views with a Lisp macro to generate the boilerplate automatically at compile-time.

The problem is that Catalogia isn’t done, but I’m already bored with it. This is a classic problem in side projects, I know, but I’m trying to figure out what to do with it.

What I’d really like to do, now that I’ve got a viable Lisp running on and auto-transpiling to Python, is write even more tools to extend Hy even further. I don’t like the existing suite of PEGs for Python; I’m completely spoiled by David Majda’s PEG.js, which marries PEG to Javascript with the absolute minimal amount of boiler plate possible; I’d like to port something that succint to Python. Lexer/Parser technology is one of those spaces that’s assumed to be “solved,” but there are still places where it could be better, especially in the UX of the development process, and there’s also an entirely new Lexer/Parser theory called the Derivatives of Determinite Finite Automata that has one implementation (in Racket, natch) that I’d like to see happening in a popular language like Python.

What I’d also like to do is strike out on my own and build on the experience Hy gave me to build a language research platform for Python. Something like GardenSnake, but complete, on top of which it would be easy, even trivial, to add new tiles that construct whole new operators in Python. I’d like to be able to pipe and compose Python instructions in a point-free syntax; how cool would that be without having to run through a transpiler? Just write in this “extended” Python, call Python, run Python, and have it work. (Psst: Polyloader is a key component of this idea.) Something that could be rolled back simply, providing plug-and-play additions to the Python grammar/compiler, just by adding a single call in your script to polyloader.install()?

Meanwhile, all the other desires are piling up. I want to run through this class, and this class. (I already have the textbooks.) I want to move this blog off effin’ WordPress onto something sane, and then Dockerize the sanity. I want to finish my basic editor for my stories, with all the front-end stuff that’s been missing for so long, and do a visual refresh, and all the other critical things that happen when the Web Guy’s Website Doesn’t Get Revamped.

I really should commit to Catalogia. I’m just afraid of it becoming popular.

Leave a comment
The thing about Trump Lies is that Trump's lack of connection to reality isn't lying: it's worse than that.

It's bullshit.

Time after time in the WaPo article outlining a court case from 2008 that broke open just how often, easily, and readily Trump says what isn't true, it's plain that Trump doesn't connect what he's saying to what he knows. When the lawyers actually call him out and point to things he said or did that don't jibe with his current testimony, he blames someone else for the mistake, or tries to explain how in his version of reality $400K is really $1M. In the philosophy of bullshit (yes, there really is a "philosophy of bullshit"), it's explained this way:
The bullshitter may not deceive us, or even intend to do so, either about the facts or about what he takes the facts to be. What he does necessarily attempt to deceive us about is his enterprise. His only indispensably distinctive characteristic is that in a certain way he misrepresents what he is up to.

The bullshitter hides that the truth-values of his statements are of no central interest to him; what we are not to understand is that his intention is neither to report the truth nor co conceal it. This does not mean that his speech is anarchically impulsive, but that the motive guiding and controlling it is unconcerned with how the things about which he speaks truly are.

A person who lies is responding to the truth, and he is to that extent respectful of it. For the bullshitter, however, all these bets are off: he is neither on the side of the true nor on the side of the false. His eye is not on the facts at all except insofar as they may be pertinent to his interest in getting away with what he says. He does not care whether the things he says describe reality correctly. He just picks them out, or makes them up, to suit his purpose.
Now you tell me that isn't the GOP candidate.

Tags: ,

1 comment or Leave a comment
I really, really wanted to love The Life Engineered by JF Dubeau. The back cover sounded exactly like my kind of thing— a posthuman mystery in which the a long-dead police officer finds herself resurrected in the body of a first responder robot; humans have long since disappeared from the galaxy and she is soon thrust into a shadowy war between factions with very different ideas about what humanity's legacy will be.

And the cover art is gorgeous.

About two-thirds of the way through the book, I really wanted to hate it. A story outline like the one above has so much potential. Like many a book or movie, there's a brilliant idea hiding in the center of this book that's screaming to get out if only a more mature or skilled writer were allowed to develop it.

The book is either far too long or far too short. It has two introductory chapters, the first of which sketches (and I do mean sketches) out the setting: two humans have a dialogue about whether or not they entrust their robots to take care of the galaxy while humanity goes into hiding, and decide not to tell the robots where humanity's cryogenic creches will be constructed; they have to go into hiding because a series of neutron star bursts are making the galaxy uninhabitable— they discuss whether or not this is deliberate– but they're wary of their AI children. The second shows our heroine in her 21st century existence, and its conclusion is one of those painful "character development" scenes where the heroine gets beaten/raped/abused to give her a "reason to fight."

The rest of the book is a ham-handed expository sequence of our first-person POV heroine telling us what happens next. In a lot of ways, the book reads more like the treatment for an fantastic third-person POV science fiction story like Mass Effect or Dead Space III, only "with robots!". Events leap from setting to setting, incident to incident, with sometimes only very tenuous connections. There are very few surprises in the book, very few twists and reveals. Technological abilities and limitations exist only at the need of the story, and not due to careful consideration of the universe Dubeau had crafted in the previous chapters. Word-by-word, the style is clunky and prosaic, with no attempt to escape, expand, or even embrace the dialect and idioms of the writer himself.

What I wanted was something that pointed to the kind of story Iain Banks or Greg Egan would give us, with lyricism, panorama, character and depth. Banks, Egan, and company didn't jusnt plow the ground toward viable transhumanist writing; they did it with enthusiasm, with panache, with style. But plow they did; they showed us where the road points and they dared (and continue to dare) the rest of us to come up to the standards they've set on this new ground.

What I got was the awkward retelling of a game session from Steve Jackson's Transhuman Space RPG with some clumsy FTL handwavery added for convenience. There are so many moments in the book which are just disappointing, where the author had a chance to show us how magnificent the sights are, rather than having the main character tell us about its magnificence, or to give us revelation in carefully crafted dialogue rather than just reel it out as another expository lump.

In the end, I guess I... liked (?) the book. It ends with a promise that there's more to come, and there's so much hope in this story— not in the story itself, but in writer's potential to mature into something more than just another RPG-esque chronicler. (Not to put down RPG chroniclers; Steven Brust has made an entire career out of it. But he's good at his job!) May Dubeau have a long and happy life; he had patrons for his effort and they deserved better.

Tags: ,
Current Mood: disappointed disappointed

Leave a comment
Every morning, there's a ten-minute drive between my house and the local light rail station that takes me into the city and my day job. It's not long enough to be memorable, or short enough to avoid, so I tend to flip through the radio on the way to work, and since out of the give talk show stations in Seattle three are conservative, one is "conservative," and one is NPR (which is about as liberal as its corporate sponsors want it to be), I tend to get an earful of the right's zeitgeist.

They were really depressed this morning. Not one of them can see a way out of the mess Donald Trump's primary supporters have gotten them into. One guy, though, was putting on a brave face.

It's a common trope on the left that right-wing talkers take their own worst sins and project them onto others. It's well-documented that white people see racial equality as a zero-sum game: the granting of privilege to minorities is seen as a loss for white people. (And it's quite real; in all of the "he says what we're all thinking" commentary on Donald Trump, one thing these people feel deeply is the pain of not being allowed to mistreat minorities or women without obloquy. They miss that, a lot.) So when I heard a right-wing talker use the phrase "zero sum," I let the radio dial lie.

"Leftists believe in the zero-sum fallacy," he said. "They believe that if one group is making a lot of money, they must be taking it away from others. They don't believe in growth. This is why the right doesn't care about the 1%. You shouldn't care about the 1%. Fear of the 1% exists only because of the zero-sum fallacy."

Well, no, I wanted to explain. There are actually worse things than a zero-sum game. We could have growth, and the 1% could be sucking up all of the newly-generated returns, leaving nothing for the rest, which is exactly what's been happening for 40 years. Because r > g (The rate of return on capital is greater than the rate of economic growth, and regulatory capture dictates that it will stay that way for the foreseeable future), money generated through growth gravitates toward the biggest deposits, resulting in corporate fiefdoms, massive index pools, and more regulatory capture.

The 1% own 36.4 of the wealth. And here's the real problem: The rest of us simply don't believe the 1% generate the kind of economic growth that justifies allocating that much of the nation's ongoing income toward them. We don't believe that the CEO really generates 200 times the amount of wealth for a company as a factory floor worker. There are only so many hours in a day; the CEO can't create 200 times as much money per day, every day, compared to the steady output of labor.

Rich people don't really create jobs. Entrepreneurs do, but they're not "rich" people; they're entrepreneurs, who could be anywhere in the cash cycle from wealthy to indebted. It is the middle class, not the rich, that make the economy grow.

All of which is to say that one shouldn't listen to right-wing radio.

Tags: , ,
Current Mood: amused amused

Leave a comment
Last night I sat down to watch London Has Fallen. I actually enjoyed the original, Olympus Has Fallen, about a terrorist takeover of the White House. Gerard Butler did a fine job in that film as the middle-aged secret service agent disgraced by a tragedy he couldn't prevent who finds himself the sole officer left in a building filled with hostiles. The movie has some of its energy sucked out of it halfway through-- a pacing error, basically-- but overall it has a number of highly effective "action" set pieces-- nine, by my count-- and at almost exactly two hours long is just about right.

London Has Fallen is awful. It's 80 minutes long, barely a TV special, it has exactly three set pieces (the initial attack, the first attempt to get away, the final rescue), and its set-up lacks all the emotional punch of the original. But what's most awful is the premise, because what carries the premise is basically UKIP and Trumpian politics gone utterly sad.

Olympus proposes an attack by a highly-trained, well-equipped military force supplied by a state power. With one notable exception (a cargo airplane armed with mini-guns), the bad guys use mostly off-the-shelf weaponry and cleverly exploit city infrastructure, like using garbage trucks as assault vehicles; heavy steel protects the attackers while allowing them to hose down the combat area with .50 caliber fire, and by blowing up the tires with small charges the trucks cannot be pushed/dragged out of the fire zone effectively. The attackers also had months to train and weeks of heads-up time in which to prepare.

London gives the bad guys three days to put together an attack on a much larger scale, hitting a large number of well-defended landmarks all throughout the city. The bad guys come equipped with every imaginable weapon, including a specialized thermite grenade that "melts through" engine blocks. The bad guys supposedly knew where every world leader was at the moment of attack and had elaborate tools at their disposal for committing mayhem.

But London's biggest crime is that it depicts every Muslim in the UK as a potential terrorist. Swarthy members of her Majesty's Royal Guard, Scotland Yard, the London Constabulary, and Emergency Services are depicted suddenly dropping their masks and opening fire on everyone around them. London depicts the UK's Muslim population as a foreign body ready to rise up and become a disciplined, well-equipped insurgency ready to commit atrocities. During the final manly fist-fight, the protagonist grunts out an actual "thousand year" (tausendjähriges) speech between blows.

It's just gross. It's jingoism of the worst kind. And Butler, who produced as well as acted, doesn't deserve attention for any of his roles in producing this steaming pile of elephant poo.

Tags: ,
Current Mood: annoyed annoyed

3 comments or Leave a comment