Hacker School, Tuesday, June 10th, 2014

Disclaimer: This is an experiment. Unlike most of my blog posts here and elsewhere, this isn't an essay with a theme, it's really much more like the etymology of blog would suggest; a web log to just keep track of my days. At some point I might decide that subsymbol is not the right place for that, but I didn't want to block on figuring that out — a fate Allison Kaptur wisely warned us about on Monday.

I'm writing this Wednesday from notes and memories of yesterday.

Energy and Flow

I spent twelve and a half hours at the Hacker School space yesterday. I didn't leave the building, because I had brought enough food and coffee to last me all day. (I ate 11 boiled eggs and a big slab of butter.) There is no pressure to stay here beyond official hours. It is simply that my family is far away, and I wanted to be here. I should probably keep an eye out for signs of burnout, but I was pretty happy all day.

I took a break around 14:00, because I was getting what I call nap signal, back from the days of experimenting with polyphasic sleep: a slowing of mind, a heaviness of posture. I curled up on the beanbag for 20 minutes with my binaural + white noise nap track, and that was very refreshing.

At official closing I spent half an hour catching up on Twitter and Facebook and email, but other than that I focused on code, which is really amazing. I had feared that this might be hard for me to do, as I don't normally have the chance to try.

So, in the morning at checkin, I made the following plan.

Plan

Here is a log of what I actually did.

Actual

Adventures in conributing to open source

  • Started reading Tahoe-LAFS's How to Write Tests guide: https://tahoe-lafs.org/trac/tahoe-lafs/wiki/HowToWriteTests

    • Ran /usr/bin/tahoe debug trial allmydata.test.test_cli : All good!
  • Tried to install coverage

    This did not run for me. So I got help on the irc channel. The developers were interested in the bug I encountered and patched it after we explored it interactively.

    At the same time I started trying to understand each line of a unit test I will need to replace, called test_cli.test_ignore_symlinks This had a method I couldn't find the definition of, which turned out to be part of the Twisted Trial program. I asked the Twisted irc channel for advice on browsing the source, and I found the definition I was looking for on the GitHub repo.

    Meanwhile, Zooko wrote a patch to attempt to fix my coverage problem, but I am still git-nervous, and he had to go, so instead of blocking I switched to my reading task.

Reading

Monads for the Curious Programmer, Part 1

Here are my notes.

"The one category that’s really important in programming languages is the category of types and functions, in particular its Haskell version called Hask. There usually is a finite set of basic types like integers or Booleans, and an infinite set of derived types, like lists of integers, functions from integers to Booleans, etc. In Hask, a type is just a set of values."

  • I had forgotten since last time I looked at Category Theory that a category has an object and a morphism. It is generalises a group or a graph, not a set. Set consists of sets and functions.
  • The morphism is the inner relation, and the functor is the map between categories.
  • An endofunctor maps categories into themselves.
  • A functor in Hask maps types into types. For example,
    • Int -> [Int] with map

"A monad is an endofunctor together with two special families of morphisms, both going vertically, one up and one down. [...] The one going up is called unit and the one going down is called join."

"Unit can be though of as immersing values from a lower level into the higher level in the most natural way possible."

  • Eg. Bool -> [Bool] with True -> [True]

"To explain join, imagine the functor acting twice. For instance, from a given type T the list functor will first construct the type [T] (list of T), and then [[T]] (list of list of T). Join removes one layer of “listiness” by joining the sub-lists. Plainly speaking, it just concatenates the inner lists. Given, for instance, [[a, b], [c], [d, e]], it produces [a, b, c, d, e]. It’s a many-to-one mapping from the richer type to the poorer type and the type-parameterized family of joins also forms a polymorphic function"

  • I had trouble seeing this in a general way from the example given.

So, I'll pick up Part 2 tomorrow.

Got started with Factor

  • installed the binary

  • started reading the cookbook depth-firsting http://docs.factorcode.org/content/article-cookbook.html

    "As the parser reads tokens it makes a distinction between numbers, ordinary words, and parsing words." http://docs.factorcode.org/content/article-parser-algorithm.html

    • As I learn Factor, I'm constantly thinking about a natural language analogy.

    So, at the moment I'm mapping words to morphemes. NL morphemes sometimes are strictly grammatical (parsing words), or strictly semantic (ordinary words?), and sometimes both. That is sometimes the morpheme has multiple features even though the morpheme is atomic.

    • tokens are space separated
    • " is a special first character treated as a parsing word that signals that the rest of the token is a string.
    • Known ordinary words are appended to the parse tree.
    • Known parsing words are executed.
    • Unknown words are treated as numbers, which can raise an error.

    Hmm. According to http://docs.factorcode.org/content/vocab-syntax.htmlparsing words affect the interpretation of subsequent tokens, whereas ordinary words have stack effects. That seems like the opposite of what the parser description says.

    Except it is compiled, so stack effects are not executions.

  • At this point I wanted to play around, but I wasn't sure how to run the listener.

    • Got help from the irc channel figuring out that I had unmet dependencies.
    • Started working through the first program tutorial.
    • Learned about writing unit tests.
    • Submitted an issue about the tutorial to the tracker: https://github.com/slavapestov/factor/issues/1069
      • This was patched within about half an hour of my posting it!
    • Finished: "Your first program."

Rust

  • Paired with Zooko picking up where we left off on the tutorial: http://static.rust-lang.org/doc/master/tutorial.html#references-1

    I realised I was unclear on the use of semicolons, so I went back to this section: http://static.rust-lang.org/doc/master/tutorial.html#expressions-and-semicolons

    "the semicolon in Rust ignores the value of an expression."

    So, I think this means you need a semicolon whenever you are going to throw away the value of the last expression.

    For example, I have this simple program to test my understanding of the behaviour of mutable strings:

    use std::string::String;

    fn main() {

    let mut string = String::from_str("fo");

    println!("{}", string)

    string.push_char('o');

    println!("{}", string)

    }

    • Why do println! statements not need semi-colons?
    • I remember from last time that let statements can't end a function, because they don't evaluate to something, and functions return the last evaluated thing, so you have to add a semi-colon.

Misc

Throughout the day I intermittently interacted on the Zulip chat system. I agreed to participate in a Project Euler group.

Reflections

  • I'm still having fears about overcommitment, and about the pros and cons of switching tasks often vs. sticking to one thing until it is "done".
  • The one thing I would like to do better today is to work on something with someone else here. I want to gain the advantages of being here, and I want to help other people, too! So, I hope to collaborate on Coq and Project Euler today.
Share