ClojureCLR.Next

A project to rewrite the ClojureCLR engine.

Posts

  • Qualified methods -- for ClojureCLR

    Clojure has introduced a new qualified methods feature allows for Java methods to be passed to higher-order functions. This feature also provides alternative ways to invoke methods and constructors, and new ways to specify type hints. We need to enhance this mechanism for ClojureCLR in the same ways we enhanced ‘classic’ interop.

  • What's the point? BigDecimal in review

    More to the point: Where’s the point? Recently I had to dig into the BigDecimal implementation to fix a reported bug. Every time I have to look at the BigDecimal code, it is a journey of rediscovery. I’m going to write down a few things to save me some time in the future.

  • PersistentHashMap, part 5 -- At a loss

    We look at performance of the new F# version of PersistentHashMap and compare it to the Clojure version. And in the end, declare ourselved mystified.

  • PersistentHashMap, part 4 -- Other matters

    We continue our discussion of PersistentHashMap with a discussion of transiency and alternative F# coding techniques.

  • PersistentHashMap, part 3 -- The guts

    We take a look at the internal nodes that implement the core algorithms of the PersistentHashMap data structure.

  • PersistentHashMap, part 2 -- The root

    I’ll sketch the code for the root of the PersistentHashMap structure in this post. The focus is on the data structures used and the primary operations: adding a key/value pair, find the value associated with a key, and removing a key. We’ll start with the Clojure interfaces that must be implemented.

  • PersistentHashMap, Part 1 -- Making a hash of things

    The first of several posts on implementing immutable, persistent Hash Array Mapped Tries. This post describes the data structure at a high level; subsequent posts will provide F# code for the base implementation and then discuss transiency.

  • Corrigendum -- Static initialization

    I must have made an error benchmarking static initialziations, detailed in a preceding post. Here I do a little more analysis and provide a correction to my comments and to the code.

  • A mega-dose of micro-benchmarks, Part 3 -- Finishing touches

    We apply some finishing touches to the PersistentArrayMap creation code. And then declare success.

  • A mega-dose of micro-benchmarks, Part 2 -- by the numbers

    Improving the numerics code for type mapping, operations lookup, and conversions.

  • A mega-dose of micro-benchmarks, Part 1 -- Setting the stage

    We go deep doing micro-benchmarks to improve the performance of one little function.

  • Persistent vectors, Part 4 -- Performance

    This is the first data structure we’ve worked on where performance can reasonably be tested. How does the new F# version of the code compare to the original C#? Where can performance be improved?

  • Persistent vectors, Part 3 -- Transiency

    Clojure’s vectors, hash-maps and hash-sets support transients. We examine the implementation of transiency for PersistentVector.

  • Persistent vectors, Part 2 -- Immutability and persistence

    An implementation of a vector class that is immutable, persistent, and efficient takes some non-trivial machinery. It’s time to go deep.

  • Persistent vectors, Part 1 -- The landscape

    This is the first of a series of posts on the design and implementation of PersistentVector, an immutable, persistent vector class supporting a transient mode for efficient batch operations.

  • Reductionism

    You can be a boss at reducers if you know this one weird trick!

  • Laziness and chunking

    Laziness is a central concept in the handling of sequences in Clojure. Chunking comes along as an efficiency measure. Surprisingly, at the level of implementation we are looking at it, very little needs to be done; laziness is defined most in the Clojure code that builds clojure.core. We’ll take a look at what is needed at the bottom to support laziness and chunking.

  • A road to maps

    I’d like to draw a roadmap for how to approach implementing the remaining collections.

  • First code

    We have working code.

  • Doing a number on Numbers

    Actually, more like Numbers did a number on me. But we’re good friends now. Numbers is ready to go. This is a long post; Numbers is big.

  • con-Sequential objector

    In which I contemplate the meaning of Sequential. This is an easy one compared to what you just went through.

  • A numbers game

    Getting started implementing Clojure collections requires methods in clojure.lang.Util for operations such as equality testing and hashing. These methods must operate properly on numeric types. The machinery for this is the class clojure.lang.Numbers.

  • Making a hash of it

    Wherein I look at hashing and equality in Clojure.

  • Circular reasoning (part 2)

    The code with the greatest entanglement across the Clojure codebase comes in the static classes clojure.lang.RT and clojure.lang.Util. How can these classes be restructured to reduce cyclic dependence and improve clarity?

  • Circular reasoning (part 1)

    I have to analyze the nature of circular references in the current Clojure implementations in order to avoid making an inelegant F# monolith – massive quantities of code in one file with all the types mutually recursive.

  • This map is the territory

    Maps are hugely important in Clojure programming. Internally, they are supported by a specific group of interfaces. Here we will examine these interfaces and provide an incredibly naive implementation. The intention is to make clear the mechanics of these interfaces in a simple setting. Later, when we implement realistic maps, we can wave at this stuff in passing and focus on the intricacies of the data structures themselves.

  • Odd questions

    Now for some homework. Let’s see how well you absorbed the material in the previous post.

  • A minimal implementation of Cons

    Seeing the complexity of the Clojure interface/data-structure ecosystem as we did in the last post can be a bit daunting. But if we start gently we can tease out some of the basic interactions and techniques that underlie how the real Clojure versions of these data structures are implemented.

  • For your Cons-ideration

    To build a Lisp, you could perhaps start with the simplest data structure, the cons cell: a simple record structure with two fields that hold pointers and a staple of Lisp implementation from the beginning.

  • The plan of attack

    One does not simply start writing a Clojure implementation. One needs a plan.

  • ClojureCLR -- Reconsidered

    Introducing a project to rewrite ClojureCLR – ClojureCLR.Next. With this blog, I hope to record some of the thinking I go through in the process, for myself mostly but perhaps for a future maintainer of the project.

subscribe via RSS