Características del lenguaje de programación semi-único Killer [cerrado]

25

Al aprender un nuevo lenguaje de programación, a veces te encuentras con una función de lenguaje que te hace desear tenerlo en tus otros lenguajes de programación que conoces.

¿Cuáles son algunas de las características del lenguaje que en el momento de aprender eran muy nuevas para usted y que desearía que tuvieran otros lenguajes de programación?

Un ejemplo de esto son los generadores en Python o C #. Otros ejemplos pueden incluir comprensiones de listas en Python, plantillas en C ++ o LINQ en .NET o evaluación diferida en Haskell.

¿Qué otras características de lenguaje semi-únicas ha encontrado que fueran completamente nuevas y esclarecedoras para usted? ¿Hay otras características de los lenguajes de programación más antiguos que eran únicos y han pasado de moda?

Brian R. Bondy
fuente

Respuestas:

25

Prácticamente cualquier cosa en Haskell

  • Mónadas Sí, la gran palabra aterradora que hace que los analizadores, IO, operaciones en listas y otras cosas sean increíblemente fáciles (una vez que notas un patrón común)
  • Flechas Lo mismo para usuarios avanzados;)
  • Cosas estándar como lambdas, etc.
  • Funciones de curry
  • Tipos de datos algebraicos
  • La coincidencia de patrones

Y muchos más.

PD. Sí. Soy fanático de Haskell si alguien me pregunta.

Maciej Piechotka
fuente
12
Para ser justos, debe dar crédito ML para la mayor parte de esa lista.
munificent
1
Bueno, excepto mónadas y flechas IIRC. Pero todavía son semi- únicos
Maciej Piechotka
¿Alguna razón particular para el voto negativo?
Maciej Piechotka
2
+1 para la coincidencia de patrones. Se lo muestro a otras personas y no lo entienden. Creo que es genial.
Barry Brown
Obligatorio ( steve-yegge.blogspot.com/2010/12/… ). Por cierto, difícilmente consideraría que las lambdas sean únicas, python, C #, javascript, etc. ¿Mónadas? La mayoría de los otros idiomas se refieren a él como encadenamiento; jquery core es esencialmente un conjunto masivo de mónadas HTML / DOM y AJAX (Google: jQuery.fn). El curry también es relativamente común hoy en día.
Evan Plaice
21

Macros Lisp.

El lenguaje macro de Lisp es Lisp, con algunas características de sintaxis predefinidas por conveniencia. Al usarlos, es posible agregar características principales al lenguaje, como la elección de estilos de orientación a objetos o la coincidencia determinista tipo Prolog, sin mirar fuera de lugar. Hace setfposible la macro, que es una macro conceptualmente muy poderosa: (setf A B)significa que, cuando evalúas A, obtendrás B, y eso se puede extender a cualquier límite que desees.

La metaprogramación de plantillas de C ++ es capaz de cosas similares, pero en un lenguaje muy diferente al de C ++ normal.

David Thornley
fuente
+1 Espero que algún día pueda programar en un dialecto Lisp.
Oliver Weiler
@Helper ... a través de plantillas C ++ [risa aterradora]
mlvljr
@mlvjr: Tienes miedo.
David Thornley
De hecho, es la única característica lista para usar que necesitará en un idioma. Con las macros Lisp puede agregar todas las demás características posibles más adelante.
SK-logic
18

El decorador de Python.

Es extremadamente fácil implementar la memorización o la sincronización de la función utilizando el decorador.

Ejemplo de temporizador de funciones.

class FuncTimer(object):
    """ Time how much time a function takes """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
        self.start_time = time.time()
    def __call__(self, *args):
        self.memo['return'] = self.fn(*args)
        print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
        return self.memo['return']

Ahora, si tiene una función para la que desea programar, simplemente puede hacer esto,

@FuncTimer
def foo():
    # foo's implememtation goes here

Verás algo como

La función 'foo' tomó 3 segundos.

grokus
fuente
Java tiene anotaciones, que tienen un propósito y una sintaxis similares, pero funcionan de manera muy diferente
Casebash
1
+1: los decoradores de Python me han impresionado más que casi cualquier otra característica del lenguaje. ¡Son muy hermosos y simples!
Adam Paynter
¿Quizás podría compartir un ejemplo simple con nosotros? No sé Python para ser honesto.
ShdNx
@ShdNx, acabo de agregar un ejemplo.
grokus
1
¿No debería calcularse la hora de inicio como parte de la llamada?
desviarse el
14

Transmitir a void*C. Puede convertir todo a bytes sin formato y hacer lo que quiera con estos datos.

(Sí, hoy en día es único ...)

