[linux-l] RS-232 oder USB lesen mit (Schauder...) Java Os-unabhaengig

Oliver Bandel oliver at first.in-berlin.de
Do Sep 22 02:09:37 CEST 2005


On Wed, Sep 21, 2005 at 03:19:52PM +0200, Volker Grabsch wrote:
> On Tue, Sep 20, 2005 at 02:14:07AM +0200, Oliver Bandel wrote:
> > Soweit ich das seh', hanfdhabt Python Datentypen ziemlich lax.
> > Was ziemlich schade ist.
> 
> Da das in eine altbekannte Diskussion über statische vs. dynamische
> Typisierung ausartet, will ich einfach nur mal die Python-Sicht
> entgegen stellen, die übrigens für Smalltalk, Objective-C und alle
> anderen dynamisch typisierten Sprachen genauso gilt.
> 
> Welches der beiden Konzepte nun insgesamt besser ist, das ist sicher
> mehr eine Geschmacksfrage.

IMHO auch, aber nicht nur.


[...]
> Von daher ist die Begrifflichkeit "schon beim Compilieren" nichts-
> sagend, wenn man erst gar nicht compilieren braucht.

Das ist ja nun ein Argument rhetorischer Art.
Dann ist es eben Python, das compiliert.
Was, wenn der Code nicht compilierbar ist?
Was macht den Python dann?
Wie weisst Du das dann?

(BTW: Wie ist das implementiert? läuft der Compiler als Daemon?)


> 
> Abgesehen davon vereinigt eine gute IDE sowieso die beieden Schritte
> "Compilieren & Starten" auf Knopfdruck. Und das machst du ja sicher
> auch, oder?

IDE?

brrr.... als Kommandozeilen-Junkie und Klicki-Bunti-Aversionist
und "ick liebe meeen vim"-Mensch nehme ich natürlich keine IDE. :)


> 
> > Und das ist eine absolute Arbeitserleichterung.
> > Verkürzt die Debugging-Zeiten radikal. :)
> 
> Wieso? Wenn du nach dem Compilieren sowieso das Programm startest,
> kann es dir doch egal sein, wenn es erst beim Starten den Fehler
> ausgibt.

Nein. Wenn es ein Fehler ist, der erst zur Laufzeit auffällt und vielleich erst
nach 10.000 testfällen, weil es sich um eine komplexe Software handelt,
oder vielleicht erst dann auffällt, wenn der entsprechende Testfall beim Anwender
ausgetestet wird, dann ist das blöd gelaufen.


> Die Unterscheidung von "Fehlern zur Compilierungs-Zeit"
> und "Fehlern zur Laufzeit" macht keinen Sinn, wenn es keinen
> umständlichen extra Compilierungs-Schritt gibt.

?


> 
> > Code, der compiliert werden kann, ist schon deshalb recht solide.
> > Man kann nicht einfach irgendwas zusammen bauen und zur Laufzeit kracht's.
> > Fehlerhafter Code fällt dann schon auf, bevor er laufen könnte.
> 
> Okay, lass uns bitte von diesen Begriffen wegkommen, da sie keinen
> Vergleich zwischen Python und OCaml ermöglichen. Wenn das Programm
> beim Starten mit einem Fehler abbricht, ist das genauso gut, als
> wenn es beim Compilieren abbricht, weil man beides sowieso
> hintereinander macht.

Nein. Da bin ich vollkommen anderer Meinung.

Ich habe mal im bereich Softwaretest gearbeitet. Mit einem wirklich
beknackten Tool sollte ic C-Code checken.
Da mussten diverse Branches abgetestet werdn, oder mindestens soundsoviel Prozent.

Wenn man da so viele Wochen braucht, nur um den Code abzusichern,
inhaltlich aber auch bzgl. potentieller Abstürze, etc. dann ist das der
falsche Weg, wenn man die auf falshen typen beruhenden Fehler nicht schon
garnicht erst abtesten müsste.

Es ist besser, der Fehler fällt so früh wie möglich auf.
Um so weniger Zeit wird für's Suchen aufgewendet.



> 
> Kommen wir nun zu einem "echten" Unterschied, den du wahrscheinlich
> meinst: Es kann sein, dass zur Laufzeit nur in besimmten Situationen
> Typfehler auftauchen, die du bei einem Ocaml-Programm gleich zu anfang
> bemerkst, aber in Python erst beim gründlichen Austesten.

