Seven More Languages in Seven Weeks: Julia

Julia feels…rough.

There are parts I absolutely love, like the strong typing, the baked-in matrix operations, and the support for multi-type dispatch.

Then there’s the pieces that seem incomplete. Like the documentation, which is very extensive, but proved useless when trying to find out the proper way to build dictionaries in the latest version. Or the package system, which will install things right into a running repl (cool!) but does it without getting your permission for all its dependencies (boo).

All in all, I’d like to build something more extensive in Julia. Preferably something ML-related, that I might normally build in Python.

Day One

  • can install with brew
  • book written for 0.3, newest version is 0.5
  • has a repl built in ­čÖé
  • typeof for types
  • “” for strings, ” only for single-chars
  • // when you want to divide and leave it divided (no float, keep the fraction)
  • has symbols
  • arrays are typed, but can contain more than one type (will switch from char to any, for example)
  • commas are required for lists, arrays, etc (boo)
  • tuples: fixed sized bags of values, typed according to what they hold
  • arrays carry around their dimensionality (will be important for matrix-type ops later on)
  • has dictionaries as well
  • hmm: typeof({:foo => 5}) -> vector syntax is discontinued
  • Dicts have to be explicitly built now: Dict(:foo => 5) is the equivalent
  • XOR operator with $
  • bits to see the binary of a value
  • can assign to multiple variables at once with commas (like python)
  • trying to access an undefined key in a dict throws an error
  • in can check membership of arrays or iterators, but not dictionaries
  • but: can check for key and value in dict using in + pair of key, value: in(:a => 1, explicit)
  • book’s syntax of using tuple for the search is incorrect
  • julia docs are really…not helpful :/
  • book’s syntax for set construction is also wrong
  • nothing in the online docs to correct it
  • (of course, nothing in the online docs to correct my Dict construction syntax, either)
  • can construct Set with: Set([1, 2, 3])
  • arrays are typed (Any for multiple types)
  • array indexes start at 1, not 0 (!) [follows math here]
  • array slices include the ending index
  • can mutate index by assigning to existing index, but assigning to non-existing index doesn’t append to the array, throws error
  • array notation is row, column
  • * will do matrix multiplication (means # of rows of first has to match # of columns of second)
  • regular element-wise multiplication needs .*
  • need a transpose? just add ‘
  • very much like linear algebra; baked-in
  • dictionaries are typed, will throw error if you try to add key/value to them that doesn’t match the types it was created with
  • BUT: can merge a dict with a dict with different types, creates a new dict with Any to hold the differing types (keys or values)

Day Two

  • if..elseif…end
  • if check has┬áto be a boolean; won’t coerce strings, non-boolean values to booleans (nice)
  • reference vars inside of strings with $ prefix: println(“$a”)
  • has user-defined types
  • can add type constraints to user-defined type fields
  • automatically gets constructor fn with the same name as the type and arguments, one per field
  • subtype only one level
  • abstract types are just ways to group other types
  • no more super(), use supertype() -> suggested by compiler error message, which is nice
  • functions return value of last expression
  • … to get a collection of args
  • +(1, 2) -> yields 3, operators can be used as prefix functions
  • … will expand collection into arguments for a function
  • will dispatch function calls based on the types of all┬áthe arguments
  • type on pg 208: int() doesn’t exist, it’s Int()
  • WARNING: Base.ASCIIString is deprecated, use String instead.
  • no need to extend protocols or objects, classes, etc to add new functions for dispatching on core types: can just define the new functions, wherever you like, julia will dispatch appropriately
  • avoids problem with clojure defmulti’s, where you have to bring in the parent lib all the time
  • julia has erlang-like processes and message-passing to handle concurrency
  • WARNING: remotecall(id::Integer,f::Function,args…) is deprecated, use remotecall(f,id::Integer,args…) instead.
  • (remotecall arg order has changed)
  • randbool -> NOPE, try rand(Bool)
  • looks like there’s some overhead in using processes for the first time; pflip_coins times are double the non-parallel version at first, then are reliably twice as fast
  • julia founders answered the interview questions as one voice, with no distinction between them
  • whole section in the julia manual for parallel computing

Day Three

  • macros are based off of lisp’s (!)
  • quote with :
  • names fn no longer exists (for the Expr type, just fine for the Module type)
  • use fieldnames instead
  • unquote -> $
  • invoke macro with @ followed by the args
  • Pkg.add() will fetch directly into a running repl
  • hmm…installs homebrew without checking if it’s on your system already, or if you have it somewhere else
  • also doesn’t *ask* if it’s ok to install homebrew
  • not cool, julia, not cool
  • even then, not all dependencies installed at the time…still needed QuartzIO to display an image
  • view not defined
  • ImageView.view -> deprecated
  • imgshow does nothing
  • docs don’t help
  • hmm…restarting repl seems to have fixed it…window is hidden behind others
  • img no longer has data attribute, is just the pixels now
  • rounding errors means pixels != pixels2
  • ifloor -> floor(Int64, val) now
  • works!

Seven More Languages in Seven Weeks: Factor

Continuing on to the next language in the book: Factor.

Factor is…strange, and often frustrating. Where Lua felt simple and easy, Factor feels simple but hard.

Its concatenative syntax looks clean, just a list of words written out in order, but reading it requires you to keep a mental stack in your head at all times, so you can predict what the code does.

Here’s what I learned:

Day One

  • not functions, words
  • pull and push onto the stack
  • no operator precedence, the math words are applied in order like everything else
  • whitespace is significant
  • not anonymous functions: quotations
  • `if` needs quotations as the true and false branches
  • data pushed onto stack can become “out of reach” when more data gets pushed onto it (ex: store a string, and then a number, the number is all you can reach)
  • the `.` word becomes critical, then, for seeing the result of operations without pushing new values on the stack
  • also have shuffle words for just this purpose (manipulating the stack)
  • help documentation crashes; no listing online for how to get word docs in listener (plenty for vocab help, but that doesn’t help me)
  • factor is really hard to google for

Day Two

  • word definitions must list how many values they take from the stack and how many they put back
  • names in those definitions are not args, since they are arbitrary (not used in the word code itself)
  • named global vars: symbols (have get and set; aka getters and setters)
  • standalone code imports NOTHING, have to pull in all needed vocabularies by hand
  • really, really hate the factor documentation
  • for example, claims strings implement the sequence protocol, but that’s not exactly true…can’t use “suffix” on a string, for example

Day Three

  • not maps, TUPLES
  • auto-magically created getters and setters for all
  • often just use f for an empty value
  • is nice to be able to just write out lists of functions and not have to worry about explicit names for their arguments all over the place
  • floats can be an issue in tests without explicit casting (no types for functions, just values from the stack)
  • lots of example projects (games, etc) in the extra/ folder of the factor install

Seven More Languages in Seven Weeks: Lua

Realized I haven’t learned any new programming languages in a while, so I picked up a copy of Seven More Languages in Seven Weeks.

Each chapter covers a different language. They’re broken up into ‘Days’, with each day’s exercises digging deeper into the language.

Here’s what I learned about┬áthe first language in the book, Lua:

Day One

Just a dip into basic syntax.

  • table based
  • embeddable
  • whitespace doesn’t matter
  • no integers, only floating-point (!)
  • comparison operators will not coerce their arguments, so you can’t do =42 < ’43’
  • functions are first class
  • has tail-call-optimization (!)
  • extra args are ignored
  • omitted args just get nil
  • variables are global by default (!)
  • can use anything as key in table, including functions
  • array indexes start at 1 (!)

Day Two

Multithreading and OOP.

  • no multithreading, no threads at all
  • coroutines will only ever run on one core, so have to handle blocking and unblocking them manually
  • explicit over implicit, i guess?
  • since can use functions as values in tables, can build entire OO system from scratch using (self) passed in as first value to those functions
  • coroutines can also get you memoization, since yielding means the state of the fn is saved and resumed later
  • modules: can choose what gets exported, via another table at the bottom

Day Three

A very cool project — build a midi player in Lua with C++ interop — that was incredibly frustrating to get working. Nothing in the chapter was helpful. Learned┬ámore about C++ and Mac OS X audio than Lua.

  • had to add Homebrew’s Lua include directory (/usr/local/Cellar/lua/5.2.4_3/include) into include_directories command in CMakeLists.txt file
  • when compiling play.cpp, linker couldn’t find lua libs, so had to invoke the command by hand (after reading ld manual) with┬ábrew lua lib directory added to its search path via -L
  • basically, add this to CMakeFiles/play.dir/link.txt: -L /usr/local/Cellar/lua/5.2.4_3/lib -L /usr/local/Cellar/rtmidi/2.1.1/lib
  • adding those -L declarations will ensure make will find the right lib directories when doing its ld invocation (linking)
  • also had to go into the Audio Midi Setup utility and set the IAC Driver to device is online in order for any open ports to show up
  • AND then needed to be sure was running the Simplesynth application with the input set to the IAC Driver, to be able to hear the notes