Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.
Toon posts:

[ALG] Waarom zijn if statements zonder body toegestaan?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik was vandaag een beetje java code aan het krassen en maakte daarbij een enigszins klasiek foutje:
Java:
1
2
3
if (someAttribute == null); {
  throw new IllegalArgumentException("whatever");
}

Aangezien je hier snel overheen leest: het gaat om de punt komma achter het if statement.
Ook bijvoorbeeld in C# is dit toegestaan hoewel je daar wel netjes een warning krijgt.

Nu vraag ik mij af waarom dit uberhaupt is toegestaan. Is er een (legacy) toepassing die ik over het hoofd zie? Een compiler warning lijkt mij dus wat mild en ga ik liever voor een compilation failure.

Wie heeft enig idee?

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

omdat volgens mij een "<niets>" ook een statement body is en er na een if een statement body verwacht wordt ?

ASSUME makes an ASS out of U and ME


  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

H!GHGuY schreef op dinsdag 22 juli 2008 @ 11:28:
omdat volgens mij een "<niets>" ook een statement body is en er na een if een statement body verwacht wordt ?
Wat zeg je precies :?

Punt blijft dat een if statement zonder body geen nut heeft, waarom dan wel toestaan?

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17-11 15:37

Janoz

Moderator Devschuur®

!litemod

Het enige dat ik kan bedenken is dat het een (onbedoeld) gevolg is van de syntax definitie. Ik kan niet echt een toepassing verzinnen. Waarschijnlijk passen ze het niet aan vanwege backward compatibility, maar dat is niet echt een antwoord aangezien er dan eigenlijk ook een nuttige toepassing zou moeten zijn.

Het enige wat ik me zou kunnen voorstellen is dat je enorm in je conditie loopt te hacken en de conditie zelf (door lazy evaluation) de gewenste functionaliteit bied, maar dit is ook zonder de if te doen (denk aan de or die constructies van php). Een ander voorbeeld zou een for of while loop kunnen zijn waarin de complete functionaliteit al tussen de haakjes van de for of while zit.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dat de triviale lege statement block een valide block is.

Voor wat betreft het nut: Dankzij deze feature kan je dmv short-circuit logica gruwelijke one-liners schrijven. Uiteraard is dat in zo goed als alle gevallen een foutgevoelige, slechte code style. Het is een stomme valkuil met twijfelachtig nut. Dat bepaalde compilers een warning/hint kunnen geven is imo zeer mooi.

{signature}


Verwijderd

Topicstarter
Janoz schreef op dinsdag 22 juli 2008 @ 11:31:
Het enige wat ik me zou kunnen voorstellen is dat je enorm in je conditie loopt te hacken en de conditie zelf (door lazy evaluation) de gewenste functionaliteit bied, maar dit is ook zonder de if te doen (denk aan de or die constructies van php). Een ander voorbeeld zou een for of while loop kunnen zijn waarin de complete functionaliteit al tussen de haakjes van de for of while zit.
Bij een for/while lus kan je er inderdaad wat mee.


Oh en dan opeens heb je het. Posten op een forum helpt toch altijd:
Java:
1
if(evaluatesFalseButWasExecuted() || evaluatesTrueAndWasExecuted() || notCalled());

Dit kun je natuurlijk niet als op zichzelf staant statement schrijven. Gebruiken zou ik het denk ik nooit. Maar er is dus een toepassing.

/edit zoveel
Ik zit echt niet op te letten, ik quote je zelfs nog en lees er nog overheen dat je bovenstaand al gezegd hebt... 8)7.

[ Voor 20% gewijzigd door Verwijderd op 22-07-2008 11:47 ]


  • dvvelzen
  • Registratie: Februari 2002
  • Laatst online: 07-08 19:20
ik weet niet precies wat de code/syntax is voor java/C, maar bv in perl en shellscripts kan je ook dit doen:

print "blabla" if ( $debug == 1 );

hth

  • Canaria
  • Registratie: Oktober 2001
  • Niet online

Canaria

4313-3581-4704

Voutloos schreef op dinsdag 22 juli 2008 @ 11:33:
[...]
Dat de triviale lege statement block een valide block is.
zoals in
code:
1
2
3
4
for (;;)
{
// do something
}

Apparticle SharePoint | Apps | Articles


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Canaria schreef op dinsdag 22 juli 2008 @ 11:39:
[...]

zoals in
code:
1
2
3
4
for (;;)
{
// do something
}
Nee, eerder:
code:
1
for(;doSomethingWithUglySideEffect(););
De reden dat het toegestaan is, is volgens mij wat Janoz hierboven zegt puur de syntax-definitie (stukje BNF):
code:
1
2
3
4
5
6
7
8
9
10
if_statement 
      ::= 
      "if" "(" expression ")" statement
      ..... // blah, blah

statement 
      ::= 
      ( expression ";" )
      |     ...... // blah, blah
      | ( ";" )
; is dus een legaal statement. Een uitzondering maken voor situaties waarin dat (waarschijnlijk) niet is wat je wilt is het mindere kwaad in zo'n geval (wil je dat wel, dan verhoog je "onnodig" de complexiteit van de syntax). Het heeft dus NIET tot doel het soort vieze constructies waar dit topic inmiddels vol mee staat ;) mogelijk te maken.

[ Voor 60% gewijzigd door Herko_ter_Horst op 22-07-2008 11:56 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Face_-_LeSS
  • Registratie: September 2004
  • Niet online
Volgens mij zijn er tig constructies te bedenken in code die geen nut hebben maar als overal op gecontroleerd moet worden staat je IDE straks 5 minuten te checken of alles wel nut heeft voordat je kunt runnen.

Maar van sommige dingen is het wel handig om een melding van te krijgen natuurlijk.

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op dinsdag 22 juli 2008 @ 11:37:
[...]
Oh en dan opeens heb je het. Posten op een forum helpt toch altijd:
Java:
1
if(1 == 2 || 1==1);

De tweede wordt natuurlijk enkel uitgevoerd als de eerste onwaar is. Een los statement schrijven gaat niet.
Janoz zegt net dat het zonder if ook kan :P

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17-11 15:37

Janoz

Moderator Devschuur®

!litemod

nee, dat dacht ik even, maar ik heb net ff snel wat gechecked en dat blijkt niet zo te zijn.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Verwijderd schreef op dinsdag 22 juli 2008 @ 11:37:
Oh en dan opeens heb je het. Posten op een forum helpt toch altijd:
Java:
1
if(evaluatesFalseButWasExecuted() || evaluatesTrueAndWasExecuted() || notCalled());

Dit kun je natuurlijk niet als op zichzelf staant statement schrijven. Gebruiken zou ik het denk ik nooit. Maar er is dus een toepassing.
Dat is wel ontzettend ranzig en misbruik van het if-statement waar het niet voor bedoeld is :P

En dat kan je toch wel herschrijven naar een if/else if/else of switch?

[ Voor 6% gewijzigd door Haan op 22-07-2008 11:50 ]

Kater? Eerst water, de rest komt later


  • GlowMouse
  • Registratie: November 2002
  • Niet online
Janoz schreef op dinsdag 22 juli 2008 @ 11:46:
nee, dat dacht ik even, maar ik heb net ff snel wat gechecked en dat blijkt niet zo te zijn.
Hier bij Delphi 5 werkt het gewoon. Je moet er overigens wel een boolVar := expressie van maken, want gewoon true of false is ook geen statement.

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 22:42
Heel krom gedacht is dit natuurlijk een mogelijkheid om een simpele guard conditie aan een methode aanroep te knopen, zonder een body block nodig te hebben, wat dus een koretere notatie oplevert.

code:
1
if(foo && doBar());


Waarbij doBar() (die natuurlijk wel een boolean moet retourneren) alleen wordt aangeroepen als conditie foo true is. Een waardige WTF-kandidaat, maar het is wel legaal.

Equivalent aan het multi-line en veel leesbaardere :

code:
1
2
3
if(foo){
    doBar();
}


Ik denk dat ik teveel tijd doorbreng op TDWTF :X

Edit: Anders lees ik eerst even heel het topic door :)

