A Qubit DSL?


I have a general question, is it possible to design a DSL using Dirac’s bra ket notation? It seems that |> is already used in the language, which corresponds to kets, so I’m not sure what the possibilities are.

For example, could I have something like |0> \tensorProduct |1> , where |0> and |1> parse to 2-dimensional arrays respectively, and the latex symbol for the tensor product be used? I’m new to Julia and wondering if there is a way to achieve this so that it is semantically clean, without using additional symbols.


The main problem is that we’d need a different symbol than | for the bar in the middle. I’m also not sure if we can have <x| and |y> and <x|y>.


The correct characters to use are actually \langle and \rangle written \langle and \rangle, respectively. Currently (0.6.2) these are invalid characters in Julia. It would certainly be really cool if they were made into some sort of special delimiters to allow Julia expressions such as |ψ⟩. It would be similarly cool if people could define the function ⟨x⟩.


Yes, even better would be \langle and \rangle. And | \psi \rangle would be great. If it’s possible to do it’s something I am interested in pursuing. I guess I’m really just trying to get a feel for what’s possible with the parser. Like for cross products, is a binary operator necessary? Or can whitespace be meaningful? I have some experience working with the Maude framework, where one can do these sorts of things, along with defining associativity and precedence of operators, but unfortunately, Maude does not support Unicode, which is critical if one wants to have a clean mathematical syntax.


Is this a pure syntax question? Or is this a question of how to do this performantly?

I guess you want at least lazy outer products (so that |i,j,k> does not have length(I)*length(J)*length(K) entries-- low rank tensors appear often enough in most non-PDE QM problems that they should get special support if you write a package for it. Likewise, many expressions might want to stay symbolic (i.e. vectors over the non-field of complex floats) until your expression grows too large, because <i1 | i2>==0 for i1!=i2 is too good to pass up on.


This is really a question of to what degree I could construct a semantic framework, I’m not really concerned with performance right now…hopefully Julia would take care of that :).

What I’d like is for a user to be able to type something like |0\rangle \otimes |1\rangle and get back |01 \rangle. This is what the user would see. Internally the result would be represented as \begin{bmatrix} 0 \\ 1\\ \\ 0 \\ 0 \end{bmatrix}

The other desiderata would be the ability to use arrows to construct circuits, and be able to parse this sort of thing. Really I am mainly concerned with understanding what the parser is capable of towards the aim of creating a clean, semantic DSL for qubit and circuit manipulation.


One possible way to create a proof-of-concept would be to create a string macro, which modifies the code (i.e. replaces currently invalid symbols), then calls parse.


Thanks, that seems like it may be promising. Do you think there would be any stumbling blocks to the notation as I’ve written it? Is the tensor product currently valid as a binary infix operator or would I need to replace that?


You can test the availability of syntax by trying to construct an expression:

julia> :(|x>)
ERROR: syntax: "|" is not a unary operator

which fails. Thus Simon’s suggestion to use a string-macro (check the docs). This just uses a string as DSL (and the string-macro transforms it). That way any string can be part of the DSL.


The following might also interest you https://github.com/MikeInnes/Probably.jl


This is relevant…


That’s cool, but I kind of feel like the strings make the Dirac notation not worth it.


Very cool. Both Probably.jl and QuDirac.jl look very interesting. I’m hoping with string parsing I can get to basically latex and defining U_f numerically, and then writing something like (H \otimes I)U_f(H \otimes H)(|0\rangle \otimes |1\rangle). Which would output |0\rangle or |1\rangle for the first qubit. Internally, after parsing, it’s just doing linear algebra under the covers. For reference H is the Hadamard matrix, I is the identity matrix, and U_f is the problem specific matrix that performs a unitary evolution on the qubits.


Two things on my list of fun Julia projects that I’d really like to do

  1. Create a Julia package for evaluating quantum expectation values using functional integration. I’ve started a lattice gauge theory package (only planning on gauge fields and scalars), haven’t gotten to work on it in a while. Made the mistake of insisting on doing it in arbitrary dimensions (conceptually no harder, but wow is it harder from programming perspective). Would like to do something more general even though fermions are a huge pain in the ass and no fun (but I could still do non-field theory-stuff without touching fermions).

  2. Some sort of tool for using tensor networks. This topic is still rather unfamiliar to me, so I’d probably learn a lot more doing that than lattice gauge theory (but it’s somehow less cool).


Cool paper on tensor networks! Yeah I’m interested mainly in quantum information, and there seem to be now some broad implications of the theory…i.e quantum error correcting codes etc. I think I’ll have a crack at defining a DSL for QI, and hopefully can make it generally useful for all these types of calculations. I’ve searched for a while to be able to check all the boxes in terms of having an elegant syntax for these types of things. It seems the tradeoff is always a language/framework either has elegant metaprogramming/language definition support or Unicode support, but not both, I’m hoping there’s a way forward with Julia.


Julia does indeed have both of these things, but there are limits, and unfortunately one of the (relatively few) limits you will encounter is Dirac notation. If we are lucky maybe \langle and \rangle will get defined in a useful way in the future.

My advice before you start would be to stay away from strings. If you want, you can eventually go bananas with metaprogramming, but only if you have valid Julia expressions. If you use strings, you will have to go crazy manipulating strings and it will be much harder to get things done at compile time. The Dirac notation would be really nice, but as things are right now, it’s probably not worth it. Doing something like ket[0,0] or whatever is far from perfect, but probably better than strings.


Good points, I’ll definitely think about that. I guess the sticking point for me on this is that it has to be an executable mathematical notation, otherwise it’s not worth it. I could define it more elegantly in Maude if Unicode weren’t essential. It simply must be beautiful:)

I will hold out hope for being able to use angle brackets.


We had in fact talked about teaching julia some sort of parsing/lowering for dirac syntax, but nobody ever came up with a concrete proposal. We did however make sure that \langle and \rangle remained invalid syntax, so we could do this after 1.0.

I think concrete proposal for a lowering of the syntax that covers common syntax use cases for the notation and interacts well with the rest of the language would be useful.


I’ll write something up and then post it back here.


Sure. Just to mention how these things work, our surface syntax generally lowers to some sort of function call, so that’s what your proposal should look like. e.g. say something like

|a⟩ should lower to `Ket(a)`, ⟨a|b⟩ should lower to `Bra(a)*Ket(B)`

or whatever, and then describe the parsing rules for those and maybe even show what an example implementation of the lowered functions would look like.