Mod. siirsi keskustelusta Structured text: Suureneeko luku?
Quirzo kirjoitti:
IF anturiArvo > edellinenLuku THEN laskuri := laskuri + 1; END_IF
Hienoa, ei aaltosulkuja eikä begin-sanaa. Mikäs kieli tämä on? Sain idean kirjoittaa Eiffelistä.
vinsentti kirjoitti:
Hienoa, ei aaltosulkuja eikä begin-sanaa.
Mikä siinä on hienoa? On ihan sama, kirjoitetaanko kielessä ”if x then begin ... end” vai ”if x then ... end_if”. Tämä ero ei tee kummastakaan kielestä hienompaa tai parempaa eikä varsinkaan vaikuta kielen käyttömahdollisuuksiin.
vinsentti kirjoitti:
Mikäs kieli tämä on?
Selvästikin edellä mainitun keskustelun kieli oli Structured text.
Metabolix kirjoitti:
Mikä siinä on hienoa?
Nämähän ovat kielen äärimmäisiä alkeita. Turhien begin-sanojen pois jättäminen on hienoa, niitä tulee muuten hitosti. Kyllähän se nyppii. Tilanne johtaa siihen, että yhden komennon tapauksesta tehdään erikoistapaus ilman begin-end komentosulkuja monimutkaistaen näitä pohjimmaisia alkeita. Ei tämä käyttömahdollisuuksiin vaikuta, voidaanhan noita sanoja kirjoittaa. Tulee vain ikävää sotkua.
vinsentti kirjoitti:
Nämähän ovat kielen äärimmäisiä alkeita. Turhia begin-sanoja tulee hitosti. Kyllähän se nyppii. Tilanne johtaa siihen, että yhden komennon tapauksesta tehdään erikoistapaus ilman begin-end komentosulkuja monimutkaistaen näitä pohjimmaisia alkeita. Ei tämä käyttömahdollisuuksiin vaikuta, voidaanhan noita sanoja kirjoittaa. Tulee vain ikävää sotkua.
Alla PL/I:n tapa ja mielestäni ja mielestäni mikään näistä vaihtoehdoista ei ole luettavuuden kannalta ikävää sotkua:
if x > 0 then STATEMENT; else STATEMENT; if x > 0 then do; STATEMENTS; end; else do; STATEMENTS; end; if x > 0 then begin; STATEMENTS; end; else begin; STATEMENTS; end;
jalski kirjoitti:
PL/I:n tapa ja mielestäni ja mielestäni mikään näistä vaihtoehdoista ei ole luettavuuden kannalta ikävää sotkua:
Kokonaan begin-sanasta luopuminen vapauttaa turhista end-sanoistakin. Tuossa PL/I esimerkissä näkyy niitäkin. Yhden komennon erikoistapaus on hätääntymistä ylenpalttisesta komentosulkumäärästä. Tuloksena syntyneestä sotkusta selvitään kylvämällä puolipisteitä. Siivoamisen jälkee tilanne on tämä:
if x > 0 then STATEMENT else STATEMENT end if x > 0 then STATEMENTS else STATEMENTS end if x > 0 then STATEMENTS else STATEMENTS end
end-sanoja on yksi vähemmän, yhtä monta (3) kuin komentorakenteitakin, kaksi turhaa on poistettu ja yksi tarpeellinen lisätty.
Mod. lisäsi kooditagit!
vinsentti kirjoitti:
Turhien begin-sanojen pois jättäminen on hienoa, niitä tulee muuten hitosti. Kyllähän se nyppii.
Ei tuo ole mikään perustelu. Sinunkin ratkaisussasi tarvitaan lohkolle aivan turha end-sana. Jos sanojen vähentäminen on tavoitteena, kannattaisi vaihtaa Pythoniin, jossa lohkot merkitään vain sisennyksellä. Toisaalta jos turhien merkkien vähentäminen on tavoitteena, aaltosulut lohkon merkkinä säästävät tilaa – ja voidaan jättää myös turhat rivinvaihdot pois ja koodata kaikki samalle riville.
Jos begin-sanan tai aaltosulkujen olemassaolo tuntuu olennaiselta osalta jonkin kielen ”hienoutta”, ollaan kyllä äärimmäisen kaukana ohjelmoinnin ytimestä eli algoritmeista ja ohjelman rakenteen loogisesta ilmaisemisesta.
Metabolix kirjoitti:
Sinunkin ratkaisussasi tarvitaan lohkolle aivan turha end-sana. Jos sanojen vähentäminen on tavoitteena, kannattaisi ....
Ei ole kysymys minun ratkaisustani, vaan korjauksesta, jonka Algol-perinteen kielet tekivät tekivät 80-luvulla ADAsta lähtien poistamalla komentosulut turhina. Näiden kielten syntaksista on turha etsiä "compound statement"ia tjms. C otti komentosulut Algolista ja perinne jatkaa erehdystä.
Tässä ole kysymys sanojen tai merkkien lukumäärästä vaan syntaksin turhuudesta, josta seuraa sotkua.
Tämä on niin itsestäänselvää ja alkeellista, että Eiffel-väki huomasi perustella ratkaisua vasta 30 vuotta myöhemmin, toissa vuonna:
Linkittämäsi artikkelin viestinä ei ole koodin ulkonäön tyylikkyys vaan tiettyjen virheiden välttäminen ja tietynlaisen syntaksin vaikutus siihen. Artikkelissa ei olennaisesti kritisoida begin-sanan tai aaltosulkujen olemassaoloa vaan päinvastoin sitä yksittäistä poikkeustilannetta, jossa niitä ei tarvitsekaan käyttää. Eiffelin eduksi ei lueta begin-sanan puuttumista vaan end-sanan pakollisuus. Ongelman kannalta on merkityksetöntä, onko lohkon alussa ”ylimääräinen” begin.
vinsentti kirjoitti:
Tässä ole kysymys sanojen tai merkkien lukumäärästä vaan syntaksin turhuudesta, josta seuraa sotkua.
Turha väittää, että Eiffelissä olisi hienosti poistettu kaikki tarpeeton, kun siinäkin on turhaan sellaisia sanoja kuin then, loop ja until. Tässähän Python on selvästi edistyneempi, ei ole noita turhia sanoja eikä edes turhaa end-sanaa.
Kuten alussa sanoin, voi noita komentosulkuja kirjoittaa, jos haluaa. Tai jos on pakko.
Muusta turhasta keskustelu muualla.
Minä en saanut ihan selvää siitä, mistä tässä keskustelussa oikein puhutaan, mutta ilmeisesti saan kritisoida ohjelmointikielen lohkosyntakseja.
Ensinnäkin Basic. On suunnattoman epäloogista, että jotkut lohkot ovat loogisesti muotoa Avainsana ... End Avainsana
ja jotkut jotain aivan muuta:
If jotain Then ... End If While jotain ... End While Do ... Loop ' Miksi?
Sama on monissa muissakin kielissä. Esimerkkejä ovat mm. Bourne shell ja C-shell:
if jotain; then ... fi case jotain in ... esac while jotain; do done # epäjohdonmukaista, miksei elihw?
if ( jotain ) then ... endif switch ( jotain ) ... endsw while ( jotain ) ... end # miksei endwh?
Oma lukunsa on Python, jonka ohjausrakenteet ovat yksiä epäselvimmistä. Missä lohko alkaa ja minne se päättyy? Jos näen ison Python-tiedoston, en voi päätellä siitä juuri mitään lukematta tarkasti läpi. Entä miten copy-pastetan koodia sisennystasolta toiselle huonolla editorilla? Automaattinen sisennys ei toimi hyvissäkään editoreissa. Erilaiset kopiointivirheet ym. sekä yleinen epäselvyys tekevät Pythonista aivan yhtä haavoittuvan kuin mistä tahansa muustakin epä-Eiffel-tyylisestä kielestä.
Sama epäselvyyden ongelma on Lispeissä, sillä niissä taas käytetään samoja sulkuja aivan kaikkeen. Käytän kieltä niin satunnaisesti, etten ilman rutiinia pysty erottamaan ohjausrakenteita ja lausekkeita toisistaan. Kokemus auttaisi varmaan tähän.
fergusq kirjoitti:
done # epäjohdonmukaista, miksei elihw?
Tai "od" :D
fergusq kirjoitti:
Minä en saanut ihan selvää siitä, mistä tässä keskustelussa oikein puhutaan, mutta ilmeisesti saan kritisoida ohjelmointikielen lohkosyntakseja.
Avaukseni kyseenalaisti komentosulut tai kuten sanot lohkosyntaksin eli begin-end tai {} ohjelmointikielissä. Syntaksin, jolla ei ole muuta tarkoitusta kuin reunustaa komentolohkoa.
Sinun tuskastumisesi näyttää johtuvan muunlaisista toheloinneista kielten perusasioissa. Mikään esimerkeistäsi esim.
If jotain Then ... End If While jotain ... End While Do ... Loop ' Miksi?
ei ole tarpeetonta (väittämäni mukaan) lohkosyntaksia vaan komentosyntaksia. Komentorakenteen viimeisen lohkon loppumerkkiä lukuunottamatta kaikilla sanoilla on muutakin tarkoitusta. Rakenteen muilla kuin viimeisellä lohkolla on merkityksellinen loppumerkki, esim else.
Esimerkeistäsi huomataan, että monissa kielissä on luovuttu lohkosuluista. Toki rakenteen viimeiselle lohkolle tarvitaan loppumerkki. Loppumerkkien valinnassa on suurta kirjavuutta. Neutraali valinta on sama kaikille: end. Yksinäistä } ei kai kukaan ole kokeillut.
Luettuani tuon linkatun artikkelin havahduin, että tällainenkin aihe on olemassa. Täytyy katsoa alkuperäisista Ada-rationaaleista, miten siellä perustellaan.
vinsentti kirjoitti:
Kokonaan begin-sanasta luopuminen vapauttaa turhista end-sanoistakin. Tuossa PL/I esimerkissä näkyy niitäkin. Yhden komennon erikoistapaus on hätääntymistä ylenpalttisesta komentosulkumäärästä. Tuloksena syntyneestä sotkusta selvitään kylvämällä puolipisteitä.
Eiväthän nuo END-sanat ole turhia, vaan PL/I-ohjelmointikielessä päättävät DO-ryhmän tai BEGIN-lohkon. Lohko orientoituneessa ohjelmointikielessä ei ole olemassa mitään yhden komennon erikoistapausta, vaan koko lohkon tarkoitus on saada ryhmä käskyjä käsiteltyä niin kuin kyseessä olisi yksi käsky. Lisäksi lohkon avulla voidaan rajoittaa muuttujien ja aliohjelmien näkyvyyttä sekä elinikää.
vinsentti kirjoitti:
Kokonaan begin-sanasta luopuminen vapauttaa turhista end-sanoistakin.
Ei pidä paikkaansa! ”Turhista” end-sanoista päästään eroon sillä, että sovitaan, että pelkkä else tarkoittaakin end else; tämä ei estä käyttämästä alussa begin-sanaa. Ihan samoin ”turhista” begin-sanoista päästään eroon sillä, että sovitaan, että pelkkä then tarkoittaakin then begin (ja else tarkoittaakin else begin); tämä ei estä käyttämästä turhia end-sanoja.
Voidaan aivan toisistaan riippumatta sopia seuraavista kohdista:
Seuraavat tulokseltaan identtiset C-koodit havainnollistavat tilannetta (joskin puutteellisesti, koska merkityksettömän sanan pakollisuutta ei voi helposti makroilla esittää):
Pascal-tilanne: begin ja end ovat tarpeen, jos halutaan lohko.
#define then #define begin { #define end } if (a == b) then begin foo; bar; end else begin bar; foo; end
Kieli, jossa end on pakollinen mutta begin-sanaa ei ole.
#define then { #define else else { #define begin #define end } if (a == b) then foo; bar; end else bar; foo; end
Kieli, jossa begin tulee vain elsen jälkeen.
#define then { #define begin { #define end } if (a == b) then foo; bar; end else begin bar; foo; end
Kieli, jossa begin-sana on pakollinen mutta välissä ei ole ”turhaa” end-sanaa.
#define then #define else } else #define begin { #define end } if (a == b) then begin foo; bar; else begin bar; foo; end
Kieli, jossa ei ole begin-sanaa eikä ”turhaa” end-sanaa välissä.
#define then { #define else } else { #define end } if (a == b) then foo; bar; else bar; foo; end
Eiffel-tyylinen "end"-sanan pakottaminen on ihan hyvä ajatus, vaikka se saattaa joskus tuntuakin ärsyttävältä. Esimerkiksi itse en pidä siitä, että Javassa on pakko olla aaltosulkeet tryn jälkeen, vaikka ne ovat usein täysin tarpeettomat:
// Ei toimi :( Joku j; try j = teeJotain(); catch (JokuException e) j = jotainMuuta();
Grez kirjoitti:
fergusq kirjoitti:
done # epäjohdonmukaista, miksei elihw?
Tai "od" :D
"od" olisi epäjohdonmukainen paitsi, jos if:n päättäjä olisi "neht" ja casen päättäjä "ni": silloin lohkon alkusana vastaisi lohkon loppusanaa.
Tässä on perustelua 30 vuoden takaa
http://archive.adaic.com/standards/83rat/html/
Ada luopui lohkosuluista, jotka olivat käytössä vielä Pascalissa muodossa begin-end. Jokaisella rakenteella näkyy Adassa olevan oma loppumerkki: end if jne. Proseduurin avainsanaksi otettiin tuttavamme begin! Eiffelissä ja monessa muussa sillä paikalla on "do", joka on kyllä sattuvampaa. Tekemisestähän proseduurissa on kyse.
vinsentti kirjoitti:
Ada luopui lohkosuluista, jotka olivat käytössä vielä Pascalissa muodossa begin-end. Jokaisella rakenteella näkyy olevan oma loppumerkki, end if jne.
Oikeastihan tuo on ollut vain perustelujen keksimistä heikolle parserille.
Imho, syntaksi on vain syntaksia. Kielen foo syntaksi saattaa olla mieleinen henkilölle bar, ja kielen X syntaksi mieleinen henkilölle Y.
Todennäköisesti jos ei itse jonkun tietyn kielen syntaksista välitä, se ei ole sopiva kieli sinulle. Onneksi valinnanvaraa on.
jalski kirjoitti:
Oikeastihan tuo on ollut vain perustelujen keksimistä heikolle parserille.
Ilmeisesti osa ihmisistäkin lasketaan "heikoksi parseriksi" kun joissain tyyliohjeissa kehotetaan laittamaan kaarisulut sellaistenkin yhden käskyn lohkojen ympärille, joissa se ei olisi pakollista.
Grez, tuo tosin ei ole aina kehittäjän omassa päätösvallassa. Isommissa projekteissa on usein kehitysohjeet määritettynä, jotta koodi pysyy helposti luettavana koodareiden välillä. Samoja asioita kun voi tehdä niin monella tapaa.
groovyb kirjoitti:
....jotta koodi pysyy helposti luettavana koodareiden välillä.
Niinhän mä just sanoin: Joku on päättänyt, että ilman ylimääräisiä kaarisulkuja koodi ei ole osalle koodareista helposti luettavaa.
Niin, tuo ehtolausekehomma tosin on yksin pienimmistä ärsyttävistä tyylimääreistä. Eniten ärsyttää esim C#:ssa kehitysmääreet miten Linq:iä saa käyttää ja mahdollisesti kielletty ternaryt ja func:t ja ja ja.. lista on ollut joidenkin projektien kohdalla loputon.
jalski kirjoitti:
lohkon tarkoitus on saada ryhmä käskyjä käsiteltyä niin kuin kyseessä olisi yksi käsky.
Tämä tarve tuli siitä, että lausekielten komentosyntaksi oli: (avain)sana komento sana komento .... Kun komentoja tarvitaan enemmän kuin yksi, niistä on tehtävä lohko. Adasta eteenpäin Algol-perinteen syntaksi on: sana komentoja sana komentoja ... end.
jalski kirjoitti:
Lisäksi lohkon avulla voidaan rajoittaa muuttujien ja aliohjelmien näkyvyyttä sekä elinikää.
Tästä on luovuttu. Komentorakenteista ainoastaan proseduurilla on omia muuttujia, mutta ei silläkään sisäisiä proseduureja. Myöhemmin luokalla on molempia. Paljolti OOnkin ansiosta syvistä komentorakenteista on luovuttu.
vinsentti kirjoitti:
Tästä on luovuttu. Komentorakenteista ainoastaan proseduurilla on omia muuttujia, mutta ei silläkään sisäisiä proseduureja.
Mistäköhän kielestä nyt puhut?
Adassa voi näköjään määritellä paikallisia näkyvyysalueita declaren avulla, ja lisäksi sisäkkäiset proseduurit ovat sallittuja.
http://www.infres.enst.fr/~pautet/Ada95/
http://www.infres.enst.fr/~pautet/Ada95/
Lisäys: Ehto- ja silmukkarakenteet eivät tosiaan luo näkyvyysaluetta, vaan niiden sisään pitää tehdä lisäksi declare-lohko. Tämä on minusta aika erikoinen valinta, jonka luulisi johtavan joko ylimääräiseen sisennykseen tai muuttujien esittelyyn tarpeettoman korkealla tasolla (kuten muinaisessa C:ssä).
jlaire kirjoitti:
Adassa voi näköjään määritellä paikallisia näkyvyysalueita declaren avulla, ja lisäksi sisäkkäiset proseduurit ovat sallittuja.
En osaa Adaa. Luin vain yllämainituista artikkeleista vähän Adasta koskien ketjun aihetta. Tällaista on ollut PL/1ssä ja Algol68ssä, että sitten Adassakin. Tuskin noita piirteitä on käytetty.
vinsentti kirjoitti:
Tällaista on ollut PL/1ssä ja Algol68ssä, että sitten Adassakin. Tuskin noita piirteitä on käytetty.
Onhan kyseisiä piirteitä käytetty useissakin ohjelmointikielissä ja itsekin käytän kyseisiä ominaisuuksia ohjelmoidessa hyödyksi säännöllisesti.
Alla jlairen linkittämiä Ada esimerkkejä vastaavat PL/I toteutukset:
nesting: proc options(main); put skip list('Start the triple nesting here.'); call triple; put skip list('Finished, and back to the top level.'); triple: proc; put skip list('This is procedure triple talking to you.'); call secondlayer; put skip list('We are back up to the procedure named triple.'); secondlayer: proc; put skip list('This is the second layer talking.'); call bottomlayer; put skip list('We are back up to the second layer.'); bottomlayer: proc; put skip list('This is the bottom layer talking.'); end bottomlayer; end secondlayer; end triple; end nesting;
block: proc options(main); dcl 1 b, 2 (index, count) fixed bin(31); index = 27; count = 33; put edit('In the main block - values are:', index, count) (A(42), F(5), F(5)); begin; dcl (index, stuff) fixed bin(31) init(-345); index = 157; put skip edit('In the embedded block - values are:', b.index, index, stuff, b.count) (A(42), F(5), F(5), F(5), F(5)); end; put skip edit('Back to the main block - values are:', index, count) (A(42), F(5), F(5)); who: /* No named begin block's in PL/I, we use label instead to simulate */ begin; dcl 1 w, 2 (index, stuff) fixed bin(31) init(-345); index = 157; put skip edit('In the block labelled who - values are:', b.index, index, w.index, stuff, w.stuff, b.count) (A(42), F(5), F(5), F(5), F(5), F(5), F(5)); end; put skip edit('Back to the main block - values are:', index, count) (A(42), F(5), F(5)); end block;
Puolihuolimatonta herjanheittoa Objective-Cstä. Koskee toki koko C-perinnettä.
http://www.infoworld.com/article/2606364/
Aika turhaa valittamista. Ainoa oikeasti pätevä kohta tuossa artikkelissa on nimiavaruuksien puute. Objective-C:n syntaksi on erilaista kuin C:n tai Pythonin, onhan se eri kieli. Erilaisuus itsessään ei laske kielen arvoa. Lisäksi kielellä on samasta syystä eri tiedostopääte (tästä valitetaan, oikeasti?).
Valittaja tietää itsekin, että väitteet Xcodesta ainoana kehitystyökaluna ja muiden suoritusympäristöjen puutteesta ovat täyttä puppua. Olen itse pelannut paljon Oolite-peliä, joka on kirjoitettu GNUStepille ja toimii hyvin.
Periaatteessa väite Applesta "diktaattorina" on oikea, mutta kirjoittaja epäonnistuu esimerkkien luettelemisessa. Se, että Apple kontrolloi tiukasti iOS-ohjelmien toimintaa, ei liity mitenkään Objective-C:hen.
Koko artikkeli tuntuu pelkältä valittamisen vuoksi valittamiselta. Jos asiaa tutkiskelee, voi todeta kaikkien ohjelmointikielten olevan aivan kauheita. Kunnolliseen argumentaatioon tarvitsee kuitenkin muitakin perusteita kuin "mutta kun musta @-merkit ovat rumia enkä osaa käyttää gcc:tä".
fergusq kirjoitti:
Aika turhaa valittamista. Ainoa oikeasti pätevä kohta tuossa artikkelissa on nimiavaruuksien puute.
Ihmettelenkin, miksi Meyer ruoti artikkelia. Juuri tuossa nimiavaruusasiassa hän jäi selvästi puolustuskannalle.
Mitä ketjun aiheeseen tulee, lohkosuluton end-puolue on uusien kielten kilvassa mukana, vaikka {}-puolue on niskan päällä. Aihe on elävä.
GCC 6:ssa on hauska ominaisuus, joka varoittaa harhaanjohtavasta sisennyksestä.
if (1) a(); b(); /* Varoitus! */
vinsentti kirjoitti:
lohkosuluton end-puolue
Tämä on edelleenkin väärin tai vähintäänkin epäselvästi sanottu. Kielessä selvästi on lohkoja ja niitä määrittäviä erityismerkintöjä, jos then aloittaa lohkon, else lopettaa ja aloittaa lohkon ja end lopettaa lohkon. Tässä vain merkintä käytetystä rakenteesta riippuvainen sen sijaan, että kaikki lohkot käyttäisivät samaa merkintätapaa (sulkuja tai begin-end-paria).
Lähinnä aidosti lohkosulutonta kieltä olisi edelleenkin jokin Pythonin tapainen, jossa ei ole aloittavaa sanaa (tosin on :-merkki) eikä mitään lopettavaa sanaa.
Minusta taas lohkosanalliset on lohkosuluttomia
Jos lohkosanallista kieltä kutsuu lohkosululliseksi, niin eikös sitten samalla logiikalla lohkosisennyksellinen kieli, kuten Python, ole lohkosulullinen.
Tätä keskustelua on leimannut toistuva harhaanjohtavien termien käyttö. Minusta olisi kiva, jos vinsentti vaivautuisi edes määrittelemään selkeästi, mitä kannattaa.
Grez kirjoitti:
Minusta taas lohkosanalliset on lohkosuluttomia
Joo, haksahdin viestissäni ja korjasin sitä tältä osin. Kuitenkin aiemmin vinsentti on valittanut myös turhista begin-sanoista, joten oletan, että ne kuuluvat edelleen hänen asialistalleen.
Määrittelyt tosiaan olisivat kivat, ja ylipäänsä vinsentti voisi vähän paremmin perehtyä niihin kieliin, joita kannattaa tai haukkuu, ettei homma olisi pelkkää huutelua.
Olen aina pitänyt tätä aihepiiriä sekavana, kunnes luin linkatun Meyerin artikkelin. Avainsanapohjaisissa "lausekielissä" komennot järjestetään näin:
... avainsana komentoja avainsana komentoja end.
Tässä komentoja-kohtien ympärille ei tarvita sulkupareja sen enempää {} kuin begin-end:kään.
Kun tämä havainto on tehty, niin sekavuus on vähentynyt.
Mikähän ihme siinä on sitten alkujaankaan ollut sekavaa?
Onko ollut jotenkin epäselvää, että eri kielten syntaksit eroavat toisistaan? Ylipäätään, syntaksissa harvoin on kyse siitä mikä on ollut tarpeellista parserin kannalta. Eiköhän siinä ole painanut se, mikä on kielen kehittäjän/kehittäjien mielestä ollut se loogisin tapa toteutukselle. Ja imho, juuri tämä sama syy saa ohjelmoijan mieltymään tiettyyn kielisyntaksiin - jotkut vaan tuntuu loogisemmalta kuin toiset.
Tällaista jälkeä syntyy, kun komentorakenne nimeltä proseduuri rakennetaan avainsanasyntaksilla.
draw (amount : INTEGER) require amount > 0 saldo >= amount do saldo := saldo - amount ensure saldo = old saldo - amount end
Tai tämmöistä..
draw int amount begin check amount > 0 & saldo >= amount saldo_of_cakes = saldo - amount end
Joten mikä idea? Mihin vastaat tolla pätkällä, mitä väliä? Komppaan groovyb:tä ja totean että osa tykkää, osa ei.
Oskuz kirjoitti:
Joten mikä idea? Mihin vastaat tolla pätkällä, mitä väliä?
Komentorakenteissa, esimerkkinä tämä, on vaihteleva määrä osioita. Ne kaikki rakennetaan samalla periaatteella. Syntaksiin ei laiteta mitään turhaa, puhumattakaan että ne rakennettaisiin ilman periaattetta sekavasti kukin omalla tavallaan. Yhden ja useamman komennon lohkot ovat samanlaisia. Avainsanan poisjäänti on syntaksivirhe. Ja mitä kaikkea.
Tuohon sekavuusasiaan koitan vastata. Näitä tuo artikkelikin käsittelee, otsikkokin on Code Matters eikä Who Cares.
En sanoisi, että end-sanan pakottaminen lopulta vähentäisi bugien määrää kovinkaan paljon. Voisin kuvitella, että alla olevaan virheeseen sortuvat eniten sellaiset ihmiset, jotka eivät ole tottuneet C-tyylisiin kieliin, sillä virhe on hyvin ilmeinen.
if (a) f(); g();
Lisäksi on olemassa monia muitakin huolimattomuus-/kopiointivirheitä, joita end-sanan pakottaminen ei poista. Mielestäni lohkosyntaksi on lopulta hyvin pieni vaikuttaja virheissä.
Niin aikaisemmin jo viittasinkin siihen, että joissain tyylioppaissa käsketään laittamaan aaltosulut sellaisiinkin kohtiin, joissa lohkoon tulee vain yksi komento (tietyin poikkeuksin). Tämä varmasti voitaisiin helposti myös pakottaa kääntäjässä.
Kaipa tuollainen käytäntö vähentää virheitä, ei kai sitä muuten haluttaisi käyttää.
Itse pidän Visual Studion tyylistä sisentää C# koodi automaattisesti, jolloin tuon tyyliset virheet on helppo nähdä, mutta makuja on varmasti monia.
Sulkujen lisäksi lähti puolipisteetkin. Aikaa tosin kului parikymmentä vuotta siitä, kun suluista oli päästy eroon. Ei tämä niin helppoa ole.
vinsentti kirjoitti:
(21.01.2016 12:12:34): Sulkujen lisäksi lähti puolipisteetkin. Aikaa...
Mikä noissa puolipisteissä tökkii? Eiffel vaatii melko varmasti jonkun merkin ilmaisemaan, jos komento jatkuu seuraavalle riville. Puolipisteen kanssahan näin ei ole.
Entä sitten joku PL/I:n kaltainen ohjelmointikieli, jossa ei ole varattuja sanoja? Ainakin itse pidän mielelläni nuo puolipisteet...
Merkkijonoilla jotakin tähän suuntaan:
class HELLO_WORLD create make feature make do print ("Hello, %N% %World%N") end end
jalski kirjoitti:
Mikä noissa puolipisteissä tökkii? Eiffel vaatii melko varmasti jonkun merkin ilmaisemaan, jos komento jatkuu seuraavalle riville. Puolipisteen kanssahan näin ei ole.
Jo lähtökohtaisesti kuulostaa hassulta ajatukselta, että 90% riveistä täytyy lisätä jokin merkki vain sen takia, että 10% riveistä ei tarvitsisi..
Eiffelistä en tiedä, mutta esimerkiksi Javascriptissä ei tarvitse laittaa rivien perään puolipistettä ja silti voi kirjoittaa komennon monelle riville, ilman lisämerkkejä.
Voihan monessa kielessä jatkaa komentoaja seuraavalla riville ilman merkintää siitä ensimmäisellä rivillä (paitsi olla sulkematta komentoa), eri asia on sitten se että tarvitseeko viimeistä komentoa sulkea, kuten esim C#:ssa täytyy.
foo.DoSomething() .AndThis("foo" + "bar", 123) .AndAlsoThis() .AndThisAlso();
Vai tarkoititko että yksittäisen komennon voi jakaa usealle riville? tuossakin toki rajoituksensa myös niin C# kuin js puolella, merkkijonoa ei voi jakaa usealle riville ilman lisämerkkejä (jos annetaan vaikka funktioon parametriksi)
var data = test("12", "13") //Toimii data = test("1 2", "13") //Ei toimi data = test("1" + "2", "13") //Toimii function test (a,b) { return a + b }
groovyb kirjoitti:
Vai tarkoititko että yksittäisen komennon voi jakaa usealle riville?
Tuota lähinnä meinasin. Lisäksi, jos esim. muuttuja on saman niminen kuin avainsana ja näitä tulee peräkkäin. Kuinka tässä tapauksessa parseri tai ihminen hahmottaa tilanteeen ilman komennon päättävää merkkiä (tai sisennystä).
esim:
dcl i fixed bin(31); dcl do fixed bin(31); do; do=1; do i = 1 to 20 by 1 while(do = 1) until(i > 10); put skip list(i); end; end;
Grez kirjoitti:
Niin aikaisemmin jo viittasinkin siihen, että joissain tyylioppaissa käsketään laittamaan kaarisulut sellaisiinkin kohtiin, joissa lohkoon tulee vain yksi komento (tietyin poikkeuksin).
Kaarisulut: ()
Aaltosulut: {}
jlaire kirjoitti:
Kaarisulut: ()
Aaltosulut: {}
Kiitos muistutuksesta. Korjasin ajatusvirheeni :)
Grez kirjoitti:
jalski kirjoitti:
Mikä noissa puolipisteissä tökkii? Eiffel vaatii melko varmasti jonkun merkin ilmaisemaan, jos komento jatkuu seuraavalle riville. Puolipisteen kanssahan näin ei ole.
Jo lähtökohtaisesti kuulostaa hassulta ajatukselta, että 90% riveistä täytyy lisätä jokin merkki vain sen takia, että 10% riveistä ei tarvitsisi..
Eiffelistä en tiedä, mutta esimerkiksi Javascriptissä ei tarvitse laittaa rivien perään puolipistettä ja silti voi kirjoittaa komennon monelle riville, ilman lisämerkkejä.
Puolipisteet ovat hyödyllisiä luettavuuden kannalta. Näin sivunmennen voin sanoa, että pilkut argumenttien välissäkään eivät ole parsimisen kannalta oleellisia 90% tilanteissa ja voitaisiin hyvin jättää pois suurimmasta osasta kieliä.
f(a, b, c); // ruma? f a b c // parempi? f(a, (b+c)*d, e); f a, (b+c)*d e // tähän pitää tulla pilkku, jottei sekoittuisi funktiokutsuun // vrt. f() g(); // pakollinen puolipiste (2-3).abs()
Sekä pilkuista että puolipisteistä pääsee lopullisesti eroon käyttämällä välilyöntiä argumenttierottimena ja uuttariviä lause-erottimena.
Ehdotan että luovumme turhista välimerkeistä Isosta alkukirjaimesta näkee aivan selvästi missä virke loppuu Kun lause alkaa erisnimen takia isolla kirjaimella voidaan käyttää pistettä selkeyden vuoksi. Haskellissa lohkojen merkitsemiseen voi käyttää vapaavalintaisesti joko whitespacea tai aaltosulkuja ja puolipisteitä Useimmat suosivat whitespacea
f(a, b, c); // ruma! f a b c // parempi! f(a, (b+c)*d, e); f a ((b+c)*d) e // tarvitaan lisäsulut, silti 2 merkkiä lyhyempi
jlaire kirjoitti:
Haskellissa lohkojen merkitsemiseen voi käyttää vapaavalintaisesti joko whitespacea tai aaltosulkuja ja puolipisteitä Useimmat suosivat whitespacea
Lohkojen, mutta ei komentolohkojen vaan lausekelohkojen. Käytetäänkö Haskelissa aaltosulkuja? Lausekkeissa on tapana käyttää tavallisia sulkuja.
f(a, b, c); // ruma! f a b c // parempi! f(a, (b+c)*d, e); f a ((b+c)*d) e // tarvitaan lisäsulut, silti 2 merkkiä lyhyempi
Tässä on kysymys funktiokutsun merkitsemisestä suluilla tai ilman. Kutsu on tosin komento (imperaatiivipurkkaa), pitäisi puhua funktion soveltamisesta.
En tiedä mitä tarkoitat komento- ja lausekelohkoilla.
Haskellin syntaksissa on joka tapauksessa monta rakennetta (do
, let
, case
yms.), jotka näyttävät tältä: {...; ...; ...}
, mutta joissa aaltosulut ja puolipisteet voi korjata sisennyksellä ja rivinvaihdoilla.
jlaire kirjoitti:
En tiedä mitä tarkoitat komento- ja lausekelohkoilla.
Komentoja on vain imperatiivikielissä. Peruskomennot ovat sijoitus muuttujaan ja funktiokutsu. Joissakin kielissä on muitakin hyppyjä. Näistä tehdään komentorakenteita, joissa niitä komentolohkoja sitten on. Lausekkeelle voidaan vain laskea sen arvo. Esimerkiksi funktiokutsun argumentit muodostavat lausekelohkon.
jlaire kirjoitti:
Haskellin syntaksissa on joka tapauksessa monta rakennetta (
do
,let
,case
yms.), jotka näyttävät tältä:{...; ...; ...}
, mutta joissa aaltosulut ja puolipisteet voi korjata sisennyksellä ja rivinvaihdoilla.
Haskelissa on varmaan lausekelohkoja kaikkialla. Haskell ei ole imperatiivikieli, mutta siellä on avainsana "do", joka viittaa komentoihin. Täytyy katsoa. Jaa, se monadijuttu, että saadaan tehdyksi muutakin kuin lausekkeen arvo laskettua.
Puhutaanhan fonteistakin. Nyt kun alkuperäinen aihe on jätetty taakse, niin jatketaan. Tällaisesta en ollut ennen kuullutkaan: proportional fonteille sopiva kieli. Mitähän se on suomeksi?
http://liberty-eiffel.blogspot.fi/2012/01/im-almost-literate-program-please.html
Ainakin Wikipediassa käytetään termiä "suhteelliset kirjasinlajit", joka omaan korvaan kyllä ei kuulosta kovin hyvältä suomelta.
Lisäksi siellä kerrotaan, että:
Wikipedia kirjoitti:
Suhteuttamattomia kirjasimia käytetään edelleen ... ohjelmakoodin kirjoittamiseen, koska se helpottaa ohjelmakoodin ja komentojen luettavuutta.
Äkkiseltään en näe että tuo pitäisi kovinkaan hyvin paikkaansa. Voisikin kokeilla laittaa kehitysympäristöön huvikseen suhteellisen fontin käyttöön.
Se on kyllä totta, että toiset kirjasimet on koodatessa miellyttävämpiä kuin toiset.
Lisäys: Testasin tuossa niin en nyt sanoisi, että luettavuutta haittasi mitenkään. Nopeasti testaten ainoa haitta oli, että ylös/alas liikkuessa kursori pomppi hassusti sivusuunnassa.
Fonttikin on tottumuskysymys. Tasalevyisessä fontissa erottaa selvästi merkit toisistaan, mikä on ohjelmoinnissa tärkeää. Monissa muissa fonteissa välimerkit ovat liian pieniä tai sekaantuvat kirjaimiin ja muihin merkkeihin (", ' ja `; !, i, j, t, I, l, 1 ja 7; jne...), mikä tasalevyisessä ja päätteellisessä fontissa on epätodennäköisempää. Toki hyviä hyviä monilevyisiäkin fontteja on. Itse pidän tasalevyisessä esimerkiksi siitä, että sisennystaso on helppo havaita laskemalla merkit viimeisellä rivillä ennen sisennystä.
Mitä tulee väitteeseen, että Eiffel näyttää englannilta, niin minun on oltava tästä eri mieltä. Eiffelillä saa aikaan hyvin "luonnotonta" tekstiä, eikä englannin mimikointiin ole hyvä edes pyrkiä: silloin turhat "koristeet" ja epäloogiset ja monimutkaiset rakenteet korvaavat ohjelmointikielille tyypillisen minimalismin. Esimerkkinä tästä:
list.add(foo, bar).and(baz)
Jotkut kirjastot toimivat oikeasti näin ja silloin voi kysyä, mitä virkaa metodilla .and() oikeasti on.
Aihe on jo aika vanha, joten et voi enää vastata siihen.