P Shved
fuente
1
El objeto en lenguajes .Net es muy similar. Solo más tipos seguros, etc.
Maciej Piechotka
Puede emitir objetos en muchos idiomas. El principal problema es que muchos idiomas separados primitivas y objetos
Casebash
55
@Maciej: incluso en .NET, realmente no puedes lanzar primitivas a Object. Los encajonas , y es una bestia bastante diferente. Además, eso es totalmente diferente al casting para void*...
Dean Harding
1
Lanzar Pointeren Pascal y Object Pascal hace lo mismo.
Frank Shearar
1
@DeanHarding: Bueno, en C tienes algo a int64_tlo que no siempre puedes enviar de forma segura void *(Perdón por el retraso: 2 años: respuesta).
Maciej Piechotka
12

Ceda en Python

En Python (y creo en C #), puede definir un denominado generador que pausa la ejecución de la función en una yieldinstrucción, devuelve el valor y en las llamadas posteriores, reinicia la función donde se dejó (con el estado preservado entre las llamadas). Esto es ideal para generar largas listas de valores donde solo le interesa el valor actual de la función (que es muy común). Le permite construir secuencias potencialmente infinitamente largas mientras solo ocupa un espacio muy limitado en la memoria.

Chinmay Kanchi
fuente
1
El rendimiento ya figura en la pregunta.
Trinidad
Esto se remonta a BCPL.
Peter Taylor
8

Expresiones lambda (cierres, funciones anidadas, métodos anónimos, como se llamen).

Primero los encontré en Perl, los amé al instante y me pregunté por qué otros idiomas no los tienen. Hoy en día supongo que ya no es tan único; incluso PHP ha logrado hackearlos de alguna manera. Pero eran semi-únicos en ese momento.

Timwi
fuente
55
Único, siempre y cuando cuente volver a Lisp, que es el segundo lenguaje de programación más antiguo. ;-)
Michael H.
-1: No semi-único
Casebash
7

Los conjuntos en Delphi son muy útiles, casi solo una matriz booleana con nombre. Son muy útiles para guardar un formulario de configuración con 32 casillas de verificación. Pero tienen todas las mismas funciones de teoría de conjuntos (es decir, diferencia, intersección, unión).

No estoy seguro de si han pasado de moda, pero los uso todo el tiempo.

Peter Turner
fuente
Bien, pero ¿no sería fácil de implementar en Java, por ejemplo: boolean []?
Mark C
Sí, puede, pero no creo que sea tan sucinto como: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = conjunto de TForm;
Peter Turner el
7

Enviar

De Erlang Envía un mensaje asíncrono a otro hilo.

Expr1 ! Expr2

Recibir

De Erlang Recibe un mensaje de otro hilo.

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end
Jonas
fuente
5

Propiedades de C #

/// <summary>
/// Get ID
/// </summary>
public int ID
{
    get; set;
}

vs

(Java)

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}
TheLQ
fuente
2
Sí, son mejores, pero este es un mal ejemplo. La diferencia sería mucho menor si el getter / setter realmente hiciera algo especial, y la versión de C # se documente menos.
Bart van Heukelom
1
Mi jefe está firmemente en contra de las propiedades automáticas de C # y cada vez que tenemos una discusión al respecto, ninguno de nosotros es capaz de ver por qué el otro tiene razón o no. Simplemente los amo porque hacen que el código sea mucho más limpio y me ahorra mucho tiempo a largo plazo.
mbillard
2
Simplemente no permita que esto anime a las personas a tener captadores y setters por todas partes. Solo se deben usar aquellos captadores y establecedores que tengan sentido como acciones en un objeto.
David Thornley
3
No se llaman propiedades C #, se llaman propiedades automáticas
Jaco Pretorius
1
Las propiedades automáticas son muy comunes en estos días. Python, Objective-C ...
Casebash
5

Uniones en C

Honestamente, no puedo decir que no he escrito suficiente C para hacer ninguno de estos, pero he trabajado con el código de otros que lo hace.

Cuando se trata de empaquetar mezclas de diferentes datos en aplicaciones que manipulan bits / bytes sin procesar, como redes o almacenamiento de datos binarios. En idiomas fuertemente tipados no hay una manera fácil de hacer el equivalente.

Renuncia:

Aunque las Uniones son extremadamente útiles en algunos casos, no se encuentran en la mayoría de los idiomas de nivel superior porque no son de tipo seguro. Es decir, puede hacer que los datos sangren a través de los límites de las variables utilizando uniones (un gran no no en el mundo de tipo seguro). Con un gran poder viene una gran responsabilidad.

