[java] Switch is slecht ontworpen ?

Pagina: 1
Acties:
  • 201 views sinds 30-01-2008
  • Reageer

  • yrew
  • Registratie: Augustus 2001
  • Laatst online: 13:16
Ik lees net een stuk waarin wordt geschreven dat het switch statement een ramp is omdat code er voortdurend op hangt.

Heeft iemand hier een andere mening over of was ik tot nu toe de enige die switch statements ideaal vond ter vervanging van if statements?

Groetjes


  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 31-08 22:49
waar staat dat stuk dan?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

een switch die werkt volgens mij heel goed :) heb er nog nooit problemen mee gehad. Misschien omdat je een 'break' kan vergeten??

Ik gebruik tegenwoordig dit:
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
33
34
35
36
37
interface FruitSwitch{
   public void caseAppel(Appel appel);

   public void casePeer(Peer peer);
}

class FruitSwitchAdapter implements FruitSwitch{
   public void caseAppel(Appel appel){};
   
   public void casePeer(Peer peer){};
}

abstract class Fruit{

  public abstract void apply(FruitSwitch fruitSwitch);
}

class Peer extends Fruit{
   public void apply(FruitSwitch fruitSwitch){
     fruitSwitch.casePeer(this);
   }
}

class Appel extends Fruit{
   public void apply(FruitSwitch fruitSwitch){
    fruitSwitch.caseAppel(this);
   }
}

class PeerPers extends FruitSwitchAdapter{
    public void casePeer(Peer peer){
      System.out.println("pers peer");
    }
}

Fruit fruit = fruitMand.haalFruitVanPersoon("peter");
fruit.apply(new PeerPers());

Dit is handig als je veel types begint te krijgen en objecten niet wil vervuilen met allerlei niet interessante functies. En de fruitSwitchAdapter moet je eigelijk altijd van extenden want als er een extra type bij komt, moet iedereen die FruitSwitch gebruikt weer bijgewerkt worden en daar heb je met die adapter geen last van.

ps: dit is geloof ik het visitor design pattern.

Verwijderd

Op dinsdag 12 maart 2002 12:37 schreef Dash2in1 het volgende:
waar staat dat stuk dan?
Daar ben ik ook wel benieuwd naar...

Verwijderd

Het lijkt me ook niet erg waarschijnlijk dat zoiets fundamenteels als een switch-statement buggy is, en al zeker niet omdat Java al zo lang bestaat. (Vraag me niet hoe lang ;))

Verwijderd

Waar ik me wel altijd aan stoor is dat break statement, dat is volgens mij overbodig (en erg irritant als je het weer eens vergeet).

  • servies
  • Registratie: December 1999
  • Laatst online: 12:02

servies

Veni Vidi Servici

Op dinsdag 12 maart 2002 13:05 schreef Zef het volgende:
Waar ik me wel altijd aan stoor is dat break statement, dat is volgens mij overbodig (en erg irritant als je het weer eens vergeet).
Dus is het niet overbodig.

  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 09-09 14:51

thomaske

» » » » » »

Op dinsdag 12 maart 2002 13:05 schreef Zef het volgende:
Waar ik me wel altijd aan stoor is dat break statement, dat is volgens mij overbodig (en erg irritant als je het weer eens vergeet).
Hmm, dan is het toch niet echt overbodig he..! >:)

[edit]
fuk, te laat! ;)

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


Verwijderd

Op dinsdag 12 maart 2002 13:08 schreef servaas het volgende:

[..]

Dus is het niet overbodig.
Dan vraag ik me af waarom talen als pascal en modula-3 dan geen break (of variant daarop) hebben. En verder: Wat is dan het nut?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 13:05 schreef Zef het volgende:
Waar ik me wel altijd aan stoor is dat break statement, dat is volgens mij overbodig (en erg irritant als je het weer eens vergeet).
Ik plaatst meteen achter een case de break. Op die manier kan ik het minder snel vergeten. En de layout is ook vrij belangrijk, ik gebruik zelf dit:
code:
1
2
3
4
5
6
7
8
9
10
switch(a){
   case 1:
    ...
    break;
   case 2:
    ...
    break:
   default:
    ....
}

Maarja.. het kan gebeuren dat je het vergeet :) en het zijn echt van die dingen die je over het hoofd ziet als je aan het debuggen bent.

En ik vind persoonlijk het break commando ook overbodig. Ik heb nog nooit een waterval effect in mijn switch case gehad. Dus daarom zou er 'gebreakt' moet worden als je een nieuwe case tegenkomt ipv verder gaan.

  • Jelmer
  • Registratie: Maart 2000
  • Laatst online: 12-09 20:46
Die break is ervoor om dit soort dingen te maken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case 1:
{
// doe iets wat alleen van toepssing is op 1
}
case 2:
{
// doe iets wat van toepassing is op 1&2
break;
}

case3:
{
doe iets wat van toepassing is op alleen 3
break;
}

of is dit juist er misbruik van maken ;)

Verwijderd

Op dinsdag 12 maart 2002 13:10 schreef Jelmer Barhorst het volgende:
Die break is ervoor om dit soort dingen te maken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case 1:
{
// doe iets wat alleen van toepssing is op 1
}
case 2:
{
// doe iets wat van toepassing is op 1&2
break;
}

