3 Answers
3

In what situations lists in F# are optimized by F# compiler to arrays, to for-loops, while loops, etc. without creating actual list of single linked data?

Never.

Your later comments are enlightening because you assume that this is a flaw in F#:

...it should be smart enough to do it. Similar to Haskell compiler...

Somewhat true.

...Haskell compiler is doing a lot of such optimizations...

True.

However, this is actually a really bad idea. Specifically, you are pursuing optimizations when what you really want is performance. Haskell offers lots of exotic optimizations but its performance characteristics are actually really bad. Moreover, the properties of Haskell that make these optimizations tractable require massive sacrifices elsewhere:

Purity makes interoperability much harder so Microsoft killed Haskell.NET and Haskell lives on only with its own incompatible VM.

The GC in Haskell's VM has been optimized for purely functional code at the expense of mutation.

Purely functional data structures are typically 10× slower than their imperative equivalents, sometimes asymptotically slower and in some cases there is no known purely functional equivalent.

Laziness and purity go hand-in-hand ("strict evaluation is a canonical side effect") and laziness not only massively degrades performance but makes it wildly unpredictable.

The enormous numbers of optimizations added to Haskell in an attempt to combat this poor performance (e.g. strictness analysis) render performance even less predictable.

For a trivial example of these optimizations not paying off look no further than the idiomatic 2-line quicksort in Haskell which, despite all of its optimizations, remains thousands of times slower than Sedgewick's quicksort in C. In theory, a sufficiently smart Haskell compiler could optimize such source code into an efficient program. In practice, the world's most sophisticated Haskell compilers cannot even do this for a trivial two-line program much less real software.

Haskell.NET was basically a Master's project out of the University of Canterbury, as far as I know, how did Microsoft kill it?
–
ScottWestJan 5 '12 at 7:07

AFAIK some people at MS Research Cambridge pursued the idea further but gave up when it became apparent that .NET interop is not so valuable with Haskell because almost every function relies upon side effects. Don Syme touched upon this in one of his video interviews.
–
Jon HarropJan 5 '12 at 18:38

It'll be pitty! Haskell compiler is doing a lot of such optimizations.
–
The_GhostNov 1 '11 at 21:18

3

It's a whole lot easier to do optimizations for an effect-free language, I imagine!
–
BrianNov 1 '11 at 23:03

1

I think improving GC from CLR side is the solution. I have also heard that JVM's GC is kind-of good at these short-time small objects while .Net's isn't.
–
Yin ZhuNov 2 '11 at 3:24

Yes, @Brian but this is obvious case with the example above. And I believe that F# compiler is doing side-effects analysis so it knows which part of the code has no side-effects for sure.
–
The_GhostNov 2 '11 at 16:06

No, I don't know of any side-effect analysis in any .NET compiler.
–
BrianNov 2 '11 at 18:22

You can see that at 000c and 0011 the enumerable is created, and then at 0016 the sequence is converted to a list

So in this case the optimisation doesn't happen. In fact it would be very hard for the compiler to make such an optimisation as there could be any number of differences between Seq.Map and List.Map (which is the simplest optimisation as it would avoid the temporary list).

Great, but are there some situations where lists are optimized (in Release mode with optimizations)?
–
The_GhostNov 1 '11 at 21:17

1

@The_Ghost - Brain is on the compiler team, so if he says that it never happens, it never happens, I was just expanding on the answer and showing how you could directly check a specific instance
–
John PalmerNov 1 '11 at 21:58