Schaltjahr: "sauberer" Code

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
paedubucher
Beiträge: 856
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von paedubucher » 08.11.2016 17:09:02

@hikaru
Das sieht nur so besch...eiden aus, wenn man nicht eingeloggt ist. Die Werbe-Zwischenposts verschwinden nach dem Einloggen ebenfalls.

@Lord_Carlos
Die Lösung mit isCenturyLeap finde ich nicht schlecht, zumal man da nicht drei Variablennamen erfinden muss, sondern eben nur einen Begriff ("century leap"). Damit könnte ich leben.

Das "year & 3" wäre wirklich ein Griff ins Klo, wenn das tatsächlich so im Code steht. Dass der Compiler so etwas erzeugt, kann ich aber gut nachvollziehen. Aber dass das aus dem De-Compiler kommen soll, scheint mir unwahrscheinlich, da JavaDoc und alles weitere auch dabei ist.

Ich habe auch schon bei einigen Java-Programmierern festgestellt, dass Code sehr schnell als "hässlich" bezeichnet wird, wenn darin viele Operatoren vorkommen. Man versucht dann, dass auf Methoden zu verteilen. Zur Klarheit trägt das aber nur bedingt bei.

Nachtrag: In Clean Code wird es so gelöst:

Code: Alles auswählen

public static boolean isLeapYear(int year) {
	boolean fourth = year % 4 == 0;
	boolean hundredth = year % 100 == 0;
	boolean fourHundredth = year % 400 == 0;
	return fourth && (!hundreth || fourHundredth);
}
Die Variablennamen sind sinnvoll gewählt, finde ich. Auch auf das isDividable wird verzichtet. Von daher halte ich das für eine gute Lösung.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
TRex
Moderator
Beiträge: 8071
Registriert: 23.11.2006 12:23:54
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: KA

Re: Schaltjahr: "sauberer" Code

Beitrag von TRex » 21.11.2016 12:32:21

Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 21.11.2016 14:30:51

Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 27.11.2016 21:15:27

paedubucher hat geschrieben: Nachtrag: In Clean Code wird es so gelöst:

Code: Alles auswählen

public static boolean isLeapYear(int year) {
	boolean fourth = year % 4 == 0;
	boolean hundredth = year % 100 == 0;
	boolean fourHundredth = year % 400 == 0;
	return fourth && (!hundreth || fourHundredth);
}
Auch ich will noch was nachtragen:

In ``The C Programming Language'' (2nd Ed.) von Kernighan und Ritchie ist auf Seite 41 folgender Code zu finden:

Code: Alles auswählen

if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
	printf("%d is a leap year\n", year);
else
	printf("%d is not a leap year\n", year);
Auf Seite 111 wird die gleiche Codezeile aufgegriffen, aber mit fehlendem Whitespace um den Modulo-Operator und ohne Klammern:

Code: Alles auswählen

leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
(Evtl. ist die Anpassung der kurzen Zeilenlaenge im Buch geschuldet.)


In ``The Practice of Programming'' von Kernighan und Pike -- dem IMO besseren Zwilling von ``Clean Code'' -- steht auf Seite 7, im Abschnitt zu runden Klammern:
Even if parenthesis aren't necessary, they can help if the grouping is hard to grasp at first glance. This code doesn't need parenthesis:

Code: Alles auswählen

leap_year = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
but they make it easier to understand:

Code: Alles auswählen

leap_year = ((y%4 == 0) && (y%100 != 0)) || (y%400 == 0);
We also removed some of the blanks: grouping the operands of higher-precedence operators helps the reader to see the structure more quickly.
(Dass hier `y' statt `year' verwendet wird ist vermutlich der Zeilenlaenge geschuldet; dafuer wurde aber vorne `leap_year' statt nur `leap' verwendet, was das `y' dadurch verstaendlich macht.)

(Edit: Interessanterweise klammern Kernighan und Co. vorne, waehrend alle anderen hinten klammern.)


Um aber auch noch was ganz Abgefahrenes aus dem alten Unix-Umfeld zu bieten, hier ein Stueck Code aus Heirloom cal(1):

Code: Alles auswählen

        switch((jan1(y+1)+7-d)%7) {

        /*
         *      non-leap year
         */
        case 1:
                mon[2] = 28;
                break;

        /*
         *      1752
         */
        default:
                mon[9] = 19;
                break;

        /*
         *      leap year
         */
        case 2:
                ;
        }
Da war jemand super-clever und wollte das auch zeigen. Solchen Code will man nicht bearbeiten muessen.

(Ich sollte wohl mal zurueck verfolgen wo diese konkrete Implementierung herkommt ... wuerde auf Kalifornien tippen ;-) denn in der Codebasis von mmh, meinem Softwareprojekt, gab es auch so Zeugs, und der Code stammt auch aus Kalifornien. :-D )
Use ed once in a while!

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 27.11.2016 22:00:04

Meillo hat geschrieben:hier ein Stueck Code aus Heirloom cal(1):
Wie ist das Makro bzw. die Funktion jan1() implementiert?

Benutzeravatar
schorsch_76
Beiträge: 2543
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: Schaltjahr: "sauberer" Code

Beitrag von schorsch_76 » 27.11.2016 22:30:06

Etwas Offtopic, aber im Bezug zum Compiler Optimizer

Understanding Compiler Optimization - Chandler Carruth - Opening Keynote Meeting C++ 2015
https://youtu.be/FnGCDLhaxKU?t=23m30s

