According to the documentation, F# supports operator overloads. This means you should be able to overload common operators like > and <.
YOU CAN OVERLOAD OPERATORS,
F# actually does does support declaring operator overloads. If you compile the code below it will emit the same IL you would expect from other .NET languages.
type OppTest4(value: int) = member this.value = value static member (^) (left : OppTest4, right : OppTest4) = OppTest4( Int32.Parse( left.value.ToString() ^ right.value.ToString() )) static member (+) (left : OppTest4, right : OppTest4) = OppTest4(left.value + right.value ) static member (>) (left : OppTest4, right : OppTest4) = left.value > right.value static member (<) (left : OppTest4, right : OppTest4) = left.value < right.value
BUT YOU CAN’T USE THEM!
That’s right folks. Even though F# goes out of its way to allow you to overload operators in such a way that other languages can honor them, F# itself doesn’t.
Well, that’s a bit of an exaggeration. Lets look at them each in turn:
- + (op_Addition): Works just fine.
- ^ (op_Concatenate): Compiler error in F#. Apparently only strings can be concatenated.
- > (op_GreaterThan): Runtime Error – Failure during generic comparison: the type Program+OppTest4 does not implement the System.IComparable interface.
WHAT THE HELL JUST HAPPENED?
Ok, so you can’t overload op_Concatenate. Fine, I get that. It’s stupid, but whatever.
But what the hell is going on with op_GreaterThan? I can overload the operator just like op_Addition, but it doesn’t honor it. Moreover, it waits until runtime to tell me that it is going to ignore the overload and use System.IComparable instead.
Seriously, is this what they mean by a “strongly typed language”? You can’t make safe conversions like integer to decimal or string to Option<string>, but you can do something reckless like cast a class to an interface it doesn’t implement?
STATIC TYPING MY ASS
I have never seen another language screw up static typing so badly. Support for operator overloads is hard to design, I get that. But to get them so wrong that they effective break your static type checker is inexcusable.
> But what the hell is going on…
Have you asked in a forum where there’s a chance someone might actually know – like hubFS?
http://cs.hubfs.net/forums/
Comment by Isaac Gouy — June 8, 2009 @ 11:08 pm
I should, but honestly I’m so pissed off about it that I need some time to cool down.
Comment by grauenwolf — June 8, 2009 @ 11:37 pm
Note that this code gives compiler warnings like:
The name ‘(>)’ should not be used as a member name. To define comparison semantics for a type, implement the ‘System.IComparable’ interface. If defining a static member for use from other .NET languages then use the name ‘op_GreaterThan’ instead.
The name ‘() and (<), which themselves use IComparable.
Comment by Brian — June 9, 2009 @ 4:53 pm
Oops, in my previous comment, my less-than and greater-than operators got munged into markup. I intend to say that
F# supports generic structured comparison, allowing you to compare tuples, lists, arrays and other data structurally using the default implementations of the less-than and greater-than operators, which themselves use IComparable.
Comment by Brian — June 9, 2009 @ 4:57 pm
Yes, I understand how it works. My objections are in regards to why it works that way.
Comment by grauenwolf — June 9, 2009 @ 10:47 pm
[...] F# – You can overload operators, but you can’t use them. [...]
Pingback by Rick Minerich's Development Wonderland : Discoveries This Week 06/14/2009 — June 15, 2009 @ 12:19 am