Killer semi-einzigartige Programmiersprachenfunktionen [geschlossen]

25

Beim Erlernen einer neuen Programmiersprache stößt man manchmal auf eine Sprachfunktion, die den Wunsch aufkommen lässt, sie in anderen Programmiersprachen zu haben, die Sie kennen.

Was sind einige Sprachfunktionen, die zum Zeitpunkt des Lernens sehr neu für Sie waren und die Sie sich für Ihre anderen Programmiersprachen wünschen.

Ein Beispiel hierfür sind Generatoren in Python oder C #. Andere Beispiele können Listenverständnisse in Python, Vorlagen in C ++ oder LINQ in .NET oder verzögerte Evaluierung in Haskell umfassen.

Welche anderen halb-einzigartigen Sprachfunktionen sind Ihnen begegnet, die für Sie völlig neu und aufschlussreich waren? Gibt es andere Merkmale älterer Programmiersprachen, die einzigartig und unmodern waren?

Brian R. Bondy
quelle

Antworten:

25

Praktisch alles in Haskell

  • Monaden. Ja - das große unheimliche Wort, das Parser, E / A, Operationen an Listen und andere Dinge so einfach macht (sobald Sie ein gemeinsames Muster bemerken)
  • Pfeile. Gleiches gilt für Fortgeschrittene;)
  • Standard Sachen wie Lambdas etc.
  • Currying Funktionen
  • Algebraische Datentypen
  • Mustervergleich

Und viele mehr.

PS. Ja. Ich bin Haskell Fanboy, wenn jemand danach fragt.

Maciej Piechotka
quelle
12
Um fair zu sein, sollten Sie ML für den größten Teil dieser Liste gutschreiben.
Munificent
1
Nun - außer Monaden und Pfeile IIRC. Aber sie sind immer noch halb- einzigartig
Maciej Piechotka
Gibt es einen bestimmten Grund für eine Ablehnung?
Maciej Piechotka
2
+1 für den Mustervergleich. Ich zeige es anderen Leuten und sie verstehen es nicht. Ich finde es genial.
Barry Brown
Obligatorisch ( steve-yegge.blogspot.com/2010/12/… ). Übrigens, ich würde Lambdas kaum für einzigartig halten, Python, C #, Javascript usw. Monaden? Die meisten anderen Sprachen bezeichnen es als Verkettung; Der JQuery-Kern besteht im Wesentlichen aus einer großen Menge von HTML / DOM- und AJAX-Monaden (Google: jQuery.fn). Currys sind heutzutage auch relativ häufig.
Evan Plaice
21

Lisp-Makros.

Die Lisp-Makrosprache ist Lisp mit einigen vordefinierten Syntaxfunktionen. Mit ihnen ist es möglich, der Sprache wichtige Merkmale hinzuzufügen, wie z. B. die Auswahl von Objektorientierungsstilen oder prologähnliche deterministische Übereinstimmungen, ohne den Platz zu verlassen. Es macht das setfMakro möglich, die ein konzeptionell sehr leistungsfähiger Makro ist: (setf A B)bedeutet , dass, wenn Sie bewerten ASie erhalten B, und das kann auf jeden Grenzen Sie wie verlängert werden.

Die Metaprogrammierung von C ++ - Vorlagen kann ähnliche Dinge, jedoch in einer anderen Sprache als reguläres C ++.

David Thornley
quelle
+1 Ich hoffe, dass ich eines Tages in der Lage sein werde, in einem Lisp-Dialekt zu programmieren.
Oliver Weiler
@ Helper ... über C ++ Vorlagen [gruseliges Lachen]
mlvljr
@mlvjr: Du bist unheimlich.
David Thornley
Tatsächlich ist es die einzige sofort einsatzbereite Funktion, die Sie jemals in einer Sprache benötigen werden. Mit den Lisp-Makros können Sie später alle anderen möglichen Funktionen hinzufügen.
SK-logic
18

Pythons Dekorateur.

Mit dem Decorator ist es extrem einfach, Merkzettel oder Timing von Funktionen zu implementieren.

Beispiel einer Funktionsuhr.

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

Wenn Sie eine Funktion haben, die Sie zeitlich festlegen möchten, können Sie dies einfach tun.

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

Sie werden so etwas wie sehen,