Das ist zwar von der Cppcon, aber Optimizer arbeiten auf der gemeinsamen Zwischensprache welche auch für C verwendet wird.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 28.11.2016 05:21:56

owl102 hat geschrieben: Wie ist das Makro bzw. die Funktion jan1() implementiert?
http://heirloom.cvs.sourceforge.net/vie ... iew=markup
Entschuldige, dass ich den Code nicht gleich verlinkt habe.
Use ed once in a while!

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Schaltjahr: "sauberer" Code

Beitrag von seep » 30.11.2016 08:57:01

Schöner Thread! :)

Erinnert mich an meine ersten Schritte in C, als ich für ein Projekt mal eine for-Schleife mit wenig, aber selbsterklärendem Getöse im Schleifeninneren programmiert hatte, was ein sehr erfahrener Programmierer sah und direkt in das for() hineinprogrammiert hatte. 5 Zeilen Code gespart, dafür 5 Zeilen Kommentar geschrieben, der erklärte, was die Schleife eigentlich macht.
paedubucher hat geschrieben:

Code: Alles auswählen

public static boolean isLeap(int year) {
	return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
Das ist doch für jeden Programmierer, der zumindest den Modulo-Operator kennt, sofort begreifbar. Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.

Zur besseren Lesbarkeit drösel ich solche Konstrukte lieber in einzelne if-Statements auf, kommentiere die und lasse den Compiler die möglichen Optimierungen vornehmen.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 30.11.2016 09:36:05

seep hat geschrieben: Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.
Wie wuerdest du das machen? Sind dir Klammern lieber? Und was denkst du ueber die Frage, ob sich durch die damit eingefuehrte Negation (d.h. mit Ausrufezeichen ist es ganzzahlig teilbar) die natuerliche Verstaendlichkeit des Ausdrucks erschwert?

Ich frage auch deshalb, weil ich bei dieser Art von Optimierung schonmal auf die Schnauze gefallen bin: http://marmaro.de/rem/texte/fizzbuzz
Use ed once in a while!

Benutzeravatar
MSfree
Beiträge: 10755
Registriert: 25.09.2007 19:59:30

Re: Schaltjahr: "sauberer" Code

Beitrag von MSfree » 30.11.2016 09:39:08

seep hat geschrieben:Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.
Moderne Compiler generieren dann aber gerne Warnungen.

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Schaltjahr: "sauberer" Code

Beitrag von seep » 30.11.2016 10:43:09

Meillo hat geschrieben:
seep hat geschrieben: Als C-Programmierer würde man da noch die überflüssigen "== 0" und "!= 0" wegoptimieren.
Wie wuerdest du das machen? Sind dir Klammern lieber? Und was denkst du ueber die Frage, ob sich durch die damit eingefuehrte Negation (d.h. mit Ausrufezeichen ist es ganzzahlig teilbar) die natuerliche Verstaendlichkeit des Ausdrucks erschwert?
Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben. Klammern sind mir in jedem Fall sehr lieb, ich setze lieber zuviele als zuwenige, sprich lieber ein "(year % 4 == 0) && (...)" als ein "year % 4 == 0 && ...". Und bevor man es dem Compiler überlässt, ob && höher priorisiert wird als || dann halt noch einmal mehr klammern.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 30.11.2016 11:18:44

seep hat geschrieben: Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben.
Meiner Meinung nach ist halt gerade das die entscheidende Frage: Ist es nur eine Sache der Vorliebe oder ist eine der beiden Varianten tatsaechlich besser? Natuerlich ist diese Frage schwer konkret zu packen und fundierte und verstaendliche Ergebnisse erreicht man auch nicht so einfach (meist laeuft es auf das Sammeln von Beispielen bei denen bestimmte Konstrukte zu Bugs gefuehrt haben oder missverstanden wurden raus), aber das ist halt eines meiner wichtigsten Interessensgebiete in der Informatik. ;-) ... und ich bin nicht alleine damit: http://www.paulgraham.com/taste.html

<Nachtrag>
Das ist der hierfuer relevanteste Ausschnitt des Aufsatzes:
If there is such a thing as beauty, we need to be able to recognize it. We need good taste to make good things. Instead of treating beauty as an airy abstraction, to be either blathered about or avoided depending on how one feels about airy abstractions, let's try considering it as a practical question: how do you make good stuff?



If you mention taste nowadays, a lot of people will tell you that "taste is subjective." They believe this because it really feels that way to them. When they like something, they have no idea why. It could be because it's beautiful, or because their mother had one, or because they saw a movie star with one in a magazine, or because they know it's expensive. Their thoughts are a tangle of unexamined impulses.

Most of us are encouraged, as children, to leave this tangle unexamined. If you make fun of your little brother for coloring people green in his coloring book, your mother is likely to tell you something like "you like to do it your way and he likes to do it his way."

Your mother at this point is not trying to teach you important truths about aesthetics. She's trying to get the two of you to stop bickering.

Like many of the half-truths adults tell us, this one contradicts other things they tell us. After dinning into you that taste is merely a matter of personal preference, they take you to the museum and tell you that you should pay attention because Leonardo is a great artist.

What goes through the kid's head at this point? What does he think "great artist" means? After having been told for years that everyone just likes to do things their own way, he is unlikely to head straight for the conclusion that a great artist is someone whose work is better than the others'. A far more likely theory, in his Ptolemaic model of the universe, is that a great artist is something that's good for you, like broccoli, because someone said so in a book.