Oder erst der Anwender... vielleicht erst in Monaten oder Jahren.
Aber genau DANN, wenn es nicht sein soll. ;-(


> 
> Dies ist zwar tatsächlich ein Problem, aber kein allzu großes: Wenn
> du sauber programmieren willst, also dein Ziel stabiler Code ist
> (davon reden wir ja die ganze Zeit), dann wirst du ohnehin alles
> gründlich austesten müssen.

Selbstverständlich.


> Dann wirst du sowieso inkrementell
> Programmieren: Immer nur kleine Sachen ändern, und gleich austesten.
> Sobald es plötzlich einen Fehler gibt, kannst du seine Ursache sehr
> schnell eingrenzen

Aber nicht, wenn der Fehler einer eben gemachten Änderung womöglich erst
später auffällt. gerade wenn man nicht-funktionale Sprachen nutzt arbeitet
man ja viel mit Nebeneffekten.
Die Probleme können sich also heute anhäufen und später erst auf die Füsse
fallen!


> auf die Stelle, die du eben geändert hast. 100
> Zeilen Code umschreiben, und dann erst zu testen, ist kompletter
> Wahnsinn und viel zu riskant.

Kommt drauf an. :)
Wenn die Sprache einem dabei hilft, daß es auch mehr als zwei Zeilen
sein dürfen, die man ändert. ;-)


> 
> Aber was bedeutet "testen"? Testen heißt ja nicht bloß "Syntax-Check"

Eben, den macht der Compiler ja schon.
und wenn er die Typen auch gleich testet, um so besser!


> oder "Compilieren". Nein, gerade die inhaltlichen Sachen wollen getestet
> werden.

Selbstverständlich.

Und das schönste ist es doch, wenn man sich beim testen auch
auf die inhaltlihen Tests konzentrieren kann, statt auch noch
über andere mögliche Fehler nachdenken zu müssen (obwohl man sich daraus
auch einen Sport machen kann...;-)).


> Logikfehler, Denkfehler, Designfehler sind nämlich das wirkliche
> Problem, dem zu zuleibe rücken musst.

Das muß man doch sowieso machen, jedenfalls wenn man ernsthaft vor hat,
das Programm auch das machen zu lassen, was man von ihm erwartet.

Wenn man aber zusätzlich noch die Aufgaben des Compilers übernehmen muß,
dann ist das unnötige Mehrarbeit für den Programmierer.




[...]
> So gesehen sind Bugreports erstklassige extern
> entwickelte Testfälle.


Das nennt man: "Aus der Not eine Tugend machen" ;-)


> 
> Wenn man Testfälle aber sowieso benutzt, weil man ja sowieso Laufzeit-
> Tests braucht, dann wird beim Starten des Test-Programmes sowieo alles
> aufgerufen und alles abgearbeitet, was du programmiert hast.

Ob es alles ist, das laß ich mal dahin gestellt,
gehe aber davon aus, daß es höcht wahrscheinlich NICHT so ist.

Gerade Code mit vielen Bedingungen kann zu Problemen führen.
Wenn man dann vergisst, einen Fall abzufragen, dann ist das
möglicherweise genau der Fall, wo es probleme gibt - die aber
eben möglicherweise nicht gleich auffallen.

Wie schön, daß man bei OCaml mit dem Pattern-Matching
arbeiten kann. Wenn man einen Datentyp definiert und
mit einem Pattern-Match einzelne Fälle abtestet,
und dabei einen vergisst, dann schneisst der Compiler eine
Warnung raus:

===================================================================
first:~ oliver$ cat beispiel.ml 
type blah = Blih | Blah | Blubb | Untested_case

let string_of_type der_typ = match der_typ with
        Blih -> "Blih"
      | Blah -> "Blah"
      | Blubb -> "Blubb"
    
first:~ oliver$ ocamlc beispiel.ml 
File "beispiel.ml", line 3, characters 29-118:
Warning: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
Untested_case
first:~ oliver$ 
===================================================================

Finde ich geil, sowas. :)

kann man natürlich auch einen testcase für schreiben...
... aber was, wenn der den nicht abdeckt?
Es soll ja recht große SW-Projekte geben... :)


Aber ich schweife ab... ;-)




> Und dabei
> fallen Typfehler (d.h. bei Python: Aufrufen von nicht existierenden
> Methoden) automatisch mit auf.

Naja, und wenn die Methode nicht aufgerufen wird, weil der Testfall
noch nicht definiert ist?

Vor einer Weile habe ich mir mal Objective-C angeschaut.
Ist ja mit late binding extrem Flexibel. Das hat ja auch so seine
Vorteile. :)
Aber kaum hatte ich mal mit ObjC etwas herum probiert... und mich schon
gefreut, wie flexibel man damit ist, da kam schon genau SO ein Fehler.

Und DAS hat mich vielleicht genervt, ey!

Aber wirklich!

Nö, da lieb' ich doch den auf die Finger klopfenden OCaml Compiler. :)



> 
> Wenn du also sowieso inhaltliche Tests machst, hast du automatisch
> auch Typ-Tests.

Je früher ein Fehler gefunden wird, desto besser.

