WEBVTT

00:00.000 --> 00:12.000
I want to talk about effective handlers in particular in the fusion language and how they

00:12.000 --> 00:18.000
are used in there for error handling and how designed by contract is done in the fusion

00:18.000 --> 00:25.800
language. A bit background to myself and how you can reach me. Putting in short, I worked

00:25.800 --> 00:32.600
on computers all of my life with a long-term working on Java implementations for safety

00:32.600 --> 00:40.040
critical applications and now since five years I'm working on the fusion language and now

00:40.040 --> 00:45.640
within Tokyo Software Small Company where I lead a small team of four developers working

00:45.640 --> 00:53.000
on fusion. The overall view of my talk is I will start with a very quick overview of the

00:53.000 --> 01:01.320
fusion language, then give you an example of error handling that will then lead me to

01:01.320 --> 01:07.560
explaining what design by contract is, then I will explain what effect handlers are and how

01:07.560 --> 01:14.200
they can be used to implement design by contract and then how a hierarchy of errors,

01:14.200 --> 01:19.240
foldable, could be made and if there's time I'll talk a bit about a cool feature in that context

01:19.240 --> 01:25.800
which is type constraints. So the quick entry to fusion, I wrote some stickers maybe if somebody

01:25.800 --> 01:33.960
is interested in us, then I'll take as many as you like. The idea behind fusion is to have

01:33.960 --> 01:38.920
a simple language to basically base everything on one concept, the concept of a fusion

01:38.920 --> 01:45.640
feature and the idea behind that is that our systems are becoming more and more safety critical

01:45.640 --> 01:51.640
and we want to make it easy to develop correct code for those systems and making it easy by

01:51.640 --> 01:58.840
having tools that help the developers life to correct to analyze the correctness of the application.

01:58.840 --> 02:06.280
So fusion language is statically typed, it is polymorphic in several ways, it has union types,

02:06.280 --> 02:12.920
it has parametric types, generics and it has object oriented style inheritance and it's a pure

02:13.000 --> 02:19.560
functional language where everything that is non-functional, non-pure is wrapped into effects.

02:20.840 --> 02:28.360
A start of with an example, my very small example here is a function that takes an x and returns

02:28.360 --> 02:37.160
to string that shows x and the square of x and the x is any numeric parameter. Fusion uses a

02:38.120 --> 02:43.960
syntax sugar so actually this is a short form for a function that actually has two arguments.

02:43.960 --> 02:52.120
There is a type parameter n that is numeric and a value argument x that is a value of that type.

02:52.120 --> 02:56.600
So basically this is a generic function here but I stick with the short version.

02:56.600 --> 03:02.600
And I can now run this giving different arguments of different types, here's an integer

03:02.760 --> 03:14.840
fraction or complex and I will go to the fusion website where I have this talk and where you see

03:15.880 --> 03:23.560
the examples so I can run this example now and it will then calculate the squares and print those

03:23.640 --> 03:33.880
free strings. If I extend the example and call the square function with a byte, an 8-bit integer

03:33.880 --> 03:40.600
and provide the value of 30 that will not so the result will not fit into the byte.

03:41.240 --> 03:48.200
What will happen is I will get an awful error in the middle of the code. So

03:48.520 --> 03:57.800
the question is now how can we do this error handling better. One approach is we could just add a test

03:57.800 --> 04:03.000
in our square implementation if the multiplication would overflow and perform the calculation only

04:03.000 --> 04:09.160
if it doesn't and otherwise we panic and if we run this so we check this and we panic.

04:10.040 --> 04:16.600
Panic is an effect so we have to mark this in the signature of the function that this function requires

04:17.560 --> 04:23.400
the panic effect to be executed. And when we run this we get the default implementation of the

04:23.400 --> 04:33.880
panic effect which then produces this overflow for 30 output. The problem is it fails here the problem

04:33.880 --> 04:40.040
is who is actually to blame for that? Where is the bug? Is it in the square function? That panic

04:40.120 --> 04:46.600
or is it the caller who just provides arguments that cannot work with that function?

04:50.600 --> 04:55.720
This is where designed by contract comes into play. Design by quantity of the

04:55.720 --> 05:03.320
ideas that we formally specify for every function. What preconditions has to hold has to be

05:03.320 --> 05:10.760
satisfied by the caller to call that function and specify then what guarantees that function can

05:10.760 --> 05:17.640
give after it has executed the post conditions. So the function provides a formal contract for

05:19.400 --> 05:24.600
via the pre-inpost conditions and this is used for several things. It can be used for runtime