Saying that taste is just personal preference is a good way to prevent disputes. The trouble is, it's not true. You feel this when you start to design things.
</Nachtrag>

Und bevor man es dem Compiler überlässt, ob && höher priorisiert wird als || dann halt noch einmal mehr klammern.
Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann und dass in diesen Fallen Klammern meist oder vielleicht auch immer trotzdem sinnvoll sind, dem kann ich durchaus zustimmen.
Use ed once in a while!

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Schaltjahr: "sauberer" Code

Beitrag von seep » 30.11.2016 14:58:10

Meillo hat geschrieben:
seep hat geschrieben: Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben.
Meiner Meinung nach ist halt gerade das die entscheidende Frage: Ist es nur eine Sache der Vorliebe oder ist eine der beiden Varianten tatsaechlich besser?
Aus meiner Sicht eine Frage der Perspektive bzw. Fragestellung. Frage ich mich "beim Teilen ist der Rest 0?", werde ich "== 0" bevorzugen. Frage ich mich "kein Rest?", wähle ich das !(...)". Ob der Compiler da in einem Fall besser optimieren kann und ein paar Taktzyklen zu sparen hilft, interessiert mich erst dann, wenn es auch darauf ankommt.
Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann und dass in diesen Fallen Klammern meist oder vielleicht auch immer trotzdem sinnvoll sind, dem kann ich durchaus zustimmen.
Das ist soweit korrekt. Und wenn man von morgens bis abends über das Jahr hinweg ausschließlich in einer Sprache programmiere, dann weiß ich das auch. Ich weiß aber auch, dass die Punkt-vor-Strichrechnung gilt und erwische immer zielsicher immer genau den Taschenrechner, der aus 1+2x3 trotzdem eine 9 errechnet, will sagen, was weiß ich denn, ob Perl und PHP und Python und Python und Java und hassenichgesehen && und || in all ihren Releases genauso wie C abarbeiten oder nicht. Klammern können da für Klarheit schaffen, nicht nur optisch. :D

Noch kurz ein Buchtipp, ich habe mich köstlich amüsiert, echt lesenswert, und ich habe mich oft ertappt aber auch bestätigt gesehen: https://www.amazon.de/Weniger-schlecht- ... 3897215675

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 01.12.2016 09:44:00

seep hat geschrieben:
Meillo hat geschrieben:
seep hat geschrieben: Ob ein "year % 4 == 0" lesbarer ist als ein "!(year % 4)" sei mal dahingestellt, da wird jeder seine eigenen Vorlieben haben.
Meiner Meinung nach ist halt gerade das die entscheidende Frage: Ist es nur eine Sache der Vorliebe oder ist eine der beiden Varianten tatsaechlich besser?
Aus meiner Sicht eine Frage der Perspektive bzw. Fragestellung. Frage ich mich "beim Teilen ist der Rest 0?", werde ich "== 0" bevorzugen. Frage ich mich "kein Rest?", wähle ich das !(...)".
Danke fuer die Erklaerung deiner Sichtweise. Die finde ich sehr wichtig, weil sie verstaendlich macht *wieso* du das so schreibst und dass du das als Idiom ansiehst.
Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann und dass in diesen Fallen Klammern meist oder vielleicht auch immer trotzdem sinnvoll sind, dem kann ich durchaus zustimmen.
Das ist soweit korrekt. Und wenn man von morgens bis abends über das Jahr hinweg ausschließlich in einer Sprache programmiere, dann weiß ich das auch. Ich weiß aber auch, dass die Punkt-vor-Strichrechnung gilt und erwische immer zielsicher immer genau den Taschenrechner, der aus 1+2x3 trotzdem eine 9 errechnet, will sagen, was weiß ich denn, ob Perl und PHP und Python und Python und Java und hassenichgesehen && und || in all ihren Releases genauso wie C abarbeiten oder nicht. Klammern können da für Klarheit schaffen, nicht nur optisch. :D
Ich verstehe was du meinst, habe aber eine etwas andere Sicht darauf. Ich vermute, dass alle Sprachen, die die Operatoren && und || kennen, ihnen die gleiche Praezendez-Reihenfolge geben wie in C. (Zumindest in Python, Perl, PHP, Ruby, Java, C++ und JS habe ich es geprueft. Gegenbeispiele willkommen!) Und das ist auch gut so, denn es ist ein Zeichen von Konsistenz und Verlaesslichkeit. Gerade diese Aspekte sind mir wichtig. Gute Sprachen bieten diese Verlaesslichkeit, die man auch Principle of Least Surprise (POLS) nennen kann. Vielleicht mache ich es mir ja auch nur einfach bzw. bin ich in der gluecklichen Lage, hauptsaechlich Sprachen zu verwenden, die qualitativ so gut sind, dass man sich auf sie verlassen kann. ;-)

