ugrás a tartalomhoz

Why most unit testing is waste

Hidvégi Gábor · 2015. Ápr. 21. (K), 18.21
Az egységtesztelésnél elkövetett gyakori hibákról, javaslatok a helyes használatra
 
1

Ez egy jó írás. Ennek kapcsán

Joó Ádám · 2015. Ápr. 21. (K), 18.27
Ez egy jó írás. Ennek kapcsán sor került egy beszélgetésre is a szerző és Uncle Bob között: https://www.youtube.com/watch?v=KtHQGs3zFAM

Szomorú, hogy tapasztalatom szerint a legtöbb fejlesztő nem igazán érti a tesztelés inherens korlátait, ami egyrészről rengeteg elvesztegetett munkát, másrészről hamis biztonságérzetet és végeredményben rossz kódot eredményez.
2

Tesztelés korlátainál a unit

blacksonic · 2015. Ápr. 21. (K), 21.15
Tesztelés korlátainál a unit tesztelés korlátaira gondolsz?
Mert önmagában unit tesztelés nem tud mindent lefedni, érdemes kiegészíteni másfajta tesztekkel is.
3

Nem, arra, hogy ahogy

Joó Ádám · 2015. Ápr. 21. (K), 22.48
Nem, arra, hogy ahogy Dijkstra írja:

Testing shows the presence, not the absence of bugs


Hiába az összes teszt, amit írsz, általános jellegű garanciát ezek semmire nem jelentenek (szemben a formális analízis különböző fajtáival, mint például egy statikus típusrendszer).

Tesztelni kell, és van, amit érdemes automatizáltan tesztelni, de ez semmi mást nem jelent, mint hogy kipróbáltam a kódomat egy célzottan megválasztott bemenetre.

Ahogy arra Rich Hickey hívja fel a figyelmet:

What’s true of every bug found in the field? It passed all the tests.
7

Formális analízis témában

pythonozok · 2015. Ápr. 24. (P), 11.47
Formális analízis témában tudnál valami rövid, közérthető, lehetőleg magyar nyelvű olvasmányt ajánlani? Esetleg két-három mondatban összefoglalni, hogy ezek miért jelenthetnek garanciát a hibamentességre?
(a statikus típus példád értem azt hiszem, ott csak azt nem értem, hogy az hol kapcsolódik a formális analízis témához... de lehet, hogy az egészet félreértem és ennek kicsit más a funkciója, mint a unit-, funkcionális- stb. teszteknek)


Válaszolok magamnak: infokukac.com
8

a statikus típus példád értem

Joó Ádám · 2015. Ápr. 26. (V), 01.45
a statikus típus példád értem azt hiszem, ott csak azt nem értem, hogy az hol kapcsolódik a formális analízis témához...


A típusellenőrzés egy formális módszer. Egy statikus nyelvben deklaratívan meg tudom adni, hogy egy művelet eredménye milyen érték lehet, és a fordító garantálja, hogy soha nem lesz más; egy dinamikus nyelvben írhatok rá egy tesztet, ami garanciát még arra sem fog adni, hogy ugyanazokra a bemeneti értékekre ugyanazt fogom eredményül kapni.

de lehet, hogy az egészet félreértem és ennek kicsit más a funkciója, mint a unit-, funkcionális- stb. teszteknek


A kettőnek nem ugyanaz a funkciója, nyilvánvalóan nem lehet mindent formálisan ellenőrizni. Engem csak az ijeszt meg, amikor állítólagos szakemberek szájából elhangzik az az érv, hogy „a statikus típusrendszer felesleges, hisz úgyis kell tesztelni!”, illetve, amikor egy kódbázis minőségét az alapján ítélik meg, hogy vannak-e hozzá unit tesztek, egy refaktorálást pedig ipso facto sikeresnek könyvelnek el, mert futnak a tesztek.
13

"Engem csak az ijeszt meg,

virág · 2015. Ápr. 28. (K), 15.31
"Engem csak az ijeszt meg, amikor állítólagos szakemberek szájából elhangzik az az érv, hogy „a statikus típusrendszer felesleges, hisz úgyis kell tesztelni!”, illetve, amikor egy kódbázis minőségét az alapján ítélik meg, hogy vannak-e hozzá unit tesztek, egy refaktorálást pedig ipso facto sikeresnek könyvelnek el, mert futnak a tesztek."

+100

Abszolút igazad van. Szerintem az ilyesmi akkor szokott bekövetkezni amikor valaki megfeledkezik arról, hogy minden eszköz csak eszköz és annyit ér amennyit a felhasználója...a "unit teszt"-re valóban sokan csodaszerként tekintenek, ez hiba. De azért abba a hibába se kéne beleesnünk, hogy azt sugalljuk, hogy nem fontosak. Mindennek megvan a helye.
17

Engem csak az ijeszt meg,

ydsMo9gx · 2015. Május. 31. (V), 06.12
Engem csak az ijeszt meg, amikor [...] egy refaktorálást pedig ipso facto sikeresnek könyvelnek el, mert futnak a tesztek.

A refaktorálás utáni sikeres tesztekre is érvényesek Dijkstra, illetve Rich Hickey állításai. Vagyis a sikeres tesztek csak azt bizonyítják, hogy nincs velük kimutatható jele az átgyúrás kudarcának.

No de pont ez a lényege a TDD-nek. Nem garantál semmit, csak detektál.

Korábban ezt írtad:
általános jellegű garanciát ezek semmire nem jelentenek (szemben a formális analízis különböző fajtáival, mint például egy statikus típusrendszer).

Ugye erős típusosságra gondoltál? Merthogy például a C statikusan típusos, de a compilerek hibajelzés és figyelmeztetés nélkül lefordítanak neked olyan hibás kódot is, amitől elsírod magad, ha jól megnézed... Gondolj csak az automatikus típuskonverziókra. A C statikusan, de gyengén típusos.
18

A lényeg az, hogy ne

MadBence · 2015. Május. 31. (V), 23.26
A lényeg az, hogy ne dinamikus legyen (fordítási időben szeretnénk ismerni a kifejezések típusát). Innentől kezdve a fordító képes (kéne hogy legyen) felismerni a hibás kifejezéseket. Pusztán az erős típusosság nem elegendő (már ha azt a definíciót vesszük alapul, hogy erős típusosság = nincs implicit típuskonverzió), lásd Python.
19

definíciók - erősen és gyengén, statikusan és dinamikusan

ydsMo9gx · 2015. Jún. 1. (H), 08.43
Úgy tudom, nincs "hivatalos" (számítástudományi) meghatározása ezeknek a fogalmaknak.

