Just a quick note to men­tion that I will be speak­ing to local user groups about Aspect Ori­ented Pro­gram­ming next month:

The ses­sion will offer you a high-level overview of AOP and give you some ideas on how it might help you write cleaner, more reusable code. I’ll be includ­ing plenty of code demos, the more involved of which will be in Post­Sharp given that most of my expe­ri­ence of AOP is through Post­Sharp, but there will also be exam­ples of AOP using dynamic inter­cep­tors and higher-order func­tions in F#, etc.

Any­way, hope to see you there, do come and grab me to say hi. Smile

Share

Nor­mally, with lan­guages like C# or Java, there is quite a bit of over­head in cre­at­ing a quick and dirty pro­gram to do small tasks like bulk renam­ing files in a direc­tor, etc. This is the spot that is filled by script­ing lan­guages like Python, Perl and Ruby, but did you know that you can write F# code in a script­ing style too?

If you have F# installed, it will reg­is­ter the .fsx exten­sion as F# script files. From within Win­dows Explorer you can exe­cute it directly by select­ing the “Run with F# Inter­ac­tive” con­text menu option:

image

Exe­cut­ing a F# script file this way would send the file to the con­sole ver­sion of F# inter­ac­tive, fsi.exe.

You can also dou­ble click on the file to edit it inside Visual Stu­dio, whilst writ­ing F# as a script you have access to a num­ber of com­piler direc­tives such as __SOURCE_DIRECTORY__ and __SOURCE_FILE__ which returns the cur­rent direc­tory and file­name respectively.

As a sim­ple exam­ple, here’s a script I put together in 5 min­utes that iden­ti­fies image files in the cur­rent direc­tory and sub-directories and renames them to be title cased, e.g. “my_image.jpg” will become “My_Image.jpg”.

Exe­cut­ing this script gives the fol­low­ing output:

image

Part­ing thoughts…

Using F# in this fash­ion has the obvi­ous ben­e­fit that you don’t have to learn another lan­guage just so that you can hack some scripts together to per­form sim­ple tasks for you. Build automa­tion tools is one area this can be very use­ful. Inspired by the Rake build tool of the Ruby world – which allows you to write your build script in Ruby – we now have a Fake build tool that lets us do the same with F#.

Another ben­e­fit of using F# as a script­ing lan­guage is per­for­mance. Script­ing lan­guages typ­i­cally sac­ri­fices exe­cu­tion speed for the ease of mod­i­fy­ing and deploy­ing. F# on the other hand, is not inter­preted and is always com­piled first so it can be faster than pure script­ing languages.

Share

I touched on the topic of mem­o­iza­tion in the past in rela­tion to doing aspect-oriented pro­gram­ming with Post­Sharp, how­ever, with func­tional lan­guages like F#, Haskell or Erlang there is no such frame­works (although Post­Sharp should still work with F# to some extent) to help you.

That’s not to say that you can’t do AOP in a func­tional lan­guage though, in fact, here’s a sim­ple imple­men­ta­tion of the afore­men­tioned mem­o­izer in F# as a higher-order function:

image

Here’s a FSI ses­sion that shows the mem­o­ize func­tion in action:

image

Note that the mem­o­ized ver­sion of the orig­i­nal func­tion f took a sec­ond to exe­cute the first time around but then sub­se­quent calls didn’t take anytime.

Part­ing thoughts…

The imple­men­ta­tion I’ve shown here is a very basic and only works for func­tions that takes in a sin­gle para­me­ter, if you can think of an ele­gant way to make it sup­port func­tions with dif­fer­ent num­ber of inputs please feel free to con­tact me as I’m very inter­ested to hear about your thoughts.

Also, this imple­men­ta­tion won’t work with recur­sive func­tions because when the func­tion recurs it will be call­ing the non-memoized ver­sion of the func­tion, it’ll require some spe­cial han­dling to make a recur­sive func­tion ‘memoizable’.

In gen­eral, I don’t feel AOP is as well suited to func­tional pro­gram­ming as it is to object ori­ented pro­gram­ming, but there’s still a pocket of use cases where AOP can be ben­e­fi­cial. Mem­o­iza­tion is one of them, so is trac­ing and input val­i­da­tion, all of which is pos­si­ble through the use of higher-order func­tions. A word of warn­ing though, If you’re famil­iar with frame­works such as Post­Sharp, the AOP expe­ri­ence you’re going to get through higher-order func­tions is not going to be as unob­tru­sive as you’re used to.

Share

In F#, you have the choice of using a struct or a record as a light­weight con­tainer for data. The sim­i­lar­i­ties between the two are strik­ing – both are immutable by default, nei­ther can be inher­ited, and they both offer struc­tural equal­ity seman­tics by default too!