Insgesamt finde ich gerade das einen der wichtigsten Aspekte von Programmiersprachen (und von Software allgemein), dass der Programmierer bzw. Anwender weiss, auf was er sich verlassen kann und auf was nicht. Wenn Systeme es schaffen, dies zu vermitteln, dann haben sie viel erreicht.
Noch kurz ein Buchtipp, ich habe mich köstlich amüsiert, echt lesenswert, und ich habe mich oft ertappt aber auch bestätigt gesehen: https://www.amazon.de/Weniger-schlecht- ... 3897215675
Ich kenne das Buch nicht (und mir persoenlich ist es auch etwas zu neu ;-) ), aber der Titel hoert sich so an als ob darin manch sinnvoller Gedanke zu finden sein koennte. Ob es nun eines der besseren Buecher zu diesem Thema ist oder nicht, wichtig ist, dass es ein Buch zum Thema Code-Qualitaet und Entwicklungs-Qualitaet ist, und Literatur in diese Richtung sollte jeder Programmierer lesen.
Use ed once in a while!

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 02.12.2016 09:17:46

Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann
Widerspruch! Doch! Ich setze unbedingt voraus, daß jemand, der in C kodiert, sein Handwerkszeug beherrscht.

Und: Wer beim Kodieren unsicher ist, soll eben klammern. Wer beim Lesen unsicher ist, soll nachlesen und was dazulernen.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 02.12.2016 11:06:19

owl102 hat geschrieben:
Meillo hat geschrieben:Wenn ich mir erlauben darf, hier zu korrigieren: ``ob'' ist das falsche Wort, denn (zumindest bei C) ist klar definiert *dass* && eine hoehere Praezedenz hat als ||. Dass man dieses Wissen aber nicht unbedingt voraussetzen kann
Widerspruch! Doch! Ich setze unbedingt voraus, daß jemand, der in C kodiert, sein Handwerkszeug beherrscht.

Und: Wer beim Kodieren unsicher ist, soll eben klammern. Wer beim Lesen unsicher ist, soll nachlesen und was dazulernen.
Widersprichst du dir da nun nicht selbst? Erst sagst du, dass man dieses Wissen voraussetzen sollte, dann sagst du aber, dass diejenigen, die das Wissen nicht haben, einfach klammern sollen. Also wird das Wissen doch nicht vorausgesetzt ...


Ich denke ebenfalls, dass man seine Arbeitsmittel verstehen sollte, aber die Frage ist, wie weit das geht. Muss man als C-Programmierer das von TRex verlinkte Codekonstrukt verstehen koennen? Muss man Functionpointer verstanden haben um C-Programmierer sein zu koennen? Muss man wissen, dass <= staerker bindet als ==? Muss man die C-Grammatik so gut verstanden haben dass er sie auswendig reproduzieren kann? Muss ein C-Programmierer Harbison und Steeles C Reference Manual gelesen haben? Alle diese Fragen wuerde ich verneinen. Wie weit man voraussetzen kann und sollte dass C verstanden wird, haengt IMO vom jeweiligen Projekt ab. In mancher Codebasis koennte ich && und || ohne Klammern schreiben in anderer nicht ... wobei ich im Normalfall doch in beiden Faellen klammern wuerde, weil das dann besser lesbar ist. Normalerweise wuerde ich sagen, dass C-Programmierer die Beziehung von Arrays und Pointern in C verstanden haben sollten und somit die Ausdruecke a[4] und *(a+4) gleichwertig behandeln, aber ist das *notwendig* um C programmieren zu koennen? Denn wenn es so waere, dann duerfte ich sicher kein Python, Perl oder Java programmieren ... und doch tue ich es hin und wieder ... mit einigermassen grossem Erfolg.

... oder wolltest du nur darauf anspielen, dass gerade C ein zu scharfes Messer ist als dass man mit ihm arbeiten sollte, wenn man es nicht beherrscht?
Zuletzt geändert von Meillo am 03.12.2016 21:59:33, insgesamt 1-mal geändert.
Grund: Link repariert
Use ed once in a while!

Benutzeravatar
TRex
Moderator
Beiträge: 8071
Registriert: 23.11.2006 12:23:54
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: KA

Re: Schaltjahr: "sauberer" Code

Beitrag von TRex » 02.12.2016 18:33:14

Meillo hat geschrieben:Muss man Functionpointer verstanden haben um C-Programmierer sein zu koennen?
Klares Ja. Wer das nicht will, sollte zu einer anderen Sprache greifen, die die Anforderungen erfüllt und das mit den Pointern abstrahiert (java, python, ...) oder anders löst (rust).
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 02.12.2016 21:31:36

Meillo hat geschrieben:Widersprichst du dir da nun nicht selbst? Erst sagst du, dass man dieses Wissen voraussetzen sollte, dann sagst du aber, dass diejenigen, die das Wissen nicht haben, einfach klammern sollen. Also wird das Wissen doch nicht vorausgesetzt ...
Ich hatte dich so verstanden, daß man als wissender auch lieber Klammern setzen sollte, damit es auch unwissende verstehen. Hier gibt es ein klares "nein" von mir, aber vielleicht hatte ich dich auch flasch verstanden...
Muss man als C-Programmierer das von TRex verlinkte Codekonstrukt verstehen koennen?
Kann ich nicht sagen, der der Link falsch ist ;-)
Muss man Functionpointer verstanden haben um C-Programmierer sein zu koennen?
Auch von mir ein klares Ja.