[ Voor 4% gewijzigd door Kwistnix op 22-07-2008 11:55 ]


Verwijderd

Topicstarter
Haan schreef op dinsdag 22 juli 2008 @ 11:49:
Dat is wel ontzettend ranzig en misbruik van het if-statement waar het niet voor bedoeld is :P

En dat kan je toch wel herschrijven naar een if/else if/else of switch?
Ik denk inderdaad dat je het niet moet toestaan. Maar aangezien er een toepassing is zal er ongetwijfeld iemand zijn die het heeft misbruikt. Dus lastig om dit nu nog te veranderen. Meer iets voor taalontwerpers om bij nieuwe talen rekening mee te houden.

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Jullie vergeten dat je bij 1 bepaalde hit van een if statement misschien wel niets wil doen

dus:

if (i = 1); // doe nog even niets...
else if ( i = 2)
{
doe iets;
}
else
{
sluit af
}

Even niets...


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
thijs_cramer schreef op dinsdag 22 juli 2008 @ 11:55:
Jullie vergeten dat je bij 1 bepaalde hit van een if statement misschien wel niets wil doen

dus:

if (i = 1); // doe nog even niets...
else if ( i = 2)
{
doe iets;
}
else
{
sluit af
}
Maak dan liever een leeg block. Een stuk leesbaarder wat mij betreft:
code:
1
2
3
4
5
6
7
8
9
if (i == 1) {
 // doe nog even niets...
}
else if (i == 2) {
 doIets();
}
else {
 sluitAf();
}


offtopic:
= vs == is nog zo'n leuke

[ Voor 18% gewijzigd door Herko_ter_Horst op 22-07-2008 12:02 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Verwijderd

Topicstarter
thijs_cramer schreef op dinsdag 22 juli 2008 @ 11:55:
Jullie vergeten dat je bij 1 bepaalde hit van een if statement misschien wel niets wil doen

if (i = 1); // doe nog even niets...
Wat is het nut dan van deze regel volgens jou?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17-11 15:37

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op dinsdag 22 juli 2008 @ 11:55:
[...]
Ik denk inderdaad dat je het niet moet toestaan. Maar aangezien er een toepassing is zal er ongetwijfeld iemand zijn die het heeft misbruikt. Dus lastig om dit nu nog te veranderen. Meer iets voor taalontwerpers om bij nieuwe talen rekening mee te houden.
Ik vermoed dat er maar twee situaties zijn waarin je het tegen zal komen. Ten eerste in gegenereerde of automatisch gerefactorde code, net als met de goto in veel gegenereerde tokenizers.

Ten tweede in de door zichzelf erg cool vindende autodidacten met een hoog 'kijk mij eens nasty ingewikkelde code schrijven, oeh wat ben ik slim dat ik dit kan'-gehalte.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Cloud
  • Registratie: November 2001
  • Laatst online: 03-11 10:25

Cloud

FP ProMod

Ex-moderatie mobster

Verwijderd schreef op dinsdag 22 juli 2008 @ 11:58:
Wat is het nut dan van deze regel volgens jou?
Een herinnering dat hij wel iets moet gaan doen? ;)

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


  • Salandur
  • Registratie: Mei 2003
  • Laatst online: 17-11 13:41

Salandur

Software Engineer

edit : al gezegt door iemand anders. moet toch eerst refreshen voordat ik wat ga tiepen....

[ Voor 87% gewijzigd door Salandur op 22-07-2008 12:02 ]

Assumptions are the mother of all fuck ups | iRacing Profiel


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17-11 15:37

Janoz

Moderator Devschuur®

!litemod

