Try to avoid global state. Everything else is a matter of taste. Pick the implementation that you find easiest to understand or least error prone and which has the required performance characteristics. If that implementation is mutable, that's ok.

Stephan

By on 7/2/2009 12:04 AM ()

How bad is the performance though actually?

I'm learning F# out of academic curiosity for the most part, so I would like to use immutability as much as I can.

You'd think it can get really bad with all the initializations, but F# is reportedly quite fast nonetheless even with functional implementations.

By on 7/4/2009 3:43 AM ()

I tend to use immutable types in my programs a lot and tend to find the performance is very good. If you do micro bench marking of immutable/mutable then mutable is always going to come out faster. However in my experience this not were the bottle necks in programs are so using immutable structures doesn’t affect overall program performance. Immutable structures use a small amount of computational performance, modern programs tend to I/O bound rather than computationally bound. The amount of extra computation performance tends to be insignificant. I’ve built large programs only using immutable structures and I’ve been very happy with the overall performance. Take a look at the some of the collective intelligence samples on git hub for more details: [link:github.com]

Immutable types have a bad image somewhat unfairly because of .NET string class. If you need to build up large strings though concatenation then you will see poor performance because each time you perform a concentration an entirely new string is created, and if the string is large then it’s going to be based on a large buffer.

Most immutable types in F# do no work like this. For example when concatenating values to an F# immutable list the pervious list is not recreated, the existing list is reused and the new node is added to the end. This means the two lists now “share” some of their nodes, but this doesn’t matter since they are immutable there’s no danger of something changing them.

Similarly F# has immutable record types that create updated copies of them. These generally perform well as you if you’re object graph is entirely immutable you generally only need to make a shallow copy. Say a record has 4 fields, that’s just 4 references to be copied – not a lot of copying. Also if you allocation then copying in a short space of time then you’ll only every writing to the first generation of .NET garbage collector, which does a create job of cleaning them up efficiently.

Finally I’ve come to find F# immutable Set and Map structures vital for multithreaded programming. It’s great to be able to pass theses structures off to separate threads to perform some processing retrieve the results and merger them in without having to worry about locking etc.

So given all that, my general approach would be to start of immutable for clarity and easy of programming. If performance is not good enough profile careful and see where the bottles necks are. You probably won’t find that it’s the immutable types that are problematic, but if you do you can always optimize and use some mutable types in their place.

Hope that helps clarify things a bit,

Rob

By on 7/5/2009 12:04 AM ()

Thanks, that gives me some direction.

The performance is easier to guess intuitively now that I know to think in terms of Gen 0 heap size and copy time.

Another thing I realize now too is that there isn't any getting away from mutable objects so long as I want to ensure that an object is straightforward to use from other .NET languages, but it's still a lot easier to manage the state of mutable objects when they're made up mostly of immutable objects.

Also, I'm guessing immutability is impossible when you need to abstract the state of a non-stateless network protocol.

By on 7/5/2009 7:44 PM ()

Also, I'm guessing immutability is impossible when you need to abstract the state of a non-stateless network protocol.

Actually, you can model state without keeping a mutable variable. The State Pattern gets you part-way there: it suggests keeping state by instantiating singleton objects, and maintaining a mutable reference to the current state class.

In a functional language that supports mutually-recursive functions, though, you can keep the state in the instruction pointer by calling the correct function for the state you want to transition to; about as close as you can get to totally immutable in a von Neuuman Architecture.

For an example in F#, see the bubble sort code in this thread.

By on 7/5/2009 9:12 PM ()

Actually what I meant is that it probably gets to be quite difficult to make an immutable object that has a lot of properties that change quite often.

It seems like it would get even more complicated when complex objects need to reference other complex objects. The state pattern doesn't seem to be too helpful in that regard.

Maybe I'm missing something. The fact that I'm using the word "object" so much is probably a bad sign already. Hmm...

Your other thread is quite useful by the way. I thought I was pretty comfortable with functional execution flow already, but I find myself referring to it like a cheat sheet :)

Thanks for that.

By on 7/6/2009 8:21 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper