Got new project in my TODO and can't chose F# or Nemerle.
I'm currently learning F# and have some projects on Nemerle.
I like F# way , I like indent by default (also I want indent by default for nemerle2), I like many features and magic of F# but there is no macros.
The goal of F# is VS2010 and maybe (maybe) bigger developers team and it's looking like Haskell(can create light Linux programs with it and it's fun).
The goal of Nemerle is macros and I think I like some syntax of Nemerle more.
and most people just like C#...
just for example I like (Nemerle)
match(STT)
| 1 with st= "Summ"
| 2 with st= "AVG" =>
$"$st : $(summbycol(counter,STT))"
much more then (F#)
let (|Let|) v e = (v, e)
match stt with
| Let "Summ" (st, 1)
| Let "AVG" (st, 2) -> srintf "%s ..." st
F# :
["A"; "B"] |> List.iter (fun s -> printfn "%d" s.Length)
Nemerle:
["A", "B"].Iter(x => printf("%d", x.Length))
F# (hope not mistaken here):
let type X =
let mytable a = ""
let mytable b = ""
new(A, B) = {
a <- A
b <- B }
member X.A
with get = a
member X.B
with get = a
Nemerle :
[Record]
class X
public A : string { get; }
public B : string { get; }
C# :
class X
{
private readonly string _a;
public string A { get { return _a; } }
private readonly string _b;
public string B { get { return _b; } }
public X(string a, string b)
{
_a = a;
_b = b;
}
}
and here is nemerle code I already can't convert to F# (so I only learning it) ...
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; }
Comparison to C#:
abstract class ABase
{
abstract public string A { get; }
}
interface IB
{
string B { get; }
}
class My : ABase, IB
{
private readonly string _a;
public override A : string { get { return _a; } }
private readonly string _b;
public virtual B : string { get { return _b; } }
public My(string a, string b)
{
_a = a;
_b = b;
}
}
Clearly Nemerle code is easier to support and more readable.
@Brian So that's why I'm asking , 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.
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 abstract
keyword. 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 member
with a default
implementation.
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:
F# and Nemerle versions quite different:
Analogous Nemerle code for F# example is following:
struct X
mutable A : string
mutable B : string
The second example is almost the same:
Nemerle version is much shorter and clearer than F# version here.
P.S. About curly braces vs indent syntax. Nemerle supports both syntaxes.
You can write either:
class M
{
static Main() : void
{
Console.WriteLine("A");
}
}
Or use indent:
#pragma indent
class M
static Main() : void
Console.WriteLine("A");
Or even use both styles !
#pragma indent
class M
static Main() : void { Console.WriteLine("A"); }
The syntax for an F# record is
type X = {
A : string
B : string
}
As for the code you can't convert
[<AbstractClass>]
type ABase() =
abstract A : string
type IB =
abstract B : string
type MyClass(a, b) =
inherit ABase()
override this.A = a
interface IB with
member this.B = b
I'm not too sure what your pattern matching example is trying to do, but F# has the syntax (I think you're looking for)
match (STT) with
| 1 when st = "Sum" -> ...
| 2 when st = "Avg" -> ...
F# have a better record syntax:
type X = struct
val mutable A : string
val mutable B : string
end
and there is your code, converted to F#:
[<AbstractClass>]
type ABase =
abstract member A : string
// you can declare default implementation using default keyword like this:
// default this.A with get () = "default implementation"
type IB =
interface
abstract member B : string
end
type My = class
inherit ABase
override my.A with get() = "A"
interface IB with
member my.B with get() = "B"
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With