I just completed weeks 0 and 1 of Introduction to Functional Programming in OCaml and I’m loving it! It took me way too long to figure out how scoping works in the “Definitions” section, but I think I finally got it. I watched the video over and over a bunch of times and kept trying examples in the REPL. It’s not C-like at all, but I guess it kind of makes sense.

The course is entirely in the browser, so there’s no need to install OCaml locally.

screen shot of FUN platform with inline OCaml

That’s great for the course instructors, who get to avoid the inevitable questions from the students with, er, proprietary operating systems. But it’s no way to live. I want to write code in my editor of choice and run it locally, so I went ahead and installed OCaml.

On this Ubuntu 18.04 machine, I installed OPAM, the OCaml Package Manager (like CPAN for Perl or cargo for Rust), with

sudo apt install opam

This installed OCaml

$ ocaml --version
The OCaml toplevel, version 4.05.0

$ opam --version

but also installed the package manager in case I want to install any other modules as the course goes on.

Now, what’s that “toplevel” all about in that ocaml version line? In week 0, they explain that toplevel is what they call the REPL (read evaluate print loop) in OCaml. Now that we’ve installed it, we can invoke it with just “ocaml” on the command line. However, it doesn’t have readline support (boo!), so we need to invoke it with rlwrap

$ rlwrap ocaml
		OCaml version 4.05.0

# let foo = "Hello, World!";;
val foo : string = "Hello, World!"

That’s enough for now. I’m sure I’ll be moving to my editor soon, but this is already better than working in the browser.


Julia in Jupyter

screen shot of Julia Jupyter notebook

Last month, Julia 1.0 was released– hooray! I installed it on my Ubuntu 18.04 machine with

cd ~/Downloads
gpg --import juliareleases.asc
gpg --verify julia-1.0.0-linux-x86_64.tar.gz.asc

cd ~/julia
tar xf ~/Downloads/julia-1.0.0-linux-x86_64.tar.gz

cd ~/bin
ln -s ../julia/julia-1.0.0/bin/julia

That last part linked it to by bin directory, which is already in my path.

$ which julia

$ julia --version
julia version 1.0.0

Today, I tried to use Julia from a Jupyter notebook. Jupyter is already installed.

$ which jupyter

$ jupyter --version

I installed it last year with

sudo apt install jupyter-core jupyter-notebook

This has been working fine and I have notebooks in Python 2, Python 3, Perl 5, Perl 6, and Clojure. However, Julia didn’t like it.

$ julia
julia> using Pkg
julia> Pkg.add("IJulia")
julia> using IJulia
[ Info: Precompiling IJulia [7073ff75-c697-5162-941a-fcdaad2a7d2a]
ERROR: LoadError: IJulia not properly installed. Please run Pkg.build("IJulia")

Running Pkg.build and a little bit of googling revealed that I didn’t have a jupyter-kernelspec command. Why not?

$ jupyter-kernelspec

Command 'jupyter-kernelspec' not found, but can be installed with:

sudo apt install jupyter-client

Ah. I hadn’t installed jupyter-client, just jupyter-core and jupyter-notebook. Running that command and then rebuilding IJulia worked a treat. Now, either

julia> using IJulia
julia> notebook()

from the Julia prompt, or

$ jupyter notebook

from the shell prompt starts up Jupyter (and Julia 1.0 is now on the list of kernels from which to choose). I prefer the latter, since I change to my Jupyter directory first, which shows all of my notebooks. Starting it within Julia shows my entire home directory.

Anyway, the bottom line is that the Julia 1.0 executable seems to work great with the Jupyter provided by Ubuntu; we just have to install the client too!

sudo apt install jupyter-core jupyter-notebook jupyter-client
Julia in Jupyter

Breaking down

I just came across this talk on category theory by Eugenia Cheng. I thought the whole thing was pretty great, but I particulary liked this impromptu remark about the nature of mathematics:

A lot of maths is about how we can take individual objects and build them into new ones that are a bit more interesting. The converse of that is that if we can then understand big ones, relative to small ones, and break them down into small ones, then we don’t have to do as much work. Because then all we have to do is understand some small objects and building processes. And then we can understand anything. That’s how all of maths works. That’s why we like understanding prime factorisation, so that we can just understand prime numbers and then build them into big numbers. And why we like breaking topological spaces into small pieces and then building them all up out of circles and disks. And why we like expressing all groups as fundamental finite ones and then seeing how we can build everything else with that. It’s so that we don’t ever have to deal with complicated things. We can just think about simple ones and building processes.

It reminds me of what Rich Hickey said about design:

So what do I mean when I say good design? I think one of the most interesting things about design is that, you know, people think it’s generating this intricate plan. But designing is not that. Designing is fundamentally about taking things apart. It’s about taking things apart in such a way that they can be put back together. If that makes sense. So separating things into things that can be composed. That’s what design is. Right? If you just make this intricate thing, you really haven’t designed in a way that needs to support the things that designs need to support. Like change. Every component of a design should be kind of about one or very few things. That’s sort of the nature of it, breaking things down until they are nearly atomic. And only then do you take those things that you have broken apart and compose them to solve the problem you set out to solve. But the first job is to take things apart in such a way that you can do that. And a good design process is iterative. This isn’t a grand plan you do once and then you go and finish.

Perhaps software design isn’t as far from category theory as Hickey seems to think!

Breaking down