Caratteristiche del linguaggio di programmazione semi-univoco di Killer [chiuso]


25

Quando impari un nuovo linguaggio di programmazione a volte ti imbatti in una funzione linguistica che ti fa desiderare di averlo negli altri linguaggi di programmazione che conosci.

Quali sono alcune funzionalità linguistiche che al momento dell'apprendimento erano molto nuove per te e che vorresti avessero gli altri tuoi linguaggi di programmazione.

Un esempio di ciò sono i generatori in Python o C #. Altri esempi possono comprendere la comprensione dell'elenco in Python, il modello in C ++ o LINQ in .NET o la valutazione pigra in Haskell.

Quali altre caratteristiche linguistiche semi-uniche hai scoperto che erano completamente nuove e illuminanti per te? Esistono altre caratteristiche dei linguaggi di programmazione precedenti che erano uniche e fuori moda?

Risposte:


25

Praticamente qualsiasi cosa a Haskell

  • Monadi. Sì, la grande parola spaventosa che rende parsermente facili i parser, l'IO, le operazioni sugli elenchi e altre cose così facili (una volta notato uno schema comune)
  • Frecce. Lo stesso per utenti esperti;)
  • Roba standard come lambda ecc.
  • Funzioni curriculari
  • Tipi di dati algebrici
  • Corrispondenza del modello

E molti altri.

PS. Sì. Sono un fan di Haskell se qualcuno lo chiedesse.


12
Per essere onesti, dovresti dare credito ML per la maggior parte di tale elenco.
munificente

1
Bene - tranne monadi e frecce IIRC. Ma sono ancora semi- unici
Maciej Piechotka,

Qualche motivo particolare per il downvote?
Maciej Piechotka,

2
+1 per la corrispondenza dei motivi. Lo mostro ad altre persone e loro non lo capiscono. Penso che sia geniale.
Barry Brown,

Obbligatorio ( steve-yegge.blogspot.com/2010/12/… ). A proposito, difficilmente considererei lambda come unici, pitone, C #, javascript, ecc. Monadi? Molte altre lingue si riferiscono ad esso come concatenamento; il nucleo jquery è essenzialmente un insieme massiccio di monadi HTML / DOM e AJAX (Google: jQuery.fn). Al giorno d'oggi, anche il curry è relativamente comune.
Evan Plaice,

21

Macro Lisp.

Il linguaggio macro Lisp è Lisp, con alcune funzioni di sintassi predefinite per motivi di praticità. Usandoli, è possibile aggiungere funzionalità importanti al linguaggio, come la scelta degli stili di orientamento degli oggetti o la corrispondenza deterministica simile a Prolog, senza guardare fuori posto. Rende setfpossibile la macro, che è una macro concettualmente molto potente: (setf A B)significa che, quando valuti A, otterrai Be che può essere estesa a qualsiasi limite ti piaccia.

La metaprogrammazione del modello C ++ è capace di cose simili, ma in un linguaggio molto diverso dal normale C ++.


+1 Spero che un giorno sarò in grado di programmare in un dialetto Lisp.
Oliver Weiler,

@Helper ... tramite modelli C ++ [risate spaventose]
mlvljr

@mlvjr: sei spaventoso.
David Thornley,

In effetti, è l' unica funzionalità pronta all'uso di cui avrai mai bisogno in una lingua. Con le macro Lisp è possibile aggiungere tutte le altre possibili funzionalità in un secondo momento.
SK-logic,

18

Decoratore di Python.

È estremamente facile implementare la memorizzazione o il tempismo della funzione usando il decoratore.

Esempio di un timer funzione.

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']

Ora se hai una funzione per cui vuoi passare il tempo, puoi semplicemente farlo,

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

Vedrai qualcosa come

La funzione "pippo" ha impiegato 3 secondi.


Java ha annotazioni, che hanno uno scopo e una sintassi simili, ma funzionano in modo molto diverso
Casebash

1
+1: I decoratori di Python mi hanno impressionato più di quasi ogni altra caratteristica della lingua. Sono molto belli e semplici!
Adam Paynter,

Forse potresti condividere un semplice esempio con noi? Non conosco Python a dire il vero.
ShdNx,

@ShdNx, ho appena aggiunto un esempio.
grokus,

1
L'ora di inizio non dovrebbe essere calcolata come parte della chiamata?
detly

14

Trasmissione void*in C. È possibile eseguire il cast di tutto in byte non elaborati e fare ciò che si desidera con questi dati.

