Saturday, April 28, 2018

operators overloaded - perl golf and the new syntaxes of ES6

I just got done with some good React Training with Michael Jackson (the developer of react-router, not the deceased king of pop.)

I want to do some Grumpy Old Man Complaining, but first some Grumpy Old Man Nostalgia: for Perl, the hacker's friend glue language of the '90s.

The world has moved on from Perl, but I will always be grateful to it as my first introduction to 5 hugely powerful concepts - maps, automatic memory management, first class strings, regex, and loose (duck) typing - all things big in modern js programming and all things that university Programming 101 C  didn't have.

(And later, I could put Perl on cheap rented webspace, and was able to personally do just about anything that could be done on server and browser of the time - empowering!)

But Perl hard a dark side - often gnarly syntax that could let you make "write-only code", inscrutable to any poor sap who had to try to update it (maybe your own future self). The apotheosis of this was Perl Golf where people would use the intricacies of the punctuation to make the shortest possible program to solve a task.

I think that thinking is some of what killed Perl. And it didn't have to be that way! You could write in stodgy old verbose styles and keep up maintainability - I have some bits on my server that I literally wrote 20 years ago, still chugging merrily away, and when I have to update it... well, it's not great since I'm so rusty at it, but it's generally easy enough to absorb the intent of my past self.  (Vs Perl Gold that was inscrutable as soon as it was written.)

So, fast forward to the mid '10s. I sometimes fear Javacript/ECMAScript is going down the Perl Golf road. Or at least, you have too few symbols playing too many roles, and so all this code becomes very context dependent.

The hip coders frickin' hate wordy anonymous function(){ } everywhere, so the premier improvement is being able to write
var addone = function(arg) { return arg + 1; }
as
let addone = (arg) => { return arg + 1; }And I kind of like that.... => is a nice visual pun that emphasizes the transformation that is so critical to functional, side-effect-free programming.

But that wasn't enough for the hip coders, because they want this kind of anonymous value transformation function to be some common and instinctive that if there's just one argument, you can drop the parens to the argument.
let addone = arg => { return arg + 1; }

This is where they start to lose me. I guess when I read it I tend to see the "addone = arg" as an assignment chunk first, but the important grouping is the "arg => { return arg + 1; }".

And then to make it better, or worse - we dropped "function", if we are just doing one thing we can drop the "return"!
let addone = arg => a + 1;
So on a toy oneliner, that's easy enough to read, but since the whole point is who smoothly this stuff can be embedded in more complex operations... you really have to be on your toes. Everything is much more context dependent than it used to be. (Which is kind of ironic for a system that embraces modularity and being side effect free.) I hope as I get more fluent in it, this will be less of a problem and I'll get the benefit of thinking of the lil function as a singular unit.

So what did the hip coders do with all those curly braces they saved up? Object destructuring!
let o = {a: 42, b: true, c: 'haha'};
let {a, c} = o; 
//now you have a and c to work with as local variables
//and showed your disinterest in  b

I kind of like this, and love how you can turn the JS trope of "this function's argument is a single map of lotsa keys" into something that lets you use plain old local variables, but- ambiguity is growing. A lonely {foo} might be either an argument destructuring, or a return value for a fat arrow function. You can't know without investigating around it.

So we have a "{" that might be
  • starting some good ol' JSON
  • a function or conditional block, 
  • or a bit of object destructuring, 
  • or (in the JSX that React loves) wrapping a simple expression that will explode if you put in the semi-colon,  

and a "(" that might be
  • wrapping arguments for a function, 
  • or a conditional for an if  
  • or a grouping in general
And a ":" inside curly braces

  • Simple key value - let myMap = {key:value}
  • Destructure with rename: let {newVarName:oldKey} = oldMap


