Some time ago at work, one of our partner companies needed us to use an iframe because our users needed to type their usernames and passwords for their accounts with that partner into our website, but our partner didn’t want us to have access to those usernames and passwords. So they asked for the whole thing to be conducted in an iframe, served by them but embedded in our site, and then their iframe would pass a token to us, which we could use to query their site for the user’s information.
At first they tried to pass the token by having us implement a globally available function called “setToken”, and then once the user had typed in their username and password and the server had converted those into a token for us to use, they would call the “setToken” function in our page from inside their iframe, like so:
parent.setToken(token) |
And our “setToken” function would have looked something like this:
window.setToken = function(token) { // some code someDataStructureInOurSiteSomewhere[someUserId] = token; // some more code } |
(Note that we could have said just “setToken” or “var setToken” in place of “window.setToken” and it would have had the same effect for most intents and purposes — it would be declaring a global variable — but I like to make it absolutely clear when I’m polluting the global namespace, by explicitly stating that I’m adding a property to the window object).
Many of you will be aware, as neither I nor my counterpart at the other company was, that the above strategy won’t work at all. When two frames are being served from different domains, there are serious security concerns that prevent one frame from simply going into the other frame and executing one of its functions, such as “parent.setToken.” Not only can you not execute functions, you can’t even send messages in the form of strings. These are the same security concerns, in fact, that led our partner to insist on this iframe arrangement in the first place.
So what do you do if you need to pass information back and forth between frames being served from different domains? I did a bunch of research and discovered a crazy array of hacks to get around this cross-domain problem, most of which compromise security to one degree or another. They are well catalogued in this blog post.
But part of the HTML5 specification is a message-passing system intended specifically to address this very issue, centered around the window.postMessage method and its associated events. This method is supported by Firefox, Safari and Chrome going back pretty far, and IE back as far as IE8, which is all I have to support on the two projects I have going at work (and certainly in my own side projects).
Using window.postMessage, one frame can send a message to another frame as long as it can correctly identify the origin (the protocol plus the ‘//’ plus the domain, i.e. ‘http://www.somedomain.com’) of the target frame. The target frame then has to have a listener set up for ‘message’ events. The message event contains the message itself (which can be an object in decent browsers but must be a string if you want it to work in IE9 and below), and it also contains the origin of the sender, as well as a reference to the sender’s window object. The value of both of these last two things can be verified by the recipient, for added security.
The best description of how this works can be found here, and the full rundown on browser support can be found here (make sure to click on “Show all versions”). Last but not least, I have made a simple demo myself, which can be found here.
When the user clicks on the button to run my demo, the parent frame sends a message to the child frame, which prints a message and sends another one back to the parent frame. Here are the essential bits from the code for the demo:
1) The code in the parent page, html then JavaScript:
<button id="runDemo">Run the demo</button> <iframe id="inlineFrame" src="http://childdomain.com/index.html"></iframe> <p> After the child received the message, it sent the following response back to the parent: <span id="responseFromChild"></span> </p> |
var childOrigin = 'http://childdomain.com'; var childWindow = document.getElementById('inlineFrame').contentWindow; // Listen for the response from the child window.addEventListener('message', function(event) { // This 'if' block is optional, but good for security. if (event.origin !== childOrigin || event.source !== childWindow) { throw new Error('The domain of the child does not match what the parent thought it was going to be.'); } // Show that we've received the message document.getElementById('responseFromChild').innerHTML = event.data; }, false); // Activate the button var demoButton = document.getElementById('runDemo'); demoButton.addEventListener('click', function() { // Post a message to the child window childWindow.postMessage('Child, heed my call.', childOrigin); }, false); |
2) The code in the child page, html then JavaScript:
<p> Here is the message the child received from the parent: <span id="messageFromParent"></span> </p> |
var parentOrigin = 'http://parentdomain.com'; var parentWindow = window.parent; // Listen for the message from the parent window.addEventListener('message', function(event) { // This 'if' block is optional, but good for security if (event.origin !== parentOrigin || event.source !== parentWindow) { throw new Error('The domain of the parent does not match what the child thought it was going to be.'); } // Show that we've received the message document.getElementById('messageFromParent').innerHTML = event.data; // Post a message back to the parent window parentWindow.postMessage('Right back atcha.', parentOrigin); }, false); |
And a Happy New Year to all!
Over the summer, I participated in a hackathon called Story Hack (that’s me on the far right), run by an organization called Story Code, dedicated to “supporting, incubating and showcasing projects created by independent immersive and cross-platform storytellers.”
I wasn’t sure what that meant, but the project was really fun. It was actually kind of a two-weekend affair — the primary event was the second weekend, but there was an orientation on the first weekend for the core participants, and some members of the team had several more meetings during the week and actually shot a video.
Unlike most hackathons, this one was focused on storytelling, and was held at Lincoln Center. I get the feeling Story Code is made up mostly of film people who are trying to look at the big picture and figure out what the next dominant incarnation of the art of storytelling will look like, as film slowly morphs into its successor. But maybe that’s just me.
Because it was all about narrative and the use of different platforms to tell a story, some amount of theatricality was encouraged, but most teams still made their presentations more like pitches for products that had not been completely built yet. Ours was a show from beginning to end, complete with a post-apocalyptic storyline with MCs, a hilarious website (futuremate.us), a Twilio setup that connected random members of the audience to each other in conference calls (front-end manifestation at futuremate.us/speed_date.html — it’s a little buggy but you can see what it was supposed to do, and it went by quickly during the presentation so it served its purpose), and then a giant mutant zombie puppet as a deus ex machina at the end (operated by me).
We won the first prize of $1,000. Many of our competitors’ tech elements were as impressive as ours, but only we were in character during our entire presentation.
Now granted, most hackathons are not like that one — they’re not explicitly about narrative, they don’t give you ten minutes for their presentation, and they have more than eight teams. But I would suspect that at any hackathon, all else being equal, judges will give consideration to a project whose presentation was fun for the audience to watch, and participate in. Because we all know those presentation sessions can be pretty deadly, especially for the half of the audience who hasn’t slept.
Something to think about, anyway.
Recently I had to hire someone to help me out at work, and I was running the interviews, which I’d never done before.
My two co-workers (Ruby guys) told me that when one of them had been interviewing to work at our company, he was sent an exercise to complete. My other co-worker was already working there. He had tried the problem also, and had come up with a long, convoluted solution. So when the new guy emailed back with something that was about fifteen lines long, they hired him.
Here’s the problem: You have a triangle of numbers, like
1
4 3
1 9 7
1 1 5 9
and the question is, what is the greatest of all the sums that you can get by tracing a path of adjacent numbers from the top of the triangle and adding one number per row as you go down the rows?
For instance, in this case the answer is 20: the sum of the numbers 1, 3, 7, and 9, tracing a path down the right edge.
(On the github page which goes along with this blog post, a text file called ‘triangle.txt’ is provided for this exercise which has 100 rows, too many to calculate without automating it. The answer to the problem for that text file is 732506.)
Before looking at either of my co-workers’ solutions, I tried it myself and thought I had come up with a pretty elegant solution using recursion and memoization to calculate all of the possible answers and store the partial ones as it goes along so it doesn’t take forever. The array it creates is, instead of numbers, an array of objects, where each object is a node in a tree containing pointers to the next two nodes down, as well as the value of the current node.
Here’s my code. It is intended to be run in Node.js on a file in the current directory, but you could change the beginning a little bit and run it on a string or something in the browser:
var fs = require('fs'); var max = function (file) { var text = fs.readFileSync(file, 'ascii'); var array = text.split('\n').map(function(row) { return row.trim().split(' ').map(function(word) { return { num: parseInt(word) }; }); }); array.forEach(function(row, i) { row.forEach(function(node, j) { var next_row = array[i+1]; if (next_row) { node.left = next_row[j]; node.right = next_row[j+1]; }; }); }); var root = array[0][0]; return (function walk_tree(node) { if (!node) return 0; if (typeof node.memo_sum !== 'undefined') return node.memo_sum; node.memo_sum = node.num + Math.max(walk_tree(node.left), walk_tree(node.right)); return node.memo_sum; })(root); } console.log(max('triangle.txt')) |
Then I looked at my co-worker’s solution, which is here (I have slightly modified it and translated it from Ruby to JavaScript, but this is the basic gist). It turns the triangle upside down and goes through it from the wide top to the single-element bottom, replacing each number in the triangle with the partial results based on the ones above it:
var fs = require('fs'); var max = function (file) { var text = fs.readFileSync(file, 'ascii'); var array = text.split('\n').map(function(row) { return row.trim().split(' ').map(function(word) { return parseInt(word); }); }); array.reverse(); array.forEach(function(row, i) { row.forEach(function(num, j) { if (i > 0) { var previousRow = array[i - 1]; row[j] += Math.max(previousRow[j], previousRow[j + 1]); } }); }); return array[array.length - 1][0]; } console.log(max('triangle.txt')); |
His was a lot shorter than mine, and more elegant. It was a lesson to me: recursion may seem cool, but it’s not always the best idea.
However, taking it up where my co-worker left off, I was able to make his version even more elegant by using the reduceRight array method, thus making it more pure, functional-programming-wise. My new function starts from the bottom of the triangle and works its way up, constantly updating an accumulator (called ‘sumRow’) that is a row of partial results, but it doesn’t touch the original array:
var fs = require('fs'); var max = function (file) { var text = fs.readFileSync(file, 'ascii'); var array = text.split('\n').map(function(row) { return row.trim().split(' ').map(function(word) { return parseInt(word); }); }); return array.reduceRight(function(sumRow, row) { return row.map(function(num, i) { return num + Math.max(sumRow[i], sumRow[i + 1]); }); })[0]; }; console.log(max('triangle.txt')); |
As an exercise, I made versions of all these files in JavaScript, Ruby, and CoffeeScript, to see how they compared. You can see them on the github page. On that page I also added one final version in CoffeeScript which uses comprehensions to make it incredibly short, although it’s a little hard to read, I think. I’ll give it the benefit of the doubt in this case, though, and assume that I just don’t know how to write proper idiomatic CoffeeScript yet:
fs = require 'fs' max = (file) -> array = ((parseInt word for word in row.trim().split(' ')) for row in fs.readFileSync(file, 'ascii').split('\n')) result = array.reduceRight (sumRow, row) -> num + Math.max sumRow[i], sumRow[i + 1] for num, i in row result[0] console.log max 'triangle.txt' |
tl;dr I found a job!
During the six-month hiatus between the last blog post and this one, I quit a job I’d been at for fifteen years, and ventured into the new world (for me) of programming professionally. It wasn’t easy. At times I felt like I was trying to turn a cruise ship. And I couldn’t really blog about the process because of the whole don’t-let-your-boss-see-your-job-hunting-blog-post thing.
It took a bit longer than I expected, but here’s how I did it, in a nutshell, in case you’re thinking of making a similar move:
- I found a problem in my life that could be eliminated (or ameliorated) by using software. I was on a co-ed soccer team at the time, and we were sending each other 80 emails each week trying to make sure enough people were going to show up for the game, so I taught myself PHP and MySQL and made a simple attendance website. You can still find a demo version at turtleherder.com/bobcats. Feel free to mess around with it — it’s a fake team.
- I was working as a print designer, so I spent the next couple years slowly learning JavaScript for InDesign. (Adobe uses it as an embedded scripting language for all its products.) I made life easier for myself and my co-workers by automating a lot of already-existing tasks and coming up with new workflows that couldn’t even have been done without scripting.
- I’d dabbled in web design pre-CSS, but I’d let my skills lapse, so I started getting them up to date again: HTML, CSS, the DOM and all the fancy new object-oriented JavaScript techniques to go with them.
- I started to think about making the jump into programming as my primary living, but I suffered a bit of an existential crisis for a while, in that I was afraid it was going to take over my mind. I enjoyed programming, but I got very intensely focused on whatever project I was working on, and I was afraid that I wouldn’t be able to turn it off at the end of each day when I got home from work. I resolved this issue by talking to a lot of working programmers. I met some people around the country who worked remotely and seemed to have a good work-life balance, and also a lot of people at tech Meetups in New York. Eventually, I decided I would be able to handle it. As indeed I have.
- Once I got over my existential issue, I took a couple classes in JavaScript at the NYU School for Continuing and Professional Studies. The first one sucked. I’m not sure why I took the second one, but I did, and it was awesome. That class got me excited to be a programmer.
- Three months after the end of the inspiring class, at the beginning of 2012, I dropped my hours at work down to two days a week and started spending all my free time studying programming (JavaScript, HTML and CSS mostly), going to Meetups and hackathons, and working on side projects, the main one of which was a multi-user drawing program (using Node and Socket.io) based on a static version we worked on in the aforementioned class. That can be found at draw.jit.su (it usually works, but sometimes it breaks down until I restart it — whenever I get a free moment I’m going to attend to that).
- Last but not least, I wrote a resume and started slowly looking for jobs. It took me months just to get around to writing the resume itself — the psychological block that gets built up around that after fifteen years at the same job is quite formidable — but eventually I did it, and then I made a blitz, both on my own and through recruiters. One week in late May I went to six interviews, the last of which was four and a half hours long. I got a few rejections, but just when my savings were almost gone (going down to two days a week had been a calculated risk that began to seem a little scary towards the end there, financially), I ended up with two offers for half-year contract positions. I took the one that was the smaller company, 35 minutes closer to my house, $5 more an hour, and had a pit bull puppy in the office.
The job turned out great, but that’s a topic for another post. I’m over half-way through it now, and looking for my next gig. Whatever happens, I’m sure the process will be a piece of cake this time, in comparison.
When anyone mentions a coding exercise they had to do for an interview or a class, I have a habit of getting it stuck in my mind and having to go home and work it out myself.
One of my co-workers, a reporter, has recently started to teach himself Ruby. He took a Java class in college and always had a kind of hankering to get back into programming, so when he and his girlfriend had a fight about chores, he decided to make a web app to help them figure out who was doing what, and to keep track of compliance and send email reminders. Everyone who’s looking for the motivation to re-learn programming needs some precipitating excuse, and that’s his, apparently. Certainly as good a reason as any. He’s been going through a Ruby book meant for the absolute beginner to programming, “Learn to Program,” by Chris Pine.
Yesterday he (my co-worker, not Chris Pine) mentioned that he was working on an exercise to convert Roman numerals into Arabic notation. He was having some trouble. I don’t know Ruby (it’s next on my list), but I went home that night and figured it out in Javascript.
My basic realization for the central algorithm was that all you need to know to add up Roman numerals (in their standardized modern variety anyway) is that the value of each letter is added to the total, unless it’s worth less than the one after it, in which case it gets subtracted from the total. That’s the simplest way to compute it, anyway.
Alternatively, you could go through the two-step process of identifying one- and two-letter sequences (like ‘X’ and ‘IV’) and then adding them. One could argue that that’s easier to read because the one- and two-letter sequences map very well conceptually to the Arabic notation that we think in.
Which would be an interesting question to ask an expert, but in the meantime, here are two solutions that are as concise as I could make them without getting into obnoxious trickiness for its own sake. The first one uses a classic ‘for’ loop, and the second one uses the more elegant functional programming methods map and reduce from the ECMAScript 5 spec, which you unfortunately can’t count on being available in every browser, but are pretty awesome:
The For Loop Version
var romanToArabic = function(romanNumeral) { var numberMap = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }, sum = 0, i, len, num, nextNum, romanNumeralArray = romanNumeral.split(''); for (i = 0, len = romanNumeralArray.length; i < len; i++) { num = numberMap[romanNumeralArray[i].toUpperCase()]; // Check to see if we're at the end of the array, and if so, // set it up so the last element will be compared to zero. nextNum = (i + 1 < len) ? numberMap[romanNumeralArray[i + 1].toUpperCase()] : 0; // The value of a letter in a roman numeral gets added to the // running total unless it's less than the value of the one // after it, in which case it gets subtracted. sum += (num < nextNum) ? num * -1 : num; } return sum; } |
The Functional Programming Version
var romanToArabicMoreConcise = function(romanNumeral) { var numberMap = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }; return romanNumeral .split('') .map(function(romanDigit) { return numberMap[romanDigit.toUpperCase()]; }) .reduceRight(function(sum, num, i, array) { // The value of each letter in a roman numeral gets added // to the running total, unless it's less than the value // of the one after it, in which case it gets subtracted. // (If it's the last element, it gets compared to zero.) return sum += (num < (array[i + 1] || 0)) ? num * -1 : num; }); } |
Explaining map and reduce is beyond the scope of this blog post (try here instead), but just notice that there are no local variables in the second version, except the number map itself, and the function arguments. I find that easier to read, personally. Fewer things to keep track of in my head.
After I completed this post, I noticed that there’s an entire website devoted to answering a wide range of simple programming exercises in like a thousand different languages. And yes, of course this one’s there. Check out the ones for JavaScript and CoffeeScript (a language that compiles down to JavaScript — see this post) and see how they differ from mine.
Then check out the Ruby version:
def fromRoman(roman) r = roman.dup.upcase n = 0 until r.empty? do case when r.start_with?('M') then v = 1000; len = 1 when r.start_with?('CM') then v = 900; len = 2 when r.start_with?('D') then v = 500; len = 1 when r.start_with?('CD') then v = 400; len = 2 when r.start_with?('C') then v = 100; len = 1 when r.start_with?('XC') then v = 90; len = 2 when r.start_with?('L') then v = 50; len = 1 when r.start_with?('XL') then v = 40; len = 2 when r.start_with?('X') then v = 10; len = 1 when r.start_with?('IX') then v = 9; len = 2 when r.start_with?('V') then v = 5; len = 1 when r.start_with?('IV') then v = 4; len = 2 when r.start_with?('I') then v = 1; len = 1 else raise ArgumentError.new("invalid roman numerals: " + roman) end n += v r[0 .. len-1] = "" end n end |
Looks a little repetitive in the middle there. I bet it’s possible to write something a bit more succinct — Ruby people are always saying that you could write a fully-featured word-processing program in seven lines. I guess I’ll find out when I learn the language myself.
Tomorrow I’ll be going to Kaltura DevConnect, a one-day conference on html5 video. The topic of the conference is the web video platform created by the main sponsor, Kaltura, and most of the talks will be on Kaltura’s own open source html5 video platform, but there will be some more general talks on html5 video and the production and distribution of online media in general.
Kaltura’s director of community development, Zohar Babin, is the (incredibly friendly, helpful and encouraging) organizer of the Javascript Meetup I go to, which is how I found out about it.
The info is here, if you want to go. It looks to be a good quick immersion into what the kids are all talking about with this html5 video, in case you’re worried you’re about to be left behind.
Time to get serious about this blog, and about my drawing project, which I have called ‘draw.’
You can find the current version at www.turtleherder.com/draw. It came from a class project in a JavaScript class I took in November 2011 with Pedro Ha at NYU’s SCPS (School of Continuing and Professional Something). The original version of the app was written by Ha, but I have expanded it since then, primarily by adding the ability to grab color palettes from the API of a website called colourlovers.com. You can find more info about ‘draw’ on its github page.
It’s basically meant to be a simple but effective demonstration of what can be done with the Canvas API. Canvas is an official piece of HTML5 now, and many browsers have supported it for years. It’s pretty cool, and easy to use if you know any JavaScript.
Canvas is based on a very simple concept, which is that most of the screen painting is done by function calls that move a cursor from point to point. It almost reminds me of the turtle graphics programming I did in the late seventies and early eighties in Logo and GraFORTH, although that was a bit different in that the cursor movements in turtle graphics are relative (Move forward 10, turn right 45 degrees, Move forward 14.1421, etc.) as opposed to Canvas’ absolute positioning (Move from point [10, 20] to point [10, 10], Move to point [20, 0], etc.). Back then there were a lot of unusual programming paradigms being foisted on children by academic purists championing their favorite obscure language — Logo was a version of Lisp, and GraFORTH was a version of FORTH. GraFORTH is in fact currently so obscure that it doesn’t even have a Wikipedia page.
But I digress. Another post will delve more fully into the early years, and the relative virtues of functional and stack-based languages. Today I want to talk about what I’m going to do next with the ‘draw’ project. Since the class ended, I have made a few minor tweaks to it, but the reason I have continued to work on it at all is so that I can one day make it into a multi-user real-time app.
If you search around for two seconds you can find any number of much more elaborate drawing apps using Canvas, like this one for instance, which looks like frickin’ Photoshop. But ‘draw’ has the virtue of being really simple, as in something a very small child might be able to use on an iPad, as in something my niece and nephew in California might be able to use at the same time as me, drawing on the same canvas (I live in New York).
To accomplish something like that I knew I would need Node.js, and probably socket.io as well. I just barely have a handle on those technologies, but I have been to a couple of hackathons and worked doing front-end coding on teams of people who knew Node really well, so I have a good idea of what it can do, and I figured this was the perfect project to learn it on, from start to finish.
So a couple weeks ago I made myself a list of steps I’ll have to take:
- Set up the ability to have multiple simultaneous brushes.
- Set up a Node.js server that receives and sends brush move events to and from multiple clients.
- Set up hosting for that server on the Internets.
- Set up a history object, so that when a new user opens their browser to the drawing app, everything that has happened so far is reflected on their canvas. (This is an important point for those who may not be familiar with Canvas, because it’s pretty low-level. Unless you use some kind of abstraction layer on top of it, all Canvas knows is the current operation, plus the pixels that have already been displayed on the screen. If you want to recreate the drawing history, you’ll have to keep track of it yourself.)
- Set up a way to create multiple canvases, each with their own name, so everyone in the world isn’t drawing on the same canvas (all with the ability to clear the screen at any moment!) People can start new ones or click on links or go to previously defined URLs for the old ones.
- Various UX and design changes and fixes, most notably the ability to handle touch events.
I actually did #1 and #4 pretty quickly. For a proof of concept of #1, I added a second brush that is operated by the keyboard, so that I can use that one and the mouse one at the same time. For #4, I set up a ‘restore canvas’ button so that I could clear it and then test the browser’s ability to reconstruct it from the history. It does so in the blink of an eye. I was surprised. Computers these days!
So for #2, which is of course the heart of the matter (although #3 might be kind of tricky…), I am plowing through the partially-published Manning book “Node in Action,” and of course all of the excellent information available online about Node.js. I should have something to show for myself in a week or two. Wish me luck.
A few weeks ago I went to a tech Meetup in Soho at the offices of Cyrus Innovations, hosted by a guy who works there named David Newell.
I’ve been going to a lot of Meetups lately. This one was on CoffeeScript, a clever little language (and ‘little’ is a word that it proudly uses to describe itself) which compiles down to JavaScript. It’s basically syntactic sugar on top of JavaScript.
As far as I can tell, Coffeescript has two main purposes:
- The creators have tried to eliminate most of the pitfalls that can trip up the unwary JavaScript programmer by simply not including the worst aspects of that language. (I’m not impugning the abilities of Javascript’s creator here, who apparently he had 10 days (!?) to create the whole thing — more on that in a later post.) And
- To add a bunch of syntactic sugar (comprehensions, splats, etc.) to make it look more like python or ruby. Thus also having the secondary effect of making it a lot shorter to write.
We were there all day for what David called a ‘code retreat.’ With my primitive Unix skills, I had just barely managed to install CoffeeScript on my laptop, a feat which first involved installing Node.js, the technology all the kids are talking about these days but only the lucky few actually know. By the time I got done I had about an hour to go over a tutorial, so that was the extent of my Coffeescript knowledge.
I’m not sure what I expected but we all got thrown into working in pairs creating implementations of Conway’s Game of Life (wikipedia that shit) in CoffeeScript. 45 minutes for each pair, then you ERASE all the code you’ve been working on (which was super-painful), come back to the group to discuss it, pair off with someone else and do it all over again, all day. David says that every time he needs to learn a new programming language, he makes the Game of Life. We didn’t ever get very far, but that wasn’t the point. The idea was to keep refining the way you thought about the problem.
It was an interesting experience. David was a very nice guy and did a great job running it, and I learned quite a bit about the concepts behind test driven development, which I’d also never had any experience with.
The verdict is still out on CoffeeScript. I basically like it, but I’m not swayed by it being shorter to write than JavaScript, as I work out code in my head a lot slower than I can type. If that ever changes, I’ll be jumping on the CoffeeScript bandwagon. In the meantime, I’m glad I have enough of a surface familiarity with CoffeeScript now so that if I ever had to learn it, I know how long it would take me to do so.
Well, that about wraps it up for today. Oh but wait, you ask, what about the logo? Well, when I got home the night after the Meetup, I sat down and wrote an implementation of the Game of Life in good old JavaScript. It can be found here. The shapes in the logo are the four forms of a moving pattern in the Game of Life known as the ‘glider’ (one form is repeated in the logo). Again, wikipedia that shit.
Welcome to my new tech blog, in which I detail my successes and frustrations on the road to becoming a programmer.
I’ve been coding on and off — mostly off — since I first started with BASIC, Logo and GraFORTH (huge bonus points if you remember that one) on the Apple IIe in the early 1980s. I was strong in middle school and then dropped it in high school because I was afraid to be a computer geek. Then I didn’t pick it up again seriously until twenty-five years later. I made a few abortive attempts over the years (other languages I have learned a little bit of and then forgotten completely include Pascal, 6502 Assembly, C, C++, Perl, PHP, and Scheme) but only really started delving into it in earnest in the past few years, mostly into JavaScript. Which is, as many have discovered, a lot more interesting than the horrible buggy scripting language it appeared to be during the browser wars of the 1990s.
This blog will be not so much a catalog of tips and tricks and best practices — for that, go to stackoverflow.com — but rather more of a memoir of how and why I got back into this stuff. My goal is to share what I have learned about coding and about learning, and to provide some moral support to people who stumble across one of the posts here and think, now I know I’m not the only one who had <x> problem, or who couldn’t understand <y> concept.
Time to get some sleep. Tomorrow, we begin at the beginning. Or in the middle. We’ll probably keep jumping back and forth, actually.