(Sì, al giorno d'oggi è unico ...)


1
L'oggetto nei linguaggi .Net è molto simile. Solo un altro tipo di sicurezza, ecc.
Maciej Piechotka,

Puoi lanciare un oggetto in molte lingue. Il problema principale è che molte lingue separano primitivi e oggetti
Casebash,

5
@Maciej: anche in .NET, non puoi davvero lanciare primitive su Object. Li inscatoli ed è una bestia abbastanza diversa. Inoltre, è ancora totalmente diverso dal casting per void*...
Dean Harding,

1
Casting Pointerin Pascal e Object Pascal fa la stessa cosa.
Frank Shearar,

1
@DeanHarding: Beh - in C hai la int64_tquale non puoi sempre lanciare in modo sicuro void *(scusami per il ritardo - 2 anni - risposta).
Maciej Piechotka,

12

Resa in Python

In Python (e credo in C #), puoi definire un cosiddetto generatore che mette in pausa l'esecuzione della funzione in yieldun'istruzione, restituisce il valore e nelle chiamate successive, riavvia la funzione da cui era stata interrotta (con lo stato conservato tra le chiamate). Questo è ottimo per generare lunghi elenchi di valori in cui sei interessato solo al valore corrente della funzione (che è molto comune). Ti permette di costruire sequenze potenzialmente infinitamente lunghe occupando solo uno spazio molto limitato in memoria.


1
La resa è già elencata nella domanda.
Trinidad,

Questo risale al BCPL.
Peter Taylor

8

Espressioni lambda (chiusure, funzioni nidificate, metodi anonimi, come li chiami).

Mi sono imbattuto per la prima volta in Perl, li ho subito amati e mi sono chiesto perché altre lingue non li hanno. Oggi credo che non sia più così unico; persino PHP è riuscito a hackerarli in qualche modo. Ma erano semi-unici al momento.


5
Unico, purché conti tornare a Lisp, che è il secondo linguaggio di programmazione più antico in circolazione. ;-)
Michael H.

-1: Non semi-unico
Casebash,


7

Gli insiemi in Delphi sono molto utili, praticamente solo un array booleano denominato. Sono molto utili per salvare un modulo di impostazioni con 32 caselle di controllo. Ma hanno tutte le stesse funzioni di teoria dell'insieme (cioè differenza, intersezione, unione).

Non sono sicuro che siano passati di moda, ma li uso sempre.


Bello, ma non sarebbe facile da implementare in Java, ad esempio: boolean []?
Marco C,

Sì, puoi, ma non penso che sia succinto come: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = set di TForm;
Peter Turner,

7

Inviare

Da Erlang. Invia un messaggio asincrono a un altro thread.

Expr1 ! Expr2

Ricevere

Da Erlang. Riceve un messaggio da un altro thread.

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

5

Proprietà C #

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

vs

(Giava)

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

2
Sì, sono migliori, ma questo è un cattivo esempio. La differenza sarebbe molto più piccola se il getter / setter facesse effettivamente qualcosa di speciale, e la versione C # sia documentata meno.
Bart van Heukelom,

1
Il mio capo è fortemente contrario alle proprietà automatiche di C # e ogni volta che discutiamo al riguardo, nessuno dei due è in grado di capire perché l'altro abbia ragione o torto. Li adoro perché rendono il codice molto più pulito e mi fanno risparmiare molto tempo nel lungo periodo.
mbillard,

2
Basta non consentire questo per incoraggiare le persone ad avere getter e setter dappertutto. Dovrebbero essere usati solo quei getter e setter che hanno senso come azioni su un oggetto.
David Thornley,

3
Non si chiamano proprietà C #, si chiamano Proprietà automatiche
Jaco Pretorius,

1
Le proprietà automatiche sono molto comuni in questi giorni. Python, Objective-C ...
Casebash,

5

I sindacati in C.

Onestamente non posso dire di non aver scritto abbastanza C per crearne uno da solo, ma ho lavorato con il codice di altri che lo fa.

Quando si tratta di impacchettare miscele di dati diversi in applicazioni che manipolano bit / byte grezzi come reti o archiviazione di dati binari. Nelle lingue fortemente tipizzate non esiste un modo semplice per fare l'equivalente.

Disclaimer:

Sebbene i sindacati siano estremamente utili in alcuni casi, non si trovano nella maggior parte delle lingue di livello superiore perché non sono sicuri per i tipi. IE, puoi far sanguinare i dati oltre i confini delle variabili usando i sindacati (un grande no no nel tipo di mondo sicuro). Con un grande potere viene una grande responsabilità.


2
IMHO per una buona ragione. La reinterpretazione dei dati è un bel modo di spararsi a piedi ( en.wikipedia.org/wiki/Aliasing_(computing) ). Meglio usare conversioni esplicite IMHO. I sindacati nel modo giusto sono tipi di dati algebrici IMHO.
Maciej Piechotka,

@Maciej Ho aggiunto un disclaimer necessario. Tuttavia, non sono sicuro che spieghi accuratamente i pericoli dell'utilizzo dei sindacati poiché non ho una conoscenza intima di usarli. So solo che, dove li ho visti usare il codice era molto più conciso e più facile da lavorare rispetto al linguaggio equivalente di livello superiore.
Evan Plaice,

Il problema è che C è un "linguaggio di livello superiore" (solo un linguaggio di livello superiore). Dal momento che K&R C ottiene molte regole che consentono di utilizzare un codice portatile più veloce. Il prezzo è che il compilatore può assumere varie cose e alcune possono essere confuse. La maggior parte uniondell'uso è sicuro, alcuni sono idiomi ben supportati (anche se tecnicamente non corretti) - vedi cellperformance.beyond3d.com/articles/2006/06/… (anche se è più un problema con i sindacati dei puntatori può benissimo falsificarlo).
Maciej Piechotka,

Delphi estese la sua recordsintassi per supportare i sindacati: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

Mi piace molto il modificatore a meno che non sia in Ruby . Sembra così naturale e sostituisce molti scenari in cui il tuo codice sembra essere molto disordinato senza di esso.

puts "All good" unless input.nil?

Come può non piacerti? : D


6
Perl ce l'aveva prima di Ruby. Lo amo anche io.
Barry Brown,

1
Nemerle ha parole chiave simili per unlesse whenche sostituiscono gli scenari di ramificazione più comuni che tradizionalmente utilizzerebbero if/else.
MattDavey,

5

sintassi degli argomenti di fantasia in pitone

Non sono sicuro di quanto sia unico, ma in Python puoi fare cose interessanti come avere coppie di parole chiave automaticamente trasformate in un dizionario e viceversa. Lo stesso con le liste:

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')

documenti Python (scorri verso il basso per ulteriori argomenti di discussione)


1
+1 per poter passare un parametro in profondità nell'elenco senza dover passare i valori per tutti i parametri opzionali prima di esso.
eswald,

4

Il preprocessore C. Puoi persino scrivere codice comune su piattaforme diverse con ifdefs - meno o più -.


2
Esistono prontamente disponibili migliori preprocessori che fanno il loro passo in più e funzionano con tutte le lingue.
David Thornley,

Sono abbastanza contento di ifdef, ifndef e altro.
ern0

3

Categorie dell'obiettivo-C

Le categorie offrono un modo semplice per estendere la funzionalità di un oggetto in fase di esecuzione (pensa alla composizione rispetto all'eredità). L'esempio classico è aggiungere un controllo ortografico alla classe NSString.

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

Utile anche per correzioni di bug a basso impatto, poiché l'implementazione di un metodo di una categoria avrà la precedenza sull'implementazione dei genitori.


1
Molto simile ai metodi di estensione in C #
Casebash,

2

Il metodo di iniezione di Ruby combinato con la funzione Symbol # to_proc di Ruby 1.9 consente di scrivere un codice incredibilmente conciso (ma ancora leggibile):

per esempio (1..10).inject(:+)

che somma gli interi da 1 a 10 => 55

Vedere esempi come questo mi ha fatto venire voglia di imparare Ruby, che ho appena iniziato a fare.


9
Ad essere onesti, iniettare è la versione di Ruby di fold / foldl / foldr da lingue come Lisp, Haskell, ecc.
mipadi

Non lo definirei davvero unico.
Daenyth,

1
Il titolo della domanda dice "semi-unico", non unico. Certamente la concisione del codice offerto dalla combinazione di inject (o map etc) e Symbol # to_proc è molto al di là dei linguaggi tradizionali come C, Java e C ++.
Tcrosley,

Molto conciso (e mi piace), ma non sono così sicuro che sia così diverso da qualcosa come: Enumerable.Range (1, 10) .Aggregate ((s, x) => s + x); da C # o altre lingue
FinnNk,

1

Il meccanismo di associazione in JavaFX (RIP). La parola chiave bind ti consente di associare il valore di una variabile al valore di un'espressione e di sbarazzarti di tutto quel brutto ascoltatore, qualunque codice di caldaia.

Mentre JavaFX è stato un vero fallimento in molti modi, ho trovato molte funzioni del linguaggio di scripting abbastanza carine.


1

I mixin di stringhe più la valutazione della funzione del tempo di compilazione in D è una caratteristica killer davvero unica. Sì, tecnicamente sono due caratteristiche, ma il vero potere deriva dal combinarle. Con questa combinazione, è possibile scrivere normali funzioni D che generano il codice come stringa al momento della compilazione, quindi mescolare questo codice in qualsiasi ambito e farlo valutare come normale codice D. Il codice è completamente compilato staticamente ed esegue esattamente come se fosse stato scritto a mano. Questa funzione viene persino utilizzata per aggirare un paio di situazioni problematiche nella libreria standard.


Mi piace anche il tipo restituito automaticamente dedotto da un metodo ..
nawfal
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.