May 2009





first impressions: ndjango updated to the new f# ctp

Cats: Uncategorized
Tags: , ,

Thu - 21 May 2009 - 03:21 PM

so the second i post up the ndjango port, the new f# ctp hits the web... nice timing on my part ;) . well, i can take a hint. i spent some time yesterday and branched off a new fork in the svn for a version that works against the new ctp. i still have to spend some time playing with it, but at first glance, the old code worked. There's quite a bit of library name change (moving away from ocaml naming conventions it seems like), but once the renaming was done, all of our unit tests ran just fine. I have to admit that i've grown used to the underscore notation for f# code, and seeing camel case throughout will take some getting used to. Also - I'm starting to see some functions renamed in a way that's less clear than before... hopefully the f# team won't fall into the trap of c# v java where some classes and methods were named differently just for the sake of being different (*cough stringbuilder/stringbuffer cough*). And why do away with the String module?

On another note, we updated the ndjango integrations projects to include a hook for asp.mvc. You should be able to use ndjango with it now, by just declaring a variable in your Global.asax and then instantiating it on app start. That'll load up the right dlls and hook in where necessary.

1 Comment »


Putting it all together: F# on the web

Cats: Uncategorized

Wed - 20 May 2009 - 12:24 PM

The last few months have certainly been interesting. I was busy building an MVC framework, and decided to use NVelocity as the view. A friend pulled me aside, and (after slapping me for using a 6 year old, poorly-supported java port), said "take a look at the templating language in django". The rest, as they say, was history. Realizing how clean and simple the language was, I set out to build an implementation (of the template piece). As I was just starting to notice F#, i decided - why not? And so my first major project in F# was the core of the NDjango parser , a pure F# (and consequently .NET-friendly) implementation of the django templating language. Now, it's certainly gone through a number of iterations, so most of my early f#-n00b mistakes should have been excised.

The really interesting thing, though, is that as I was building this parser, I started to really get an appreciation for F#, and for it's uses in a more business-oriented environment. This was all coinciding with me building out Bistro, and so concepts merged. Bistro focuses on having multiple controllers, with well-defined inputs and outputs, service a single request. I started seeing parallels to functions - each controller can be viewed as a function with discrete parameters and tupled return values.

In c#, these concepts are relayed to the runtime through class members that are marked with scope and directionality attributes (request-level input parameter, session-level output parameter, etc). Well, with f#, and quotations, you can get away with not having to be that explicit. Whether something is an input parameter or an output parameter becomes easy to tell. The rest, can be handled through discriminated union markers (see earlier post). What that means is that I can write an F# function, and it becomes a controller, almost instantly:

 
[<ReflectedDefinition>]
[<Bind("get /home/index")>]
[<RenderWith("Views/Home/index.django")>]
let home_ct (ctx: IExecutionContext) =
    let Message = "Welcome to Bistro.FS!"
    Message
 

this controller has no input parameters, but has an output parameter called "Message" (yes, the resource name is pulled from the Quotation tree), of type string. We use defaults for most common behaviors - so that one right there is scoped to "request".

A more complex example

 
 
[<ReflectedDefinition>]
[<Bind("get /auth/changepassword")>]
[<RenderWith("Views/Account/register.django")>]
let do_change_pass_ct (ctx: IExecutionContext) (currentPassword: string form) (newPassword: string form)
    (confirmPassword: string form) (errors: Errors) =
    let currentPassword, newPassword, confirmPassword =
        currentPassword.Value, newPassword.Value, confirmPassword.Value
 
    let new_user =
        if validate_change_pass currentPassword newPassword confirmPassword (report_error errors) then
            try
                if membership_svc.ChangePassword(ctx.CurrentUser.Identity.Name, currentPassword, newPassword) then
                    ctx.Response.RenderWith "Views/Account/changePasswordSuccess.django"
                else
                    report_error errors null "The current password is incorrect or the new password is invalid."
            with | _ ->
                report_error errors null "The current password is incorrect or the new password is invalid."
 
    errors
 

This one validates some data that came from the form (currentPassword, newPassword and confirmPassword), and adds to the supplied errors collection, which it then returns as a request parameter.

The semantics of defining controller behavior become incredibly simple. Bistro already strives for smaller controllers with well-defined functions. This just takes advantage of it. Now you can write your controller tier in f#, and it actually makes sense there. If you think about it - the controller tier is effectively small data processing. It's validating and transforming input data, and then relaying it to the model, which can be in c# or whatever other language you chose. With NDjango in the mix, your view is guaranteed to be free of business logic, and your separation of concerns becomes complete!