05:24.600 --> 05:29.880
checks like the panic we had right now but it can also be the basis of static analysis tools to

05:30.040 --> 05:36.840
verify correctness or to generate tests and lots of other nice things. So doing the same function

05:36.840 --> 05:45.160
with pre-inpost conditions we can now put the at the pre-condition that there must not be an overflow

05:45.160 --> 05:51.400
when multiplying expire itself and we could add post conditions like the result is never the empty string

05:52.120 --> 05:58.920
and the implementation of the function becomes very simple now and when we run this

06:00.200 --> 06:07.560
we get a pre-condition for which clearly indicates that the caller here then provides a type

06:07.560 --> 06:16.840
that doesn't fit with the desired calculation. Now fusion uses effect purpose you've seen that

06:16.840 --> 06:23.800
in the panic example where panic effect was used so let me quickly introduce to you what effect

06:24.520 --> 06:31.080
are. An effect handler is a set of operations and these operations may have

06:32.040 --> 06:40.520
side effects like reading or writing data to a file. These operations may produce a result

06:40.520 --> 06:46.920
like when you read from a file you might want to get the data that was read or an operation

06:46.920 --> 06:55.800
might also abort which is what typically a call to panic would do and to use the operations

06:55.800 --> 07:04.040
of an effect handler the effect must first be instated for the context where these operations are

07:04.040 --> 07:14.120
supposed to be used. And effect handler for error handling this is now a part of the standard

07:14.120 --> 07:23.240
library of fusion where a handler forable is defined which inherits from effect so it's an effect

07:23.240 --> 07:33.720
handler and this is the template for errors to be defined in the fusion language and this has

07:34.360 --> 07:41.880
a feature try that would instate an instance of that effect and run some code and

07:42.200 --> 07:53.240
within that code that effect or that code can cause this error. Here's an example this can be used

07:53.240 --> 08:01.240
to create your own error, my fault within this case and we can use this we can call try and

08:01.240 --> 08:08.520
in within the code that is executed here we can then cause that error and we have a way to catch

08:08.600 --> 08:16.520
this error looks very similar like exception handling in other languages so yeah I've explained that

08:19.480 --> 08:26.360
now using going back to the the panic version of the spare example using these

08:26.360 --> 08:36.840
effect handlers we can now instate our own instance of a panic handler and run the code from

08:37.000 --> 08:46.200
the spare and in case that panic can catch that error print a message and we call square again

08:46.200 --> 08:52.440
with a larger the actually unlimited integer type to run it again. If you run this we see

08:53.400 --> 08:58.920
that we got that error and we're trying again and then we got it get a proper result.

08:59.080 --> 09:08.360
Now, question is what happens for pre and post conditions only have the pre condition here to

09:08.360 --> 09:15.960
make the example a bit simpler and fusion as I said uses a lot of syntax sugar actually pre conditions

09:15.960 --> 09:25.400
are just syntax sugar for a pre condition fault error very similar to the panic example and

09:25.480 --> 09:34.040
that means that we can also instate our own version of the pre fault and run code with that

09:35.160 --> 09:45.320
and catch this so basically this condition if that fails would cause then the same behavior as

09:45.320 --> 09:53.240
the previous example so this causes a pre condition fault which then ends up here and we can run this

09:53.320 --> 10:09.080
again and it runs successfully. Now, we have a number of fallables in our basic library and

10:09.080 --> 10:15.000
showed you panic pre fault at this fault fault is checks and there could be user defined and

10:15.000 --> 10:23.320
many more. For proper error handling what we would like to have is some kind of hierarchy if you

10:23.320 --> 10:31.000
use to Java you have this throwable hierarchy where you can catch throwable or arrow at the different

10:33.080 --> 10:40.920
areas so the question is how do we do that in fusion and the solution is we have a cascade of

10:40.920 --> 10:51.080
fallables so we have a most general fault which is the most basic error and then panic the default

10:51.080 --> 10:57.560
implementation of the panic fallable actually is implemented using the fault so it doesn't inherit

10:57.560 --> 11:04.840
from that but the implementation that propagates the error further to a fault and the pre condition

11:04.840 --> 11:11.400
and post condition faults you have seen they don't directly propagate to fault but they

11:11.400 --> 11:18.680
propagate to some intermediate a foldable which is a contract fault and that then propagates to that

11:18.680 --> 11:26.280
fault so the user can now decide what level of falls it would like to handle when it wants to

11:26.280 --> 11:31.800
catch those. There's also check falls that could be IO falls or network defaults in all