C ist ja nun wirklich übersichtlich, den K&R sollte man IMHO sowohl gelesen haben als auch beherrschen, zumindest wenn man Anwendungen entwickelt, die auf die Menschheit losgelassen werden.
Muss ein C-Programmierer Harbison und Steeles C Reference Manual gelesen haben?
Da ich das nicht getan habe, sage ich einfach mal ganz egozentisch Nein :wink: (Ich habe das aber mal zum Anlaß genommen, mir es zu kaufen. Wobei ich aber eigentlich der Meinung bin, daß es keinen Grund gibt, in C statt C++ zu entwickeln, solange es auch einen C++ Compiler für die Zielplatform gibt.)
Normalerweise wuerde ich sagen, dass C-Programmierer die Beziehung von Arrays und Pointern in C verstanden haben sollten und somit die Ausdruecke a[4] und *(a+4) gleichwertig behandeln, aber ist das *notwendig* um C programmieren zu koennen?
Hier IMHO ein dickes Ja.
Denn wenn es so waere, dann duerfte ich sicher kein Python, Perl oder Java programmieren ... und doch tue ich es hin und wieder ... mit einigermassen grossem Erfolg.
Die Frage ist für mich immer der Kontext. Ich programmiere zum Beispiel auch ein paar Shell-Scripte für mich, aber auch um meine eigenen administrative Arbeit (die auch andere betrifft) zu erleichtern. Darf ich das? Wenn diese Scripte Bestandteil einer Linux-Distribution werden sollen, dann definitiv nein. Ebenfalls ein nein, wenn es sich um ein kommerzielles Produkt handelt. In diesem Falle muß aber nur ich den Schaden ertragen, also ja.
... oder wolltest du nur darauf anspielen, dass gerade C ein zu scharfes Messer ist als dass man mit ihm arbeiten sollte, wenn man es nicht beherrscht?
Nein. Ich bin der Meinung, daß dies für jede Programmiersprache gilt. Wie sage ich es am besten... Es gibt da ein bekanntes Meme:

https://imgur.com/gallery/G4cy8en

Wenn man nicht verstanden hat, warum (bzw. daß, schließlich ist es per Definition so) *(x+4) gleich x[4] (oder 4[x]) ist, dann befindet man sich IMHO im unteren Teil des Memes. Da, wo auch ich mich befinde, wenn ich Shell-Scripte schreibe.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 02.12.2016 23:45:51

TRex hat geschrieben:
Meillo hat geschrieben:Muss man Functionpointer verstanden haben um C-Programmierer sein zu koennen?
Klares Ja. Wer das nicht will, sollte zu einer anderen Sprache greifen, die die Anforderungen erfüllt und das mit den Pointern abstrahiert (java, python, ...) oder anders löst (rust).
Nicht dass wir uns missverstehen, ich meinte Function-Pointer nicht ``normale'' Pointer. Zweitere braucht man unbedingt, aber Function-Pointer habe ich in den lezten Jahren nur ein paar Mal gebraucht. Je nach Art der Anwendung kann man bestimmt einige Jahre C programmieren ohne mit ihnen in Kontakt zu kommen.


owl102 hat geschrieben:
Meillo hat geschrieben:Widersprichst du dir da nun nicht selbst? Erst sagst du, dass man dieses Wissen voraussetzen sollte, dann sagst du aber, dass diejenigen, die das Wissen nicht haben, einfach klammern sollen. Also wird das Wissen doch nicht vorausgesetzt ...
Ich hatte dich so verstanden, daß man als wissender auch lieber Klammern setzen sollte, damit es auch unwissende verstehen. Hier gibt es ein klares "nein" von mir, aber vielleicht hatte ich dich auch flasch verstanden...
Ich wuerde Klammern setzen, weil das im Normalfall lesbarer ist. Aber ich kann mir auch vorstellen Klammern zu setzen, wenn ich glaube, dass der Code dann wahrscheinlicher korrekt verstanden wird. Wenn ich annehme, dass die Leser nicht wissen wie && und || zueinander stehen, dann wuerde ich versuchen zu klammern, wenn nichts ein wichtigerer Aspekt dagegen spricht.

Worum geht es denn? Darum, dass der Code das Richtige tut und dass er auch noch das Richtige tut nachdem jemand anderes ihn neu angefasst hat. Was dem zutraeglich ist, das wuerde ich tun.

Muss man Functionpointer verstanden haben um C-Programmierer sein zu koennen?
Auch von mir ein klares Ja.
Vielleicht sollten wir zu diesem Thema mal einen kleinen Test unter den C-Programmierern starten. ;-)

C ist ja nun wirklich übersichtlich, den K&R sollte man IMHO sowohl gelesen haben als auch beherrschen, zumindest wenn man Anwendungen entwickelt, die auf die Menschheit losgelassen werden.
Es ist halt immer schwierig die Grenze zu finden, wo beherrschen beginnt. Ich sehe mich selbst als C-Entwickler. Ich programmiere freie Software, die eingesetzt wird. Ich tue das seit mehreren aber noch nicht allzu vielen Jahren. Ich habe an der Uni Uebungen zu C geleitet. Ich habe den K&R mehrfach gelesen und weite Teile von Harbison & Steele, zudem mehrere andere Buecher zu C. Man koennte wohl annehmen, dass ich C beherrschen wuerde ... aber bei setjmp(3) und longjmp(3) beispielsweise schwimme ich total, und auch wenn ich Functionpointer verwenden und mir alles herleiten kann, so habe ich von ``beherrschen'' doch ein anderes Bild im Kopf.

Ebenso bei der Shellprogrammierung. Es koennte hier im Forum der Eindruck entstanden sein, dass ich mich recht gut damit auskennen wuerde, aber wenn ich mir ueberlege an wievielen Stellen ich mich nicht sattelfest fuehle, dann kann ich kaum von ``beherrschen'' sprechen. Und sh ist ebenfalls keine grosse Sprache.