Ik vermoed dat thijs geen =, maar == bedoeld, en dan zou zijn code equivalent zijn aan:
code:
1
2
3
4
5
if (i == 2) {
  doIets();
else if (i!=1){
  sluitAf();
}

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

thijs_cramer schreef op dinsdag 22 juli 2008 @ 11:55:
Jullie vergeten dat je bij 1 bepaalde hit van een if statement misschien wel niets wil doen

dus:

if (i = 1); // doe nog even niets...
else if ( i = 2)
{
doe iets;
}
else
{
sluit af
}
samengevat als:
code:
1
2
3
4
5
if (i ==2) 
{ 
    doeIets(); 
}
else sluitAf();


edit:
zelfde als hierboven dus, maar dan minder goed :(

[ Voor 10% gewijzigd door Haan op 22-07-2008 12:06 . Reden: else vergeten ]

Kater? Eerst water, de rest komt later


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Janoz schreef op dinsdag 22 juli 2008 @ 12:02:
Ik vermoed dat thijs geen =, maar == bedoeld, en dan zou zijn code equivalent zijn aan:
code:
1
2
3
4
5
if (i == 2) {
  doIets();
else if (i!=1){
  sluitAf();
}
Dat het equivalent is ben ik met je eens (een missende } daargelaten), maar het feit dat i == 1 een speciaal geval is, is nu minder duidelijk vind ik. De oorspronkelijke (of door mij hierboven herschreven) code maakt directer duidelijk dat 1 en 2 apart worden behandeld en voor alle overige gevallen sluitAf(); wordt aangeroepen.

[ Voor 7% gewijzigd door Herko_ter_Horst op 22-07-2008 12:07 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Verwijderd

Topicstarter
Janoz schreef op dinsdag 22 juli 2008 @ 11:59:
Ik vermoed dat er maar twee situaties zijn waarin je het tegen zal komen. Ten eerste in gegenereerde of automatisch gerefactorde code, net als met de goto in veel gegenereerde tokenizers.
Daar had ik inderdaad nog niet aangedacht. Tenminste, ik kan me dan hooguit iets voorstellen in de trend van:
Java:
1
2
3
4
5
if(someCondition) {
  //empty block
} else {
  doSomethingMagnificent();
}

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Verwijderd schreef op dinsdag 22 juli 2008 @ 11:58:
[...]

Wat is het nut dan van deze regel volgens jou?
dat ik bij een bepaalde waarde van het statement nog niets doe?
En dat ook expliciet in code laat zien misschien?

Voorbeeld:

if (i == 0) ;
else if (i == 1 && doeIets())
{

}

nu klapt het if statement er uit en word doeiets nog niet gecheckt...
bij 1 wel...

[ Voor 23% gewijzigd door FireDrunk op 22-07-2008 12:09 ]

Even niets...


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Haan schreef op dinsdag 22 juli 2008 @ 12:04:
[...]

samengevat als:
code:
1
2
3
4
5
if (i ==2) 
{ 
    doeIets(); 
}
else sluitAf();


edit:
zelfde als hierboven dus, maar dan minder goed :(
Hier ga je wel de mist in, want sluitAf() moet alleen als i niet gelijk is aan 1 (en 2).

"Any sufficiently advanced technology is indistinguishable from magic."


  • Canaria
  • Registratie: Oktober 2001
  • Niet online

Canaria

4313-3581-4704

Janoz schreef op dinsdag 22 juli 2008 @ 12:02:
Ik vermoed dat thijs geen =, maar == bedoeld, en dan zou zijn code equivalent zijn aan:
code:
1
2
3
4
5
if (i == 2) {
  doIets();
else if (i!=1){
  sluitAf();
}
Dat kan dan wel mooier
code:
1
2
3
4
5
6
7
8
9
10
11
12
switch (i)
{
case 1:
  // todo
  break;
case 2:
  doIets();
  break;
default:
  sluitAf();
  break;
}

Apparticle SharePoint | Apps | Articles


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Canaria schreef op dinsdag 22 juli 2008 @ 12:10:
[...]

Dat kan dan wel mooier
code:
1
2
3
4
5
6
7
8
9
10
11
12
switch (i)
{
case 1:
  // todo
  break;
case 2:
  doIets();
  break;
default:
  sluitAf();
  break;
}
ik denk dat als je maar 1 of 2 waardes afcheckt een if statement met 1 else sneller is dan een case (zon ding heet een switch Thijs 8)7 )

[ Voor 6% gewijzigd door FireDrunk op 22-07-2008 12:12 ]

Even niets...


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Ach, mooier... Ik vind dit niet persé leesbaarder dan de if/else if/else (komt m.n. door de breaks).

"Any sufficiently advanced technology is indistinguishable from magic."


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

@thijs: Ik denk dat het verschil (als het er al is ) beneden de miliseconde ligt ;)

offtopic:
en nee ik heb nu even geen tijd om dat te proberen :P

[ Voor 33% gewijzigd door Haan op 22-07-2008 12:15 ]

Kater? Eerst water, de rest komt later


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
thijs_cramer schreef op dinsdag 22 juli 2008 @ 12:11:
[...]

ik denk dat als je maar 1 of 2 waardes afcheckt een if statement met 1 else sneller is dan een case (zon ding heet een switch Thijs 8)7 )
Sneller? Sneller getypt bedoel je dan zeker, want ik verwacht eigenlijk dat de compiler identieke bytecode zal genereren.

Edit: ok, niet dus, maar ik kan me niet voorstellen dat je het verschil ooit gaat merken.

[ Voor 10% gewijzigd door Herko_ter_Horst op 22-07-2008 12:22 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Haan schreef op dinsdag 22 juli 2008 @ 12:14:
@thijs: Ik denk dat het verschil (als het er al is ) beneden de miliseconde ligt ;)
En laat ik door Datastructures and Algorightems in Java (mijn boek dat dikker is dan de Bijbel)
geleerd hebben dat je 1 ms nooit moet onderschatten ;)

doe de berekening 100000 x en je huilt ;)
en laat je nou net 99999 een 0 tegenkomen ;)
dan zou ik mijn code liever hebben :D

Even niets...


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
offtopic:
en nee ik heb nu even geen tijd om dat te proberen :P
offtopic:
Geen zin om te programmeren onder werktijd? :+

Even niets...


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Herko_ter_Horst schreef op dinsdag 22 juli 2008 @ 12:15:
[...]

Sneller? Sneller getypt bedoel je dan zeker, want ik verwacht eigenlijk dat de compiler identieke bytecode zal genereren.
Dat denk ik niet want een switch heeft een iets andere rekenvolgorde dan een lijst met if statements
De uitvogelsnelheid of een waarde in de lijst voorkomt kan bij een switch veel sneller...
Stel je checkt met een switch op A, B, C, D, E maar het is een F
Dan weet de switch voordat hij begint al dat hij bij default moet zijn...
Bij de if statements worden ze wel allemaal uitgevoerd denk ik...

Even niets...


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
thijs_cramer schreef op dinsdag 22 juli 2008 @ 12:18:
[...]


Dat denk ik niet want een switch heeft een iets andere rekenvolgorde dan een lijst met if statements
De uitvogelsnelheid of een waarde in de lijst voorkomt kan bij een switch veel sneller...
Stel je checkt met een switch op A, B, C, D, E maar het is een F
Dan weet de switch voordat hij begint al dat hij bij default moet zijn...
Bij de if statements worden ze wel allemaal uitgevoerd denk ik...
Net even gechecked en de bytecode is inderdaad anders. Maar ik volg jouw redenatie niet m.b.t. het sneller zijn van een switch (overigens dacht ik dat je net zei dat de if-versie sneller was?). Er zullen evenveel vergelijkingen moeten plaatsvinden om te bepalen welk block uiteindelijk moet worden uitgevoerd. Verschil zal overigens zeker niet liggen in de millisecondes, eerder in de nanosecondes.

Ter vergelijking de byte codes behorende bij respectievelijk de if-versie en de switch-versie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iconst_1
   4:   if_icmpne       10
   7:   goto    30
   10:  iload_1
   11:  iconst_2
   12:  if_icmpne       26
   15:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   18:  ldc     #3; //String 2
   20:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   23:  goto    30
   26:  iconst_1
   27:  invokestatic    #5; //Method java/lang/System.exit:(I)V
   30:  return

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  0:   iconst_0
  1:   istore_1
  2:   iload_1
  3:   lookupswitch{ //2
               1: 28;
               2: 31;
               default: 42 }
  28:  goto    46
  31:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
  34:  ldc     #3; //String 2
  36:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
  39:  goto    46
  42:  iconst_1
  43:  invokestatic    #5; //Method java/lang/System.exit:(I)V
  46:  return


lookupswitch is blijkbaar een enkele opcode. Of die veel sneller zal worden uitgevoerd dan twee keer een if_icmpne gevolgd door een goto zou een uitgebreide test moeten uitwijzen. Ik verwacht geen meetbare verschillen.

Maar goed, we gaan behoorlijk offtopic zo :)

[ Voor 9% gewijzigd door Herko_ter_Horst op 22-07-2008 12:33 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Net ook maar even iets inelkaar geflanst, de switch is een factor 7-10 sneller zo te zien :X

Foutje van mijn kant :P Het is andersom.
Ik gebruik een TimeSpan om de verstreken tijd te meten, maar ik keek eerst naar de MiliSeconds property ipv de TotalMiliSeconds property.. (dat krijg je als je iets snel wilt doen ;) )