Die Funktion 'foo' dauerte 3 Sekunden.

grokus
quelle
Java hat Anmerkungen, die einen ähnlichen Zweck und eine ähnliche Syntax haben, aber sehr unterschiedlich
funktionieren
1
+1: Pythons Dekorateure haben mich mehr als jedes andere Merkmal in der Sprache beeindruckt. Sie sind sehr schön und einfach!
Adam Paynter
Vielleicht könnten Sie uns ein einfaches Beispiel geben? Ich kenne Python nicht, um ehrlich zu sein.
ShdNx
@ShdNx, ich habe gerade ein Beispiel hinzugefügt.
Grokus
1
Sollte die Startzeit nicht als Teil des Anrufs berechnet werden?
Detly
14

Umwandeln void*in C. Sie können alles in unformatierte Bytes umwandeln und mit diesen Daten tun, was Sie wollen .

(Ja, heutzutage ist es einzigartig ...)

P Shved
quelle
1
Objekt in .Net-Sprachen ist sehr ähnlich. Nur typsicherer etc.
Maciej Piechotka
Sie können in einer Vielzahl von Sprachen zu Objekten umwandeln. Hauptproblem ist, dass viele Sprachen Primitive und Objekte trennen
Casebash
5
@Maciej: Selbst in .NET können Sie Primitive nicht wirklich in Object umwandeln. Sie boxen sie, und es ist ein ganz anderes Tier. Außerdem ist das immer noch ganz anders als bei void*...
Dean Harding
1
Das Umwandeln Pointerin Pascal und Object Pascal bewirkt dasselbe.
Frank Shearar
1
@DeanHarding: Naja - in C hast du das, auf int64_tdas du nicht immer sicher wirken kannst void *(Sorry für die späten 2 Jahre - antworte).
Maciej Piechotka
12

Ausbeute in Python

In Python (und ich glaube an C #) können Sie einen sogenannten Generator definieren, der die Funktionsausführung bei einer yieldAnweisung anhält, den Wert zurückgibt und bei nachfolgenden Aufrufen die Funktion an der Stelle neu startet, an der sie aufgehört hat (wobei der Status zwischen den Aufrufen erhalten bleibt). Dies ist ideal, um lange Wertelisten zu generieren, bei denen Sie nur den aktuellen Wert der Funktion (der sehr häufig vorkommt) benötigen. Sie können damit möglicherweise unendlich lange Sequenzen erstellen und dabei nur sehr wenig Speicherplatz belegen.

Chinmay Kanchi
quelle
1
Ertrag ist bereits in der Frage aufgeführt.
Trinidad
Dies geht bis zu BCPL zurück.
Peter Taylor
8

Lambda-Ausdrücke (Abschlüsse, verschachtelte Funktionen, anonyme Methoden, wie auch immer Sie sie nennen).

Ich habe sie in Perl kennengelernt, sie sofort geliebt und mich gefragt, warum andere Sprachen sie nicht haben. Heutzutage denke ich, dass es nicht mehr so ​​einzigartig ist; sogar PHP hat es geschafft, sie irgendwie zu hacken. Aber sie waren zu dieser Zeit halb einzigartig.

Timwi
quelle
5
Einzigartig, solange Sie zu Lisp zurückkehren, der zweitältesten Programmiersprache überhaupt. ;-)
Michael H.
-1: Nicht halb einzigartig
Casebash
7

Sets in Delphi sind sehr nützlich, so ziemlich nur ein benanntes boolesches Array. Sie sind sehr nützlich, um ein Einstellungsformular mit 32 Kontrollkästchen zu speichern. Aber sie haben alle die gleichen Mengenfunktionen (dh Differenz, Schnittmenge, Vereinigung).

Ich bin nicht sicher, ob sie aus der Mode gekommen sind, aber ich benutze sie die ganze Zeit.

Peter Turner
quelle
Schön, aber wäre das nicht einfach in Java zu implementieren, zum Beispiel: boolean []?
Mark C
Ja, das können Sie, aber ich glaube nicht, dass es so prägnant ist wie: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = Menge von TForm;
Peter Turner
7

Senden

Aus Erlang. Sendet eine Nachricht asynchron an einen anderen Thread.

Expr1 ! Expr2

Erhalten