Da frage ich mich halt, wer diese Personen sein sollen, die ihre Sprachen ``beherrschen''. Bislang habe ich kaum welche kennengelernt ...

Ich bin der Meinung, daß dies für jede Programmiersprache gilt. Wie sage ich es am besten... Es gibt da ein bekanntes Meme:

https://imgur.com/gallery/G4cy8en
Wie sehr ich dir da zustimme: Diese Situation ist schrecklich! ... leider aber viel zu oft die Realitaet. Aber lassen wir das Extrem beiseite und nehmen die Programmierer die so mitten drin stehen. Die sind doch der Normalfall ueberall da draussen. Das hat nunmal auch Auswirkungen auf meinen Programmierstil, zumindest sollte es das haben, wenn ich ein erfolgreiches Projekt anstrebe, und das tue ich.

Du siehst, es gibt da zwei Sichten, die ich habe. Wuenschen wuerde ich es mir auch so wie du es formulierst, aber es scheint mir etwas zu idealistisch und letztlich kontraproduktiv zu sein, das zu erfordern. ... wobei, wenn ich diese, meine Worte, an einem anderen Tag wieder lesen werde, dann werde ich mir nur denken, dass man so nie voran kommt, wenn man staendig an der Schlechtheit der Realitaet haengt statt zu fordern was noetig ist, naemlich die Sprachen die man spricht zu beherrschen (und wenn die Sprachen zu komplex sind, dann muss man eben simplere fordern). Tja. ;-)
Use ed once in a while!

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 03.12.2016 07:56:43

Meillo hat geschrieben:Worum geht es denn? Darum, dass der Code das Richtige tut und dass er auch noch das Richtige tut nachdem jemand anderes ihn neu angefasst hat. Was dem zutraeglich ist, das wuerde ich tun.
Grundsätzlich stimme ich dir zu. "Dass der Code auch noch das Richtige tut, nachdem jemand anderes ihn angefasst hat", trifft ja auch auf einen selber zu, wenn man nach x Jahren mal wieder in den Code schaut und eine Anpassung machen muß. Aber: Ich würde niemals auf Unwissenheit der Basics anderer Rücksicht nehmen, und ich tendiere dazu, eher wenig als viel zu klammern. (In diesem konkreten Falle würde ich auch klammern, aber aus anderen Gründen.)
Es ist halt immer schwierig die Grenze zu finden, wo beherrschen beginnt.
Für mich ist es weniger eine Grenze als eine Einstellungssache. (BTW: Beherrsche ich die Sprache "Deutsch"? Wenn ich mir so manchen Schriftsteller im Vergleich anschaue, kann ich da nur "nein" antworten.)

Wenn man schwammig wird, kann man entweder herumlavieren oder das zum Anlaß nehmen, sich ein paar Abende hinzusetzen und zu lesen. Wenn man einen Fehler gemacht hat, kann man entweder "Shit happens!" denken und so weiter machen wie bisher, oder aber man kann sich überlegen, wie man den Fehler hätte entweder vermeiden oder zumindest Mechanismen hätte einbauen können, um ihn schneller zu finden. Wenn man einen Fehler nicht versteht, kann man entweder herumbasteln bis es geht (und hat damit beide Teile des Memes erfüllt), oder aber man kann dies zum Anlaß nehmen, etwas zu lernen, indem man sich solange auf den Hosenboden setzt, bis man den Fehler verstanden hat. (Ersteres ist IMHO grob fahrlässig, denn solche Fehler tauchen oft in anderer Form (oder auf anderen Rechnern bzw. Konstellationen) wieder auf, bevorzugt bei einem Kunden in Australien. Leider wird in der Praxis oft so gearbeitet.)
aber bei setjmp(3) und longjmp(3) beispielsweise schwimme ich total
Merkwürdig, eigentlich ist das doch recht einfach (und brutal). (Vielleicht hilft es mir, daß ich einige Jahre in Assembler programmiert habe!?) Wäre ich hier schwammig, würde ich mir wohl die Implementierung von setjmp() und longjmp() anschauen.

Damit beantwortet sich (zumindest aus meiner Sicht) auch deine Frage nach dem Codebeispiel von TRex: Obwohl ich es nicht kenne (Link wäre nett!), kann ich die Frage beantworten: Muß man es verstehen? Ja! Nach meiner Ansicht versteht man es entweder schon, oder aber man schaut es sich solange an und liest ggf. nach, bis man es versteht. "Verstehe ich nicht und brauche ich auch nicht zu verstehen" ist IMHO die falsche Einstellung.
und auch wenn ich Functionpointer verwenden
Zurück zu denen. Muß man die beherrschen? Dann ist man wieder bei deiner obrigen Frage, ab wann "Beherrschen" gilt. Muß man die kennen und verstanden haben, auch wenn man die noch nie gebraucht hat? IMHO ja. Denn ich halte es für falsch, Basics erst dann zu lernen, wenn man merkt, daß man sie braucht. Wer nur grüne Legosteine kennt, wird auch nur mit grünen Legosteinen basteln, bis es offensichtlich wird, daß man ein Problem hat. Wer aber das Buch "Basteln mit Lego" gelesen hat, der wird anders (und effektiver und fehlerfreier) basteln.