case3:
{
doe iets wat van toepassing is op alleen 3
break;
}
Hmm, ja maar hoe vaak komt dat voor? Ik heb switch nog nooit op zo'n manier gebruikt of ooit een situatie tegengekomen waar dit echt handig is. Je kunt het toch ook gewoon met een paar if statementjes doen?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 13:10 schreef Jelmer Barhorst het volgende:
Die break is ervoor om dit soort dingen te maken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case 1:
{
// doe iets wat alleen van toepssing is op 1
}
case 2:
{
// doe iets wat van toepassing is op 1&2
break;
}

case3:
{
doe iets wat van toepassing is op alleen 3
break;
}

of is dit juist er misbruik van maken ;)
Als ik bij jou 1 als case hebt dan doet hij 1&2 :+ daar heb je dus al weer een fout :) En ik heb nog nooit een waterval gebruikt.

[edit]
ik zit nog even te kijken maar ik was even iets te voorbarig :) Je had het goed. Maar ik vind dit wel een enorme k*t constructie. En zou het zelf zeker niet gebruiken.

Verwijderd

Gelukkig ben je er vrij in om 't wel of niet te gebruiken. Maar buggy is 't zeker niet!

  • Jelmer
  • Registratie: Maart 2000
  • Laatst online: 12-09 20:46
Hoe bedoel je precies? Als je nu case 1 hebt, voert hij uit wat er bij 1 staan en bij 2. Als je case 2 hebt, voert ie alleen wat er bij 2 staat uit.

:) (zelf zou ik het ook niet gebruiken hoor, maar ja dit is het enige waar ik die break van toepassing kan laten zijn)

  • yrew
  • Registratie: Augustus 2001
  • Laatst online: 13:16
Ik haalde het uit een java boek nadat een collega bijna over zijn nek ging omdat ik een switch wilde gebruiken. Het zijn ongeveer 4 regels met daarin woorden als dissaster en have to discard.

Het kwam op het volgende neer.

Van de 100 switch case constructies worden er 80 gebruikt voor situaties die al impliciet zijn vastgelegd. en maar 20 om willekeurige situaties af te handelen. En wanneer je dus al je programma verloop in bepaalde situatie's weet dan kun je net zo goed een if else gebruiken

Groetjes


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 13:20 schreef yrew het volgende:
Ik haalde het uit een java boek nadat een collega bijna over zijn nek ging omdat ik een switch wilde gebruiken. Het zijn ongeveer 4 regels met daarin woorden als dissaster en have to discard.

Het kwam op het volgende neer.

Van de 100 switch case constructies worden er 80 gebruikt voor situaties die al impliciet zijn vastgelegd. en maar 20 om willekeurige situaties af te handelen. En wanneer je dus al je programma verloop in bepaalde situatie's weet dan kun je net zo goed een if else gebruiken
Ik vind een goeie switch case statement een stuk beter te lezen dan een if else reeks. Je kan niet goed zien wat je cases zijn. Dus ik snap die man niet al te best.

  • yrew
  • Registratie: Augustus 2001
  • Laatst online: 13:16
gelukkig als ik het zo allemaal eens lees blijf ik lekker mijn cases gebruiken :-)

Groetjes


Verwijderd

Op dinsdag 12 maart 2002 13:12 schreef Zef het volgende:

[..]

Hmm, ja maar hoe vaak komt dat voor? Ik heb switch nog nooit op zo'n manier gebruikt of ooit een situatie tegengekomen waar dit echt handig is. Je kunt het toch ook gewoon met een paar if statementjes doen?
Wanneer je gebruik maakt van flags is het heel handig om er geen break in te zetten en dus een waterval situatie te creeeren...

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Wat is je hometaal? ;) In c/c++/pascal zou ik het me goed kunnen voorstellen, maar ik zie het niet vaak bij java.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 12 maart 2002 13:13 schreef Alarmnummer het volgende:
[edit]
ik zit nog even te kijken maar ik was even iets te voorbarig :) Je had het goed. Maar ik vind dit wel een enorme k*t constructie. En zou het zelf zeker niet gebruiken.
Toevallig eergisteren nog een nuttige toepassing gezien :+

Stel je hebt een cluster van webservers met elk 2 (of meer) ip's.
Die wil je zichzelf aan laten melden onder een unieke identifier vanuit je code. Dus je hebt eigenlijk geen toegang tot andere zaken dan bijvoorbeeld het ip-adres waar het script mee aangeroepen werd.

Dan kan je zoiets bouwen
PHP:
1
<?switch($HOST_ADDRESS){  case '123.123.123.1' :  {}  case '123.123.124.1' :  {     doetietsvoorserver1();    break;  }  case '123.123.123.2' :  {}  case '123.123.124.2' :  {     doetietsvoorserver2();    break;  }}?>

Etc :)

Wat ik wel mis aan java is de mogelijkheid om tekstuele cases uit te voeren. Zoiets als bovenstaande voorbeeld uit php :)

[edit]
uiteraard zijn er voor bovenstaand voorbeeld 1001 andere mogelijkheden waarvan zeker 10 variantgroepen allemaal ook handig zijn...

Verwijderd

