show me if that real to make this
easer on F# , C# also if you see I do
it wrong because I’m not sure about
other ways to make clearly the same.
Your F# and C# examples aren’t very concise. Let’s rewrite some of the examples in your OP:
Pattern Matching
Nemerle:
match(STT)
| 1 with st= "Summ"
| 2 with st= "AVG" =>
$"$st : $(summbycol(counter,STT))"
F#:
I’m not 100% sure what you code is doing, but it looks like its based on this answer. I don’t think there is any easy to create new variables in a match expression, but I think active patterns are overkill.
I’d write the code like this:
let st = match stt with 1 -> "Summ" | 2 -> "Avg"
sprintf "%s ..." st
Maps work too:
let sttMap = [1, "Summ"; 2, "Avg"] |> Map.ofList
sprintf "%s ..." (sttMap.[stt])
I <3 Jon’s suggestion too:
let 1, st, _ | 2, _, st = stt, "Summ", "AVG"
Records
Nemerle:
[Record]
class X
public A : string { get; }
public B : string { get; }
F#:
type X = { A : string; B : string }
C#:
class X {
public string A { get; private set; }
public string B { get; private set; }
public X(string a, string b) {
A = a;
B = b;
}
}
Classes
Nemerle
abstract class ABase
abstract public A : string { get; }
interface IB
B : string { get; }
[Record]
class My : ABase, IB
public override A : string { get; }
public virtual B : string { get; }
F#:
[<AbstractClass>]
type ABase() =
abstract member A : string
type IB =
abstract member B : string
type My(a, b) =
inherit ABase()
override this.A = a
abstract member B : string
default this.B = b
interface IB with
member this.B = this.B
Some things to note here:
-
F# interfaces are defined using the
abstractkeyword. You can turn them into abstract classes using the[<AbstractClass>]attribute. -
Interfaces are implemented explicitly. Generally, you need to cast an object to an interface definition to invoke interface members:
let x = My("a", "b"); printf "%s" (x :> IB).B. To avoid the cast, you need to create public members that mirror your interface methods. -
Virtual functions define an
abstract memberwith adefaultimplementation.
You put all these components together, and you get class definitions which are harmful to the ocular nerves. But its ok since classes generally aren’t used very often. Most F# object models are defined through unions and records; where classes are used, the class hierarchies are very flat instead of deep, so you don’t see inheritance or virtual functions used as often in F# than C#.
C#:
abstract class ABase {
public abstract string A { get; }
}
interface IB {
string B { get; }
}
class My : ABase, IB {
public override string A { get; private set; }
public virtual string B { get; private set; }
public My(string a, string b) {
A = a;
B = b;
}
}
Long story short, I think F# is pretty comparable to Nemerle, but it looks like you’re just learning it. Don’t worry, when I was learning F#, I was writing ugly, bulky code that basically mirrored C# with a funkier syntax. It took a little while before I could write more idiomatically.
I recommend the following:
- If you’re familiar with Nemerle and like using it, continue to do so 🙂
- If you want to learn F#, I think your project is a good place to start. I think you can write F# about as clean or better than your Nemerle.
- C# is ok too, but I wouldn’t prefer it over either language if you’re doing lots of pattern matching or symbol processing.