Introduction to Reason

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so hi this is actually this is a bit of a funny position to be in I don't really work in F shop so I'm giving a talk at F sharp Sydney on a language that is an F sharp to F sharp developers and ironically I'm actually going to have the least JavaScript content in my talk out of all three tonight so it's a it's a bit of an ironic position to be in I'm going to be talking about reason which is a new language for a camel but just before I get started there's a few people I'm assuming that everyone here works in F sharp or hobbies and F sharp or is familiar kind of with like F shop how many people are familiar with a camel you've got a couple of people um the way that this talk is going to run is I'll give a very very quick introduction to what reason is and why it exists I'll show off the the slight differences in syntax between reason and F sharp just you're comfortable with what the the language itself looks like and then we'll run into some things that you can do in reason that I don't think you can do an F sharp this is all based on like research but without practical application if I'm wrong and if you can do something please tell me because I'll take it out and feel a little bit ashamed um but so we'll get started I'm Jacob it's nice to be here thank you for having me and today we're going to talk about reason so reason reason is not a transpiler so javascript it's not a JavaScript compiler tool chain it actually has very very little to do with JavaScript reason reason is a syntax over a camel so a camel is actually a really pretty amazing programming language in that you can write front ends for you can write language syntaxes for it that are totally compatible with the by coding with the language but look absolutely nothing like the default syntax for the language so there is Lisp like visual implementations of Lisp over oh camel there's reason coming up now there's the the language supports something called a PBX system which is a way of writing essentially extensions for the compiler that support all sorts of syntaxes so reason is a new syntax over the top of it but it it supports all of the same paradigms that all supports so we already have a camel and we already have a large number of like syntactic fund ends for a camel why why would we have another one why would create another one and a little bit of the reason comes back to this pretty important paper has everyone here heard of darkus has everyone everyone who had if anyone hasn't heard abacus have everyone heard of like Fortran there the scientific language so Bacchus was actually the I think the architect or at least the the the chief implementer of the Fortran compiler and in 1977 I think won the Turing award for his implementation and the was invited to give a paper and give a lecture as a result and the lecture that he gave in the paper that he gave was called can programming be liberated from liberated from the von Neumann style of programming which is the the imperative of procedural style of programming and this has kind of been the question the forefront for functional programming for a long time is there are all of these imperative and procedural languages that exist kind of at the forefront of the the industry but there's a kind of a push happening consistently as functional programming languages come out of can we can we win develop a mind share can we find enough reasons to use these things enough reasons to use these things without kind of losing people at the edges of it and one of the big reasons for reason is the intention to push a lot of what what is thought of as the meta language of functional programming away from the actual language so what you have to learn when you come to the language isn't a very conceptual all you really have to learn to come into the language is the language itself and how to implement it and everything else is kind of pushed away you don't have this this big hump to kind of jump over to get into the language the intention is very much to be able to get in and be productive as soon as possible and so the way that they kind of approach that is by looking at the syntax and identifying the syntax and then kind of workshopping the syntax with the community to try and find the most efficient and the least kind of friction in the syntax possible without giving up any of the actual underlying language features so if you look at JavaScript code and JavaScript developers javascript is one of the most widely used programming languages on the planet when you try and identify how can we take people who write Java scripts for a living and introduce them to these new concepts without also having them have to learn a whole new syntax for no actual additional like value in in an in a sense the the underlying concepts of functional programming are very like separate from whatever the syntax of the language that you're using to program them in so we have this JavaScript function which computes a computer song and here we have the same thing for reason and the reason the reason syntax becomes a lot closer to JavaScript than it does to Oh camel and it becomes a it becomes like it adds in a whole bunch of other syntactic properties like semicolons like commas in a bunch of places it changes a lot of things that are camel either elides or does differently and a lot of the thought behind that is people who are coming to these languages for the first time are more familiar with C syntax or with JavaScript syntax with PHP syntax than they are with a camel or with Haskell or with any of the more functional programming languages the fewer things they have to learn at a time the better so we're going to sprint through the syntax because the the underlying language grinches website the underlying language features are very very similar to f shops so we'll start with functions the first function defines a function where it takes two variables and just returns the first variable and ignores the second so you have the ability to define functions using the let keyword so exactly the same as f shops you can name them you can tell them the kind of arguments that they need you can ignore the types and the compiler will figure them out for you you can define recursive functions again the same as f sharp even with the same recursive keyword since both F sharpen and reason have their roots in the ml system you can define mutually recursive functions so you can say is even as a function that depends on a function is odd defined as needing a function is even and to find them as mutually recursive which is quite a nice trick we have parametric polymorphism so we have the ability for a function to say it takes any arbitrary a and returns an arbitrary B returns an arbitrary eight doesn't matter as long as the implementation details of the function don't rely on knowing the concrete type of the variable passed into the function so here we have Const context and a to a B to an a and we have here the implementation is fun XY return X we also have a an interesting feature of the type system which is you can kind of trick it into into not giving you the right answer so here we've defined wrong Const as takes an a takes to be returns an a and fun X Y returns Y now because x and y aren't concrete the compiler says I'd like to make that work so we'll make be the same as a and we'll return because we're returning Y and you've told me that you return an a type B must be exactly the same as type I type a which is not quite what we'd want so we introduced the ability to define types is different so essentially for all and we can see here that the locally abstract concise which defines a type a and a type B when we we can say return a and we promise you that we bind this type in this place but without needing to be explicit in this in this function and then we have the ability to find a for all as well so this is all pretty similar syntax I assume so what F sharp gives you we also have simple types so we have abstract types you can define a type T and not need to give it an implementation you can define the type is int and tell it that it's an int you can define abstract you can find say algebraic data types so you can define a some type and say that it's red or green or blue and use those as constructors and those will show up again a little bit later and you can also define product types so you can define that a type is a couple of int + int or int and bool of any two combinations of types um you also have mutually recursive types so you can define types as depending on each other's implementation so here we have a tree which depends on a forest and forest which depends on the console and list of tree and you can use those definitions to build up very rich data structures so so far things have probably looked pretty pretty similar I would wager so we'll jump into things that like I said that I don't think you can do an F sharp at least I couldn't find ways to do them or I found a lot of people saying I can't do this thing and I wish I could again if I know that there are there are a lot of alternatives but this is focusing on the like the actual implementation not an alternative implementation for the future so the first one we'll start with is labeled arguments so from what I saw F sharp has labeled arguments for members so for classes or for records constructors like that but reason actually have labeled arguments just for defined functions so you can label in this case we've defined a function CSS that takes an argument display and we bind display to a variable named display and we say that it has type string we pass it into the function and then we build a string concatenation building a CSS string and so this will give us the the string display block when we call it CSS and the labeled function labeled argument to the function passing block as a display but we can go a step further there's a really cool thing that you can do with labelled arguments which is you can actually give them default values so here we've said display is bound in the variable display and is by default the string block and there's a second argument width which is bound in the variable width with a type string so now if we give display flex we get back flex and we give width 50 and we get back 50 or if we don't give display at all if we completely ignore display in the function invocation the compiler basically goes cool I'm going to set that as whatever the default you gave it to me and we'll just take whatever other arguments you have this is really helpful in a few places especially with like an SSI system where you might have a lot of possible options into a function from an external and external source and you don't want to have to define at use time every single input when you're setting some of them to none or setting some of them to not being used instead you can give them defaults in the in the function definition and then just ignore them when you use them so this is used in a lot of styling libraries what you don't necessarily every potential CSS object is not the same as the ones that like the three that you want to use for the element but we can go one step further which is every single argument for a function can be labeled and defaulted and not supplied at invocation time as there is at least one concrete value being given and in this case if that value is unit so this is where we see that reason is not pure you can give it a centrally a function of a unit and return something that it has no way to really compute but what you can do here is we can now have a thousand possible entries to a function and supply none of them and get back a useful value so this is the very very powerful feature of the labeled argument syntax for for reason and unit in this case is supplied as the the two parentheses with no value inside them it's basically just like a like a void value okay so the second thing we'll look at is the module system so I know that F sharp has a module system but I've also seen that it's not like a first-class module system it looks like it leans quite heavily on classes and our members and on those kind of abstractions so reason and by proxy or camels module system is first class and what that means is the same way that functional programming language is often defined as the ability to pass functions around to other functions modules in reason are able to be passed as variables to other functions so we'll take a look at what that looks like to start with I'm just going to show you what the type definition for module looks like this should look pretty similar so we define a module type of list we say that it has a data type a locally bound data type of T which is abstract over a and it is a algebraic data types so it has a null constructor and a cons constructor and that's how we just build up a list and we have one one member length and length takes a list effectively and returns an int which is the length of the wrist so this should look pretty pretty pretty similar to a lot of things you'll have in F sharp so now we can build a structure that implements that type so now we build a module list and we say that for the type TA we has a null and we have a cons constructor and we implement length of list using pattern matching and we switch on the patterns that we have for null and for cons and we construct the function that returns us the length but we also have the ability to use these things as local invitations or as global implications so if list is available in the namespace so we can use any method on list locally internal so the the module or like available within the main space so here we define the module again and we create a list by calling let in to list B list cons one cons with list cons of two cons with list of cons of three with the the anti list not and we build up a list that way but it's quite tiring to have to type list cons list calmness cons mr. cons instead we can actually set up what's called a local open where in the second example in the list with with a apostrophe we set up a list where we call list dot and then we open parentheses within those parentheses the first place that it will look up for a function for a member will be within the list module so they'll go cons is a member of the list module so I can just call that function directly on the list and I can do that within this kind of local namespace it's like setting up a block while setting up a like a local open explicitly and the next line down with a with two apostrophes is what is the like the the same way of doing that so we have a local open where we open the module locally and we can access the methods of that module locally inside that block directly so something that I don't think F sharp can do is mutually recursive modules so if I have two modules that I wanted to find and there types of a methods depend on the definition inside the other module I can define them as mutually recursive now I haven't needed to do this in building reason code targeting reason but when I've been building FFI systems to the web audio spec in in a browser there's a lot of different objects that depend on other objects that depend on the existence of the first object so like the audio context object for instance has a lot of members or a lot of properties that are used by other objects that also then depend on the audio context object it also then depend on any of its children and it's a lot of it's a lot of like roundabout obstructions the ability to find these things is mutually recursive means that rather than time it'll host things out of a module where they belong into some shared abstraction that is a way from where it's actually used to just so that you can use it in two places instead you can define modules as mutually recursive and share their definitions at definition time so that's what we're doing here we're defining the module food the saying that has a type equal to int and it has a method bar that will give us a bar T or it has a value bar sorry that will give us a from the module bar its value its type and we define T events and we say the bar is the string three and then similarly we define bar as taking type T string and we say we have through which uses an int so again this way they're both defined at define time but they're able to use each other's definitions before they're actually concretely defined but you can actually be a little bit more clever and reason will basically alive most of that for you if what you're doing is just defining the type definitions it will take care of the implementation and just say don't worry about that the type definitions match up these things are mutually recursive that's fine so that's what the second example does where it defines them even without the implementation it just takes the types which is quite a like quite a cool trick if you're building up very complex type structures and then I mentioned first class modules so you can actually pass the modules into a function and use them modules are just structures you can just basically pass them around as you would pass variables or Israa pass other data types so in this case we build a module type bumper and we build a module in bumper and you can imagine then that maybe we have a float bumper and we have a string bumper and we have a bunch of other bumper implementations and we have a method bump list where we take a list and we want to supply the bump method for that the members of that list but we don't know when we're writing the bump list and we don't want to know when we're writing the bump list function what those types are we don't wanna think about it we just want to be able to write some abstract higher function so instead what we have here is we have led bump list and we say for some type a for any type a and for a module be where you are of the type of bumper and your inner type is the same as the type a that I've just said is local to this function I would like you to take a list of a and apply the bumper modules method to each element of that list and return list and that's exactly what we do we are able to save bump list take module into bumper so we supply the we supply the module structure we've just defined and we turn it into a first class module by calling it with module in front of it we pass that into a function and we call it with a with the miss one two three four and that's the same as that's basically being able to pass in an arbitrary object that has a number of methods on it that applies to each of the elements inside the list so we can get towards a what I'll show in another couple of slides like we can get towards some of the dictionary passing methods to simulate higher kinds of types by being able to build up these abstractions and then pass them into functions that don't really know about the implementation details so what comes to we'll come to that in a couple of slides but the other thing that's really cool is because we have first-class modules and because modules map one to one with the file system we have such class files so the two files here are list rei and list re and listed rei is the same as defining a module type it's a way of saying everything in a related implementation file has these characteristics so we can say here we've defined type T of a as null and cons and we've defined their length as taking a T of a and returning an integer so this now says that there will be a list re file that uses this type and exposes these methods and works this way and indeed there is there's a list of re that gives us the same implementation as the list that we saw before and when you pass when you use that module you're actually just referencing the the file system so the lists are each file doesn't actually use the keyword module it doesn't define a structure explicitly it just defines types and methods and properties but the compiler and the language turns that into a module and makes it available automatically to any other module or any other file that wants to use it so the files on the file system are actually first-class which is a pretty cool feature so we'll jump into functions but they're not the same kind of functions like Earth Map filters they're not they're not functions from A to B F 8fp what they are is a way of basically mapping module behavior to other module behavior they're a way of being apps back in the type of something that you're passing into a function that creates a module from that site they're abstractions are the types of modules so what we have here is a module functor and the module functor has a type defined locally of input of type c and it has a type of module type output of type so that includes the type T from input and here we have a module make and you'll see the module make definition is a little bit different so the other modules we've seen so far it actually looks a lot more like a function because it's a module function it's a function that takes a module and produces a module so we have make which is defined of taking a variable input of type input and it returns a variable output so it turns a type output whose type T whose a locally defined type T is of the same type as the input T and we just include input and pass that through so this is this is a pretty powerful structure and the reason for that is that we can actually make F map functors this way we can make we can make a whole bunch of really really nice abstractions using these tools so we can here we create a module functor that is an actual F map functor and we say we take any type s who has a type like a boxed abstraction over any a and we define a method F map from A to B for any TA to any TV and we define a module type sponsor which includes s and defined the the Haskell operator for F map left angle bracket dollar sign right angle bracket as an infix operator and we just basically alias we highlight the region's going to alias the F map functions supplied by the input to the the F map infix operator supplied by the output and then we have a function make with a module function maker sponsor that will take an S of type s and will return a sponsor with type T of a as the same as type SC of a and all that's doing is basically saying return something at your output whose input types are the same and so we include s we take anything that we've defined on s and we make it available at the top level to the the module that we're actually returning and we define the method F map we'll find a method left angled dollar right angle pronounced F map as just being the same as the the word f map and so now we have the ability to define as many of these F Maps functors as we want so we can define the option type as including the function make and we say that your type is going to be an option wrapping any arbitrary egg and we're going to define F map for you as taking a function and taking your optional value pattern-matching on the optional value and if the if the value is none then just returning none and if the value is some of something applying the function f to the value inside the option and returning some wrapping that value and now is defined f map so now when we want to apply a function to the inside of an option value we can apply it similarly for the list from third we do the same for the list we define death map as operating a fold over the list and consoling the values and so we now take any function f that operates from A to B we take a list of a's and we return a list of B's so this is pretty cool but we can see that the the F map is not ad hoc it's not ad hoc polymorphic so it's actually the opposite of ad hoc it's very specifically polymorphic there isn't a way to send like F map just a bear function invocation to the right from 0 to the right module at compile time we have to be explicit and say we're using a list and we want to use the list F map function use it in this place it's not like Haskell or AG 0 address or any of the higher kind of type functional programming languages it just gives you the ability to find these really nice abstractions or the modules so in this case what we have here is a another function at demo that takes something that is of type function and runs means to build these two these two functions on it so example one in examples are and so we build a list demo by supplying the functor list to the functor demo so the module list to the the func of the demo and we build out something that can run those two examples and then if we ran if we ran list demo in g1 and we gave it a value it would run the list F map over the value supplied so another thing that we'll cover is GA DTS has everyone heard of generalized algebraic data types a couple of people ok so everyone's heard of just algebraic data types right ff-shop has them that first-class citizen to the language a ga DT is a little bit more complex but we'll start by building up an ordinary ADT so we can define a type term as being an int I told I told you the validators we can define a side term as being an endurable we can't write because they're not able to be they're not able to be also what I'm looking for they're not able to be used together as a concrete type we could define the type term as being some algebraic data type int wrapping a type int and some algebraic data type or wrapping a pipe Pole and then use those constructors to tell the difference between them at any given time but then when we try and define our eval function and we say for any type a take a term a and return an egg and so we take that we have a function that takes a term and does some pattern matching based on that cell we're not able to return we take into X and return X and we take bubi and return B but we're back at the same problem of having to try and return something that can't be used at the same time they can't be used together so it's not possible to define a function that returns two different types you have to lift that up into an algebraic data type and a return it wrapped in one of the constructors of the algebraic data type that's out of the inner type system works and it's the same in F sharp I believe unless you'd like reach way out into any of the FFI into something outside of the language itself I think what it is but so here we build up a bit of a richer ADT so we've got a little bit of a like a small language being embedded a DSL being embedded in a language and we have a type term which gives us 0 or gives us the successor or gives us a bool or gives us a 0 or gives us if and these are some very very small grammars to give us a very very simple mathematic language inside the the syntax but when we're trying to find either what should what happens can anyone can anyone guess looking at that what will happen when we try and compile EVO so we'll get basically when we try to compile either the first case that we handle in switch returns 0 but there is not of type a it's a tight end and the second case returns eval X plus 1 which is an int but that's not the same as of type 8 and will be returns a bool but that's not a type a and so on we're not able to actually unify any of these types into something but the compiler is able to deal with so this fails with a type error so it's not able to actually give us anything that we can use we can't compile anything with this but instead we can use um we can use something called a GA DT and what a ga DT is is effectively a way of saying for the the type that you're defining to the a DT that you're defining the return types of that are still members of the a DT that you're defining so I'm defining a type term of a polymorphic a here but I'm telling you that term int is a valid return type of term polymorphic a which is exactly still within the family that term bull is and still within the family that Turnbull is and still within the family that term polymorphic a is these are all able to be unified and used as return values of a function that uses this algebraic data type so this is really powerful this is really useful because now we can define our eval function and because we say that the function can return term int that that using it that a term int is a valid output of this ADT when we extract the type 0 is now a valid member of the of the function that we're trying to return but you'll notice that it's actually 0 is being returned next to a boolean so we have this this really cool feature of actually being able to return multiple return types from a from a function using this this syntax really really helpful for defining pauses and finding grammars and defining domain-specific languages it's a very very nice feature I'm very powerful and so now when we evals ero we get 0 when we eval the successor to 0 we get 1 when we eat all the successors of the successor to 0 we get 2 if we available false we get false if we eval is 0 0 we get true and the same if we evil one we don't get true and we now have the ability to build up its really nice language inside our language so if we were working on some very specific domain problem we're able to build up a very nice elaborate domain-specific language to solve that that comes with all of the type guarantees that the language you're using build it has at compile-time guaranteed so the last thing that I'll touch on are the compiled targets and some interrupt that is really nice so the native compilation for a camel is really nice I know that F sharp has a or T compilation from a variety of different places but this is a first-class native compilation for a variety of targets which is quite nice and the day to day usage of it also assumes a native compilation so if you're targeting a server where this isn't as much a problem now snetkof but if you're targeting a server web net isn't available or where you're not going through the process of running it or for whatever reason something like a camera which compiles down to a native binary and just has a single deployed target is quite nice the other thing that's really nice we've just seen from from stable this is the only bit of JavaScript this and the next slide of the only bits of JavaScript at the top so we have something called buccal strips we also have something called JSF oh camel that I'm not sure of bacchus scripts because it's quite a cool project it produces totally readable Java scripts as an output of input of a camel which is quite amazing but the other really cool thing is it's blazingly fast and it has the ability to tell you whether or not the functions that you're defining are pure which is a really really cool feature this the defining the SFI with buccal scripts which is a totally different talk totally different day but defining an fi to a buccal script is a total joy it's an amazing piece of technology I've written I've written a bunch of like projects to kind of test how it can how well it can do and it is so much fun to FFI out through this thing you get a lot of type safety it makes it very easy it has a whole bunch of compulsory macros that hold your hand through a lot of the process and it's just a very very pleasant way to write that kind of that kind of FFI similarly because reason is being developed by Facebook one of the biggest things that they're going to be interested in is the ability to write react with reading and in this case reason react has first class bindings for reason being maintained by the person who actually invented reactive ancestors so Jordan Walker who created was one of the creators of react is also one of the people pioneering reason and there's a lot of really good work by the community and by Facebook to build really really good react bindings for it so we can see here we build a module and we have a bunch of includes we have some functions we have some radical stuff the other nice thing we have is JSX as a first-class citizen of the language so because the camel makes it so easy to define alternative syntax into the language you can actually write JSX in line inside your camel and it just picks up that it's JSX and kind of deals with that so really really powerful and really clever kind of way to write web templating code it's quite nice so a camel is a really cool language reason is a really nice syntax and combined it makes for a really really enjoyable developer experience
Info
Channel: ANZ Coders
Views: 3,127
Rating: undefined out of 5
Keywords: ReasonML, Fsharp, F#, SML, ML Language
Id: XWj24mn-wUA
Channel Id: undefined
Length: 31min 43sec (1903 seconds)
Published: Sat May 27 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.