Op dinsdag 12 maart 2002 13:20 schreef yrew het volgende:
Ik haalde het uit een java boek nadat een collega bijna over zijn nek ging omdat ik een switch wilde gebruiken. Het zijn ongeveer 4 regels met daarin woorden als dissaster en have to discard.

Het kwam op het volgende neer.

Van de 100 switch case constructies worden er 80 gebruikt voor situaties die al impliciet zijn vastgelegd. en maar 20 om willekeurige situaties af te handelen. En wanneer je dus al je programma verloop in bepaalde situatie's weet dan kun je net zo goed een if else gebruiken
Sorry maar das dus de grootste onzin, als je het verloop van je programma al weet maak geen gebruik van het switch statement noch het if-else statement...

We gaan natuurlijk alleen die 20 procent in een voorwaarde zetten, en dan moet je een afweging maken welke handiger is, oftewel welke de leesbaarheid van de code het meest te goede komt.

  • yrew
  • Registratie: Augustus 2001
  • Laatst online: 13:16
Ja textuele cases zijn er niet maar ik mis ze ook niet. Je kunt elke String toch vervangen door een int

Groetjes


Verwijderd

Op dinsdag 12 maart 2002 13:32 schreef ACM het volgende:
[..]
[edit]
uiteraard zijn er voor bovenstaand voorbeeld 1001 andere mogelijkheden waarvan zeker 10 variantgroepen allemaal ook handig zijn...
Op zich wel, maar ook wel begrijpelijk dat je ze alleen op primitieve types kunt uitvoeren. In PHP maakt dat allemaal geen verschil. Maar hoe wou je dat in java doen? Dan moet er dus voor elke object een equals methode bestaan (en dat is meen ik niet zo?) zodat je de objecten kunt vergelijken...

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 12 maart 2002 13:34 schreef yrew het volgende:
Ja textuele cases zijn er niet maar ik mis ze ook niet. Je kunt elke String toch vervangen door een int
Ja, dat kan. Maar waarom zou je perse alle strings in int's moeten veranderen. Trouwens. Je _moet_ vorogedefinieerde waarden gebruiken. Dus _moet_ je van te voren allerlei dingen uithalen om waarden voor je Strings te bedenken.

In php voeg je gewoon een nieuwe case toe met een string waarde in dat geval en klaar. Bij php moet je helemaal lastig doen met allerlei conversie zaken.
Op dinsdag 12 maart 2002 13:35 schreef Zef het volgende:
Maar hoe wou je dat in java doen? Dan moet er dus voor elke object een equals methode bestaan (en dat is meen ik niet zo?) zodat je de objecten kunt vergelijken...
Dan laat je het alleen met Comparable's werken...
Die hebben gegarandeerd een equals methode.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 13:32 schreef ACM het volgende:

[..]

Toevallig eergisteren nog een nuttige toepassing gezien :+

Stel je hebt een cluster van webservers met elk 2 (of meer) ip's.
Die wil je zichzelf aan laten melden onder een unieke identifier vanuit je code. Dus je hebt eigenlijk geen toegang tot andere zaken dan bijvoorbeeld het ip-adres waar het script mee aangeroepen werd.

--geen code ivm verneukte layout.

Wat ik wel mis aan java is de mogelijkheid om tekstuele cases uit te voeren. Zoiets als bovenstaande voorbeeld uit php :)

[edit]
uiteraard zijn er voor bovenstaand voorbeeld 1001 andere mogelijkheden waarvan zeker 10 variantgroepen allemaal ook handig zijn...
Is dit dan niet handiger?
code:
1
2
3
4
5
6
7
8
9
10
11
12
switch(ip){
  case '1.1.1.1':
     doWebServer1Stuff();
     break;
  case '1.1.1.2':
    doWebServer1Stuff();
    break;
  case '1.1.2.1':
    doWebServer2Stuff();
    break;
  ....
}

Verwijderd

Op dinsdag 12 maart 2002 13:32 schreef ACM het volgende:
[...]
Wat ik wel mis aan java is de mogelijkheid om tekstuele cases uit te voeren. Zoiets als bovenstaande voorbeeld uit php :)
Ja daar ben ik het niet met je eens, een voorwaarde wordt altijd geëvalueerd naar een getal (0 voor false en groter dan 0 voor true). En juist een ip adress zoals in jouw voorbeeld hoort natuurlijk gewoon een integer te zijn een geen string.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 10:37

Creepy

Tactical Espionage Splatterer

(jarig!)
Op dinsdag 12 maart 2002 13:09 schreef Zef het volgende:

[..]

Dan vraag ik me af waarom talen als pascal en modula-3 dan geen break (of variant daarop) hebben. En verder: Wat is dan het nut?
code:
1
2
3
4
case blaat of
1,2: { doe iets wat voor 1 en 2 geld }
3: { doe iets wat voor 3 geld }
end;

Daarom bestaat break in pascal niet. In C/Java is dit niet mogelijk. Daarom bestaat break wel in C/Java.

En dat stukje over dat je van te voren precies weet welke situaties zich voor kunnen doen: De eerste "pogingen" van een case/switch statement hadden geen else constructie, zodat je voor elke case/switch je alle situaties moest weten. Daar werd vervolgens zo om heen geprogrammerd:
code:
1
2
3
4
5
6
7
8
9
10
if ((c > 0) && (c < 4))
{
  switch (c) {
  case 1: //
  case 2: //
  case 3: //
  }
} else { 
  //
}