How­ever, there’s a key dif­fer­ence between them, their per­for­mance char­ac­ter­is­tics.

When you’re deal­ing with tons of small objects, structs offer sig­nif­i­cant per­for­mance ben­e­fits because as value types they are stack allo­cated which is much faster, and don’t need to be garbage collected.

Records on the other hand, are ref­er­ence types, and are there­fore heap allo­cated (plus point­ers on the stack), which is slower, and require the extra step of garbage col­lec­tion when they’re no longer referenced.

As a sim­ple test, given these two iden­ti­cal types, one as a struct and one as a record:

image

The snip­pet below con­structs two arrays each with 10 mil­lion items, one with struct instances and the other with record instances:

image

Over three runs, the structs array took an aver­age of 0.146 sec­onds to con­struct whilst the records array took an aver­age of 2.919 sec­onds!

Part­ing Thoughts…

Although this test shows that cre­at­ing large num­bers of records takes sig­nif­i­cantly longer than structs, in prac­tice how­ever, would you really care if gen­er­at­ing 10 mil­lions objects takes 3 sec­onds instead of 0.1? Is that likely to be the source of your per­for­mance issues?

All and all, the per­for­mance gains you get by using structs over records is neg­li­gi­ble, in most cases you won’t be gen­er­at­ing large num­ber of these objects fre­quently enough for you to notice the dif­fer­ence. Also, we haven’t even cov­ered the cost of copy­ing them when pass­ing them as para­me­ters (Value types are passed by value as opposed to ref­er­ence), which if you’re not care­ful can have a detri­men­tal effect on the over­all per­for­mance of your application.

Also, records have two very use­ful fea­tures for work­ing with F# which structs don’t:

  • type infer­ence can infer a record’s type, no need for type annotation
  • records can be used as part of stan­dard pat­tern match­ing, no need for when guards

both are big pluses in my book and worth con­sid­er­ing when you’re choos­ing between records and structs.

Share

In my pre­vi­ous post on dis­crim­i­nated unions, I pre­sented dis­crim­i­nated unions as an alter­na­tive to stan­dard .Net classes to rep­re­sent hier­ar­chi­cal data struc­tures. How­ever, in terms of data struc­ture, dis­crim­i­nated unions share much more sim­i­lar­i­ties with enums than they do classes – both allow you to define a set of named con­stants and asso­ciate some data with these constants.

The syn­taxes for cre­at­ing enums and dis­crim­i­nated unions in F# are very sim­i­lar too:

image

Despite their appar­ent sim­i­lar­i­ties, there are some sig­nif­i­cant dif­fer­ences between the two:

    • Enums don’t offer a safety guarantee
    • Enums only hold one piece of data
    • Dis­crim­i­nated unions are ref­er­ence types
    • Enums can be used as bit flags

Now let’s take a closer look at these differences.

Enums don’t offer a safety guarantee

As enums are lit­tle more than syn­tac­tic sugar over a prim­i­tive inte­gral type such as int, there is no guar­an­tee that the value of an enum is valid. For instance, it’s pos­si­ble to cre­ate an instance of an enum type with an inte­gral value that is not asso­ci­ated with one of the named constants:

image

it’s easy to see how bugs can creep in when you mis­tak­enly cre­ate enum val­ues that don’t make any sense, espe­cially when you’re work­ing with enum val­ues from exter­nal sources. Which is why it’s a good prac­tice to check the enum val­ues with the sta­tic Enum.IsDefined method.

Dis­crim­i­nated unions, on the other hand, can only be one of the defined val­ues, any attempts to do oth­er­wise will be met with a swift com­piler error!

Enums only hold one piece of data

This one is self evi­dent from the ear­lier snip­pet, enums only hold one piece of data but dis­crim­i­nated unions hold a tuple of data.

Dis­crim­i­nated unions are ref­er­ence types

Enums are value types and instances of an enum type there­fore reside on the stack as a few bytes. Dis­crim­i­nated unions, as do all other ref­er­ence types, reside in the heap (plus a pointer on the stack whilst it’s still ref­er­enced) and need to be garbage col­lected when they are no longer referenced.

The impli­ca­tion of this is such that enums offer sig­nif­i­cant per­for­mance ben­e­fits over dis­crim­i­nated unions. Take the fol­low­ing snip­pet for instance, where I pop­u­late two arrays with 10 mil­lion items, one with enums and the other dis­crim­i­nated unions.

image

Aver­aged over three runs, the enum array took 0.048 sec­onds to fin­ish whilst the dis­crim­i­nated union array took 1.919 sec­onds!

Enums can be used as bit flags

From MSDN:

You can use an enu­mer­a­tion type to define bit flags, which enables an instance of the enu­mer­a­tion type to store any com­bi­na­tion of the val­ues that are defined in the enu­mer­a­tor list.

image

Share