Evan Plaice
fuente
2
En mi humilde opinión por una buena razón. La reinterpretación de datos es una forma hermosa de dispararse a sí mismo en el pie ( en.wikipedia.org/wiki/Aliasing_(computing) ). Mejor usar conversiones explícitas en mi humilde opinión. Los sindicatos que están haciendo lo correcto son tipos de datos algebraicos de mi humilde opinión.
Maciej Piechotka
@Maciej Agregué un descargo de responsabilidad necesario. Sin embargo, no estoy seguro de si explica con precisión los peligros de usar uniones, ya que realmente no tengo un conocimiento íntimo de su uso. Solo sé que, donde los he visto usar el código fue mucho más conciso y más fácil de trabajar que el equivalente de lenguaje de nivel superior.
Evan Plaice
El problema es que C es 'lenguaje de nivel superior' (solo lenguaje de nivel superior de nivel bajo). Desde K&R C, tiene muchas reglas que permiten usar un código portátil más rápido. El precio es que el compilador puede asumir varias cosas y algunas pueden confundirse. La mayor parte del unionuso es seguro, algunos son modismos bien soportados (aunque técnicamente no son correctos); consulte cellperformance.beyond3d.com/articles/2006/06/… (aunque es más problemático con los punteros, las uniones pueden simularlo).
Maciej Piechotka
Delphi extendió su recordsintaxis para apoyar a los sindicatos:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
Frank Shearar
5

Realmente me gusta el modificador a menos que sea en Ruby . Parece tan natural y reemplaza muchos escenarios en los que su código parece ser muy desordenado sin él.

puts "All good" unless input.nil?

¿Cómo no te puede gustar eso? :RE

Jaco Pretorius
fuente
66
Perl lo tenía antes que Ruby. Me encanta también.
Barry Brown el
1
Nemerle tiene palabras clave similares para unlessy whenque reemplazan los escenarios de ramificación más comunes que usarían tradicionalmente if/else.
MattDavey
5

elegantes sintaxis de argumentos de python

No estoy seguro de cuán único es esto, pero en Python puedes hacer cosas geniales como hacer que los pares de palabras clave se conviertan automáticamente en un diccionario y viceversa. Lo mismo con las listas:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"


parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

documentos de Python (desplácese hacia abajo para ver más argumentos para pegar)

Gordon Gustafson
fuente
1
+1 para poder pasar un parámetro profundo en la lista sin tener que pasar valores para todos los parámetros opcionales anteriores.
eswald 01 de
4

El preprocesador C. Incluso puede escribir código común en diferentes plataformas con --de menos o más-- ifdefs.

ern0
fuente
2
Hay mejores preprocesadores disponibles que dan su propio paso adicional y funcionan con todos los idiomas.
David Thornley
Estoy bastante contento con ifdef, ifndef y más.
ern0
3

Categorías Objective-C

Las categorías ofrecen una manera fácil de extender la funcionalidad de un objeto en tiempo de ejecución (piense en composición versus herencia). El ejemplo clásico es agregar un corrector ortográfico a la clase NSString.

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

También es útil para la corrección de errores de bajo impacto, ya que la implementación de un método por parte de una categoría anulará la implementación de sus padres.

un golpe
fuente
1
Muy similar a los métodos de extensión en C #
Casebash
2

El método de inyección de Ruby combinado con la función Symbol # to_proc de Ruby 1.9 le permite a uno escribir un código increíblemente conciso (pero aún legible):

p.ej (1..10).inject(:+)

que suma los enteros del 1 al 10 => 55

Ver ejemplos como este me hizo querer aprender Ruby, que acabo de empezar a hacer.

tcrosley
fuente
99
Para ser justos, inyectar es la versión de Ruby de fold / foldl / foldr de idiomas como Lisp, Haskell, etc.
mipadi
Realmente no llamaría a esto único.
Daenyth
1
El título de la pregunta dice "semi-único", no único. Ciertamente, la concisión del código que ofrece la combinación de inyectar (o mapa, etc.) y Symbol # to_proc está mucho más allá de los lenguajes convencionales como C, Java y C ++.
tcrosley
Muy conciso (y me gusta), pero no estoy tan seguro de que sea tan diferente a algo como: Enumerable.Range (1, 10) .Agregre ((s, x) => s + x); de C # u otros idiomas
FinnNk
1

El mecanismo de enlace en JavaFX (RIP). La palabra clave bind le permite vincular el valor de una variable al valor de una expresión y deshacerse de todos esos feos oyentes del código repetitivo.

Si bien JavaFX fue un gran fracaso en muchos sentidos, encontré muchas características del lenguaje de script bastante agradable.

Oliver Weiler
fuente
1

La combinación de cadenas más la evaluación de la función de tiempo de compilación en D es una característica asesina bastante única. Sí, técnicamente son dos características, pero el verdadero poder proviene de combinarlas. Con esta combinación, puede escribir funciones D regulares que generan código como una cadena en tiempo de compilación, y luego mezclar este código en cualquier ámbito y hacer que se evalúe como código D regular. El código está totalmente compilado estáticamente y se ejecuta exactamente como si hubiera sido escrito a mano. Esta característica incluso se utiliza para solucionar un par de situaciones difíciles en la biblioteca estándar.

dsimcha
fuente
También me gusta el tipo de retorno inferido automáticamente de un método ..
nawfal