A dinamikusnak az lehetne, amit írsz, vagyis fordítási időben nem ismert a változók típusa. Közelebbről megnézve persze kiderül, hogy a dinamikusan típusos(nak nevezett) nyelvekben is meghatározható, illetve behatárolható egyes változók típusa a program futása előtt, de nem az összes változóé. Példa: a műveletek általában impliciten jelzik, hogy numerikus típusú egy változó, string, vagy mondjuk logikai, illetve skalár, tömb, vagy összetett (record, struct stb.). A statikusan típusos nyelvekben is egyre inkább támaszkodnak erre a fordítók készítői, mert lehetővé teszi a típusmegadás elhagyását. Friss példa a Go. Nem kell leírni benne, mégis egyértelmű, hogy az x := 3.14 utasításban x lebegőpontos változó, ez egyben típusdeklaráció is, 64 bites float (float64) lesz (mert a nyelvben az a default float típus).

A lebegőpontos konstansok írásmódja a legtöbb nyelvben a gépi ábrázolás pontosságát is jelzi. A kettő együtt precízen meghatározhatóvá teszi a változó típusát? Nem feltétlenül, mert egyes nyelvekben az azonos gépi ábrázolású lebegőpontos változók típusa is eltérhet, ha úgy definiálod, hogy az egyik típus például hosszúságot, a másik tömeget, a harmadik dollárban megadott pénzmennyiséget ábrázol: 2.5 m és 3.42 kg vagy 91.8 $ nem adható össze. És persze euró sem adható össze mondjuk dollárral. Friss példa erre az F# valamelyik új verziója (eleinte nem volt benne ilyen). Adában értékintervallumot is megadhatsz a numerikus típusoknál, és ha egy művelet végeredménye kilép abból, akkor hardveres túlcsordulás nélkül is kivétel lép fel. Negatív hossznak vagy időtartamnak nincs értelme, abszolút nulla alá nem csökkenhet a hőmérséklet stb. A kivételt persze lekezelhetjük.

És a legdinamikusabban típusos nyelvekben sincs mindenről mindenre konverzió futási időben.

A dinamikus-statikus spektrum tehát nem két fokozatú, nem fekete-fehér. És még ez a legkönnyebben elemezhető kérdés a témában.

A gyengén-erősen dualitás esetében is inkább az erősség mértéke a kérdéses. A C típuskonverzióit csak példának hoztam fel, nem definíciónak szántam. Vannak veszélytelen implicit típuskonverziók, például 8 bites egészek 16, 32, 64 bitesre nyugodtan átalakíthatók, persze az előjelességüket megtartva. (Ez is csak példa.) Itt a spektrum egyik végén egyáltalán nincsenek típusok: assemblyk, Forthok, Lispek többsége (ezekből is vannak típusos fajták). A másik végén nemhogy erős típusok vannak, hanem különféle merevségű típusrendszerek, precíz elméleti háttérrel és annak könyörtelen gyakorlati megvalósításával.

Ami a kérdés lényege: mennyit segít egy nyelv (pontosabban nyelvi implementáció, értelmező vagy fordító) statikus, illetve erős típusossága a program helyességének ellenőrzésében?

Azt állítom, hogy a dinamikusan típusos nyelvek közel azonos mértékben segítenek, mint a statikusak, csak nem fordítási időben, hanem futásidőben ellenőriznek. Persze bosszantó, ha futás közben kiderül, hogy hibáztunk a program írásakor, de szerintem semmivel nem kellemetlenebb, mint amikor a compiler figyelmeztet erre, legfeljebb szokatlan és emiatt meghökkentő eleinte. A kevésbé használt programágakra ritkán kerül rá a vezérlés, emiatt egyes típushibák sokáig rejtve maradhatnak, de a gyakorlatban nagyon ritkán fordul elő ilyesmi, és akkor sem csak típushibák jöhetnek elő, mindezek ellen pedig kötelező a legalább felületes tesztelés. Másrészt futásidőben olyan információkhoz is hozzájut a futtatórendszer, amiket fordítási időben nem ismerhet, és ez további ellenőrzésekre ad lehetőséget. Most akkor a dinamikusan típusos nyelvek segítenének többet a hibák kiderítésében? Szerintem nem, a mérleg itt inkább döntetlenre áll.

Sokéves gyakorlati tapasztalatom: a Python duck typingja elegáns, tömör, jól olvasható programokat tesz lehetővé, gyorsan írható a kód, mégis erősen típusos a nyelv és ritkán okoz gondot a statikus ellenőrzés hiánya. Elég trehány vagyok, néhányszor futásidejű kivételt kaptam nem tesztelt programágakon, de ezek túlnyomó többsége nem típushiba volt! Korábban a PHP-vel sokat szívtam, mert az interpreter a legostobább elírásaimat is megpróbálta valahogy értelmezni és valamit lefuttatni. Anyáztam eleget, utáltam a nyelvet és a hülyeségemet, de nem volt rá megoldás. A PHP ad hoc ötletek kusza halmaza, Rasmus Lerdorf bevallottan nem ért a nyelvtervezéshez, nem is akarta soha megtanulni, büszke a saját hülyeségére, mint a politikusaink. C-ben az implicit konverziókkal szívtam sokat, még többet a void pointerekkel. Statikusan típusos nyelv, de a compiler alig segít, mert nagyon lazák (gyengék) a típusok. Nem a dinamikus kontra statikus kérdés az igazi.

Az erős kontra gyenge típusosság esetében viszont határozottan előnyt ad a típusok meghatározhatóságának és ellenőrizhetőségének mértéke. Minél erősebb, annál több hibát jelezhet. A statikus típusmegadás persze elkerülhetetlen, ha a numerikus ábrázolás pontosságát, értékintervallumot, az értékek dimenzióját is meg akarjuk határozni. A típusrendszer merevsége (erőssége) látszólag gúzsbaköt, valójában felszabadít, átveszi a programok megtervezésének egy részét. Ha tudatosan kihasználjuk a lehetőségeit, különösen sokat segíthet nem csak a kód írásakor, hanem a későbbi megértésében is! A compiler vagy interpreter figyelmeztetéseinek, hibajelzéseinek örüljünk, ne bosszantásnak vegyük! Helyettünk dolgozik.

Nemrég futottam bele egy típusrendszerek hasznosságát vizsgáló, alaposnak tűnő áttekintésbe. Az empirikus vizsgálatok többsége érthető okokból a kész programok minőségét vizsgálja (mennyi hiba esik 1000 kódsorra stb.), de pont emiatt nem mutatja ki az erős típusosságnak a programok tervezésekor és írásakor nyújtott segítségét. A típusvizsgálat legtöbb típushibát tervezési és írási időben segít kiszűrni, nem fordítási időben. A statikus kontra dinamikus kérdéskör is pont a két kései fázist firtatja, pedig nem a fordítási és a futási időben kapunk sok segítséget a típusok kezelésétől.