Aus Erlang. Erhält eine Nachricht von einem anderen Thread.

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

C # -Eigenschaften

/// <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
quelle
2
Ja, sie sind besser, aber das ist ein schlechtes Beispiel. Der Unterschied wäre viel geringer, wenn der Getter / Setter tatsächlich etwas Besonderes tun würde, und die C # -Version ist weniger dokumentiert.
Bart van Heukelom
1
Mein Chef ist entschieden gegen die automatischen Eigenschaften von C #, und wenn wir darüber streiten, kann keiner von uns erkennen, warum der andere richtig oder falsch ist. Ich liebe sie einfach, weil sie den Code so viel sauberer machen und mir auf lange Sicht viel Zeit sparen.
mbillard
2
Nur nicht zulassen, dass dies die Leute dazu ermutigt, überall Getter und Setter zu haben. Es sollten nur die Getter und Setter verwendet werden, die als Aktionen für ein Objekt sinnvoll sind.
David Thornley
3
Sie heißen nicht C # -Eigenschaften, sondern Auto-Eigenschaften
Jaco Pretorius
1
Auto-Eigenschaften sind heutzutage sehr verbreitet. Python, Objective-C ...
Casebash
5

Gewerkschaften in C

Ich kann nicht ehrlich sagen, dass ich nicht genug C geschrieben habe, um eines davon selbst zu machen, aber ich habe mit dem Code anderer gearbeitet, der das tut.

Wenn es darum geht, Mischungen verschiedener Daten in Anwendungen zu verpacken, die unformatierte Bits / Bytes wie Netzwerk- oder Binärdatenspeicherung manipulieren. In stark typisierten Sprachen gibt es einfach keine einfache Möglichkeit, das Äquivalent zu tun.

Haftungsausschluss:

Obwohl Unions in einigen Fällen äußerst nützlich sind, werden sie in den meisten höheren Sprachen nicht gefunden, da sie nicht typsicher sind. IE, Sie können Daten mit Hilfe von Gewerkschaften über Variablengrenzen hinweg bluten lassen (ein großes Nein Nein in der typsicheren Welt). Mit großer Macht kommt große Verantwortung.