I'm sure a lot of this makes less sense on this blog than it does in my head - I've been living this for the past few months, so i'm sure some of the connecting dots didn't make it on here, but if you're interested, take a look at some of the writeups that i've put together:

Bistro itself is here, the FSharpExtensions component is here, and NDjango is here

The FSharpExtensions library still has some issues, (like url parameter values can't be option types right now, and a few others), plus the performance piece needs some work, but it's a start, and we'll be working on it. Already it performs within 90% of its c# counterpart, and that's with full-on reflection lookups on every request. Once that stuff is cached up, it'll be on-par if not faster.

As always, I welcome all feedback, on any of these projects.

1 Comment »


10 cool things about f# that aren’t functional-specific

Cats: Uncategorized
Tags: ,

Sun - 10 May 2009 - 05:58 PM

i'm going to be speaking about f# and applicability outside the lab in a few days (see here), so i figured i'd put this up here as part of my prep for the meeting. so - 10 cool things about f# as a .net/oo language

  1. #light syntax. Indentation based syntax, while i'm sure viewed as the bane of our existence, is amazingly easy to deal with, given a proper editor and assistance. Yes, sometimes it's quirky, but not having to look at 40 pages of curly braces is worth it. You simply end up writing less code, seeing more code per screenful, and writing code that's easier to read.
  2. type inference. F# is the ultimate combination - it's a statically typed language, that reads like a dynamic one. That's because the F# compiler infers value and parameter types from their usage. There are mechanisms to specify data types, but unless you're doing funky reflective programming, you don't need them often. Most of the time, the compiler will hit it spot on. That means that this works
     
    let f x y = x + y
    // val f : int -> int -> int
     

    but so does this

     
    let f2 (x: float) y = x + y
    // val f2 : float -> float -> float
     
  3. record types. Or rather how you consume them. Records are compound data structures (kind of like structs). With a record definition of
     
    type SomeRecord = {
        first_name: string
        last_name: string
        dob: DateTime
    }
     

    you can get an instance by just writing

     
    let alex = { first_name = "alex"; last_name = "p"; dob = (System.DateTime.Parse("01/01/1900")) }
     

    Cool, huh? Notice i didn't have to specify what the type of alex is. It's actually inferred from the record labels i supplied in the expression. What's more, is that i can now create a clone of that record:

     
    let alexs_twin = { alex with first_name = "twin" }
     
  4. object expressions. Ever have a piddly little object that you needed to return? Ever wonder why you have to go through the hoopla of defining a class for something that'll never be used outside of where it's declared? Well, in f#, you don't. This example comes from a parser implementation for a markup language. It was broken up into a tag class, and a node class. Tag class did the parsing, node was the AST node representation, and typically did very little work, with most of the functionality being defined in the base clas Node. This specific tag translates words into template syntax:
     
    type TemplateTag() =
        interface ITag with
            member this.Perform token parser tokens =
                let args = List.tl <| smart_split token
                let buf =
                    match args with
                        | "openblock"::[] -> "{%"
                        | _ -> raise (TemplateSyntaxError ("invalid format for 'template' tag"))
                [{
                    new Node(Block "templatetag")
                    with
                        override this.walk walker =
                            {walker with buffer=Some buf}
                }], tokens
     

    What this little code snippet does is rather than explicitly defining a new class TemplateNode that just overrides the "walk" method on Node, it combines the instantiation and definition steps, and returns an anonymous subclass of node, with the "walk" method redefined to do something else. Now, you can take this even further, and use object expressions to define anonymous interface implementations. Say you wanted to make sure that when an operation was done, some resource was released, but that's all you cared about. Simple - use an object expression to implement the IDisposable interface, and you're done:

     
    let disp = { new Object() interface IDisposable with member x.Dispose() = (*do stuff*) }
     

    Side note here - object expressions make a lot of sense when coupled with the fact that F# has the concept of closures, but that's more functional so just a quick blurb on this. A closure means that as you define your instance/type combination, you have access to local values of all of your parent scopes. That's why, in the TemplateTag example, my Node class implementation can access the local value "buf" from within it's method definition.

  5. tuples. Ever need to return 2 values from a function? Okay, you do a return value and an output parameter. Annoying to consume, but doable. But what about 3? or 4? At that point it gets to be just unmanageable. In F# this is simple. A tuple is a composition of multiple other types. If i have a function (or method, to stay with our theme) that took my "SomeRecord" from before, and returned the first and last names only, it would look like this
     
    member x.get_names record = record.first_name, record.last_name
     

    That's it! Now, when i consume it, i can either treat it as a single value of type tuple, and then use special accessor functions to read from it:

     
    let names = someclass.get_names alex
    printf "first name %s\r\n" <| fst names
    printf "last name %s\r\n" <| snd names
     

    or using f# syntactical sugar to unfold the value explicitly:

     
    let first, last = someclass.get_names alex
    printf "first name %s\r\n" <| first
    printf "last name %s\r\n" <| last
     

    or ignore one of the values entirely:

     
    let _, last = someclass.get_names alex
    printf "last name %s\r\n" <| last
     
  6. discriminated unions. When the set of values you care about depend on what you're representing, discriminated unions are awesome. Example here is - if you wanted to have a single data type that represented a vehicle, but wanted to store different attributes for different vehicle types, you could define a discriminated union that stores passenger capacity and Color for passenger cars, and maximum load and number of wheels for trucks:

     
    type Vehicle =
    | Passenger of int * Color
    | Truck of float * int
     
  7. null value handling. F# doesn't really have the concept of a null. I mean it does, but it mostly comes up when interfacing with external libraries that'll slip one in here or there. Outside of that, if you say that method someclass.get_names takes a record of type SomeRecord, you can be sure that you'll never get a null there. Now, if you want to allow for that, you can use the "Option" type. Option is a discriminated union of
     
    type Option<'a> =
    | None
    | Some of 'a
     

    which means that it either contains "None", or Some value of type 'a (the whole ' thing is to identify a generic type parameter, so the Option type is a generic type). That means that whenever you're dealing with values that may not be supplied, you have to explicitly handle that scenario. That also means that the pesky NullReferenceException goes bye-bye.

  8. lists, list literals and other fun built-in structures. We're starting to get closer to f#'s functional nature, but this is still very much oo-applicable. Lists. F# has awesome support for lists. For starters, you can do stuff like this:

     
    // new list, containing 0 through 5
    let l = [0..5]
    // new list, concatenating l with the list containing 6
    let l2 = l @ [6]
    // h is the head element in l, t is the remainder
    let h::t = l
    // pull the first three elements out into h1,2,3 respectively
    let h1::h2::h3::t = l2
     

    then you can move on to generating expressions

     
    // 10 squares
    let l3 = [for i in 0..10 -> i * i]
     

    The other thing is that default lists in F# are immutable structures, so when you modify them, you're actually creating new instances that contain the modified values. But fear not - there's no copying involved. Since each instance is immutable, f# can share elements among instances, allowing the operation

    some_giant_list @ [0]

    to not have to copy the contents of some_giant_list. Oh and with arrays, you can also do slicing notation:

     
    // generate array of 0 through 5
    let a = [|0..5|]
    // get the first 4 elements
    let a2 = a.[..3]

    .

  9. pattern matching. We're getting closer and closer to functional territory, but with f# that line is somewhat blurred. Pattern matching is effectively a very concise way to write a long if-then-elseif. You can

     
    // match over literals
    match alex.first_name with
    | "alex" -> printf "woo"
    | _ as name -> printf "don't know %s" name
     
    // and over lists
    match l with
    | h::t -> printf "the first element is %d, and there are %d in the tail" h <| List.length t
    | [] -> printf "the list is empty"
     
    // and over Types (there shouldn't be a space between the : and the ?)
    match disp with
    | : ? System.ICloneable as cloneable -> printf "%A is clonable" cloneable
    | : ? System.IDisposable as disposable -> printf "%A is disposable" disposable
    | _ as unk -> printf "dunno what %A is" unk
     

    you can also pattern match over discriminated unions (that's actually the main way of working with those), and various other data structures.

  10. access to .net libraries. Okay, i'm cheating a little here, because the remarkable part isn't that there's access to the .net library, but that a functional, statically-typed language has access to the .net library. The fact that I can reach out to components written in c#, with no penalty, is what will make this language more mainstream than most other functional implementations (scala and the like, of course, notwithstanding).
5 Comments »
Meta
Posts | Comments | RDF | Atom | Valid XHTML | CSS | Log in