Habe lange genug in Perl gemacht.
Habe damals auch so geredet. Ich sehe das mittlerweile anders.

Bei Perl war ich dann froh, daß es "use strict;" gibt.
Aber das hilft auch nur bedingt, und manche Fehlermeldungen
sind echt strange. Naja.
Solange es nicht zwingende Gründe für so eine dynamische Sprache gibt
(und ich denke: die gibt es nur sehr selten), fährt man besser
mit so einem rigiden Aufpasser, der Syntax, typen, Vollständigkeiten
von Pattern-Matches abtestet.




> Und im "Ändern - Testen - Ändern - ..."-Zyklus
> werden dir Typfehler entsprechend auch "sofort" angezeigt, weil
> du ja nach jeder Änderung automatisch deine Testsuite drüberjagst.

Du gehst davon aus, daß Deine testsuite jeden Fehler findet.
Mit dieser Annahme begesht Du einen Fehler.

Das mag für die Heimprogrammierung genügen, und das mag auch
in der Industrie üblich sein, aber letztlich dennoch IMHO
fahrlässig.

Gut, daß Du nicht sicherheitskritische SW schreibst...
...obwohl: Selbst in den Industriezweigen arbeitet man
mit Sprachen und testtools, die unverantwortlich sind.


[...]
> Wenn dir Ocaml hingegen irgendwelche Sachen durch die Typisierung
> unnötig schwer macht

macht es nicht.
Warum sollte eine Sprache, die einem die Fehler früh aufzeigt,
einem bei tests das leben schwer machen?
Keines wegs.
Im gegenteil: ich kann mich bei der programmierung dann auf die
inhaltlichen Tests konzentrieren, und mir fallen nicht andauernd
irgendwelche casts und so'n Blödsinn auf die Füße!



> (ganz so dynamisch wie Python kann es ja kaum
> sein, oder?), und du nur dann eine Gegenleistung kriegst, wenn du
> auf inhaltliche Tests, also Laufzeit-Tests, "bequemerweise"
> verzichtest, dann ist das IMHO ein schlechter Deal.

Du verwechselst da was.

Warum sollte ich auf Tests verzichten, nur weil ich mich für eine
Sprache entschieden habe, die mir viele Tests schon vorab erledigt?



> 
> Wenn dir Ocaml ein sicheres Gefühl bei deinem Programm verleiht,
> ohne dass du Testfälle geschrieben hast, dann ist das eine trügerische
> Sicherheit und sehr gefährlich.

nu iß aber ma gut, ey!


> Stabile Software braucht
> in jedem Fall automatisierte Laufzeit-Tests! Das wird sich später
> 100fach wieder auszahlen, wenn du Bugs produzierst, die sich nur

Danke, danke, aber ich bin derjenige, der für seine Testgeilheit
meist immer erst für verrückt erklärt wurde, und hinterher am schnellsten
fertig war. :)

Und da ich solche tests für so notwendig halte, lasse ich die
grundlegenden tests (Syntax und Typ) den Compiler erledigen.

Ich meine... mal das ganze anders herum: Da man eh - wenn man es so wie
Du hier vertrittst - diverse tests durchführt, reicht ein Compiler,
der nicht nur auf typprüfung verzichtet, sondern auch die Syntax nicht
korrekt prüft.
Der übersetzt also irgendwie irgendwas, und wenn das programm dann
zur Laufzeit Müll fabriziert, weiß man ja, daß man wohl einen
syntaktischen Fehler in seinem Code hat.
Da man das eh mit zig testcases automatisiert abtestet, braucht der Compiler
auch nicht die Syntax nicht zu prüfen.
Es richt, wenn er korrekte Syntax voraussetzen kann und dann bei koirrekter Syntax
korrektes Compilat erzeugt.

Na, gehst Du auch so weit noch mit?



 
[...]
> Aber wiegesagt, das ist die "pythonische Sicht", und diese Argumentation

Nein, das ist DEINE Sicht der Argumentation.


[...]
> Ich weiß nicht, ob eine statisch typisierte Sprache jemals so flexibel
> sein kann wie z.B. Ruby oder Python.

Ist ja die Frage, ob man diese Flexibilität wirklich benötigt, oder sie nicht nur
aus mangelnder Programmierdisziplin gerne in kauf nimmt, weil einem
die viell. recht häufigen Typ-Probleme niht immer vor die Nase gehalten werden.

MetaOCaml gibt es ja auch noch... habe ich mir aber noch nicht angeschaut.

Ich hätte ja bei Perl bleiben können. Anfangs dachte ich auch immer:
Naja, OCaml mag viell. für größere projekte sinnvoll sein, aber nicht für
kleinere Sachn, denn die kann man in Perl schneller zusammen hacken.

Naja, auch das sehe ichheute anders. :)