Akit a téma mélyebben is érdekel, annak a Lambda the Ultimate-et ajánlom.

Ha rám hallgattok, akkor tegyétek félre a kételyeiteket, és próbáljátok ki a Gót. Erősen és statikusan típusos. A Rust compilere segít talán legtöbbet, de nagyon lassan fordít. És ez a legtöbb erősen és statikusan típusos nyelvre igaz, mert sok munkához sok idő kell. A Go compilere és linkere villámgyors, és az is marad, mert kifejezetten így tervezték a nyelvet, egyszerűnek és gyorsan fordíthatónak. Pont azokra a problémákra adnak benne jó megoldásokat, amik annak idején oly sokat bosszantottak a C-nél. Nem váltja le a C-t, de kiváló eszköz, egyre több területen használható. Webre már ideális eszköz. PHP, Java, és a mostanában divatba jött Node.js is elbújhat mögötte. Könnyen megtanulható. Tapasztalt, vén profik tervezték és fejlesztik. Több évtizedes tapasztalataim alapján az összes döntésükkel egyetértek. Ezt egyetlen más nyelv sem közelíti meg, pedig sokat tanulmányoztam és próbálgattam. Doktrínák, kísérletezés, kétes használhatóságú elméletek, dogmák helyett tapasztalatokból kiindulva könnyen használható, sokat segítő, gyorsan fordítható és futtatható nyelvet terveztek és készítettek. Emberek, Go a jövő. Ne keresgéljetek tovább.
20

Menjünk

Hidvégi Gábor · 2015. Jún. 1. (H), 09.53
Nem tudom, nekem sosem volt gondom PHP-ban a típusokkal, bár hozzáteszem, mindig az egyszerűségre törekedtem. Ettől függetlenül szerintem is a Go a legigéretesebb nyelv manapság.
21

most találtam

ydsMo9gx · 2015. Jún. 1. (H), 19.49
Building Web Apps with Go

Nekem se a típusokkal volt gondom PHP-ben (mert lényegében nincsenek, de ez csak annyit jelent, hogy az interpreter sokkal kevesebbet segít az adatok kezelésében). Mondjuk az mellbevágott, amikor idézőjelek nélküli (kapkodásban elírt), angol nyelvű (ékezet nélküli) stringeket is értelmezett valahogy az interpreter (részletekre már nem emlékszem, csak a megdöbbenésemre).

Beszéljen helyettem inkább a web :). Nem az érdekes, hogy lehet elborult kódot írni PHP-ben, hanem egyes erre használható konkrét fordulatok az izgalmasak, némelyik sűrűn előfordulhat tisztességes kódban is.

Mint C-ben ez a gyöngyszem:

#include <stdio.h>

int main(){
    int i;
    for(i=0; i<10; i++);{
        printf( "%d\n" ,i);
    }
    return 0;
}
Itt kipróbálhatjátok, ha nem tűnik szembe a hiba oka. Cut&paste, compile, execute, egyetlen számot ír csak ki.

Nem ennyire egyszerű, sokkal nehezebben átlátható volt a kód, itt kiemeltem a baki lényegét. Törlések, hozzáírások, hétköznapi módosítások idézték elő, teszt se mutatta ki a hibát, mert a for ciklus feltétele nagyon összetett volt, és ritkán teljesült (elvileg), mégis mindig lefutott egyszer a hozzá tartozó {} blokk.

Elnézést az offolásért.
25

Mondjuk az mellbevágott,

Joó Ádám · 2015. Jún. 4. (Cs), 02.39
Mondjuk az mellbevágott, amikor idézőjelek nélküli (kapkodásban elírt), angol nyelvű (ékezet nélküli) stringeket is értelmezett valahogy az interpreter (részletekre már nem emlékszem, csak a megdöbbenésemre).


Konstansként értelmezi, aminek, ha nincs definiálva, akkor a konstans neve mint sztring az értéke. Elképesztő nyelv.
22

Friss példa

ydsMo9gx · 2015. Jún. 3. (Sze), 17.24
Friss példa az erősen típusos nyelvek (lehetséges) előnyeire.
24

A lebegőpontos konstansok

Joó Ádám · 2015. Jún. 4. (Cs), 02.33
A lebegőpontos konstansok írásmódja a legtöbb nyelvben a gépi ábrázolás pontosságát is jelzi. A kettő együtt precízen meghatározhatóvá teszi a változó típusát? Nem feltétlenül, mert egyes nyelvekben az azonos gépi ábrázolású lebegőpontos változók típusa is eltérhet, ha úgy definiálod, hogy az egyik típus például hosszúságot, a másik tömeget, a harmadik dollárban megadott pénzmennyiséget ábrázol: 2.5 m és 3.42 kg vagy 91.8 $ nem adható össze.


Ezekre illene is önálló típust bevezetni, ha nem volna túl körülményes a legtöbb nyelvben. Az Adában nagyon szeretem ezt a lehetőséget, a legújabb C++ pedig egyedi literált is enged rendelni saját típushoz.

a Python duck typingja elegáns, tömör, jól olvasható programokat tesz lehetővé, gyorsan írható a kód


Állításom: a Python nem a statikus típusrendszer hiányától lesz egy fantasztikus nyelv, és annak jelenléte nem rontana lényegesen az általa nyújtott élményen.

Elhiszem, ha azt mondod, hogy úgy érzed, a te mindennapi munkád során nem térül meg számodra egy statikus típusrendszer használata, mert mondjuk Pythonban is tudsz helyes kódot írni. Vannak, akik azt mondják, hogy ők PHP-ban is tudnak. Ezek szubjektív állítások. Az, hogy egy statikus típusrendszer nem enged bevezetni bizonyos hibákat, az meg tény.

Ami azt a kérdést illeti, hogy mennyire gyakoriak a típushibák a hibák közt általában, arra a válasz leginkább embertől (egy személyiségéből fakadóan kevésbé precíz vagy fáradt fejlesztő több formai hibát fog véteni) és feladattól (egy komplex algoritmus több logikai hibát fog tartalmazni, mint egy triviális) függ. A magam részéről elég fegyelmezett vagyok, ezért hosszú évekig jól megvoltam különböző dinamikus (vagy statikus, de gyengén típusos) nyelvekkel, de egy idő után rájöttem, hogy mennyi energiát emészt fel az a fajta koncentráció, ami mondjuk ahhoz szükséges, hogy az ember C++-szal ne vágja le a kezét, és amit egy fordító a megfelelő nyelv esetén megspórol neki. Ezért váltottam például Adára. Egy kellően kifejező típusrendszer egyébként a megfelelő programozói gyakorlattal olyan hibákat is típushibákká alakíthat, és így kiküszöbölhet, amik elsőre nem tűnnek annak.