Dus werd de case uitgebreidt met een else statement
code:
1
2
3
4
5
6
7
8
switch (c) {
case 1: //
case 2: //
case 3: //
else 
    { // }

}

Als je bijv. 100 situaties hebt, is een case/switch naar mijn idee beter leesbaar als 100 if's achter/onder elkaar.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • elnino
  • Registratie: Augustus 2001
  • Laatst online: 03-09 05:13
Switch is (net als break) eigenlijk nog een soort overblijfsel van GoTo, vandaar ook na iedere case een dubbele punt en ik vind het wel een handig middel, maar ik stoor me, net zoals Zef, ook aan het break-statement. Het zou volgens mij vele malen logischer zijn om bijv. het volgende te hebben:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
switch(...)
{
    case 1, 2, ...
    {
      code;
    }
    case 4, 5, ...
    {
      code;
    }
    default
    {
      code;
    }
}

Maar gelukkig kan je altijd { en } toevoegen bij switch'es, dus doe ik het meestal dan zo:
code:
1
2
3
4
5
6
7
8
9
switch(...)
{
    case 1:
    case 2:
    {
      code;
      break;
    }
}

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 12 maart 2002 13:39 schreef markvleth het volgende:
En juist een ip adress zoals in jouw voorbeeld hoort natuurlijk gewoon een integer te zijn een geen string.
Ach, de code is een stuk leesbaarder als je de ip's ziet als String, ipv als getal.

Vooral omdat je vervolgens toch weer de bewerkingen die bij een speciale server horen moet uitvoeren.

En het was gewoon maar een voorbeeld.
Op dinsdag 12 maart 2002 13:37 schreef Alarmnummer het volgende:
Is dit dan niet handiger?
Vast wel, maar waarom zou je 2 (of meer) keer hetzelfde opschrijven als het niet hoeft? ;)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 14:12 schreef elnino het volgende:
Maar gelukkig kan je altijd { en } toevoegen bij switch'es, dus doe ik het meestal dan zo:
code:
1
2
3
4
5
6
7
8
9
switch(...)
{
    case 1:
    case 2:
    {
      code;
      break;
    }
}
Wat is de toegevoegde waarde van die extra accolades?
code:
1
2
3
4
5
6
7
8
switch(..){
   case 1:
   case 2:
    ...
    ...
    break;
   ...
}

kan ook uitstekend. De enigste reden dat ik zelf zo nu en dan accolades gebruik is dat de scope van een variable gedeclareerd in een case over alle onderliggende cases zichtbaar is.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
switch(..){
   case 1:
    {
        String s = haalNaam();
    }
    break
   case 2:
    {
        String s = haalWoonplaats();
    }
    break;
   ...
}

Ik doe dit als een variable naam nodig heb die in beide cases voorkomt en geen zin heb/nut heeft om een nieuwe te bedenken.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 14:17 schreef ACM het volgende:

Vast wel, maar waarom zou je 2 (of meer) keer hetzelfde opschrijven als het niet hoeft? ;)
Omdat het duidelijker is, en een functie naam 2 keer opschrijven vind ik nog niet zo`n groot probleem ;)

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op dinsdag 12 maart 2002 14:23 schreef Alarmnummer het volgende:
Omdat het duidelijker is, en een functie naam 2 keer opschrijven vind ik nog niet zo`n groot probleem ;)
En 5x 3x hetzelfde doen? ;)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op dinsdag 12 maart 2002 14:24 schreef ACM het volgende:

[..]

En 5x 3x hetzelfde doen? ;)
ctrl c + ctrl v ;)

Maar ik snap waar je heen wilt, maar ik zou dan nog geen waterval gebruiken.

Verwijderd

Mompel mompel, Duff's device, mompel...

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik heb het even opgezocht:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
register n = (count + 7) / 8;   /* count > 0 assumed */

   switch (count % 8)
   {
   case 0:    do {  *to = *from++;
   case 7:        *to = *from++;
   case 6:        *to = *from++;
   case 5:        *to = *from++;
   case 4:        *to = *from++;
   case 3:        *to = *from++;
   case 2:        *to = *from++;
   case 1:        *to = *from++;
                } while (--n > 0);
   }

AAAARRRGGGGHHHHHH :) Wat een zaad constructie zeg. Volledig misbruik van een switch case en slecht te lezen. (Kan trouwens alleen in c geloof ik.. gelukkig )

Verwijderd

Gatverdamme! :D

Verwijderd

Ik dacht dat ik ooit eens ergens gelezen dat het switch statement ook beter te optimaliseren is dan een if..else if..etc. (Stond dat niet ergens in de MSDN C++ docs?). Dat zou dus een reden kunnen zijn om juist wel een switch te gebruiken...vind het zelf ook wel overzichtelijk eigenlijk.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op dinsdag 12 maart 2002 13:32 schreef ACM het volgende:
Wat ik wel mis aan java is de mogelijkheid om tekstuele cases uit te voeren. Zoiets als bovenstaande voorbeeld uit php :)
C# kan wel een switch op een string uitvoeren :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 12 maart 2002 14:21 schreef Alarmnummer het volgende:

[..]

