Es gibt also erst gar keine Verwirrung oder Streitigkeiten über die Reihenfolge
Punkt vor Strich lernt man doch schon in der Grundschule. Da sollte doch keine großen Verwirrungen mehr auftreten? Ansonsten einfach eine Klammer mehr als eine zu wenig setzen, das werden immernoch sehr viel weniger sein und damit übersichtlicher als mit einer "Add" Methode.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Spaßig wird es halt, wenn die Operatoren nichts mit arithmetischer Addition / Multiplikation zu tun haben. Da erwartet man dann (wenn man erstmal in dem Mindset dessen, was die Operatoren des Objektes mathematisch tun, drin ist) eventuell andere Reihenfolgen als die, die die Programmiersprache vorgibt.
viele Grüße, Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Man kann diverse Sachen mit C-artigen for Schleifen machen, die in Pascal nur mit mehreren Schleifen moeglich sind.
Gut. Welche Sachen kannst du mit einer c-artigen for-Schleife machen, die mit einer while-Schleife unmöglich sind?
Zitat:
Nein, das würde man nicht, sondern CrossProduct und DotProduct oder XPD, DP3 und MUL oder so etwas
CrossProduct. Möglich. Aber wenn der Programmierer Wert auf Lesbarkeit legt, wird er auch mit operatoren nicht irgendeinen Unfug machen. DotProduct. Hoffentlich nicht. Weil wenn DotProduct einen Vector zurückgibt ist das schlimmer, als wenn dort * steht, und du beim ersren Mal nachsehen musst, was das heißt. XPD, DP3, MUL: auch nicht besser lesbar als *
Zitat:
Zitat:
Zitat:
Eigentlich war C seiner Zeit weit voraus, denn in modernen Skriptsprachen sind untypisierte Parameter wieder "in".
generic != void*
(und int als default für ausgelassene Typbezeichner hat erst recht nichts damit zu tun. weder mit untypisiert noch mit modernen Sprachen)
Wie ich bereits sagte, das ist Legacy-Kram. Früher war halt das Hardware-Word der einzige Datentyp den es gab (mal abgesehen von Spezialfällen). Floating Point und Single-Byte kamen halt erst später dazu. Ich finde es aber durchaus bemerkenswert das wir heute wieder solche alten Sachen wiederentdecken und feststellen das es hier und dort cool ist.
Da das offensichtlich zu schwer zu verstehen war: 1) In den meisten modernen Sprachen bedeuten weggelassene Typbezeichner, dass es sich um generics handelt. 2) untypisierte Parameter sind void* generic != void*
3) die weggelassenen Typbezeichner als generics sind älter als c. die gibt es bereits in lisp (1956), und das hatte zwar nicht extrem viele typen, aber mehr als einen allemal 4) die wurden auch nicht wiederentdeckt, die gab es die ganze Zeit über 5) structs und arrays/listen gab es auch schon lange
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
sharkman hat geschrieben:
Da das offensichtlich zu schwer zu verstehen war: 1) In den meisten modernen Sprachen bedeuten weggelassene Typbezeichner, dass es sich um generics handelt.
Vorsicht mit solchen generalisierungen. Hier einige Beispiele: rust, Go, (etwas älter) Haskell. Rust verweist auch auf OCaml und SML, mit denen ich aber noch nichts gemacht habe.
Unklar ist mir auch, was du überhaupt mit generics meinst. Als generics kenne ich nur die templates von Pascal und die "templates" (doppelte Anführungszeichen um anzudeuten, dass es wirklich was ganz anderes ist) von C#. Eventuell heißt auch das Java-Zeug so.
sharkman hat geschrieben:
2) untypisierte Parameter sind void* generic != void*
Wo sind untypisierte Parameter void*? In C? Da sind sie int, nicht void*. So viel type safty hat C gerade noch, dass es dich int nicht einfach ohne cast dereferenzieren lässt .
viele Grüße, Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
OpenglerF hat geschrieben:
Zitat:
Es gibt also erst gar keine Verwirrung oder Streitigkeiten über die Reihenfolge
Punkt vor Strich lernt man doch schon in der Grundschule. Da sollte doch keine großen Verwirrungen mehr auftreten? Ansonsten einfach eine Klammer mehr als eine zu wenig setzen, das werden immernoch sehr viel weniger sein und damit übersichtlicher als mit einer "Add" Methode.
Gut das du mir zustimmst und der Rest der Aussage?
sharkman hat geschrieben:
Zitat:
Man kann diverse Sachen mit C-artigen for Schleifen machen, die in Pascal nur mit mehreren Schleifen moeglich sind.
Gut. Welche Sachen kannst du mit einer c-artigen for-Schleife machen, die mit einer while-Schleife unmöglich sind?
For Schleifen sind für vorhersagbare Wiederholungen mit Initialisierung, Test und "Schritt" gedacht, While-Schleifen hingegen nur für einen Test (also von-bis vs solange). Das ist bei beiden genau das gleiche Prinzip, nur das die generalisierte Form von C für Pascal gar keinen Sinn ergeben würde. Pascal kann nämlich nur einen Ausdruck für den Test machen aber nicht für Initialisierung oder "Schritt", dafür wären extra Statements notwendig. Daher bleiben nur diese spezialisierten Formen.
sharkman hat geschrieben:
Zitat:
Nein, das würde man nicht, sondern CrossProduct und DotProduct oder XPD, DP3 und MUL oder so etwas
CrossProduct. Möglich. Aber wenn der Programmierer Wert auf Lesbarkeit legt, wird er auch mit operatoren nicht irgendeinen Unfug machen. DotProduct. Hoffentlich nicht. Weil wenn DotProduct einen Vector zurückgibt ist das schlimmer, als wenn dort * steht, und du beim ersren Mal nachsehen musst, was das heißt. XPD, DP3, MUL: auch nicht besser lesbar als *
Mhh ja ODER man macht es wie Id-Tech und implementiert genau das gleiche wie Blender, Latex und co. ODER man macht es so wie Unity und MS und verzichtet, natürlich rein zufällig, komplett darauf....
sharkman hat geschrieben:
1) In den meisten modernen Sprachen bedeuten weggelassene Typbezeichner, dass es sich um generics handelt.
Nein, das bedeutet das du den Typen implizit und eindeutig Herleiten kannst. Generics/Templates hingegen bedeuten einfach nur das man den gleichen Code für unterschiedliche Typen verwenden kann. Früher war das aber beides nicht der Fall, da es nur eine Limitierung der Hardware war (siehe z.B. "Development of C Language").
sharkman hat geschrieben:
2) untypisierte Parameter sind void* generic != void*
Ähhh keine Ahnung was du damit sagen willst, aber man kann void pointer tatsächlich als eine Art generic verstehen. De Facto gibt es aber keine Generics wie du sie zum Beispiel aus Java oder C# kennst, denn C benutzt ein schwaches Typensystem. (siehe 5).
Du kannst natürlich auch wie hier die Generics vom Präprozessor benutzen....
sharkman hat geschrieben:
3) die weggelassenen Typbezeichner als generics sind älter als c. die gibt es bereits in lisp (1956), und das hatte zwar nicht extrem viele typen, aber mehr als einen allemal
Nein siehe 1. und Lisp ist sowas von überhaupt nicht was du denkst. Als Typen gibt es tatsächlich nur Word als Zeiger auf Lambda oder Hardware Funktion. Das was du meinst sind in Wahrheit nur Funktion. Selbst einfache Zahlen sind nur Funktionen die nacheinander die Atomaren Funktion 0-9 aufrufen. Und deshalb kannst du Lisp auch gleichzeitig Ausdrucken und Lesen
sharkman hat geschrieben:
4) die wurden auch nicht wiederentdeckt, die gab es die ganze Zeit über
Ich machs mal zusammen mit 5, vielleicht wird es dann deutlich
sharkman hat geschrieben:
5) structs und arrays/listen gab es auch schon lange
Jein, das ist bei älteren Sprachen wie C etwas anders, denn Sie haben nicht die gleiche Bedeutung wie etwa bei C++ oder C#. Dazu währen zusätzliche Funktionen während der Runtime oder im Compiler nötig. Tatsächlich geben diese Typen nur an wie deine Funktionen auf etwas zugreifen aber nicht was man damit macht und man kann sie daher ohne Probleme austauschen. Besonders deutlich sieht man das bei Funktionen die "void"-Pointer benutzen, denn egal welche Art von Struct du benutzt memcpy funktioniert immer. Aber dafür kann zum Beispiel eine statische Struct unter C niemals durch so etwas wie einen Constructor initialisiert werden. Oder wie float und int andere Ergebnisse bei division liefern. Es ist also eher ein Mittelding zwischen typenlos, wie bei Lisp, und komplett starken Typen wie bei C++.
Noch deutlicher wird das wenn du mal den funktionalen Bruder hinzunimmst. Bei so etwas wie Objective-C ist der Typ selbst eher eine Variable. Daher kann man eine statische Methode in der Grundklasse implementieren und diese hat dann immer noch genau den gleichen Effekt bei den Unterklassen hat. String::Alloc ist hier also das gleiche wie Object::alloc nur das String und Object die Parameter für alloc sind...
Gut das du mir zustimmst und der Rest der Aussage?
Der Rest der Aussage scheint sich mir darauf gestützt gewesen zu sein, dass du der Meinung bist, dass Methoden einfacher zu verstehen und deutlicher wären. Ich stimme hier aber nicht zu und würde glatt das Gegenteil behaupten. Mein Gegenargument dazu bezog sich auf die kompaktere Schreibweise, mit der man eigentlich aufgewachsen sein sollte. Es sollte offensichtlich besonders im Code im grafischen und mathematischen Kontext, um den es mir zentral geht, wesentlich einfacher mit klassischen Operatoren zu erfassen und zu verstehen sein. Ich würde auch mal den Vorschlag machen an der Stelle wenigstens konsequent zu sein und auch die Operatoren von den internen Operatoren entfernen. Angeblich ist das ja weniger missverständlich.
Code:
//Variante 1:
float Result =Math.Add(Math.Sqrt(Math.Add(Math.Multiply(X, X), Math.Multiply(Y, Y))), Math.Sqrt(Math.Add(Math.Multiply(A, A), Math.Multiply(B, B))));
//Variante 2:
float Result =Math.Sqrt(X.Multiply(X).Add(Y.Multiply(Y))).Add(Math.Sqrt(A.Multiply(A).Add(B.Multiply(B))));
//Anstatt...
float Result = sqrt(X * X + Y * Y)+ sqrt(A * A + B * B);
Zitat:
ODER man macht es so wie Unity und MS und verzichtet, natürlich rein zufällig, komplett darauf....
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
Ok.... ich habe dir gesagt das ich persönlich es praktisch finde und auch benutze. Jedenfalls dann wenn es eindeutig ist, das meinte ich mit zweischneidigen Schwert.
Der ganze andere Kram geht darum das es nicht-eindeutigen Kram wie Vector-Multiplikation (für Mathe), Castings, Shift- und Bitoperation und co. gibt. Programmierer streiten sich darüber weil:
Und es ist nicht eindeutig weil unterschiedliche Entwickler und Projekte unterschiedlicher Meinung bei genau diesen Thema sind Mathematiker sagt es eindeutig weil Zeichen eindeutig, der Rest ist falsch und Schmorrt in der Hölle. Haskell-Mensch nimmt das was ein Zeichen spart (ohne Scheiß die Leuten sollten als Verschlüsselung eingesetzt werden). Und Programmierer nimmt component-wise weil SIMD und GPU. Und bestimmte Experten überladen '%' oder '^' fürs Kreuzprodukt.... oder rotieren mit Shift und implementieren gleichzeitig Bit-Operationen.... Und der nächste macht irgendwelchen Impliziten-Mist über den Rückgabewert...
Was ist jetzt also besser? Garnicht, Irgendwas, Das was geht oder soviel man will?
Und btw. ich meinte DirectX und kein kleines der Dritte-Welt Projekt die es anders machen.
Und btw. ich meinte DirectX und kein kleines der Dritte-Welt Projekt die es anders machen.
DirectX selbst ist eine OO API, ist aber nicht an C++ gebunden und besitzt so keine Möglichkeit zum Ausdrücken von Operatorüberladung. Außerdem enthält Direct3D selbst, ähnlich wie OpenGL, gar keine Vektorfunktionen. Das was du verlinkt hast, ist eigentlich inzwischen tatsächlich ein veraltetes dritte Welt Projekt. Managed DirectX war ein Wrapper mit dem das alte DirectX 9 von Dot.Net 1.1 aus verwendet werden konnte. Das neuere Binding, Xna, das ich verlinkt habe(aber aktuelle wohl auch wieder eingestellt wird), verwendet Operatorüberladung. So ist es auch mit anderen neueren Technologien von Microsoft, wie eben zum Beispiel Simd und WPF.
Zitat:
Und bestimmte Experten überladen '%' oder '^' fürs Kreuzprodukt.... oder rotieren mit Shift und implementieren gleichzeitig Bit-Operationen....
Das sollte man in der Tat nicht machen, weil es mit der ursprünglichen Intention des Operators nichts zu tun hat. Hier sind wir uns also einig. Ich finde nur, dass es schlechte Namen, um eine Sache auszudrücken, auch ganz ohne Operatorenüberladungen gibt.
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
OpenglerF hat geschrieben:
Zitat:
Und btw. ich meinte DirectX und kein kleines der Dritte-Welt Projekt die es anders machen.
DirectX selbst ist eine OO API, ist aber nicht an C++ gebunden und besitzt so keine Möglichkeit zum Ausdrücken von Operatorüberladung. Außerdem enthält Direct3D selbst, ähnlich wie OpenGL, gar keine Vektorfunktionen. Das was du verlinkt hast, ist eigentlich inzwischen tatsächlich ein veraltetes dritte Welt Projekt. Managed DirectX war ein Wrapper mit dem das alte DirectX 9 von Dot.Net 1.1 aus verwendet werden konnte. Das neuere Binding, Xna, das ich verlinkt habe(aber aktuelle wohl auch wieder eingestellt wird), verwendet Operatorüberladung. So ist es auch mit anderen neueren Technologien von Microsoft, wie eben zum Beispiel Simd und WPF.
Oh ich denke jetzt haben wir es gleich Die XNA-Version die du angesprochen hast, wurde tatsaechlich von den neueren DirectX Versionen uebernommen und weiterentwickelt. Dort findest du immer noch Vector-Funktionen und Klassen mit Operator-Overloading. Allerdings nur fuer C++11 und nur als Extension (also einmal using namespace). Interessant wird es erst wenn man sich dagegen einmal die Vector3D Klasse im Media3D von WPF anschaut. Diese entspricht naemlich immer noch der alten DirectX Version, es gibt also dort keinen Overload fuer Vector * Vector, sondern nur Vector * Skalar (btw. "op_Multiply" und co. sind die Overloads, das findest du auch bei XNA so beschrieben). Noch verrueckter wird es wenn du dir mal sehr alte Versionen von XNA-Anschaust (z.B. bei Mech Commander 2). Dort wurde Vector * Vector mit Punktprodukt, statt Component-Wise angegeben.
Ich denke aber das laesst sich sehr leicht dadurch erklaeren, das man hier halt nur auf aktuelle Hardware statt generischer Loesung setzt. Und dann ist es wie gesagt relativ eindeutig.... jedenfalls wenn man nicht gerade beide Versionen braucht oder Code Pflegen/ Portieren muss:)
OpenglerF hat geschrieben:
Zitat:
Und bestimmte Experten überladen '%' oder '^' fürs Kreuzprodukt.... oder rotieren mit Shift und implementieren gleichzeitig Bit-Operationen....
Das sollte man in der Tat nicht machen, weil es mit der ursprünglichen Intention des Operators nichts zu tun hat. Hier sind wir uns also einig. Ich finde nur, dass es schlechte Namen, um eine Sache auszudrücken, auch ganz ohne Operatorenüberladungen gibt.
Die XNA-Version die du angesprochen hast, wurde tatsaechlich von den neueren DirectX Versionen uebernommen und weiterentwickelt. Dort findest du immer noch Vector-Funktionen und Klassen mit Operator-Overloading. Allerdings nur fuer C++11 und nur als Extension (also einmal using namespace).
Was hat C++11 mit XNA zu tun? XNA ist ein Managed Wrapper (bzw. teilweise Engine) um DirectX von C# aus zu nutzen.
Zitat:
einmal die Vector3D Klasse im Media3D von WPF anschaut. Diese entspricht naemlich immer noch der alten DirectX Version, es gibt also dort keinen Overload fuer Vector * Vector, sondern nur Vector * Skalar (btw. "op_Multiply" und co.
Ich verstehe gerade nicht, was die alte DirectX Version mit WPF zu tun hat.
Bei der 2D-Variante ist es auch nicht optimal, dort ist es als Punktprodukt definiert. Meiner persönlichen Erfahrung nach braucht man in der 2D und 3D Grafik das komponentenweise Produkt aber viel häufiger, als Kreuz- und Punktprodukt zusammen. Und dafür scheint es überhaupt keine Funktion zu geben. Wie man sieht ist man sich hier nicht ganz einig. Ich denke allerdings, dass das Problem auch ohne Operatorüberladung bestehen würde. Das man ein komponentenweises Produkt "Multiply" nennt anstatt dem längeren "ComponentwiseMultiply" was wieder genauso Potential für Verwirrung besitzt, wenn man aus unterschiedlichen Hintergründen kommt. Das lässt sich meiner Meinung nach kaum vermeiden und Operatorüberladung scheint mir wenig Schuld daran zu tragen.
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
OpenglerF hat geschrieben:
Zitat:
Die XNA-Version die du angesprochen hast, wurde tatsaechlich von den neueren DirectX Versionen uebernommen und weiterentwickelt. Dort findest du immer noch Vector-Funktionen und Klassen mit Operator-Overloading. Allerdings nur fuer C++11 und nur als Extension (also einmal using namespace).
Was hat C++11 mit XNA zu tun? XNA ist ein Managed Wrapper (bzw. teilweise Engine) um DirectX von C# aus zu nutzen.
Ähm jein, ich glaube du verwechselt das jetzt mit dem XNA-Framework, was nur ein Teil davon ist. Andere Teile wie z.B. XNA-Build waren zum Beispiel schon vor .NET und C# im Einsatz. Hier speziell meinte ich aber die XNA Math Library. Diese war Teil vom DirectX SDK und der direkte Nachfolger ist jetzt DirectXMath.
OpenglerF hat geschrieben:
Ich verstehe gerade nicht, was die alte DirectX Version mit WPF zu tun hat.
Oh das war im Bezug auf diesen speziellen Operator gemeint.
OpenglerF hat geschrieben:
Bei der 2D-Variante ist es auch nicht optimal, dort ist es als Punktprodukt definiert. Meiner persönlichen Erfahrung nach braucht man in der 2D und 3D Grafik das komponentenweise Produkt aber viel häufiger, als Kreuz- und Punktprodukt zusammen. Und dafür scheint es überhaupt keine Funktion zu geben. Wie man sieht ist man sich hier nicht ganz einig. Ich denke allerdings, dass das Problem auch ohne Operatorüberladung bestehen würde. Das man ein komponentenweises Produkt "Multiply" nennt anstatt dem längeren "ComponentwiseMultiply" was wieder genauso Potential für Verwirrung besitzt, wenn man aus unterschiedlichen Hintergründen kommt. Das lässt sich meiner Meinung nach kaum vermeiden und Operatorüberladung scheint mir wenig Schuld daran zu tragen.
Naja du könntest es HadamardProduct, Elementwise oder, wenn die Sprache coole Zeichen erlaubt, den ⊙ Operator benutzen (Gott das wäre so cool wenn das irgendwo gehen würde...) übrigens ist das Teil gerade im kartesischen Koordinatensystem eigentlich "falscher" als Skalar oder Kreuzprodukt....
Unklar ist mir auch, was du überhaupt mit generics meinst.
In pascal/java bedeutet “generic” 1) dass du das Ding mit verschiedenen Typen benutzen kannst 2) infolgedessen, dass ein Funktions/operator -name jeweils die Version meint, die der Typ braucht. (möglicherweise in java bereits durch OO gewährleistet) Dasselbe passiert in zumindest einem von deinen “Gegenbeispielen” (nämlich Haskell), wenn du die Funktion nicht explizit durch Typ-annotationen einschränkst, auch wenn das dort nicht “generic” heißt (da du es nicht hinschreiben musst -> braucht keinen Namen). Wenn auch sicher anders umgesetzt, passiert dasselbe in dynamisch typisierten Sprachen (mit dem Unterschied, dass dort Typ-annotationen teilweise nicht möglich sind)
Zitat:
Wo sind untypisierte Parameter void*? In C? Da sind sie int, nicht void*.
Wenn sie int sind, sind sie nicht untypisiert, denn dann haben sie einen Typen (nämlich int), auch wenn der nicht dortsteht.
Zitat:
Zitat:
Gut. Welche Sachen kannst du mit einer c-artigen for-Schleife machen, die mit einer while-Schleife unmöglich sind?
For Schleifen sind für vorhersagbare Wiederholungen mit Initialisierung, Test und "Schritt" gedacht, While-Schleifen hingegen nur für einen Test (also von-bis vs solange)
Das ist aber keine Antwort auf die Frage unter der es steht. Mal konkret ausgedrückt:
Code:
for (init;cond;step) {
block;
}
==
{
init;
while (cond) {
block;
step;
}
}
(übrigens habe ich NICHT gefordert, dass for-schleifen abgeschafft gehören, nur gesagt, dass ich nicht verstehe, was an c-for-schleifen so viel besser sein soll als an anderen for-schleifen, da sie offenbar für genau denselben Anwendungsfall gedacht scheinen. Ich persönlich bevorzuge übrigens python-for-schleifen, weil sie für den häufigsten Anwendungsfall sehr simpel sind (weniger Aufwand beim Schreiben/Lesen), ohne aber für etwas unbrauchbar zu werden, das nicht super von der while-schleife abgedeckt ist)
Zitat:
Nein, das bedeutet das du den Typen implizit und eindeutig Herleiten kannst. Generics/Templates hingegen bedeuten einfach nur das man den gleichen Code für unterschiedliche Typen verwenden kann.
Wo kann zB python einen typen implizit und eindeutig herleiten? Das Gegenteil ist der Fall: Typen existieren überhaupt nur zur Laufzeit, Funktionen können grundsätzlich mit jedem Typen aufgerufen werden (und werfen dann ggf einen Fehler). und was das herleiten angeht: da kommen dann (haskell) so typen raus wie (Num a => a) (lies: funktioniert für alle Typen die die Num-class (class bedeutet in haskell interface) implementieren)
Zitat:
aber man kann void pointer tatsächlich als eine Art generic verstehen.
Mit ziemlichen Einschränkungen, aber ja, sie werden für das gleiche benutzt. Jetzt wird mir auch klar, wieso niemand verstehen konnte worauf ich hinaus wollte: (dass die “untypisierten” parameter, die angeblich in modernen Sprachen wieder in sind, meist super typisiert sind).
Zitat:
De Facto gibt es aber keine Generics wie du sie zum Beispiel aus Java oder C# kennst, denn C benutzt ein schwaches Typensystem.
??? Und weil c schwach typisiert ist, kann es in keiner Sprache Generics geben? Aber in java/c# schon? Entweder lese ich das falsch, oder es ergibt keinen Sinn.
Zitat:
Als Typen gibt es tatsächlich nur Word als Zeiger auf Lambda oder Hardware Funktion. Das was du meinst sind in Wahrheit nur Funktion.
?Du meinst das in etwa so wie: “in python ist in wahrheit alles ein typ, weil zur Laufzeit Typ-information angehängt ist”? Zwar ist das Lisp, das ich kenne (common lisp), etwas neuer als 1956, aber ich schätze, dass auch das damalige Lisp bereits a)rechnen b)text manipulieren konnte (egal, wie das intern repräsintiert wurde); oder zumindest zwei unterschiedliche Sachen. Ist das korrekt? Wenn so, dann Typen, zumindest im python-sinn.
Wenn so (und da bin ich mir ziemlich sicher), war es möglich, eine Funktion zu schreiben, die mit Zahlen eine Sache und mit Text eine andere machte, wovon beide sinnvoll waren (so wie heutzutage + in vielen Sprachen)? Und diese Funktion dann aus einer anderen aufzurufen, welche dann sowohl mit Zahlen als auch mit Text etwas sinnvolles macht, ohne explizit einen Unterschied zu machen?
Zitat:
Und deshalb kannst du Lisp auch gleichzeitig Ausdrucken und Lesen
?? Was genau würde mich bei anderen Sprachen denn daran hindern, sie gleichzeitig auszudrucken und zu lesen? (und wofür sollte ich (?den code?) überhaupt ausdrucken wollen?)
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
Nein darum geht es an dieser Stelle nicht. ready for some Brainfuck?:
Es ist voellig Egal ob man Variablen Deklarieren kann usw.. Der wesentliche Unterschied im Vergleich zu zum Beispiel Python ist das C ausschliesslich auf sog. ausdrucksorientierte Kontrollstrukturen setzt. Bei Python hingegen haben wir zum Beispiel bei der For-Schleife eine bereichsbasierte Kontrollstruktur. Das bedeutet Python braucht hier einen zusaetzlichen Mechanismus um die Eigenschaften fuer einen Bereich mitzuliefern, ansonsten funktioniert es einfach nicht. Und genau das gleiche gilt auch fuer Generics.
sharkman hat geschrieben:
?Du meinst das in etwa so wie: “in python ist in wahrheit alles ein typ, weil zur Laufzeit Typ-information angehängt ist”?
Viele OOP-Sprachen schleppen dazu diese Eigenschaften die ganze Zeit ueber mit sich. Das ist leider zwingend Erforderlich um zum Beispiel der Polymorphie gerecht zu werden und fuehrt leider auch zu Problemen waehrend der Laufzeit. Denkt zum Beispiel mal daran was passiert wenn in C++ die V-Table nicht initialisiert wird. Dafuer kann man aber sehr leicht ganze Hierarchien von Verhalten herstellen. Ein VW und ein Porsche koennen also beiden Fahren weil der gemeinsame Grundtyp Auto es vorgibt.
Funktionale Sprachen wie Haskell verfolgen aber einen anderen Ansatz. Hier gibt es keinen Status der so etwas das den Typen festhalten koennte. Stattdessen bedient man sich der Kategorientheorie. Damit kann man aus dem was eine Funktion macht einen abstrakten oder konkreten Typen implizit herleiten. Das funktioniert deshalb weil Funktionen und Daten im Prinzip das gleiche sind. Du kannst ja zum Beispiel eine Funktion auch als Lookup-Table implementieren.
Wenn das interessiert: hier ist ein einfacher Einstieg in die Welt der funktionalen Sprachen.
Es ist also tatsaechlich so
sharkman hat geschrieben:
dass die “untypisierten” parameter, die angeblich in modernen Sprachen wieder in sind, meist super typisiert sind
und natuerlich auch Variablen und Funktionen Man "versteckt" also diese grundlegenden Prinzipien nur vor dem Programmierer.
Sprachen wie C und Lisp hingegen gehen anders an die Problematik heran. In der Lisp-Familie geht man davon aus das Daten und Funktion nicht nur im Prinzip sondern auch tatsaechlich das Gleiche sind. Wenn man also nun den Quelltext “(+ 1 2 3 4)” hat, dann wird tatsaechlich auch ein “String” mit genau diesen Werten erzeugt. Und dieser “String” kann entweder ausgefuehrt oder ausgeschrieben oder sonste was werden
Bei C hingegen versucht so nahe wie moeglich am eigentlichen System zu bleiben. Es geht also nur darum den Programm und Datenfluss optimal zu steuern. Wenn man also einer Variable zusaetzliche Eigenschaften, wie etwa eine V-Table oder einen Typen, mitgeben wuerde, dann modifiziert man unbewusst die Daten und das Verhalten. Genausowenig kann man diese Eigenschaften wie bei Haskell herleiten, denn im Gegensatz zu diesen Sprachen will man ja seinen Programmfluss fuer zum Beispiel einen globalen Status optimieren.
Es wuerde also gar keinen Sinn ergeben diese “modernen” Elemente anzubieten. Dafuer kann man sich ein Superset wie Objective-C oder Common Lisp besorgen was dann diese Geschichten fuer einen “generiert” und gut ist. Oder man implementiert es selbst
@End Beide deiner Codes sind leider falsch. Beim Ersten, hast du einfach ein ";" dazugedichtet. Was soll der Compiler nach dem 3. Semikolon machen? Es sind nur drei Anweisungen in der "for"-Schleife definiert. Was allerdings tatsächlich geht, ist, einzelne Anweisungen mit dem Komma-Operator zu verbinden. Im ersten Statement der Schleife hast du den Typ zweimal angegeben, auch das geht leider nicht. Das geht leider auch nicht, auch wenn es praktisch wäre, wenn man auch Variablen unterschiedlichen Typs dort definieren könnte. Die beiden Bedingungen sind übrigens eigentlich sinnlos, weil beide immer das gleiche Ergebnis liefern.
Code:
for(int x =0, y =0; x <100; x++, y--)
Der zweite Code macht mir auch keinen Sinn. Du führst am Ende jeder Iteration "loadnextchar()" aus und dividierst dessen Rückgabe durch den aktuellen Schleifenzähler. Das Ergebnis wird dann verworfen. Aus deinem Text schließe ich, dass du auch hier möglicherweise ein "," setzen wolltest.
Code:
for(int x =0; x >10; loadnextchar(), x++)
Auch wenn ich Ersteres in seltenen Fällen ganz nützlich finde, wenn ich mit mehreren Iteratoren arbeite. Ansonsten muss ich leider eingestehen, dass das Feature leicht zu umschreiben ist und es schnell unübersichtlich wird.
EDIT: Noch zwei Anmerkungen: Für statische Polymorphi benötigt man gar keine Typinformationen zur Laufzeit, die Calls werden zur Compilezeit aufgelöst. In C++ gibt es auch bei dynamischer Polymorphie sonst sehr wenig Typinfo. Wenn man nur RTTI als Typinformation versteht, kann man sogar sagen, dass gänige Polymorphie in C++ ohne Typinformationen zur Laufzeit auskommt.
Bei der Typisierung gibt es auch noch eine weitere Möglichkeit, das "auto", wie es in C++ heißt. (In C# heißt es "var") Das behält 100%ige Typsicherheit zur Compilezeit und keinen Overhead. Der Typ einer solchen Variable wird einfach beim Kompilieren ermittelt, abhänig davon welchen Typ die Expression hat, die ihm anfangs zugewiesen wird.
Mitglieder in diesem Forum: 0 Mitglieder und 13 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.