- Welcome back to fsharp Conf.
We have our next speaker with us
joining over Skype, John Azariah.
John, I'll ask my usual question.
Where are you right now?
Where are we calling?
- I'm actually on route to the UK.
I'm speaking at Indy.Code() tomorrow,
so I'm in Indiana for tonight.
- Just as I was getting into Redmond,
you started running away from me.
Is that right?
- Pretty much.
- Whoo, whoo.
That's not very nice.
It's a virtual conf, so we can deal with speaker
stars who travel all over the world.
Cool.
So do you know any good quantum jokes
that I could make at this point?
Probably no.
- Yes and no.
- That was good.
All right, so I'll switch to your screen
and you can get started with your talk.
- Fair enough.
Let me know if the audio goes a bit wonky.
It's hotel wifi.
And also I seem to have a frog in my throat.
So if you want me to repeat something, just say so.
- All right, I'll keep an eye on things here.
And let's get to your slides then.
- Very good.
- And I'll hide my camera as well,
so that we just see a little
tiny picture of you in the corner.
And you're on, ready to go.
- Thank you.
So you must have heard
the whole buzz about Microsoft
announcing that we entered
the whole quantum computing thing.
IBM's got a whole bunch of stuff going on.
Google has everything.
Everyone and their dog is trying to build qubits
and make a big deal out of something.
But Microsoft's approach was to actually look
at the full stack of the quantum computer.
And so at the top end of the stack, there's this
whole problem of being able describe quantum algorithms
and be able to develop quantum programs.
And do it in a nice developer-friendly way.
And so very serendipitously,
I got involved in this project.
I'll give you an overview
of what actually happened.
And then I'll walk through how Q# the language was
actually developed and what role F# played in that.
And hopefully, this should serve
as a kind of object lesson of F#
in the wild, what functional
programming's strengths really are.
And hopefully, it might actually encourage
someone to keep at doing what they're doing.
So who am I?
So I've been a .NET practitioner
since before it was .NET.
I actually worked on what was knows as
[ inaudible ] back in 1999, before they called it .NET.
I have a weird history with languages.
I actually worked on the Visual J# .NET Compiler,
which was the .NET cleanroom implementation of Java.
And so while I've been a professional C#
developer and a F# enthusiast since about 2014 or so,
I've had two kind of interesting things
sort of going through my background.
I built the whole enterprise software type stuff.
But in the back of my mind has always been
a deep interest in programming languages
and a deep interest
in functional programming.
So that's kind of the background
which I came to this picture with.
As it turns out, I was working in Azure
at the time and somebody in the
quantum team put out a tweet saying,
"Hey, the quantum guys want
someone interested in F#."
And I didn't know anything about quantum,
so I just retweeted the tweet.
And then went down to the quantum team to actually have
a quick chat with the person who put the tweet out.
And he told me about LIQUiD.
LIQUiD was actually written by Dave Wecker
who's in the quantum research team.
And it is a quantum simulator written in F#.
A quantum simulator is nothing but a library
of linear algebra functions
with the specific domain
of quantum computing.
So basically, it turns out that all of
the quantum mess of matter
that we can talk about
is quite accurately described
using linear algebra.
We can define a set of libraries that allows us
to model quantum mechanics in linear algebra
and then allows us to
write programs on a computer
that would perform those linear
algebra operations for us.
And that's in effect what the simulator does.
And so LIQUiD was written.
It was a very popular package.
It was a brilliant piece of work.
He wrote code in F#.
Now this is actually LIQUiD code,
but it's really F# code, as you can see.
And it's got the primitives for quantum.
For example, H, which is Hadamard
and M, which is measure.
These are all functions that are quantum operations,
which are effectively matrix multiplications.
You express them in F#
and then they have an implementation,
which involves basically doing the math.
And LIQUiD will simulate what the behavior
of this system would do for you.
As I said before, it was
a brilliant piece of work.
It's very widely used in academia.
Lots of peoples reference it.
It's a very powerful simulator
that you can just use.
And the beauty of it was that
it actually proved that F#
was a powerful enough language
to express quantum constructs.
So while this thing was being
put in production and being used -
and you can still download
it from GitHub today
- and you'll pardon the pun because people
in research have strange senses of humor.
We had a product called
Solid as opposed to LIQUiD.
Solid was supposed to be the way
in which you took the program
that you wanted to run
from the simulator itself,
separate the simulator out
and be able to plug in
a proper quantum computer.
Being that we were building a quantum computer,
we were in the race to get a qubit.
So at some point when the qubit is ready, well,
we want to be able to program the thing.
So they did what they do best.
Which was to take F# code and use
this really neat feature in F#
called the reflective definition,
which gives you the ASD of the program
that you're trying to write.
You can then interpret the ASD to do
what you want in terms of saying -
oh, this sequence of function calls
is really a sequence
that needs to be run
on the quantum device.
So we'll batch it up and send it down
to the quantum computer to do stuff.
Now, I'm gonna stop here and point out something
that isn't entirely obvious to everybody.
A quantum computer - probably in my lifetime -
will not run on your local machine.
It won't run at room temperature.
It certainly won't run on your desktop.
The quantum computer, it turns out
to involve using some really nifty physics,
but most of the physics happens
at very close to absolute zero.
So what we end up doing is we have to build a fridge
and then we have to build this quantum device.
Kind of like your processor that sits
in the middle of this fridge,
protected and so on and so forth.
It's a very challenging science problem.
It's an extremely challenging
engineering problem.
And it's runs at about 20 millikelvin.
Basically, to 20,000th of a degree
above absolute zero.
So it's not likely that we're gonna
get that kind of infrastructure
in our basements anytime soon.
So what we will end up doing is always program
the quantum device as if it was a core processor.
And the core processor is going
to perform computations
that are going to be difficult
for the main computer to do.
And those computations in
the quantum context
are basically the linear
algebra multiplications,
matrix operations.
Matrix operations, if you remember your maths,
and if you think about what they actually do -
they're extremely compute
intensive in a classical sense.
Both in terms of compute
and in terms of storage,
you need to have enormous capacity on your machine
to be able to do a bunch of stuff.
Whereas the quantum devices,
kind of do those at much lower cost.
So the goal is for us to be able to write
a program that we want to separate out into two pieces.
One that is going to run
on the classical machine.
And the other is the piece that's
going to have to be shipped off,
probably across the cloud, to something in a fridge
that's about 15 millikelvin or 20 millikelvin.
And it's going to do the matrix multiplication for you
because it's able to do that much, much, much,
much faster than you could
do it on your local machine.
And that's a very handwavy way of
explaining what quantum computation looks like.
So the goal here in this example,
for example, is still taking F#
code, but we have reflective definition,
which gives us the ASD
of the EPR function, for example.
So instead of just calling EPR and expecting it
to be a function call, we go into the body of EPR
and look into what it's trying to do
and build up the set of
sequence of instructions
that needs to go and be
executed on the quantum device.
So what was the net result of that?
Well, F#'s reflective definition is
extremely powerful and extremely cool.
It allows you to use F# as a native language
to express quantum computation.
But then, F# turns out to be too powerful
because you can write code that is correct in F#,
but has no meaning
in the quantum domain.
And that becomes very difficult
to extract by just looking at the ASD.
Effectively, what you're doing
is looking at the ASD
to try to determine the intent
of the what the person was trying to write,
so that you can discover
the quantum set of instructions
that needs to be
equivalent to it.
Additionally, you'll have
a conflation of type systems,
so you'll end up having the ability
to create complex types for example in F#,
which really have no meaning
in the quantum context.
But of course, now we recognize
that the quantum computer and the simulator
are both really
core processors
of a classical computer.
And so there are two real
programs that are interleaved.
That's really the big message
that came out of this.
And at this point, they hired us
to come in and take a look at Solid
and try to make it work
with a real quantum device.
And that's the context
in which I joined the team.
Of course, if you've probably
run into me a few times you know
that the m word
comes up fairly quickly.
And it turns out that this turns out
to be a very, very powerful
and very, very useful to think
about quantum computation.
So I won't launch myself into a full-blown
monad tutorial at the moment.
But fundamentally, what the idea of monad is
is once you lift the value into this monadic context,
you can then sequence a bunch
of operations on top of that context
without having to know
the individual value.
Because the context is the one
that's going to bind the operations
and create the sequence for you.
Now this model of thinking about monads.
This turns out to be extraordinary powerful
because the quantum device is in effect modeling state
that you cannot represent
physically in a classical machine.
And so when you make operations
on the quantum device,
what you're really doing is you
can't get access to the state
to actually do the
calculations yourself.
You are asking the quantum device
to sequence the instructions
for you very much
like a quantum monad.
So we basically took that concept
and ran with it.
And very quickly, instead of having
to interpret everything
and run in a very performance
resource constrained way,
we wrote the thing out
as a CE instead.
So now we created the quantum monad thing.
And then we were able to actually
express the computations
that you wanted to do
on the quantum monad
and chain the whole thing
using the CE - the constructs.
And this turned out to actually
be strongly powerful.
Very, very fast.
There was examples where the
Solid approach of interpreting
would've taken us
eight hours to do something,
whereas monadic approach landed up doing
exactly that in about 300 milliseconds.
So because we were able to remove
the whole concept of reflection,
remove the whole concept
of interpretation,
but still separate out
the two contexts.
So we know there's something
inside the quantum CEs
is actually in the quantum
context from the thing outside,
we're able to achieve a level of separation
without sacrificing performance.
Obviously, there's a cost that will come to it
and that is one of the things is that the syntax
becomes a little more cumbersome.
You'll find that there's a whole bunch
of quantum dot here and a quantum dot there.
It tends to be a little bit
of a nuisance.
And then one of the things that
turns out to be kind of useful
is for us to be able to look at the sequence
of instructions in the code and reason over them.
So it turns out that you can actually
compress sequences of instructions,
for example, by just looking at them.
Which you won't be able to do
if you just executing the thing.
So landed up creating the new way
of representing this.
And one of the things that we did
for this was recognize
that this is really us trying to
interpret something that is quantum.
We're trying to interpret a
sequence of quantum instructions.
Well, if you've seen Scott Wlaschin's
13 Ways to Look at a Turtle,
he introduces a very
interesting concept.
The concept of the interpretive
backend has a functional equivalent.
And that functional equivalent turns out
to be something known as the free monad.
Now, the free monad is something
that you could recognize
basically if you come
from a non-F# background.
Because it turns out that you need
to have a higher level of abstraction
to be able to think about it
and talk in terms of it.
But the concept is actually quite useful
and you can actually implement the free monad in F#.
And so what we did was we separated out the language
that the quantum instructions supposed to represent
and put that into what is
the free monad functor
and created a free monadic program.
And put a runtime in place as well
because the free monad turns out
to be extremely expensive on stack.
So we created a trampoline
that allows us to do this.
The paper for doing this is available.
I'll give you the resources and I'll
give you the gist of the code as well.
But now once you do that, you effectively
haven't changed the syntax of what you're doing
except that the CNOT and the H and the jm
and so on are not quantum dot anymore.
And this gives us also the ability
for us to ask the sequence
to describe itself to us
in the way in which it will run,
so that we could then figure out what the cost
of doing the computation, for example, are.
But there are some severe limitations to this.
What we've gained is we formalized the
operations that are native quantum computing.
We haven't sacrificed
any performance for doing that.
We can kind of reason over what
the sequence looks like,
but clearly we can't ask
the program to analyze itself.
We can't look at the whole program
and get a sense of how many qubits it's going to take,
or how many sequence or operations
it's going to run and so on and so forth.
But this was an improvement in terms of clarifying
the approach that we wanted to take.
I put these links up.
The first one is actually the 13
Ways of Looking at a Turtle.
The paper that we implemented was
Runar Oli Bjarnason's paper,
Stackless Scala, but we put it in F#.
And this just actually contains the entire
F# implementation of the free monad.
It's only 150 lines long.
I'm not gonna walk through any of that.
But it's just to give you an idea that F#
played a critical role
in actually allowing us to crystallize
our idea of what quantum computation
was gonna look like.
So what we did at that point was we sat back
and said, look, this monadic context is very important.
What we need though is not just the monadic context,
but the ability for us to be able
to look at the monadic context
and then reason over it.
And also control the constructs in such a way
that what belongs to the quantum domain
doesn't get conflated
with what's not inside the quantum domain.
So we wanted to have an disparate type universe
that is only for quantum device.
And we landed needing to re-target the quantum
sequence wherever we wanted to do.
So it turns out that what we did was we took the
free interpreter and gave it some steroids.
And a free interpreter on steroids
is really a compiler.
So we created a little programming
language with it's own syntax
and the ability for you to now
reason over the whole program.
Because the compiler can now build up
a picture of what the thing looks like
and be able to execute that
against the quantum device.
So in some sense, we came back full circle.
In that, we came back to the solid context
where what the idea was that
we were gonna interpret everything.
But in doing so, what we've done is
we've cleanly separated out F# from what is Q#.
And the Q# piece can be
reasoned about in the Q#
compiler while it's being
exercised in the host program.
So if you think about this program, you can think
about this as the body with its own custom syntax.
The compiler is basically a being a beefed version
of the interpreter of the monadic interpreter.
And if you think that this thing
looks imperative and side-effectful.
It is.
Because it's exactly that.
It's actually performing side
effects on the quantum device
and on the quantum device only.
Because that's really the context
in which this whole sequence is run.
And in some sense, this justifies
why we have a new language.
Because we needed to have this
clean separation of universes,
so that the stuff that's running
on the quantum context
can be expressed idiomatically in
terms of just the quantum context.
So we were able to give it new syntax
constructs like repeat-until-fixup,
which turns out to be a very common
pattern to use in quantum computing.
And we're now able to run extensive
whole program analysis on the whole program
because we have full
control of the compiler.
So now you say, OK, you got this whole thing.
You created a new language.
How did F# play a role in it?
Well, if you think about Q#,
it's got some familiarity from C#.
It's got semicolons
and it looks kind of like C#.
But in reality, it's actually very
deeply influenced in its nature by F#.
It's fully functional in the sense
that functions and operations are effectively
[ inaudible ]
and you have first
order functions.
And everything's immutable by default.
If you want something to be mutable, you literally have
to do a very explicit thing by saying,
hey, I want this to be mutable
and now I'm going to set mutable
thing over and over again.
So it makes the code more ugly.
And I think it's justifiably so.
Of course, had some interesting
idiosyncrasies all of its own.
For example, it allows for partial application,
but not partial application like F# does.
In that, because we have
a tuple-in/tuple-out kind of structure,
you can pass in any number of the tuple
constituents and partially apply.
If you're input arguments
were five tuple of arguments,
you could potentially carry
in argument one, three and five
and it would a return a function that would take
the other two arguments and apply those.
So there's a little bit of charm that
we've brought into this language by itself,
but it's deeply influenced
by functional languages -
F#, in particular.
More to the point, F# is actually the tool
that we use for the entire development process.
The parsers that we implemented using fparsec.
And we have quite a powerful parser now.
All written in fparsec and does
a lot of the heavy lifting.
The compiler in terms of the fact checker and so on
and so forth - all of that stuff is written in F#.
The code generator actually uses another library
that I wrote a long time ago to generate C#
from F#.
And that's written in F#.
There's a BrightSword.RoslynWrapper library
that you can go down and get at.
And we generate all our C#
code for simulation purposes with F#.
And that document generator
entirely written in F# as well.
So there's a bit of influence in terms of the tooling
that we have that we use F# on a daily basis for.
And of course, F# can be the host language.
So we even have a sample where F#
can be used to control the Q# sequence
and actually get the quantum program
run from within the context of a F# program.
So in summary, F# has been instrumental
in getting us to where we are both
in terms of the evolution of quantum
computing as a growth pattern in Microsoft.
We have a quantum computing effort
that started over the simulator.
And through a host of very interesting,
very functional steps
landed up giving us a new language,
which we then implemented using F#.
And then, of course, the code generator
for the simulation runtime
and as a host language
for the quantum computing itself.
Both of those can be done using F#.
And that's in effect the tale of the two languages
that has led to the quantum
computing effort at Microsoft.
So I'm happy to take further questions.
Let me go back to the screen here and see if I can stop
sharing the desktop maybe.
How does it work?
- Yeah.
Just switch to the video.
Yeah, sounds good.
Thank you.
- OK.
- And we do actually have some questions
from people from F# Slack.
- Excellent.
- The first question sounds like,
"What the heck is qubit?"
"And why has the definition changed
so many times since biblical days?"
- Oh, well, it all depends on who wrote
the bible, to be honest - in terms of qubit.
So a bit is a binary structure
that stores a binary value.
OK.
So a binary value that you and I know
is typically zero or one, right?
In a two level binary system,
you have zero and one.
And a bit stores that information.
To actually store 2n values,
you need 2n bit strings, right?
Now, it turns out that from
a quantum mechanical perspective,
there's some interesting
phenomenon that takes place.
You can get many two bit systems
in quantum mechanics
that exhibit a property
known as superpositon.
And that property of superposition means
that you don't just store zero or one,
but you can store any linear
combination of the zero vector
and the one vector at the same time.
So the superposition principle basically allows you
to store an arbitrary set of values.
So in order to store 2n values
in quantum mechanics, you only need a qubit.
You don't need 2n bit strings.
And because that difference is very large,
you get a very big storage speed up
for several algorithms using that approach.
[ inaudible speech from unknown source ]
- Sound from the studio?
So we have another question, which is,
"Could you say a few words about
how Microsoft's specific approach
is different to measuring qubits differs
from other players
like D-Wave or Intel?"
- Wow.
So this is going to stray away from F#
if we go down this road.
So I'll give you the top level version.
And really the conversation about
what a quantum approach is like
I think is a different conversation
than the one we're gonna have in F#, to be honest.
But let me try to answer the question.
So it turns out that qubits,
quantum mechanical devices
that store the quantum
mechanical information,
are very unstable.
And they are unstable for many reasons.
Mostly because of interference with nature.
So the quantum mechanical concept of measurement
is simply a function of how the system is being
interacted with by another large system.
So if we take a qubit and you let it
interact with its surroundings,
that surrounding is going to effectively
measure that qubit and change its state.
So one way of actually solving this problem
is to change the environment,
so that you limit the amount
of interference that you get.
And one way to do that is to
chill it very, very cold.
And that's part of the reason a lot of qubits
actually work in the sub-kelvin regime.
So basically, you'll end up having
temperatures in the millikelvin region.
And the amount of interference that you'll get
from the outside is reduced significantly,
so your qubits can stay alive
for a bit longer.
There are other things that you can do though.
What Microsoft is doing is pursuing
what is known as a topological qubit.
The mathematics of this is actually
well beyond me, so I can't explain it.
But what I can tell you is something
sort of analogous to topology.
So if you think about a donut and you think
about the property of a donut
as something that has a hole inside it.
If you think about a donut that way.
You could do quite a bit of twisting
of a donut, for example,
before that hole is not
recognizable as a hole anymore.
As opposed to a ball right.
The moment you take a ball and you
deform it slightly, it stops being a ball.
But if you define a donut's donut-ness
as a hole in the center,
you can do a lot of things to a donut
before it stops being a donut.
And that means that the donut is actually more
sort of topologically stable than a ball.
And in some sense, the qubits that we're
looking at are similar in that regard.
They have a topological structure
that is capable of taking
a little bit more beating from the outside world
without losing its qubit-ness.
And in some sense, the physical qubit
is going to be different in that regard.
- Cool.
We have another question from Slack.
A person is asking, "I read the Q#
guide on the official site."
"And right now, the classical part of
the program has to be written in C#."
"I would like to ask if Microsoft plans
to expand the support to other languages?"
- Oh, that's absolutely not true.
Actually, there's nothing in the documentation
that said that it needs to be written in C# at all.
In fact, we have a demo written in F#.
And that's kind of the point
I was trying to make earlier -
that you can continue to use F#
in the host language of a program
and write the quantum part in Q#
and the host part in F#.
We, in fact, have a demo of the hydrogen
bond experiment written in F#.
So it's definitely possible to use
multiple languages to do it.
There's even support for Python
coming down the track.
We had a demo earlier in Python, but once we moved
to .NET, that sample doesn't work anymore.
But we're working on trying to get support
for multiple host languages to do it.
- Sounds good.
Thank you so much.
The talk was really interesting.
We learned a lot about how some
cool things are built with F#.
And I will disconnect from the call.
Thank you so much.
- Thank you.
- And right now,
we probably are going
to have a small break.
And stay tuned for
the next talk from Jeremy.
And we're just gonna have a small break.
