 Okay, so one of the things that mini-constant LCI is meant to do is encourage people who haven't presented at free software conferences before to get up and do just that. Our next presenter is a functional programming geek from who's recently finished his Bachelor of IT at QUT, so he's also a local presenter which is rather good. Please welcome Brian McKenna speaking about F-Sharp. Well, that's up. All right, yeah, I just finished from QUT and I'm about to move down to Sydney to work for an Australian company called Atlassian, so check them out if you're into Australian IT. Is that better? Good. All right, so I'll just get strange to the talk because we don't have much time. So why am I talking about this now? Well, F-Sharp was first released around 2002, so it's kind of getting old, like according to programming language history anyway, so why would I be talking about it in 2011? Well, the old versions of F-Sharp up until November were released under this thing called the Microsoft Research Shed Source License Agreement. So that was not an open source license and you could download the source code, you could compile it on Windows maybe and it just wasn't, but you weren't allowed to distribute your changes or anything. It was only for personal use. November 2010, they released under the Apache license. So now it's completely open source, you can download it and redistribute it everywhere and you can make your own version of F-Sharp. So why would you look into F-Sharp? Well, it runs on the .NET platform, so that means it's portable. You can compile something on Windows, have it run on Linux, have it run on Mac, same binary format and it runs on all three operating systems. It's also language independent, so you can use F-Sharp with C-Sharp with Ion Python with Ruby with any language that runs on .NET at the moment. There's heaps of them. So you can look into that and try and integrate that with F-Sharp. It's functional object oriented, which is actually a trend these days. I've seen OCaml come around about 1996. Scullers come out, well, it's been around for a little while, but it's only gotten pretty popular pretty recently. And there's languages like Phantom that are coming out and they're all integrating, they're object oriented at the core, but they're integrating functional aspects to make your code cleaner. So F-Sharp's largely OCaml compatible. It actually is started off as camel.NET, but then it started making some mutations to language and kind of forked off onto its own language. But a lot of the basic syntax is still OCaml. So Microsoft has taken the concepts from F-Sharp like things like type inference, higher order functions, tuples, all these things, and they're put into their other languages. So they've taken all the good things from F-Sharp, put it in other things. So I think if you stay into F-Sharp, if you study F-Sharp, you're going to stay ahead of the curve and you're going to see that you're going to know things before they actually get into the mainstream. Great opportunities for parallelism because you've got immutable data and data sharing is pretty much the worst thing for parallelism. And something I like, which is it's white space sensitive, so it looks pretty nice. I like languages like Python and Haskell, so. Who here is the fan of Microsoft? Everyone, right? Benning's conference, Microsoft. All right. So it comes with a REPL. It's not one of those REPLs where you can't create classes or anything. It's a full REPL. You can create classes. You can create anything that you can do with the compiler. You can do with the REPL. So it's really nice to use. So start off with the actual language. It's multi-paradigm. So on the left here, I've got its object-oriented. So I've just got a little example. So you've got a person and he can shower or he can eat something. You can see down in the comments, Roger is showering. Roger is eating lobster. So it's object-oriented like you're probably used to with C-Sharp or Java. But then on the right, which is really interesting, is a full Quixel implementation. And I mean, that's only about 10 lines of code. And I think that's beautiful, really. I mean, you wouldn't be able to do that in a, just doing that in an object-oriented fashion or even like a procedural fashion. You can't make something that short and make it functional. So type inference. Usually with Java and C-Sharp, you have to go like string A equals and put in your string. With F-Sharp, it kind of guesses. It is able to infer what type every variable should be. What type every binding should be, I should say. So in the first example there, let A equals 10 is able to see that A is an integer and just uses that as the type. It's a strong type, so it's not dynamic. It resolves the types at compilation, but it does that through inference. So we've got a function there. So let Fx equals x plus 1, two string. That takes an int and gives you a string. So that's the type definition there. Gx equals x. It's got a dash A there. That means it's generic, so it can take any type and give you back that same type. You can be explicit, so we've got a h function there which takes an integer and gives you back that same thing. So it's able to infer that if it takes an integer, it gives back an integer. With the bottom one, it's got let Ix and the type is an int. That int is actually to that function, so it's able to infer that if it returns an int and it's only returning the parameter, then it's able to see that the parameter must be an int. So this allows for some significant code, list comprehension, so you've probably seen this in Python or I guess Ruby's got it. So you're able to just generate lists using short syntax. You're able to provide a step in the middle. So I've got 2.2.10. That skips every second one. And you're able to do with anything, so I've got characters there as well. And you can do complex... You can run functions inside of the comprehension. So there's a for loop and... Well, it's a comprehension that gives you back x times x. So it squares each number in that comprehension. That arrow is shortened for a yield. Yield just returns a value and assigns it to that list. And you can do that yield estimation mark. So that takes a list and kind of concatenates them all together and gives you back one big list. And you can kind of map... You can put them all together and you can generate complex comprehensions from them. They work for arrays as well. In all these examples, I've got lists, but fsharp supports arrays, so you can do it with arrays and you can do it with lazy sequences. Algebraic data types. Most of this talks going to be about the functional types, the functional parts of fsharp, because I'm assuming most of you are going to be into object-oriented programming or something like that. So I'm going to go over the functional parts. So algebraic data types are pretty big in functional programming. You've got tuples, which take... Which... The length is encoded in the type and the type of every part of the tuple is encoded in the type as well. So an int by a string by a string is different to an int by an int by an int. So you can't actually mix them together or you can't... It's all encoded in the type anyway. And a record is just pretty much a named type. So I've got... In that tuple, I've got 20, Brian, Brisbane. You can use it like that if you know what they mean, but if you want to kind of make it explicit what you mean by each of those numbers and strings, then you can make a record and say that they age 20, my name is Brian, and the location is Brisbane. Discriminate unions. So this is kind of a way of making like a single hierarchy. In object-oriented, you probably make an employee... You make an abstract class of employee. You make a concrete class of part-time and a concrete class of full-time. And they all... The part-time and full-time classes would be... would derive from the employee class. With F sharp, we've got discriminating unions. So we can just say that a part-time... Say that a part-time is a float and an end and a full-time isn't an end. And they're both employee types. So you can pass them around and you can pattern match on both of those. So it's just a short way of creating a single hierarchy. We have enums. They have to be fully qualified. So size.small, size.large. But they just work as an enum. And pattern matching is a big thing in functional programming. So we make a function called printItem. It takes either a sum or a none. And that's a type of option. So you can either give it a sum of three or you can give it a none or you can give it a sum of one, a sum of four or a none. And it prints out... In this example, it prints out what you give it. So we have a three, nothing here. We have a one, we have a four, so on. Higher order functions are a big thing in functional programming as well. So we've got a plus function, which is an operator as well. It takes an end and returns an end. Now we can carry that and say that the first parameter is five and assign that to another function. So add five. It takes a single parameter now and gives you back an end. So add five to ten gives you back fifteen. So it's a way of kind of reducing the amount of parameters that something takes and binding them to a name. This is an example of a closure in an anonymous function. So we have a function called createAdder. The best way to show it is through the add three line. So add three equals createAdder three. So what that does is it passes three as X in createAdder. Then createAdder returns a function that takes a Y and returns three plus Y. So then we can use that add three function and apply ten to it and we get back thirteen. So it's enclosed that X parameter inside that new function. We're able to compose functions as well. So for example, you'd probably write abs and then bracket X plus four in something. But we can get rid of one of those parameters and just have composed the two functions together. So we've got a left composition here. So it does an abs of plus four. So when you give it negative four, it abses out and then it pluses four to that. So you go from negative four to four and then to eight. And the same thing with the bottom there, except we're dealing with five and we're dealing with a right composition. So it does abs first, then it does the plus five to that negative four and we get back nine. To mutate something in F sharp, we've got to actually say that it's mutable. So it's got a keyword there. So you say this binding is mutable and then you can use this backwards arrow to mutate that. In the first example, in the comments there, I've got let A equals one and then I've tried let A equals two. It can't do that. F sharp just doesn't allow that. It's, bindings are always immutable unless you provide the mutable keyword. And then I've tried mutating A to make it two. I can't do that unless it's actually, unless the mutable keyword is used. So I've made an F function here anyway that takes an X pluses to that A mutable variable and stores it back into A and then it prints it out. So that works nicely. But you can't pass mutable variables around. You can only pass references around. So here I've defined a reference to 100 and there's a special syntax where estimation mark of the binding means get the value from it and the colon equals means change the value of that reference. Change what it's pointing to. So you're able to pass references around. The actual reference, the memory that it's pointing to is mutable but the value that it's pointing, the actual value that it's pointing to is mutable. So you can mutate that as you want. Munits of measure are pretty cool. This is pretty unique to F sharp. I haven't really seen this in many other languages. So you can annotate something as a measure and you can kind of use that in your program to say this is a measure. So we've got a float of m, so that's like saying we've got 10 meters. We've got 80 meters divided by 5 seconds. So that creates a new type of float meters per second. And we can add two. So we can make functions that take those measurements and it's type safe. So if you can't add one second to one meter, it just doesn't make sense. It's all defined by types. Lazy computations. In this example I've made a Fibonacci function. I've also made a time function, so it times any lazy computation. So what I've got here is I've got a Fibonacci of 35, so it takes about 521 milliseconds. As you can see, time lazy. But every other time that I've called it, it takes 0.001 seconds. So it doesn't actually compute when I say Fibonacci 35 didn't compute because I've got the lazy keyword there. It's when I do L.force up in the time lazy function that it actually gets computed. So the first time it gets computed and then it stores it in that reference. And then every other time I want to get it back, it's already there, so it takes 0.001 milliseconds. Milliseconds. There's a tricky subject of monads in here. F-sharp supports a special syntactic trigger to allow monadic computing. They call it computation expressions, which I think is pretty smart because it kind of gets around that whole monad thing. So to define a monad, you just have to create a new type, give it a delay definition, bind definition, and return definition, where delay just takes a function. Bind just takes a value in a function and return takes a value, and they all wrap them up and pass them to the next function in the chain. You probably won't understand that until this example. So here I've got, from the last one I've got, I'm defining trace equals new trace builder, so I've created a new instance of that. And now I can use trace as a keyword and I can use these new keywords, let, exclamation mark, and return. And in between each of those lines there, so in between let and return, code is happening. So that's a pretty nice way of, you know, running code in between each of your sequence of instructions. So down the bottom you can see you start tracing, it's binding to three, it's returning 3.14, and the actual result at the bottom there is 3.14. This is used in asynchronous workflows. You've probably heard about these if you enter F sharp at all. So you can define a, I've got Fibonacci here again. You can find that as a asynchronous computation, so it's printing out the Fibonacci sequence. You can run it in parallel and run it, then you can do the async.run synchronously and it'll wait for each of those. And you can see it prints out each one. Code quotations. You can, down the bottom you can see I've got an at one plus two times three and then another at. That is a, that's a quotation of F sharp code. So you can put any F sharp code. I could have put a function call in there. I could have put anything. And then I pass that to the two prefix function, which pattern matches on that quotation. So it sees that I've got a specific call to plus and then it prints, it gives back a string that puts it into prefix form. And it keeps doing that recursively until I get down the bottom there. I've got a comment that says plus one and it's put it into prefix form, which is pretty nice way of transforming your F sharp code into some other language or something. So I've actually seen quotations be used for like database query language. So it actually takes F sharp code, converts it into a query language and passes it up to a database layer, which is a pretty nice thing to do. You can actually extend modules and types. So here I've got a module and I'm putting a method onto it and I'm putting a concat map method onto it. And on the string type, I'm putting a first character member. So I just really quickly, I'll show this mono develop plugin we've got. So down the bottom you can see we've got an interactive version of F sharp running. So I can put in a value there, just press control enter and it will run down the bottom and it will give you back the type and give you back the value and you can then come down and use IntelliSense and that all works fine in mono develop, which is a really nice way of developing programs on Linux. So to compile your own, you have to use a recent version of mono. You just compile it like usual. Get it out from GitHub. Get F sharp from GitHub. Just make install it. At the moment F sharp is releasing in a code drop kind of fashion. So we can't actually see what F sharp has done since they've released it last in November. They're not accepting any patches from us. They're a really small team so I can kind of understand that. So that means when F sharp releases a new version, you have to go in and merge back in all those changes and it's slightly buggy on mono at the moment. If you download the version from Microsoft, you can actually run it on Linux and you can run it on mono, but it's a bit buggy. So I don't recommend that. I recommend making your own version. And you can help out. Thank you. So it's been good to see Pete tweeting about the talk during the talk. Are there any other questions for Brian? Oh, yep. With the definition of mono, did you have an F sharp there? What's the significance of the delay? Sorry, what definition of what? Of monads. Monads, yeah. Significance of delay. That's a good question. It is just passed in at the beginning of that workflow execution. So you can see it's just start tracing. So it just takes that whole, as far as I know, that whole sequencer is a function that gets passed into delay and we've just run it. Is that... Well, I'm used to the Haskell version where you only have bind and return to worry about, not delay as well. Yeah. I couldn't really tell you why delay is necessary, but it is in F sharp. Sorry. Nobody else? Okay, so if there are no more questions, Brian McKenna.