Ha rám hallgattok, akkor tegyétek félre a kételyeiteket, és próbáljátok ki a Gót. … Pont azokra a problémákra adnak benne jó megoldásokat, amik annak idején oly sokat bosszantottak a C-nél.


És pont az a mentalitás, ami mindig is bosszantott a C-nél. Ami nem csoda, hisz ugyanazok az emberek állnak mögötte. Ne érts félre, én nagyon szeretem a C-t, de a C a maga idejében sem számított modern nyelvnek, és nem is igazán fenntarthatóak benne nagyobb (a nagyobb egy elég kicsi definíciójára) projektek.

A Go esetében például a generikus programozás hiánya számomra érthetetlen, és a strukturális típuskompatibilitással együtt eléggé leértékeli a statikus típusrenszerét ahhoz, hogy fájó szívvel, de lemondtam róla, amikor lelkesen tanulmányozni kezdtem.
26

lokálisan optimális kompromisszumok

ydsMo9gx · 2015. Jún. 4. (Cs), 04.39
a Python nem a statikus típusrendszer hiányától lesz egy fantasztikus nyelv, és annak jelenléte nem rontana lényegesen az általa nyújtott élményen.

Egyetértek. Pontatlanul fogalmaztam, nem akartam hosszasan boncolgatni ezt a unit testinggel kevéssé összefüggő részletet. Pontosítom az eredeti állításomat, első lépésben csak a feltétlenül szükséges mértékben: a duck typingot statikus típusellenőrzésre cserélve, a típusrendszer további erősítése nélkül még nem nyerne semmit a Python.

(A 2. lépés már más nyelvekre is igaz:) A statikus ellenőrzések ugyanis csak szükséges, de nem elégséges előfeltételei az erős(ebb) típuskezelésnek.

(A 3. lépés az érdekes:) Tehát az a kérdés (a Python esetében), hogy mit tennénk hozzá a típuskezeléshez a statikus típusosság bevezetése után? Most vezetik be a type hintinget, függvény-annotációk formájában, persze csak a Python 3-ba. (Most fogadták el az erre vonatkozó PEP-et, a 484-es rémlik valamiért, de az tavaly szeptemberi.) No, ezzel semmit nem nyernek, rengeteg munka árán. Nyilván időt hagynak maguknak, a felmerülő ötletek és javaslatok közül ráérnek válogatni majd akkor, amikor elkészültek ezzel a munkafázissal.

Az, hogy egy statikus típusrendszer nem enged bevezetni bizonyos hibákat, az meg tény.

Fenntartom, hogy "a dinamikusan típusos nyelvek közel azonos mértékben segítenek, mint a statikusak, csak nem fordítási időben, hanem futásidőben ellenőriznek". (A teljes bekezdést lásd a 19. hozzászólásban, nem másolom ide.) Tehát példát kérek a statikusság előnyére, a legszűkebben vett értelmében (azaz a statikusságra építő kiegészítések nélkül). Vagy inkább hagyjuk a kérdést, mert szerintem egyetértünk, és immár eljutottunk a szőrszálhasogatásig.

Egy kellően kifejező típusrendszer egyébként a megfelelő programozói gyakorlattal olyan hibákat is típushibákká alakíthat, és így kiküszöbölhet, amik elsőre nem tűnnek annak.

Így van, ha a nyelv lehetőséget ad rá, a típusrendszer sokat segít a tervezésben. Sajnos ezt sehol nem tanítják. Ja, tanítják, csak OO design néven :).

A Go esetében például a generikus programozás hiánya számomra érthetetlen

Csak azért hagyták ki, mert még nem találták meg az igazán jó implementálásának módját. (Nekem megfelelne az Adáéhoz hasonló megoldás, de ha nekik nem, belenyugszok. Még nem hiányzott.) Miután bevezetik valamilyen formában, azután nem, vagy inkább nagyon nehezen módosíthatják majd a később megírt kódok miatt. A nyelvtervezés olyan, mint a mikádó/marokkó, csak itt a tervezők építik a pálcikahalmot, nem véletlenszerűen áll elő. Roppant nehéz visszabontani valamit egy nyelvből anélkül, hogy más részeket is megmozdítanának. Sok nyelv szenved az elkapkodott, nem eléggé körültekintően hozzáadott kiegészítései miatt. Kísérleti nyelveknél nem gond, de népszerűeknél a nyelv hosszas kínlódását, stagnálását okozhatja egy-egy visszabontás. (Szerintem ne menjünk bele a részletekbe, nem annyira érdekes.)

A Gónál a generikusok hiánya
a strukturális típuskompatibilitással együtt eléggé leértékeli a statikus típusrenszerét

A szerkezeti típuskompatibilitás teszi lehetővé az öröklés elegáns kikerülését, az OOP előnyeinek megtartásával. Választaniuk kellett, és szerintem jól választottak.

Fuss neki még egyszer a Gónak, érdemes. Lokálisan szuboptimális kompromisszumokból álló, kiváló érték/ár arányú konfiguráció. És a tervezői priorizálták a teendőket. A nyelvtervezés nem kívánságműsor, hanem komoly mérnöki munka, sok tapasztalatot kíván és rengeteg gürcölést. (Én is foglalkoztam vele, nem jutottam messzire, de sokat tanultam belőle.)
28

Python type hint: ez azt

pythonozok · 2015. Jún. 4. (Cs), 19.16
Python type hint: ez azt hiszem, leginkább az IDE-k kódkiegészítő funkcióját akarja megtámogatni, szabványos formában. Most is létezik ilyesmi, csak ahány IDE, annyiféle stílus.

update: bocs, most tudtam csak megnézni azt a PEP-t, ez már egészen más, mint ami ezzel foglalkozó írást én láttam.
Úgyhogy a fenti storno...
27

A statikus ellenőrzések

Joó Ádám · 2015. Jún. 4. (Cs), 17.57
A statikus ellenőrzések ugyanis csak szükséges, de nem elégséges előfeltételei az erős(ebb) típuskezelésnek.


Tudsz mondani példákat a lehetséges további lépésekre, mert nem tudom, hogy jól értem-e a mondandód.

Fenntartom, hogy "a dinamikusan típusos nyelvek közel azonos mértékben segítenek, mint a statikusak, csak nem fordítási időben, hanem futásidőben ellenőriznek". … Tehát példát kérek a statikusság előnyére
from random import randint
from datetime import date

def n():
    return randint(1, 9) if date.today().timetuple()[1:3] != (2, 29) else ':P'

# …

print(result - n())
A fentit a fordító megfogná, a teszt nem.

Csak azért hagyták ki, mert még nem találták meg az igazán jó implementálásának módját.


Ez a magyarázat elég kínos, egyrészt azért, mert veteránokról van szó, másrészt azért, mert éles használatra késznek mondják a nyelvet.

