Pregunta

nuevo proyecto se puso en mi TODO y no puede eligió F # o Nemerle.

Actualmente estoy aprendiendo C # y tiene algunos proyectos en Nemerle.

I como F # manera, como guión por defecto (también quiero guión por defecto para nemerle2), que al igual que muchas características y magia de F # pero no hay macros.

El objetivo de F # es VS2010 y tal vez (tal vez) equipo de desarrolladores más grandes y es el aspecto de Haskell (puede crear programas de Linux ligeras con él y es divertido).

El objetivo de Nemerle es macros y creo que me gusta una sintaxis de Nemerle más.

y la mayoría de la gente simplemente como C # ...

  • Así que el lenguaje debe ser la perspectiva
  • Sintaxis debe ser lógico, a la fácil entender, limpio y de gran alcance (menos código)
  • Debe ser fácil de usar con .NET
  • Así que ya cerré el auto con el eligió de este 3 queridos.
  • Me puede utilizar todos ellos, pero ¿qué pasa con elegir uno. No es tan fácil para mí.

sólo por ejemplo I como (Nemerle)

match(STT)
    | 1 with st= "Summ"
    | 2 with st= "AVG" =>
        $"$st : $(summbycol(counter,STT))"

mucho más a continuación (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 # (esperanza no se equivoca aquí):

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;
    }
}

y aquí está el código Nemerle que ya no puede convertir a F # (por lo que sólo aprenderlo) ...

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; }

Comparación con 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;
    }
}

Es evidente código Nemerle es más fácil de apoyo y más fácil de leer.

@ Brian Entonces es por eso que te pido, me muestran si eso real para hacer este easer en F #, C # también si ver lo hago mal, porque no estoy seguro acerca de otras maneras para hacer claramente la misma.

¿Fue útil?

Solución

F # y Nemerle versiones bastante diferentes:

  1. Nemerle define clase mientras que F # define struct.
  2. Nemerle define miembros de sólo lectura mientras que F # define miembros mutables.
  3. Nemerle define las propiedades públicas, mientras que F # define campos públicos.
  4. Nemerle define constructor mientras que F # no lo define.

código Análogo Nemerle para F # ejemplo es el siguiente:

struct X
  mutable A : string
  mutable B : string

El segundo ejemplo es casi el mismo:

  1. Nemerle define constructor para Mi Fa #, mientras que no lo define.
  2. Nemerle define las propiedades que devuelven el valor pasado en el constructor, mientras que F # define las propiedades con valores constantes.

Nemerle versión es mucho más corto y más claro que F # versión aquí.

P.S. Acerca de llaves vs sintaxis guión. Nemerle soporta tanto sintaxis.

Se puede escribir bien:

class M
{
  static Main() : void
  {
    Console.WriteLine("A");
  }
}

O uso guión:

#pragma indent
class M
  static Main() : void
      Console.WriteLine("A");

o incluso usar ambos estilos!

#pragma indent
class M
  static Main() : void { Console.WriteLine("A"); }

Otros consejos

me muestran que si real para hacer esto easer en F #, C # también ver si lo hago Es malo, porque no estoy seguro acerca de otras maneras de hacer claramente la misma.

Su F # y # C ejemplos no son muy concisa. Vamos a reescribir algunos de los ejemplos en su OP:

Pattern Matching

Nemerle:

match(STT)
    | 1 with st= "Summ"
    | 2 with st= "AVG" =>
        $"$st : $(summbycol(counter,STT))"

F #:

No estoy 100% seguro de lo que el código está haciendo, pero parece que la basado en esta respuesta . No creo que hay alguna fácil crear nuevas variables en una expresión de coincidencia, pero creo que los patrones activos son una exageración.

me gustaría escribir el código como el siguiente:

let st = match stt with 1 -> "Summ" | 2 -> "Avg"
sprintf "%s ..." st

Mapas trabajo también:

let sttMap = [1, "Summ"; 2, "Avg"] |> Map.ofList
sprintf "%s ..." (sttMap.[stt])

<3 href="https://stackoverflow.com/questions/4544890/f-match-with/4546360#4546360"> de Jon también:

let 1, st, _ | 2, _, st = stt, "Summ", "AVG"

Registros

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;
    }
}

clases

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

Algunas cosas a destacar aquí:

  • F # interfaces se definen usando la palabra clave abstract. Puede convertirlos en clases abstractas utilizando el atributo [<AbstractClass>].

  • Las interfaces se implementa de forma explícita. En general, es necesario convertir un objeto a una definición de interfaz a los miembros de la interfaz de invocación: let x = My("a", "b"); printf "%s" (x :> IB).B. Para evitar el reparto, es necesario crear miembros públicos que reflejan sus métodos de interfaz.

  • funciones virtuales definir un abstract member con una aplicación default.

Se pone todos estos componentes juntos, y se obtiene definiciones de clases que son perjudiciales para los nervios oculares. Pero está bien ya que las clases generalmente no se utilizan muy a menudo. La mayoría de los modelos F # objetos se definen a través de los sindicatos y los registros; donde las clases son utilizado, las jerarquías de clases son muy plana en vez de profundidad, por lo que no se ve funciones de herencia o virtuales utilizados tan a menudo en la que F # 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;
    }
}

Es una larga historia corta, creo F # es bastante comparable a Nemerle, pero parece que sólo estás aprenderlo. No se preocupe, cuando estaba aprendiendo C #, que estaba escribiendo feo, voluminosos código que básicamente refleja C # con una sintaxis más funky. Tomó un poco de tiempo antes de que pudiera escribir más idiomáticamente.

recomiendo lo siguiente:

  • Si está familiarizado con Nemerle y como usarlo, continuará haciéndolo:)
  • Si quieres aprender F #, creo que su proyecto es un lugar bueno para comenzar. Creo que se puede escribir F # tan limpio o mejor que su Nemerle.
  • C # también está bien, pero no lo preferiría más de uno u otro idioma, si está haciendo un montón de coincidencia de patrones o el procesamiento de símbolos.

La sintaxis para un registro # F es

type X = { 
    A : string
    B : string 
}

En cuanto al código que no se puede convertir