11:31.800 --> 11:38.280
points so on. Do we have two minutes? I have four minutes okay and I'll quickly talk about

11:38.280 --> 11:44.360
type constraints because they are cool feature in this context if I go back to the square function

11:44.360 --> 11:51.960
and I call it now where a huge floating point argument and I expect this to fail because this

11:51.960 --> 11:57.800
overflow but it doesn't fail I still get the infinity and the reason is because floating points

11:58.360 --> 12:02.920
is just that this doesn't overflow on multiplication just perfectly produce the infinity.

12:02.920 --> 12:10.840
If I want to catch this error what I can do is I can actually put a constraint on the type

12:10.840 --> 12:19.240
parameter I can say if my type parameter is a float I want to have a stricter precondition here and

12:19.240 --> 12:27.720
if I do this now I can also in this specific case get an error for that so we can really

12:27.720 --> 12:36.280
work with these type parameters pretty much like compile time values doing all sorts of special

12:36.280 --> 12:45.880
things there. So that's it I come to you to the end. The status of fusion it's still

12:46.680 --> 12:52.520
underdeveloped into the whole project. The language definition is getting more and more stable.

12:52.520 --> 13:00.760
We have back ends for Java VM Java by code and C code and we have foreign function interfaces

13:01.480 --> 13:09.640
more or less working for Java and for C we're working a lot on the basic libraries and static

13:09.640 --> 13:16.280
analysis tools and we have first applications that are being developed and since last month we

13:16.360 --> 13:23.800
are part of European project in the idea framework called green code with lots of partners all

13:23.800 --> 13:32.200
of course rule Europe we're trying to improve that language. That's it you can find more information

13:32.280 --> 13:37.400
at the sandals please follow us give us stars.

13:46.760 --> 13:49.720
Questions?

13:54.280 --> 13:56.280
Can you repeat?

14:02.200 --> 14:16.760
Let's say that you have a function that can produce multiple type of effects like I've

14:16.760 --> 14:23.800
followed some of those you show how you do with those cases. That would mean that the function

14:23.800 --> 14:31.320
in that signature would have to list all of those effects as effects that are required by this function

14:31.400 --> 14:37.160
and now when this function is used the call can then be side what it wants to do it can

14:40.200 --> 14:47.000
run this code with specific handlers for part of the effects that it wants to to handle and leave

14:47.000 --> 14:57.720
the rest to the default handler which is a fault or it could just be more general and

14:58.680 --> 15:05.800
handle the more generic fault in any cases and catch all the errors that could happen in

15:05.800 --> 15:16.840
there. You can have multiple touches. They can be nested so whatever matches would then be used.

15:16.840 --> 15:21.960
You don't need to cover all of them you can have so you just use the default for whatever you don't

15:21.960 --> 15:28.200
handle. But if you use the default that means that your code yourself actually causes that effect

15:28.200 --> 15:32.360
it propagates and the call of that has to handle that.

15:37.800 --> 15:43.320
If you so you should some examples with three conditions assuming you have

15:43.320 --> 15:47.640
enough information at compile time with precise types like single type sorry

15:47.640 --> 15:53.880
payment types can you avoid having to install handler like can you statically check the things.

15:58.200 --> 16:01.320
What kind of things do you want to have checked statically?

16:01.880 --> 16:07.640
So if you know statically but the input of square is like 10 you know it's never going to overflow.

16:08.280 --> 16:13.640
So in that case do you still need to install handler or can you statically know that you don't need it

16:13.640 --> 16:21.480
and then optimize it away? What we do right now already is we specialize the code for

16:21.480 --> 16:26.760
these specific types like for the for the float there's only the specific version for float that

16:26.760 --> 16:31.320
is put in and if it's called with an integer the specific handling for float is completely optimized

16:31.320 --> 16:38.360
out. What we don't do yet is propagating constant values that are passed in there but it is a

16:38.440 --> 16:45.080
pretty straightforward compiler optimizations of specializing a call for a constant argument at this

16:45.080 --> 16:50.840
pass so we don't do it yet at the moment but that eventually we'll have to have to be done and

16:50.840 --> 16:58.120
it's not very difficult. Time for one more question or if you use this one.

16:59.080 --> 17:01.320
Ah, this one. Ah, okay, this one to Andy.

17:15.880 --> 17:23.480
The tri function is is a function in our standard library for the fallable effect and it does quite

17:23.560 --> 17:29.080
a bit of thing it actually creates an instant instance of that effect in states it and then calls

17:29.080 --> 17:40.360
the code that is passed to that function. Yeah. Okay, I think I'll have to leave. Thank you.

