Daily Learning Notes for July 12th, 2017

Today I did just a little more work on the mob coding app, did some rock climbing and went for a short run, met with my fellow Girl Develop It co-organizer to do some planning, and hosted another web dev study group where I helped out with some JavaScript practice problems.

Real-time notes

10:53am: At the climbing gym after a morning workout with a friend who also works here during the day sometimes. Whew, my arms are tired! But I do want to try to write some code now. Where did I leave off? Oh yeah, I was going to write an async function that combines the forking/editing code. I’m thinking it’ll look something like this:

async function forkAndEditGist (tempCode) {
  let gistDataOrGistId;
  if (previousPlayer.login !== gameState.currentGist.owner) {
    // Fork the current Gist on behalf of this client (the previous player, whose turn is ending), and send new ID to server
    gistDataOrGistId = await forkGist(gameState.currentGist.id, editor.getValue());
  }
  editGist(gameState.currentGist.id, editor.getValue());
}

11:01am: I have a question, though… Do I need to return a value here? Would running the async forkAndEditGist function block other code from running? I guess I’m feeling a bit confused about which parts are asynchronous and which aren’t. Time to experiment more in my browser console with some quick tests! I’ll borrow from that Web Fundamentals article on async functions that I looked at before.

Async function examples

So here’s a very simple example illustrating that “async functions always return a promise”, even if you don’t put a promise next to the return keyword:

// wait ms milliseconds
function wait(ms) {
  return new Promise(r => setTimeout(r, ms));
}

async function hello() {
  await wait(500);
  return 'world';
}

// Ouput of the below code is: Hello !!!!! world
console.log("Hello ");
hello().then(console.log);
console.log("!!!!!");

What if I don’t return any value at all, though? Is the function still asynchronous? I’ll test it out. Yup! So this slight variation produces the exact same result:

async function hello() {
  await wait(500);
  console.log('world');
}

// Same output as before. Now I can use hello() without .then, because I'm relying on side effects:
console.log("Hello ");
hello();
console.log("!!!!!");

OK, so here’s my next question for myself: in my mob coding app, when forking/editing the Gist, what depends on what? The rest of the code in the handleTurnChange function does not depend on forking/editing the Gist – it can run in parallel! So forking/editing the Gist should indeed be an async function. Within that function, what depends on what? There are two cases: either the client needs to fork and edit the Gist, or the client only needs to edit the Gist. In the first case, editing the Gist should only happen after the Gist has been forked. In the second case, I just need to catch any errors, but that’s it.

Here’s a small example using the sample functions above, but in a structure similar to what I need (minus the try/catch blocks):

async function doOneOrTwoThings(condition) {
  if (condition) {
    await wait(500);
    console.log("Thing 1 done!");
  }
  
  await wait(500);
  console.log("Thing 2 done!");
}

console.log("Do some stuff first.");
doOneOrTwoThings();
console.log("Do other stuff in parallel!");

If I replace the wait function with whatever forking/editing code returns a promise, and I add a try/catch block around each, I’m basically done! Next question: is there any reason to keep the fork and edit functions separate, or should I just throw all the code into this one function? I’ll take a look and see how I feel about it.

12:59pm: I took a break to chat with my friend about math stuff, and he walked me through the general idea of the paper he was just reading and trying to understand, all about machine learning algorithms and “regularizers”, functions that apply penalties to other functions for being overcomplicated, sort of like a way to add Occam’s Razor right into an equation. Or something like that. I’m probably explaining it wrong, since I have no context at all for this stuff. Oh, and it totally made my day to hear that people who work in math also do a lot of Googling for things! That’s awesome, haha. It was fun hearing about and seeing part of that process of working through a math paper – like any technical writing, understanding it requries much more than just reading!

I need to send an email for tonight’s meetup real quick, before I forget! Then I’ll try to finish up with the async/await stuff before I need to leave for my meeting to discuss Girl Develop It stuff.

1:25pm: I tested it, but something is undefined where it shouldn’t be… Oh, I think I forgot to parse the response from GitHub to convert from a JSON string into an object! I did have a question about that. But first, let’s see if this works. Well, I fixed one bug, but there’s another! Forking isn’t working. And I need to pack up and leave soon. Bleh! I’ll have to look at this again later.

2:14pm: Sitting at Starbucks, just finished wolfing down the snack I packed up for today. I was hungry! On the way here I had an idea about that last error… Ah, but that doesn’t seem to be the problem. Oh well. Time to do some class planning work for Girl Develop It now with my co-organizer!

3:33pm: At Peet’s Coffee now, since there happened to be one on my way home, and I have a coupon for a free coffee! It’s really crowded here, though. I have my laptop on my lap, with my charger going across the aisle because there aren’t many power outlets. But it works. I’m not sure if I should take care of some followup tasks after that planning meeting, or jump right back into coding. Eh, OK, I’ll do some email and admin stuff real quick while it’s on my mind. It was a good meeting, and nice to meet in person for a change! Both of us feel a bit overwhelmed right now, but at least we agreed that it’s OK if we need to scale back. OK, time for some emails!

4:25pm: That took longer than I thought. Everything always does. OK, back to programming for a little bit!

4:35pm: It works, yay! The intuition I had while driving was correct after all, but I just didn’t see it earlier. I guess I was distracted. Like I thought, I was using the old Gist ID when trying to edit the Gist, instead of the new ID saved in the local game state. Now it works great! I just had one quick question about these async functions and promises… Can I do await returnsAPromise().then(JSON.parse); or do I have to do JSON.parse( await returnsAPromise() );? How can I test this real quick in the browser? Hmm, how about with a real call to the GitHub API?

Another quick async function experiment:

// This function returns a promise! Borrowed from EloquentJavaScript.net:
function get(url) {
  return new Promise(function(succeed, fail) {
    let req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.addEventListener("load", function() {
      if (req.status < 400)
        succeed(req.responseText);
      else
        fail(new Error("Request failed: " + req.statusText));
    });
    req.addEventListener("error", function() {
      fail(new Error("Network error"));
    });
    req.send(null);
  });
}

// Let's test this...
async function getSomeGitHubStuff(url) {
  try {
    // Instead of: JSON.parse( await get(url) );
    var someData = await get(url).then(JSON.parse);
    console.dir(someData);
  } catch (err) {
    console.log(err);
  }
}

getSomeGitHubStuff('an actual GitHub API URL here');

Interesting. It seems to work the same either way! Good to know. OK, I’ll take one more look at the code and save this change and close this issue!

5:05pm: Yay, done! I guess I should head home soon.

Wrapping up: The meetup group tonight was fun! I spent most of the time pair programming with one new friend and helping out with some JavaScript, especially working with callback functions. I was talking with another guy for a while about some other ES6 features like generators and how he was using them for testing his code, and it sounded really cool!

Gathering string

  • An unexpected short lesson on some of the math behind machine learning algorithms was really interesting! If I ever read or hear about regularizers again, they’ll sound a little less scary and more familiar to me now!

  • Apparently, reading through math papers involves a lot of Googling! That was cool to hear about.

  • I hadn’t thought about Occam’s Razor in a while. I definitely want to read about it again sometime.

  • Today I was reminded about generators in JavaScript ES6 again, and I do want to learn how to make use of them!