Wat is de toegevoegde waarde van die extra accolades?
dan kun je locale variabelen declareren in je case block, zonder accolades gaat dat niet :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 12 maart 2002 15:48 schreef Alarmnummer het volgende:
Ik heb het even opgezocht:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
register n = (count + 7) / 8;   /* count > 0 assumed */

   switch (count % 8)
   {
   case 0:    do {  *to = *from++;
   case 7:        *to = *from++;
   case 6:        *to = *from++;
   case 5:        *to = *from++;
   case 4:        *to = *from++;
   case 3:        *to = *from++;
   case 2:        *to = *from++;
   case 1:        *to = *from++;
                } while (--n > 0);
   }

AAAARRRGGGGHHHHHH :) Wat een zaad constructie zeg. Volledig misbruik van een switch case en slecht te lezen. (Kan trouwens alleen in c geloof ik.. gelukkig )
iiieuw wat is dat? :)
wat doet het eigenlijk? lijkt me een beetje nutteloos stukje...

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

dat is Duff's device.

ff opzoeken op google ofzo..

offtopic:
futurama is toch al lang gestopt?? Ik download ze zo nu en
dan van het internet.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 12-09 23:01
Misschien dat er OO bewegingen zijn die dit beweren en liever het eerder genoemde Visitor pattern liever gebruiken?

Veel switch instructies in een OO project kan er op duiden dat het ontwerp niet helemaal koosjer in elkaar zit.

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.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 12-09 23:01
Op dinsdag 12 maart 2002 20:22 schreef OiSyN het volgende:

[..]

iiieuw wat is dat? :)
wat doet het eigenlijk? lijkt me een beetje nutteloos stukje...
Een quote uit het 'writing unmaintainable code' handboek ? :)

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.


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

Op dinsdag 12 maart 2002 20:22 schreef OiSyN het volgende:

[..]

iiieuw wat is dat? :)
wat doet het eigenlijk? lijkt me een beetje nutteloos stukje...
"Duff's Device, a devious mechanism for massive loop unrolling."

Wat het ding doet is in feite een simpele byte-copy-loop
maar dan geunrolled (een bekende code optimalisatie).

Een goede compiler zal dit automatisch voor je doen
maar soms is het nodig om het toch zelf uit te schrijven.
Dit stukje C is in handgeschreven assembly niet of
nauwelijks sneller te krijgen.

FireFox - neem het web in eigen hand


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Het probleem met switch statements (in het algemeen in elke willekeurige taal die deze constructie ondersteund) is dat je geneigd bent minder zorgvuldig te zijn dan met de zelfde zaken in een if/else boom.

Stel je vangt een bepaalde switch mogelijkheid niet goed op, bijvoorbeeld je default afhandeling ontbreekt of is niet volledig, dat kan nare gevolgen hebben. Geld ook voor if/else structuren, maar daar wordt meestal beter naar gekeken dan naar switch structuren.

Trouwens, veel compilers bouwen een switch onder water ook om naar code die gelijk is aan hetzelfde gegoten in een if/else structuur.

Vreemde vastlopers zijn over het algemeen altijd programmer error en worden doorgaans niet veroorzaakt door een probleem in de implementatie taal die je gebruikt. Je mag van een redelijk doorontwikkelde taal toch wel uitgaan dat de basis statements grondig getest en dus bugvrij te beschouwen zijn.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 12 maart 2002 21:30 schreef Alarmnummer het volgende:
dat is Duff's device.

offtopic:
futurama is toch al lang gestopt?? Ik download ze zo nu en
dan van het internet.
nee hoor, ze zijn nog steeds aan het uitzenden (in de VS dus), maar ze wilden de hele cast ontslaan omdat seizoen 4 toch al helemaal af was. Tegen de tijd dat ze seizoen 5 willen uitzenden wilden ze een nieuwe cast inhuren (andere mensen, dus niet dezelfde futurama |:()
Op dinsdag 12 maart 2002 22:09 schreef PommeFritz het volgende:

[..]

"Duff's Device, a devious mechanism for massive loop unrolling."

Wat het ding doet is in feite een simpele byte-copy-loop
maar dan geunrolled (een bekende code optimalisatie).

Een goede compiler zal dit automatisch voor je doen
maar soms is het nodig om het toch zelf uit te schrijven.
Dit stukje C is in handgeschreven assembly niet of
nauwelijks sneller te krijgen.
uhm ja wel loos dat ze dan de modulo operator gebruiken en niet de and (hetzelfde geldt voor de division operator ipv een rightshift)... en bovendien wordt to niet geincrement . En het lijkt me stug dat het in asm niet sneller te krijgen is. Elke instructie is hier afhankelijk van de vorige, maw het is niet te pipelinen. Het zal beter gaan als je met indices 0 t/m 7 werkt en dan aan het eind steeds 8 bij de pointers optellen
just a thought :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

Op dinsdag 12 maart 2002 23:04 schreef OiSyN het volgende:

[..]

uhm ja wel loos dat ze dan de modulo operator gebruiken en niet de and (hetzelfde geldt voor de division operator ipv een rightshift)... en bovendien wordt to niet geincrement .
"Note that the omission of postfix ++ from *to was intentional (though confusing). Duff's device can be used to implement memory copy, but the original aim was to copy values serially into a magic IO register."
Je kunt dus *to++ gebruiken om er een byte-copy-loop van te maken.
En het lijkt me stug dat het in asm niet sneller te krijgen is. Elke instructie is hier afhankelijk van de vorige, maw het is niet te pipelinen. Het zal beter gaan als je met indices 0 t/m 7 werkt en dan aan het eind steeds 8 bij de pointers optellen
Hmmm ik herinner me weer een mooi staaltje 680x0 assembly
code:
1
2
.loop: movem.l d1-d7/a0-a6,(a7)+
     dbra d0, .loop

plaats 14 32-bits registers in 1 keer achter elkaar in het geheugen (=56 bytes)en auto-increment de target address (a7).
Verlaag register d0 en herhaal zolang die niet 0 is :)

