2008-11-21 14 views
7

¿Qué funciones desea en idiomas comunes? Más precisamente, me refiero a las características que, en general, no existen en absoluto, pero sería agradable de ver, en lugar de decir: "Me gustaría que la escritura dinámica fuera popular".¿Qué características desea en idiomas comunes?

Respuesta

2

Para comenzar, desearía que el estándar para cadenas fuera usar un prefijo si desea usar códigos de escape, en lugar de que su uso sea el predeterminado. P.ej. en C# puede prefijar con @ para una cadena sin formato. Del mismo modo, Python tiene el prefijo r. Prefiero usar @/r cuando no quiero una cadena en bruto y necesito códigos de escape.

1

Me gustan algunas de las capacidades de manipulación de matrices que se encuentran en el lenguaje Ruby. Ojalá tuviéramos algo de eso integrado en .Net y Java. Por supuesto, siempre puedes crear una biblioteca así, pero sería bueno no tener que hacer eso.

Además, los indexadores estáticos son increíbles cuando los necesita.

+0

¿Querías publicar este comentario en la publicación de alguien más? Nunca dije nada sobre F #. – Kilhoffer

+0

Err, sí. No tengo idea de dónde. :-) –

0

Ojalá hubiera un operador de asignación autoinversiva, que retrocedió cuando estaba fuera del alcance. Esta sería la de sustituir:

type datafoobak = item.datafoobak 
item.datafoobak = 'tootle' 
item.handledata() 
item.datafoobak = datafoobak 

con este

item.datafoobar @[email protected] 'tootle' 
item.handledata() 

Una explícitamente podría deshacer estos cambios, pero habían retroceder una vez fuera de su alcance, también. Este tipo de característica sería un poco propenso a errores, tal vez, pero también haría un código mucho más limpio en algunos casos. Una especie de clon sin profundidad podría ser una manera más efectiva de hacer esto:

itemclone = item.shallowclone 
itemclone.datafoobak='tootle' 
itemclone.handledata() 

Sin embargo, los clones poco profundas podría tener problemas si sus funciones modifican sus datos interna ..., aunque por lo que las asignaciones reversibles.

5

Supongo que la respuesta más obvia son las macros Lisp. Ser capaz de procesar su código con su código es maravillosamente "meta" y permite que algunas características bastante impresionantes se desarrollen desde (casi) cero.

Un segundo cercano es el envío doble o múltiple en idiomas como C++. Me encantaría que el polimorfismo se pudiera extender a los parámetros de una función virtual.

11

A menudo he pensado que "observable" haría un gran modificador del campo (como públicas, privadas, estática, etc.)

GameState { 
    observable int CurrentScore; 
} 

Luego, otras clases podrían declarar un observador de esa propiedad:

ScoreDisplay { 
    observe GameState.CurrentScore(int oldValue, int newValue) { 
     ...do stuff... 
    } 
} 

El compilador cerraría todo el acceso a la propiedad CurrentScore con el código de notificación, y los observadores serían notificados inmediatamente después de la modificación del valor.

Claro que puedes hacer lo mismo en la mayoría de los lenguajes de programación con oyentes de eventos y manipuladores de cambios de propiedad, pero es un gran dolor en el culo y requiere una gran cantidad de plomería, especialmente si no eres el autor de la clase cuyos valores quieres observar. En ese caso, generalmente tiene que escribir una subclase de contenedor, delegar todas las operaciones al objeto original y enviar eventos de cambio desde los métodos de mutador. ¿Por qué el compilador no puede generar todo ese código boiler mudo?

+0

Suena muy parecido al enfoque AspectOriented que en este momento está publicitado (más o menos). Creo que el inconveniente será que el resultado será muy difícil de depurar (debido al efecto lateral oculto lateral, problema similar con la sobrecarga del operador en C++) – flolo

+0

De la manera en que lo he concebido, el observador siempre obtiene una instancia inmutable de los valores antiguos/nuevos. Así que no creo que sea tan problemático para la depuración como pueda parecer. – benjismith

+1

Oye, esa es una muy buena idea. Me pregunto si podría hacerlo en Ruby. – zaratustra

5

Me encantaría que hubiera más idiomas para tener un sistema de tipos como Haskell.Haskell utiliza un sistema type inference realmente impresionante, por lo que casi nunca tiene que declarar tipos, sin embargo, todavía es un lenguaje fuertemente tipado.

También me gusta mucho la forma en que declaras nuevos tipos en Haskell. Creo que es mucho mejor que, por ejemplo, los sistemas orientados a objetos. Por ejemplo, para declarar un árbol binario en Haskell, podría hacer algo como:

data Tree a = Node a (Tree a) (Tree a) | Nothing 

Así que los tipos de datos compuestos son más como tipos algebraicos que objetos. Creo que hace que el razonamiento sobre el programa sea mucho más fácil.

