1. Brett Giles
  2. lqpl

Wiki

Clone wiki

lqpl / TechnologyChoices

Haskell was chosen as the language for the compiler and emulator due to:

  • Strong Static Typing
  • Conciseness
  • Laziness

We also used Haskell for the original GUI (using Gtk2hs), primarily for consistency. However, that has recently changed to a Swing interface written in Java/JRuby.

Haskell

Strong Static Typing

Haskell programs will not even compile until the types of all elements work together properly. This tends to reduce bugs and especially reduces run-time errors.

Conciseness

As Haskell is a functional language, it allows us to write small functions and combine them in multiple ways. Additionally, it allows function transformers which allow us to implement an algorithm on a simpler data type and lift to a more complex data type. A good example of this can be seen in the Emulator, in the QSM.QSM module. There, we define four different datatypes, BMS, LBMS, CMS and MachineState:

data BMS b =
    BMS { quantumStack :: QuantumStack b,
          classicalStack :: ClassicalStack,
          runningCode :: [Instruction Basis ],
          codeMem :: Memory Basis,
          instructionPointer :: (EntryPoint,Label),
          dump ::(Dump b),
          namesupply :: NameSupply,
          stackTranslation :: MemoryMap}
   
data LBMS b =
    LBMS { quantumStackLbld :: Controlled(QuantumStack b),
         classicalStackLbld :: ClassicalStack,
         runningCodeLbld :: [Instruction Basis ],
         codeMemLbld :: Memory Basis ,
         instructionPointerLbld :: (EntryPoint,Label),
         dumpLbld ::(Dump b),
         namesupplyLbld :: NameSupply,
         stackTranslationLbld :: MemoryMap}

data CMS b =
    CMS {cmsCodeMem :: Memory Basis,
         controlStack :: [ControlStack b],
         cmsInstructionPointer :: (EntryPoint, Label),
         cmsRunningCode:: [Instruction Basis],
         ctrldMS ::[ ((NameSupply,ClassicalStack,MemoryMap),
                      (Controlled(QuantumStack b), Dump b))]
        }

type MachineState b = Stream (Int,CMS b)

In order of complexity, we have:

BMS < LBMS < CMS < MachineState

In the same module, the majority of machine operations are defined on the BMS data type and then lifted so that they may apply to the top level, the actual MachineState. Writing functions on the simplest data type reduces the chances of error.

Laziness

Haskell is a Lazy language, meaning that expressions are not evaluated until you actually need them. This is quite useful in our emulator where the implemented semantics is based upon an infinite list of approximations to the correct answer. Laziness can be implemented in other languages, having it "built-in" in Haskell makes it somewhat easier.

GUI Choices

Gtk2hs (now unsupported)

The original choice of Gtk2hs was made as we wanted a Haskell based GUI and gtk was thought to be a reasonably cross-platform GUI.

However, a number of issues appeared over time:

  • Gtk moves quickly and it is difficult for Gtk2hs to keep up.
  • Building is rather problematic, very few other people were able to actually complete a build.
  • The interface on the mac is quite non-standard.

For those reasons, we decided to deprecate the Haskell GUI after version 0.8.

Swing

Swing is a very mature cross-platform GUI with a significant amount of support and documentation. In order to retain some of the advantages of Haskell - especially the functional aspects, we chose JRuby to implement the GUI, using the monkeybars MVC package to help structure the code.

Updated