FireFox - neem het web in eigen hand


  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
Op dinsdag 12 maart 2002 23:04 schreef OiSyN het volgende:

En het lijkt me stug dat het in asm niet sneller te krijgen is. Elke instructie is hier afhankelijk van de vorige, maw het is niet te pipelinen. Het zal beter gaan als je met indices 0 t/m 7 werkt en dan aan het eind steeds 8 bij de pointers optellen
just a thought :)
Toen Duff dat schreef bestonden er nog geen pipelines.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

TlighT: Toen Duff dat schreef bestonden er nog geen pipelines.
Lijkt me vreemd dat hij het dan in C geschreven heeft, terwijl C ontworpen is voor UNIX... Does it ring a bell? ;)
Orphix: C# kan wel een switch op een string uitvoeren :)
in dat codebase topic staat ook een stukje macro-code voor C, C++ waarmee je een switch op strings kunt doen.

Is het voor Java niet mogelijk op een of andere manier een interface er voor te schrijven? hm...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • yrew
  • Registratie: Augustus 2001
  • Laatst online: 13:16
Je kunt ook een hashtable aanmaken en daar al je strings inzetten. Dan de index van die hashtable als case gebruiken.

Groetjes


  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 10-07 04:13

PommeFritz

...geen friet

Op woensdag 13 maart 2002 08:52 schreef drm het volgende:
Lijkt me vreemd dat hij het dan in C geschreven heeft, terwijl C ontworpen is voor UNIX... Does it ring a bell? ;)
Ehh volgens mij ben je in de war met Unix pipes... dat is iets heeel anders dan de pipelining waar hierboven over gesproken werd.

FireFox - neem het web in eigen hand


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 13 maart 2002 08:32 schreef TlighT het volgende:

[..]

Toen Duff dat schreef bestonden er nog geen pipelines.
ja dat vermoeden had ik dus al :)
loop unrolling is ook sinds de PII (ongeveer) niet nuttig meer door de goede branch prediction enzo, en kan het vaak negatief uitpakken omdat je meer instructies hebt waardoor je instructiecache vaker vernieuwd moet worden :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

PommeFritz:
Ehh volgens mij ben je in de war met Unix pipes... dat is iets heeel anders dan de pipelining waar hierboven over gesproken werd.
* drm mag niet meer voor 10 uur 'sochtends posten :z

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • elnino
  • Registratie: Augustus 2001
  • Laatst online: 03-09 05:13
Op dinsdag 12 maart 2002 14:21 schreef Alarmnummer het volgende:
Wat is de toegevoegde waarde van die extra accolades?
[..]
kan ook uitstekend. De enigste reden dat ik zelf zo nu en dan accolades gebruik is dat de scope van een variable gedeclareerd in een case over alle onderliggende cases zichtbaar is.
Het heeft eigenlijk 2 redenen: als eerste omdat je zo variabelen binnen een scope kan definiëren en ten tweede ik het een stuk overzichtelijker vind. Overal wordt in je code { en } gebruikt, dus waarom bij cases niet?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

elnino: Overal wordt in je code { en } gebruikt, dus waarom bij cases niet?
omdat je een case meer moet zien als een label dan als een compound statement (met de daarbij behorende eigen scope) :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • elnino
  • Registratie: Augustus 2001
  • Laatst online: 03-09 05:13
Op woensdag 13 maart 2002 21:56 schreef OiSyN het volgende:
omdat je een case meer moet zien als een label dan als een compound statement (met de daarbij behorende eigen scope) :)
Het switch-case statement is inderdaad een overblijfsel van Goto. Misschien verklaart dat ook mijn (lichte) afkeer van die manier van schrijven.

Maar switch-statements kunnen op sommige manieren een slecht beeld geven, zoals in het volgende voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
switch (...)
{
    case 1:
      code1;
    case 2:
      code2;
    case 3:
      code3;
    default:
      code4;
}

Als de waarde '1' is, dan zullen alle codes daaronder uitgevoerd worden. Het kan dus in sommige situaties onduidelijk werken (uiteraard moet een goede programmeur dat voorkomen door break; te gebruiken). Ik heb dan liever { en }'s en dat je geen break hoeft te gebruiken, maar daarover zullen de meningen wel verschillen.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op woensdag 13 maart 2002 22:07 schreef elnino het volgende:

[..]