Én szomorúan úgy gondolom, hogy a nyelv a C-hez hasonlóan a Bell csapat személyes preferenciáit tükrözi, nem pedig arra vonatkozó megfontolásokat, hogy mi segítené leginkább helyesen működő szoftverek írását a nagyvilágban.

Még nem hiányzott.


Nyilván, hisz korábban kifejtetted, hogy megelégszel a futásidejű hibákkal is. Én csak azt állítom, hogy a generikusság hiánya aláás egy egyébként statikus típusrendszert, mert arra kényszerít, hogy megkerüld.

A szerkezeti típuskompatibilitás teszi lehetővé az öröklés elegáns kikerülését, az OOP előnyeinek megtartásával.


Az öröklődés és a típuskompatibilitás ortogonális funkciók. Ha nem akarnak öröklést, nominális kompatibilitás mellett is kihagyhatták volna. A strukturális kompatibilitás ismét csak gyengíti a statikus típusrendszert, hisz szándékolatlan kompatibilitást vezehet be típusok közt.

Fuss neki még egyszer a Gónak, érdemes.


Én szeretnék, tényleg, mert sok nagyon vonzó tulajdonsága van. De mindig rájövök, hogy a fenti és hasonló hiányosságok túl zavaróak volnának.
29

Tudsz mondani példákat a

ydsMo9gx · 2015. Jún. 5. (P), 01.03
Tudsz mondani példákat a lehetséges további lépésekre, mert nem tudom, hogy jól értem-e a mondandód.

Példa: a C statikusan típusos, de gyengén. Tehát a statikus ellenőrzések önmagukban nem elégségesek az erős(ebb) típuskezeléshez (de nyilvánvalóan szükségesek).

Ha a típusrendszer lehetővé teszi a típusdeklarációk finomabb kidolgozását, a compiler gondosan ellenőrzi is ezeket a részleteket, és nem konvertál automatikusan, akkor megvalósul az erős(ebb) típuskezelés, beteljesül a lehetőség (a finom kidolgozás, a gondos ellenőrzés és az automatikus átalakítások hiánya csak példák). Példák: szinte az összes statikusan típusos nyelv. Az erős(ebb) típuskezelés egyes módjai csak statikus típuskezelés mellett lehetségesek, például a részletes típusdeklarációk. Az adatábrázolás egyezése mellett megkövetelhető például az adatokon végezhető műveletek egyezése is (egyik a másik részhalmaza legyen, nem kell a teljes egyezésük), és ezt is statikusan érdemes ellenőrizni.

Végül a "dinamikus erősebb lehet, mint a statikus" változatra példa a numerikus túlcsordulások és az index-túllépések futásidejű ellenőrzése. Ezt ugyan például sok C compiler is felkínálja fordítási opcióként, de a nyelv nem definiálja a kezelésük lehetőségeit, kivételkezelés sincs. Pythonban van kivételkezelés, és a futásidejű túlcsordulások is lekezelhetők, az indextúllépések szintén. (Egész túlcsordulás nincs, korlátlan a számábrázolás.)

Ha a Pythonnál a most bevezetésre kerülő statikus alapokra építve megvalósítható lehetőségeket firtatod, hirtelenjében ezek jutnak eszembe:

1) A változók és az argumentumok típusmegadási konzisztenciájának ellenőrzése. Azaz ha mondjuk egy pragmával előírjuk a típusmegadást, akkor mindenütt követelje meg a compiler, ahol nincs kikapcsolva a megfelelő pragmával. A standard libraryben így tetszés szerint lehetne továbbra is megadni vagy elhagyni a típusokat, kikapcsolva a típusmegadás megkövetelését. A programokban, librarykben stb. pedig a szerzők dönthetnék el, mit szeretnének: szigort és hatékonyságot, avagy rugalmasságot?

Nekem tetszene ez a lehetőség. Ennél sokkal erősebb típusosságra szavaznék ugyan, de Guido van Rossum ezt kizárta előre, ő nagyon rugalmas Pythont akar továbbra is. A fentihez hasonló kompromisszumra még látok esélyt.

2) Erősebb típusmegadási lehetőségek. Például az egészek értékkészletének korlátozása révén elérhető optimalizálások érdekében. A NumPy egy sor példát mutat erre és továbbiakra, nyilván a hatékonyabb kód érdekében. Jókora részét amúgy is C-ben írták, ha jól tudom.

A fentit a fordító megfogná, a teszt nem.

Ezt kaptam rá:
NameError: name 'result' is not defined

De enélkül sem értem a példát, talán a hőhullám miatt.

Egyébként sem a tesztek mellett, netán a statikus ellenőrzések ellen érveltem (ha mégis úgy tűnik, akkor elnézést, fel sem merült bennem ez a szándék). A nagyon erős típusosság híve vagyok, az pedig csak statikus ellenőrzések révén lehetséges. Az elméleti alapokat akartam csak tisztázni, elnézést, ha nehezen érthető volt, amit írtam.

Ez a magyarázat elég kínos, egyrészt azért, mert veteránokról van szó, másrészt azért, mert éles használatra késznek mondják a nyelvet.

Sorra vették az ismert lehetőségeket, és egyiket sem találták kifogástalannak a továbbiakra nézve. Mindegyikkel adódnak gondok, ez tény, nem ők hozzák fel mentségnek. A dilemma lényege: vagy szörnyen kövér lesz a kód, vagy kínosan lassú lesz, vagy aránytalanul elbonyolódik egy amúgy kellemesen egyszerű nyelv.

A generikusok hiánya szerintem nem akadálya az éles használatnak. Évek óta sikeresen fejlesztenek Góban elég nagy cégek, én már elég későn kapcsoltam.

a generikusság hiánya aláás egy egyébként statikus típusrendszert, mert arra kényszerít, hogy megkerüld

Nem kényszerít. Az egyirányú kódgenerálás elegáns megoldás egy sor problémára, erre is. A cog pedig kiváló, nyelvfüggetlen kódgenerátor. Sokat használtam már.

A strukturális kompatibilitás ismét csak gyengíti a statikus típusrendszert, hisz szándékolatlan kompatibilitást vezehet be típusok közt.

OCamlben nem okoz sok gondot, Haskellben sem, pedig nagyon erősen típusosak. Vannak még példák, most ezek jutottak eszembe.

Ha tartasz a váratlanul fellépő strukturális kompatibilitásoktól, megfelelő típusdeklarációval védekezhetsz az ilyen hibák ellen. Ha ki akarod használni, akkor pedig jól jön.

Nem akarlak győzködni. Az Ada és a Rust mellett valóban komolytalannak tűnhet a Go. Nem az, de annak tűnhet :).
30

Évek óta sikeresen

Joó Ádám · 2015. Jún. 6. (Szo), 19.56
Évek óta sikeresen fejlesztenek Góban elég nagy cégek, én már elég későn kapcsoltam.