Evan Scholle
quelle
2
IMHO aus gutem Grund. Das Neuinterpretieren von Daten ist eine wunderbare Möglichkeit, sich selbst in den Fuß zu fassen ( en.wikipedia.org/wiki/Aliasing_(computing ). Verwenden Sie besser explizite Konvertierungen IMHO. Gewerkschaften, die den richtigen Weg gehen, sind IMHO-algebraische Datentypen.
Maciej Piechotka
@Maciej Ich habe einen notwendigen Haftungsausschluss hinzugefügt. Ich bin mir allerdings nicht sicher, ob dies die Gefahren des Einsatzes von Gewerkschaften genau erklärt, da ich nicht wirklich über genaue Kenntnisse im Umgang mit Gewerkschaften verfüge. Ich weiß nur, dass der Code, wo ich gesehen habe, dass er verwendet wurde, viel prägnanter und einfacher zu handhaben war als das höhere Sprachäquivalent.
Evan Plaice
Das Problem ist, dass C eine höhere Sprache ist (nur eine niedrigere höhere Sprache). Seit K & R C gibt es viele Regeln, die es erlauben, schnelleren portablen Code zu verwenden. Der Preis ist, dass der Compiler verschiedene Dinge annehmen kann und einige verwirrt sind. Der Großteil der unionVerwendung ist sicher, einige werden gut unterstützt (obwohl technisch nicht korrekt) - siehe cellperformance.beyond3d.com/articles/2006/06/… (obwohl es schwieriger ist, Zeiger zu verwenden, können Gewerkschaften dies gut vortäuschen).
Maciej Piechotka
Delphi erweiterte seine recordSyntax, um Gewerkschaften zu unterstützen: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

Ich mag den wenn nicht Modifikator in Ruby . Es scheint so natürlich und ersetzt viele Szenarien, in denen Ihr Code ohne es nur sehr chaotisch zu sein scheint.

puts "All good" unless input.nil?

Wie kannst du das nicht mögen? : D

Jaco Pretorius
quelle
6
Perl hatte es vor Ruby. Ich liebe es auch.
Barry Brown
1
Nemerle hat ähnliche Schlüsselwörter für unlessund whenersetzt die gängigsten Verzweigungsszenarien, die traditionell verwendet werden if/else.
MattDavey
5

ausgefallene Python-Argument-Syntax

Ich bin mir nicht sicher, wie einzigartig dies ist, aber in Python können Sie coole Dinge tun, z. B. Keyword-Paare automatisch in ein Wörterbuch umwandeln und zurück. Gleiches gilt für Listen:

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

Python-Dokumente (scrollen Sie nach unten, um weitere Argumente zu finden)

Gordon Gustafson
quelle
1
+1, um einen Parameter tief in der Liste übergeben zu können, ohne zuvor Werte für alle optionalen Parameter übergeben zu müssen.
Eswald
4

Der C-Präprozessor. Sie können sogar gemeinsamen Code mit weniger oder mehr ifdefs auf verschiedene Plattformen schreiben.

ern0
quelle
2
Es gibt bessere Präprozessoren, die einen eigenen Schritt machen und mit allen Sprachen arbeiten.
David Thornley
Ich bin ziemlich zufrieden mit ifdef, ifndef und anderen.
ern0
3

Ziel-C-Kategorien

Kategorien bieten eine einfache Möglichkeit, die Funktionalität eines Objekts zur Laufzeit zu erweitern (Komposition versus Vererbung). Das klassische Beispiel ist das Hinzufügen einer Rechtschreibprüfung zur NSString-Klasse.

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

Auch nützlich für Fehlerbehebungen mit geringer Auswirkung, da die Implementierung einer Methode durch eine Kategorie die Implementierung der Eltern überschreibt.

Schock
quelle
1
Sehr ähnlich zu Erweiterungsmethoden in C #
Casebash
2

Ruby ‚s inject Methode mit dem kombinierten # to_proc Symbol Feature von Ruby 1.9 kann einen Schreib einig unglaublich präziser (aber immer noch lesbar) Code:

z.B (1..10).inject(:+)

das summiert die ganzen Zahlen 1 bis 10 => 55

Beispiele wie dieses zu sehen, hat mich dazu gebracht, Ruby zu lernen, was ich gerade angefangen habe.

Tcrosley
quelle
9
Um fair zu sein, injizieren ist Rubys Version von fold / foldl / foldr aus Sprachen wie Lisp, Haskell, etc.
mipadi
Ich würde das nicht wirklich als einzigartig bezeichnen.
Daenyth
1
Der Titel der Frage lautet "semi-unique", nicht unique. Sicherlich geht die Prägnanz des Codes, der durch die Kombination von inject (oder map etc) und Symbol # to_proc erreicht wird, weit über die gängigen Sprachen wie C, Java und C ++ hinaus.
Tcrosley
Sehr prägnant (und ich mag es), aber ich bin nicht sicher, ob es etwas anderes ist als: Enumerable.Range (1, 10) .Aggregate ((s, x) => s + x); aus C # oder anderen Sprachen
FinnNk
1

Der Bindungsmechanismus in JavaFX (RIP). Mit dem Schlüsselwort bind können Sie den Wert einer Variablen an den Wert eines Ausdrucks binden und all den hässlichen Listener-Code loswerden.

Während JavaFX in vielerlei Hinsicht ein ziemlicher Fehlschlag war, fand ich viele Funktionen der Skriptsprache ganz nett.

Oliver Weiler
quelle
1

String-Mixins und die Auswertung der Kompilierzeitfunktion in D sind ein ziemlich einzigartiges Killer-Feature. Ja, technisch gesehen sind es zwei Merkmale, aber die wahre Stärke liegt in der Kombination dieser Merkmale. Mit dieser Kombination können Sie reguläre D-Funktionen schreiben, die zum Zeitpunkt der Kompilierung Code als Zeichenfolge generieren. Anschließend können Sie diesen Code in einen beliebigen Bereich mischen und ihn als regulären D-Code auswerten lassen. Der Code ist vollständig statisch kompiliert und wird genauso ausgeführt, als ob er handgeschrieben wäre. Diese Funktion wird sogar verwendet, um ein paar unangenehme Situationen in der Standardbibliothek zu umgehen.

dsimcha
quelle
Ich mag auch die Rückgabetyp automatisch aus einer Methode abgeleitet ..
Nawfal