Het switch-case statement is inderdaad een overblijfsel van Goto. Misschien verklaart dat ook mijn (lichte) afkeer van die manier van schrijven.
Ik heb geen problemen met switch case statement omdat je heel duidelijk de cases kan afleiden waaruit je kan kiezen en daarom ook stukken makkelijker te lezen zijn tov een lading if statement. Maar wil je me eens uitleggen waarom dit nog uit het goto tijdperk komt? Een switch is misschien wel niet erg oo ;) maar ik vind het wel een mooie constructie.
Maar switch-statements kunnen op sommige manieren een slecht beeld geven, zoals in het volgende voorbeeld:
code:
1
2
3
4
5
6
7
8
9
10
11
switch (...)
{
    case 1:
   code1;
    case 2:
   code2;
    case 3:
   code3;
    default:
   code4;
}

Als de waarde '1' is, dan zullen alle codes daaronder uitgevoerd worden. Het kan dus in sommige situaties onduidelijk werken (uiteraard moet een goede programmeur dat voorkomen door break; te gebruiken). Ik heb dan liever { en }'s en dat je geen break hoeft te gebruiken, maar daarover zullen de meningen wel verschillen.
Waterval is badddddd :) En om mij had die break ook wel weg gemogen. Automatisch 'breaken' als je een nieuwe case/default tegenkomt.

  • TheOneLLama
  • Registratie: Oktober 2000
  • Laatst online: 20-01-2022

TheOneLLama

A llama like no llama before

Op woensdag 13 maart 2002 23:13 schreef Alarmnummer het volgende:

Waterval is badddddd :) En om mij had die break ook wel weg gemogen. Automatisch 'breaken' als je een nieuwe case/default tegenkomt.
Een switch zonder break is gewoon if {} else if {} else if{} etc.
Een switch met breaks kan toch een aantal mooie
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
final int ERROR_NOTFOUND = 404;
final int ERROR_NOTALLOWED = 401;
final int ERROR_NOTIMPLEMENTED = 402;

final int ERROR_INTERNAL = 500;
final int ERROR_NOTSUPPORTED = 501;

switch(i) {
  case 200:
    System.out.println("werkt");
    break;

  case ERROR_NOTALLOWED:
    System.out.println("je moet ingelogged zijn");
    /* falls through */

  case ERROR_NOTFOUND: 
  case ERROR_NOTALLOWED:
  case ERROR_NOTIMPLEMENTED:
  case ERROR_INTERNAL:
  case ERROR_NOTSUPPORTED: 
    System.out.println("fout: "+i);
    break;
  }

Om dat allemaal met if en else te gaan doen..

Opera OpenOffice.org Jabber Psi jabber://llama@mordax.com


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

een switch zonder breaks is niet een reeks met if else statements.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch(a){
    case 1: 
        System.out.println("1");
    case 2:
        System.out.println("2");
    case 3:
        System.out.println("3");
     
}

if(a==1){
    System.out.println("1");
}else if(a==2){
    System.out.println("2");
}else if(a==3){
    System.out.println("3");
}

Als ik in de case met a=1 erin ga, dan krijg ik 123 op de out en als ik in de if reeks met a=1 erin ga dan krijg ik alleen 1 op de out.

En ik heb zelf nog nooit de behoefte gehad om in java een waterval te maken. (in c gebruikte ik ze wel).

Maar volgens mij heb jij zonder en met door elkaar gehaald, want dan klopt je berichtje beter :) Of we begrijpen elkaar verkeerd :)

Verwijderd

Wat ik heel erg mis in het Switch statement is, behalve dan het vergelijken van strings, het maken van een samengestelde vergelijking.

In VB kan je doen:
code:
1
2
3
4
5
6
7
8
Select Case variabele
    Case 1
      Doe iets
    Case (>1 AND <4)
      Doe iets anders
    Case (>=4 OR <0)
      Doe de default afhandeling
End Select

Volgens mij kun je in VB zelfs object-variabelen in een Select Case gebruiken, toch wel handiger lijkt mij!

En intern wordt het toch vertaald naar If Then, dus het is alleen maar voor de leesbaarheid van je code.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op donderdag 14 maart 2002 13:24 schreef IJskoud het volgende:
Wat ik heel erg mis in het Switch statement is, behalve dan het vergelijken van strings, het maken van een samengestelde vergelijking.

In VB kan je doen:
code:
1
2
3
4
5
6
7
8
Select Case variabele
    Case 1
      Doe iets
    Case (>1 AND <4)
      Doe iets anders
    Case (>=4 OR <0)
      Doe de default afhandeling
End Select

Volgens mij kun je in VB zelfs object-variabelen in een Select Case gebruiken, toch wel handiger lijkt mij!
Ik ben blij! dat dit niet kan in java omdat het misleidend is. Het zou namelijk kunnen voorkomen dat op jouw manier meerdere cases zijn die voldoen en je zou alleen de eerst pakken. Bij de java switch is dit niet mogelijk omdat iedere case uniek is.
En intern wordt het toch vertaald naar If Then, dus het is alleen maar voor de leesbaarheid van je code.
Absoluut niet, check out de vm specs.

Als de case waarden opeen volgend zijn:
code:
1
2
3
4
5
6
7
8
int chooseNear(int i) {
    switch (i) {
      case 0:  return 0;
      case 1:  return 1;
      case 2:  return 2;
      default: return -1;
    }
}

