The Least a C# Programmer Needs to Know about F# Part II--Modules

The Least a C# Programmer Needs to Know about F# Part II--Modules

  • Comments 3

Jomo Fisher--Many languages, especially those in the OO vein, require an outermost class to put code in. Usually, good practice requires an enclosing namespace as well.  F# allows functions and even function calls in the outermost scope. Here is the minimal F# program:

 

printf "Hello!"

 

Really, that's the whole thing. My first concern upon seeing this was that the all these functions in the global namespace would eventually collide in larger projects making things unmanageable. It seemed a lot like returning to the nasty global state that you sometimes see in older C codebases. It turns out, however, that F# puts each file's functions, function calls and types inside its own construct called a "Module". Consider this slightly modified version:

 

// File Hello.fs

#light

let Say s = printf s

Say "Hello!"

 

Which is saved in file called Hello.fs. This defines a function called 'Say' and then calls it. Using Reflector, I can see the Say method decompiled into C#:

 

[CompilationMapping(SourceLevelConstruct.Module)]

public class Hello

{

    public static T Say<T>(Format<T, TextWriter, Unit, Unit> s)   {

        return Pervasives.printf<T>(s);

    }

}

 

The F# compiler has put the method into a public class called Hello . This is F#'s representation of the Module. The class name Hello is derived from the file name Hello.fs.  You can change the Module name if you like:

 

module MyModule =

    let Say s = printf s

    Say "Hello!"

 

For larger projects, I think its best to explicitly name modules. For smaller, one-off projects its convenient not to have to think about it.

 

In most .NET projects I've worked on, there usually ends up being a few utility classes that just have a bunch of related static methods in them. These are functions that just didn't cleanly fit the OO paradigm. Its tempting to think of these classes as code smells. After all, surely there's a clean OO representation for them that I haven't thought of yet, right?

 

I think the answer to this is: no, not everything fits well into object-orientation.

 

My proof by existence is to consider .NET's Stream classes that were released in .NET 1.0. These classes were extremely well factored. They beautifully hid the underlying media or communication protocol behind an abstract stream of information.  They were also damn hard to use for simple cases. In a later .NET release the File, Path and Directory classes were introduced. These were just classes with nice, simple static methods for doing the common things you want to do with files, paths and directories.

 

F#  makes this style of API a first-class citizen: the Module.

 

So am I saying good-bye to OO? No way. But I consider it a hammer and not every problem is a nail.

 

This posting is provided "AS IS" with no warranties, and confers no rights.

Leave a Comment
  • Please add 8 and 2 and type the answer here:
  • Post
  • “F# makes this style of API a first-class citizen: the Module.”

    A big +1 to that. I think having modules as well as classes is only a small shift in thinking but it’s an important one. The C# model of OO seem designed to make you think everything should be class, that is every part of a program should be modeled as something that can have multiple instances. For me, this simply isn’t true there are lots of places where having modules are very useful, the File/Directory/Path static classes from System.IO you high light are great examples of this. Sure let’s not throw out the baby with the bath water there are still lots of places where classes are useful, but let’s not assume classes are simply better than modules nor feel guilty about having modules/static classes in our programs.

  • Expert F# is about practical programming in a beautiful language that puts the power and elegance of

  • Expert F# is about practical programming in a beautiful language that puts the power and elegance of

Page 1 of 1 (3 items)