Een switch is nu steeds ~7x langzamer, getest bij 10-10-100 miljoen iteraties.

[ Voor 67% gewijzigd door Haan op 22-07-2008 12:42 ]

Kater? Eerst water, de rest komt later


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Haan schreef op dinsdag 22 juli 2008 @ 12:35:
Net ook maar even iets inelkaar geflanst, de switch is een factor 7-10 sneller zo te zien :X
Ok, nou maak je me kwaad ;) Ben zo terug :)

Edit: ik kom op een ander resultaat, namelijk ongeveer een factor 3 voordeel voor de if.

Op mijn E6600:
If constructie86915.447605 ms
Switch constructie275479.111462 ms

Dit na het runnen van een microbenchmark die (na warm-up) 10000 x 1000000 keer zowel de if en de switch-versie aanriep voor de waarden 0, 1 en 2 voor i.

Elk van de constructies is dus 30 miljard keer doorlopen! Deel ik de tijd door het aantal runs, dan kom ik op een verschil van 2.9 vs 9.2 nanoseconden gemiddeld om deze constructie te doorlopen. Mocht je het even kwijt zijn: een nanoseconde is 1 miljoenste milliseconde (1 miljardste seconde).

Hier zit dan ook nog het doorlopen van een for-loop, een method-call en het assignen en retourneren van een String bij in. Het verschil is dus naar schatting minder dan 5 miljardste van een seconde. De tijd die ik heb besteed om dit uit te zoeken, verdien ik dus van z'n lang-zal-ze-leven niet meer terug ;)


Java: IfvsSwitch.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public class IfvsSwitch {

    /**
     * @param args
     */
    public static void main(String[] args) {
        long ifResult = 0;
        long switchResult = 0;

        System.out.println("Starting warm-up runs...");
        for (int count = 0; count < 10000; count++) {
            runUsingIf(0, 100000);
            runUsingIf(1, 100000);
            runUsingIf(2, 100000);
            runUsingSwitch(0, 100000);
            runUsingSwitch(1, 100000);
            runUsingSwitch(2, 100000);
        }

        System.out.println("Starting real runs...");
        for (int count = 0; count < 10000; count++) {
            long startForIf = System.nanoTime();
            runUsingIf(0, 1000000);
            runUsingIf(1, 1000000);
            runUsingIf(2, 1000000);
            long endForIf = System.nanoTime();

            long startForSwitch = System.nanoTime();
            runUsingSwitch(0, 1000000);
            runUsingSwitch(1, 1000000);
            runUsingSwitch(2, 1000000);
            long endForSwitch = System.nanoTime();

            ifResult += endForIf - startForIf;
            switchResult += endForSwitch - startForSwitch;
        }

        System.out
                .println("If took " + ((double) ifResult / 1000000.0) + " ms");
        System.out.println("Switch took " + ((double) switchResult / 1000000.0)
                + " ms");
    }

    public static String runUsingIf(int i, int numberOfRuns) {
        String dummy = "";
        for (int count = 0; count < numberOfRuns; count++) {
            dummy = usingIf(i);
        }
        return dummy;
    }

    public static String runUsingSwitch(int i, int numberOfRuns) {
        String dummy = "";
        for (int count = 0; count < numberOfRuns; count++) {
            dummy = usingSwitch(i);
        }
        return dummy;
    }

    public static String usingIf(int i) {
        String result = null;
        if (i == 1) {
            result = "1";
        } else if (i == 2) {
            result = "2";
        } else {
            result = "~";
        }
        return result;
    }

    public static String usingSwitch(int i) {
        String result = null;
        switch (i) {
        case 1:
            result = "1";
            break;
        case 2:
            result = "2";
            break;
        default:
            result = "~";
        }
        return result;
    }

[ Voor 114% gewijzigd door Herko_ter_Horst op 22-07-2008 13:51 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Whahahaha... zei ik toch..
maar een switch is denk ik sneller als je een op een volgende rij van waardes checkt.
De waardes waarmee een switch vergelijkt worden toch in een array gezet, zodat daar door middel van een zoekopdracht snel de code gevonden word? of denk ik nu dat een switch te intelligent is?

dus switch (letter)
case: a
case: b
case: c
case: d
...
case: z

Word een gesorteerde array met alle letters en referenties naar de code blokken...
of ik denk te ingewikkeld :)

Even niets...


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Ben ik voor m'n werk bezig met een stuk javascript dat maar een error blijft geven op een element dat null is, ondanks een check if(element != null), blijk ik
JavaScript:
1
if (element != null); 
getypt te hebben 8)7

Kater? Eerst water, de rest komt later


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Hahahahaha... Neem een kop koffie :)

Even niets...


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Volgens mij is C# best intielligent... (ik niet)
In de volgende code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void Main(string[] args)
        {
            string command = "if";
            while ( command != "exit")
            {
                if (command == "if")
                {
                    CalcIf();
                }
                if (command == "switch")
                {
                    CalcSwitch();
                }
                command = Console.ReadLine();
            }
        }


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
static void CalcSwitch()
        {
            double time = DateTime.Now.TimeOfDay.TotalMilliseconds;
            Console.WriteLine("Time: " + time);
            Random rand = new Random(Convert.ToInt32(time));
            for (int i = 0; i < 100000; i++)
            {
                int nr = rand.Next(1, 20);
                switch (nr)
                {
                    case 1:
                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    case 4:
                        break;
                    case 5:
                        break;
                    case 6:
                        break;
                    case 7:
                        break;
                    case 8:
                        break;
                    default:
                        break;
                }
            }
            Console.WriteLine("Calculation time: " + (DateTime.Now.Millisecond - time) + "MS");
        }


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void CalcIf()
        {
            double time = DateTime.Now.TimeOfDay.TotalMilliseconds;
            Console.WriteLine("Time: " + time);
            Random rand = new Random(Convert.ToInt32(time));
            for (int i = 0; i < 100000; i++)
            {
                int nr = rand.Next(1, 20);
                if (nr == 1) { }
                else if (nr == 2) {}
                else if (nr == 3) { }
                else if (nr == 4) { }
                else if (nr == 5) { }
                else if (nr == 6) { }
                else if (nr == 7) { }
                else if (nr == 8) { }
                else { }
            }
            Console.WriteLine("Calculation time: " + (DateTime.Now.TimeOfDay.TotalMilliseconds - time) + "MS");
        }


Word 1x +- 50ms gerekend...
De volgende keer is hij instant klaar...

mis ik iets? :)

Even niets...


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
In Java zou me dit niets verbazen: lege loops/statements worden door de JIT compiler gewoon weggeoptimaliseerd.

Mijn resultaten met Java heb ik hierboven in een eerdere reactie gepost.

[ Voor 20% gewijzigd door Herko_ter_Horst op 22-07-2008 13:54 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Haan schreef op dinsdag 22 juli 2008 @ 13:04:
Ben ik voor m'n werk bezig met een stuk javascript dat maar een error blijft geven op een element dat null is, ondanks een check if(element != null), blijk ik
JavaScript:
1
if (element != null); 
getypt te hebben 8)7
Ah, gelukkig weer iemand on-topic ;)

