Egy új programozási nyelv - esetelágazás
2011-07-11T10:56:43+02:00
2011-08-01T08:01:26+02:00
2022-07-18T21:15:24+02:00
  • Értem a hátrányát, ez egy design tradeoff.

    Feltéve, hogy az értékadás visszatérési értéke void (amit üdvözlendőnek tartanék), a probléma akkor jelentkezik csak, ha egy metódus utolsó expressioneként valamit visszaadó (nem void) függvényt hívsz, de csak mellékhatásért, vagyis az értékét nem adod értékül semminek. Ez valamit véletlen (nem 'szándékunk szerint') visszaad, amit hívásoldalon meg kihasználsz.

    Kérdés, hogy ez mennyire gyakori. A gyakorlatban ha valami értéket ad vissza, azt nagyrészt értékül is adom valaminek, vagyis nem fog ott lógni csak úgy meghívva a metódusom végén, ha meg nem akarom, hogy bármit visszaadjon egy metódusom, legtöbbször return this-t írok, hogy működjön a method chaining.

    De tényleg ízlés kérdése. A nagyon durva implicit varázslásokat én sem szeretem, de ez nekem még nagyon fekszene, mert jóval elegánsabbá tenne sok programomat. (Scala-ban pl., vagy CoffeeScript-ben persze így van, (talán Ruby-ban is ha jól emlékszem?) de legtöbb programomat nem ezekben a 'minden ami csak lehet kifejezés' jellegű funkcionálisprogramozás-barát nyelvekben írom.)
    Mutasd a teljes hozzászólást!
  • Illetve hozzátenném, hogy egy jó nyelvben minden blokk is ad vissza értéket az utolsó kifejezésének az értékét. Továbbá ha egy metódus void-ot adna vissza, az igazából 'this'-t ad vissza a method chaining elegáns támogatása miatt.


    Ez szerintem ízlésfüggő, nem mondanám, hogy általában véve "jó" dolog. Én biztos nem szeretném, hogy a függvényem végére egy plusz sort írva megváltozzon a visszatérési értéke, esetleg a visszatérési típusa is. Mivel nem írtam ki explicite a returnt, lehet, hogy én nem is akartam értéket visszaadni, de közben egy másik kód már épít erre a visszatérési értékre...

    "Explicit is better than implicit", ahogy a Zen of Python is mondja

    (Persze ez is csak valakinek az ízlése, konkrétan Guido van Rossumé.)
    Mutasd a teljes hozzászólást!
  • Én igazából nem nagyon találtam fel semmit, csak a Scala switch-jét butítottam le. A Scala switch-je majdnem mindent tud, amit leírtam, meg még többet is. (A Scala már-már túlbonyolított nyelv (még az én ízlésem szerint is)).

    Ezt a VB.NET-et nem ismertem, de így első ránézésre borzalmasan szószátyárnak tűnik. Nem egy kifejező tömör nyelv, inkább olyan oldschool 4GL feeling.
    Ha jól látom pl. egyáltalán nem funkcionális, a switch case nem is ad vissza értéket. Hát én ezt nem szívesen találnám fel...
    Mutasd a teljes hozzászólást!
  • Szép lassan feltaláljátok a VB.NET-es Select Case Statementet. :D

    És ha már egyszer megoldották az interpretert, akkor "csak másolni kellene" a két nyelv közt.
    Mutasd a teljes hozzászólást!
  • Még az jutott eszembe, hogy egyrészt egy ideális megoldásba bele kellene tenni az LC által is említett módot, amikor egy case-hez több értéket teszünk vesszővel elválasztva.
    Továbbá szerintem a case kulcsszó itt már fölösleges, csak fölösleges karakterleütés.
    Illetve hozzátenném, hogy egy jó nyelvben minden blokk is ad vissza értéket az utolsó kifejezésének az értékét. Továbbá ha egy metódus void-ot adna vissza, az igazából 'this'-t ad vissza a method chaining elegáns támogatása miatt.

    Összefoglalva tehát itt egy példa, ami minden említett feature-t felhasznál:


    var myvar = switch(expression()) { 'a': fun1(); 'b', e1(), 'c': { fun2(); fun3(); fun4(); } }

    Itt pl. ha expression() értéke 'c', akkor myvar értéke a fun4() által visszaadott érték.

    Ez már tetszene.
    Mutasd a teljes hozzászólást!
  • A switchnek pont a jump table generálás, az egyszerű constans expressionok az előnyei, és ezért érdemes használni egy if-elseif-...-else láncolat helyett.

    Persze azt nem tudom, hogy egy "modern" nyelvnél mennyire számít a programozónak az ilyen sebességnyerés, mert manapság a legtöbb nyelv arra megy rá, egyszerű fejleszthetőség, a sebesség meg csak másodlagos...
    Mutasd a teljes hozzászólást!
  • Teljesen igazad van. (Bár tegyük hozzá, hogy a fordítónak azt is meg kellene oldania, hogy az eredeti switch-fejben lévő kifejezés is csak egyszer értékelődjön ki if elseif esetén, ami nem menne, ezért a programozó kénytelen lenne temporáris változóba tenni fölöslegesen az értéket if elseif esetén*.) Nem vagyok híve annak, ha egy nyelv 'feature-bloated' (ez a gáz sajnos pl. az amúgy fejlett Scala-val), de az if elseif mellett egy switch szerkezet fenntartása a nyelvben még éppen belefér az én ízlésem szerint.

    * példa


    switch(expression()) { case 'a': fun1(); case 'b': fun2(); }

    megfelelője if elseif-ekkel:

    var e = expression(); if(e == 'a') { fun1(); } elseif (e == 'b') { fun2(); }

    Azért az első csak szebb, átláthatóbb kód annyival, hogy egy ilyen szerkezetet én elviselnék egy nyelvben.

    Ja, még egy dolog: egy jó nyelvben a switch a lefutott case ág visszaadott értékét adja vissza,)vagis ekvivalens egy többágú ?: operátorral.
    Mutasd a teljes hozzászólást!
  • Igazából a megoldás az lenne, ha a js szépen menne a kukába ahová való, és a böngészők kapnának egy bytekód értelmezőt, kb. hasonlót mint a .NET-é vagy a javáé. A js csak az erőforrások pazarlása és biztonsági rés.

    Ezzel együtt a gugli kersztülveri - hacsak idővel rá nem jön hogy ez az egész egy igen nagy fostalicska, és pont az ő céljait akadályozza leginkább azzal, hogy egy azonos szolgáltatást nyújtó vastagklienshez képest a html5/js semmivel nem igényel kisebb vasat a kliens oldalon.
    Mutasd a teljes hozzászólást!
  • Az, hogy tetszőleges expression lehessen a case expression, meg azért jó, mert a compiler/interpreter írók majd szépen eldönthetik, hogy mit hogy optimalizáljanak, és ráérő idejükben egyre több mindent optimalizálhatnak.


    Ez szerintem felvet egy érdekes kérdést: mi a különbség a switch és egy olyan if-elseif-else lánc között, amiben minden feltétel egyenlőségvizsgálat? Elvileg manapság a fordító képes lenne a másodikat is detektálni, és ugyanolyan módszerekkel kioptimalizálni, mint a switch-et. (Tegyük fel, hogy az érintett típusok viselkedését ismeri a fordító, vagyis tudja garantálni, hogy az == operátornak nincs vicces mellékhatása.)

    Ha kivesszük a teljesítmény-specifikus részét a dolognak, igazából ugyanannak a dolognak a kétféle leírási módját kapjuk. Ha még egyenlőségen/halmaz tartalmazáson túl tetszőleges más kifejezést is megengedünk, a különbség még kisebb lesz. Megéri egy külön vezérlési szerkezetet tartani csak azért, hogy ne kelljen többször kiírni egy változó nevét?
    Mutasd a teljes hozzászólást!
  • kicsit off:

    Én most ha új nyelvet fejlesztenék, akkor a dinamikus és statikus nyelvek közötti szép átmenettel foglalkoznék.
    Érdekes terület pl. a Javascript-re való source to source fordítás, lásd coffeescript.

    Nekm ha ez lenne a dolgom, akkor kialakítanék a js++ nevű nyelvet, amiben lennének class-ok, private kulcsszó, a 'function' kulcsszót helyettesíteném egy '#' jellel, és lenne némi opcionális type annotáció úgy megoldva, hogy egy sima JAvascript-et is elfogadna (felülről kompatibilitás, úgy, mint ahogy majdnem működik C -> C++-nál is), de fokozatosan lehetne az extrém dinamikus dolgokat kicsit statikusítain ízlés szerint, de úgy, hogy mindig trivi legyen, hogy milyen Javascript fog generálódni a kódból, szóval igazán komoly absztrakciós ugrás nem lenne a js és a js++ között.

    Nem mintha a dolgoknak így kellene mennie, de a realitás az, hogy a JAvascript egyre kikerülhetetlenebb, és reálisan most az ilyen megoldásoknak nagy keletje lesz.

    on
    Mutasd a teljes hozzászólást!
  • Egy modern (mainstream) nyelv switch szerkezetének szvsz. fall-through nélkülinek és case expressionnek nem csak konstansokat, hanem tetszőleges kifejezést elfogadónak kellene lennie.

    (A fall-through nélküliség azt jelenti, hogy nem kell ú.n. disruptive statement (break, return vagy throw) a case végére, hogy ne folyjon át a következő esetre.)

    Az, hogy tetszőleges expression lehessen a case expression, meg azért jó, mert a compiler/interpreter írók majd szépen eldönthetik, hogy mit hogy optimalizáljanak, és ráérő idejükben egyre több mindent optimalizálhatnak. Pl. először csak az integer konstansokat, később a stringeket (hashinggel vagy prefix tree-vel téve ezt pl. sokkal gyorsabbá mint az if elseif láncos összehasonlítást.)

    Pl. a primkó Javascriptben a case expression tetszőleges lehet, de sajnos a fall-through-t átvették a C-ből. A fall-through manapság gonosznak nyilvánítottságát jól mutatja Pl. hogy a javascript-hez írt modern ' szép kód ellenőrző' program, a JSLint beszól, ha nem disruptive statement a case blokk utolsó statement-je.

    Egyébként most a viszonylag egyszerű, mainstream nyelvekről beszéltem. Durvább nyelvek, mint pl. a Scala sokkal fejlettebb és bonyolultabb switch szerkezetet nyújtanak ahol lehetséges a case expressionben case class-okat használni és pattern matching-et csinálni...

    Hogy miért lett a C-ben fall-through? Ez a nyelv 40 éves, és a filozófia mögötte az volt, hogy éppcsak a minimális szükséges absztrakciót tegyék az ASM felé. Illetve a performancia fontos volt. Namost nagyon performanciaigényes kódban annakidején a fall-through kihasználása mindennapos volt. Lásd Duff's Device, mint Csabóka említette a másik topicban.

    Szerk: A prog.hu motorja valahogy escapeli a következő url-t:

    Duff's device - Wikipedia, the free encyclopedia
    Mutasd a teljes hozzászólást!
  • Ezt a topicot azért hoztam létre, hogy körbejárjuk, hogy szerintetek milyennek kéne lennie ma egy modern esetelágazási blokkutasítás szintaxisának és funkciójának.

    Akinek más területről van esetleg ötlete, az hasonló elnevezéssel nyithatna másik topicot, pl. valahogy így:
    Egy új programozási nyelv - OOP
    Egy új programozási nyelv - LINQ
    stb...

    Az "új programozási nyelv" nem feltétlenül jelentene egy teljesen új nyelvet, jelenthet akár egy új nyelvi feature-t is, amiket kisebb átalakításokkal elviekben más (elterjedt) nyelvbe is átlehetne vinni esetleg.


    Példákat és ötleteket várok ide.
    Mindjárt itt is van egy a "Melyik a legjobb prognyelv?" című topicból.



    LC válasza NPL:
    A switch viszont nekem sem tetszik, nem igazán értem hogy miért így oldották meg anno. Sokkal jobb lett volna valami ilyesmi:


    switch(alma) { case 100: elso_fuggveny(); case 200: { masodik_fuggveny(); elso_fuggveny(); } default { default_fuggveny(); } }

    vagy

    switch(alma) { case (100) elso_fuggveny(); case (200) { masodik_fuggveny(); elso_fuggveny(); } default { default_fuggveny(); } }

    Ez a break-es csordogálós szisztéma kilóg az egész nyelv filozófiájából, szvsz ez anno egy ad-hoc hekk lehetett hogy gyorsan csináljunk valami case-t a nyelvbe, aztán úgy maradt.


    hurka válasza LC:
    case (100) elso_fuggveny();
    case (200) { masodik_fuggveny(); elso_fuggveny(); }


    Hát nem tudom. A példádból számomra nem egyértelmű, hogy mi történik 100 esetén.
    Lefut az elso_fuggveny(); és a { masodik_fuggveny(); elso_fuggveny(); } rész is? vagy csak a elso_fuggveny();?


    Csaboka2 válasza hurka:
    Szerintem csak azért nem egyértelmű, mert már "meg vagy fertőződve" a C-stílusú switch blokkal

    Sehol máshol nem szokás szó nélkül átesni a következő vezérlési struktúrára: az if szerkezet then ágából nem esel át az else ágba, a függvények végén nem esel át a következő függvénybe még akkor se, ha lemaradt a return, a try végéről nem esel át az első catch ágba stb. Ha a C-be valami Pascal/Ada stílusú switch került volna a kezdetektől, szerintem senkinek nem hiányozna a jelenlegi megoldás.

    (Mondjuk szegényebbek lennénk egy Duff's device-szal. Nekem személy szerint az se hiányozna)


    sirpalee válasza LC:
    Az, hogy kell a break néha hasznos lehet :)

    Pl mi van ha

    case 150:
    case 250:
    // ugyanaz
    break;


    LC válasza hurka:
    Pedig egyértelmű: blokkok vannak. Azaz 100 esetén az első függvény hívódik meg, ugyanúgy mint ha egy if után lenne.


    LC válasza sirpalee:
    (100 || 150 || 200) { elso(); masodik(); }


    Joga válasza LC:
    Igen, ez jó lenne, csak mondjuk zárójel nélkül, vesszővel elválasztva, valahogy így:
    case 100, 150, 200:
    ( esetleg még intervallumok használata lenne hasznos

    Amúgy, ahhoz képest, hogy ez ma még durván hibás, láttam már az infó tanáromat ezt így leírni.


    real_het válasza Joga:
    Ez van a pascalban, szoval C-ben szerintem jogos a kiirando break meg a fallthrough, igy lehet ott halmazokra ifelni.
    De most akkor hogy van ez? Az C for tulsagosan rugalmas, de a C switch ne legyen rugalmas?! :D

    Joga válasza real_het:
    Ezeket szerintem nem rugalmasra alkották, hanem a szintaxissal utalni akartak a működésre. A switch nem rugalmas, hanem iszonyat igénytelen lett.


    real_het válasza Joga:
    "szintaxissal utalni akartak a működésre"
    Igen, egy egesz switch constructot ugymond szavankent at lehet alakitani asmra/gepikodra. De ez lenne a lenyege a FOR-nak is. Pacalban ott egy 'aranyszabaly, hogy a for-nak a tól-ig-ja csak a ciklus elejen van kiertekelve, a C-s forban pedig iteracionkent (while szeruen) van ellenorizbe a vége kriterium. De hat ezek bemagolando dolgok.
    Mutasd a teljes hozzászólást!
abcd