PHP-ban is rengeteg cég fejleszt sikeresen (legalábbis a siker valamilyen definíciójára). Nem állítom, hogy a Go használhatatlan, csak azt, hogy szerintem nem teszi meg a jelenlegi tudásunk szerinti legtöbbet azért, hogy előremozdítsa az iparágat.

Sorra vették az ismert lehetőségeket, és egyiket sem találták kifogástalannak a továbbiakra nézve. Mindegyikkel adódnak gondok, ez tény, nem ők hozzák fel mentségnek. A dilemma lényege: vagy szörnyen kövér lesz a kód, vagy kínosan lassú lesz, vagy aránytalanul elbonyolódik egy amúgy kellemesen egyszerű nyelv.


Ha nincs jó megoldás egy megoldandó problémára, akkor választani kell egyet a rosszak közül.

Az egyirányú kódgenerálás elegáns megoldás egy sor problémára, erre is.


Ha elegáns megoldás a problémára, akkor miért nem támogatja a Go nyelvi szinten? ;) A kódgenerálás mindig a generált nyelv hiányosságára mutat rá.

OCamlben nem okoz sok gondot, Haskellben sem, pedig nagyon erősen típusosak. Vannak még példák, most ezek jutottak eszembe.


Elég rosszul kell állniuk a csillagoknak ahhoz, hogy ebből az elméleti lehetőségből gyakorlati hiba legyen, ez tény. Én azonban épp az elvi garanciák miatt propagálom a statikus típusrendszereket.

Ha tartasz a váratlanul fellépő strukturális kompatibilitásoktól, megfelelő típusdeklarációval védekezhetsz az ilyen hibák ellen.


Itt mire gondolsz?

Nem akarlak győzködni. Az Ada és a Rust mellett valóban komolytalannak tűnhet a Go. Nem az, de annak tűnhet :).


Szerintem hasonlóak az elvárásaink, csak árnyalatokban térnek el :)

De enélkül sem értem a példát, talán a hőhullám miatt.


A példában szereplő függvény szökőnapokon egész helyett sztringet ad vissza, ilyenkor a függvényt használó, egészet feltételező műveletek elszállnak. Egy statikus típusrendszer mellett ez a kód nem fordul le, egy dinamikus esetén a példában feltételezett specifikáció mentén írt tesztek sem fogják kimutatni, hacsak nem február 29-én futnak.

Végül a "dinamikus erősebb lehet, mint a statikus" változatra példa a numerikus túlcsordulások és az index-túllépések futásidejű ellenőrzése. Ezt ugyan például sok C compiler is felkínálja fordítási opcióként, de a nyelv nem definiálja a kezelésük lehetőségeit, kivételkezelés sincs. Pythonban van kivételkezelés, és a futásidejű túlcsordulások is lekezelhetők, az indextúllépések szintén.


Ahogy mondjuk az Ada is nyelvi szinten támogatja ezeket. Az, hogy egy objektum futásidőben milyen állapotba kerülhet (túlcsordulás), illetve hogy adott állapotában milyen paraméterekkel végezhetők rajta műveletek (túlindexelés), az az állapotát fenntartó műveletek (nyelvi vagy felhasználói) definícióján múlik, és futásidőben dől el. Ennek nincs köze ahhoz, hogy fordítási időben ellenőrizzük-e, milyen műveleteket támogat.

Ennél sokkal erősebb típusosságra szavaznék ugyan, de Guido van Rossum ezt kizárta előre, ő nagyon rugalmas Pythont akar továbbra is.


Szerintem sosem fogok választ kapni arra, ez a bizonyos, a dinamikus nyelvek kapcsán sokat hangoztatott rugalmasság hol jelent előnyt :)

a C statikusan típusos, de gyengén. Tehát a statikus ellenőrzések önmagukban nem elégségesek az erős(ebb) típuskezeléshez (de nyilvánvalóan szükségesek).


A Python erősen típusos, de dinamikusan. Tehát az erős típusosság önmagában nem elég a típusbiztossághoz (de nyilvánvalóan szükséges) :)

Egyébként sem a tesztek mellett, netán a statikus ellenőrzések ellen érveltem (ha mégis úgy tűnik, akkor elnézést, fel sem merült bennem ez a szándék). A nagyon erős típusosság híve vagyok, az pedig csak statikus ellenőrzések révén lehetséges. Az elméleti alapokat akartam csak tisztázni, elnézést, ha nehezen érthető volt, amit írtam.


A felütésben még valóban úgy tűnt, mintha a statikus típusosság ellen érvelnél, de szerintem teljes mértékben ugyanazon az állásponton vagyunk, csak más oldalról közelítjük meg a kérdést (lásd az előző bekezdést).
31

Egy statikus típusrendszer

inf3rno · 2015. Jún. 6. (Szo), 20.02
Egy statikus típusrendszer mellett ez a kód nem fordul le, egy dinamikus esetén a példában feltételezett specifikáció mentén írt tesztek sem fogják kimutatni, hacsak nem február 29-én futnak.


Ezt inkább nevezném tervezési hibának, mert ahelyett, hogy injektálnák a dátumot, elkérik egy globális függvénytől. Így nem tesztelhető jól a kód. TDD-vel fejlesztett kódnál nem fordulhatna elő ilyen. Szóval itt nagyjából annyit mondtál, hogy egy teszteletlen dinamikus kódnál nem jelzik a hibát a tesztek...
32

Ezt inkább nevezném tervezési

Joó Ádám · 2015. Jún. 6. (Szo), 20.26
Ezt inkább nevezném tervezési hibának


A példa a lehető legegyszerűbb és leglátványosabb próbál lenni, az éles hibák általában nem ilyenek.

Szóval itt nagyjából annyit mondtál, hogy egy teszteletlen dinamikus kódnál nem jelzik a hibát a tesztek...


Itt annyit mondtam, hogy ha ez a kód statikus, akkor akármilyenek is a tesztek, ha vannak egyáltalán tesztek, a kód nem fordul le.

Ez a kód egyébként lehet egy külső könyvtár része is, amit behúzol, lefuttatod a tesztjeid, és egy év múlva összedől tőle az alkalmazás.
33

Ez a kód ugyanúgy elszáll

inf3rno · 2015. Jún. 6. (Szo), 22.10
Ez a kód ugyanúgy elszáll szökőévente ha a 10-es out of range, ill. lefordul és átmegy a teszteken statikus és dinamikus nyelvnél is.

from random import randint
from datetime import date

def n():
    return randint(1, 9) if date.today().timetuple()[1:3] != (2, 29) else 10

# …

print(result - n())


Nem érzem azt, hogy bármelyik (dinamikus vs statikus) megoldás superior lenne, mindegyiknek megvannak az előnyei és a hátrányai.
36

