Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: Lohkot ohjelmointikielissä (begin, aaltosulut jne.)

Sivun loppuun

vinsentti [03.01.2016 20:48:42]

#

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ä.

Metabolix [04.01.2016 00:22:33]

#

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.

vinsentti [04.01.2016 06:31:38]

#

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.

jalski [04.01.2016 08:07:52]

#

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;

vinsentti [04.01.2016 12:21:23]

#

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!

Metabolix [04.01.2016 16:54:42]

#

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.

vinsentti [04.01.2016 18:18:40]

#

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:

https://bertrandmeyer.com/2014/05/17/code-matters/

Metabolix [04.01.2016 18:54:48]

#

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.

vinsentti [04.01.2016 19:32:38]

#

Kuten alussa sanoin, voi noita komentosulkuja kirjoittaa, jos haluaa. Tai jos on pakko.
Muusta turhasta keskustelu muualla.

fergusq [05.01.2016 10:54:27]

#

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.

Grez [05.01.2016 11:25:44]

#

fergusq kirjoitti:

done # epäjohdonmukaista, miksei elihw?

Tai "od" :D

vinsentti [05.01.2016 14:23:43]

#

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.

jalski [05.01.2016 18:31:50]

#

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ää.

Metabolix [05.01.2016 19:17:55]

#

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

fergusq [05.01.2016 19:47:42]

#

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.

vinsentti [06.01.2016 09:41:14]

#

Tässä on perustelua 30 vuoden takaa

http://archive.adaic.com/standards/83rat/html/ratl-02-02.html#2.2

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.

jalski [07.01.2016 22:14:01]

#

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.

groovyb [08.01.2016 10:44:01]

#

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.

Grez [08.01.2016 11:02:30]

#

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.

groovyb [08.01.2016 14:03:19]

#

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.

Grez [08.01.2016 14:41:06]

#

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.

groovyb [08.01.2016 15:34:04]

#

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.

vinsentti [10.01.2016 08:20:25]

#

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.

jlaire [10.01.2016 16:59:55]

#

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/e_c09_p3.ada
http://www.infres.enst.fr/~pautet/Ada95/e_c08_p5.ada

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ä).

vinsentti [10.01.2016 17:22:28]

#

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.

jalski [11.01.2016 21:24:56]

#

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;

vinsentti [14.01.2016 22:54:03]

#

Puolihuolimatonta herjanheittoa Objective-Cstä. Koskee toki koko C-perinnettä.

http://www.infoworld.com/article/2606364/objective-c/article.html#slide5

fergusq [15.01.2016 19:34:12]

#

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ä".

vinsentti [17.01.2016 19:00:38]

#

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ä.

Metabolix [17.01.2016 19:15:53]

#

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.

Grez [17.01.2016 22:03:49]

#

Minusta taas lohkosanalliset on lohkosuluttomia

Jos lohkosanallista kieltä kutsuu lohkosululliseksi, niin eikös sitten samalla logiikalla lohkosisennyksellinen kieli, kuten Python, ole lohkosulullinen.

fergusq [17.01.2016 22:42:37]

#

Tätä keskustelua on leimannut toistuva harhaanjohtavien termien käyttö. Minusta olisi kiva, jos vinsentti vaivautuisi edes määrittelemään selkeästi, mitä kannattaa.

Metabolix [17.01.2016 23:01:21]

#

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.

vinsentti [17.01.2016 23:43:36]

#

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.

Metabolix [17.01.2016 23:47:16]

#

Mikähän ihme siinä on sitten alkujaankaan ollut sekavaa?

groovyb [18.01.2016 15:27:04]

#

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.

vinsentti [19.01.2016 18:42:20]

#

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

Oskuz [19.01.2016 19:10:29]

#

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.

vinsentti [19.01.2016 21:44:34]

#

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.

fergusq [20.01.2016 17:56:00]

#

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ä.

Grez [21.01.2016 10:48:39]

#

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.

vinsentti [21.01.2016 12:12:34]

#

Sulkujen lisäksi lähti puolipisteetkin. Aikaa tosin kului parikymmentä vuotta siitä, kun suluista oli päästy eroon. Ei tämä niin helppoa ole.

jalski [21.01.2016 13:27:42]

#

vinsentti kirjoitti:

(21.01.2016 12:12:34): Sulkujen lisäksi lähti puoli­pis­teetkin. 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...

groovyb [21.01.2016 14:21:27]

#

Merkkijonoilla jotakin tähän suuntaan:

class
    HELLO_WORLD
create
    make
feature
    make
        do
            print ("Hello, %N%
                    %World%N")
        end
end

Grez [21.01.2016 14:30:31]

#

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ä.

groovyb [21.01.2016 14:48:22]

#

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
}

jalski [21.01.2016 15:51:09]

#

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;

jlaire [22.01.2016 04:32:36]

#

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: {}

Grez [22.01.2016 10:09:12]

#

jlaire kirjoitti:

Kaarisulut: ()
Aaltosulut: {}

Kiitos muistutuksesta. Korjasin ajatusvirheeni :)

fergusq [23.01.2016 12:58:59]

#

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.

jlaire [24.01.2016 02:59:33]

#

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

vinsentti [24.01.2016 10:20:57]

#

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.

jlaire [25.01.2016 06:17:43]

#

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.

vinsentti [25.01.2016 08:09:24]

#

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.

vinsentti [27.01.2016 08:47:29]

#

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

Grez [27.01.2016 15:49:15]

#

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.

fergusq [27.01.2016 17:33:10]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta