Wednesday, September 3, 2014

Writing a PhD dissertation in Latex

Writing a PhD dissertation in Latex

Having just finished writing my PhD dissertation using Latex, I'd like to share my experiences -- what was easy, what was hard, and some problems to watch out for.

Writing a PhD dissertation is a daunting task. Besides the actual content, we also need to worry about formatting, references, bibliographies, tables of contents, page numbering, figure layout, dedication pages, ... Using a good document preparation program can help you with these issues, leaving you free to focus on the science. A bad program can suck up your time on annoying, trivial details.

If you've never heard of Latex before, the short version is that it's a program used to create documents, much like Microsoft Word. I decided to use Latex to write my PhD dissertation because I didn't want to waste time on side issues, and I thought Latex would be able to handle those. (Also, I didn't know how to do those in Word, which would otherwise have been the default choice).

Why Latex?

In Latex, your document is plain text. This is advantageous because of the wealth of tools that work with plain text, such as git. I knew before starting that I wanted to manage my dissertation using git (due to its project management features such as tags to help me keep track of which versions I shared with my committee, ability to compare revisions with line-based diffs, and integration with cloud-hosting services such as bitbucket and github), and it's far more pleasant to work with text files than binary ones in git. Writing my dissertation in Latex is a natural fit for git.

Latex distributions are free, lots of people use them and contribute and test code and answers to the community. There's also lots of features both built-in and available through add-on packages to help build documents efficiently.

Latex's pleasant surprises

  • the pdflatex program produces beautiful PDFs from your plain text Latex source files
  • references are easy to manage and share. The Bibtex format is pretty standard and it's easy to get references in this format from most journals
  • citing references from within the text is easy; Latex makes sure the citations are consistently numbered, formatted, and named
  • Latex can automatically generate the bibliography
  • Latex can automatically generate a table of contents
  • Latex can automatically generate internal hyperlinks within a PDF
  • beautiful rendering of mathematical equations
  • can refer to figures, tables, and other sections of text using labels and anchors

There's a learning curve

If you're coming from Word, then learning to use Latex is going to take some time -- it does things differently, and you'll have to figure out a new approach to writing documents. I expected that I would spend a decent chunk of time learning how to use Latex, debugging and fixing my mistakes, and solving problems. This did indeed turn out to be the case.

You can also expect to face your fair share of standard problems (that you'll probably run into no matter what program you use). This includes finding a version of the program that runs on your platform, figuring out where to find add-ons and how to install them, and building a conceptual understanding of how the program works -- so that you understand why errors occur and how to fix them.

Problems and issues I encountered

More of my time than expected was spent managing Latex (instead of working on the content). While there's undoubtedly solutions for each of these problems, it's tough for a beginner. Here are some of the problems that I encountered:

  • the error messages produced by pdflatex were pretty cryptic, which made it difficult to understand and google for the problem
  • default settings and parameterizations are occasionally surprising, and often difficult to discover
  • the built-in "report" document class did not exactly meet my university's formatting requirements -- that's okay, however, it took a lot of work to figure out how to fix the formatting
  • there are multiple contexts, and some characters mean different things in different contexts
  • conflicts between packages. Some Latex packages don't play nice with each other. Sometimes this means that you can't use certain packages together, other times it means that you'll silently get weird results. I believe there are also cases where packages have to be imported in a certain order to get them to work correctly
  • entries in the bibliography had different capitalization in the output PDF than what I had put into the bibliography file
  • it's hard to see where things start and end. Some commands aren't, delimited but are implicitly ended by later commands. Others have effects in some scope, which again is implicitly defined
  • margins were routinely violated. I had assumed that the default behavior would be to respect margins, but this was not the case
  • special characters. If you're not familiar with them, you may accidentally write something totally different from what you meant, without realizing it. Syntax-highlighting text editors are a big help here. Also, figuring out how to write a non-special version of the special characters
  • I had to spend time manually checking the PDF to ensure that everything turned out correctly. Sometimes, there were surprising problems in the output that I wouldn't have found except by actually looking at the PDF (that is, there wasn't an error or warning generated by pdflatex)
  • I had a very hard time finding complete, correct answers to problems. Many answers did not attempt to solve the problem, but rather argued with the premise of the OP. Many worked sometimes, but not in all contexts. Many others had unstated caveats, which later blew up in my face
  • I was unable to find complete, precise documentation for packages, macros, document classes, and commands -- what they are intended to do, and how they are intended to be used. For instance, I needed to know what the "report" document class entailed and what its options meant, so that I could compare to my university's formatting requirements. I couldn't find this information anywhere
  • it was difficult to choose between multiple competing packages solving the same problem -- it was hard to find good comparisons which included caveats, pros and cons, etc.
  • I wasn't able to find resources to help me build a conceptual understanding of how Latex works. This meant that I wasn't able to understand why errors occurred