Ez a kód ugyanúgy elszáll

Joó Ádám · 2015. Jún. 9. (K), 01.08
Ez a kód ugyanúgy elszáll szökőévente ha a 10-es out of range, ill. lefordul és átmegy a teszteken statikus és dinamikus nyelvnél is.


Ez igen, a fenti nem. Én csak ennyit mondtam: bizonyos típusú hibákat egy statikus típusrendszer garantáltan kiszűr.

Nem érzem azt, hogy bármelyik (dinamikus vs statikus) megoldás superior lenne, mindegyiknek megvannak az előnyei és a hátrányai.


Én nem látom hátrányát a statikus ellenőrzésnek, ellenben látom előnyét (lásd az előző bekezdést) – ebből számomra logikusan következik, hogy az egyik hatékonyabb, mint a másik. Továbbra is meggyőzhető vagyok az ellenkezőjéről, de csak hatásos érvekkel.
37

Indexen produkált valaki egy

pythonozok · 2015. Jún. 9. (K), 18.19
Indexen produkált valaki egy jó példát, miért nem jó, hogy a PHP dinamikus, gyengén típusos...
A kérdező megmérte egy PHP szkriptbe ágyazott SQL kódjának a futásidejét valahogy így:
$start=microtime();
# ... SQL végrehajtás ...
$end=microtime();
echo $end-$start;
És igencsak meglepődött, hogy a böngésző hosszú másodpercekig vár, miközben a kiírt futási idő tizedmásodpercekben volt mérhető. :)
Nem tudom, hogy beállítás kérdése-e, de ez azért nálam is kiverte a biztosítékot: hogy a fenébe csinálhat olyat egy akármilyen interpreter, hogy a számok közt is szóközt tartalmazó stringet numerikusként kezel? :(
38

Dokumentáció?

Poetro · 2015. Jún. 9. (K), 18.47
Még jó, hogy a dokumentáció leírja, hogy hogyan kell használni a fenti függvényt, ami egyébként képes float értéket is visszaadni, nem csak stringet. Az, hogy a kivonás implicit tipuskonverziót csinál, nem szerencsés, de láttam már rosszabb dolgokat is PHP-ban.
var_dump('1.22' > '01.23'); // bool(false)
var_dump('1.22.00' > '01.23.00'); // bool(true)
var_dump('1-22-00' > '01-23-00'); // bool(true)
40

O.K., én megnéztem a doksit,

pythonozok · 2015. Jún. 9. (K), 19.03
O.K., én megnéztem a doksit, viszont ilyesmi figyelmetlenségből is belekerülhet. És az, hogy egy '0.12112322 12345678' formátumú stringet numerikus értékként kezel ahelyett, hogy legalább stringként működne... szóval ez kissé báncsa a szépérzékemet. ;)
41

Figyelmetlenségből gyalogost

Hidvégi Gábor · 2015. Jún. 9. (K), 19.20
Figyelmetlenségből gyalogost is el lehet ütni.

Operands of modulus are converted to integers (by stripping the decimal part) before processing
Észak-Koreában hasonló definíció szerint nem lehet kritizálni a legfőbb vezetőt, mert különben kivégeznek. Szerencsére van választási lehetőség.
39

Szerintem ez inkább arra

Hidvégi Gábor · 2015. Jún. 9. (K), 18.50
Szerintem ez inkább arra példa, amikor a dokumentáció elolvasása nélkül okoskodik valaki.
35

Én szomorúan úgy gondolom,

Hidvégi Gábor · 2015. Jún. 7. (V), 14.25
Én szomorúan úgy gondolom, hogy a nyelv a C-hez hasonlóan a Bell csapat személyes preferenciáit tükrözi, nem pedig arra vonatkozó megfontolásokat, hogy mi segítené leginkább helyesen működő szoftverek írását a nagyvilágban.
Lehet, hogy a nagy többségnek ez bőven elég. A helyesen működő szoftvereknek nagy az ára, a "How Is Critical 'Life or Death' Software Tested?" blogmarkban idézett NASA fejlesztés is rengeteg pénzbe és időbe került, de ott nyilvánvalóan nagy a tét.

Ha neked mindenképp helyesen működő szoftverre van szükséged, és ez nem valósítható meg a Go segítségével, akkor ez valóban nem a te nyelved.
23

No de pont ez a lényege a

Joó Ádám · 2015. Jún. 4. (Cs), 01.39
No de pont ez a lényege a TDD-nek. Nem garantál semmit, csak detektál.


Ez az, amit szerintem sokan nem értenek.

Ugye erős típusosságra gondoltál?


Erős statikus típusosságra.
4

Én most BDD-t nézegetem, azt

inf3rno · 2015. Ápr. 22. (Sze), 04.10
Én most BDD-t nézegetem, azt mondják egy prezentációban, hogy azzal nem kell minden egyes felület áttervezésnél refaktorálni a teszteket. Hát nem tudom, régebben is nézegettem a cucumber-t, de valahogy nem fogott meg. Elvileg jasmine is BDD framework, ami megint csak fura, mert sima unit testing framework-nek tűnik összehasonlítva az uborkával.
5

Szerintem a Jasmine nem BDD framework.

T.G · 2015. Ápr. 22. (Sze), 07.32
Nálunk az üzleti logika PHP-ben van, így a Behat lett a választás. Szerintem arra a célra, amire kitalálták tökéletesen megfelel: Emberi nyelven értelmezhető szövegek alapján lekéréseket készíteni. Ha bármely lekérés nem megfelelően válaszol, akkor szól. Nem tudom, hogy a Jasmine-nak van-e ilyen kiterjesztése, de az én értelmezésem szerint a Jasmine nem BDD framework. Igaz, nem lenne nehéz köré építeni egy wrappert, és biztos már többen megcsinálták, de a honlapjukon lévő példák azért messze vannak attól, hogy azt mondjuk rá, hogy emberi nyelven értelmezhető szövegek.

Nálunk sincs komoly lefedettség, de már számtalan alkalommal fogott meg olyan hibákat egy-egy teszt, ami mellett máskülönben simán elmentünk volna, az meg szerintem természetes, hogy annál ártalmasabb egy hiba, minél később fedezik fel.
6

Nekem is egy sima unit test

inf3rno · 2015. Ápr. 22. (Sze), 18.17
Nekem is egy sima unit test framework-nek tűnik, és nem BDD-nek. Amit néztem egy BDD fw úgy épül fel, hogy egy unit test fw köré építenek plusz egy értelmező réteget, ami lefordítja unit test-ek nyelvére a szöveget. Van pl cucumber - jasmine adapter is, szóval elméletileg a cucumber-ben írt dolgok lefordulnak jasmine tesztekre. Nézegetem tovább a témát.
9

