Normally I pass values of option<int> to it, but once in awhile I would like to pass a normal int.

let b = Foo(a, 5) // Error: This expression has type int but is here used with type int option

So? You don’t have to understand that the set of all option<int> values contains all int values. Or in other words, it is always safe to convert a int into an option<int>. I’ll even go one step further. It is always safe to convert any T into any option<T>.

SO WHY ARE YOU WASTING MY TIME?

Ok, lets try something a little bit easier. Every language high on the chain than assembly knows about implicit numeric conversions, right? Well lets try that with F#.

What do you mean “the type int is not compatible with the type decimal”? Every possible int can be exactly represented as a decimal, so what the heck are you complaining about?

Maybe I’m using it wrong. Maybe I should try F#’s famous automatic generalization of functions.

let SimplyAdd x y = x + y //Type constraint mismatch. The type int is not compatible with type decimal The type 'int' is not compatible with the type 'decimal'
let f = SimplyAdd c d //Type constraint mismatch. The type int is not compatible with type decimal The type 'int' is not compatible with the type 'decimal'

Cool. Now I got errors on tow separate lines, and they each tell me the same thing twice. Where else can you get four error messages for the price of one type conversion?

If the F# designers were to put in just a little bit of compiler magic so that the language would do the semantically right thing, F# would be a really pleasant language to work with. But like the way they introduced option-style nulls without removing CLR nulls, making something technically consistent at the expense of both inconsistent syntax and inconsistent semantics is just wrong.

You stated incorrectly that most languages do automatic number conversion. This of course isn’t true. Since F# has its lineage in both Haskell and OCaml, it very much follows the number conversion logic of those languages. The reason is quite simple for this, because adding unlike numbers can produce unintended consequences. Did you want any rounding to occur or not? I’d rather be explicit, especially around the ideas of mathematical purity that is at the heart of Functional Programming. Read here for more details:
OCaml: http://www.ocaml-tutorial.org/the_basics
“OCaml never does implicit casts like this. In OCaml, 1 + 2.5 is a type error. The + operator in OCaml requires two ints as arguments”
Haskell: http://www.haskell.org/haskellwiki/Converting_numbers

Before going off on rants such as these, please do spend some time in the language to understand its roots. The F# books available right now do have some great material on the motivations of the Option type such as Don Syme’s Expert F#.

Only if you wanted that to be a decimal in the first place and that was my point. I for one like the explicit nature of those operators and to me it’s not a hardship.

I really think you ought to be interested in the homage because that’s where you really start to understand functional programming instead of this rant which didn’t seem to make much sense to me. Remember that F# was written in the beginning to have OCaml compatibility and that’s where these constructs came from.

As for the automatic conversion to and from option, well that is part of the OOP syntax for F# but I’m not sure it’s going to make it to VS2010. I hope it does.

I totally agree with this rant. I don’t program to be technically pure, I solve problems. And I don’t need a language that thinks it knows what’s best and gets in my way to prove. Ada was already invented for that.

Static typing is here to catch errors? Think again when it comes to OCaml/F#.

Static typing is here to emphasise the semantics of your program.

Mistaking an integer for a decimal is a semantic misconception.

You want operator overloading, so that you can “convert from an integer to a decimal”? Sure, there won’t be errors… but overloading will get in your way when debugging something else somewhere else in your code.

I also thought at one point that there should be some sort of automatic conversion for some issues. Seems simple at first glance. At second glance, it gets horrible. Say you have “a + (b + c)”. Do you want to handle all cases for conversion possibilities when you have a type inference going wrong?

I do not: I’d rather use the BENEFITS of static typing typing… i.e. finding SEMANTIC errors quickly due to TYPE INFERENCE and have a QUICK coding/compiling cycle.

Just try to level up your notion of error from “segfault” to “semantics”, and you’ll see that type inference is not simply a better way to statically type memory usage as in C… it’s semantics that you’re typing, not merely the ocurrence of NULL pointers.

And I love None / Some… and nice code is code that doesn’t use None / Some much because its semantics are well thought out, in such a way that you do not need such option types.

In OCaml/F# you think more than you code, in order to code much faster in the medium to long run.

Lack of an error does not imply that the type coercions respect equational reasoning. Static typing is intended to allow the developer to express the semantics of the application domain in a way the compiler can verify for consistency in a well-founded equational theory.

Unprincipled implicit coercions defeat this purpose since what the developer types and what the compiler does may be at odds, without the user ever knowing. Type classes are an exception here since they respect proper equational reasoning.