Además, mezclar en clases de tipo es mucho más agradable. Una clase de tipo es simplemente un conjunto de clases que implementa un tipo, algo así como una interfaz en un lenguaje como Java, pero más como una mezcla en un lenguaje como Ruby, supongo. Es genial.

Idealmente, me gustaría ver un lenguaje como Python, pero con tipos de datos y tipos de clases como Haskell en lugar de objetos.

+0

Un poco de abstracción, pero me pregunto si no lo permitiría para que surjan algunas pesadillas de depuración divertidas ... –

+0

¿Qué tipo de pesadillas de depuración? – mipadi

+0

No creo que pueda causar pesadillas de depuración. Este tipo de sintaxis es en gran medida simplemente azúcar sintáctica para las estructuras. – Brian

0

Me gustaría ver un solo método y de un solo operador interfaces:

interface Addable<T> --> HasOperator(T = T + T) 

interface Splittable<T> --> HasMethod(T[] = T.Split(T)) 

... o algo por el estilo ...

Me imagino que como una aplicación de seguridad de tipos de pato -mecanografía. Las interfaces no serían garantías proporcionadas por el autor de la clase original. Serían afirmaciones hechas por un consumidor de una API de terceros, para proporcionar seguridad de tipo limitada en los casos en que los autores originales no habían anticipado.

(Un buen ejemplo de esto en la práctica sería la interfaz INumeric que la gente ha sido clamboring en C# desde los albores del tiempo.)

En una lengua de pato escrito como Ruby, puede llamar a cualquier método desea, y no sabrá hasta el momento de ejecución si la operación es compatible, porque el método podría no existir.

Me gustaría poder hacer pequeñas garantías acerca de la seguridad del tipo, de modo que pueda llamar polimórficamente métodos en objetos heterogéneos, siempre que todos esos objetos tengan el método u operador que deseo invocar.

Y debería ser capaz de verificar la existencia de los métodos/operadores a los que quiero llamar en tiempo de compilación. Esperando hasta que el tiempo de ejecución sea para chupones: o)

+0

vea las clases de tipo haskell –

+0

y los tipos estructurales de Scala. – Anonymous

+0

y objetos en OCaml, IO, Go ... –

5

Soy un gran admirador de cierres/funciones anónimas.

my $y = "world"; 

my $x = sub { print @_ , $y }; 

&$x('hello'); #helloworld 

y

my $adder = sub { 
    my $reg = $_[0]; 
    my $result = {}; 
    return sub { return $reg + $_[0]; } 
}; 

print $adder->(4)->(3); 

sólo desearía que eran más comunes.

4

Cosas de Lisp que se pierda en otros idiomas:

  • devolver múltiples valores
  • requerida, palabra clave opcional, y el resto parámetros (libremente mezclable) para las funciones
  • funciona como objetos de primera clase (convirtiéndose más común hoy en día)
  • cola de optimización llamada
  • macros que operan en el lenguaje, no en el texto
  • sintaxis consistente
+0

Múltiples valores de retorno son malos. Obtener tuplas –

+0

@Jon Harrop: puede devolver algo como tuplas en cualquier idioma. Los valores de retorno múltiples son algo (casi) completamente diferente. Por un lado, obtienes un valor único, sin caja, "inocente" si solo haces un enlace de valor único estándar de los valores devueltos, pero también puedes hacer un enlace de valor múltiple. Además, los valores se pueden guardar en varios registros en lugar de escribirlos en la memoria RAM --- No he visto la semántica para tal cosa fuera del ensamble todavía. – Svante

+0

No, los valores de devolución múltiples no son más que un caso especial de tuplas. Las tuplas no tienen que ser asignadas. En HLVM, las tuplas siempre se desempaquetarán. –

0

Lisp style macros.

Despacho múltiple.

Optimización de la llamada de la cola.

Continuaciones de primera clase.

0

Llámame tonto, pero no creo que todas las características pertenezcan a todos los idiomas. Es el síndrome del "gato de todos los oficios, maestro de ninguno". Me gusta tener una variedad de herramientas disponibles, cada una de las cuales es lo mejor que puede ser para una tarea en particular.

+0

Sí, pero la integración de todos estos subproyectos en un millón de idiomas diferentes es un PITA. – dsimcha

-1

Me gustaría un lenguaje mucho más restrictivo y diseñado para producir código bueno y fácil de mantener sin ningún tipo de engaño. Además, debe diseñarse para que el compilador tenga la capacidad de verificar tanto como sea posible en tiempo de compilación.

Comience con un lenguaje basado en VM recientemente basado en OO.

  • Elimina las complejidades como la sobrecarga del operador y la herencia múltiple, si es que existen.
  • Fuerce todas las variables no finales a Privado.
  • Los miembros deben tener como valor predeterminado "Final" pero deben tener una etiqueta "Variable" para anularla. (Esto puede requerir compatibilidad integrada para que el patrón del generador sea completamente efectivo).
  • Las variables no deben permitir un valor "Nulo" por defecto, pero las variables y los parámetros deben tener una etiqueta "anulable" que indique que nulo es aceptable para esa variable.

