in Code


Justin Le

Welcome! My name is Justin Le. I’m a PhD student at Chapman University in California, studying Computational Science & Applied Maths; I studied Physics and Computer Science at University of California, San Diego :)

This is just my weblog covering my various adventures in programming and explorations in the vast worlds of computation, physics, engineering, mathematics, and knowledge. Expect a healthy curiosity and an only slightly unhealthy obsession for finding new ways to marvel, wonder, and create. Join me if you wish!

Check out my most popular articles: Inside My World (Ode to Functor and Monad) and The Compriseless Reconciliation of Purity and I/O!

Recent Entries

  • First-Class “Statements”

    One thing I’ve really always appreciated about Haskell is that all “statements” in Haskell (or at least, what would be statements in other languages) are first-class members of the language. That is, (imperative) statements are literally just normal objects (no different from numbers, or lists, or booleans) — they can be saved to variables, passed to functions, transformed using normal functions, copied, etc. Haskell doesn’t have statements — everything is an expression, representing normal data! This really opens up a whole world of possibilities for not only reasoning about your code, but also for new ways to frame ideas in contexts of parallelism, concurrency, exceptions, DSLs, and more.

    To clarify, by “statement”, I mean it in the sense of a “command” from traditional imperative programming that, when control flow reaches it, executes some sort of action or modification to some state. The wikipedia article has a nice explanation. Some typical statements from common imperative languages include:

    int a = 4;              // declaration & assignment
    a += 5;                 // modification
    printf("hello world");  // call
    return false;           // exit points

    In these languages, whenever control flow reaches these statements, something happens. We do not differentiate the act of evaluating these statements (figuring out what they are) from executing these statements. Something just happens when you see an assignment.

    It is clear that in these languages, something about these statements are magical or a special part of the language. They are wholly different than, say, an integer, or a boolean. They aren’t normal “objects” or “data” in your system.

    Even if your programming languages have first-class functions, printf might be a first-class value, but the call of it (usually indicated with parentheses, like printf()) is definitely something…different altogether. You can simulate this in languages by creating a sub-language inside the language, but you’re always going to have an interplay between the two. There will always be the dichotomy between statements and data.

    Read more … Comments

  • Auto as Category, Applicative & Arrow (Intro to Machines/Arrows Part 2)

    Welcome back! It’s been a while since the last post, admittedly; sorry! In this post we’ll be continuing on from the previous post. In particular, we’re going to be looking at the Auto type as something that is a part of a pretty powerful pattern of abstraction, and try to exploit it to write concise, expressive code using Auto composition and proc notation. We’ll also see first hands the principles of locally stateful composition, and how much more expressive and safe it makes our code.

    And eventually, we’re going to tie it all together into how it fits into the semantics and implementation of Functional Reactive Programming! Yay!

    As always, feel free to leave a comment if you have any questions, or try to find me on twitter, or drop by the #haskell Freenode IRC channel! (I go by jle`)

    Note that all of the code in this post can be downloaded (from Auto.hs for the last post, and Auto2.hs for this post’s new material) so you can play along on GHCi, or write your own code using it the concepts and types here :) You can also run it online interactively.

    A fair warning: at times this post might feel a bit fragmented; but remember that we really are just going to be exploring and getting very familiar with the Auto type and building an intuition. Everything comes to a mini-climax at the end, and a final satisfying one at the next post — kind of like every Part 2 in every trilogy ever, you know? :)

    Read more … Comments

  • Pipes: Streaming Huffman Compression in Haskell (Part 3)

    Let’s finally finish up our Streaming Huffman Compression project by actually implementing the “streaming” part :) In part 1 we looked at the data structures which we used to implement our compression logic; in part 2 we looked at the actual compression/decompression algorithm and implemented it. Finally, let’s wrap it all up and actually implement a streaming interface!

    If we were using an imperative approach, this would usually involve some sort of loop — read a byte, process it, write the resulting byte, read the next, process it, write it…it’s a step of instructions that a computer will be able to perform step-by-step.

    In Haskell, when we can, we try to look for a pure, declarative approach based on compositions of abstractions. That’s what Haskell does best, after all. So let’s see what we can do!

    (All of the code in this article and the ones before can be downloaded from github, so you can download it and try it out yourself!)

    Read more … Comments

  • Looking forward: A Doctorate Program

    So a bit of some personal news (which you can safely ignore if you’re not interested in my personal life!) — I’m excited to announce that I have decided to accept an offer to the Computational and Data Science Doctorate Program at Chapman University in California. I came to this decision after a decently long period of deliberation and thinking things over, and weighing opportunities at Chapman against my other offers. However, having just finalized everything this week, I am ready to announce Chapman as my home for my doctoral studies in the upcoming years.

    There are two main aspects to my decision — why computational science, and why Chapman?

    Williams Hall — Chapman University (Photo by Tom Arthur)
    Williams Hall — Chapman University (Photo by Tom Arthur)

    Read more … Comments

  • Inside My World (Ode to Functor and Monad)

    I like Haskell because it lets me live inside my world.

    There are a lot of special worlds out there! And Haskell lets me stay in those worlds, and use all of the tools I normally have when I’m not there. I get to transform normal tools into tools that work in my world.

    (This post is meant to be approachable by people unfamiliar with Haskell! That being said, if there is a concept you don’t understand, feel free to leave a comment, tweet me, stop by on irc at freenode’s #haskell, or give Learn You a Haskell a quick read!)

    Read more … Comments

  • Streaming Huffman Compression in Haskell (Part 2: Binary and Searches)

    Continuing on this series of beginner/intermediate projects for newer Haskell users, let’s look back at our Huffman encoding project.

    In our last post we went over two types of binary trees implemented as algebraic data structures in Haskell, and also a scheme for assembling a Huffman encoding tree using the State monad.

    Now let’s look at serializing and unserializing our prefix trees for easy storage, and then at actually using them to encode and decode!

    Read more … Comments

  • A (Dead End?) Arrowized Dataflow Parallelism Interface Attempt

    So I’ve been having several ‘dead end’ projects in Haskell recently that I’ve sort of just scrapped and move from, but I decided that it might be nice to document some of them :) For reading back on it later, for people to possibly help/offer suggestions, for people to peruse and possibly learn something, or for people to laugh at me. Here is my most recent semi-failure — implicit dataflow parallelism through an Arrow interface.

    tl;dr:

    1. Compose parallelizable computations using expressive proc notation.
    2. Consolidate and join forks to maintain maximum parallelization.
    3. All data dependencies implicit; allows for nice succinct direct translations of normal functions.
    4. All “parallelizable” functions can also trivially be typechecked and run as normal functions, due to arrow polymorphism.

    The main problem:

    • Consider ParArrow a c, ParArrow b d, ParArrow (c,d) (e,f), ParArrow e g, and ParArrow f h. We execute the first two in parallel, apply the third, and execute the second two in parallel. Basically, we want two independent ParArrow a g and ParArrow c h that we can fork. And this is possible, as long as the “middle” arrow does not “cross-talk” — that is, it can’t be something like arr (\(x,y) -> (y,x)).

    Read more … Comments

  • Streaming Huffman Compression in Haskell (Part 1: Trees and State)

    So you’re learning Haskell and are looking for some projects that aren’t super trivial, are familiar enough that you can use what you already know, and are difficult enough to maybe help you learn new things. Hey, maybe this is for you :)

    Let’s take a go at Huffman encoding in Haskell. We will look at two types of binary trees, which we use to implement immutable/persistent priority queues and prefix trees. We’ll play around with the State monad a bit, explore some useful typeclasses, learn how to serialize, marshal, and unmarshal data structures using the binary library, and also look at how to load data from a file and write to another in a pure way, avoiding lazy IO using the ever-more-popular pipes library. And hopefully we learn some neat Haskell idioms!

    We’re going to be assuming some basic Haskell knowledge, like algebraic data types, higher order functions, basic monad usage, and some basic familiarity with the functions in Prelude/base, the standard library. If you have any questions, feel free to leave a comment, drop by on #haskell on freenode, throw me a tweet, or give the great Learn You A Haskell a quick read!

    Read more … Comments