I did a bad regular experession and tried to find the most heinous examples I could in the React Training materials, I came up with
          <Route
            render={({ match }) => ( //...
the first { is JSX saying that's an expression, the ( starts a fat-arrow argument, the next { is doing some destructuring... and the final ( is starting an expression for the invisible return statement. 

Oh of course the ... is just my placeholder in a comment, it isn't the spread operator... (Jackson sometimes used ... and I wasn't always positive which he meant.)

To be clear, this is complaining isn't me trying to kick against which way the wind is blowing - while I have reservations about modern UI toolkits being such a moving target, with a LOT of flavor of the month and "welp, here's the new version, hope you didn't set up npm or yarn to automatically pull the latest" (I have 18 year old Perl code going merrily along, but my 18 month old React experiment had to be rewritten) and I'm a little nervous about building a long term structure on it. (Just the image of interviewing candidates in 2021- "yeah, sorry, our React is in that old 2018 style, we know, we should really refactor it but its too much to do at once, even with the unit tests.")

React is still pretty damn cool, and I think it's answer to the age old "how do we relate DOM bits with script-y bits" solution is good and relatively transparent, and error messages give you some idea of what you did wrong (which is more than I can say for my time with Angular)

My coworker Peter says, half-joking, we should consider using more punctuation to avoid this overloading, now that Unicode is a thing - like «french-style quotetation marks». (Kind of like APL used to do with "←" for assignment) I think this idea is a non-starter, cranky engineers like me barely remember to put in proper quotes in UIs, since inch marks and foot marks are good enough and can be directly typed on the keyboard.

UPDATE: my manager Eric came up with a good example. He slacked me
.map(({ id }) => id)code i just wrote, but then changed to .map(listing =>listing.id)because it’s so much easier to read the second way
He's absolutely right! And I'm not a total stick in the mud, I think the latter way is clearly better for thinking about and reading than
.map(function(listing) { return listing.id; })

Thursday, April 26, 2018

quote

"Our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed. For that reason we should do (as wise programmers aware of our limitations) our utmost to shorten the conceptual gap between the static program and the dynamic process, to make the correspondence between the program (spread out in text space) and the process (spread out in time) as trivial as possible."
--Edsger Dijkstra

react'ing to the need for a todo program

It is ironic that toy todo apps are a favorite way for programmers to learn a new toolkit, but I can't find the perfect real app, and may end up building it myself.  I've been daydreaming on the ideal app ever all the way back in 2005 (then I would have wanted it for the PalmPilot) and then 3 years ago I was taking a deep look at Apple Reminders as a possible substitute for AppiGo Todo, which I've been using pretty much since iPhones had apps. (I remember a big wall poster in the apple store showing the built-in notes app being used for a todo list, back before there was an app store or the default Reminders app - an odd reminder that the 2007 iPhone was a serious step down from the 1996 Palm in terms of being a PDA until Apple got its Appstore going.) 

AppiGo Todo is pretty good but gets several things wrong, and feels like abandonware. (At least the free version?) It has had a glaring bug in how it does attached notes for years, and I'm pretty sure they're they're never going to fix it.

In increasing order of importance, here's what I want in a Todo app but find hard to find, and would emphasize :

  • Snooze Button - dated Todos would have a simple "kick this can down the road" button. (Gmail is introducing this feature for its core web-based app)
  • Hot/Medium/Cold priority - it's a sad fact in life that there are worthy(ish) tasks  that I may or may not ever get around to, but I don't want to go away forever. A "Cold" priority, with appropriate filters so I'm usually not seeing them mixed in with the more pressing stuff, would be great. ("Hot/Cold Todo" is a possible name for this app if I ever make it) 
  • One Big List showing multiple categories - many programs have categories or tags, and just about every single one I've found either says "here's every Todo with every tag all mixed up" or "here's a big list of categories, please navigate into each sublist separately if you want to see the corresponding tasks".  I long for a unified list of categories, but with headers acting as visual dividers - these headers would be customizable per person. For me, they would mostly focus on where I am where they need to get done (home, work, online, store) with some special topics (bands, projects). Each category header line would have its own "add task" button. Ideally each task in a category would be manually sortable. Also, whole categories could be collapsed when it's time to focus elsewhere. ("Buckets" or "Starbuckets" would be another possible name for the app, if I thought people would recognize those as corresponding to GTD/Getting Things Done Bucket system) 
Recurring Todos are table stakes (with a "set up next reminder based either on the date the task was first set, like for a recurring bill, or for when it was completed, like get a haircut X weeks after I got my last one.) Date-based recurring Todos are especially tricky - ideally you want to be able to say "the 3rd Thursday of the month" as well as "3 days before the end end of the month" (like for rent).

I would also avoid the biggest UX misthink I've seen in Todo apps featuring sorted/dated tasks, namely that the more a task is "overdue", the more urgent it must be, when usually the opposite is true (it has been demonstrated that the task can slide a few days without major consequence!)  I guess this would be less of a problem in Appigo Todo if it didn't make the other misthink of "any task with a date is more urgent than any task without a date, so we're going to put anything without a date waaaaaaay at the bottom". So my life with Appigo is a big list of 20-40 minor things, most of which are technically overdue but it doesn't matter, and I always have to scroll down to where the recent and daily things are scrolling up.

I'd also love to make a web interface to get to my data - with stuff like Simplenote I've seen how useful it is to be able to use a computer keyboard to supplement the device that's always on my person. (It might be interesting to have a second mode of bulk editing as text, where lists could be converted into and back from a text memo format, like
Some Category
-a task
-another task
Some Other Category
-yet another task
could go back and forth. That reminds me that it would be great to be able to make subtasks, and handle projects thats way, but that doesn't seem as crucial to me as it once did.)

I'm in training for React now, and I'd like to look into React Native for making an iOS client. Here's hoping! But if I get it done it could be a real gamechanger for me.

UPDATE: The app 2do may cover enough of those things - especially the "one big list" one - that I maybe should just switch to that. It doesn't cover everything perfectly (and of course covers lots of others people's preferences that I'd rather not mess with) but overall seems pretty great.

Tuesday, April 24, 2018

git log -S : grepping over old commits

Today I learned
git log -S "someString"
which greps over lines in checkin - techinically it "Look for differences that change the number of occurrences of the specified string (i.e. addition/deletion) in a file." so if the number of invocations changed you might be out of luck...

cmd-k to klear the macos terminal

For decades I've used ctrl-L (or cmd-L) in a Unix shell window to clear the terminal screen.

Too often, however, I would press return a bunch of times so that when I scrolled back up there was a visual break showing where the start of the latest command's output...

The other day I learned cmd-K (the ctrl version doesn't work... and like I've said there are way too many modifier keys on Macs) - this clears the screen and the scrollback buffer, so such flim-flammery is no longer needed.

Tuesday, April 17, 2018

rant: worried about dependency culture

I am really losing my shit - er, I mean, my precious equanimity over being thwarted by the bad parts of npm/yarn culture. I burnt all yesterday tracing mysterious 404s from an artifact repository at work, and then for an otherwise fun art project, similar "can't find that file", based on my node version number and then some other "fsevents" crap that I don't even know how to find the version number of.

I know I have an over-simplified view of how things "could" be, based on
<script src="whatever.js"></script>
hacking being sufficient - but when I remember that 2016 event where one file deleted from the npm dependency tree - FOR A DAMN LEFT-PAD ROUTINE (amusingly, very similar to the hack I posted the other day ) - broke a thousand project - it really makes me wonder about  whatever the opposite of "Not Invented Here" culture is - the people who are like, well, even though this module would be 5 seconds to write, if I find someone else wrote it, I can just include it and then get a unit test for free!!!!!!!!!" I feel like this population never counts the cost of throwing in other people's code.

Monday, April 16, 2018

the joy of tiff

One of the adventures of making websites for porchfests is dealing with quirky tech things generated by non- and semi-technical musicians.

It's easy to come up with little petty gripes like "c'mon, people, it's a BAND DESCRIPTION not your frickin' album press release blurb"!

But here: some folks uploaded 2 versions of the same image (a simple "two headshots pasted side by side into a new image" with no attempt at photoshopping, just two non-matching-background squares) One file in TIFF and then a JPG version of the same thing. And resizing it with ImageMagick for some reason converts the JPG to a photonegative.

It raises interesting questions!
1. Who uses tiff? I feel like it used to be more popular in the 90s or something? Is it probably just some old tech being used, or does it have some niche use I'm unaware of?
2. What on earth would cause a simple ImageMagick "convert {} -resize 240x240" to flip it to a freaky photo negative?

This isn't meant to be snarky - I think every band that comes together for a Porchfest is awesome, and there's no "you must be this technical to ride this ride", but I really am curious as to the background story.

Monday, April 9, 2018

Saturday, April 7, 2018

good ux for print maps for porchfests and other many-performances events

I'm working with Newton Porchfest and got into this long-winded discussion of what makes a good non-interactive map for that kind of event...

(NOTE: I'd worked with the people of the neighborhood Porchfest I dig into here, and they resented it. For this unsolicited and specific criticism I am sorry and I have redacted the identifying information.)

For reference, I was able to dig up the printable material of another neighborhood's Porchfest and put a screen shot of the relevant bits here. The design of the original is great, higher quality than what I generally make, but it had some information flow issues that I thought would lead to a poorer experience for people going to the porchfest

Lets study what it does:

It's sorted by time - actually, I'd say "grouped" by time, into 6 or so color-coded blocks.

Within each time chunk it seems... sorted by address number I guess? With some exceptions, but mostly it seems to be in increasing street number. But that kind of sorting is well-nigh useless, since that's not how street addresses on multiple streets work, and most people won't know the address ahead of time anyway. So effectively, there is no band or porch sorting here, just grouping into time chunks.

So, first problem: there is no kind of identification, like an arbitrary number or other label, for each porch or band that would connect a band name and address back to the map. Once a reader finds a band they might like, they honestly probably have to enter the address into a GPS if they don't know the neighborhood, only a few streets are labeled.

Second problem: while I think there's some use to visually cueing what time block a performance is, I'm not sure the rainbow ordering carries the information well - (though I do dig its LGBTQ -community connection!) ROYGBIV, the rainbow order, only does a so-so job of saying "well Red is earlier, Orange is later, Yellow later, Green even later..." People don't know that intuitively, they have to think about it if they recognize the order at all

(Somerville famously has the porch location determine its timeblock, and so has a progression in east to west order- see https://somerville.porchfest.info/2017/ - the 3 colors aren't any more obvious then rainbow order, but the east-west migration helps make order of the chaos)

Showing time on the icons is a tough infographic problem! If there were few start times, I might say "early shift is black porch or performance numbers on white dot, mid shift is black numbers on gray dot, late shift is white numbers on black dot" - so at least there's a logical progression from light to dark that if people are seeing an icon the map, they might be able to guess when there's a performance there. You could do something with shapes as well?

Third problem: because there is no meaningful listing order, even if you know your buddies band name you have to skim the whole list to find them.

Final critique: there's a lot of repetition in the table. "Brookline, MA" appears on every line! Similarly, each row in a time block still says the time... 1:00PM 1:00PM 1:00PM 1:00PM. If you got ride of the city name on each line, and then labeled each time block (I could see maybe a BIG 1:00PM, rotated 90 degrees, along the side? Just spitballing), maybe then you could use a two column layout, and bump up the font size for easier reading...



Lets compare that to what I did for JP Porchfest. Probably the easiest to read description is on my developer blog: i'm not a print designer but i play one on the web.
My design has its flaws but I think I made some good trade-offs...

It splits the city North and South (arbitrarily - but after the first year of watching people flip the map over and over with the schedule on one side and the map on the other, this seemed better) and assigns arbitrary numbers for porches, also going North to South. Each porch number then is also a row on the block schedule, so each porch has its own row with the address and the bands playing go in chronological order, left to right.

So this poster assigns arbitrary numbers for porches, going North to South. So if you can locate yourself on the map, it's pretty easy to find a nearby porch number, then find that in the block schedule. And once you've done that, you can look around neighboring rows on the map, and see "what else is in this neighborhood that I might want to wander over and see?" -- because neighboring rows in the block schedule are more or less actual neighbors, and then time is in a logical order too, so you can plot a day without having a lot of travel (JP is pretty dang big!)

(In 2017 I improved my tools so things weren't 100% North South - like in 2016, Porch 3 might be on the west, but Porch 4, while technically the next one south, might be far to the east, then Porch 5 might be back west... so in 2017 I built tools to let me number porches by hand, into clusters... still North / South roughly, but higher chance of being in the same set of blocks if you're nearby in the block schedule)

What the JP Poster doesn't do is let you easily answer "hey I know this band is playing, where and when are they?" You'd have to skim the whole block schedule (and it's tougher to skim than Brookline's, because the blocks would make your eyes jump around) But once you find the band, it's pretty easy to find it on the map, since the porches are numbered, and in a North South order.

So, getting to what Newton might want to do; admittedly it would be a ton of work to do a JP-style block schedule by hand (the printmap is basically a giant screenshot of HTML I made) so I can either help with that, or we can get some of the same principles in a more list-y, less block-y view.

But whether block-schedule or list, ordering is amazingly important. You need to decide if your primary usage is:
1. I know a band! Where are they and when?
In which case you might want to a giant list of bands, each with the porch info there (the porch numbers will seem to jump around in the list though) - or you might want several lists of bands, the 12PM bands, the 1PM bands, the 2 PM bands, etc, like how Brookline does it but with the bands sorted in alphabetical order not the porches
2. I know where I am in the neighborhood? what's playing near me?
In this case the listing will be in north/south or east/west order (or chunked by neighborhood if you're feeling ambitious!), and bands will be in arbitrary order, so people will have to skim the whole list

I know for its first year [Some Other City] had both style of listings! (In theory great, in practice they didn't do a good job using numbers or letters or colors to let people take advantage of the good work they did.)

It can be challenging to make the block schedule, and also to make custom icons or whatever. I might be able to team up with a designer for this, I have some tools that automate certain things. Also there might be some "thinking outside the box" I'm not doing... like maybe bands should be numbered, no porches. And on the map, instead of an icon, you might see [5|12|20|31] Which would say band 5 plays at noon, band 12 at 1, band 20 at 2, band 31 at 3. That might be a mess! (And or if you had a HUUUUUUUUGE map you might able to put the band names right there. That's sort of what you get when you click on a porch at https://archive.jpporchfest.org/2016/ but of course that' web so things can be clicked)