 Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today is Phillip Carter. Hey, Phillip. Hi. How's it going? Welcome to the show. Yeah. Thanks for having me. We're here to talk about F-Sharp. Yes. Yes, which is, I think, one of the most under-appreciated languages out there. Functional programming, and we've heard about it for a while. F-Sharp's been out there for a while. You're going to show us what's new in F-Sharp in Visual Studio, some of the tooling, and you're going to sneak in whenever you can, reasons why we should pick it up and use it. We're all in C-Sharp, some VB developers, why would we want to do F-Sharp? So make sure you get that in there. Yeah, absolutely. I mean, there are a lot of cool things that happened with F-Sharp. We shipped a new version of the language. It's not the most exciting update in that there are a lot of little features that were added, but they weren't big headliner features or something. They were nip and tuck, fixing up various parts of the language that people identified as problematic over the years and things like that. It now runs on.NET Core and.NET Standard in Rc form, and we're going to be targeting.NET Core 2.0 and.NET Standard 2.0 with a lot more stuff because that brings a lot more APIs. So much more of F-Sharp is going to be able to run on that, and we're super excited about that. But with VS 2017, we shipped quite a few updates to the tools, and these are really special in my mind because they introduced a ton of new features that have never been inboxed in the product before, and basically all of these came from the community. So we have an incredibly talented and really strong community that basically know the language in and out, they know Visual Studio in and out. It's actually pretty incredible how much they know about the way Visual Studio APIs work and that sort of stuff. So they had this extension called the Visual F-Sharp Power Tools that had some extra features, and they began porting some of that stuff over to this newer infrastructure that we put in there to sit F-Sharp on top of what is known as Roslin Workspaces. So it's this common layer where a lot of features are actually implemented so that if you sit on a Roslin Workspace, you get a whole bunch of features for free. And also- Was F-Sharp on Roslin in 2015? It was not on the Roslin Workspaces layer in 2015, no. So this is completely brand new. Some of the things that you're using, especially if you've been using the Visual F-Sharp Power Tools before, they may not seem new, but you'll probably notice there's a new UI, and they're probably a bit faster. Things look a bit snappier. The UI is a little bit just cleaner looking, and more importantly, the same really great UI that C-Sharp and Visual Basic have for these features, F-Sharp now has them too, which is something that we've never had before. And you get to take advantage of the compiler working, the background and the refactorings and the tooltips and all that kind of fun stuff? Absolutely. Cool. So I guess first thing, I'll just show you how you actually get it on the box if you don't have it already. Yeah. So this is the Visual Studio 2017 installer. I have community on my machine, so I can just go modify. And in here, I mean, this is the workload page and you'll think, okay, well where is F-Sharp in this? Well, I've already installed.NET desktop development. So if you go on the right-hand side, you can expand this and you can see some of those components that are associated with that particular workload. And they see that I checked F-Sharp language support. So it's optional that means it's not installed by default? No, it will actually be unchecked by default, but all you got to do is go in here and check it by default. That's the same thing for the ASP.NET workload. Okay. It runs on core. It's the same thing for the data storage and processing workload. I'm just going to uncheck that one there. And it's actually checked by default in the mobile development with.NET workload. That's the Xamarin workload. Yep. Or if you're feeling like hunting through the list of components, you can go to individual components and you can look for it here. I think it's under languages or something. It's right next to the- There's no search in that, is there? Yeah, they got to get that in there. There we go. Okay. So that under development activities, I thought it would be under languages. But there's a whole bunch of different places where you can look for it. As the installer improves with search and things like that, hopefully, it'll be even easier to find it. And so let's see, it looks like this. But it's easy enough to add if you don't have it. Yeah, exactly. And so you would just go modify if you needed to. But since I already have it on box, I'm just going to launch Visual Studio. Okay. So once my user settings are loaded, there's one other extra thing or like definitely a pro tip that I suggest. We blogged about this on the.NET blog, but we established a new nightly release process for the F sharp tools. So basically when code gets checked into master, it runs through our CI and all that sort of stuff. And it's basically at a point where it's fairly stable, runs through a set of other checks and things like that. And then a V6 is generated. And that V6 is then signed and all that sort of stuff as if it were to be inserted into the product itself. And basically it's the same kind of V6 that you get when you check the F sharp checkbox. But we have it as a nightly process. So if a new feature gets checked in and you want to try it out, you're interested in onboarding to a whole set of new features which is the case today. You can go here under tools, extensions and updates and that needs to load up. And you'll be able to find a visual F sharp tools here. You'll notice this thing says experimental. That's because I actually have something on my machine today. But so that's the actual extension. So experimental is that's internal to Microsoft. Is that correct? No. Oh, no. Okay. So that's the nightly. Yes. This is the nightly itself. So you notice Rosalind language service experiment like all these different things that say experimental visual F sharp tools like this. If you want to onboard yourself to new features, this is a way that you can do it. So I can go to change your extensions and update settings. If I click that, you'll notice I have this little thing that says visual F sharp nightlies and this.net.migot.org dash slash F slash F sharp slash V6. If you go here, this is actually the feed where we publish the latest version of the signed V6. Wow. So you can set up your extensions to be updatable on a regular basis and that's different than the usual publishing a new one where it shows up in a little flag and they have a variety. So there's a variety of different ways. This one you can actually, in this case, you just give it a name in URL, you click apply and that will basically say, oh, there's this V6 that I could now use. So what's going on is it then downloads the V6 when there's a new one available and then it installs it in your app data folder on your machine. So there's basically two V6's that you have now. One that is in the release of Visual Studio location where all the other components are and things like that, and then one under app data. So we change the setup offering a little bit for this nightly release process so that Visual Studio knows to go and pick the one in app data rather than the one that are installed by default. So what happens is later when there's a future update of Visual Studio 2017, we'll basically take wherever one of those nightly release V6's are, we will just test it a bit more, make sure everything is really solid, maybe make a few changes if we need to, and then it will then get installed in that other place where everything else gets installed when you're installing by default. So basically we have this really great process where code changes and it's all out in the open, all open source, gets into a new V6, you can play with that V6 and then as you play with it, you're actually also kind of testing stuff out, you notice problems, you maybe make an issue, you say, hey, I noticed this bug, that sort of stuff, and then what you have been working with just gets fixed up and eventually finds its way into the release version itself. So there's not this huge weight of time between big updates to get a set of features that you care about, you can start getting them today and then see what they will look like when they're actually in the product. Cool. So then you just press okay and because I already updated the latest update here, I don't actually have a new one waiting for me, but what happens is it will update and download it and then install it for you and then eventually you'll get prompted, like, hey, if you want to have this thing installed, you have to restart Visual Studio and then it goes ahead and it does it. But so I'm gonna start creating an F-Sharp app, a really, really basic one. Let's just make this run on 4.6. We'll just, I'll call it web demo or VS Toolbox demo. There we go. So this is just a simple console app that runs on Donut Framework today. And so what I'm gonna do is I'm gonna turn this console app into a very basic web service and I'm going to do that with the SWAV web library. It's kind of a progressive library in that you can use the whole thing and it has a web server and a routing thing that you can do. You can set up API routes and that sort of stuff or you can take those API routes and you can sit them on top of another web server technology if you like. But we're just gonna go with the whole thing because that's just kind of the default out-of-box experience. So the first thing you see here is just basically your hello world. Just let main, main is the name of the function. I'm defining a function called main. It takes in argv which is just a string array because that's just kind of how main works for most stuff. We have the entry point attribute which that's just the entry point of the application and printfn is basically just printf and it's a formatted print. So this percent a basically means print whatever it is and internally it uses reflection and that sort of stuff. But I could change that to just be percent s for a string and this will actually give me an error because it's like oh argv is a string array but you're expecting a string. So this is kind of a cool thing with fsharp. If you're doing anything with logging or things like that where you really care about the information that you're writing to a file or something like that you can use formatted printing with sprintf which is a function which prints a formatted print string and use kind of that type safety to then say, oh well you know I'm just not printing random crap like you know the types have to match what I say they match. And that's gonna be a benefit for certain people. But I'm just gonna go ahead actually first I need to add the suave package that'd be helpful. So I'll go under and manage new get packages and browse and I'll type suave. And it's the first one see it's the little guy with the mustache and the bow tie. We got a cool logo. So we'll just go ahead and install it need some dependencies yada yada yada goes ahead and adds them all right we're good to go. So I'm gonna get rid of this and I know that start web server is the actual function that starts a web server but I don't have anything added so I get red squigglies but I also get a light bulb. Light bulb says open suave all right now I'm good to go. And notice I typed default config actually I think I just there we go default config I'm already getting intelligence for this thing this default config is this sort of you can just well it's a default configuration for your web server it listens on a certain ports it binds on IPv4 has a kind of a generic error handler and stuff like that. You could pass your own configuration if you want but we're not gonna do that. And then the second argument to start web server is a web part or basically your routes. I'm not gonna go into the details of what web part means in suave that's just they have that on their site explaining kind of the types behind it and how they get the types to all match and that sort of stuff. But what's really great is within the screen here I'm just gonna type some stuff fill some stuff in and I will have basically 15 to 20 lines and a web server already going. So I'm gonna set it up as a get I'm going to compose that with this choose function and I'm going to have a list of routes. So I'll type path. And that'll be the hello route. I'll compose that with an okay of hello folks and all okay does is just return to 200 okay. And so you'll notice that types of stuff that doesn't compile things are kind of weird. Again, I get light bulbs suave.successful. That's where the okay function is actually defined. Get another one, suave.filters that's where the path function is defined. And I get another light bulb saying suave.operators and that's where this custom operator is defined. And so that operator it uses some pretty cool type system stuff known as Klycely composition to sort of compose functions between each other that sort of return these types that are context sensitive. And you want to be able to compose them together and there's a whole bunch of theory on how that works but in practice it just means you get to write very little code that's very expressive and saying oh well you know the path of hello composes with this output. Okay. And so I will just go ahead and do another one. We'll call it goodbye. All right so now I have two paths. We'll just go ahead and start it without debugging just so it's a little bit faster. All right and then I'll go to localhost 8080 oh that's right I didn't actually have a path just for 8080 we'll go hello. And it says hello folks. And then I'll go goodbye and goodbye folks. So this is I mean this is super basic stuff. I mean like this is just spitting out strings. But I've got 18 lines of code including some white space and some comments and I have two routes on a web server already running. That's pretty nice I'd say. And so this is sort of one of the great things about Fsharp is that you know there may be some extra stuff that you gotta learn like you gotta learn that there's this composition that there's these functions that are being composed with each other and all that sort of stuff. But at the end of the day I have four lines of code that defines my API routes for my web server. And then I just have a function called start web server that takes in those routes as a parameter. Takes in a function as a parameter to that other function. And so this is it's like this foundational thing in functional programming that as you use it more and more you'll really start to love it. If you've been using link in Csharp or Visual Basic and you know composing different link expressions that sort of stuff that's exactly sort of the same path. And so if you find yourself loving code like that in Csharp you will probably end up falling in love with Fsharp because it basically takes that to a whole nother level. So this is kind of cool but you know you get some you get some hovers I can actually do something kind of nice here and click on routes I can go okay find all references this is something that's brand new in VS 2017 for Fsharp. It's kind of down here at the bottom here but you notice this is the same UI that Csharp has. So there was so much functionality implemented at this common layer. We didn't have to do anything to implement this UI. We didn't have to you know the fact that you could hover over this and see a little block of code that shows where it's being used. We didn't have to implement that at all. That was just done in a common layer. We got so much of that stuff for free. The other thing that you may have noticed on the guidelines right. Oh yeah yeah we have these structured guidelines as well. Which you know you can hover over it you can see that you can collapse them. That's also that was only available via a power tools extension that not everybody downloaded before. And even then it wasn't quite it wasn't using the same UI. And then under default config you know if I were to type that again right. You'll notice that it's using this sort of fuzzy matching. So there we go I got it to die there. So diff a C and it's already knowing to pick it. So you'll notice it's kind of hovering that C and stuff like that. That fuzzy matcher is implemented at the workspace layer. It's not implemented at the F sharp layer. We got that for free. Also these filters that you see here we also got that for free. Now we had to add some glyphs and like associate certain things with glyphs. That sort of stuff that was about maybe a hundred lines of F sharp code to do that in our tools. But you know that's easy. Also another cool one I can rename routes because you know why not. We'll go to rename and this is the Roslin inline rename sort of thing. We'll call it app instead. You'll see that online. Some people will call their routes app. I'll hit enter and that'll be good to go. And then I can rename that to oops rename. There we go. We'll call it routes again and we can do preview changes and you can see the same preview changes window that you can see sharp as well. This is like this is kind of a whole another level of F sharp tools that haven't existed in box before. And they're getting better and better and better. And especially if you're on the nightly release train you're gonna see so many of these things. So I'll just go ahead and close that out. And I'll do something a bit more exciting to sort of kind of really try to nail down why you want to use F sharp. So browse will go to F sharp data. Whoops I can't spell. There we go. So this is a really awesome library that is used by well it's built by some people who had worked for Microsoft and worked on F sharp and they're now a part of the community. They're absolutely amazing. And so this is basically a whole bunch of different data storage data processing data gathering parsing that sort of stuff inside of this library. And most importantly it uses what's known as F sharp type providers. Now type providers are I mean I'm basically gonna say they are your way to get IntelliSense for data under the covers what they do is they you effectively pass a sample data set to a type provider say it's you're reading some JSON data right you can either pass a schema or you could pass an example and then it will read that in build up an object model that represents that thing for you and then pass it to the compilers and specifically the compiler service. And so then the compiler service inside of Visual Studio will allow you to get IntelliSense for that object model so you could dot into things. So that way you don't have to create these sort of ephemeral types that exist solely for being able to deserialize into so that you could turn them into something useful. Yeah that's just kind of boilerplate that nobody really likes doing. And so at type providers let you just do away with that entirely. So I'll just go ahead and open F sharp dot data so get some IntelliSense there so I don't have to quite remember the thing this is actually unused right now so I could choose to just remove it but you know I'm not gonna do that cause I wanna actually use it. So I'm going to put a little bit of boilerplate here that you should never actually do in real life. Never do this in real life. I have like my own generated code here that for using this API for the Washington State Ferries. It's they have a rate limit and stuff so I'm not too worried about having the string up there or anything. Like they force you to actually access it with your own your own GUID. But so I take the ferry to work because I live on an island and to get over here I have to ride a boat and they have an app that I'm not the most happy about and so I've just been kind of curious about like. That tells you when the ferries are and which ones have been canceled and which ones are out of service. Yeah yeah and so like you know I know that I'm on a particular route has these sets of boats between these two terminals and then basically the question that I wanna ask is like okay when is what's the set of ferries that I can take for my point in time and where I'm at right now. And so I'm working on building an app that sort of does that but I figured I'd show off just type providers for accessing a real life data set. Okay. So I'll go ahead and open system here just so I have this date time offset here. And so now I have this ability to build this URL out just takes a base URL and a little code. And then one thing that I'm gonna do here is I'm going to create a sample URL. So you would package this up somewhere in a self-contained spot of your app. You wouldn't actually like do it like this. But that's fine and this notion of storing these things inside of a module is also kind of a code smell but you know whatever. So I'm going to define this string so we'll go sketch routes sample. So basically this data set is the intersection of schedules and routes. So a route is like this abstraction of there are these two points across the water that a boat can go across and that's considered a route. And then routes have IDs, schedules have IDs and there's a way to correlate them and that sort of stuff. So we're just gonna grab that information and see what it looks like. So I will go ahead and create a string literal here. And I just built out the URL here and we are good to go. Actually I just realized I'm not using the state string in any way but you know whatever. I just copied that out from somewhere else. So I will create a new type provider here. So we'll call this sketch routes context because JSON provider because it's a context and I will just pass in this sketch routes sample string. And so it compiled all that sort of stuff. I have this now type provider object. So let's have a function that gets the data. It's not gonna take in any parameters because the URL itself is kind of a static thing. There's no input parameter to this schedule routes URL. It's always gonna be the same thing. If there was a URL that you had to provide meaning there was like a parameter or something you needed to have that would probably be good as a parameter to this get data function. And then you would build the URL out like that and then you pass that off to the context object. So we'll just say that the data will assign data to something and we will go sketch routes URL. Did I not? Oh, I didn't open that. I gotta open up my module. There we go. Okay, and I'm going to pipe that. So this is the way of passing a parameter to a function in a Unix pipeline sort of style. And I'm going to pipe that into something. And so pipelines are really cool. If you ever use Unix pipes and you basically say there's this operation, I pipe something into an operation. The output of that operation could then get piped into the input of another operation and so on. We have that as a language construct in F-sharp. And so you think of like stacked link queries when you know dot where dot select dot select many things like that. You could do that with just F-sharp pipes and just piping regular functions together. So you don't need like special functions to do that. Just regular boring plain old F-sharp functions can get piped, which is pretty cool. So I'm going to pipe that into the sketch routes context dot load function. So there's a couple different things. I could do this in an asynchronous context but I'm not gonna do that just for the sake of time. So now I have piped it into the load function. And so that means within this scope, I now have data and data is an array. Okay, that's kind of cool. I guess I got an array back for the thing. So I'll pipe that into an array function. We'll do array dot map. So let's just, we'll transform this into a array of tuples. So that I can get some of the data off of it. Cause some of the data I'm probably- The tuples new in this version of F-sharp or where they always there. They've been in there for a long time. Okay. And just as an aside, we introduced struct tuples in F-sharp 4.1. And those are the ones that actually fully interoperate with C-sharp tuples. So they operate across assembly contacts. So like, you can dot into a tuple or like you can consume a tuple and just have that be an F-sharp tuple. You can pass an F-sharp tuple and have that be just a C-sharp tuple. So we're gonna dot into this X. So X is an item inside of that JSON array. And it looks like, what's this? It says contingency something, contingency description. The description sounds kinda nice. That looks like real-life data. Yeah. Sweet. This is real-life data. Nice. It's IntelliSense for data. Wow. It's pretty magical. And it's, I mean, I don't have to construct these intermediate types to do any crap. I just- And while you were typing, the compiler went out and retrieved that and did that all for you. Absolutely. That's pretty cool. It's a pretty sweet feature. We have one for Azure, by the way. So, you know, you're doing stuff with Azure Storage, Azure Blob Storage. You don't like dealing with these long names or, you know, whatever like that. You can just dot into it. Cool. Yeah, it's pretty fantastic. And so, we'll just go description. Yeah, we'll do description. So we got the data, then we didn't wanna do one last thing. We'll just kinda put that into a string somewhere. Let's see. Yeah, I'll just do that in one fell swoop here. No, I'll just make that another function. That's better. We'll call that format and we'll just call it data. In this case, I'm going to explicitly annotate my type. So something you may have noticed that I didn't even mention is that I didn't specify the types for anything anywhere. It uses global type inference to figure out what things are. But you can also specify types if you want. There's kind of a, some people, and I subscribe to this belief, is that if you have a function which is intended to be consumed, outside of whatever you're working in, so not just as an implementation detail, but actually something that you want other consumers to have like in a package or just within your own code base in different projects, things like that, is annotating the input parameters. And that's just kind of more of a stylistic thing, but I choose to do that. So what I've actually done here is under get data, if you hover, if I, hang on. All right, I'll just hover over this and you'll see there's a type signature that was generated by the compiler here. Given a unit, which is basically void, this produces an array of tuples and that tuple is, has an int and int and a string inside of it. So that's what my signature for format should be. That type, yeah, okay. Formats and we'll go data and we will say that that is an int, int string array. And so now I know what that is. So basically I had to wrap this thing all around. I specified the type with colon. If I did not wrap this with parentheses, then what it actually does is it says data is a generic type and then the output type of the format function is this. That's kind of a gotcha. So you can specify the output types of functions as well. That's just with a colon at the very end of your signature and then type stuff there. So that's why I have this wrapped in parentheses, in case anybody was wondering why. So we're just going to take this array of tuples and we'll just turn it into a big fat string. If I can type here. Again, we'll just map this over here. Array.map, no, sorry, we'll do fold. So this is a bit more of a functional programming thing. So fold basically takes a data set, so in this case an array and then just collapses the items together into a result. So basically it applies this function that for each item in there goes in and just kind of gives it to this state that keeps getting passed in the implementation details. So you can imagine that summing an array is basically implemented that way. If you think about it, that's basically what you do is you go through an array, you add to a cumulative thing, that sort of stuff. This is just kind of a generalized concept of that. So I'm going to fold this array of data into a string. So we'll go fun at. So in this case, I'm going to destructure the tuple here. So we'll just call this schedule ID, route ID and description. And so I have just kind of ad hoc, destructure that tuple and given it a name so that I could access those constituent parts. And I'm just gonna new line this thing so it doesn't go off the screen here. And we'll go let str equal to sprintf. So this is similar to the printf one except this does that formatted print but it generates the string that you wanted that format to be of. And we'll say schedule ID and that's an int so we'll do percent d. We'll do route ID. We'll do another percent d and then we'll do. What's the backslash t? Oh, that's the tab. Yeah, tab space. So any sort of formatting that you may have done with C it's basically the same stuff here. There's a few extra formats that we have but those are documented and you'll let them. Description and that's an s because that one's a string so that's percent s. And then I will type schedule ID and we want to go, believe this is what I was going for here. So I want to have an initial state of a string here and this guy is generating the string. Did I screw up on my parentheses here? Yes. No, I'm having a little fun here and we'll just line that or something. Oh, gosh, I'm absolutely, absolutely stupid. Okay, this is schedule ID. I'm sorry, I'm having a bit of a brain fart because it's demo mode and I'm trying to talk and write code at the same time. Okay, so string. All right, yeah, I'm using the correct fold function. Well, in the interest of time, let's just turn that into a set of strings because I don't want to try to talk and think at the same time. So we'll just go SID, RID description and we'll go, there may have been some sort of scope thing where I was screwing up here. Percent D, okay. So I have now turned that into an array of strings. Right, so now string.4, no, not format. String. is it join? String.join, yeah. So I'll just use a .NET function instead. So that's kind of another benefit of F-sharp is that you can just, this is a .NET function, well, sorry, .NET method and I'm just passing stuff in and it all just kind of works. So in this case, format now takes in the data and produces a string. I don't know why I was having trouble with the actual F-sharp function. There must have been some sort of thing that I wasn't thinking right, but so now I'm just gonna wire that up to a quick path. And we'll call that. When it occurs to you three hours from now we can put the correct line of code in show notes. Yeah, yeah, exactly. That's always the way it works. Yeah, exactly, yeah, exactly. So in this case, I will just call get data format. And so I've just kind of done this inline pipe where I'm calling get data and I'm piping the result of that into the format function and the result of the format function goes into the okay. So let's just go ahead and start with this without debugging here. Oh no, there were build errors. What do I do this time? Because capitalization turns out that's important. There we go, okay. So now the web server has started and goodbye, it works again. Hello, it works again. We'll go fairies. And there we go. So I just have a data set here that let's see if I can zoom in here. It wasn't the best zoom, but yeah. So you can see there's this schedule ID, route ID. Yeah, so this is the actual data from the fairies in this Yaddle area. So I mean, you could conceivably take, okay, given a schedule ID and a route ID and the description, correlate that schedule and route and say, okay, these are the things that I care about, so then I could pass that to another thing that says, okay, for a given route and for a given schedule, give me the set of departures that are gonna happen at a particular terminal or something like that. And you could use the description to sort of throw that up on your app or something like that. So I mean, even with just not being able to think while coding for some reason, I was able to spit out a data set pretty quickly here and not with that much code. Let's see, what do we have here? 39 lines of code with some comments. And 38, if you take out the date string, which you're not even using, right? Yeah, yeah. Never do this. Never do this. We always do this. You can't hide your codes. So you are doing it already. I just, I don't wanna perpetuate a bad practice, but yeah, so kinda, I hope this sort of demonstrated that, you know, A, you can use F-sharp to do real stuff, like, you know, there's kind of this misconception that it's for super smart people who only do math and science and all that sort of stuff. And, you know, certainly great for that. But, you know, here, this is just a web server picking up a real JSON data set and playing around with it. And in this case, I just dot into what I need. I format the data into a string. I mean, I could of course do more with that data if I wanted to. I could construct some types and then work with those and then, you know, build out an application, which is what I'm actually doing. So are there people that build their data libraries in F-sharp and then call them from their C-sharp apps? Is that the? Absolutely. Yeah. That's a good scenario. Yeah, yeah, that's very common. Typically what'll happen is, you know, they may have some existing code that was written in C-sharp. They have a web service or a WPF app or, you know, something like that. And they say, okay, well now we have this new requirement. Right. Which, you know, we could certainly do it in C-sharp but we heard F-sharp is great for it, so let's give it a go. Right. And then they do it and then they love it and then they keep wanting to write more F-sharp. And so because it's just a project, you know, just to demonstrate how easy this is, I will add a new project in C-sharp. We'll do it a framework 4.6 library. Do you trust this source? Are you kidding me? Of course I do this in my laptop. You got that on creating a new, I've never seen that when you created something new. I've only seen that when you open existing code. That's interesting. But so I can go add reference, class library one, it's already there. Okay. Did I click okay? Oh, did I create this Donut standard? Oh, that's my bad. Well, so we have a bit of a point in time problem which is, I mean, that's gonna be coming in a future update is the ability for F-sharp projects to reference Donut standard class libraries. And basically work bi-directionally in that case. And then we're also gonna be doing some future work to take this project system that we have here and use the same project system that C-sharp is using for .NET Core and Donut standard. And so as that becomes the future project system of C-sharp, that's also going to become the future project system of F-sharp. Okay. And I mean, I guess I could show you debugging but debugging also works in F-sharp. It's, you know, it's not too crazy. You could write a PCL, a portable class library using F-sharp, right? Absolutely. And call it from multiple places. Absolutely, so if I go- So that might, that's, just to finish the thought, that might be the way of getting into this, right? Just focusing on a handful of things that does really, really well, right? Those bits of the app in F-sharp to kind of get your feet wet without deciding that you're going to completely switch over everything over to F-sharp, right? Exactly. You can just create a class library and just stick it in your existing solution. Or as you said, a PCL, maybe, so like these portable profiles, for example, these map to Xamarin profiles. So you're building a Xamarin app. You could have a library component in F-sharp. You could actually write the UI in F-sharp, which is what I'm doing today in Visual Studio for Mac, which actually also supports F-sharp. So I'll just open that up really briefly to just show you that it exists. Once it loads, my machine seems to be having a bit of stuff here. So there's this fairies thing. So you're just showing Visual Studio code, which has support for F-sharp. That too. And Visual Studio for Mac has support for F-sharp. Yeah, so this is a talk that I'm working on, but yeah, yeah, there's, and so here, like getting some highlights, that sort of stuff, and under this fairies right here, you can go this tab controller, that's the one. So you're doing the whole app in F-sharp. Yeah, okay. So for example, I mean, this is just an absolutely dead basic sort of thing here that doesn't even really do anything except for allow you to switch between tabs in an iOS app. But I mean, as you can see, it's less than 20 lines of code, and this is a UI tab bar controller, which kind of lets you go back and forth between different tabs, and you can launch it on the iPhone simulator, which you get, and so there's being able to click on that sort of stuff. That's 20 lines of code to get that hooked up. It's kind of nice. So templates are definitely a work in progress there. We definitely want to get more templates out for Xamarin. Get some of this sort of stuff right here, making sure you inherit the right thing, and for different types of apps that you want to do where there's different controllers, we could just have different, lay out the boilerplate for you. So then all you're focused on is, okay, well, what's the title? What's the background color? What children do I want to add to this UI view controller, that sort of stuff? But it's also, it's pretty easy. I highly recommend people try it out. This is Visual Studio for Mac, which is in preview. It already works today. Visual Studio, it's already there. You can set up the nightly feeds, get even more stuff. There's Visual Studio code. I'll just briefly show, there's this inide F-sharp. So this is a community project that is amazing. They have a ton of features in there. So many of that, you'll probably think that Visual Studio code is itself an IDE by using this. And so this, because I'm running on Mac, it requires mono, but if you have it on Windows, it just needs the F-sharp tools and MS build and that sort of stuff. And it, yeah, it gives you all sorts of really cool stuff. Some syntax highlighting, tool tips, go to declaration, show symbols in file. It has the little Visual Studio code, code lines. It actually takes advantage of that and then puts type signatures in the code lines thing that pops up too, so. Cool. Yeah, it's really great. You can basically, whatever flavor of tooling you want, you can use F-sharp in, which is great. There's also a command line, but I'm not gonna show that, but you know, Donut CLI, you know, Donut New console, Dash Lang F-sharp, Donut New Class Lib, Dash Lang F-sharp for doing stuff on Donut Core. It's all there. So what's the best way to learn F-sharp? Best way to learn F-sharp. There are a number of good ways to learn F-sharp. One of the things that I would recommend is we'll go docs. Interesting that type extension showed up here. There we go. Ooh, the new header's there. I got the header color change for the docs, so I just didn't, I didn't realize that. So we have the F-sharp guide. So if you go under docs.microsoft.com.net, you see there's this F-sharp guide here. Click on that. There's a couple of different things. You know, there's some links to external sources that are amazing that we definitely suggest. Then we also have our own content. There's this tour of F-sharp, which kind of goes through, you know, at a very fundamental level, what are some of the cool features of the language and why you might use them, what some of the code looks like. You can copy and paste this over and run it on your machine. We have a couple of tutorials for getting started. So getting started with Visual Studio. These are the kind, this is, you know, setting yourself up and running code using F-sharp interactive, which I didn't even show, but that's a replica. It also works with Xamarin Workbooks, right? Does Xamarin Workbooks support F-sharp at this point or is there only C-sharp? No, it's only C-sharp at the moment, but they are going to be adding F-sharp support. They're super excited. I know that Miguel loves F-sharp, so he's going to want to add it. It can't be too far away. Yeah, and so then we have getting started with F-sharp and Visual Studio Code and I-Nite. So, you know, this is the setup, this is the thing you got to click on, like, you know, the name of the extension, you know, how you can use that with command line tools just using the.NET CLI. So you can find all those ways to get started here. I'll be adding a Visual Studio for Mac article here pretty soon. I've just been busy with other stuff. And yeah, and then, you know, you want to dive into parts of the F-sharp language that are kind of weird. Like, say you're already on your machine, you saw some code online, tried it out, kind of worked. You're not really sure why. You don't know what's going on. You can go here. You can be like, oh, well I saw this thing called async. Oh gosh, what's that? Oh, asynchronous workflows under F-sharp language service. And so you can go here and sort of get a really deep explanation of the actual language constructs and why things are happening the way they are. Another one that I highly suggest is F-sharp for fun and profit. And actually, I actually like the Git book more than anything else. I donated to this, which is pretty neat. So this right here, so if you go ahead and read this here, this is a huge thing written by Scott Willaschen who is a longtime member of the F-sharp community who he came from an enterprise development background. And so although this isn't the enterprise learning thing, it's actually really fun and exciting. And all that sort of stuff. He's like, oh, if you have used Python or C-sharp or Visual Basic or something like that, well, here are some common concepts that you know in those languages. And here's what it looks like in F-sharp. And so this is super, super awesome. Like this low-risk ways to use F-sharp at work. Highly recommend this thing right here. Goes through all sorts of things that F-sharp is good at in ways that you can incorporate it into your code base without basically telling everybody, oh, you gotta go learn a whole new language to do everything, right? Yeah, incremental, using it incrementally, picking a specific task and using it would seem like a great way to get to introduce it into your existing code, certainly. I know that when I was going from VB to C-sharp, I made good use of a lot of these. There were some tools or online places where you could enter VB code and it would translate it into C-sharp code for you. Are there things like that for F-sharp, C-sharp? Maybe. Maybe, all right. I'm not aware of it. That might be a good community project if somebody wants to write that. Yeah, so I mean, one thing you can do if you're into it is you can actually recompile the IL that F-sharp compiles into and you can recompile that into C-sharp. But it's kind of messy, because you see- That sounds kind of messy. Yeah, there are some, so you can go this, there's this place called glott.io. So if you just want to try it out in the browser, you can see F-sharp right there. And so this, it doesn't have too many things, like there's no, there's no even like highlighting and things like that. Like there's some basic syntax highlighting, but I can go, you know, let's square x equal to x times x, and you know, print fn square of 12 is like that. I'll go ahead and run that. And it'll run this thing, my analogist thing has like a Docker container in the background and it needs to do that sort of stuff. But then you can kind of play with it there. So there's some online playgrounds for learning how to play with it as well. There's going to be, there's this tri-f-sharp site that you may have, that you may run into at some point, which is like this silver light thing. That's going to end up getting replaced here pretty soon. The community's been working on having a much more modernized version of that. And it's using what's known as Fable, which is an f-sharp to ECMAScript compiler. And it actually produces really beautiful JavaScript, which is kind of- Is there such a thing? Yes, it is. Like the JavaScript that it produces is very functional and modern and all sorts of stuff. And it's like, it's this super incredible project and they're basically almost to the point where they can host the f-sharp compiler service in the browser itself. So you can imagine, for a playground perspective, you want IntelliSense, the browser's actually generating it for you rather than needing to go to like a remote server that goes and generates this stuff for you. So we're super excited about that and getting the work done into our compiler service project so that we could support this Fable compiler being able to do that because that lets you use f-sharp to write web apps. And so everybody has to write a web app and not everybody likes using JavaScript for it. And so f-sharp developers can say, well, I can use f-sharp. So it's pretty great. Very cool. All right, lots of cool stuff here. Thanks so much. Not a problem. All right, I hope you enjoyed that and we will see you next time on Visual Studio Toolbox.