Dit is waarom ik een hekel heb aan die lege if's (of 1-regelige "blocks"). Ik gebruik altijd {}, ook al staat er niks of maar één regel. Dan kan zo'n fout natuurlijk nog voorkomen, maar als je je IDE op zo'n "standaard" instelt loop je wel een stuk minder risico.

"Any sufficiently advanced technology is indistinguishable from magic."


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Het is een (goede) design keuze om het (een lege if-statement) toe te staan. Het concept heet orthogonal design.

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Zoijar schreef op dinsdag 22 juli 2008 @ 14:19:
Het is een (goede) design keuze om het (een lege if-statement) toe te staan. Het concept heet orthogonal design.
Mee eens. Dat je er ook ongewenste dingen mee kan doen is dan de prijs die je betaalt.

"Any sufficiently advanced technology is indistinguishable from magic."


Verwijderd

Topicstarter
Zoijar schreef op dinsdag 22 juli 2008 @ 14:19:
Het is een (goede) design keuze om het (een lege if-statement) toe te staan. Het concept heet orthogonal design.
Het is maar met welke bril je het bekijkt. Functioneel gezien wil dergelijke statements niet in de code tegenkomen. Immers, ze zijn onduidelijk en er zijn betere alternatieven. Tevens is de kans vrij groot dat je met een bug te maken hebt in plaats van een bewuste keuze.
Zet je je language design bril op dan valt er veel voor te zeggen om het wel toe te staan. Echter neig ik een beetje meer naar de functionele kant, simpelweg omdat het bugs kan voorkomen.

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Maar zo zijn er vast wel meer dingen die mogen ondanks dat ze heel raar zijn.

Zo mag je in C# een bestand in een map hebben staan zonder dat je de namespace daarnaar vernoemt hebt... (vind ik design technisch heel onhandig...)

Even niets...


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op dinsdag 22 juli 2008 @ 14:51:
[...]
Het is maar met welke bril je het bekijkt. Functioneel gezien wil dergelijke statements niet in de code tegenkomen. Immers, ze zijn onduidelijk en er zijn betere alternatieven. Tevens is de kans vrij groot dat je met een bug te maken hebt in plaats van een bewuste keuze.
Zet je je language design bril op dan valt er veel voor te zeggen om het wel toe te staan. Echter neig ik een beetje meer naar de functionele kant, simpelweg omdat het bugs kan voorkomen.
Juist in het geval van een taal wil je een zo eenduidig en eenvoudig mogelijke syntax. Elke uitzondering levert meer problemen op (niet alleen in programmeertalen, hetzelfde zie je in het Nederlands), met name bij het parsen. Bugs voorkomen is niet de taak van de taal (anders zou je in C geen pointers moeten willen ;)). Tools moeten dit ondervangen (in Eclipse kun je "Empty statement" dus ook als warning of zelfs error laten rapporteren).

"Any sufficiently advanced technology is indistinguishable from magic."


  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 19:31
Visual Studio geeft ook een warning...

Dit is het "Grijze Gebied" waar fout overgaat in stijl denk ik...

Even niets...


Verwijderd

Topicstarter
Herko_ter_Horst schreef op dinsdag 22 juli 2008 @ 15:11:
Juist in het geval van een taal wil je een zo eenduidig en eenvoudig mogelijke syntax. Elke uitzondering levert meer problemen op (niet alleen in programmeertalen, hetzelfde zie je in het Nederlands), met name bij het parsen.
Je zet nu duidelijk de taalbouwersbril op ;) Dit gaat enkel over parsen maar functioneel schiet je er echt niets mee op. Met andere woorden: mijn software wordt er niet beter van.

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op dinsdag 22 juli 2008 @ 15:18:
[...]
Je zet nu duidelijk de taalbouwersbril op ;) Dit gaat enkel over parsen maar functioneel schiet je er echt niets mee op. Met andere woorden: mijn software wordt er niet beter van.
Dat zou ik niet zomaar durven te zeggen. Naast het feit dat het lastiger te parsen is, is het voor jou als programmeur ook lastiger om alle uitzonderingen te onthouden. In plaats van overal dezelfde constructie te kunnen gebruiken ("statement") moet je bij een if ineens een "after_if_statement" gebruiken, bij een for een "after_for_statement" etc. Dat zou best eens gevolgen kunnen hebben voor de kwaliteit van je software.

Blijft over de vraag of een empty statement überhaupt zinvol is (ik kan zo geen voorbeeld bedenken waar ik een empty statement als beste oplossing zou gebruiken).

[ Voor 4% gewijzigd door Herko_ter_Horst op 22-07-2008 15:48 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Verwijderd

En een vaak lastig te vinden bug wanneer je zowel in Delphi/Pascal als in C(++, #)/Java programmeert: in Delphi is '==' '=', en '=' ':='. En als dan die andere taal assignments toestaat in if, for, while, etc. statements dan is 't meestal heel erg lastig om 't te debuggen.
Een Delphi programmeur ziet die extra '=' vaak over het hoofd in z'n (bij mij) C# code, en zelfs als je de knop naar de gebruikte taal hebt omgezet is dat nauwelijks te voorkomen.

Gerelateerd voorbeeldje: in Delphi is standaard F5 een breakpoint aan/uit zetten, en F9 runnen vanuit de debugger. In VS is dat precies andersom. Geen probleem als je een dag of zo in 1 van die IDE's werkt, maar wanneer ik op een dag vaak moet wisselen tussen IDE's dan run ik in Delphi applicatie met F5 F5 F9, en een VS project met F9 F9 F5.

Heeft niks te maken met het kennen van de taal of IDE, maar gewoon met "dat wat je zonet gewend was".

  • pkuppens
  • Registratie: Juni 2007
  • Laatst online: 23:50
Herko_ter_Horst schreef op dinsdag 22 juli 2008 @ 11:41:
[...]

Nee, eerder:
code:
1
for(;doSomethingWithUglySideEffect(););
De reden dat het toegestaan is, is volgens mij wat Janoz hierboven zegt puur de syntax-definitie (stukje BNF):
code:
1
2
3
4
5
6
7
8
9
10
if_statement 
      ::= 
      "if" "(" expression ")" statement
      ..... // blah, blah

statement 
      ::= 
      ( expression ";" )
      |     ...... // blah, blah
      | ( ";" )
; is dus een legaal statement. Een uitzondering maken voor situaties waarin dat (waarschijnlijk) niet is wat je wilt is het mindere kwaad in zo'n geval (wil je dat wel, dan verhoog je "onnodig" de complexiteit van de syntax). Het heeft dus NIET tot doel het soort vieze constructies waar dit topic inmiddels vol mee staat ;) mogelijk te maken.
Volgende stukje vind ik niet echt een ranzige manier om danwel de eerste index i te vinden met a[i] <= 0,
danwel uit het array te lopen met i == N:
C:
1
for (i=0; (i<N) && (a[i] > 0); i++) ;


Ik moet zeggen dat de coding standard die wij hanteren wel een explicitiete empty statement vereist:
C:
1
for (i=0; (i<N) && (a[i] > 0); i++) { /* empty */ };

Zo kan het statisch gecheckt worden en is duidelijk dat e.e.a. bedoeld is.

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

pkuppens schreef op woensdag 23 juli 2008 @ 13:37:
[...]


Volgende stukje vind ik niet echt een ranzige manier om danwel de eerste index i te vinden met a[i] <= 0,
danwel uit het array te lopen met i == N:
C:
1
for (i=0; (i<N) && (a[i] > 0); i++) ;


Ik moet zeggen dat de coding standard die wij hanteren wel een explicitiete empty statement vereist:
C:
1
for (i=0; (i<N) && (a[i] > 0); i++) { /* empty */ };

Zo kan het statisch gecheckt worden en is duidelijk dat e.e.a. bedoeld is.
Een while loop met boolean vind ik toch duidelijker en netter
code:
1
2
3
4
5
6
boolean found = false;
int index = 0;
while(!found)
{
    if(a[index++]>0) found = true;
}

Liever iets meer typen dan kortere onduidelijke code :)
farlane schreef op woensdag 23 juli 2008 @ 14:35:
[...]


En het feit dat jouw code alle elementen doorloopt tot a.length maakt niets uit?
Jawel, wat er eerst stond was ook niet de bedoeling, ik heb het aangepast O-)