[<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

No estoy muy seguro de lo que tu ejemplo coincidencia de patrones está tratando de hacer, pero F # tiene la sintaxis (creo que se está buscando)

match (STT) with
    | 1 when st = "Sum" -> ...
    | 2 when st = "Avg" -> ...

F # tienen una sintaxis mejor registro:

type X = struct
  val mutable A : string
  val mutable B : string
end

y no es su código, convertido a 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

La conversión de código publicado por Sparkie es ligeramente infiel al # conversión de C, en el que la propiedad B no es virtual y no se expone directamente en instancias de tipo Mi (tienen que desechar los casos de IB de acceso B). Aquí está una conversión más fiel:

[<AbstractClass>]
type ABase() =
    abstract A: string

type IB =
    abstract B: string

type My(a, b) =
    inherit ABase()

    override this.A = a

    abstract B: string
    default this.B = b

    interface IB with
        member this.B = this.B

Una cosa a la nota si usted es nuevo en F #: la referencia this pasado a implementaciones de elementos de interfaz es del tipo de la clase que se declara, por lo que (en la anterior) la implementación del IB de referencias B la propiedad B declara en el clase.

Si te gusta los dos idiomas, ¿por qué no mezclarlos? Usted puede construir algunas bibliotecas en Nemerle utilizando macros y otros en F # para todo lo demás. ¿No es una de las ventajas de utilizar el tiempo de ejecución administrado? : D

A continuación, se puede construir la interfaz de usuario (si lo hay) usando un lenguaje más conveniente para ella, tales como C # o VB.NET.

Y una vez que decida añadir soporte de scripting para su producto, puede utilizar IronPython / IronRuby!

Mi entendimiento es que el apoyo Nemerle IDE está trabajando sólo en VS2008 (pero soporta .net3.5 y 4.0) y # F trabajos tanto en VS2010 y VS2008, lo que además de las diferencias de sintaxis, se cree que su decisión también se debe tener en cuenta que , que IDE que va a utilizar.

"código Claramente Nemerle es más fácil de apoyo y más fácil de leer."

Más fácil de apoyar a quien?

Más legible a quién?

A qué estás basando dicha sentencia que no sea su propia experiencia de la lengua y sus propios prejuicios personales? He codificado en C ++ por años y por lo tanto me parece cualquier idioma que no utiliza llaves para bloques de código delimitar un poco contra-intuitivo. Pero otras personas que han codificado en Lisp (o lenguajes Lisp-based) probablemente encontrar la idea de utilizar llaves muy raro y por lo tanto contrario a la intuición. Las personas que han codificado en Pascal o lenguajes basados ??en Pascal prefieren ver "empezar" y "fin" a los bloques de código delimitan - -habían encuentran que "más fácil de soportar y más legible".

¿Tiene algún estudios que demuestran que el código de comprensión es mayor con la sintaxis Nemerle de F # o C #? Debido a que sería la única medida empírica y objetiva que puedo pensar que se probaría que Nemerle código es "más fácil de apoyo y más fácil de leer".

Para el desarrollador profesional, es sólo tres sintaxis diferentes. A menos que usted está comparando un lenguaje a Brainf * ck básicamente es sólo una cuestión de qué tipo de sintaxis que ya está acostumbrado y cuánto tiempo usted tiene que aprender una nueva estructura sintáctica.

Another comparison.

using keyword:

F#

use x = X()
use y = Y()
use z = Z()
...

Nemerle:

using (o = SomeType())
  ...

using (x = X())
using (y = Y())
using (z = Z())
  ... 

String formatting:

F#:

let a = 1
let b = "x"
sprintf "%d %s" (a + 1) b

Nemerle:

def a = 1;
def b = "x";
def c = Nemerle.IO.sprintf("%d %s", a + 1, b);

String interpolation:

Has F# this feature ?

Nemerle:

def a = 1;
def b = "x";
def c = $"$(a + 1) - $b"; // 0 - x

foreach keyword: F#:

let list1 = [ 1; 5; 100; 450; 788 ]
for i in list1 do
  printfn "%d" i

let list1 = [ 1; 5; 100; 450; 788 ]
Seq.iteri (printfn "%d - %d")

let list1 = [ 1; 5; 100; 450; 788 ]
Seq.iteri (fun i x -> if i > 10 then printfn "%d - %d" i x)

let list1 = [ 1; 5; 100; 450; 788 ]
for x in list1 do
  printf "%s" (if x > 10 then printf "A"
               elif x < 10 then printf "B"
               elif "C"

Nemerle:

def list1 = [ 1, 5, 100, 450, 788 ]
foreach (i in list1)
  WriteLine($"$i")

def list1 = [ 1, 5, 100, 450, 788 ]
foreach (i in list1 with index) // index has an index of item. works for any collection.
  WriteLine($"$index - $i")

def list1 = [ 1, 5, 100, 450, 788 ]
foreach (i when i > 10 in list1 with index) // Pattern in foreach
  WriteLine($"$index - $i")

def list1 = [ 1, 5, 100, 450, 788 ]
foreach (_ in list1) // Implicit match
  | i when i > 10 => WriteLine("A")
  | i when i < 10 => WriteLine("B")
  | _ => WriteLine("C")

foreach (_ in [])
  | i when i > 10 => WriteLine("A")
  | i when i < 10 => WriteLine("B")
  | _ => WriteLine("C")
otherwise // Otherwise is taken when there were no iterations
  WriteLine("X")
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top