dan krijg je de volgende bytecode.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Method int chooseNear(int)
0iload_1          // Push local variable 1 (argument i)
1 tableswitch 0 to 2: // Valid indices are 0 through 2
   0: 28          // If i is 0, continue at 28
   1: 30          // If i is 1, continue at 30
   2: 32          // If i is 2, continue at 32
   default:34      // Otherwise, continue at 34
28 iconst_0      // i was 0; push int constant 0...
29 ireturn      // ...and return it
30 iconst_1      // i was 1; push int constant 1...
31 ireturn      // ...and return it
32 iconst_2      // i was 2; push int constant 2...
33 ireturn      // ...and return it
34 iconst_m1        // otherwise push int constant -1...
35 ireturn

Nu kan eenvoudig met een voorafgaande boundcheck worden geindexeerd (index waarde is waarde van de case) naar het adres waar naar toe gesprongen moet worden. Je kan het zien als een soort hash berekening waar je naar toe moet springen.

Bij n opeen volgende elementen in je case commando kost het bij een if else vertaling reeks n/2 check acties, dus naarmate n groter wordt kost het meer tijd. Bij de switch case kost het altijd een vaste tijd omdat aan de hand van de switch waarde gesprongen kan worden naar de juiste index(case) in de tabel en aan de hand daarvan naar de code die hoort bij de case.

Als de waarden wat verder uit elkaar liggen dan gaat dit niet op (omdat je namelijk enorm grote tables begint te krijgen)

vb:
code:
1
2
3
4
5
6
7
8
int chooseFar(int i) {
    switch (i) {
      case -100: return -1;
      case 0:   return 0;
      case 100:  return 1;
      default:   return -1;
    }
}

bytecode
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Method int chooseFar(int)
0 iload_1
1 lookupswitch 3:
    -100    : 36
    0    : 38
    100     : 40
    default :42
36 iconst_m1
37 ireturn
38 iconst_0
39 ireturn
40 iconst_1
41 ireturn
42 iconst_m1
43 ireturn

Wat er in dit geval gebeurt is dat de specificaties van de vm voorschrijven dat de keys gesorteerd moeten worden. Afhankelijk van de implementatie van de vm wordt daar een algoritme voor bedacht.

Stel dat je het in een gesorteerde binaire boom zou plaatjes dan ben je log(n) zoek acties kwijt ipv n/2 van de if else reeks. (Je zou ook 'binair' kunnen zoeken in de table door eerst op de helft te kijken en dan kijken of de case groter of kleiner is dan de switch enz enz).

En switch case commando wordt door de vm niet herschreven tot een reeks if else commando`s.

uitleg vm:
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Compiling.doc.html

en dan ff doorscrollen naar 7.10

  • Johannes
  • Registratie: Juni 2000
  • Laatst online: 27-08 21:32
Op dinsdag 12 maart 2002 13:32 schreef ACM het volgende:
[edit]
uiteraard zijn er voor bovenstaand voorbeeld 1001 andere mogelijkheden waarvan zeker 10 variantgroepen allemaal ook handig zijn...
Dit is misschien niet mogelijk in alle talen, maar wat ik zelf vaak doe in Python:
code:
1
2
3
4
5
6
# Dictionary is een soort van hashtable.
Dict = {
'121.121.121.121':DoServer1, 
'121.121.124.121':DoServer1, 
'121.121.121.122':DoServer2}
apply(Dict[HOST_ADRESS])

Het fijne is dat je ook at-runtime je Dict kan updaten, niet alleen at-compiletime. Ook kun je de Dict laten meegeven door de aanroepende. Ik weet niet of dit mogelijk is in Java(er hoeft alleen maar een manier te zijn om dynamisch een functie aan te roepen), maar het lijkt me wel mooi.
Ik geloof dat Bruce Eckel er ook een stukje over gaat schrijven in Thinking in Python(eerst: Thinking in Patterns), hij noemde het table-driven code.

Uit volle borst op weg naar nergens / Zonder reden zonder doel
Met m'n zeden en m'n zonden / En mijn angstig voorgevoel
Laat mij mijn kont tegen de krib / Laat mij dit goddeloze lied
Hef jij je handen maar ten hemel / Maar red mij niet


  • TheOneLLama
  • Registratie: Oktober 2000
  • Laatst online: 20-01-2022

TheOneLLama

A llama like no llama before

Op donderdag 14 maart 2002 12:08 schreef Alarmnummer het volgende:
een switch zonder breaks is niet een reeks met if else statements.
Maar volgens mij heb jij zonder en met door elkaar gehaald, want dan klopt je berichtje beter :) Of we begrijpen elkaar verkeerd :)
we begrijpen elkaar verkeerd, ik bedoelde als je het "break" gedeelte van de switch eruit haalt (en er vanuit gaat dat er altijd gebroken word) *dan* is een case statement net een if else if etc. statement: oftewel, dan kan je dat hele switch statement net zo goed weggooien.

Misschien heb jij er nooit behoefte aan om switch te gebruiken, ik heb constructies zoals ik als voorbeeld heb gegeven wel gewoon in m'n code staan, en ik moet zeggen dat ik ze gewoon netjes en overzichtelijk vind..

Opera OpenOffice.org Jabber Psi jabber://llama@mordax.com

Pagina: 1