Ein konkretes Beispiel: Jemand kennt das Wort "static" bei Memberfunktionen in C++ nicht. Nun hat er aber eine C-API, wo er eine Rücksprungadresse angeben muß. Eine Memberfunktion kann er nicht nehmen, "static" kennt er hier nicht, also nimmt er eine globale Funktion. Die wiederum ruft Memberfunktionen seiner Klasse auf, also muß er alles, was hier benutzt wird, "public" machen. Schlechter Code aus Unwissenheit. Nächstes Beispiel: Forward Declarations sind unbekannt. Es kommt eine Situation, wo man das gut gebrauchen könnte, weil man ungünstige Abhängigkeiten von Header-Dateien hat. Was macht man? Zum Beispiel eine Datei "alles.h" basteln, wo man alles in der "richtigen" Reinfolge lädt, so daß es klappt? (So daß der Code zwar nun compiliert, man aber nicht mehr sehen kann, welche Module die einzelnen Module denn tatsächlich verwenden.) Oder man lagert Sachen in eine neue Header-Datei aus? (Oder...) Auch hier wieder: Schlechter, fehleranfälliger Code aus Unwissenheit. (Daraus abgeleitet die Frage, ob man in C forward declarations kennen sollte? Die Antwort ist natürlich IMHO ja, auch wenn man sie in der Praxis kaum benötigt.)
Aber lassen wir das Extrem beiseite und nehmen die Programmierer die so mitten drin stehen. Die sind doch der Normalfall ueberall da draussen. Das hat nunmal auch Auswirkungen auf meinen Programmierstil, zumindest sollte es das haben, wenn ich ein erfolgreiches Projekt anstrebe, und das tue ich.
Auch ich strebe (natürlich) erfolgreiche Projekte an, aber das schaffe ich durch Disziplin und stetige Verbesserung, und nicht durch Anpassung an den "Normalfall".
Wuenschen wuerde ich es mir auch so wie du es formulierst, aber es scheint mir etwas zu idealistisch und letztlich kontraproduktiv zu sein, das zu erfordern. ...
Wieso kontraproduktiv? Von einem klassischen Musiker erwartet der Kunde auch, daß er über die Jahre reift und besser wird, und dabei aber den Respekt zu den Werken nicht verliert. Wieso darf man das nicht auch von einem Programmierer erwarten? Zumal die Auswirkungen hier schlimmer sind: Ein Kunde in Australien hat ein Problem, was man bei sich in der Firma nicht nachstellen kann. Das kann man nicht verhindern, aber aktiv die Wahrscheinlichkeit, daß es passiert, minimieren.
Zuletzt geändert von owl102 am 04.12.2016 11:15:52, insgesamt 2-mal geändert.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Schaltjahr: "sauberer" Code

Beitrag von Meillo » 03.12.2016 21:58:06

@owl102: Nachdem ich den Tag ueber ueber deine Worte nachgedacht habe, moechte ich dir zuerst mal fuer deine Beitraege danken. Ich finde, du hast sehr weise geschrieben. Auch hast du mir gehoerig zu denken gegeben ... nicht aber weil deine Ansichten mir neu waeren -- im Gegenteil -- weil ich mich frage warum ich nicht selbst gerade so argumentiere wie du es getan hast -- denn das waere mir keineswegs fremd. Ich denke, es liegt mit daran, dass ich seit einiger Zeit in einem Projekt stecke, in dem die von dir (und ebenso von mir) gewuenschte Geisteshaltung fehlt und auch nicht zu erhoffen ist. Darunter leide ich. Leider ist mir das Projekt so wichtig, dass ich es nicht einfach hinter mir lassen kann. Ich hatte lange stark mit der Situation zu kaempfen. Seit einiger Zeit geht es aber besser ... vermutlich deshalb, weil ich aufgehoert habe soviel unter den Defiziten meiner Mitmenschen zu leiden und angefangen habe, das anzustreben was realitisch ist. Wenn ich nun deine Worte lese, dann erkenne ich darin ein kompromissloseres, ein strebsameres, ein idealistischeres ... und leider auch frueheres Selbst wieder. Danke, dass du mir diesen Blick eroeffnet hast. Nun werde ich darueber nachdenken muessen, was das fuer mich bedeutet ...
Use ed once in a while!

Benutzeravatar
TRex
Moderator
Beiträge: 8071
Registriert: 23.11.2006 12:23:54
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: KA

Re: Schaltjahr: "sauberer" Code

Beitrag von TRex » 03.12.2016 22:07:30

Meillo hat geschrieben:Nun werde ich darueber nachdenken muessen, was das fuer mich bedeutet ...
Darüber nachdenken, welcher Wert aus deiner Herangehensweise entsteht, warum das dem anderen nicht so wichtig erscheint und reflektieren, ob die Gründe des Gegenübers, es nicht zu tun, es rechtfertigen könnten, auf deine Werte zu verzichten. Vielleicht schaffst du es in einem weniger "kritischen" Projekt, dem Gegenüber deine Werte zu vermitteln und ihm beizubringen, wie man sie umsetzt und was man letztlich praktisch gewonnen hat. Oder du stellst fest, dass du dich irrst - passiert auch hin und wieder (zB die Notwendigkeit zu proklamieren, jedes Programm durch mathematischen Beweis auf Fehlerfreiheit zu prüfen).
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

owl102

Re: Schaltjahr: "sauberer" Code

Beitrag von owl102 » 04.12.2016 11:59:10