perl nehme ich nur noch sehr selten, seit ich OCaml nutze.
So ungefähr, wie ich C kaum noch nahm, seit ich Perl-te.

Der vermeintliche Vorteil dieser Sprachen ist aber oftmals ihr Nachteil.

Mag sein, diese sind für manche Anwendungen doch besser geeignet,
aber IMHO muß die Anwendung solcher Sprachen (mit ihrer erhöhten
Bug-Wahrscheinlichkeit, die sie einbringen)  ausserordentlich begründet
werden, zumindest, wenn man wirlich solide Software schreiben will
und nicht nur herum daddeln.

[...]
> > > Aber das würde ich dir einfach mal empfehlen: Lerne Python,
> > > das ist nicht weiter wild, und sollte nicht allzu lange dauern.
> > Naja, wenn ich mal die Muße habe ;-)
> 
> > > Zumal
> > > Python weit genug verbretiet ist, sodass du damit in absehbarer
> > > wahrscheinlich sowieso zu tun haben wirst.
> > Das ist natürlich eine Überlegung wert.
> 
> > > Wenn du das getan hast, würde
> > > mich deine Meinung zum Vergleich von OCaml und Python sehr interessieren
> > > ... nicht wegen der Einarbeitungszeit, sondern ob sich diese
> > > Einarbeitungszeit danach auch auszahlt.
> > Da ich OCaml schon kann, wird sich Python nur dann auszahlen, wenn
> > jemand dafür bezahlt, daß ich das benutze.
> > Ansonsten lohnt es nicht.
> 
> Achso? Nur für Geld würde sich das lohnen? Also, das wäre für mich der
> letzte Grund für so eine Entscheidung. Es sei denn natürlich, ich werde
> direkt nach Arbeitsstunden bezahlt. ;-)
> 
> Aber was wäre, wenn du mit Python schneller zum Ergebnis kommst, also
> es dir Enticklungs - *Zeit* erpart. Würde es sich dann nicht auszahlen?

Wenn es einen Anwendungsfdall gibt, bei dem das der Fall ist,
mag Python sich anzushauen auch noch Sinn machen.

Nachdem "die dynamischen Verlockungen" von Perl mir das Hirn verdreht hatten,
dachte ich auch, das muß alles so sein. Erst, als ich mit OCaml dann mal
was anderes sehen durfte (war ein harter Kampf, am Anfang, wenn einem
ständig irgendwelche Typfehler gemeldet werden) und mich da auch dran gewöhnt
hatte, und als ich dann sah, wie viel besser man damit komplexe Probleme
lösen kann (während einem Perl mit seiner Abwasser-Syntax das Hirn verknotet),
wußte ich, daß das so viel besser ist.
OK, Python ist, nach allem, was ich mitbekommen hab, wesentlich aufgeräumter als Perl.
Aber sicherlich nicht so wie OCaml.
Und warum soll ich auf die Sachen, die ich bei OCaml jetzt schon habe,
bei Python noch drauf warten? (Du schriebst da mal was zu zip() und
irgendwelchen neuen features, die nicht extra Listen erzeugen.
=> List.iter sage ich nur. :)


> 
> Das weiß ich natürlich nicht. Aber abgesehen von eventuellen Vorteilen
> bei der Typisierung ist OCaml ja ziemlich festgefahren auf funktionale
> Konzepte.

Du redest da gerade Müll. (Fehlt wohl ein Testcase in Deiner Testsuite ;-))


Das schöne an OCaml ist, daß es neben funktionaler Programmierung auch imperative
Programmierung und objektorientierte Programmierung erlaubt.
Ist also gerade NICHT festgefahren auf funktionale Programmierung.
Das ist es doch gerade, was programmieren in OCaml so angenehm macht:
Löst man das Problem am besten funktional, macht man es so.
Löst man das Problem am besten imperativ, macht man es so.
Löst man das Problem am besten objektorientiert, macht man es so.
Alles andere wäre Dogmatismus. Und obwohl OCaml da so viele Möglichkeiten
bietet, ist es schön streng beim Prüfen des Codes.

OCaml ist da also sehr "freizügig". ;-)
Wenn das bisher zu wenig hervor kam, liegt es daran, daß ich von den anderen
Sachen nicht so viel sprach. Unter anderem deswegen, weil vieles, wofür
i.A. OO eingesetzt wird, in OCaml OO garnicht notwendig ist, und man es
mit der funktionalen Programmierung/Higher-Order Functions und
dem Modulsystem alles erschlagen kann.

Und weil das so mächtig ist - nur deswegen habe ich es so hervor gehoben!


> In Bereich Software-Design hättest du in Python wesentlich
> bessere Karten, IMHO.

IMHO nicht.

Oder fährt man mit Assembler im bereich Software-Design NOCH besser? :->


Ciao,
   Oliver



Mehr Informationen über die Mailingliste linux-l