Cucumber.js

T.G · 2015. Ápr. 26. (V), 15.53
https://github.com/cucumber/cucumber-js Első ránézésre jónak tűnik, bár nem telepítettem fel, így csak a leírás alapján tudom megítélni.
10

Én ezt néztem:

inf3rno · 2015. Ápr. 26. (V), 20.42
Én ezt néztem: https://github.com/DealerDotCom/jasmine-cucumber ez is jónak tűnt. Amíg nem értem a BDD lényegét, addig szerintem nincs értelme konkrét megvalósítást nézegetni. Még olvasgatok a témában. Kösz a linket.
11

Néhány magyar nyelvű BDD videó

T.G · 2015. Ápr. 26. (V), 22.01
Anno összeszedtem azokat a magyar nyelvű videókat, amelyek a témában megtalálhatóak: https://www.youtube.com/playlist?list=PL4gueC1a4rbQ9F-r91mIGs597E7NGVtD2
(ezek nekem segítettek helyretenni a dolgokat)
12

Köszi!

inf3rno · 2015. Ápr. 27. (H), 18.14
Köszi!
16

Szvsz, a 4 közül egyedül

inf3rno · 2015. Május. 27. (Sze), 07.24
Szvsz, a 4 közül egyedül Mészáros Mártonnak ment át, hogy mi az a BDD. Előadásban is a Mészáros féle volt a legjobb, lehetett volna hosszabb is, rengeteg fontos miért és fogalom nem hangzott el, de legalább a lényeg igen. Majd összeszórok én is egy blog bejegyzést BDD-vel kapcsolatban, ha lesznek gyakorlati példáim. Mindenképp érdemes használni, sokkal gördülékenyebb vele az outside-in fejlesztés és jobban karbantartható a (teszt) kód is.
14

CodeCoverage

Gixx · 2015. Ápr. 30. (Cs), 11.18
Ha minden ellenérvet elfogadunk és hagyjuk a fenébe a teszteléseket, azért azzal nehéz vitába szállni, hogy amikor végignézed a CodeCoverage HTML reportot és azt látod mindenhol, hogy zöld, akkor azért egy rövidke pillanatig a Világ Királyának érzed magad, ami valljuk be, hogy egy meglehetősen nagy pozitív löketet ad a folytatáshoz...
15

+1, én eleve úgy szeretek

inf3rno · 2015. Ápr. 30. (Cs), 17.30
+1, én eleve úgy szeretek fejleszteni, hogy amikor abbahagyom aznapra, akkor minden zöld legyen. ha nincs így, az valami zsigeri kellemetlen érzést okoz nálam. csapatban ez még rosszabb lehet, mivan, ha lebetegszel, és más veszi át a munkádat, ott hagynád neki pirosan, hogy debuggoljon?
34

(Ez válasz a 30. hozzászólásra, nem tudom, miért ide csúszott)

ydsMo9gx · 2015. Jún. 7. (V), 00.39
Ha nincs jó megoldás egy megoldandó problémára, akkor választani kell egyet a rosszak közül.
Választani akarnak, csak későbbre tolták.

Ha elegáns megoldás a problémára, akkor miért nem támogatja a Go nyelvi szinten? ;)
Kódgenerálásra szerintem nyelvfüggetlen módszert érdemes használni. A Cog jó példa erre, bevált, miért lenne érdemes újraírni minden egyes új nyelvnél? (A makrózás más téma, DSL-ek szintén.)

Egyébként már lehet nyelvi szinten Go kódot generálni :).

A kódgenerálás mindig a generált nyelv hiányosságára mutat rá.
Sok esetben igen. De van, amit így lehet legjobban és ezért így érdemes megvalósítani. És biztos vagyok benne, hogy a tárgykódok bináris előállítása idővel kimegy a divatból, az új nyelveknél mindig valamilyen forráskódot állítanak majd elő a compilerek. Az pedig nagyipari kódgenerálás. Vagyis a compilerek többsége transpilerré válik, és csak néhány agyonoptimalizált compiler marad talpon.

megfelelő típusdeklarációval védekezhetsz az ilyen hibák ellen. Itt mire gondolsz?
Arra gondoltam, hogy a védeni kívánt típusoknak külön package-et készíthetsz. De itt egy igazán szép kivesézés.

hasonlóak az elvárásaink, csak árnyalatokban térnek el :)
Igen. Te szigorúbb vagy, én engedékenyebb. A tapasztalatok erősen hatnak az ízlésre.

A példában szereplő függvény szökőnapokon egész helyett sztringet ad vissza, ilyenkor a függvényt használó, egészet feltételező műveletek elszállnak.
Ha ilyen függvényt ír valaki, akkor tesztelje le az if mindkét ágát. Ha tesztelte, írjon hozzá legalább minimális dokumentációt (egy doctesttel mindkét kötelességét letudhatja). Az n() meghívásakor így ellenőrizhető a visszaadott érték típusa:
type(n())
Ahogy mondjuk az Ada is nyelvi szinten támogatja ezeket.
Igen, de ezt állítottam: "a dinamikus erősebb lehet, mint a statikus". Az Ada a "statikus is lehet olyan erős, mint a dinamikus" esetre példa, ami "a dinamikus erősebb, mint a statikus" cáfolata, de nem cáfolja a példával alátámasztott állításomat.

Szerintem sosem fogok választ kapni arra, ez a bizonyos, a dinamikus nyelvek kapcsán sokat hangoztatott rugalmasság hol jelent előnyt :)
Ha keresgélsz, találhatsz rá példákat. Meggyőzni aligha tudnak majd (engem sem győztek meg, engedékenyebb létemre). Ez már ízlés kérdése.

Egyértelműen a dinamikus típuskezelésre törekvők történelmi érdeme a type hinting (típusjavaslat?), az opcionális típusmegadás, a típuskikövetkeztetés (type inference, type deduction) és hasonlók terjedése. Szigorú szemmel nézve ezek az ördög patái az ajtóban, engedékeny szemmel angyalszárnyak is lehetnek. Szerintem nyelvi megvalósítástól függően jó vagy rossz a lazább típusmegadás, mindkettőre vannak példák (jóra csak mostanában). Ha az olvashatóság rovására megy, akkor ellenzem.

Mégis kerestem erős példákat a dinamikus pártiak támogatására: Benefits Of Dynamic Typing,
Why dynamic typing?, Strongtalk.

Engem azért nem győztek meg, mert szerintem tervezési időben nyújtanak segítséget a típusok, a későbbi hasznuk jóval kisebb, és hátrányuk is van. Valamikor gondolkodni kell róluk, és ha már gondolkodtunk, akkor érdemes leírni a gondolataink eredményeit, lehetőleg a forráskódba, lehetőleg programmal feldolgozható és ellenőrizhető formában.