Meillo hat geschrieben:@owl102: Nachdem ich den Tag ueber ueber deine Worte nachgedacht habe, moechte ich dir zuerst mal fuer deine Beitraege danken.
Die Blumen gebe ich gerne zurück, denn auch ich reflektiere gerne über dieses Thema, und du bist auch schon an zwei Buchkäufen schuld.

In diesem konkreten Falle frage ich mich, wie ich mich wohl an deiner Stelle verhalten würde. Im Endeffekt geht es ja darum, als Team das Projekt zu heben. Wenn ich dabei Code produziere, bei dem die Wahrscheinlichkeit groß ist, daß ein Kollege bei der Bearbeitung einen Fehler einbaut, weil er ihn nicht komplett versteht, hilft das nicht, da bleibt mir gar nichts anderes übrig, als dir recht zu geben. Auch wenn der Kollege meinen Code debuggen muß (es bleibt ja nie aus, daß man beim Debuggen der eigenen Probleme auch im Code des Kollegen landet), ist es hilfreich, wenn er dort sattelfest ist. Es hilft auch nur begrenzt, den Kollegen zum Lernen zu animieren, wenn die Deadline wie üblich schon am Horizont droht, er also aktuell keine Zeit dafür findet.

Schwierige Frage. Ich denke man muß zwischen Anfängern mit einer Ethik zum Beruf und seiner Arbeit, und jemandem unterscheiden, der nicht bereit ist, sein "Durchwuseln" zu ändern. Bei letzterem wäre es mir wohl zu einseitig, wenn ich ihm entgegenkomme, aber von seiner Seite kein entgegenkommen zu erwarten ist. Das schafft nur Frust, denn letztendlich unterstützt man seine Arbeitsweise auch noch, ohne daß es viel hilft. (Solche Leute kenne ich leider aus der Praxis. Die wuseln vor sich hin. Das Meme, daß ich verlinkt hatte, passt perfekt. Wenn Fehler auftreten, dann setzen sie sich eben ran. Wenn sie Urlaub haben, oder jemand anderes den Code erbt, ist es ihnen egal, daß Kollegen darunter leiden müssen. Das müssen nicht einmal A****l***er sein, sondern nette Kumpels, die das einfach als Grundhaltung haben. Und dann genau das an ihren Kindern monieren, aber das ist ein anderes Thema. :mrgreen: )

Ich schweife ab. (Sorry!) Mein Zwischenstand: Ich denke ich würde mir einen anderen Job suchen bzw. das Projekt verlassen, wenn der Projektleiter nicht eine gewisse Qualität vorlebt und unterstützt. (Ja, das mußte ich leider schon einmal machen, es ist mir alles andere als leicht gefallen, aber im Nachherein bin ich sehr froh um diesen Schritt.) Man kämpft ansonsten gegen Windmühlen, und was schlimmer ist, man bekommt keine Ruhe in das Projekt. Ich arbeite ja auch deswegen ordentlich, weil ich faul bin. Ich bin zu faul, aus dem Urlaub gerufen zu werden, weil mein Code Probleme macht. Ich bin zu faul, mich nach Abschluß eines Projektes im späteren Verlauf immer wieder durch Altlasten unterbrochen zu werden. Ich bin zu faul, um zum Kunden nach Japan zu fliegen, um dort unter Stress und Augen des Kunden zu debuggen, deswegen bin ich froh um jeden Fehler, den ich zuhause finde und unterstütze stattdessen aktiv sowohl das Fehlervermeiden als auch das Fehlerfinden während der Entwicklung (Modultests, asserts, sinnvolle und gut filterbare Logs, ...). Usw.

Wenn es jedoch so ist, daß manche Kollegen einfach noch nicht soweit sind, müssen sie ihre Bedenken / Probleme offen äußern, und dann muß das in den Coderichtlinien berücksichtigt werden. Wichtig ist außerdem, daß in dem Projekt ein Umfeld herrscht, in dem offen gefragt werden kann, wenn man mal etwas nicht verstanden hat oder unsicher ist. (Man kann dann zusammen erarbeiten, wie man es hätte codieren können, so daß es für den anderen verständlicher ist, so lernen beide was dazu. Oder man findet gar zusammen einen Fehler in dem Codeteil.) Ich versuche das immer zu fördern, denn wenn sich jemand nicht traut zu fragen, weil die Frage dumm sein könnte, dann haben wir wieder die Wahrscheinlichkeitserhöhung, daß ein Fehler produziert wird, der nur beim Kunden in Japan auftaucht.

Vielleicht hilft es, wenn man mal offen in deinem Projekt über die Thematik redet? (Schließlich geht es ja nicht nur um dein Unwohlsein, sondern um die Qualitätssicherung.) Oder interessiert das dort keinen?

Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: Schaltjahr: "sauberer" Code

Beitrag von Lord_Carlos » 04.12.2016 12:12:50

In meinem Team, bevor wir unseren code ins repo pushen machen wir meistens einen kleinen code review, so das mehr als 2 Augen drauf geguckt haben. Da diskutieren wir dann auch gerne ob etwas in eine variable oder extra Methode ausgelagert werden soll. Dank java und einer netten IDE geht das auch recht fix und man macht es gerne. Meistens ist man sich da recht schnell einig wie es aussehen soll.

Am Ende eines zwei woechigen Sprintes haben wir dann noch ein Sprint Review wo wir unter anderem diskutieren was uns zurueckgehalten oder nicht gut gefallen hat. Da kann man das ganze dann auch noch mal übergeordnet diskutieren.

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

Antworten