También sería agradable ser capaz de evitar algunos patrones comunes: cuestionables

  • Algunos forma integrada de simplificar COI/DI para eliminar únicos,
  • Java - eliminar las excepciones controladas para que la gente deje de poner trampas vacías

Finalmente se centran en la legibilidad del código:

  • Parámetros con nombre
  • Retire la capacidad de crear métodos más de, digamos, 100 líneas de largo.
  • Agregue algunos análisis de complejidad para ayudar a detectar clases y métodos complicados.

Estoy seguro de que no he nombrado 1/10 de los elementos posibles, pero básicamente estoy hablando de algo que se compila en el mismo bytecode como C# o Java, pero es tan restrictivo que un programador puede difícilmente ayuda pero escribe un buen código.

Y sí, sé que hay herramientas tipo lint que harán algo de esto, pero nunca las he visto en ningún proyecto en el que haya trabajado (y no se ejecutarían físicamente en el código I ' estoy trabajando ahora, por ejemplo) así que no están siendo muy útiles, y me encantaría ver una compilación realmente fallar cuando escribe en un método de 101 líneas ...

+0

Si usted es un PHB y sus programadores son tan incompetentes que no confía en ellos con cierta flexibilidad, la mejor respuesta es despedirlos y obtener otros nuevos. – dsimcha

+0

No soy un PHB, soy un programador que pasó 20 años arreglando los lindos trucos de otros programadores. Y tiendo a ser llamado cuando una compañía ha arruinado sus cosas bastante mal. –

+0

No necesita restricción, necesita lenguajes declarativos. – Anonymous

1

Tipo de inferencia. Poco a poco va abriéndose camino en los principales idiomas, pero aún no es lo suficientemente bueno. F # es el estándar de oro aquí

2

Plantillas más potentes que en realidad son diseñadas para ser utilizadas para la metaprogramación, en lugar de plantillas C++ que están diseñadas para genéricos relativamente simples y son Turing-completas casi por accidente. El lenguaje de programación D tiene estos, pero aún no es muy común.

+1

LISP hace un gran trabajo aquí –

+0

Echa un vistazo a MetaOCAML también. –

0

Funciones funcionales, como map, flatMap, foldLeft, foldRight, y así sucesivamente. Tipo de sistema como scala (constructor de seguridad). Hacer que los compiladores eliminen las bibliotecas de alto nivel en tiempo de compilación, mientras las tiene si se ejecuta en el modo "interpretado" o "menos compilado" (velocidad ... a veces lo necesita).

0

Hay varias buenas respuestas aquí, pero voy a añadir algo:

1 - La capacidad para obtener una representación de cadena para el código actual y la persona que llama, para que pudiera salida de un nombre de variable y su valor fácilmente, o imprima el nombre de la clase, función o traza de pila actual en cualquier momento.

2 - Las tuberías también serían agradables. Esta característica es común en shells, pero poco común en otros tipos de idiomas.

3 - La capacidad de delegar cualquier número de métodos a otra clase fácilmente. Esto se parece a la herencia, pero incluso en presencia de herencia, de vez en cuando necesitamos algún tipo de envoltorio o talón que no se puede implementar como una clase secundaria, y el reenvío de todos los métodos requiere mucho código repetitivo.

2

immutable palabra clave. Sí, puedes hacer objetos inmutables, pero eso es mucho dolor en la mayoría de los idiomas.

class JustAClass 
{ 
    private int readonly id; 
    private MyClass readonly obj; 
    public MyClass 
    { 
     get 
     { 
      return obj; 
     } 
    } 
} 

Aparentemente parece JustAClass es una clase inmutable. Pero ese no es el caso. Como otro objeto contiene la misma referencia, puede modificar el objeto obj.

Por lo tanto, es mejor introducir la nueva palabra clave immutable. Cuando se usa immutable, ese objeto se tratará como inmutable.

+0

Algún soporte para la inmutabilidad sería útil, pero no estoy del todo claro qué debería hacer una palabra clave 'inmutable'. ¿Podrías aclarar? – supercat

+1

Si se usa la palabra clave 'inmutable' en la declaración de variable, entonces el objeto al que se hace referencia será inmutable, lo que significa que la variable de referencia no puede cambiar ese objeto ni ninguna otra variable de referencia. Al igual que los tipos de valor en C#. – user

+0

¿Cuál sería el efecto de copiar la variable de referencia, o un campo o propiedad de ella, en otro lugar? Hay muchos casos de esquina para tratar. Además, hay una gran diferencia entre una referencia de "solo lectura" y una "inmutable". El código que contiene una referencia de solo lectura no puede modificar el objetivo, pero no tiene ninguna garantía de que el objetivo no sea modificado por otra cosa. – supercat

Cuestiones relacionadas