[ Voor 18% gewijzigd door Haan op 23-07-2008 14:41 ]

Kater? Eerst water, de rest komt later


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Haan schreef op woensdag 23 juli 2008 @ 14:15:
Liever iets meer typen dan kortere onduidelijke code :)
En het feit dat jouw code alle elementen doorloopt tot a.length maakt niets uit?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 17-11 11:25
Is gewoon heel simpel...

Een lege body is in een aantal gevallen een valide constructie. Ik kan me voorstellen dat een if statement zelf een dusdanig side effect heeft dat een body niet noodzakelijk is.

In C is het volkomen normaal om te schrijven:
code:
1
2
3
FILE fp
//doe iets waardoor je misschien wel of niet een file pointer hebt.
if(fp == null || fclose(fp));


Waarom dat er ooit ingekomen is weet ik niet. Maar mijns inziens is het van belang dat een programmeer taal niet voor interpretatie vatbaar is. Dat er dan een paar edge cases zijn (al dan niet met reden), lig ik niet wakker van.

Verwijderd

En wat natuurlijk ook mogelijk is, is het definiëren van een functie in een interface :)


PHP:
1
2
3
interface iExample {
   public function mijnFunctie($szVar);
}

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
The - DDD schreef op woensdag 23 juli 2008 @ 14:39:
Is gewoon heel simpel...

Een lege body is in een aantal gevallen een valide constructie. Ik kan me voorstellen dat een if statement zelf een dusdanig side effect heeft dat een body niet noodzakelijk is.

In C is het volkomen normaal om te schrijven:
code:
1
2
3
FILE fp
//doe iets waardoor je misschien wel of niet een file pointer hebt.
if(fp == null || fclose(fp));


Waarom dat er ooit ingekomen is weet ik niet. Maar mijns inziens is het van belang dat een programmeer taal niet voor interpretatie vatbaar is. Dat er dan een paar edge cases zijn (al dan niet met reden), lig ik niet wakker van.
Heb je het topic gelezen? Een voorbeeld als dit is al diverse keren voorbij gekomen en volgens mij zijn de meeste posters het er over eens dat dit niet de duidelijkste manier om zoiets op te schrijven. Ik vind het veel duidelijker om te schrijven:
code:
1
2
3
if(fp != null) {
 fclose(fp);
}
Nu maak je m.i. gebruik van maar liefst drie impliciete eigenschappen bij elkaar die extra mentale verwerkingskracht vergen om te snappen: short-circuit van boolean expressies, een leeg statement en het feit dat fpclose() blijkbaar een boolean retourneert (terwijl je daar verder niks mee doet).

Plus het feit dat je erg makkelijk over een leeg statement heen leest waardoor je kunt denken dat het eerstvolgende niet-lege statement wordt "beschermd" door de if.

[ Voor 8% gewijzigd door Herko_ter_Horst op 23-07-2008 14:59 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op woensdag 23 juli 2008 @ 14:48:
En wat natuurlijk ook mogelijk is, is het definiëren van een functie in een interface :)


PHP:
1
2
3
interface iExample {
   public function mijnFunctie($szVar);
}
Verkeerde topic?

"Any sufficiently advanced technology is indistinguishable from magic."


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

Verwijderd schreef op woensdag 23 juli 2008 @ 14:48:
En wat natuurlijk ook mogelijk is, is het definiëren van een functie in een interface :)


PHP:
1
2
3
interface iExample {
   public function mijnFunctie($szVar);
}
Maar dat heeft vrij weinig met het if-statement te maken hè ;)

En volgens mij mag je het public keyword ook weglaten in een interface, omdat die sowieso altijd public methoden bevat. correct me if I'm wrong offcourse

Kater? Eerst water, de rest komt later


  • Face_-_LeSS
  • Registratie: September 2004
  • Niet online
pkuppens schreef op woensdag 23 juli 2008 @ 13:37:
[...]


Volgende stukje vind ik niet echt een ranzige manier om danwel de eerste index i te vinden met a[i] <= 0,
danwel uit het array te lopen met i == N:
C:
1
for (i=0; (i<N) && (a[i] > 0); i++) ;


Ik moet zeggen dat de coding standard die wij hanteren wel een explicitiete empty statement vereist:
C:
1
for (i=0; (i<N) && (a[i] > 0); i++) { /* empty */ };

Zo kan het statisch gecheckt worden en is duidelijk dat e.e.a. bedoeld is.
[ALG] Waarom zijn if statements zonder body toegestaan?

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Om het topic een beetje on-topic en algemeen te houden: in Oracle PL/SQL is het niet toegestaan...onderstaande code compileert simpelweg niet:
code:
1
2
3
4
5
6
7
8
9
CREATE OR REPLACE PROCEDURE TEST IS

BEGIN
 IF (sysdate>to_date('16/09/1975','dd/mm/yyyy'))
 THEN

  END IF;
END;
/

Het is dus niet altijd zo dat een lege body een valide constructie is.

When life gives you lemons, start a battery factory


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Herko_ter_Horst schreef op woensdag 23 juli 2008 @ 14:54:
Nu maak je m.i. gebruik van maar liefst drie impliciete eigenschappen bij elkaar die extra mentale verwerkingskracht vergen om te snappen: short-circuit van boolean expressies, een leeg statement en het feit dat fpclose() blijkbaar een boolean retourneert (terwijl je daar verder niks mee doet).
Volgens mij zijn short-circuit en het casten van een type naar een booleaanse waarde behoorlijk expliciet in C, als je daar geen gebruik van zou mogen maken omdat het onduidelijk zou zijn kun je 50% van de C software afschrijven.

Afgezien van dat zou ik deze manier ook niet kiezen in dit geval.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • pkuppens
  • Registratie: Juni 2007
  • Laatst online: 23:50
