@BlackJack: Kann ich nachvollziehen, JS hat ein paar Designfehler ¹ aber Crockford listed m.E. ein paar sehr gute Workarounds auf. (wobei ich sein Buch nicht mag)
LISP Macros wären dafür schön.... Aber zugegeben letztendlich braucht man eine Metasprache die in JS umgesetzt wird.
Minimalismus hat halt seine Nachteile, aber der Vorteil ist, dass es jetzt wohl die Plattformmäßig die meistverbreitete Sprache ist und sowas wie ein JIT-Compiler wie es scheint viel einfacher umzusetzen ist.
Ich brauch mir z.B. für kleine Anwendungen auch keinen Kopp zu machen ob mein Smartphone Android oder IPhone OS hat, DHTML kann ich heutzutage fast überall fahren.
OTOH gibts Sachen die in JS konsequenter umgesetzt sind als in Python, z.B. keine eingeschränkten Lambdas oder richtige Closures.
Das dich die "Flexibilität" des OO-Models nervt erklärt sich wohl auch aus deiner Python Herkunft, wenn man von Perl kommt, wie ich ist man TIMTOWTDI gewöhnt...roter Faden ist dann halt Guido's World.
1) konkret es fehlen einfach noch 2-3 Kommandos/Flags, z.B. damit man einfach durch ein Hash iterieren kann OHNE die gerbten Methoden aufzulisten.
Python to C Converter
Deswegen nutzt man ein Framework wie jQuery und wenn man mehr braucht nutzt man Plugins.BlackJack hat geschrieben:Benutze in einem Projekt 3 grössere Bibliotheken und Du hast drei verschiedene Vererbungsmodelle im Programm. Plus dem Eigenen vielleicht noch.
@LanX: "Flexibilität" ist auch in Programmen kein Selbstzweck, sondern nur gut, wenn sie einem Zweck dient. Bei einem Vererbungsmechanismus ist das nicht unbedingt sinnvoll.
@DasIch: Das funktioniert nur, wenn man absolute Kontrolle über Umgebung und Projekt hat. Und wie oft ist das in der Realität schon der Fall?
@DasIch: Das funktioniert nur, wenn man absolute Kontrolle über Umgebung und Projekt hat. Und wie oft ist das in der Realität schon der Fall?
@lunar: Prototypische Vererbung ist ziemlich simpel und klar definiert, alles anderen Vererbungsmechanismen sind von Modulautoren draufgesattelt, die es gerne wie zu Hause haben wollen (meistens ist Java=Daheim)lunar hat geschrieben:@LanX: "Flexibilität" ist auch in Programmen kein Selbstzweck, sondern nur gut, wenn sie einem Zweck dient. Bei einem Vererbungsmechanismus ist das nicht unbedingt sinnvoll.
Auch kann man auch mit Closures in JS viel weiter kommen, wo man in Python zu umständlicherer OOP gezwungen wird.
Ist das dann noch ein NPOV? Ich meine, weil nicht py-mäßig ist, ist es nicht unbedingt schlechter...
Aber hier prallen IMHO auch die unterschiedlichen Paradigmen von Perlern und Pythonistas aufeinander...TIMTOWTDI.
Ja:LanX hat geschrieben:ich kenne das Thema aus Perl boards, das Hauptproblem ist die dynamische Typisierung von Scriptsprachen.
http://www.perl.com/pub/2001/06/27/ctoperl.html
Dürfte für Python entsprechend gelten.
@LanX: Das JavaScript die meistverbreitete Sprache ist, halte ich für ein Gerücht -- jedenfalls wenn man da nicht noch Einschränkungen bei dieser Annahme macht. Überleg einfach mal wieviel mehr Embedded-Systeme in allen möglichen "intelligenten" Geräten -- von der Waschmaschine bis zum Auto stecken -- im Gegensatz zu den "paar" Rechnern mit Web-Browsern.
Python hat richtige Closures. Seit ``nonlocal`` auch welche, die semantisch wie bei JavaScript benutzt werden können, aber auch ohne sind das richtige Closures.
Die "Flexibilität" des OO-Models nervt mich nicht wegen der Python-"Vorbelastung" sondern weil ich sowohl bei Scheme als auch bei JavaScript schon die "Freuden" von mehreren Modellen in einem Projekt "geniessen" durfte. Das macht keinen Spass. Zumal das was man so im allgemeinen als den "vorgesehenen" Weg präsentiert bekommt 1. syntaktisch ziemlich blöd aussieht und 2. mit dem "leeren" Exemplar der Basisklasse als Prototyp IMHO ziemlich hässlich ist, weil man den Konstruktor ja so schreiben muss, dass man ihn auch komplett ohne Argumente aufrufen kann.
Schöne und einfache prototypische Vererbung hat zum Beispiel Io. Dagegen sieht der JavaScript-Krampf hässlich wie die Nacht aus.
JavaScript hat ein paar nette Grundgedanken, aber wenn ich das nächste mal damit etwas machen muss, werde ich das wohl über CoffeeScript in Angriff nehmen. Und das nicht nur weil die Sprache ein Vererbungssystem vorgibt (mit denen von Bibliotheken muss man sich im Ernstfall ja trotzdem rumschlagen).
Python hat richtige Closures. Seit ``nonlocal`` auch welche, die semantisch wie bei JavaScript benutzt werden können, aber auch ohne sind das richtige Closures.
Die "Flexibilität" des OO-Models nervt mich nicht wegen der Python-"Vorbelastung" sondern weil ich sowohl bei Scheme als auch bei JavaScript schon die "Freuden" von mehreren Modellen in einem Projekt "geniessen" durfte. Das macht keinen Spass. Zumal das was man so im allgemeinen als den "vorgesehenen" Weg präsentiert bekommt 1. syntaktisch ziemlich blöd aussieht und 2. mit dem "leeren" Exemplar der Basisklasse als Prototyp IMHO ziemlich hässlich ist, weil man den Konstruktor ja so schreiben muss, dass man ihn auch komplett ohne Argumente aufrufen kann.
Schöne und einfache prototypische Vererbung hat zum Beispiel Io. Dagegen sieht der JavaScript-Krampf hässlich wie die Nacht aus.
JavaScript hat ein paar nette Grundgedanken, aber wenn ich das nächste mal damit etwas machen muss, werde ich das wohl über CoffeeScript in Angriff nehmen. Und das nicht nur weil die Sprache ein Vererbungssystem vorgibt (mit denen von Bibliotheken muss man sich im Ernstfall ja trotzdem rumschlagen).
Wie schon erwähnt, funktioniert der JIT inzwischen soweit, dass PyPy fast immer deutlich schneller als CPython ist. Aktuelle Zahlen: http://speed.pypy.org/LanX hat geschrieben:Ja aber JS ist extrem kompact und erweiterbar, dass macht die Implementierung und Optimierung auch so einfach.
Laut WP ist PyPy nicht wirklich schneller als CPython, während V8 abgeht wie ein geöltes Zäpfchen.
Das ist das Problem. Jede umfangreichere Bibliothek implementiert eigene Vererbungsmechanismen. D.h. man darf die Sprache für jede Bibliothek neu lernen. Und wenn schon prototypenbasiert dann bitte Self.Geschmacksache, ich sattle mir immer drauf was mir fehlt. Prototypische Vererbung machts möglich...Darii hat geschrieben:JS find ich persönlich eher abstoßend.
Würde nicht schaden.Roter Faden = "There is only Guido's way to do it" ???Darii hat geschrieben: Der Sprache fehlt der rote Faden.
Was ich hauptsächlich störend finde sind die seltsame Syntax zur Definition von Objekten, die dieses eigentlich völlig überflüssige new-Schlüsselwort erfordert. Das seltsame this, auf das man sich nicht verlassen kann (var self = this *hust*). Und die umständliche Scoping-Regel, der man zu verdanken hat, dass man vor praktisch jede Variable var schreiben muss. Die Zahl der Prototypen ist natürlich auch nur auf einen beschränkt. Und die Möglichkeit ein Programm gescheit in mehrere Dateien aufzuteilen und somit etwas zu strukturieren fehlt auch völlig. Da braucht man dann wieder zusätzliche Software (sprich: Präprozessoren).
Musst du in Python bei Mehrfachvererbung eigentlich auch machen, sonst knallt u.U. super irgendwo.BlackJack hat geschrieben: 2. mit dem "leeren" Exemplar der Basisklasse als Prototyp IMHO ziemlich hässlich ist, weil man den Konstruktor ja so schreiben muss, dass man ihn auch komplett ohne Argumente aufrufen kann.
@Darii: Ich verwende weder Mehrfachvererbung noch `super()`. Höchstens mal "Mixin"-Klassen, aber das auch sehr selten.
Tatsächlich! Nächstes mal wenn ich mich auf meiner Waschmaschine oder Auto einlogge werde ich besser drauf achten in welcher Sprache ich progge...BlackJack hat geschrieben: Überleg einfach mal wieviel mehr Embedded-Systeme in allen möglichen "intelligenten" Geräten -- von der Waschmaschine bis zum Auto stecken -- im Gegensatz zu den "paar" Rechnern mit Web-Browsern.
Soso, und mit nonlocal werdens dann "richtigere" Closures ...BlackJack hat geschrieben:Python hat richtige Closures. Seit ``nonlocal`` auch welche, die semantisch wie bei JavaScript benutzt werden können, aber auch ohne sind das richtige Closures.
BlackJack hat geschrieben:Die "Flexibilität" des OO-Models nervt mich nicht wegen der Python-"Vorbelastung" sondern weil ich sowohl bei Scheme als auch bei JavaScript schon die "Freuden" von mehreren Modellen in einem Projekt "geniessen" durfte.
Es hat sich leider (noch) kein einheitliches Best Practice durchgesetzt, das hat viele Gründe, siehe The World's Most Misunderstood Programming Language
Meine Aussage war aber dass JS trotzdem einfach zu erweitern ist und gleichzeitig der Kern trotzdem wg seiner Kompaktheit einfach zu implementieren und zu tunen ist.
Also die Notwendigkeit eines Hash-Objektes in Prototype.js finde ich in der Tat verwirrend. Es ist halt leider Designfehler dass man bei vererbten Methoden keine Spezialflags setzen kann - wie z.B. mit "isEnumerable" vorhanden - setzen kann.BlackJack hat geschrieben: Das macht keinen Spass.
Aber, hei ...andere Sprachen verzichten dafür darauf rechtzeitig "nonlocal" einzuführen, und vertrösten auf die nächste Hauptversion... shit happens
Auch hier verweise ich gerne auf Crockford http://javascript.crockford.com/prototypal.html.BlackJack hat geschrieben: Zumal das was man so im allgemeinen als den "vorgesehenen" Weg präsentiert bekommt 1. syntaktisch ziemlich blöd aussieht und 2. mit dem "leeren" Exemplar der Basisklasse als Prototyp IMHO ziemlich hässlich ist, weil man den Konstruktor ja so schreiben muss, dass man ihn auch komplett ohne Argumente aufrufen kann.
Schöne und einfache prototypische Vererbung hat zum Beispiel Io. Dagegen sieht der JavaScript-Krampf hässlich wie die Nacht aus.
Io kenne ich nicht aktiv... Aber Interessant, eine Sprache die trotz M-Expressions Macros beherrscht hört sich tatsächlich faszinierend an.
Allerdings wo komme ich damit in Berührung? Etwa in meiner Waschmaschine...
Interessant http://jashkenas.github.com/coffee-script/ ....BlackJack hat geschrieben:JavaScript hat ein paar nette Grundgedanken, aber wenn ich das nächste mal damit etwas machen muss, werde ich das wohl über CoffeeScript in Angriff nehmen.
Meine Vision geht aber eher dahin ein zurechtgestutztes Perl einzusetzen, >95% der JS Semantik (inkl Objektmodell) ließe sich bereits heute 1:1 abbilden.
Die restlichen 5% sind das -ähm - unorthodoxe scopingverhalten von var und Details bei der Typkonversionen...
In Perl hätte ich dann dank expliziten concat operators auch explizit die Möglichkeit zwischen 1+0 und "1"+"0" zu unterscheiden.
PS: Kann man in diesem PHP Board eigentlich den Teilthread über JS absplitten, mit C hats ja nur noch bedingt zu tun...
ja ... das "new" hatte wohl Marketinggründe, wie die umbenennung von in JAVAscript.Darii hat geschrieben: Was ich hauptsächlich störend finde sind die seltsame Syntax zur Definition von Objekten, die dieses eigentlich völlig überflüssige new-Schlüsselwort erfordert.
ich kann dir nicht folgen... Beispiel?Darii hat geschrieben: Das seltsame this, auf das man sich nicht verlassen kann (var self = this *hust*).
hä??? ... gibts außer Python eine andere (nichtakademische) Sprache die per default localisiert und wo man explizit "nonlocal"-isiseren muss (wenn man denn kann)?Darii hat geschrieben: Und die umständliche Scoping-Regel, der man zu verdanken hat, dass man vor praktisch jede Variable var schreiben muss.
"var" ist nervig weil es für den ganzen Scope - also auch vorhergehenden Code - gilt.¹
Deswegen bemängelt Crockfords JS-Lint es auch wenn du die var-Deklarationen nicht am Funktionsanfang machst.
Das ist IMHO ein fettes Plus! Ich bevorzuge - schon aus Designgründen - Mixins. Die Nützlichkeit der Mehrfachvererbung ist m.E. ein Mythos.Darii hat geschrieben: Die Zahl der Prototypen ist natürlich auch nur auf einen beschränkt.
Doch Packaging bekommt man schon ohne Präprozessoren hin, aber auch hier gibts leider keine akzeptierte Best Practice.Darii hat geschrieben: Und die Möglichkeit ein Programm gescheit in mehrere Dateien aufzuteilen und somit etwas zu strukturieren fehlt auch völlig. Da braucht man dann wieder zusätzliche Software (sprich: Präprozessoren).
1) ich bin mir nicht ganz sicher was Python macht, wenn ich eine neue Variable binde ...gleich mal testen...
@LanX: Es wird sich wohl auch keine einheitliche Best Practice durchsetzen. Das ist eben der Nachteil bei der Freiheit an der Stelle.
Ich sehe ``nonlocal`` nicht als essentiell wichtig an. Python hat Klassen, man bekommt da also nichts, was man vorher nicht auch relativ einfach ausdrücken konnte. Klassen sind ein wichtiger Bestandteil von Python und nichts exotisches. Wenn man sie braucht, sollte man sie auch verwenden.
Crockford bastelt mit der `Object.create()`-Funktion `clone` aus Io nach. Der Punkt ist, dass man so etwas Kleines aber Essentielles nicht selber machen sollen müsste. Denn Crockford macht das so und nennt das `create`. Der nächste macht das gleiche und nennt es aber anders. Ein dritter macht etwas leicht verschiedenes, nennt es aber auch `create` und pappt es an das globale `Object`. Und dann versuch mal Code von diesen drei Programmieren in einem Programm zu verwenden.
Nichts gegen Freiheit, aber bei solch grundlegenden Dingen sollte von den Sprachentwicklern mindestens ein Weg fertig und ohne Boilerplate funktionierend angeboten werden. Wer was anderes will, soll ja ruhig die Möglichkeit haben. Bei Io kann man sich auch andere Semantiken basteln.
Ich persönlich mag bei JavaScript am liebsten das Idiom was Crockford "functional inheritance" nennt.
Ich sehe ``nonlocal`` nicht als essentiell wichtig an. Python hat Klassen, man bekommt da also nichts, was man vorher nicht auch relativ einfach ausdrücken konnte. Klassen sind ein wichtiger Bestandteil von Python und nichts exotisches. Wenn man sie braucht, sollte man sie auch verwenden.
Crockford bastelt mit der `Object.create()`-Funktion `clone` aus Io nach. Der Punkt ist, dass man so etwas Kleines aber Essentielles nicht selber machen sollen müsste. Denn Crockford macht das so und nennt das `create`. Der nächste macht das gleiche und nennt es aber anders. Ein dritter macht etwas leicht verschiedenes, nennt es aber auch `create` und pappt es an das globale `Object`. Und dann versuch mal Code von diesen drei Programmieren in einem Programm zu verwenden.
Nichts gegen Freiheit, aber bei solch grundlegenden Dingen sollte von den Sprachentwicklern mindestens ein Weg fertig und ohne Boilerplate funktionierend angeboten werden. Wer was anderes will, soll ja ruhig die Möglichkeit haben. Bei Io kann man sich auch andere Semantiken basteln.
Ich persönlich mag bei JavaScript am liebsten das Idiom was Crockford "functional inheritance" nennt.
@LanX: Ich verstehe Deine Anmerkung zum Scope nicht wirklich. Ohne ``var`` sind Variablen in JavaScript *global* und zwar so *richtig* global. Das ist doof weil in 99% der Fälle nicht das was man will. Und dass sich das ``var`` egal wo es steht auf die Funktion und nicht den Block besteht, ist die nächste Überraschung.
Beispiel für's `this` sind Methoden die man rumreicht und die vielleicht irgendwo in anderen Bibliotheken an ein Objekt gebunden werden, weshalb man das `this` selbst vorher in einem Closure "festnageln" muss, weil es sonst bei der Ausführung nicht an das Objekt gebunden ist, von dem die Methode ursprünglich mal kam. Bin ich auch erstmal mit auf die Schnauze gefallen.
Zum Packaging bringt CommonJS ja vielleicht eine Vereinheitlichung.
Beispiel für's `this` sind Methoden die man rumreicht und die vielleicht irgendwo in anderen Bibliotheken an ein Objekt gebunden werden, weshalb man das `this` selbst vorher in einem Closure "festnageln" muss, weil es sonst bei der Ausführung nicht an das Objekt gebunden ist, von dem die Methode ursprünglich mal kam. Bin ich auch erstmal mit auf die Schnauze gefallen.
Zum Packaging bringt CommonJS ja vielleicht eine Vereinheitlichung.
An paar Anmerkungen: Es ist Mythos, dass fehlende statische Typen zwangsläufig langsamere Programme ergeben. Da gibt es ein Paper aus dem Self-Projekt so ca. 1995, das ich aber zu faul bin, jetzt herauszusuchen, welches das Gegenteil zeigt. Dynamisch typisierte Sprachen sind in der Regel langsamer, weil sie ausdrucksstärker als ihre statisch kompilierenden Brüder sind. So bieten die meisten z.B. korrekte Artithmetik ohne Überlauf ins negative, eine automatische Speicherverwaltung oder ein Modell, wo jeder Datentyp gleichartig (als Objekt) behandelt wird. Mehr Features drücken da natürlich auf die mögliche Maximalgeschwindigkeit.
Ein Python-Programm in ein äquivalentes C-Programm zu übersetzen erfordert letztlich, dass in diesem C-Programm ein kompletter Python-Interpreter vorhanden ist, denn z.B. der exec-Befehl müsste ja funktionieren. Man will also in jedem Fall ein Subset von Python in C übersetzen.
Der andere Ansatz wäre, mit dem semantischen Modell von C zu beginnen, dies in eine Python-Syntax einzupacken und dann zu schauen, welche Features, die C nicht bietet aber Python jetzt noch "billig" hinzuzufügen wären.
Der Autor von Galcon ist auch Autor von tinypy und hat dafür einen Python nach C++ Übersetzer gebaut, damit er Spiele wie Galcon (was AFAIK einen Python-Teil hat oder sogar ganz in Python geschrieben ist) in C++ übersetzen und so einfacher für's iPhone entwickeln kann. So weit ich weiß, ist die Calcon-Version für's iPhone dann aber doch direkt in C++ und/oder Objective-C++ geschrieben worden.
Tinypy könnte aber vielleicht auch so schon für embedded Systeme geeignet sein. Aber auch hier gilt: Das ist kein Python gemäß der von GvR erstellten Spezifikation, sondern etwas, das eine ähnliche Syntax hat und mehr oder weniger nahe bei Python gelegen hat.
Ich hatte man angefangen, einen Übersetzer für ein mit Python-Syntax geschriebenes Java-Programm nach Java zu bauen: http://github.com/sma/dython Damit das funktioniert, braucht man jedoch einen guten Typ-Inferenzer und dazu war ich im May nicht motiviert genug. Statt Java könnte man aber genauso gut auch C-Code erzeugen, müsste dann noch einen GC dazu tun (boehmgc) und ein bisschen Laufzeitbibliothek entwickeln. Ich wollte ja einfach dem Duby^W Mirah-Ansatz folgen und ausschließlich das Laufzeitsystem der Zielsprache einsetzen.
Ich würde übrigens so weit gehen und sagen, JavaScript (ECMAScript 5) kann man prinzipiell schneller ausführen als Python, weil es weniger flexibel ist und weniger Konzepte der Implementierung durchscheinen. Als Beleg würde ich die belang mäßigen (um nicht zu sagen enttäuschenden) Erfolge des Unladen Swallow-Projekts anführen gegenüber dem V8-Projekt und das, obwohl die wirklich wussten, was sie tun und alle State-of-the-Art-Techniken kannten.
Des weiteren würde ich eine Lanze für JavaScript brechen wollen und sagen, dass ich die Sprache nett finde und nur empfehlen kann, Vorurteile abzulegen und sich näher damit zu beschäftigen. Immerhin ist es die am weitesten verbreitetste Sprache und sie wird uns noch viele Jahre erhalten bleiben.
Besser als Lisp (was ich als CommonLisp lesen würde) ist IMHO Scheme, was Reinheit und Klarheit der Konzepte angeht. Diese findet man (bis auf Continuations) auch in JavaScript wieder. Dazu kommt das Objektkonzept von Self, welches sich aus Smalltalk weiterentwickelt hat. Objective-C ist übrigens der Versuch, das Objektmodell von Smalltalk über C zu stülpen. War so eine "das kann doch nicht so schwer sein Idee" von Brad Cox, der 1986 Smalltalk sah, aber lieber C machen wollte und die Idee von Software-Komponenten verfolgte. Der größte Fehler war, die Blöcke zu ignorieren. Kaum 25 Jahre später hat Apple ihn dann korrigiert und eigenmächtig in ihre Version von C, C++ und Objective-C das Konzept von Blöcken integriert. Die selben Blöcke von Smalltalk (traditionell keine Closures wie bei Scheme) machen Ruby übrigens zu einer der mächtigsten Sprachen, was DSLs angeht.
Wo war ich? JavaScript! Ich denke, wo heutzutage C der portable Assembler (wer nicht muss, nutzt diese primitive Sprache doch hoffentlich nicht mehr freiwillig einfach nur so) wird in Zukunft JavaScript im Web-Umfeld diese Rolle übernehmen. 2012, wenn es nach Brendan Eich geht, kommt die nächste EcmaScript-Version, die ein paar weitere Probleme von JS beseitigt, etwa die standardmäßig globalen Variablen oder das Fehlen eines "doesNotUnderstand"-Catchalls. Wie auch immer, CoffeeScript ist ein schönes Beispiel für die JS-ist-portabler-Assembler-für-andere-Sprachen Ansatz.
Lua wäre übrigens anstelle von Python eine IMHO sehr schöne Alternative, wenn es um embedded Systems geht. Gibt es auch einen recht fixen JIT dafür.
Übrigens, Closures sind alles, was man braucht, um Objekte zu realisieren. Daher kann man in Scheme so schön als Fingerübung ein OO-System bauen. Andersherum ginge es auch, ist aber deutlich anstrengender. Wer den Schmerz fühlt, den man hat, wenn man in Java funktional programmieren will, weiß, was ich meine.
Und wer mal "verrückte" (im Sinne von genial) funktionale Programmierung in JavaScript sehen will, schaue sich (fab) (die Klammern gehören zum Produktnamen) (http://github.com/jed/fab) an, ein funktionales Webrahmenwerk für JavaScript.
Noch was: Wer Io mag (und damit eigentlich auch Self mögen müsste) schaue sich mal Ola Binis Ioke an. Das ist eine ziemlich interessante (experimentelle) Weiterentwicklung an.
Stefan
Ein Python-Programm in ein äquivalentes C-Programm zu übersetzen erfordert letztlich, dass in diesem C-Programm ein kompletter Python-Interpreter vorhanden ist, denn z.B. der exec-Befehl müsste ja funktionieren. Man will also in jedem Fall ein Subset von Python in C übersetzen.
Der andere Ansatz wäre, mit dem semantischen Modell von C zu beginnen, dies in eine Python-Syntax einzupacken und dann zu schauen, welche Features, die C nicht bietet aber Python jetzt noch "billig" hinzuzufügen wären.
Der Autor von Galcon ist auch Autor von tinypy und hat dafür einen Python nach C++ Übersetzer gebaut, damit er Spiele wie Galcon (was AFAIK einen Python-Teil hat oder sogar ganz in Python geschrieben ist) in C++ übersetzen und so einfacher für's iPhone entwickeln kann. So weit ich weiß, ist die Calcon-Version für's iPhone dann aber doch direkt in C++ und/oder Objective-C++ geschrieben worden.
Tinypy könnte aber vielleicht auch so schon für embedded Systeme geeignet sein. Aber auch hier gilt: Das ist kein Python gemäß der von GvR erstellten Spezifikation, sondern etwas, das eine ähnliche Syntax hat und mehr oder weniger nahe bei Python gelegen hat.
Ich hatte man angefangen, einen Übersetzer für ein mit Python-Syntax geschriebenes Java-Programm nach Java zu bauen: http://github.com/sma/dython Damit das funktioniert, braucht man jedoch einen guten Typ-Inferenzer und dazu war ich im May nicht motiviert genug. Statt Java könnte man aber genauso gut auch C-Code erzeugen, müsste dann noch einen GC dazu tun (boehmgc) und ein bisschen Laufzeitbibliothek entwickeln. Ich wollte ja einfach dem Duby^W Mirah-Ansatz folgen und ausschließlich das Laufzeitsystem der Zielsprache einsetzen.
Ich würde übrigens so weit gehen und sagen, JavaScript (ECMAScript 5) kann man prinzipiell schneller ausführen als Python, weil es weniger flexibel ist und weniger Konzepte der Implementierung durchscheinen. Als Beleg würde ich die belang mäßigen (um nicht zu sagen enttäuschenden) Erfolge des Unladen Swallow-Projekts anführen gegenüber dem V8-Projekt und das, obwohl die wirklich wussten, was sie tun und alle State-of-the-Art-Techniken kannten.
Des weiteren würde ich eine Lanze für JavaScript brechen wollen und sagen, dass ich die Sprache nett finde und nur empfehlen kann, Vorurteile abzulegen und sich näher damit zu beschäftigen. Immerhin ist es die am weitesten verbreitetste Sprache und sie wird uns noch viele Jahre erhalten bleiben.
Besser als Lisp (was ich als CommonLisp lesen würde) ist IMHO Scheme, was Reinheit und Klarheit der Konzepte angeht. Diese findet man (bis auf Continuations) auch in JavaScript wieder. Dazu kommt das Objektkonzept von Self, welches sich aus Smalltalk weiterentwickelt hat. Objective-C ist übrigens der Versuch, das Objektmodell von Smalltalk über C zu stülpen. War so eine "das kann doch nicht so schwer sein Idee" von Brad Cox, der 1986 Smalltalk sah, aber lieber C machen wollte und die Idee von Software-Komponenten verfolgte. Der größte Fehler war, die Blöcke zu ignorieren. Kaum 25 Jahre später hat Apple ihn dann korrigiert und eigenmächtig in ihre Version von C, C++ und Objective-C das Konzept von Blöcken integriert. Die selben Blöcke von Smalltalk (traditionell keine Closures wie bei Scheme) machen Ruby übrigens zu einer der mächtigsten Sprachen, was DSLs angeht.
Wo war ich? JavaScript! Ich denke, wo heutzutage C der portable Assembler (wer nicht muss, nutzt diese primitive Sprache doch hoffentlich nicht mehr freiwillig einfach nur so) wird in Zukunft JavaScript im Web-Umfeld diese Rolle übernehmen. 2012, wenn es nach Brendan Eich geht, kommt die nächste EcmaScript-Version, die ein paar weitere Probleme von JS beseitigt, etwa die standardmäßig globalen Variablen oder das Fehlen eines "doesNotUnderstand"-Catchalls. Wie auch immer, CoffeeScript ist ein schönes Beispiel für die JS-ist-portabler-Assembler-für-andere-Sprachen Ansatz.
Lua wäre übrigens anstelle von Python eine IMHO sehr schöne Alternative, wenn es um embedded Systems geht. Gibt es auch einen recht fixen JIT dafür.
Übrigens, Closures sind alles, was man braucht, um Objekte zu realisieren. Daher kann man in Scheme so schön als Fingerübung ein OO-System bauen. Andersherum ginge es auch, ist aber deutlich anstrengender. Wer den Schmerz fühlt, den man hat, wenn man in Java funktional programmieren will, weiß, was ich meine.
Und wer mal "verrückte" (im Sinne von genial) funktionale Programmierung in JavaScript sehen will, schaue sich (fab) (die Klammern gehören zum Produktnamen) (http://github.com/jed/fab) an, ein funktionales Webrahmenwerk für JavaScript.
Noch was: Wer Io mag (und damit eigentlich auch Self mögen müsste) schaue sich mal Ola Binis Ioke an. Das ist eine ziemlich interessante (experimentelle) Weiterentwicklung an.
Stefan
LanX hat geschrieben: 1) ich bin mir nicht ganz sicher was Python macht, wenn ich eine neue Variable binde ...gleich mal testen...
Code: Alles auswählen
>>> a="outer"
>>> def test():
... print a
... a="inner"
... print a
... return
...
>>> test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in test
UnboundLocalError: local variable 'a' referenced before assignment
@LanX: Ich sehe da die Vorteile: Es kann nicht passieren dass sich ein und der selbe Name zum Beispiel in einer Schleife in verschiedenen Durchläufen auf verschiedene Sichtbarkeitsbereiche bezieht. Und da der Compiler schon feststellt welche Namen lokal sind, wird schnellerer Code generiert. Lokale Variablen werden nämlich nicht in einem Dictionary gespeichert, sondern in einem Array und im Bytecode werden die lokalen Namen über einen festen Index referenziert.
Naja du argumentierst Python habe "richtige" Closures und dann sagste man solle OOP dafür nutzen...BlackJack hat geschrieben:Ich sehe ``nonlocal`` nicht als essentiell wichtig an. Python hat Klassen, man bekommt da also nichts, was man vorher nicht auch relativ einfach ausdrücken konnte. Klassen sind ein wichtiger Bestandteil von Python und nichts exotisches. Wenn man sie braucht, sollte man sie auch verwenden.
Es gibt halt ein riesiges funktionales Erbe aus der LISPischen ecke, wenn ich jedes Pattern erst halb auf Pythons OOP umschreiben muss, ist das nicht dasselbe wie wenn ich es direkt umsetzen kann. (wie z.B. in "Higher Order Perl" für Perl beschrieben.)
Das mag für dich nicht essentiell sein, mich schränkt es ein.
Und um den Kreis zu schließen JS bietet es vollständig an¹.
Mithilfe von Closures kannste dort die vermissten OOP Features mehr als kompensieren.
Dazu muss man sich auch in Closures wohlfühlen und denken können. Das meinte ich damit, dass ein reiner Python POV dann viele Möglichkeiten in JS übersieht.
1) zugegeben, das Fehlen von echten Blockscopes durch Curlies zwingt einen manchmal diesen Workaround mit anonymen Funktionen zu nutzen, die sofort in-place ausgeführt werden... auch etwas nervig.
Wenn man eine Methode (Funktion) eines Objektes beispielsweise an einen Event-Handler bindet verweist this nicht mehr auf das aktuelle Objekt aus dem diese Methode stammt sondern auf den Kontext des Event-Handlers. http://www.digital-web.com/articles/sco ... avascript/ Deswegen muss man dann das magische this vorher an eine lokale variable binden, um später noch auf das eigene Objekt zugreifen zu können. In Python wird das verhindert weil man auf normalem Wege nur an die „bound method“s rankommt. In anderen Sprachen (Java, C++) ergibt sich die Problematik auch nicht weil man sowieso nicht an den Funktionszeiger einer Methode rankommt ohne sich auf den Kopf zu stellen.LanX hat geschrieben:ich kann dir nicht folgen... Beispiel?Darii hat geschrieben: Das seltsame this, auf das man sich nicht verlassen kann (var self = this *hust*).
Ja. Java, C ... such dir was aus.hä??? ... gibts außer Python eine andere (nichtakademische) Sprache die per default localisiert und wo man explizit "nonlocal"-isiseren muss (wenn man denn kann)?
Wie sollte es denn sonst funktionieren? Erst ein bisschen mit der Globalen Variable a rumspielen, dann lokal machen und irgendwann später wieder zu einer globalen Variable machen. Wenn das nicht unübersichtlich wäre…"var" ist nervig weil es für den ganzen Scope - also auch vorhergehenden Code - gilt.¹
Deswegen bemängelt Crockfords JS-Lint es auch wenn du die var-Deklarationen nicht am Funktionsanfang machst.
Sprich, da es dafür in Javascript keine Sprachmittel gibt, denkt sich jeder ein eigenes System aus, um gemeinsames Verhalten in die Prototypen zu kopieren.Das ist IMHO ein fettes Plus! Ich bevorzuge - schon aus Designgründen - Mixins. Die Nützlichkeit der Mehrfachvererbung ist m.E. ein Mythos.
Das ist tatsächlich, wie es bei (korrekter) lexikografischer Bindung funktionieren sollte.Darii hat geschrieben:[Wie sollte es denn sonst funktionieren? Erst ein bisschen mit der Globalen Variable a rumspielen, dann lokal machen und irgendwann später wieder zu einer globalen Variable machen. Wenn das nicht unübersichtlich wäre…
Code: Alles auswählen
a = 1
def f():
print(a) # dies müsste eigentlich 1 sein, ist in Python aber ein Fehler
a = 2 # jetzt habe ich eine lokale Variable, die die globale überschattet
print(a) # dies müsste 2 sein
print(a) # dies ist 1
f() # müsste 1 und 2 ausgeben, bricht aber ab
print(a) # dies ist wieder 1
Code: Alles auswählen
(define a 1)
(define f (lambda ()
(print a) ; dies ist 1
(let ((a 2))
(print a)))) ; dies ist 2 (die Klammern machen die Bindung deutlicher)
(print a) ; gibt 1 aus
(f) ; gibt 1 und 2 aus
(print a) ; gibt 1 aus
Code: Alles auswählen
if (true) {
function f() { return 1; }
} else {
function f() { return 2; }
}
f();
Stefan
Das ist für Java falsch. Die Sprache verhält sich im Gegensatz zu Python so, wie bereits in meinem Scheme-Beispiel gezeigt und wie man's eigentlich erwarten würde. Für C kann ich's nicht sagen und habe keine Lust, das auszuprobieren. Ruby hingegen macht es wie Python und würde in dem folgenden Programm einen NameError liefern:Darii hat geschrieben:Ja. Java, C ... such dir was aus.hä??? ... gibts außer Python eine andere (nichtakademische) Sprache die per default localisiert und wo man explizit "nonlocal"-isiseren muss (wenn man denn kann)?
Code: Alles auswählen
a = 1
def f()
puts a
a = 2
puts a
end
f()
In einer früheren Lua-Version gab es IMHO mal die Notwendigkeit, etwas ähnliches wie "nonlocal" zu deklarieren (irgendwas mit upvals oder so), doch das man man schon vor Jahren zugunsten der gewohnten lexikografischen Bindung aufgegeben.
Stefan