Conclusion: was using Latex the right decision for me?

Yes. I wanted to write my dissertation in plain text, manage it using git, and have my table of contents, references, and bibliography automatically generated. Latex had no trouble handling these. It was usually fun to use Latex, and the output from pdflatex was beautiful.

On the other hand, I spent much more time than expected troubleshooting, debugging, digging through old forums looking for answers, deciphering cryptic error messages, and wondering why things didn't work. Latex can be a very frustrating and complicated tool, and it's difficult to find help when you need it. I ran into numerous problems that I just couldn't solve and couldn't find solutions to using the internet. These left a bad taste in my mouth. I feel like a lot of Latex goes against standard principles of building robust software, such as encapsulation, abstraction, composition, and invariants.

Nevertheless, it was more than worthwhile to learn to use Latex for my dissertation. I think these issues are traps for beginners, but don't prevent advanced users from getting work done. I expect the downsides of using Latex shrink as one gains more experience using it.

Disclaimer: please keep in mind that I am only reporting my experience and my thoughts, and that it is certainly possible that my conclusions are flawed. I intended for this to be a fair portrayal of Latex.

Thursday, March 6, 2014

Four different ways to inspect types and prototypes in Javascript

What is a type in Javascript?

It's hard to succinctly and accurately define `type` in Javascript. A couple of complications are Javascript's dynamic typing (meaning that variables don't have types), and that the tools that Javascript provides don't unambiguously and uniquely divide values in separate groups (meaning that there's overlap and differences between the various ways, and no one single way is more "right" than the others). Given these difficulties, let's forget about coming up with an unambiguous definition of "type" and also forget about what "type" means in other languages. Instead, let's just say that for the purposes of this article, "type" will mean "some way to group objects based on certain similar properties".

What are some of the properties that we can use to group Javascript's values? First, we can look at whether a value is an object or a primitive. We can further divide and group the objects by their prototype chains or constructors. We can divide the primitives into smaller groups based on their primitive types.

However, as I mentioned earlier, there are alternative, meaningful ways to group values. For instance, objects with identical prototype chains can be separated (`arguments` vs `{}`). There is also some overlap between primitives and certain objects -- some primitives are automatically converted to objects under certain circumstances, similar to Java's autoboxing.

This article will take a close look at Javascript's type-inspecting tools, and the different notions of "type" that they provide. Using a small amount of code -- and a large set of test cases -- we'll gather some data about each of the tools. This data will give us insight into the pros and cons of each tool -- and perhaps help to indicate when each should be used.

What are the tools at our disposal?

Object.getPrototypeOf

Can be used recursively to get the full prototype chain of an object. See the MDN docs. Related: Object.prototype.isPrototypeOf.

Object.prototype.toString

Used by Underscore for type inspection.

instanceof

Performs inheritance checks which respect the prototype chain.

typeof

Mostly useful for distinguishing between primitives and objects.

Array.isArray

A special method for checking if an object is an array. (Since this kind of method only exists for arrays, I won't use it in the rest of this article).

The code

We want to inspect as many different kinds of values as possible -- so let's make sure that we have each of the primitives, each of the commonly-used built-in object types, functions, user-defined types, `arguments`, object wrappers for primitives, and the root object for good measure. Remember, for each of these example values, we'll try each of the four previously-mentioned tools for inspecting types.

For each example, there's a meaningful string for display purposes, an expression that will evaluate to the desired value, and also a constructor function that we'll use for an `instanceof` check. The last part is pretty arbitrary -- I just use it to show that a given value can satisfy `instanceof` for multiple different constructors.

// put examples inside a function to get access to `arguments`
function getExamples() {
    var functionText = "new Function('x', 'return x + 1;')";
    return [
        // schema:  
        //   0: human-readable text
        //   1: expression to be inspected
        //   2: (optional) constructor for instanceof-checking
        ['undefined'        , undefined                         , null     ],
        ['null'             , null                              , null     ],
        ["'abc'"            , 'abc'                             , String   ],
        ["new String('abc')", new String('abc')                 , String   ],
        ['123'              , 123                               , Number   ],
        ['new Number(123)'  , new Number(123)                   , Number   ],
        ['Infinity'         , Infinity                          , Number   ],
        ['NaN'              , NaN                               , Number   ],
        ['true'             , true                              , Boolean  ],
        ['new Boolean(true)', new Boolean(true)                 , Boolean  ],
        ['function g(x) {}' , function g(x) {}                  , Function ],
        [functionText       , new Function('x', 'return x + 1;'), Function ],
        ["{'a': 1, 'b': 2}" , {'a': 1, 'b': 2}                  , null     ],
        ['new Object()'     , new Object()                      , null     ],
        ['new ObjectExt()'  , new ObjectExt()                   , ObjectExt],
        ['[1, 2, 3]'        , [1, 2, 3]                         , Array    ],
        ['new Array()'      , new Array()                       , Array    ],
        ['new ArrayExt()'   , new ArrayExt()                    , Array    ],
        ['/a/'              , /a/                               , RegExp   ],
        ["new RegExp('a')"  , new RegExp('a')                   , RegExp   ],
        ['new RegExpExt()'  , new RegExpExt()                   , RegExp   ],
        ['new Date()'       , new Date()                        , Date     ],
        ["new Error('!')"   , new Error('!')                    , Error    ],
        ['Math'             , Math                              , null     ],
        ['JSON'             , JSON                              , null     ],
        ['arguments'        , arguments                         , null     ],
        ['this'             , this /* the root object, right? */, Window   ]
    ];
}
Here's the code for setting up the three user-defined constructors. Each of Array, Object, and RegExp are extended:
// extend Array
function ArrayExt() {}
ArrayExt.prototype = [1, 2, 3];

// extend Object 
function ObjectExt() {}
 
// extend RegExp
function RegExpExt() {}
RegExpExt.prototype = /matt/;
Finally, the function used to grab an object's prototype chain. This throws an exception if `obj` is a primitive:
function getParents(obj) {
    var parents = [],
        par = obj;
    while ( true ) {
        par = Object.getPrototypeOf(par);
        if ( par === null ) {
            break;
        }
        parents.push(par);
    }
    return parents;
}

The data

Now we take each of the example values, and apply each of the four tests to it -- plus an extra `instanceof` test to show inheritance. For each expression "e", we'll do:
typeof e

Object.prototype.toString.call(e)

e instanceof Object

e instanceof [subtype]

getParents(e)
Here are the results. Especially surprising, inconsistent, and strange results are in red:
example typeof Object.prototype.toString instanceof Object instanceof subtype prototype chain
undefined undefined [object Undefined] false -- --
null object [object Null] false -- --
'abc' string [object String] false String: false --
new String('abc') object [object String] true String: true String,Object
123 number [object Number] false Number: false --
new Number(123) object [object Number] true Number: true Number,Object
Infinity number [object Number] false Number: false --
NaN number [object Number] false Number: false --
true boolean [object Boolean] false Boolean: false --
new Boolean(true) object [object Boolean] true Boolean: true Boolean,Object
function g(x) {} function [object Function] true Function: true Function,Object
new Function('x', 'return x + 1;') function [object Function] true Function: true Function,Object
{'a': 1, 'b': 2} object [object Object] true -- Object
new Object() object [object Object] true -- Object
new ObjectExt() object [object Object] true ObjectExt: true ObjectExt,Object
[1, 2, 3] object [object Array] true Array: true Array,Object
new Array() object [object Array] true Array: true Array,Object
new ArrayExt() object [object Object] true Array: true ArrayExt,Array,Object
/a/ object [object RegExp] true RegExp: true RegExp,Object
new RegExp('a') object [object RegExp] true RegExp: true RegExp,Object
new RegExpExt() object [object Object] true RegExp: true RegExpExt,RegExp,Object
new Date() object [object Date] true Date: true Date,Object
new Error('!') object [object Error] true Error: true Error,Object
Math object [object Math] true -- Object
JSON object [object JSON] true -- Object
arguments object [object Arguments] true -- Object
this object [object global] true Window: true Window,EventTarget,Object
Notes:
  • these results were obtained in Firefox, Javascript 1.5; Chrome, Javascript 1.7
  • the results in the last row vary by implementation

The analysis

typeof

`typeof` distinguishes between primitives and objects. However:
  • `typeof null` is "object"
  • it returns "function" for functions, even though they are objects -- this is not wrong, just misleading
  • for String, Number, and Boolean: `typeof` return "object" for wrapped values
  • it doesn't distinguish between different objects -- arrays, dates, regexps, user-defined, etc.: all are just "object"

instanceof

`instanceof` checks whether a constructor's prototype property is in an object's prototype chain. However:
  • the 2nd argument must be a constructor. The constructor is used to look up a prototype. This is a problem if creating objects with `Object.create` -- there is no constructor function (that you have access to).
  • may not work if there are objects moving across frames or windows
  • different results for corresponding objects and primitives
  • doesn't tell you what the prototypes actually are

Object.prototype.toString.call(...)

This seems to differentiate between the built-ins correctly. See this for more information. However:
  • it doesn't differentiate between corresponding objects and primitives
  • it reports all primitives as objects
  • doesn't seem to work for user-defined constructors and objects. Apparently, it depends on an internal [[Class]] property which can't be touched, according to this.

prototype chain using Object.getPrototypeOf

Gets the prototype objects. However:
  • can't distinguish `arguments` from `Math`, `JSON`, and other objects. In fact, can't distinguish between any objects that share the same prototype chain.
  • doesn't work on primitives -- even those which have corresponding objects
  • may fail for passing objects between windows/frames -- like `instanceof` -- (not sure)

Conclusion

It appears that none of these approaches is capable of dealing with this problem by itself. I'm not even sure if it's possible to come up with a 100% accurate and unbreakable method for classifying Javascript values. However, using a combination of these tools will probably get you most of the way there. Good luck!

Tuesday, March 4, 2014

Simplifying a formal grammar using transformations and BNF extensions

Integer literals

A BNF grammar is a great way to specify a language, due to its concise and declarative nature. However, one major limitation of BNF is that it's not extendable -- which means if you identify a common pattern, you can't factor it out. You're stuck with repeating the boilerplate everywhere it occurs.

For an example of boilerplate making a grammar far more difficult to understand, let's take a look at the Java Language Specification While the specification is formal, it's rather verbose and it's difficult to intuitively see what language the grammar really generates -- especially the corner cases:

DecimalNumeral:
    0
    NonZeroDigit Digits(?)
    NonZeroDigit Underscores Digits 

Digits:
    Digit
    Digit DigitsAndUnderscores(?) Digit 

Digit:
    0
    NonZeroDigit

NonZeroDigit: one of
    1 2 3 4 5 6 7 8 9

DigitsAndUnderscores:
    DigitOrUnderscore
    DigitsAndUnderscores DigitOrUnderscore 

DigitOrUnderscore:
    Digit
    _

Underscores:
    _
    Underscores _
That's 7 rules on 21 lines of code (27 if you include blank lines), and describes the syntax for base 10 integer literals.

The challenge: can we transform this grammar into one that generates the same language, but is clearer and more concise? (We are allowed to extend BNF with additional operators, if necessary)

Three simple transformations

Repetitions: + quantifier

First, let's borrow some regex notation -- whenever we see this pattern:
RuleName:
    terminal
    RuleName  terminal
that means there's one or more repetion of "terminal", so we can instead use the "+" quantifier:
RuleName:
    terminal(+)
That pattern appears in two places, and after substituting our new shorthand for both of them, we now have:
DecimalNumeral:
    0
    NonZeroDigit Digits(?)
    NonZeroDigit Underscores Digits 

Digits:
    Digit
    Digit DigitsAndUnderscores(?) Digit 

Digit:
    0
    NonZeroDigit

NonZeroDigit: one of
    1 2 3 4 5 6 7 8 9

DigitsAndUnderscores:
    DigitOrUnderscore(+)

DigitOrUnderscore:
    Digit
    _

Underscores:
    _(+)

Factoring in

I use the "factor in" transformation when a rule is:
  1. only used once
  2. very simple
  3. given a semantically void name such as "Underscores"
Here's the basic idea of factoring in (it's the opposite of factoring out repeated code):
// before -- need to look up `SubRule1` in order to understand `Rule1`
Rule1: 
    SubRule1

SubRule1:
    ... some pattern ...

// after -- no additional rule to look up, also shorter
Rule1:
    ... some pattern ...
Applying this transformation to "DigitsAndUnderscores" and "Underscores" yields:
DecimalNumeral:
    0
    NonZeroDigit Digits(?)
    NonZeroDigit _(+) Digits 

Digits:
    Digit
    Digit DigitOrUnderscore(+)(?) Digit 

Digit:
    0
    NonZeroDigit

NonZeroDigit: one of
    1 2 3 4 5 6 7 8 9

DigitOrUnderscore:
    Digit
    _
Which saves 4 more lines, and two meaningless names. This transformation can be easily abused, leading to grammars that are more difficult to read instead of less so. The trick is to decide when "factoring in" clarifies the grammar and when it obfuscates.

Character classes

This borrows more regex short-hand -- square bracket notation and character ranges. It means the rule must match any one of the characters in the given range. I'll apply it to shorten "NonZeroDigit":
DecimalNumeral:
    0
    NonZeroDigit Digits(?)
    NonZeroDigit _(+) Digits 

Digits:
    Digit
    Digit DigitOrUnderscore(+)(?) Digit 

Digit:
    0
    NonZeroDigit

NonZeroDigit:
    [1-9]

DigitOrUnderscore:
    Digit
    _
Okay, that didn't help much yet -- but we'll use it again shortly.

The plot thickens

Now we can start reusing those transformations we just covered. First, let's factor in "NonZeroDigit":

DecimalNumeral:
    0
    [1-9] Digits(?)
    [1-9] _(+) Digits 

Digits:
    Digit
    Digit DigitOrUnderscore(+)(?) Digit 

Digit:
    0
    [1-9]

DigitOrUnderscore:
    Digit
    _
Now, combine "Digit"s two alternatives, using the square bracket notation, factor it in to "DigitOrUnderscore", and then combine "DigitOrUnderscore"s two alternatives:
DecimalNumeral:
    0
    [1-9] Digits(?)
    [1-9] _(+) Digits 

Digits:
    Digit
    Digit DigitOrUnderscore(+)(?) Digit 

Digit:
    [0-9]

DigitOrUnderscore:
    [0-9_]
Now factor in both "Digit" and "DigitOrUnderscore":
DecimalNumeral:
    0
    [1-9] Digits(?)
    [1-9] _(+) Digits 

Digits:
    [0-9]
    [0-9] [0-9_](+)(?) [0-9]
The quantifiers "+" and "?", when used together, mean the same as "*":
DecimalNumeral:
    0
    [1-9] Digits(?)
    [1-9] _(+) Digits 

Digits:
    [0-9]
    [0-9] [0-9_](*) [0-9]
And we can get rid of the "?" quantifier using its definition, splitting an alternative into two:
DecimalNumeral:
    0
    [1-9]
    [1-9] Digits
    [1-9] _(+) Digits 

Digits:
    [0-9]
    [0-9] [0-9_](*) [0-9]

Closing steps

Let's now factor in "Digits" -- but we'll have to be careful since it has two alternative rules. This means the factored-in result we'll have two alternatives wherever "Digits" is replaced:
DecimalNumeral:
    0
    [1-9]
    [1-9] [0-9]
    [1-9] [0-9] [0-9_](*) [0-9]
    [1-9] _(+) [0-9] 
    [1-9] _(+) [0-9] [0-9_](*) [0-9] 
And now let's combine the first two alternatives:
DecimalNumeral:
    [0-9]
    [1-9] [0-9]
    [1-9] [0-9] [0-9_](*) [0-9]
    [1-9] _(+) [0-9] 
    [1-9] _(+) [0-9] [0-9_](*) [0-9] 
The final transformation requires a bit of intuition -- notice that underscores are only allowed in the interior of the numeral, never on the edges. Let's combine the last 4 alternatives:
DecimalNumeral:
    [0-9]
    [1-9] [0-9_](*) [0-9]
And ... voila! We've gone from 21 lines, down to 3 concise and simple ones. This makes it easier to see common error cases -- for example, a number cannot end with an underscore. Try it out on your Java compiler!

Conclusion

The length and complexity of the original grammar caused quite a few problems:

  • more code means more chances for error -- misinterpretations, typos, omissions, etc.
  • we couldn't tell what the code was saying. This makes it tough to write effective tests
  • semantically void names -- "DigitsAndUnderscores" -- were distracting
  • corner cases were not obvious
  • difficult to maintain in the face of change
To deal with this, we defined several transformations, as well as extended BNF with a couple of new operators borrowed from regular expressions:
  • the "+" repetition quantifier -- one or more
  • square bracket notation and character ranges
  • factor in simple rules, one-off rules, and poor names
We then used these transformations and extensions to transform the grammar, creating a clearer, more concise grammar.