Wednesday, September 20, 2017

trivial php router for local dev and under apache

I wanted to make a PHP app so that I could work on it online and offline, with or without Apache, and that maybe it would be cool to have a centralized controller... do things a bit MVCishly rather than just having a pile of .php scripts (in particular, my first attempt for chart-o-tron did a lot of htaccess hackery to allow for pretty URLs, but the other URLs were all .php which looks pretty janky these days)

The page on the PHP built-in webserver mentions you can run PHP from the command line, and have every request be piped into a router
php -S localhost:8000 router.php
and here's their sample router script:
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
    return false;    // serve the requested resource as-is.
} else { 
    echo "<p>Welcome to PHP</p>";
The trouble was when I setup .htaccess to have Apache send all requests to it, the idea of "return false;" doesn't mean anything when Apache has already ceded control. In theory I could have used readfile() to handle PHP stream up static files, but it seemed weird, not leveraging Apache's optimization in serving static content, and a potential security weakpoint.

I decide to put all my static content under /static/ rather than worry about file extensions, or regular expressions to tell Apache to treat .php files differently... It took some fumbling to get the regex quite right:
RewriteEngine On
RewriteRule !^static router.php [L]

I then fiddled with the router script to do the parallel thing when I'm running locally:
if (preg_match('/^\/static\//', $_SERVER["REQUEST_URI"])) {
    return false;    // serve the requested resource as-is.
} else { 
    echo "<p>Welcome to PHP</p>".$_SERVER["REQUEST_URI"];
Seems like a good start. There are other PHP router scripts that are configurable, but I kind of like this low level of control. 

farewell 32-bit iOS apps...

Well, we knew this day was coming... with the release of iOS11, Apple is dropping support for 32-bit apps. I can't blame them, entirely - eventually a company should probably decide to drop the technical weight of supporting everything forever. Still messages like "'ThisApp' May Slow Down Your iPhone" "If no update is available, contact the app developer for more information" were kind of disingenuous. It's stretching it to say it "slowed down the phone" - it would take a moment to setup the legacy libraries, and it's less memory efficient, but really the transition was seamless.

But contact the developer? As if the problem was they didn't know... more "nag the developer and hope that they care about this app even though they didn't figure out how to make it financially viable on an ongoing basis".

If you want to find out what apps you might lose if/when you upgrade to iOS11, go to Settings App, General | About | Applications.

The damage was less bad for me personally than I had feared. I just wanted to take a second to note the apps as I say farewell...


  • ENDI Tank was a playful 3D tank game, taking place in a sandbox. Seems to be a student game, from the École Nationale de Divertissement Interactif , but it was nicely balanced and looked great.
  • Little Master Cricket is a simple physics game from the maker of QWOP. I guess you can play it online (if you still run Flash anyway... sigh.) - balls got pitched in and your batsman had to hit them away and protect the wicket, or whatever cricket is about. It was a fun quick-hit.
  • Truckers was a raucous 16-bit-graphic-flavored semi-driving romp, a bit like Outrun. It's so well polished that I'm surprised it never saw an update. 
  • Big Fat Lies was one of the best "entertain people incuding the driver" car games I've seen. A bit like that part of "Wait Wait Don't Tell Me", two outlandish stories would appear and the current player would have to say which one was false.
  • Galcon was a primitive but fun 2D Real Time Strategy game that I've seen on many platforms, send your hoardes of triangular spaceships to take over planet by planet, turning each into a ship manufacturer to increase the size of your fleet. It was kind of inspiring because I knew it was written in Python/PyGame, back when I thought everything for iPhone had to be in ObjectiveC.
  • Weightbot was a terrific little weight tracking tool that made nice little bloops and blurps and clicky noises as you entered your weight. I was using it from 2010 'til this year. Now I use "Weight Record", which has a very similar vibe, but isn't as cute, and with much less satisfying clicks.
  • You've Gotta See This! was a fine bit of photo-stitch software, using the then-new gyroscope to let you wave around the camera and then put together panoramas of the result:
    I have a few similar programs, but haven't yet searched to see if anything does quite as well as this one.
So apps I won't miss: Cracked - "Cracked Lite" has been superior for a long time for reading that great content. I guess duplicates the website functionality which hasn't felt trustworthy in a while. 20 Questions was another car-able game, mostly just a collection of words to guess. That just leaves iMetronomeTempoTool (heh, kind of a port of an app I wrote for Palm PocketC to tell me what the current BPM are) and SimpleResize - I think these are all utilities I can find replacements for if/when the need arises.

With today's curated online appstores, digital archiving becomes harder and harder- a harsh reality for a lazy retrogamer like myself. Even before this great 32-bit-app purge, there was a great 2D Tank game called "Tron" that Disney commissioned when the new movie came out that has been AWOL for a while. And it's not just Apple - even on Xbox Live, there's a Doritos-sponsored game called "Dash of Destruction" that had such fun with scale - playing on the same board as either a GIANT dinosaur or a tiny delivery van - but if anything ever happens to my hardware I'll probably lose access to the game. For digital historians it's a tough road to hoe.

Monday, September 18, 2017

syntactic high-fructose corn syrup

It's easy for old fogies like me to get a bit cynical about ES6 and all the new syntactic sugar - it can be tough to pick up because if you've only seen it in a webinar or two, but it's not prevalent in the legacy code base you're working with daily, it's easy to forget, and then confusing when you do run into it.

Case in point, this line:
const { urls = {} } = window || {};

Roughly it's saying "set a constant variable (ok, a 'constant') called urls to window.urls if it exists, but don't blow up if window or window.urls doesn't exist."

Besides recognize const vs var, there are three things going on in that tangle:
  1. The good old fashioned, pre-ES6 "short circuit" operator, where you can say
    something = thatthing || {};
    so the right side is thatthing if thatthing is truthy-true otherwise, set to an empty map.

    (huh, surprised the people who love triple equals haven't made triple-or to specifically handle "if this is null or undefined")
  2. Destructuring! The simple case here would be if you had an object called foo with a key bar set to something and a key baz set to something. Then you could say
    var {bar,baz} = foo;
    to get a local var bar and a local var baz set to and foo.baz, respectively.

    This actually neatly addresse a weird asymmetry in C-style syntax I blogged about 13 years ago - that it's strange that you pass many things into a function, but you only get one thing out. But now you can do
    var {oneThing, anotherThing} = someFunctionCall();
    and you don't have extract simple variables out of a map object by hand.
  3. Default parameters - for a second
    {urls = {}}
    seemed so strange... I mean I see the value of saying "set urls equal to this if all else fails" but was it a special, one-off syntax just for destructuring? Well, no, now that I think about it... in ES6 you can have
    function someFunc(someParamWithADefault="that default"){ 
    and if nothing is passed in for that first parameter, the first parameter becomes that default. And so we see the syntax used inside the destructuring assignment is borrowing from that generalized default parameter shortcut
So thanks to Dan at work who wrote the code and then explained it to me nicely when asked... he also pointed out I can go to this Babel.js tool to see the concise syntax translated into old school javascript.... in this case
  const { urls = {} } = window || {};becomes

"use strict";
var _ref = window || {},
    _ref$urls = _ref.urls,
    urls = _ref$urls === undefined ? {} : _ref$urls; 
Still a little tough to digest, but it's nice to be able to trace the steps. 

So it seems like Javascript is borrowing the Perl idea of "lets say this more concisely with nifty syntaxes!" but missing Perl's "lets not blow up if we try to pull a value out of an object that doesn't really exist". 

Sunday, September 10, 2017

put something back into the world

Steve Jobs over dinner with Steven Levy:
"I look at myself as [sort of trapeze artist, without a net] if anything. But it's a way of expressing feelings about, a group of feelings. Wanting to put something back into the world. You know we're constantly taking. We don't make most of the food we eat, we don't grow it, anyway. We wear clothes other people make, we speak a language other people developed, we use a mathematics other people evolved and spent their lives building. I mean we're constantly taking things. It's a wonderful ecstatic feeling to create something and put it into the pool of human experience and knowledge.
The interview transcript is an appendix to a new edition of his older book about the development of the Macintosh, "Insanely Great"

One thing the book mentioned was John Sculley pricing the late-80s Mac a bit high, going for profit margin rather than marketshare. I guess a version of that strategy is working well for Apple now, taking something like 90% of the mobile phone industry profits, but still visions of a world where the Mac had early, Apple II like penetration, and where every college kid had one rather than just the artsy ones... if HyperCard had been in the hands of even more people...

(Of course, looking around in the environs of Boston tech and Cambridge coffeeshops, it's astounding that only 1 in 10 PCs are by Apple - they seem to be omnipresent)

Getting back to the Steve Jobs quote, thinking of what I try to add to that pool. I guess except for "JoustPong" (heh) my best bet is helping people to calm down about death via So, You're Going to Die.

Sunday, September 3, 2017

css-only icons

Keeping my eyes open for icon packs that are cheap, both in terms of complexity/files to load, and in terms of cost (though i don't mind spending $10 or so I guess.)

Icono pure CSS icons are pretty dope, but it's weird there's no obvious "edit" (like maybe a pencil to a piece of paper?) Also they're not easy to resize I guess. Maybe I should keep looking for future projects, but for my current project it'll do.

Saturday, September 2, 2017

i teach you the spongeman

A while ago my erstwhile debating partner introduced me to Rapoport's Rules, guidelines for criticizing the argument of an opponent. As formulated by my favorite philosopher Daniel Dennett, they go:
  1. You should attempt to re-express your target’s position so clearly, vividly, and fairly that your target says, "Thanks, I wish I’d thought of putting it that way."
  2. You should list any points of agreement (especially if they are not matters of general or widespread agreement).
  3. You should mention anything you have learned from your target.
  4. Only then are you permitted to say so much as a word of rebuttal or criticism.
Another term for this is "steelmanning" - in contrast to "strawmanning", where you knock down a lightweight representation of the opposing argument that's designed to be knocked down, here you make an effort to really understand and then gird it in rhetorical steel and state it back to them.

On some levels the rules' concept is appealing, but also - unlikely, I guess I'd say, for people who have are arguing sincerely. If you could whole-heartedly restate your partner's (or as the rules put it, "target's") view, you'd pretty much have to be believing it yourself. That "Thanks, I wish I'd thought of putting it that way" bit is also weirdly condescending - your displayed mastery of the domain is such that your "target" will humbly thank you for your cleverness of the restatement? For something that you still don't believe? What kind of insincere sophistry is that? Like a suit of armor, I think this kind of steelman will ring hollow.

My erstwhile buddy didn't really grasp my objections until he listened to Hannibal Buress on the Sam Harris podcast. (Admittedly Buress might be a little drunk, but I appreciate his sincere points) Around 29:00 minutes in, Sam Harris says
Here's a bet, here's a bet: I could summarize your view of me in a way that you'd agree with. You couldn't return the favor. You want to take that bet? I'm absolutely sure I can articulate how you view your side of the conversation in a way that you'd sign off on. I have absolutely no faith that you could do the same for me. That's a problem, we're not successfully communicating.
My buddy had an even strong reaction against Harris there than I did, that he saw Harris using the "I can see your side" concept as a bludgeon.

My counter-proposal was "spongemanning". The best we can do is try to absorb the other person's argument, then wring ourselves out, restating the argument as best we can, and have our partner comment on the drippings, to see how much of the salient info we had actually taken in. Spongemanning offers more substance than the superficialities of steelmanning, and it is more respectful than steelmannings "anything you can think, I can think better".

At its very best it invites participants to think about where their partner is coming from, and what are the headwaters of their current flow. (At the risk of straining the wet metaphor.) One of the few things I like about Ayn Rand is her alleged greeting of "What are your premises?" It's rather belligerent, but it gets to the heart of why sincere people who keep faith in the methods of rationality and discourse as a way of understanding the universe can still disagree... they have different starting assumptions and then differing concepts on what is best prioritized in life. By trying to absorb what your opponent is saying, you might better identify and catalog those sticking points - fundamental areas of disagreement where "agreeing to disagree" isn't throwing out the whole kit and kaboodle.

Behold: the spongeman! (With normal, double-tube-shaped pants)

Thursday, August 31, 2017

count your secular blessings

A blog I like, Lost in Mobile, sometimes parlays thoughtful comments into new articles. Here's a bit from a comment I made on an entry on folks being jaded about smartphone improvements:
Sometimes I still get myself a little frisson of excitement about how cool the little gadget I'm carrying is, how chuffed I am to have my Todo list all organized on it, and my music all sorted and at the ready, etc. I think that's a weird kind of consumerist mindfulness. I'd seriously suggest people do that – take inventory of the blessings bestowed upon you by an engineering savvy society – from crisp clean water, hot showers, and flush toilets, to public health saving us from a bajillion ailments, to our crazy ability to travel at 60 mph like it ain't no thing and hundreds of miles faster than that for a reasonable sum, to the way our little gadgets have access to SO much information, and provide (for worse but generally better) a constant lifeline of contact with our loved ones. Be thankful for all this stuff, because it's well-nigh miraculous.
Full ramble here...

Tuesday, August 29, 2017

Friday, August 18, 2017


Async/Await Will Make Your Code Simpler... the next step beyond netsting pyramids and promise chains. It kinda just lets your async code look like good old fashioned terrible sync code!

(I always thought that the pyramid of doom could be somewhat mitigated if you didn't put a lot of logic in the pyramid itself, but left it as a structure to a lot of named callbacks instead of anonymous functions, but still, these new techniques seem pretty good.)

Wednesday, August 9, 2017

simple countdown timer

My cousin posted
Thanks for the birthday wishes, folks! Tech dorky friends- if you want to give me a gift, what I really need right now is a countdown timer that displays in its own window, without a lot of other crap in the window. The ability to set the font is a huge plus. 
It is *amazing* how hard this is to find through casual Google searching.
Well, I'M a tech dorky friend! So I did an exercise in quick and dirty vanilla js and made . Its default colors are black on green (I think he's doing a green screen process and using it as an overlay) but you can change the RGB for the starting color, and then what to show when the counter hits zero, like this

At any time you can click on the time and reset it. (I also added a font= parameter but anything that's not a monospace will wiggle a bit as the centered text changes width during the countdown)

Nice to have the mojo to be able to say "I got you fam, gimme ten minutes" though it was more like half an hour. It's not lovely code. Some small tricks used include this quick and dirty vertical centering and use of "vw" CSS units so that the display was scaled to the screen (I had to set the block's height to 1em for the vertical centering to work)

Sunday, August 6, 2017

visual design and the broadway version of frozen

Here's the poster for the broadway version of Frozen... the NY Times has an article with 7 other candidates and their strengths and weaknesses.
Great seeing some of the process of evaluation at work. And I dig the "is it a lamp or two faces in silhouette" they snuck in the final design.

Saturday, July 29, 2017

RIP microsoft paint?

MS Paint to be phased out, though reports of its death are slightly exaggerated.

...I love that video ("Can we... can we thin out the line? Can we make the line thinner-" "-No" "...Ok")

Old school Paint did one thing better than almost all of its peers, and almost every program today even, in that the the mouse pointer was actually the brush you were about to paint with. Between that and not having to worry about anti-aliasing, it was pretty cool for pixel art. (And then there are some folks who use it as an actual art tool apparently in a pixel by pixel way)

That said there was a revamp of it that made me like it a bit less than the original.

Sunday, July 23, 2017

file syncing / folder watching over scp (not ftp)

Just some technical notes to my future self...

I wanted a file syncer, so that I could edit some webstuff locally on my Mac and see it immediately on refresh of the website I'm working on.

(I have a kind of clunky but useful textarea based online editor for my websites based on markitup, but since it submits as an old fashioned form POST rather than something clever with AJAX, I'm always losing my place, plus I haven't researched how to give it more of the IDE-ish features like line numbering, autotabbing and parens balancing)

I wasn't having much luck with Yummy's "FTP Watcher", as far as I could tell it can only be set to poll as low as one second, which is a bit too slow. (My gold standard right now is IntelliJ - its cleverness is to notice that it has lost focus, and THEN run the file copy. This works much better and transparently than I would have expected for stuff that doesn't have a build cycle.)

The best bet I found was sshync -

(In turn I had to follow its instructions to install and run ssh-copy-id - but then it was asking me for my passphrase not remote password each time.  So I found some instructions on running ssh-add and now it does what I wanted.

The only other note is I misguessed how to specify the source and destination folders, I had thought it would be like
sshync ~/dev/website-folder/ username@server:/site-parent-folder/website-folder/
but instead it was
sshync ~/dev/website-folder/ username@server:/site-parent-folder/
i.e. the destination is kind of like the parent instead of the peer. And I wanted to avoid worrying about wildcards.

to be more specific, after using this setup on one system for a while, and then doing it on a different system...

I had to get and run ssh-copy-id, using
brew install ssh-copy-idand follow the instructions at - I already had by key generated, so I used ssh-copy-id on the public key in the folder.

Then my notes say I tend to have to run
exec ssh-agent bash
each time before starting sshync , otherwise it keeps asking me for my password

Tuesday, July 18, 2017

thinking about xml vs json

Seeing an XML config file at work got me to thinking why JSON feels so much better than XML for so many people. I find it a fascinating topic, maybe because it seems like the industry movement towards more JSON is validating my personal biases...  One friend of my mine paraphrases it "well, you see, XML has way too many sharp pointy bracket bits, it's hard on the eyes".

I guess it's weird that XML lets you enforce discipline about what CAN be said (via validating schemas) but has less to say about how a coder should what they'd probably want to say...  namely "I am likely to want to serialize a lot of lists and key/value pairs".

It reminds me of when I first learned Perl, coming from a background of C (with a bit of BASIC and Logo growing up) - the concept of maps, regular expressions, strings as "first class" participants (vs C's  not "arrays of characters"), duck-typing, and not having to micromanage memory use were revelations. But especially maps (key-value pairs) - a hugely empowering concept.... trivially simple yet enormously powerful, which is about the definition of elegant. And that elegance is something that JSON leverages so well.

Googling a bit I found Stop Comparing JSON and XML which, honestly, sounds a little defensive to me. For some engineers, XML's precision and control just feels better, but it sounds like some fans feel they're on the wrong side of the trendlines, so it opens up like this:
Stop it! These things are not comparable. It's similar to comparing a bicycle and an AMG S65. Seriously, which one is better? They both can take you from home to the office, right? In some cases, a bicycle will do it better. 
The not so subtle implication being that XML is more like the $220K Mercedes and JSON the bike.

I'm not sure I agree that "JSON is a data format, XML is a language". The article points out some standard tools that XML comes with: XPath processors for pulling things out of a chunk of data, XML Schemas for validating (I guess that one out over DTD?),  XSL for transforming (and OH what a pain that can be, trying to use a pure-functional "I can't even use a conditional to set the initial value of a variable, because once I'm out of scope the conditional set up the variable went away")... I don't see those things as being intrinsic to the format, however.

Moving on - take a look at the example that article gave, JSON vs XML
  "id": 123,
  "title": "Object Thinking",
  "author": "David West",
  "published": {
    "by": "Microsoft Press",
    "year": 2004


<?xml version="1.0"?>

<book id="123">
  <title>Object Thinking</title>
  <author>David West</author>
    <by>Microsoft Press</by>

(The article says that's 140 vs 167 characters, but I put the latter at 189) ... anyway, back to my point that XML is a bit worse at suggesting a "best practice" of how something should encoded - because you're so often not sure if something "should" be an attribute or a child element. The article puts id as "metadata", but that seems kind of an arbitrary distinction to me. (Trying to think of what the rule of thumb takeaway is - data is the information that would have to exist in a different storage system, but metadata is sort of specific to that system?) I've certainly seen other folks who would have done something like
  <published year="2004">
    <publisher>Microsoft Press</publisher>

and so coming into a place, trying to follow the previous developers' footsteps- the decision can be arbitrary, and thus hard to predict.

I remember thinking it weird how hard it was to write a Schema (or maybe a DTD?) that let the child elements be in any order; the tools I was using in the mid-aughts made it much simpler to insist on, say, "first title, THEN author, THEN published", rather then saying "there needs to be a title, author, and published but they can be in any order". It seemed odd to me, because the idea of maps were so in my head then, while this kind of stricter document definition felt weirdly like an obfuscated round of "fill in the blank".

Conversely, JSON is actually stricter - in the sense of it STRONGLY suggesting that keys of a map should be unique. It guides you to thinking in terms of maps and ordered lists (it's kind of interesting that there's not a strong concept of an unordered set in it, but obviously the interpreting system is free to ignore or embrace the order given.)

Still, I think a lot of the vehemence come from engineer's gut feelings, rather than any small set of arguments. Probably some of the same people who dislike duck-typing are more likely to prefer XML's style of strictness, and the ability to verify the semantic completeness of a document before having code interact with it. (Also worth checking out is stuff like my friend Leonard Richardson's O'Reilly book "RESTful Web APIs"; I suspect he feels the rise of JSON is a bit of a step backwards, in terms of making information available to all, and understandable by automated systems, and so he's interested in best of both world approaches that have the strengths of a JSON foundation while adding in some of the missing meta- aspects that tell you what you're actually looking at.)

You know I see a lot of the points I make here are often well covered in the comments of that Stop Comparing JSON and XML article. It's nice to have allies!

Wednesday, July 12, 2017

the robotic ruler of the river of no return

River Raid was one of the finest games produced for the Atari 2600. One of the first vertically scrolling shooters, this game was remarkably well designed. While the enemies (copters and boats and later small jets) could only threaten the player with menacing kamikaze moves upon approach, the constantly diminishing fuel supply would lead the player to recklessly hightail it down the "River of No Return" to pass over replenishing fuel depots, a tension-provoking detail most other games of the era couldn't match. And I am going to introduce you to the games indisputable conqueror.

First, a note about the game's author, Carol Shaw- the first professional female video game designer. This game is her singular masterpiece (I don't think many people really look back that fondly on "3-D Tic Tac Toe", and the 1-on-1 Pong-like action of her "Polo" tie-in game never saw the light of day...) This interview has her talking about her experience. But her peers thought she was great, designer Mike Albaugh said
I would have to include Carol Shaw, who was simply the best programmer of the 6502 and probably one of the best programmers particular, [she] did the [2600] kernels, the tricky bit that actually gets the picture on the screen for a number of games that she didn't fully do the games for. She was the go-to gal for that sort of stuff.
As a guy who wrote an original Atari 2600 from scratch in assembly , I know how tricky that kernel stuff is... (and true confession, my game ended up having its kernel tweaked by genius Paul Slocum anyway.)

One of the cleverest bits of River Raid is its use of pseudorandom number generators to generate section after section of the river - this let the game pack in a consistent, huge game playing field even though the whole cartridge was only 4K bytes of ROM. The levels alternated between straight sections and split sections and went on practically forever.

Over a decade ago I got to wondering about how far the river went, and got so far as having B. Watson generate this image of the first 4 sections, guaranteed to bring a bit of nostalgia to the 80's gamer heart:
(Of course the funny thing about posting this kind of image is that River Raid scrolls from the bottom, but webpages scroll from the top...) That project to map out more of the river never went anywhere, but this AtariAge thread gets revived from time to time... and I would say, the indisputable Ruler of the River of No Return (and one of the participants in that thread) is one "Lord Tom"

For starters, here's Lord Tom's map of the first 600 river sections...

And how does Lord Tom know what the first 600 sections look like? I contacted him at AtariAge (such a damn fine resource!) and he said
To make the map, I wrote a Lua script for use in the BizHawk emulator that essentially cheated through the game with the plane offscreen somewhere, taking screen-shots of each enemy/terrain slot along the way (32 per map section). I assembled these into the big map with a simple Java app.
But that wasn't enough for Lord Tom. He's a member of the "TAS Community" - Tool Assisted Speedruns, folks who learn how to let machines help them drive through to the ending of games faster than any human ever could. They don't cheat - the actual code of the game is sacrosanct - but by abusing every input available to them they're like the crew of the Nebuchadnezzar getting ready to dive back into the Matrix, mastering the code behind the world that lets, say, Mario move like a crazy drug-fueld Ninja, or in Lord Tom's case, to build a frickin' robot to play the game better than any human (or 'bot) in history ever has. Specifically, to get the maximum possible score of 1,000,000 (or in Activision speak, !!!!!!) That looks like this:

To give that robot a script, he built a replica of River Raid in Java, one that could reproduce all the twists and turns and boats and helicopters and fuel tanks that that little cartridge's algorithm could churn out with incredible precision, and then used it to power something like the "Many Worlds Interpretation" of Quantum Physics, plotting out a millions of possible futures for each frame, then pruning and working the best 150,000 or so, until he got a damn near optimal path. (And to give you an idea of this robot's skill about this, not only does this well-nigh perfect path take an hour twenty to get to that million points, Activision would send you a patch designating you a "River Raider" if you sent in a photograph showing that you got 15,000!)

So, in his own words:
Yes, due to the technique I used for solving the game, I had to write a Java simulator, which I think ended up being something like 10,000 times faster than trying to do the bot computations through the emulator. And I only simulated the game's logic/state; I didn't actually output a display or sound, though in the grand scheme of things that would have been easy enough to do.

The solving algorithm focused heavily on fuel and (of course) score. Since fuel is consumed at the same rate regardless of speed, it's best to almost always go full throttle. There are a few terrain exceptions, and the other main exceptions are slow-downs to get extra fuel or manipulate which enemies move/don't move to make them easier to kill.

For fuel, I basically looked at the map and plotted out how far I'd get for each life (once fuel becomes rare, it's better score-wise to die for a full tank than to keep slowing down to milk depots). Then for various points along the route (e.g. section 5, 10th enemy) I'd specify a minimum fuel to have -- any solution paths with less fuel would be killed.

The only non-survivable states in the game relate to fuel, and then very limited times when e.g. you can't slow down fast enough to clear terrain, or avoid an enemy that's about to hit you.

Other than that, it was pure heuristic; 30 times a second it would simulate paths with each possible input, eliminate duplicates and deaths, and periodically score them and keep the best several thousand. To handle islands, I stipulated that a certain # of paths would always be kept alive on each side of the screen. As I recall, the algorithm would score and cull several times each section; it never really "looked ahead" at all, just periodically compared outcomes for 500,000 or so input possibilities and kept the best ones.

I think all in all, I calculate the bot simulated over 2 trillion game states to complete the game. 
You can read even more details at his TASVideos Submission Page, but I think you get the idea here.

Amazing. I've done Atari coding and even some Java-based "tool assistants" (to get photorealistic images into the long-lost site pixeltime, or to remove the scrolling credits from still backdrops) but nothing that comes ANYWHERE NEAR what Lord Tom (or Carol Shaw, for that matter) has done.

the end of the genius bar

The Cambridgeside Galleria is a surprisingly durable shopping mall undergoing a makeover. (I assume to make it look less 90s brassy bling and more Star Trek/Apple Store-ish) Their Apple Store just reopened after a long time closed for renovations and expansion. Now it looks like this:

There's more tables, better use of the sidewalls for product display but, most strikingly: no Genius Bar at the back. They do have a bunch of these little cube stools:

and you can see one of the Genius-y worktables in the back, the worktables are where they actually do their magic. Reports are some of the idea is to remove that old counter as a barrier, and literally get the Genius on the same side as the customer.

It's an interesting idea, and maybe a gamble to get rid of that visible base of support. I've long thought that the Genius Bar was the secret sauce, the "unfair advantage" Apple sported its rivals Android and Windows. Microsoft has most obviously started to follow Apple's lead with its own stores, but since it doesn't control the hardware as much as Apple does, I wonder if it feels like more of a mixed bag. And for Android? The people at the various carrier's stores never seem like they're going to be quite as focused or with it as the Apple folk, though I'm sure some are quite good.

Monday, July 10, 2017

what's new with you?

At work I got to thinking about that if there's an international icon for "NEW" that doesn't use icons (new as opposed to used, obviously a plus sign is pretty common for "add another")

It reminded me of an old videogame, Captain Blood, where you had to travel a galaxy communicating with aliens, but you could only pick from a bank of 28 pictograph icons...
Interesting concept...

Thursday, July 6, 2017

porchfest poster cheats and tweaks

So this marks the 4th year of be doing the web (and print) work for the Jamaica Plain Porchfest.

Like I said last year, I'm not a print designer but I play one on the web - last year's innovation was splitting the collection of porches north and south and putting a map and performance list on either side of the print map, rather than having a big map on one side and making people flip flip flip to see who was playing where in the block schedule.

In general, this year's print map looks fairly similar to last's...

This year my energy was directed into making most of the website reusable on a year-after-year basis. Prior to this, I would start with a more or less blank slate and then copy in old files as needed. Also I tended to have all the data lumped in the same set of folders as the content. I knew I could do better.

The core of it is still good, reliable, rugged JSON files in directories, but this year I moved them (and the band photos) to a separate root folder from my main content, and so now every script looks at  a hidden ".dbroot" folder containing the path to that year's data.

I address one big usability issue: in prior years I had the webpage and poster number porches on a strict North to South basis. This had a big flaw: it was hard to follow when  sometimes house "n" would be way on the east side but house "n+1" would be on the west, and then house "n+2" would be back to the west. I wanted a more human-friendly way of clustering things, so a group of houses consecutively numbered would all be near each other. I wasn't feeling smart enough to teach a computer to do all that clustering work so I hacked an existing map display page so I could click each house in order, and that would assign it its number. (This will also make it easier to maintain ordering if a porch is added or removed late; the people running the event consider it important to keep the porch numbering on the print maps consistent with whatever is online, which wouldn't happen if the computer was reassigning numbers based on latitude every time the page loaded.)

Another issue is that sometimes one address is supporting multiple events, or maybe it is hosting musical performance (marked by an orange house icon) but is also one of the event sponsors (marked by a yellow circle with a letter). Previously I then made a new type of icon (yellow house) but this year I realized it was better to just adjust icons' positions, so they were abutting on the map rather tha overlapping. It's not like they icons need to be precise, we're not targeting drone strikes, just making sure people get to the right side of the street in the right area until they can hear and follow the music themselves.

I'd "cheated" latitude and longitude years prior for similar reasons, but it was a serious pain in the butt...  a single degree of latitude change is about 70 miles, so to make "one icon over" adjustments on a map you have to deal with thousandths of a degree, and it was terribly fiddly. Also it's hard to translate from x and y (i.e. what I'm looking at on screen) into Lat/Long, especially since North America is in the negative Longitudes, and I the developer would have to remember which way was positive and which was negative. BLEH!

So in my JSON database, I added a "xycheat" field as an array of two numbers which was then read by code like this
   var cheat = location.xycheat;
     location.long += cheat[0] / 2500; -= cheat[1] / 3500;

Those values meant xycheat = [1,.5]; would move a porch roughly one icon worth east, and half an icon's worth south. Much easier than the "tweak a value in the thousandth of decimal, reload, check where it landed, repeat".

Finally, I almost got bitten at the last minute by bitrot. Lacking print tools or the know how to use them, I tend to assemble the parts of the print map on a big webpage - map and block schedule, and then finesse the assemblage by hand. To get it at closer to 300 dpi for print vs the 72 dpi web standards are based on, I put a "zoom:3" on the body, then (as I described earlier) use the headless browser Phantomjs to make an oversized screenshot.

This year - and of course this is all at the last minute when I assume I'm on the finish line... phantom didn't work. I was getting

Assertion failed: (_consumed <= scratch_size), function _hb_coretext_shape, file src/, line 764.

No idea. Luckily downloading the latest version fixed it (I found it a little easier to get the latest via their download page rather than homebrew where I loaded it before.)

Once that was settled I was still getting this error:
ReferenceError: Can't find variable: google

Not sure if it was tied into me using https on all my sites now or what, but googling I found 
./phantomjs  --ignore-ssl-errors=true  phantom_view.js 
which seemed to fix it. Phew! I'm not sure what my plan B would have been - maybe just coping with screen resolution print - highly suboptimal.

The final site is looking a little long in the tooth (especially from the inside... panicked coding every 4 years doesn't always lead to the best engineering)  despite the still pretty decent mobile support. So next year maybe I'll focus on clean up, or even try (maybe) making some kind of app, though android support is going to be a pain for this Apple fanboy. 

Friday, June 30, 2017

feel over appearance

As you've probably been made aware, it's the 10th Anniversary of the iPhone going on sale.

I was a first week early adopter (I accidentally drowned my Palm device and cellphone kayaking on July 4th, and the timing seemed fortuitous.)

Slashdot's Coverage (speaking of things that may also seem like history) linked to John "Daring Fireball" Gruber's iPhone First Impressions.

As he mentions, probably the biggest lack in the first device (other than, arguably, the app store) was copy and paste. That was an interesting choice to punt on, to let it wait until a future generation of the product could get it right...

One of the biggest "WOW" factors though was the web browser- especially the scrolling which he describes as:
Real-time dragging is such a priority that if the iPhone can’t keep up and render what you’re dragging in real-time, it won’t even try, and you get a checkerboard pattern reminiscent of a transparent Photoshop layer until it catches up (typically, an instant later). I.e. iPhone prioritizes drag animation over the rendering of the contents; feel over appearance.
As the hardware has improved I haven't seen that checkerboard in a while, but yeah- it felt SO GOOD, the perfect compliment to how the capacitive touch screen was allowing much more vibrant finger interaction than the stylus-or-fingernail screens that came before it.

Thursday, June 29, 2017

parkie redux

There's some old line about "I'd rather spend hours writing a program to figure something out than ten minutes with a pen and paper"...

Anyway, a while ago I wrote about Parkie, a micro-webpage I made to calculate which side of the street I should park on.

Recently I updated it to cope with my new parking circumstance, with rules like "first and third Wednesday park on even side, second and fourth Thursday park on odd side".  (This is more complex than the rules in Boston which at least always did it on the same day of the week) as well as making it sort of customizable... if one person writes me that it would be useful for them, I'd make it so its config block

    restricts: [
        {dayOfWeek: 3, nth: 1, avoid: 'odd/our side', gofor: 'even/other side'},
        {dayOfWeek: 3, nth: 3, avoid: 'odd/our side', gofor: 'even/other side'},
        {dayOfWeek: 4, nth: 2, avoid: 'even/other side', gofor: 'odd/our side'},
        {dayOfWeek: 4, nth: 4, avoid: 'even/other side', gofor: 'odd/our side'}
was readable from the URL, as URLencoded JSON.  Until then I have to assume this will only be useful to me and my girlfriend so I won't bother.

The code is, admittedly, kind of nightmare of side effects and general poorly structured bullcrap. (Which is too bad, date calculations are kind of an awesome candidate for unit testing). The general question "which closest upcoming date (inclusive of today) matches a '1st/3rd Wed, 2nd/4th Thu' kind of rule?" is tricky! My approach was to take all the rules as outlined in "restricts", calculate which day of the month each represented for the current month, then walk forward from today to see which one matched first. (And being willing to jump to next month if need be...critical for the end of a month that ends on a Tuesday, say...)

So it's Vanilla.js. Besides using console.write(), kind of a forgotten way of constructing a page, The CSS used vviewport percentage widths for the character size, which got me nice, screen-filling (if a bit brutalist) results without fiddling with viewport stuff. (In this case the unit is 1/100 of the screenwidth, so 6 or 7vw would get a nice number of characters in per line.)

Wednesday, June 28, 2017

against the fixed position

Daring Fireballs has had some anti-"dickbar" ranting lately (social media "share me share me!" widgets, often fixed in place -- this one on best practices for sharing (tl:dr; emphasize sharing via the site the person CAME from) has a side note
You read that right: adding a locked toolbar to the small-screen experience shortened sessions and reduced page views. The very small increase in share-button usage was far outweighed by reduced site usage. (I can't explain why this is the case, but I've seen it elsewhere with locked toolbars, too. They chase small-screen users away.)
That jives with some "surprising" A/B results we found at my job, where we though permanent "Contact" buttons at the bottom would get more hits- some of our competitors were using them, so they might be a good idea, but apparently irritation from users at the sacrifice in free screen real estate overcomes the "hey look at this!" factor.

Wednesday, June 21, 2017

google maps style customizer is kind of a "style roller" for Google Maps. I like the "retro" style especially, and it's the easiest way to, say, hide business names or what not if you don't want them cluttering the view you're making.

on mac modifier keys

"Hot Take" time!

Ok, not that hot.

With all its dandy ports I still think my Macbook Air is gonna remain my main personal machine for a while, but I was still daydreaming over at, and I noticed both the "Adorable" Macbook and the new Macbook Pro have much better iconography for the modifier keys- displaying the ^ over control and the weird broken equals sign for option, so that both of those join command key and its little clover in actually showing up on the physical keyboard the same way they do for the top of the screen menus.

 A definite improvement! But it raises the question, why are Apple's modifiers keys such a hot mess? Don't get me wrong, it's a pleasure to be back in a shell and have cmd-c copy and ctrl-c break, but really, fn, control, option, command (not to mention shift) - so often arbitrarily thrown together in strange combinations by various programs for random shortcuts.

Windows had a much more coherent strategy (despite its weird legacy of "alt-f4", and various exceptions in various software titles) - there's only three keys down there, really: the hubristic "windows" key, control and alt. And control keys usually are tied into commands meaning "do this now" and the alt key was tied into menu pulldown shortcuts.

I suppose this disdain for keyboard menu operations flows from the Mac history of relying on the mouse; remember, the first Mac lacked even arrow keys, and there's never been the same menu pulldowns via keyboard that Windows has enjoyed.  But it's weird they went from such minimalism to such a multi-key mess.

Tuesday, June 20, 2017

github note - ignore whitespace

When doing a Pull Request via github you can add a ?w=1 to the end of a url e.g.  https://YOURCOMPANYSITE/BRANCH/pull/1785/files?w=1

Monday, June 19, 2017

tribute to two meta-artists

I've always liked software that let the user make something - from Bill Budge's Pinball Construction Set to the make-a-game fun without programming Klik N' Play, there have been some great examples of that over the years.

I want to write briefly about two creators, Toshio Iwai and Takeo Igarashi both of who made original UIs letting users exercise their creativity. Each creator's work was then used in separate commercial products in the 90s and 00s, products that deserve more recognition than they get.

Toshio Iwai is a multimedia artist. He may be best known for Electroplankton, a fairly early but very limited release for the Nintendo DS- his name appears on the packaging for it, an unusual-for-Nintendo recognition of singular artistic creation.

Electroplankton is not quite a game, not quite an instrument... it consists of ten different interfaces for making music and sounds of various types...

This was not Iwai's first multi-part collaboration with Nintendo - that would be the 4-part Sound Fantasy. One of those parts was based on his earlier work Musical Insects. This concept, 4 musical bugs, each one playing a different instrument that sounded at various pitches as the bug waddled over different colored tiles laid out on a blank canvas, got parlayed by Maxis into a nifty package called SimTunes. I guess this trailer gives you the overview about as well as anything:

This program was a terrific and playful mini-sequencer and paint program. Kids and Adults could focus on the sound, the look, or both. Just out of college, I remember setting it up with versions of Groove is in the Heart and "Alphabetter", a replacement for the alphabet song that I hope catches on but I'm sure never will. I appreciated that it had different palettes - for example, limiting the painted notes to a specific scale or modality, such as my favorite "Blues Scale" and an aspiring kid or adult could easily apply music theory they had or learn something new.

More recently Iwai collaborated with Yamaha to make the Tenori-On, a sequencer grid of lights. (I was almost ashamed at using a ThinkGeek knock off called the Bliptronic 5000, 'til I realized it was about 1/10 the price... and about 1/10 the functionality, but still.) I also found this overview of his art installations.

Takeo Igarashi seems to be more of a computer scientist than an artist, but his UI implementations are at least as impressive.  His academic homepage is of the ancient variety, and sadly most of his demos are a serious pain to get running in this day and age where Java on the desktop is all but forgotten. Still, his Smooth Teddy interface is remarkable; the user draws basic 2D shapes that then get rendered into 3D shapes.

The most straight forward descendent of the "Smooth Teddy" family is MagicalSketch 3D for iOS, a somewhat pricey (by app standards) tool, but one that promises to be an easy path to modeling for 3D print. (I haven't played much with Microsoft's "Paint 3D" but I think they would be well-served licensing out the core model.)

The finest rendition of this concept, however, is Magic Pengel: The Quest for Color for the Playstation 2. I feel it's a shame it didn't go by a more direct translation of its Japanese name, "Doodle Kingdom", because this project (a joint production with some collaboration from Studio Ghibli (of "My Neighbor Tortoro" and "Spirited Away" fame) deserves more attention than it ever got. (A "Pengel" is a Pen-Angel, I think a little helper sprite in the game. I'm not sure to whom they were trying to market with a name like that.)

Because not only can you doodle in 3D - your creations come to surprisingly charming life. Here's a Let's Play of it:

The editor works by letting you indicate what you're drawing (body, arm, wing, etc) - this knowledge is then incorporated to inform various animations (Walk, Tackle, Jump, Dance, etc) and the effect can be stunning- here's what a talented artist can make with its editor:

It's so delightful to sketch something out and then have it frolic around the "practice field".

Unfortunately, the game is horribly marred by ... well, too much game-ness. In some ways the body you construct doesn't do much to determine how your creation interacts with its virtual physical universe, it's just raw numeric material for a probability based monster battler ala Pokemon, with Rock-Paper-Scissors type strengths and weaknesses. Also, they limit the amount of "ink" you have to draw lines with, and then make the game about fighting monsters so you can get more ink to make your own creations that much more powerful, rather than creative.

There was a semi-sequel for the Game Cube called Amazing Island and one for the PS2 called Graffiti Kingdom. I remember getting absolutely stuck early on in Amazing Island and some utterly crap minigame, and if memory serves, Graffiti Kingdom tried to codify its editor too much, and lost much of the organic charm of the original.

Finally, I'd like to make one honorable mention for a game with a kind of brilliant editor built-in (though I don't believe there's a singular artistic vision behind it) - Banjo-Kazooie: Nuts + Bolts:

 This is by far the best "game" of everything I've talked about here - it starts with a gorgeous Mario 64-esque hub (looking like someone said "what if we ran all those pretty colors of the N64 into the kind of engine we can make today?)  with all these delightful themed subworlds, but each as if you can see the gears behind the walls work. Each subworld has multiple challenges that you build various vehicles to beat: cars, of course, but also boats and planes and flying balloons and sumo-karts etc. At first I thought all the creations were ugly and orthogonal-looking (VERY reminiscent of the old Capsela toys) but then the delight of making a car where the design really matters in a cartoon-physics kind of way takes over (and you can put on enough bolt-y bits to improve the look quite a lot.) And as you get more parts (there's that game-ness) you can go back and try for higher "medals", but the challenge level is generally well done, and the level of backtracking needed is negligible.

(And a small group of super-hard-core fans have really stretched the editor system to the limit, making these absurdly heavy jet-powered walking mechs in a game that was never meant to have any such thing...a joy to behold.)

Anyway, I love stuff like this, making a easy enough for a beginner but rich and engrossing enough to reward continued play (rather than a quick doodle and a "meh") is a tremendous feat. (Though I did once get a few people digging my own online Jack-O-Lantern maker) Both of these people and their works (and Banjo-Kazooie) deserve much admiration.

Tuesday, June 13, 2017

quick css throb effect with vanilla js

For a long time, I've been meaning to get back to the 30 Day Vanilla JS Coding Challenge. I learned a lot from the very first lesson even, which is a nifty little drum kit. Here's a kind of "throb" effect I picked up and modified from it, uss CSS transitions and transforms for scale: click the blue div to see it work...


Here's the code for that, most relevant bits bolded:
  #css_throb_button {
    padding:4px 20px;
    transition: all .1s ease;
  .throbbed {
    transform: scale(2);
<div id="css_throb_button" onclick="css_throb_test(event);">0</div>
  var css_throb_count = 0;
  function css_throb_test(e){
    var panel =;
    panel.innerHTML = ++css_throb_count;
  function css_throb_removethrob(e){
    if (e.propertyName !== 'transform') return;'throbbed');

  document.getElementById("css_throb_button").addEventListener('transitionend', css_throb_removethrob);  

So a couple notes:

  • there are a few ways of removing the class. You could also use setTimeout, but this is nice because it keeps you from having to confirm the timing (as set in the transition) in two places.
  • the scale transform doesn't work on inline elements - so when I started with a "span", I couldn't see the transform effect until I changed it to display:inline-block...
  • also to keep things simple I'm not doing anything special for making sure the document is ready, so I had to put the script tag after the div element in the page so the getElementById() would work
I like how it zooms in place. There are ways of tweaking the timing, size, and easing, but this seems like an easy way of getting attention to the element.

Friday, June 2, 2017

Thursday, June 1, 2017


A sysadmin-y friend of mine has helped me use Lets Encrypt to get my https mojo working on my virtual server.

One problem is that a page loaded on https referencing external scripts over http break.

One flexible fix for that is, with most of these URLs, the protocol can be left out, so instead of changing http:// to https:// I sometimes change it to // -- what we used to call wak-wak a few jobs alone. In effect your saying "load this with whatever protocol this is loaded". I guess it will break if the underlying site hasn't gotten around to offering https though...


from Pierre Buttin's Brutalist UI Redesigns:

I kind of love some of these. It reminds me of the same problem I have quantifying what exactly makes an old website look old.

Friday, May 26, 2017

css children

Nothing too rocket-sciency, but I decided to try messing with CSS for showing and hiding things based on if 1, 2, or 3 buttons are showing, rather than using scripting logic: the first one shows something different if the button is the only one, the second set is a way of saying "I have exactly two things here" (in this case, if there's only a single button it's not the one I'm worried about"

 .fixedButtonBar .fixedButton:last-child{
   border-right: none;

 .fixedButtonBar .fixedButton:only-child .multipleButtonCaption {
   display: none;

 .fixedButtonBar .fixedButton:not(:only-child) .singleButtonCaption {
   display: none;

 .hideWhenCramped {
   display:none; }

 /* when exactly two items */ 
.fixedButtonBar .fixedButton:nth-child(1):nth-last-child(2) .hideWhenCramped,
 .fixedButtonBar .fixedButton:nth-child(2):nth-last-child(1) .hideWhenCramped {

  /* when exactly two items */
.fixedButtonBar .fixedButton:nth-child(1):nth-last-child(2) .showWhenCramped,
.fixedButtonBar .fixedButton:nth-child(2):nth-last-child(1) .showWhenCramped {

I guess it might be a little too clever-clever. I liked it over the scripting approach in part because I would have had to repeat calculations to count which buttons were showing, but I'm not sure this css states its intentions very clearly

Thursday, May 25, 2017

sending via gmail smtp

Just some quick notes, nothing canonical:

I was trying to use PHP's built in mail, and my server's sendmail, and stuff to my work address arrives but stuff to gmail just got devoured; I guess they don't trust my server even enough to stamp stuff Spam!

I install Pear Mail and the NET_smtp thingy, and then I had Allow Less Secure Apps - and I think maybe Display Unlock Captcha.

Not crazy about having my private password so close to my source code, tbh.

Monday, May 22, 2017 of...

Helped my GF make up a version of Jeopardy for an ice breaker for her company using GameshowMaker (this newer version has a few skins to make it look like various other shows as well.) A little old, and some of the setup is fiddly (and kind of weird, how like the show-specific .ini file you load in for the skin overrides the settings you have in the main setup, and also by default the space allotted for Category names is WAY smaller than Jeopary standard) and it's all Flash, but still, if you need a quick thing that can be run locally or online, it is pretty solid.

Friday, May 12, 2017

when character encodings attack!

Last year I made up a new one-page-app version of the Somerville Porchfest Site, and it survived the onslaught of people hitting the site that day, unlike in previous years.

This year I ran into weird late minute problems as they changed how my files were served up. One was that the "bands.json" file was somehow turned into a html redirect message. My hack for that was to have the process that cleaned the JSON prepend a "var bandjson =" to it and then include the file as .js

But then things were still crashing and burning Autolinker.js, or rather. Autolinker.min.js , was crapping out in the console, with an "Uncaught SyntaxError: Invalid regular expression:" followed by a whole lot of goobly-gook.

Long story short the problem wasn't in how Autolinker.min.js was served, but rather the encoding used in the index.html page. When I got my apache server, it had the default of UTF-8 for everything in the headers, so it had a line like
Content-Type:text/html; charset=UTF-8
But their server only had text/html.

Adding this to the <head> seemed to fix it:

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
seems a little weird this can be fixed either as a server config or a page thing, but that's the way of the world.

Thursday, May 11, 2017

the allure of facebook

I was thinking about the allure of Facebook. Previously I attribute it's dominance to a combination of "stream/wall" (ala Twitter, Tumblr, Instagram) with real identities, a strong bias to guide you to connect with people you know in real life vs anonymous internet strangers. But there's something else: the "also commented on X's post" notification. I just now posted a second comment on friend's post on feeling blue and the seemingly masochistic desire to watch or listen to sad stuff there, two passages relevant to the topic (this passage and the Mr. Blue thing it links to) and it feels great that I know people interested in that topic will get a nudge and probably see what I put there. Old school web forums have this feature but they don't have the stream that brings content front and center, or the "real world friend" aspect.

(Heh, I remember when I would read Usenet on an old academic account, I had a perl script that would scrape and find me continuations of threads I had participated in.)

Wednesday, May 10, 2017

unpaid plug - testing old browsers with ease

My company started using BrowserStack, that looks like its giving a full-browser-screen pass through to a little VM to test old browsers without setting up the damn OS. Super easy to use.

Also, I wrote their support suggesting that dialog would be improved with tooltips showing what % of the market different versions are, and what year the browser came out.

w3schools browser info shows that - wow, IE/Edge and Safari are both separately less than 5% of the traffic? Huh, wonder if that is desktop only though... I know a lot of companies see about a 50/50 desktop/mobile split, with mobile on the rise...

Tuesday, May 9, 2017

k.i.s.s.: too long command lines in bash etc

So for my porchfest work I was making up a thumbnail using ImageMagick, but there were so many files I was running into errors since it was bigger than whatever buffer bash was using. I thought I'd have to learn xargs or something fancy... But then I realized I could just make a bunch of short lines, each ending with a \\ and then a \n , and that copy and pasted fine.

Monday, May 8, 2017

a rant against arcane js syntax

Elements of JavaScript Style -- I'm having trouble wrapping my head around #2 there, "Omit needless code", where
function secret (message) {
  return function () {
    return message;
is considered blatantly inferior to
const secret = msg => () => msg;

I remember one of the reasons people starting dumping on Perl (and just dumping Perl) was because of arcane syntax...  I think there's a strength in looking like other languages.

Concise code is critical in software because more code creates more surface area for bugs to hide in. Less code= fewer places for bugs to hide = fewer bugs.
Concise code is more legible because it has a higher signal-to-noise ratio: The reader must sift through less syntax noise to reach the meaning. Less code = less syntax noise = stronger signal for meaning transmission.
This reminds me of a scifi story that talked about an alien language that was SO EFFICIENT that they could say in a single, accented, nuanced word what a human would need to say in a sentence or a paragraph.The trouble is that kind of sci-fi think misses the reality that redundancy in a language is a feature, not a bug; for example, it means the meaning is likely to be preserved over "noisy transmission" - like when someone isn't paying full attention, for example, or when fidelity over the wire isn't perfect.

I guess some of the problem is the trivialness of the currying example - even without the syntax that will be less familiar to people steeped in other languages the need for a curry (mm, curry) is a little arcane to begin with - and in this example, it's not even clear where functional code would sit! Like if the original was
function secret (message) {
  return function () {
    return message.split("").reverse().join("");

A coworker says that would boil down to

const secret = message => () => message.split('').reverse().join('')

There's something anti-egalitarian in use of this much bleeding edge syntax.