The best of both worlds?
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Subtitle |
| |
Title of Series | ||
Number of Parts | 490 | |
Author | ||
License | CC Attribution 2.0 Belgium: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/47013 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | |
Genre |
00:00
Formal languageFluid staticsAerodynamicsComputer programmingType theoryBitMixed realityDynamical systemFluid staticsLaptopMultiplication signLecture/Conference
00:34
AerodynamicsCodeFluid staticsIntrusion detection systemType theoryRule of inferenceHybrid computerData typeTypprüfungType theoryTypinferenzWeb pageCycle (graph theory)Formal languageConfidence intervalCodeArithmetic meanDynamical systemGroup actionCAN busInterpreter (computing)Object (grammar)Level (video gaming)Row (database)MathematicsMultiplication signRange (statistics)Fluid staticsPattern languageSoftware developerCompilerMathematical optimizationCASE <Informatik>Computer programmingWorkstation <Musikinstrument>MereologyPresentation of a groupDifferent (Kate Ryan album)Process (computing)Online helpForm (programming)Limit (category theory)BitSet (mathematics)Physical systemComa BerenicesPoint (geometry)EmailParameter (computer programming)WebsiteUsabilityLogicInterface (computing)FrequencyTask (computing)Error messageRule of inferenceVariable (mathematics)QuicksortMilitary baseProgrammer (hardware)Computer animation
08:07
TypprüfungData typeDataflowCompilerType theoryCodePhysical systemCompilerTypsystemString (computer science)Boundary value problemPhysical systemScripting languageType theoryProcess (computing)Programming languageGoodness of fitCodeSource codeConfidence intervalComplex (psychology)Arithmetic meanDescriptive statisticsAreaKey (cryptography)Computer programmingCore dumpMultiplication signNumberError messageDataflowMereologyFunctional (mathematics)Staff (military)CompilerMetropolitan area networkFitness functionDifferent (Kate Ryan album)Transformation (genetics)Escape characterImplementationString (computer science)Operator (mathematics)Tape driveFormal languageEmailElement (mathematics)Sheaf (mathematics)Data storage deviceCommutatorException handlingSoftware developerBitPointer (computer programming)Stiff equationMathematical optimizationMilitary baseRun time (program lifecycle phase)Array data structureComplete metric spaceLengthComputer animation
15:35
CompilerTypsystemError messageData typeString (computer science)BootingInformation overloadType theoryDataflowPairwise comparisonDylan <Programmiersprache>Macro (computer science)Read-only memoryObject (grammar)Concurrency (computer science)Default (computer science)ChainCASE <Informatik>Functional (mathematics)Sampling (statistics)Type theoryWebsiteWritingFormal languageStreaming mediaString (computer science)Computer programmingException handlingPoint (geometry)TypprüfungString theoryTouch typingWeb applicationMultiplicationDifferent (Kate Ryan album)Variable (mathematics)DataflowDynamical systemCodeRadical (chemistry)Right angleComputer fileComputer clusterPoisson-KlammerMultiplication signReal numberVideo gameGroup actionExecution unitOperator (mathematics)Subject indexingComputer configurationAxiom of choiceCompilerChainComa BerenicesLibrary (computing)ImplementationNumberForcing (mathematics)Pairwise comparisonTask (computing)Tape driveDemonBit1 (number)Boolean algebraProgrammer (hardware)Pointer (computer programming)Error messageGoodness of fitSemiconductor memoryExpressionMathematicsJava appletConcurrency (computer science)Parameter (computer programming)CoroutineIntegerFiber (mathematics)Web 2.0Server (computing)ResultantSoftware bugComputer animation
23:52
Multiplication signUniform resource locatorDataflowRule of inferenceComputer animation
24:23
Interactive televisionPoint (geometry)ProgrammschleifeMultiplication signBound stateMathematical optimizationDimensional analysisRange (statistics)Different (Kate Ryan album)MereologyArray data structureType theoryFormal languageCompilerSubject indexingForcing (mathematics)CASE <Informatik>Self-organizationMusical ensembleWindowMoment (mathematics)Computer animation
25:48
StatisticsFacebookOpen sourcePoint cloudMultiplication signLecture/ConferenceMeeting/Interview
Transcript: English(auto-generated)
00:09
Sorry for the delay in starting. I had a hell of a time setting up my laptop died last night. So apologies.
00:22
So I'm here to talk about static and dynamic typing crystal. Is it the best of both worlds if we can have both a mix a little bit of a compromise between static and dynamic typing. And that's what Crystal aims to achieve.
00:40
I'm going to talk a lot about static versus dynamic typing in this talk. And so it's a discussion that's raged for a long time online. And there's a lot have been written about static and dynamic typing, a lot of wars online and
01:00
arguments in IRC channels and mailing lists. But I've written a couple of points about both dynamic and static typing. Dynamic languages tend to be less verbose. Typically, when you talk to a static language, so a dynamic language, if you've asked, they'll think about Python,
01:22
they'll think about Ruby. And when you talk about static languages, you think about Java, C sharp. And there's a lot more verbosity in static languages historically. Now, that's not a trait of static
01:41
or dynamic languages specifically, but that is how they've evolved in the past, because type inference has not been up to the task of removing that verbosity. But now we're coming into a period where the distinction is starting to blur. And dynamic typing proponents tend to say
02:03
that you don't have to think about types in a dynamic language. But obviously you have to think about the interface of every variable in your code and every object in your code. As much in dynamic languages as in static languages. So you do have to think about types in dynamic languages. You just don't have to write them down as much.
02:23
And you think about them in a slightly different way, a slightly more flexible way. Dynamic languages, you tend to have faster development cycles often. So a good example of this is PHP. You just save your code and then refresh the page and your changes are live immediately.
02:44
A lot of people like that. A lot of people like that. And sort of the REPL style. REPLs are harder to do in statically typed languages. So dynamic code reloading is another thing which is a lot easier in dynamic languages than statically typed languages.
03:04
Easier to create complex DSLs because often type systems are a little bit stuck in their ways. They can't represent, they can't be flexible enough to represent complex DSLs. Or often you get some crazy generic crap
03:21
to represent your DSL. And sadly, a lot of people write in dynamic languages. They have an API, some JSON that they emit. And it's really not easy to use APIs
03:45
that have been made in dynamic languages in statically typed languages. Because you have, like JSON objects for example, it's hard to create types for those JSON objects
04:02
if you haven't thought about the types beforehand. And in the dynamic languages, obviously you don't have to think so much about the types. And it can make it harder to do. For statically typed languages, you have a promise that it works first try.
04:23
Obviously that's not catching all errors. There's a lot of logic errors, a lot of other errors, different error types which statically typed languages, statically typed languages can't detect.
04:41
But you can get stricter and stricter type systems which detect more and more of these errors. But for a lot of statically typed languages, it's mostly typos and everyone makes a lot of typos. So it does actually detect quite a lot of errors. It's easier to create tooling in static languages because your IDEs, your compiler,
05:03
all of the different tooling for language can agree on a way to work out the types of every variable. In Java, for example, it's very easy to work out the type of variable because it's written right next to it almost all the time. That's another form of verbosity. It helps the tools, but it doesn't so much
05:20
help the programmer. So yeah, you have a set of rules to work out the types. It's easier to write optimizers for static languages, statically typed languages, because you have a little bit of a better idea of if you know exactly which types of variable can be, you can have a much better guarantee. And optimizers are limited,
05:43
code optimizers are limited by the edge cases, not by the common case. So if you can remove all the edge cases of your code by having statically typed and more guarantees, then you can write better optimizers, write them more easily.
06:02
And a human aspect, statically typed, static types can help guide you towards cleaner code. It can help you write cleaner code because you have to think about it a little more. You have to think about how things are structured, what names you're going to give things,
06:20
a little more than in dynamically typed languages. And of course, types of documentation as well. If you've got a big code base, especially with newer onboarding and new developers, then it's a lot easier for them to navigate around if they know the types of everything and it helps them spot patterns
06:42
and look at the documentation above each type and they can quickly navigate around the code base. So recently, in recent years, a lot of languages have tried for a static, more hybrid approach. We've seen that with type lure, which was presented a couple of presentations back.
07:03
The examples I've got here are Python type annotations. Python has recently introduced type annotations to the language. They are easy to add to existing code bases incrementally.
07:22
They're easy to add to existing code bases incrementally. And I haven't used Python, so I don't know too much about them. But the type checking is performed by Linter, which is external to Python. You're not compiling your Python into non-typed Python.
07:41
You're checking it with an external program, which is unrelated to the Python interpreter. So it doesn't have to be 100% accurate. There are holes in your type annotations. You can always decide not to annotate something if you want to do something fancy.
08:01
It doesn't have to be 100% accurate, and that doesn't mean you have 100% confidence in your type system. You don't have 100% confidence in your types, in your code. And obviously, it means you can't perform optimizations based on the types, because you don't have any guarantee
08:21
that the types are actually being obeyed when you're running the program, because it's done by an external checking tool. So another approach to that is TypeScript and Flow, which are essentially typed JavaScript. They're different types of typed JavaScript,
08:41
so they're also easy to add to existing code bases incrementally. You take your JavaScript, you add type annotations. It tells you where you've messed up. And this time, type checking is performed by a compiler. So you have the TypeScript compiler, takes TypeScript code, and it emits JavaScript. And this means that you can influence CodeGen.
09:02
TypeScript actually doesn't do this, but you can have your types in your typed JavaScript influence the JavaScript code, which is generated, and you could perform optimizations based on this.
09:23
And so TypeScript and Flow are very interesting, because they've developed very complex type systems to model JavaScript. They've done a lot of work on pushing the boundaries of how to make a type system describe dynamically typed idioms very well.
09:44
So for example, flow typing, union types, TypeScript has intersection types, which are very interesting, and all these different innovations, which I'm gonna cover some of these later when I talk about Crystal, finally.
10:02
Because Crystal has some of these, too. But it's very interesting to look into TypeScript as a person who's interested in type systems, and they've done a good job. So yeah, flow typing, union types. But it still has a hole. You don't have to type everything,
10:22
because you still have to support the old JavaScript. You still have to support interacting with things that you can't type. There's a lot of code out there which you can't type in TypeScript. You'd have to create a crazy complex type system. So you have the any type, which means just give up.
10:44
So the TypeScript compiler doesn't do any checking. So you can't be 100% confident in any code which uses any. So this brings me to Crystal, which is what I work on. I'm a core developer of the Crystal programming language. It's been around for a couple of years now.
11:03
Have any of you heard of it before? Good, that's why you're here. So a bit of history about the language. It started as an attempt to compile something very close to Ruby, as close to Ruby as they could make it.
11:21
And it was never an attempt so much to have a typed Ruby, but it was intended to stick as close to Ruby as it possibly could. It started back in 2011 or 2012. A bunch of guys down in South America,
11:45
Harry and, they did a very good job in the early days of sticking very close to Ruby and making Crystal very accessible to Ruby developers. But we chose to, Crystal chose to break with Ruby
12:03
in a couple of key areas, which sets it apart from TypeScript and Python and type annotations by expanding beyond the language that we were influenced by and creating a programming language which is unique in its own ways.
12:20
For example, if you have an empty array and you access the first element in Ruby, you will get nil. In Crystal, you will get an exception. And obviously, because we're strict about nil in Crystal, if every array access could return nil, depending on the length of the array, then you'd have to check for nil
12:41
every time you do an array access, and this will make your code a lot longer. So we decided the only way to solve this is to raise an exception at runtime if you try and access an array element which doesn't exist. So in Crystal, it just returns T, the type of the array.
13:02
And we've removed some of the warts from Ruby as well, like postfix while. I don't think anyone needs a postfix while. It's very confusing. We've added some new things. It's turning on stiff. Really? Okay. So we've also got flowtyping and uni-types.
13:22
And it's quite easy to create beautiful DSLs in Crystal. And we don't have any holes. Everything is completely typed. There's no escape hatch into not being able to type something.
13:40
You're completely... You can trust the type system completely because you can't escape from it. So we're going to go over a few examples of the type system. So we like to think of Crystal as compile-time duck typing. You have an example here of a twice function. It's just X plus X.
14:01
Now, the plus operator is implemented on numbers and strings. So if you type twice of one, then you get two. Twice of high, you get high-high. And this function doesn't note any types, but it's still completely statically typed.
14:21
This is implicitly a generic function. So the same way you have duck typing in Ruby, if it looks like a duck and it quacks like a duck, it probably is a duck, then it works pretty much the same way. But the duck typing is done at compile time
14:41
and you can be completely certain there's no errors. So what is the type of X here? Is it one? Is it a number or a string? Or what could it be? Well, actually, under the hood, what we have is we generate two functions.
15:01
So the example, the twice function is actually generic, it's implicitly generic. If you give twice an int, it will return an int. If you give it a string, it will return a string. So this creates two different functions, two different function implementations
15:22
at the typing time and at the compile time. You have essentially two different functions, but they're represented by the same source code. It's generic. So we have complete type safety.
15:41
So if you try and do twice true, you get a nice little error, undefined method plus for bool, because all our operators are methods too. And you can actually get a really nice long error if you want, which gives you even more details of where it noticed that you were passing a bool,
16:02
and it can find where your boolean came from. So you get lots of options for nice errors. And we have type restrictions. So if you type restrict your argument X to int32 or string,
16:20
so this is introducing union types, so you can specify a type which can be either an int32 or a string, so a 32-bit integer or a string. And this restricts it so that you explicitly say that this function twice can only take integers or strings.
16:40
And you get a slightly nicer type error if you do that, because it doesn't have to go through and find out where you've made the error. It can just say you passed in the wrong type to this function right away. A bit of an example about unions. So you have the gets function. It gets a string from the terminal. It can return the string that you typed in.
17:02
Or if you have an EOF, like you press Ctrl-D at the terminal, end of file, it can return nil. So if you write this code, hello, what is your name, hello, your name, you get an error, because gets can return nil.
17:25
So a way to solve this, so yeah, gets returns string or nil. We have flow typing. So if you assign your name to gets,
17:43
and if you check, you can check whether a name is nil, and the compiler will infer that inside this if branch, name cannot be nil. Name cannot be the nil type. So then you run this code again,
18:02
because you've essentially said to your compiler, if the end of file case happens, and if gets returns nil, then we will do nothing. We will not print any string at all. And that will compile, and you've saved yourself a bug.
18:20
We have this function, cromulate. Another example of flow typing. Here we have a perfectly cromulent function. If you type it, if you give it a string, then it will take the third character of the string. Or if you type in a number,
18:43
then it will give you two thirds of that number. It's a bit of a weird function, but it's a weird example. And this will actually give you, so what I'm trying to demonstrate here, sorry, is that the value can take a different type,
19:04
depending on how you've restricted it. So obviously the bracket, the indexing for the third value will not work if it's an int32. So if you restrict value to a string,
19:21
then obviously you can then do that indexing operation. And if you restrict to an int32, you can multiply it by two and divide it. So here at the bottom I've got the different instantiations of the cromulate function as well. Okay, near the end.
19:41
Another real example of flow typing this time, this is in the standard library. This is uri-resolve. It resolves one uri versus another one. So example, if you have example.com uri, and then you try and resolve index.html relative to that,
20:01
you will get the uri-example.com forward slash index.html. So at the start of this function we need to work out if you've passed in another uri or a string to this function. So if it's uri, it will duplicate the uri, otherwise it will pass the uri from a string that you pass in.
20:22
This is one function which takes a union type and then it will, based on that union type, it will do a different thing. And this is flow typing because the target variable
20:40
has a different type, multiple different points in this function. So at the top here it's a uri or string union. Here it's only a uri, so you can call duplicate. And here it's only a string because you've removed uri from the union.
21:02
It can only ever be a string here. So you can pass that string into uri.pass and get another uri. And at the end of this if branch, then target will be a uri because you've written code to ensure that. So we're going to end up with a comparison of Crystal
21:21
versus how we've done essentially, how Crystal does as a dynamic language versus a statically typed language and how it compromises between the two. So types in Crystal aren't mentioned more than dynamic languages.
21:41
So you can write Crystal code and it looks like Ruby, it feels like Ruby, and you don't have to write types all over the place like Java or C sharp. Types change and flow like a dynamic language, the flow typing that I've demonstrated in my examples. You don't have to think about one variable as not one type.
22:05
It can change throughout the course of a function and you can write neat code using that and write code which feels a lot more familiar to you as a dynamic language programmer. This, I haven't covered to you itself,
22:20
but if you look in the documentation, it's a very nice way to allow expressive type safety SLs in Crystal, which is something which I think Crystal excels very well at. We have nil safety. Everything is checked. You will never have a null pointer exception like in Java.
22:41
You will never have one of those again if you use Crystal. You have memory safety as well. There will never be any segfaults in Crystal unless you use unsafe code. And other good things at Crystal, it's object-orientated like Ruby.
23:02
We have CSP concurrency, so if you've used Go, we have a good implementation of, essentially the same thing as Go routines and channels. We have fibers and channels, and so Crystal is very good at concurrency. Everything is asynchronous I O by default, so it's very good for developing daemons,
23:23
web applications, servers. A lot of people use it for that. We've got a simple toolchain. It's a very easy to use toolchain at the command line. Very fast generated code because we have all these guarantees about types. We can use that, feed the result into LVM
23:40
and get essentially code which runs at the same speed as C, but it feels like a dynamic language and it looks like a dynamic language, but you get all the type safety as well. So try it out. It's fun. There's a URL. Crystal Lang. Finished right on time apparently. Ask your questions.
24:08
Does it take time for a question or two? Nothing. I did well then. You, what's the question? The flow typing? Yes. Does it resolve loops?
24:22
Yes, it does resolve loops. Essentially, there's a fixed point. The question was how does Crystal deal with, how does flow typing interact with loops and essentially there's a fixed point which the Crystal compiler can work out.
24:41
Yes? In the example where you have the array, can you load the dimensions of the array as part of the type? The question is with bounds checking for arrays, is it possible to look at the possible range of values
25:04
that the array index can take and allied the bounds check in that case? And the answer is no. Crystal can't do this optimization just yet, but it's something we'll probably look at later. We're focused on getting the language to 1.0,
25:23
supporting Windows, other different types of things before working on optimizations like that. Thank you. We need to switch speakers because they're both also volunteers in this room. It gets complicated now. Thank you.
25:41
Okay, Steph, can you man the camera during the talk? Then I'll ask... Thank you. Then I'll ask to time you. Do you like it? And then when you're done with the talk, Steph should do the timing. Do you have the speakers okay? And make sure it's straight. Yeah.