TypeScript for F# zealots - Tomas Petricek

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thanks for joining the typescript for f-sharp zealots talk so this is an this is a talk I'm doing that's not primarily about f-sharp which might be a surprise to some people watching this as many people who have seen some talks from you know I'm an f-sharp person but I thought I'll speak about somewhat different experience that I had had recently so I couldn't find better illustration for zealots than this meditating meditating kitten but who definitely knows what's the best programming language to use I thought everybody needs a meditating kitten in these days so this is going to be a fairly opinionated talk and I'm hoping that people will disagree with some of the points and we can we can sort of follow up in the in the comments I'll be on slack as well if people have have more things to say so why should you why should you listen to this talk I'm going to be talking about my experience with using typescript for a for one project that I've been working on and I'll say a little bit about the project first just so that you know what kind of what kind of things are I've been I've been doing what sort of motivated the the talk and then I'll say a few things about typescript and I'll cover both the sort of the things that I thought were nice about it coming from an F sharp perspective and the things that I thought were not so nice coming from an EXOR perspective now I don't really expect everybody to be an F sharp zealot so the title of the thought was a bit misleading I'll show you some some relevant bits of F sharp code but it's going to be fairly introductory so the the thing I've been working working on and this is this is a sort of project that we've been doing using our base have been using typescript this system that I've been building in collaboration with some people in the Alan Turing Institute in London which is trying to produce a new notebook system for doing data science and it's it does a few interesting things which I'll talk about and the important bit is that there's a client side that's fairly non-trivial or does some interesting things and that has been implemented in in typescript so what does this actually do there's a few things that make this this project interesting first of all if you're doing data science then these days typically your entire sort of workflow has to be in one language typically Python or R we're doing something where it's easy to mix multiple languages in a single project we're also doing quite a lot of clever work to track dependencies between different different bits of code in your cysts in your code in your notebook so that when you change something at the beginning the things that are later on get invalidated we want to be able to do more in the browser so if you just sort of join some interactive data exploration that is something you should be able to do straight in your web browser and we have this feature called AI assistants which are our clever tools that help you with with some of the common boring data wrangling problems so you can actually try this yourself if you go to rattler org we've got a button which which will load an instance of the system on someone else's computer in the cloud so you can sort of experiment with it quite easily and what you get is this is this I'm going to make this a bit bigger just so that it's easier to see so you get the way the system works is that it integrates with the standard environment that data scientists use called Jupiter so this is not really a sort of stand-alone system altogether it's it integrates with with what people are already using and it adds a new kind of notebook so this this this whole thing that I'm scrolling through right now this is actually the bit running the bit of code that we wrote so it's is hosting sort of standalone notebook inside this the speaker IDE and I can do various things so here's a sample in Python where I'm just creating some sample plot so I'm not really a data scientist so I'm not going to tell you much about data science I'm just going to tell you about building tools for data science now the more interesting thing is here so what I'm doing here is I've got a cell or code block written in Python and what this does is that it uses this under sly berry to read a CSV file from github and it reads some finance charts and then I can evaluate that but following that I've got a JavaScript code block that loads the plotly data visualization library and I've got a JavaScript code block that exercise this [Music] AAPL data set that I load it in the previous Python code block so the really interesting thing here is I can mix Python and JavaScript and if I run this without any sort of explicit passing of data between Python and JavaScript I'm able to build nice interactive charts so this is showing some finance data my zooming skills are quite bad so that's one thing we are doing the other interesting thing is how does the tracking between dependencies work so in a typical data science system what you get is you just have to run through the code sort of from top to bottom and if you miss something at the beginning later on you'll get errors saying ah you didn't run or a variable 1 is undefined so this system does something more clever where here I'm defining data sets 1 2 & 3 in JavaScript Python and in R and then I have a bit of code on again JavaScript Python and R that just connects all these three data frames together and if I try to run one of those then it figures out that it has to evaluate all these all these cells that I had at the beginning so it does that those create some data frames and then it evaluates the one I clicked on but it doesn't evaluate another sort of cell that I had earlier in the notebook that doesn't really where the current one doesn't depend on it so it does it does a bit of clever sort of tracking to figure out what depends on what and I can even visualize this so we have this little visualizer where you can see how the different bits of code all depend on each other so there's there some cells those are the bluish markdown cells which are just code just comments they don't depend on anything but then there's there's some are code some Python code and some JavaScript code and you can see that this depends on the inputs and outputs depend on that so this is what we've been what we've been building and I just wanted to give you a clear sort of quick quick demo of the system itself so that you know what's what's my what's my sort of background where I'm coming from so the client-side what I was sort of playing with in the browser that's all implemented in typescript and as I admitted already I'm an excerpt person so why did we end up with typescript so this was this was a project with a larger team we're more more people in the team knew typescript and that was one of the motivations and I wasn't really working on this full-time so it was it was quite important so so that sort of work in a way where others can be in control and and do things even when I disappear for a few weeks so that was one of the reasons for choosing typescript the other thing we thought was that the Jupiter platform itself is implemented in typescript so if we do the same thing then maybe people might contribute a bit more which is a nice nice idea in theory in practice that actually doesn't happen so getting outside contributors is always difficult so what are what are the sort of reflections on typescript based on that project and this is again this is sort of reflections coming from an F sharp perspective so maybe it's sort of interesting and not necessarily a mainstream B you on typescript so that's that's why I thought this was an interesting thing to say the good thing is that you can actually do fairly nice functional programming in typescript or you can use the sort of elegant beautiful functional architecture and I'll spent quite a bit of time showing how that worked the bet is that the typescript system does make some difficult trade-offs in the type system and this is this is inevitable because that's how typescript was designed it's sort of designed to deal with full full JavaScript world so you have to make those changes or make those decisions there's nothing else that could be done but it does make certain certain functional programming patterns quite annoying and one that I found which I call 2d ugly here is you would think that typescript has the sort of simple simple JavaScript syntax but that isn't really the case anymore so I'll have a few complaints about syntax it's not quite the what talk but you'll see what what happens so I want to start with the good things so that those of you who are interested and like typescript can watch the first step part of the talk and then switch to some other session if you don't want to hear me rambling about the bad and ugly the good thing so the way we structured our system is we're using this Elm style architecture and we've actually implemented quite a lot of that ourselves except for one monkey bit and the reason and the nice thing in this architecture is if you're using function style you really just have two immutable types representing the state the moral and event what is happening in your in your notebook and then you have two functions update and render and they're purely functional and our implementation has very few dependencies the nice thing about this model is that it's really easy to debug and understand what's going on and in a system that's fairly interactive we're sort of cells are evaluated in the background and and stuff like that this has been quite valuable so why why not just use react and this is a question that I think is is important because I'm going to show you how to implement a few things from scratch and I think this is very often a sort of good approach if if certain things are true so our a user interface in the system it's not very fancy like it's really just this page so the fancy things here are well there's a few buttons for like moving things around we're using the Monaco editor that's the only that's the only sort of rich components that we need but we're not building like complicated forms for entering dates and stuff where react has a lot of components so we don't really need a lot of components the other thing is that this is project that's been going on for a few years and it's sort of done at an academic pace where you get back to it sort of every every once in a while when you add new things so it's not exactly great if all your dependencies completely change between every time you sort of get back to your system I think this is something that's fine if you're sort of constantly working on a project every day or every week but if you have longer gaps then I think having fewer dependencies is actually what makes the development more sustainable and we do like the fact that we have more control over how things work because for example here you need to integrate with the Jupiter environment all the stuff around so you do need a certain level of control of how the user interface is rendered and it turns out that the core logic that that react or all these sort of modern programming methods for the web what they what they do is actually pretty simple sorry I'm going to show you that I'm going to show you that the way the architecture works and for this part I want to show you the F Serb code first and then how the same things look in same thing looks in typescript so this has really two purposes one is I think the F sharp version of it is quite clean and it conveys the idea very well so I'll show you how to do this and F sharp to explain how things work and if you're familiar with with or you can you can use the F sharp part to make sense of it and then sort of see how the same thing works in works in typescript and I think that the other thing is that the sort of typescript version will then help you understand what's going on in F sharp here so I'm just going to start my sample project and I've got all my code here already so let's just let's just wait until the backpack server launches so here in F sharp I'm using fable which is f sharp to JavaScript compiler that takes my absorb code produces produces JavaScript and passes it through all standard JavaScript things like backpack for for building and life reloads and this is running seven oh seven one so right now I've got a page that says welcome to counter this is not going to be a super super inspiring demo I'll just create a little counter where I'm going to count the number of clicks on a button so the way to do this is I have two types that represent model and event and model is my state in the application so in my state I'll just have count and initially let's start with 0 and then when I'm rendering it then I'm going to I'm going to put I can say current count and then at the add the current count and the current count is something that comes from I need some more parentheses from this state state variable so the way the system works is that I define what's my state I define an initial state so my state has count it's an int initially 0 and then I define a rendering function that uses this little domain-specific language for generating HTML and it can access the state if I save this then I get current count is 0 and I can add some buttons to increment and decrement so I'm going to create a button and this is going to be text plus one and I'll add a button for minus one as well if I save this I now get my buttons and how do you handle events in this architecture so the idea is that you define a type for events and here I'll just define one message which says update the state and it's going to take an integer as an argument and that's going to be plus 1 or minus 1 and in the user interface you can then trigger those events so I can say whenever click happens on the +1 button I want to trigger the update event with plus 1 and whenever click happens on the minus 1 button I'm going to get minus 1 and the the key thing is I now have to implement this other function called state called update which takes the current state and a message and we're going to pattern match on the message if this is update by some number then we're going to return a new state where the count is the original count plus the difference so I think this should this should actually do all I want it let's see if it if it can count can it count plus works - works all right so this is the core the core thing now I want to make one more change I want to do it so that the count initially is not started like you start with a counter that's not initialized you have to click the start button and the F sharp way of doing this is to use the option type so now I'm saying account can be a number or it can be set and initially this is going to be man indicating this has not been set yet and in my rendering and I'm going to save a bit of typing here in my rendering I'm going to pattern match on the count and if this has not been set meaning I haven't started counting yet I'll generate a pay up page with welcome to counter and a start button if the current count has already been stopped the counting has started I'll generate a page with and the start button is going to send a new type of message which I'm calling reset and one nice thing in F sharp is that all those things are are checked so I get a message here saying in my update function I'm not handling the risk reset message so if I get the reset message then this is the case where I want to return zero to initialize my counter and I'm go also going to have to pattern match on the current count so reset that ignores the current count but if I'm ignoring if I'm updating then I need to get the count and updated by a certain number and this is this is going to be set which is indicated by the some case if i get update but i haven't really started counting yet this is an invalid operation i'm just going to ignore it although you should probably throw an error message in this case so if i if i save it i have a counter where i can start and then i can count so this is this is all i wanted to show an f-sharp thank you shut this down and i think this is really really a nice approach to implementing reactive web applications where you're in sort of it's not i wouldn't necessarily use this if i was using something with like lots of forms where there's standard components for doing that it works really nicely for this case because we're basically creating our own user interface and f-sharp has this really nice way of modeling modeling domain logic so this is another example where i'm saying i'm implementing a to-do list the model is the list of to-do items a to-do item has a title and a due day and what can happen is I can add a new item or I can reset and in the Elm architecture you have these two operations update and render where update takes the current model and a message what's what's happened and it produces the new state new model render takes mainly the model and produces an HTML output and it also has this trigger operation which is this first function here and that's used for triggering events so can we do the same thing in typescript there's a few things that I'm going to be using so first of all I really like the way I've sharp type checks everything and if you're using typescript then typescript has various flags that you can turn on for enabling various security checks or checks in the type system so there's strict null checks flag to avoid nulls and no implicit any to avoid this any type which means any any JavaScript value so this is this is really useful and we've been using that and there's a flag just strict which terms all these things on so I'll show you how this how this works and it turns out that you can use typescript actually reasonably well for implementing both the record types that I was using an f-sharp and these discriminated unions that I was using for representing the messages now those aren't really immutable so here you just rely on being disciplined about how to use them and it's it's one thing that we didn't always do well in our project so we then occasionally mutate something by accident and then ended up scratching our heads for for a half an hour to find where we did that so what I want to do now is do basically exactly the same thing but in pipe script so I've got the same stub implemented here and I'll start it and in this project and I'll I'll send link to the code the only thing that I'm not really showing you as this is this Alma GPS file which is using the the market library and what the library does for us is the updating of the back page updating of the Dom so this is the sort of standard virtual Dom trick where we're not really replacing the whole the whole content of the screen we're just updating bits there but you could see that this was this was all my code here is some why is it 50 lines of code so I'm not really hiding anything complicated and I'm just using one external library and I'll do you exactly the same thing as I did before in F sharp so I'll have a type representing my state called model and I'll have a type representing my events and then I'll have a render function which says welcome to counter and an update function where I do the update when some some event happens and I have an initial state and then I just call my helper to start the app so this I thought running on another port there is s just to show that this is actually running if I say from typescript this should sooner or later reload there it is let's reload it says welcome from PI script so I want to recreate the same thing I did in excerpt so the model this is this is going to be quite easy I'll just have count and that's going to be a number and the more interesting thing is how do you actually represent those events so I had two events I had reset event and the representation you can use in typescript realize on on two things it relies on Union types where you can say a type is one type or another type but it also relies on this on this very interesting trick with singleton types or um where I can say a resset event has a kind and the type I'm using here is it's not string is just a constant string called reset and a reset event just doesn't have anything else I also have update event and this is going to have a kind update and a number by how much and then the event is either reset event or update event so this is really pretty much the same as the absorb discriminated Union and we'll see that this is this is quite interesting when we use this the way I'm going to do the rendering well first of all I should I should do my initialization correctly so let's start with count equals one hold on one you can see the biggest problem for an f-sharp person coming to typescript is you have to use colons and multiples and this bit here is the same kind of HTML rendering so we're going to render an h1 with the current count current is followed by we get the count and convert that to string so that should should be a good start and now I need a button I'm going to spare you some of my some of my typing slow typing attempts and copy those two bits from here so I've got two buttons and one is the increment button the other is the decrement button and they do have they do have all click event handler where if I click on the button it will trigger the event now the interesting thing here is when I'm when I'm triggering the event this is really determining that I'm triggering the update event so this is producing a value of the update event type and the interesting thing I need to do here is do the updating so if I get if I get well let me first see if it actually runs so if I save this I do get I do get current count this one so that works and my buttons don't do anything yet so how do I get my buttons to work let's see and this is the bed this is the this is the really interesting bit so if you do EVT dot then you can see that the the event which is my event has this has this property called kind and kind is of type which this can be two strengths it can be either the reset string or it can be the update string now in some cases if this is if this is update there should also be a property called by because then we're specifying whether it's plus one or minus one how do we access that well this is the bit where typescript is doing something quite interesting because if I say switch over the event kind I don't think that if the case is and and actually the editor even knows this the editor knows that EVT dot kind can only be two things it can only be reset or update so if it's reset then we're going to return a new state where the count is zero if this is update then and this is where things get interesting because if I do EVT dot I do actually get by in my autocomplete so how does this work typescript knows that event can be either reset event or update event and it knows that this is determined by the value of the kind now if the kind is reset there's nothing else but if the kind is update there's this by property here which I can now access to increment my count so count is going to be the original count plus by so with a bit of luck this should now make my incrementing and decrementing work seems alright and the one last thing that I haven't implemented yet is this this start button so I do have a improved version of my rendering function here which that's the same thing that I was doing in in f-sharp before so if state dot count is not mal then I'm counting and I'll render the current count and do the plus and minus one button otherwise I'll just say welcome to counter and we will start with count being null now five if I save this then I have the start button and now I can do counting now one thing I haven't done here really is I haven't dealt with these nulls very nicely so um I just said counts Danelle but count is actually a number and if I did not if I wasn't careful I could I could get various errors caused by now so this is the default sort of bad behavior you get you get in old-school JavaScript but the nice thing in typescript is that I can read enable these straight null checks so if I in my config say straight male chicks on then suddenly I get a bunch of errors here like a bunch of errors I get an error here so this is not the most useful place for getting my error message the main issue is that this actually does I'll sort of well typescript doesn't infer that this is model because it's not model it couldn't be modeled because it model doesn't allow no so I have to change my types a little bit and I quite like this this the way that the typescript handles mouths because you can say account is a is of type number or now so you're explicitly saying you can get mal here and well if you do that then suddenly in my update I can't just access access count and do calculations with it because it can be mal so I have to do the same thing which I did in EPS ARP in F sharp I use pattern matching on optional values here I have to say if stable count is not now then I can do this otherwise I can just return state and that's all I have to do to fix it and this is sort of pointing out a potential issue in my code and you have to be explicit about about your your nulls so I do like this strict option and it's pretty much the same as what I did before with f-sharp and option types so option types are sort of a way of doing the same thing without having all this extra machinery in the language now I can be even more strict and turn on strict strict type checking and what this does it gives me an error here so one thing this enabled is that I now have to explicitly well I'm not allowed to have to have variables which will implicitly have a type any so in in typescript the any type is a very useful thing for interoperating with JavaScript because if you don't know what what object you may get from JavaScript you just say it's any and you can do anything you want with it in typescript you can turn this and now I have to be explicit about my types the sad thing is that typescript doesn't really infer all the types so here I have to do it manually and I have to say that trigger is a function which takes an event I guess I have to say takes an event and produces unit Boyd but you have to say you have to call it somehow EVT so I think all those type annotations this is something I don't find very pleasant so that was the counter demo and the main point here is really I think this is this is a very nice architecture and it works quite well with typescript and here I'm just sort of implementing things from scratch because that mode suits suits our project for for two reasons the user interface we're building most of it ourselves so it's a very custom UI that's one thing second this is something that's not going to be sort of updated every single day so we don't want to rely on the sort of breaking changes by others so in typescript you can model what F sharp nose has discriminated unions using using these interfaces with singleton types and the Union constructor and you can put this nicely with the Elm architectural operations and the type signatures of those I think are somewhat painful to read but it's the same thing as in F sharp so you have update takes the state and event and produces a new state trigger a renderer takes this trigger operation for notifying the system that something has happened state and produces an HTML node so what are the the interesting reflections I'll demonstrate this using a few few examples so the first example and coming from from our rattler project is that Brettler is extensible and you can add new kinds of cells so we had Python JavaScript markdown but you can you can build your own cell with your own user interface as well and to do that you have to implement some interface so this defines a what is the language plug in a language plug-in defines the language that's just a string has some editor which is another object and then it defines how you parse code how you evaluate code how you sniff code and how you bind which is our name for a sort of step that happens before evaluation where we construct dependencies so all those things you have to implement and in our actual actual system I've got I've got one example we're we're implementing a little language plug-in called merger wear and this is just a demo it's not it's not useful for anything practical where the idea is you have a little little language that okay all it can do is it can merge data frames so if I turn this on and save my files I've got another instance of Rattler running here as a standalone thing so this now reloads and I turned it on and I now have a new cell type so I can add a merger cell and this has this is this is using a little while programming language not even programming language where you just say output data frame name and comma separated list of input data frames so this is a domain-specific language for merging merging data frames it's just a demo and if I evaluate this what happens is it now merged two of my data frames if I add the third one then it it merged three of my data frames so there's there's a bunch of codes running here in and the relevant bits is I need to implement this interface and in my implementation I decided to just create a value using the object notation so this is something I find quite nice you can you can sort of define interface and implement that by constructing an object that has all the required things if I remove one of the things that is required then I get an error message saying you're not you don't have that so I'm implementing that object here and as part of the work and this is this is where the sort of interesting logic comes in Rattler works is that all those all those data frames that I've been merging they're stored in a component called datastore and Python or R will put the data into datastore and when some other component wants to access that they will have to fetch it from the datastore and then the result we put back to the datastore so here we have some code that calculates the current value and puts that into the into the data store and this is a place where you just inevitably have any values because you're working with things that you get from the web now the other interesting thing is that this actually well I'm not I'm not I'm not showing the getting of the data because that's in a separate file but I'll get it get back to that so I think there's few interesting things that I find quite tricky in typescript one is this sort of you can you can often do object-oriented programming with classes and interfaces and if you're doing more object-oriented style which sort of inheritance then you do want you know you do want to use classes another thing that you get with classes is you can actually check whether in a value is an instance of a class using this instance of instance of operator and this does not work with just an interface it only works with classes and if you want to have a runtime checks then you do need that if you but the sort of object implementations of interfaces which is what I've been using give you somewhat lighter syntax there's somewhat easier to use but they don't give you this sort of ability to do two checks so one thing that we've struggled with occasionally in our case was we just started with an with an anonymous interface implementation using the object like what I'm what I'm showing here and then for one reason or another we decided we need to turn this into a class and it turns out that you can you can do that but the annoying thing I'm switching between the two versions is that pretty much every single bit of syntax changes so here you do column now this becomes implements here I say equal curly bracket now I just say curly bracket in the code previously I had columns everywhere now I just have equals everywhere my function previously was defined as a attribute which is implemented using the arrow notation followed by curly brackets now it's without that just as a function and the body the body stays the same so this is one case where I thought there's there some pretty crazy inconsistencies between the two different ways of doing the same thing now it makes sense because that's how that's how each other script works but I think it's this is one of the examples where the JavaScript heritage of typescript really means that doing certain things is quite painful the way you do constructors in classes in typescript is the sort of standard way you define a constructor and in that you initialize all the fields and do someone coming from an F sharp background where F sharp has these beautiful implicit constructors where you just as you're defining the type you take all your arguments and then you define all your fields switching to the typescript world where you need to have explicit constructors it's just that that's been a mate it's just it's a tiny thing but if you're writing a lot of classes you'll end up wasting a lot of time now there's a few places where where I managed to bring the type system or break where the type system sort of does things according to the necessities of the JavaScript environment which aren't very pleasant so one of those is when you're when you're using fetching some data from HTTP always get response or the data which is of type any and then if you're not careful you can very very easily get into trouble by sort of propagating that any value somewhere else in your code and causing all sorts of troubles and you can remove some of those places where this error can happen by using the strict mode and if you're if you're doing the same thing in F sharp there's I think F sharp type providers are one of the nice nice features that can help you with that when you can sort of strongly type your responses but if you're using Fable if F sharp you'll just this is a place where you will easily notice that this is a problematic place so you have to define some type explicitly or you just won't be accessed won't be able to access it that easily so that's where sort of F sharp makes things harder for you but I think it's actually a price worth paying because it just removes quite a few errors and I do have one one very curious example so this is a place where the fact that pipes rip is still just the JavaScript runtime underneath thus cause a few few surprising issues so this is a this is a bit of code that is actually pretty much based on what we had we have this interface representing a variable a variable has the name and we have an object which we're using as a as a lookup table you can sort of use the square brackets to index into it and it's basically just a map or lookup table we're given a variable name you'll get the variable and and I have a little function which returns the length of the name of a variable so it takes the scope which is our variables or data frames in scope the name of the variable and it says if this variable is not undefined then return the length of the name otherwise return minus one and this is this is even in the strict mode so this can't be no and the question is can this ever fail because because the name is undefined so in my type name is a string it can't be undefined otherwise you'd have to say name on string or undefined but it turns out because this is underneath JavaScript if you just call this and use empty lookup table and to string as the name of the variable then this breaks and your code crashes because this lookup is just the object lookup of JavaScript and all objects in JavaScript have to string that's the method that you can use for converting those to string so this is not undefined but it's not actually as our type requires a variable so it's a it's a function it's not a variable and this is I think a case where the fact that we're building on on JavaScript typescript can remove some of those quirks but not all and this was this was a case where we release this sounds pretty arbitrary but we really did spend an debugging this issue because we did have a variable called stew string the the last bit I wanted to talk about is some of the things that I didn't find particularly elegant in typescript but that were not really a major issue so this is mostly about the syntax and types read inherits the JavaScript syntax which is really sort of designed for not necessarily functional style of programming so this is perfectly expected that's the price you have to pay when you want to use typescript in a functional way and I'll this is again based on an experience of writing a piece of the the Rattler system where one of the one of the really sort of nice interesting innovative pieces of data science to length we've got are these guy assistants which are tools for semi automated data wrangling and I'll show you what this is so I'm going to open another demo and you can go to rattler not orc and play with this later on your own so I've got one example here where I'm downloading some data on air traffic accidents which is actually originally coming from Eurostat and the way the data is structured is that you have a row representing accidents related to all airplanes that were registered in a particular country where the accident happened in a particular country so for example here this would be a road that represents accidents that happened to aircrafts registered in Austria that happened in Cyprus and it's very sparse one of the issue with the data though is that they also include aggregates so there's there's some rows that represent the total for the whole EU and you think that is quite tricky and what I can do is I can say I want to use an AI assistant for outlier detection on my data set and this will create a cell with custom user interface where I can just run the AI assistant and then ask it how do you recommend I I fix this code and the assistant says you should add a filter where see wretches is not u28 and also geo is not u28 so it looks at my data and finds the outliers and and it recommends that I add certain filters and I can see what rows it actually removed so this is a tool where if you're cleaning data it can help you with some of the typical boring tasks and in the implementation of this there's a few things that I found quite annoying one is that sometimes you have two ways of defining a function you can you can do this using the sort of lambda syntax which works in certain contexts like when you're passing the function as an argument so here I'm defining a function that takes a list of AI assistants and generates an editor where the editor has a certain initialization code now this is written using lambda function but if I need to change it to an explicit function then again I go through this process of making so many tiny tweaks in the syntax so here in the function notation you just say curly bracket return and then you return something in the other notation you have to say arrow and then you don't need return but if this starts with curly brackets then you need extra parentheses around because otherwise the interpret the parser will treat it as a code block another thing that I find I find quite tedious is in the code that constructs these HTML blocks using the H notation in in typescript I end up with a lot of helper definitions and then I end up with sort of one messy condition that says depending on the state to do this or this or this and in F sharp this was actually this is this is one thing that can be handled quite nicely with list comprehensions where I just define a list and then I say yield this user interface element or this element or this element so you can embed quite a lot of logic in this code that constructs lists so - - to wrap up so I talked that I talked about F sorry about typescript from the perspective of an observed person and and also from the perspective of a very specific project where our project sort of is long-running not very not very sort of ongoing all the time it's reimplemented a plain user interface from scratch and typescript worked quite nicely with this Elm architecture and I did like the fact that we sort of implemented that ourselves had a nice control over that tight grip isn't really designed for functional style so some of the things will end up being ugly and in some places it's trying to be JavaScript in some places it's not and this often leads to random surprises like this - string thing would I would I sort of when would I prefer f-sharp when would I prefer typescript so I'm obviously biased here as an F sir person I always choose F sharp but I was working in a team where this was a team decision and we did did go for typescript how did how do the two compare so if you're using EPS are pour'd about with fable then I think the remarkable thing is that F Serb has this functional core which is safe and clean and works and the way fable compiles this is that it avoids most of the trade although all those sort of messiness of JavaScript so you have the core language which works nicely is predictable is understandable and then there's the extra integration curve which inevitably has to make trade-offs typescript supports many different styles including sort of object-oriented and functional and it doesn't really hide JavaScript it's sort of JavaScript is one of the styles that's a typescript some supports and unlike an EPS are where the core and the integration is quite clearly separated I felt like in typescript this is not so much the case so you always end up mixing different different bits and you can do it well or you can do it not well and it's really hard to sort of figure out what is well what is not so to go back to my to my meditating meditating kittens a lot who knows that absorb is the right choice for everything all the time I think the important things here from the talk where I was actually actually quite sort of pleased with using typescript in the way we used it I'm using the sort of plain L mich elvish architecture you have to be very disciplined and you're not really you'll you'll end up using typescript in a way that's not obvious so you I sort of thought if we go for top for typescript people won't have to learn too much that's not really the case if you want to do functional programming in typescript you have to learn functional programming in typescript I'm just like if you want to do F sharp you have to learn that sharp so that that learning is still there typescript in a functional way is really different language than typescript in the JavaScript way and a lot of these decisions really depend on the project context so you always have to have to use your use your judgment that's all I wanted to say and I'll have a look at the questions now so thanks for tuning in and for sticking to the end all right question is there a reason you're using interface as opposed to type system seems to me that the interface is just a reference to I have to move my window here haha to Microsoft's inclination 200p yeah I think that this this bit is something I found sort of confusing as well like there's there's so many different ways of doing things that I just ended up using interface because I think that's the first thing I was I was able to get to work and I don't really have a good good answer to that it's true that it's true that this this might be the case where typescript just sort of inherits a lot of different styles and some of them are more Oh like if you use oo you might end up with classes and interfaces if if you're using different style you'll you'll end up more with with types so there's no there's no good good reason for this it's just a random decision based on what I got what I was able to go to get to work easily for what I wanted but yeah if you look at some of my type definitions sort of earlier on there's there's cases where you need to say type there's cases where it doesn't really matter like here this has to be a type because I'm defining a type alias but the way you define the way you define the record types I don't really know if there's sort of subtle differences all right any more questions I don't think there's there's any other question here so I don't think anyone's anyone's joining life on zoom so if that's if that's it then thanks again for joining and I'll post all the code including most importantly the to F sharp and typescript comparisons sort of side by side of the Amish architecture which i think is a fun thing that people can play with later thank you you
Info
Channel: NDC Conferences
Views: 2,576
Rating: 5 out of 5
Keywords: Functional Programming, TypeScript, F#, NDC, Copenhagen, 2020, Online, Conferences, NDC Conferences, Tomas Petricek
Id: yrAUxjbdJmQ
Channel Id: undefined
Length: 62min 50sec (3770 seconds)
Published: Fri May 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.