Haan schreef op woensdag 23 juli 2008 @ 14:15:
[...]

Een while loop met boolean vind ik toch duidelijker en netter
code:
1
2
3
4
5
6
boolean found = false;
int index = 0;
while(!found)
{
    if(a[index++]>0) found = true;
}

Liever iets meer typen dan kortere onduidelijke code :)

[...]

Jawel, wat er eerst stond was ook niet de bedoeling, ik heb het aangepast O-)
Ik haal wel 2 serieuze bugs uit jouw programma.
1. als je array geen getal > 0 bevat loop je uit je array
2. je index met postfix geeft de gewenste waarde +1 terug.

Je bent nog wel even bezig met je code te tunen totdat die precies doet wat ik wilde, en dan heb je alsnog redelijk onleesbare code.

Dan heb ik liever mijn regel code met twee regels commentaar dan jouw code.

Maar toegegeven, mijn code maakt wel gebruik van wat C finesses en 15+ jaar ervaring, zoals dat de i++ niet meer wordt gedaan als de conditie niet meer geldig is. En reken maar dat het in die 15 jaar regelmatig niet meteen goed is gegaan.

Ook vind ik een for loop een betere keuze hier, omdat de bewijslast van de correctheid van het programma van een for-loop eenvoudiger is dan van een while loop.

Verder ging de originele vraag over if statements, en daarin kan ik me voorstellen dat je minder staat te springen om zij-effecten.

  • pkuppens
  • Registratie: Juni 2007
  • Laatst online: 23:50
farlane schreef op woensdag 23 juli 2008 @ 15:11:
[...]


Volgens mij zijn short-circuit en het casten van een type naar een booleaanse waarde behoorlijk expliciet in C, als je daar geen gebruik van zou mogen maken omdat het onduidelijk zou zijn kun je 50% van de C software afschrijven.

Afgezien van dat zou ik deze manier ook niet kiezen in dit geval.
Een redelijk favoriete quote:
C combineert de snelheid van assembly met de leesbaarheid van assembly. :)

Maar ik was ook al met m'n for-loop in C teveel afgedwaald van de originele if in Java.

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 17-11 11:25
Herko_ter_Horst schreef op woensdag 23 juli 2008 @ 14:54:
[...]

Heb je het topic gelezen? Een voorbeeld als dit is al diverse keren voorbij gekomen en volgens mij zijn de meeste posters het er over eens dat dit niet de duidelijkste manier om zoiets op te schrijven. Ik vind het veel duidelijker om te schrijven:
code:
1
2
3
if(fp != null) {
 fclose(fp);
}
Nu maak je m.i. gebruik van maar liefst drie impliciete eigenschappen bij elkaar die extra mentale verwerkingskracht vergen om te snappen: short-circuit van boolean expressies, een leeg statement en het feit dat fpclose() blijkbaar een boolean retourneert (terwijl je daar verder niks mee doet).

Plus het feit dat je erg makkelijk over een leeg statement heen leest waardoor je kunt denken dat het eerstvolgende niet-lege statement wordt "beschermd" door de if.
Eens...

De enige reden die ik kan bedenken is dat het een syntax betreft die afgeleid is van C.

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
farlane schreef op woensdag 23 juli 2008 @ 15:11:
[...]
Volgens mij zijn short-circuit en het casten van een type naar een booleaanse waarde behoorlijk expliciet in C, als je daar geen gebruik van zou mogen maken omdat het onduidelijk zou zijn kun je 50% van de C software afschrijven.

Afgezien van dat zou ik deze manier ook niet kiezen in dit geval.
Dat was niet mijn punt: natuurlijk is het gedrag expliciet gedefinieerd ergens. Het punt is dat er gebruik wordt maakt van gedrag dat niet direct en triviaal afleesbaar is uit de code om iets korter op te kunnen schrijven. Het feit dat fclose() een int teruggeeft die gecast moet worden naar een boolean maakt het alleen maar lelijker (ik wist dat niet en ging er vanuit dat fclose() een boolean zou retourneren; in Java werkt deze constructie niet eens met een int). De bedoeling van de code raakt compleet ondergesneeuwd in de "slimme truukjes" van de programmeur.

Mijn "sanity check" is vaak om te proberen de code in natuurlijke taal voor te lezen (zoveel mogelijk). Leg dat naast wat je eigenlijk bedoelt met de code. Hoe meer de twee overeen komen, hoe groter de kans dat de code ook voor anderen duidelijk is.

Wat is het doel van de code:
als de file pointer een legale waarde bevatA, sluit dan de fileB
Wat staat er in de oorspronkelijke code:
als fp null is(1), of anders(2) als de aanroep van fclose(fp) true retourneert(3) (4), doe dan niks(5)
Wat staat er in de door mij geposte versie:
als fp niet null is(6), roep dan fclose(fp) aan(7)
Mentale stappen voor de vertaling van natuurlijke taal naar code die je altijd zult moeten doorlopen:

A: 'legaal' betekent voor een file pointer "niet null"
B: een file sluiten gaat via de fclose() method op de file pointer

Mentale stappen bij het lezen van deze code:

1: het tegengestelde van A
2: ('anders' vergeet je gauw mee te nemen)
3. Als fclose() true teruggeeft? Maar fclose() geeft toch een int terug? Oh ja die wordt gecast...
4. B, als side-effect
5. Niks? Ja maar... Oh wacht, fclose() was de bedoeling...

vs.

6. A
7. B

[ Voor 34% gewijzigd door Herko_ter_Horst op 23-07-2008 18:08 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Herko_ter_Horst schreef op woensdag 23 juli 2008 @ 17:21:
(ik wist dat niet en ging er vanuit dat fclose() een boolean zou retourneren; in Java werkt deze constructie niet eens met een int).
Als je dit soort dingen niet weet van de taal waarin je werkt ben je wat mij betreft niet geschikt om je werk te doen. Sterker nog, er hoeft niet eens gecast te worden omdat de if-statement niet expliciet met bools werkt maar met 0 en niet 0.

[ Voor 14% gewijzigd door PrisonerOfPain op 23-07-2008 18:26 ]


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
PrisonerOfPain schreef op woensdag 23 juli 2008 @ 18:22:
[...]
Als je dit soort dingen niet weet van de taal waarin je werkt ben je wat mij betreft niet geschikt om je werk te doen. Sterker nog, er hoeft niet eens gecast te worden omdat de if-statement niet expliciet met bools werkt maar met 0 en niet 0.
C is dan ook niet de taal waarin ik werk :) Overigens is fopen() is geen onderdeel van de taal, maar een onderdeel van een standaard-library.

Uit jouw flame reactie begrijp ik dat het zeer onwaarschijnlijk is dat een C programmeur dit niet zou weten, maar het gaat ook niet om deze specifieke functie (je hebt de [ALG] prefix voor dit topic gezien, alsmede de voorbeeldcode in diverse talen in de rest van dit topic, neem ik aan?).

Het gaat om het aantal mentale stappen dat je moet maken om de code te overzien.

Dus bedankt voor het versterken van mijn punt: ook zonder die kennis (die NIETS met het op te lossen "probleem" te maken heeft) is "mijn" versie van dezelfde code duidelijk.

[ Voor 25% gewijzigd door Herko_ter_Horst op 23-07-2008 19:35 ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Herko_ter_Horst schreef op woensdag 23 juli 2008 @ 19:15:
[...]

C is dan ook niet de taal waarin ik werk :) Overigens is fopen() is geen onderdeel van de taal, maar een onderdeel van een standaard-library.
Toch is het allebei onderdeel van dezelfde standaard ;). Verder is het natuurlijk onzin om te verwachtten dat je een willekeurig persoon op een project kan gooien en kan verwachtten 'ie er mee om kan gaan. Mijn punt was dus ook dat als je niets van een bepaalde omgeving af weet (dat kan de stdlib zijn, maar ook ZF, Lucene, Smalltalk of het bedrijfsframework) je simpelweg geen aannames kan maken over zulke statements in het programma.
Uit jouw flame reactie begrijp ik dat het zeer onwaarschijnlijk is dat een C programmeur dit niet zou weten, maar het gaat ook niet om deze specifieke functie (je hebt de [ALG] prefix voor dit topic gezien, alsmede de voorbeeldcode in diverse talen in de rest van dit topic, neem ik aan?).

Het gaat om het aantal mentale stappen dat je moet maken om de code te overzien.
Als programmeur (en zeker in C) dien je sowieso altijd op de hoede te zijn. Programmacode is dan ook geen simpel romannetje, maar een droge juridische tekst. Als je niet precies weet wat er staat heb je gewoon een probleem. Zelfs als je alles zo duidelijk en netjes mogelijk opschrijft heb je gewoon nog voor de hand liggende basiskennis nodig.
Dus bedankt voor het versterken van mijn punt: ook zonder die kennis (die NIETS met het op te lossen "probleem" te maken heeft) is "mijn" versie van dezelfde code duidelijk.
Het punt dat ik probeerde te maken was dan ook niet dat jou code op een willekeurige welke manier minder leesbaar was; het punt was dat je sowieso moet weten wat je aan het doen bent hoe eenvoudig het er dan ook uit ziet. Je vergiste je immers zelf ook ;)

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17-11 08:45

Haan

dotnetter

pkuppens schreef op woensdag 23 juli 2008 @ 16:25:
[...]


Ik haal wel 2 serieuze bugs uit jouw programma.
1. als je array geen getal > 0 bevat loop je uit je array
2. je index met postfix geeft de gewenste waarde +1 terug.
<knip>etc.
offtopic:
Het was ook maar een snel voorbeeldje, geen weldoordachte en uitvoerig geteste productiecode ;)

Kater? Eerst water, de rest komt later


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:21

crisp

Devver

Pixelated

Janoz schreef op dinsdag 22 juli 2008 @ 11:46:
nee, dat dacht ik even, maar ik heb net ff snel wat gechecked en dat blijkt niet zo te zijn.
In sommige talen kan dat wel:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function doSomething()
{
    alert('something');

    return true;
}

function doSomethingElse()
{
    alert('something else');

    return false;
}

function dontDoThis()
{
    alert('not doing this');

    return true;
}

doSomething() && doSomethingElse() && dontDoThis();


;)

Intentionally left blank


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Herko_ter_Horst schreef op woensdag 23 juli 2008 @ 17:21:
Dat was niet mijn punt: natuurlijk is het gedrag expliciet gedefinieerd ergens. Het punt is dat er gebruik wordt maakt van gedrag dat niet direct en triviaal afleesbaar is uit de code om iets korter op te kunnen schrijven.
Laten we voorop stellen dat in dit ( gemaakt ) voorbeeld ik het helemaal met je eens ben dat de versie die jij gebruikt veel duidelijker is.

Je haalt echter ook een tweetal eigenschappen aan die je mijns inziens als C programmeur ( het voorbeeld ging immers over een stukje C ) gewoon moet weten en herkennen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Herko_ter_Horst schreef op woensdag 23 juli 2008 @ 17:21:
Mijn "sanity check" is vaak om te proberen de code in natuurlijke taal voor te lezen (zoveel mogelijk). Leg dat naast wat je eigenlijk bedoelt met de code. Hoe meer de twee overeen komen, hoe groter de kans dat de code ook voor anderen duidelijk is.
Die "sanity check" heb je m.i. weer direct omzeepgeholpen door 8 voetnoten in je quotes op te nemen die je bij normale code als comment had kunnen zetten bij de stukken code waar 't relevant voor is. Enne... o ja, voetnoot 6) is blijkbaar verdwenen... ;)

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
farlane schreef op donderdag 24 juli 2008 @ 00:02:
[...]
Laten we voorop stellen dat in dit ( gemaakt ) voorbeeld ik het helemaal met je eens ben dat de versie die jij gebruikt veel duidelijker is.

Je haalt echter ook een tweetal eigenschappen aan die je mijns inziens als C programmeur ( het voorbeeld ging immers over een stukje C ) gewoon moet weten en herkennen.
Ok, daar ging het mij niet om (en ik ben zoals gezegd geen C programmeur). Natuurlijk ken je als programmeur de regels van de taal en weet je van standaard functies de betekenis en return value. Wat je weet c.q. kunt beredeneren en wat in 1 keer duidelijk is, zijn echter twee verschillende dingen.

"Any sufficiently advanced technology is indistinguishable from magic."


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op donderdag 24 juli 2008 @ 00:22:
[...]
Die "sanity check" heb je m.i. weer direct omzeepgeholpen door 8 voetnoten in je quotes op te nemen die je bij normale code als comment had kunnen zetten bij de stukken code waar 't relevant voor is. Enne... o ja, voetnoot 6) is blijkbaar verdwenen... ;)
De sanity check bestaat uit de "quotes", hoe je de programmacode als "normale" zin leest. De voetnoten heb ik er bij gezet om aan te geven welke mentale stappen je tijdens het lezen van zo'n zin nog moet nemen om er achter te komen dat de zin inderdaad voldoet aan wat je bedoelt, of andersom: om erachter te komen wat de bedoeling is/was.

Het lijkt mij duidelijk dat het eerste voorbeeld veel verder van de bedoeling van de code af ligt dan het tweede. Dat is voor mij het criterium om voor een bepaalde manier van opschrijven te kiezen.

Ja, natuurlijk kun je het coderen als in het eerste voorbeeld. Werkt het minstens net zo goed? Ja. Is het minder typ-werk? Ja. Is het duidelijker? Nee.

"Any sufficiently advanced technology is indistinguishable from magic."


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17-11 15:37

Janoz

Moderator Devschuur®

!litemod

crisp schreef op woensdag 23 juli 2008 @ 22:50:
[...]

In sommige talen kan dat wel:
Je sais. ik gaf immers zelf ook al het php 'iets or die()' voorbeeld. Het door jou gequote stukje ging dan ook over Java.

[ Voor 10% gewijzigd door Janoz op 24-07-2008 08:33 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1