A megszokás nagy úr!

Eric Elliott [“Programming JavaScript Applications” (O’Reilly) írója] megdöbbenve tapasztalta, hogy egyeseknek egy egyszerű példa mennyire bonyolultnak, zavarosnak tűnik csak azért, mert az adott szintaxis nem megszokott a számukra.

Erről az ES6-os javascript kódról volt szó:


const secret = msg => () => msg;

Ez volt számukra bonyolult, zavaros. A vele ekvivalens ES5-ös kód viszont könnyen érthető és egyszerű számukra:


const secret = function (msg) {
  return function () {
    return msg;
  };
};

Ha valaki szeretne bővebbet olvasni arról, hogy a megszokás eltorzítja a gondolkodásunkat és ez milyen hátrányokkal jár, annak javaslom elolvasásra Eric Elliott ezen cikkét: Familiarity Bias is Holding You Back: It’s Time to Embrace Arrow Functions.

Hozzászólások

Ez nem a megszokásról szól.
Nem tudok JavaScriptül, a másodikat értem, az első érthetetlen.

Ha Javascriptül nem értesz, akkor a másodikat sem értheted :-)

Egyébként itt azért nem érted az elsőt, mert még soha nem találkoztál arrow (nyíl) függvénnyel (bármilyen nyelven), de hagyományossal meg igen (bármilyen nyelven).
Számodra ismerős, megszokott a hagyományos forma, még ha kicsit el is tér az általad használttól, mégis könnyen felismered.
Pont erről szól a cikk!
Az elsőre rámondod, hogy érthetetlen, ahelyett, hogy rászánnál max. egy órát, hogy megértsd, majd utána könnyen érthető, egyszerű, hibamentes, ... kódot tudjál (tudjatok a cégnél) írni.
Ha az első forma is ismerős, megszokott lenne számodra, akkor az első is érthető lenne, sőt, könnyebbenn érthető, mint a második.

Ráadásul, ha ezt megérted (Javascript-es arrow function), akkor ez után meg fogod érteni a Scala-sat, C#-osat, Java-sat, ... is.

"megszokás eltorzítja a gondolkodásunkat"

Ja, ezert ugy kell programoznod, hogy a "torzult gondolkodasu" tobbi programozo is ertse. Akkor is megmarad az _allasod_, csak kevesebb _munkad_ (ertsd: munkaorad) lesz vele, mert lesz, aki tudja folytatni, amig te egy masik hasznos funkcion dolgozol. :P Es ez nem csak alkalmazottkent kifizetodo. Sajat projekteknel meg halasabb folytathato kodot irni. Amihez nincs mar kedved, arra felveszel mast, es orulsz, hogy ritkan szakit meg, mert karbantarthatot irtal. Koncentralsz az uj projektedre.

Felejtsuk mar el az "egesz fejleszto csapat rosszul gondolkodik, mindnek el kene olvasnia X 800 oldalas konyvet" hozzaallast!

Nyilván nem kell túlzásba esni, de nehogy már azért ne használjuk egy language vagy library feature-t ami pont megoldja a feladatot, mert a kollégák nem értik. Tudok adni erre egy nagyon banális példát: kollégám meséli, hogy egyik telekommunikációs cégnél a házon belül fejlesztett programozási nyelvbe bekerült a for ciklus és a projektjén ő volt az első, aki használta. Ezért el kellett magyaráznia a kollégáinak, hogy ez pontosan ugyanaz a for ciklus, amit más nyelvekből már ismernek, és igen, ezt tényleg támogatja ez a programozási nyelv, benne van a dokumentációjában is. Nyilván használhatott volna while ciklust is mint korábban, de miért tette volna, ha egyszer a for ciklus alkalmasabb volt a feladat megoldására?

Oke, de a for ciklust maximum 2 perc elmagyarazni.

Itt meg tobben idejuk minimalis reszeben dolgoznak JS-sel. Mar a masodikat se ertik, miert kell (Ha jol vettem ki, erteni kell hozza par dolgot a funkcionalis paradigmabol + erteni kell, hogy miert mas a JS mint minden mas).

A piacon konkretan olyan JS-t is fejleszto emberek vannak, akik setTimeouttal valasztjak el egymastol a document readyket, es azt is nehez nekik elmagyarazni, hogy ugyan hasznaljanak mar helyette trigger eventet meg oneventet, vagy csak szimplan hivjanak meg egy fuggvenyt a korabban futni akaro document ready vegerol a kesobb futni tervezovel. Mert annyira idegen nekik mar ez is a tobbi (algoritmikus, OO) nyelv utan.

Azalapjan amit latok a felhozatalbol, a masodikat is kerulnem csapatban, nemhogy az elsot meg annak a kiguglizhatatlan operatorait.

"Itt meg tobben idejuk minimalis reszeben dolgoznak JS-sel."
"A piacon konkretan olyan JS-t is fejleszto emberek vannak, akik setTimeouttal valasztjak el egymastol a document readyket"

Egyre magabiztosabb vagyok az egyébként önértékelési gondjaim miatt alábecsült tudásomban. Kérdem én amúgy, hogy miért nem megfelelőbb személy dolgozik a JS kódokon ezekben az esetekben?

Egyébként ha valaki akarja, akkor megismeri, és megérti az arrow funkciókat. Vagy akár az ES6 összes szintaktikai újítását. Nem sok van, és nem nehéz megérteni őket legalább olyan szinten, hogy ránézésből felismerd. Még annak sem, akik nem foglalkoznak sokat a nyelvvel.

A legtobben azt se ertik, amire az arrow function operator syntax sugar, ezt fogjatok mar fel. A closure lehet hogy jo, de a programozok 90%-at ugy megzavarja ahogy van.

Arrow mikor is hasznalhato: https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20&%20beyond…

Vicces ez a diagram, de ebben a formában egy erős túlzás. Aki azt se érti, hogy a closure mire jó, annak amúgy sem mondanak ezek semmit, annak le lehet butítani annyira, hogy ha nyilat lát, akkor az ugyanaz mint ha function-t látna.

De értem mit akarsz mondani. Csak az ilyen meg maradjon az ő szakterületén.

Ha heti 40 órából 2-3-at kell JS-sel foglalkozni, akkor feltételezem a teendő mértéke is olyan elhanyagolhatóan kicsi, hogy nem számít, ha nem naprakész a tudása, és nem ismeri ezeket a dolgokat (de mint ha ilyet írtam is volna).

Szerk:
Egyébként én is full stack dev vagyok, és mind a szerveroldali, mind a kliensoldali fejlesztésben igyekszem naprakészen tartani magam, és a munkám során is projekt jellegétől függően dolgozom mindkét oldalon jócskán. Az, aki szerver oldalon fejleszt, és heti 2-3 órát foglalkozik JS-sel miért full stack? Én se tartom magam sysadminnak, mert néha a munkám részeként tologatok webszerver konfigot.

Tobbek altal approved modon (lasd: OP linkjeben twitteren kiakadtak hogy "olvashatatlan a kod") olvashatatlan syntax sugar = szakmai onkielegites

Ehhez jon hozza, hogy eleve egy ritkan/sosem kotelezo es sokak szamara nem logikus, sokak szamara nehezen ertheto es sokak altal kerult nyelvi elemrol van szo (closure). A closure megerteset elvarni meg ennek ellenere teljesen elvarhato, keves JS eseten is. De ez a syntax sugar hozza mar nagyon szakmai onkielegites, egyszeruen tul nagy az eselye, hogy aki ranez, nem fogja felfogni. Akinek meg ez nem szempont az jobb vilagot teremtene nekunk, ha nem programozna, hanem krumplit termesztene. Paraszt az OP linkjeben levo blogger is, meg o van felhaborodva, hogy nem ertik a kodjat. Es 100 fot tanitva (plusz 300-at aki raolvasott a blogjara) azt hiszi majd statisztikailag szignifikans valtozast hoz a programozok millioinak a fejeben (nem fog)

Tehát akkor mi a megoldás? Ragadjak le az elavult és kényelmetlenebb szintaxisnál hátha egyszer valaki olyan ránéz a kódomra, aki nem ért hozzá?

Nem tudom te hogy vagytok vele, én nem azért használok arrow függvényeket (vagy akármilyen más syntax sugart), mert attól dagad a gatya, hanem azért, mert kényelmesebb használni őket, és azok számára, akik értenek hozzá ténylegesen olvashatóbb.

Megint ferditesz: a fuggveny miota syntax sugar (kivetel a C++-os inline fuggveny)? Es miota tudsz aranylag hozzaertot mutatni, aki szerint "nehezebben olvashatova teszi a kodot"? Mert itt akik twitteren visszairogattak az onjelolt tanarnak, azok kozul ketlem, hogy senki nem ertett volna hozza.

"Megint ferditesz: a fuggveny miota syntax sugar"

Ki is ferdít? Konkrétan arrow függvényekről beszéltem, nem általánosságban a függvényekről. És azt sem jelentettem ki, hogy syntax sugar volna (legalábbis abban a hozzászólásban nem, amire válaszoltál). Egyébként miért is nem az?

"Es miota tudsz aranylag hozzaertot mutatni, aki szerint "nehezebben olvashatova teszi a kodot"?"

Már ne haragudj, én kinek is programozok? Egy laikusnak, vagy egy másik, a nyelvet ismerő fejlesztőnek? Nem lehet úgy dolgozni értelmesen és hatékonyan ha a nyelv nagy részét ignorálom, mert hátha egy hozzá nem értő ránéz.

"A piacon konkretan olyan JS-t is fejleszto emberek vannak, akik setTimeouttal valasztjak el egymastol a document readyket, es azt is nehez nekik elmagyarazni, hogy ugyan hasznaljanak mar helyette trigger eventet meg oneventet, vagy csak szimplan hivjanak meg egy fuggvenyt a korabban futni akaro document ready vegerol a kesobb futni tervezovel. Mert annyira idegen nekik mar ez is a tobbi (algoritmikus, OO) nyelv utan."

Ez ennek az iparágnak az egyik legnagyobb rákfenéje. Mutass még egy szakmát, ahol a hozzá nem értőket nem zavarják el a fenébe vagy nem mennek tönkre a kevés megrendelés miatt. Pl. én addig nem engednék egy fejlesztőt javascript kód közelébe, amíg az itt leírtakkal nincs tisztában.

ahol a hozzá nem értőket nem zavarják el a fenébe

Számomra ami megdöbbentő, hogy nem, hogy nem zavarják el a hozzá nem értőket, hanem azt a szintet várják el mindenkitől. Sőt, aki megmutatja, hogy ezt lehet egyszerűbben is, jobban, hibamentesebben, ..., az egy paraszt!

Szóval ilyen mélységeit a szakmánknak azért én nem gondoltam. :-(

Azok baromira nem tunnek "fact"-nek.

Az ilyenekbe, mint 4 soros vs 21 soros, nem nagyon lehet belekötni.

Amiről azt állíthatod, hogy nem tény, hanem hazudik, azok csak ezek lehetnek:
1. van több évnyi ES5 és ES6 tapasztalata,
2. pár másodperc alatt megírta hiba nélkül a 4 soros ES6 kódot,
3. több percig tartott megírni a 21 soros ES5 kódot, ráadásul három hibát is vétett, amit ki kellett debugolnia és javítania.

"3. több percig tartott megírni a 21 soros ES5 kódot, ráadásul három hibát is vétett, amit ki kellett debugolnia és javítania."

Ez tunik ferditesnek ugy visszakezbol. Nekem ugy tunik, de lusta vagyok utanamenni, hogy azt a feladatot meg lehetne kevesebb sorbol oldani ES5-ben is.

"2. pár másodperc alatt megírta hiba nélkül a 4 soros ES6 kódot,"

Es ha megis elgepelne vagy valaki mas elgepelte az nem "nehany perc" lett volna a console logban. Meg mennyit gondolkodott elotte? Mas mennyit gondolkodik majd mikor olvassa?

"Az ilyenekbe, mint 4 soros vs 21 soros, nem nagyon lehet belekötni."

De, lasd fentebb.

Ja, ezert ugy kell programoznod, hogy a "torzult gondolkodasu" tobbi programozo is ertse.

Sajnos ebben van sok igazság.

csak kevesebb _munkad_ (ertsd: munkaorad) lesz vele

A cikk is azt írja, hogy pont fordítva, a megszokottat több idő megírni, nehezebb megérteni, több a hibalehetőség, így természetesen nehezebb folytatni, karbantartani is.

Ha rövidebb idő alatt, kevesebb hibával készítesz kódot, míg mások nem, ráadásul bárki kódját könnyen folytatod, karbantartod, akkor nem hiszem, hogy neked kellene aggódnod a munkahelyed miatt.

Felejtsuk mar el az "egesz fejleszto csapat rosszul gondolkodik, mindnek el kene olvasnia X 800 oldalas konyvet" hozzaallast!

Itt egy óra alatt megérthető, begyakorolható dologról van szó, nem hónapokig tartó tanulásról.

Neked egy ora, meg annak aki full time js-ezik. Csak mert sok fejlesztonek olyan peldat mutatni ahol a masodikra van szuksege is nagyon nehez.

A linkbol en is felfogtam 5 perc alatt, de a blogbejegyzest iro nagyarcu twitteren meg nem ertett tanart alkalmatlannak tartom emberekkel valo dolgozashoz ezzel a hozzaallassal.

Nagyon szeretem Eric Elliott munkásságát. Kicsit radikális arc, de nagyon sokat tanultam tőle.

egy JS mágus elmagyarázhatná plz, hogy mire jók az efféle (értsd: második kódrészlet) nyelvi szerkezetek, nekem eddig csak jóval strukturáltabb nyelvekhez volt szerencsém (hála Istennek)

ha jól értem, egy konstanshoz rendelünk egy inline definiált függvényt, ami egy, a függvénytörzsön belül szintén inline definiált függvényt hív meg?

1. addig rendben van, hogy ez egy 5 soros példakód, de IRL használva mire jó egy ilyen?
2. mi történik, ha van egy msg2, amiből egy secret2 konstanst kéne csinálni?

Mind a két kódrészlet ugyanazt csinálja (példa a closure használatára):
definiál egy függvényt, amit meghívva egy paraméterrel, visszaad egy függvényt, amit paraméter nélkül hívva visszaadja az külső függvény paraméterét.

Itt a példa a használatára, ebből talán érthetőbb:


const mySecret = secret('hi');
mySecret(); // 'hi'

nekem eddig csak jóval strukturáltabb nyelvekhez volt szerencsém (hála Istennek)

Egy újabb jó példa arra, amiről a cikk szól! :-)

Azt hiszem, egy nagysagrenddel javitana a fat arrow olvashatosagat a zarojelezes. De igaza van a cikk irojanak, megszokas kerdese (mint ahogy senki nem akad fenn azon, hogy 2+3*4 az 2+(3*4), nem pedig (2+3)*4 - ezt eleg jol belenk verik az iskolaban).

(Konkretan ebben az esetben:

const secret = msg => ( () => msg );

szerintem egy fokkal konnyebben olvashato. YMMV.)

Tovabbgondolva, megsem ilyen egyszeru. Peldaul Haskellben:

a -> b -> c

egyszeruen az jelenti, hogy van egy fuggvenyed a es b parameterrel, ami visszaad c-t (es itt raadasul a betuk tipust jelolnek, nem valtozonevet). Itt a helyes zarojelezes inkabb:

(a, b) -> c

merthogy ezt akarjuk kifejezni, ugyanakkor technikailag a currying ezt jelenti:

a -> (b -> c)

es maris kevesbe furcsa, hogy elobb-utobb belezavarodik az ember ezekbe a dolgokba :)

Ez a mondat könnyen megérthető.
Dieser Satz ist leicht zu verstehen.

megszokás LOL

Látod ezt nem értik meg sokan (a LOL-ból gondolom, hogy Te sem), hogy amit ismer, amit megszokott, arról azt hiszi, hogy könnyebben érthető, mint amit nem.
Egyik mondat sem könnyebben érthető, mint a másik, az első azoknak könnyen érthető, akik ismerik (megszokták) a magyar nyelvet, a másik azoknak, akik a németet.

A cikk alapján ilyesmi lenne az analógia:
Ez a szavakból -, amelyeket egymás után álló betűkből képeztünk, - összeállított szerkezet, nem igényel mélyreható tanulmányozást, ahhoz, hogy az értelme mindenki számára világos legyen.
Dieser Satz ist leicht zu verstehen.

Ha ismered a német nyelvet (és a magyart is), akkor a második mondat könnyebben érthető, mint az első. Az elsőt nehezebb volt megírni is, egy csomó hibát vétettem közben, könnyen lehet, hogy még mindig hibás, ... Lényegében erről szól a cikk.

A baj azokkal van akik képtelenek megérteni, hogy nincs olyan, amit mindenki ismer, azt gondolják, hogy ami nekik ismerős, megszokott, az másoknak is az, illetve ami nekik nem az, az másoknak sem az.

A csapatjátékossághoz ennek kevés köze van. Egy csapat (vagy a vezetője) eldönti, hogy miket használnak, és a csapat tagjai, ha valamit nem ismernek, akkor megtanulják. Egy jó csapat folyamatosan fejlődik is, újabb és újabb eszközöket ismernek meg és használnak.

A probléma nem azzal van, hogy a megszokás nagy úr-e. Hanem azzal, hogy van egy kifejezendő koncepció, amire a nyelv (nem, nem az API, hanem maga a nyelv) kétféle megoldást is ad. Ez rossz dolog. Miért kéne egyféle dologra két lehetséges nyelvi elemet is használni? A syntax sugar egy rossz dolog.

Javaban sem lehet kétféleképpen kifejezni azt, hogy A osztály gyerekosztálya B osztálynak. Van az extends kulcsszó és kész. Nincs rá más szintakszis. Egy koncepció - egy szintakszis.
Ilyen egyszerű ez.

Amint egy koncepcióra van több szintakszis is, egyből előjön a hitvita: éppen itt melyik szintakszissal írjuk le ugyanazt az egy koncepciót.
Ez a baj, nem a megszokás és nem megtanulás dolga.

Azert onmagaban nem irtanek ki tuzzel vassal minden syntax sugart. De itt egy eleve ritkan ertett es megritkabban hasznalhato nyelvi elemre kaptunk syntax sugart, ami pont az automatizalas legnagyobb ellensege: hozzaerto ember kell, hogy elmagyarazza neked, hogy mi ez es miert. Megtalalni nem fogod, max veletlenul, vagy hosszu szakirodalom kozepen.

A blogger egy luddista fasz, tovabb akar elni JavaScript tanarkodasbol, de ettol meg nem lesz minden syntax sugar luddista.

Pl C++-ban azert az std::string >> es << operatorait eleg kellemes hasznalni, meg az unordered list (hashmap) is kellemesen hozzaferheto a []-vel. Ezeket is rossznak tartod?

Masik pelda ami miatt viszont tok megertelek:

Swift

Van aminek 1-2-3-ban mas-mas szintaxisa van. Ez munkaorakat pazarol mindenkinek, mert nem tudjak stack overflowrol kimasolni a megoldast, ra kell jonniuk, vagy jobb esetben kerdezniuk, hogy "ez miert nem mukodik?" (Mert swift 2.2 ota deprecated es mas syntax-szal mukodik, talald meg, good luck)

> Javaban sem lehet kétféleképpen kifejezni azt, hogy A osztály gyerekosztálya B osztálynak.

Nem, de a fenti példá(hoz hasonlót) le tudom írni többféleképpen. Még ha itt segít a típusosság is. (Amíg nem lesz JEP-286).


import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class Main {
    public static void main(String[] args) {
        Function<String, Supplier<String>> foo = msg -> () -> msg;
        System.out.println(foo.apply("Hello, world").get());
    }
}

és


import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

class Main {
    public static void main(String[] args) {
        Function<String, Supplier<String>> foo = new Function<String, Supplier<string>>() {
            @Override
            public Supplier<String> apply(String s) {
                return new Supplier<String>() {
                    @Override
                    public String get() {
                        return s;
                    }
                };
            }
        };
        System.out.println(foo.apply("Hello, world").get());
    }
}

szerk.: ejj, drupal, elrontotta a kacsacsőreimet
--
blogom

"Miért kéne egyféle dologra két lehetséges nyelvi elemet is használni?"

Azért, mert ez a három dolog nem ugyanaz:

function a() {}
const a = function() {}
const a = () => {}

1) Deklarálsz egy a nevű függvényt.
2) Deklarálsz egy a nevű változót amihez hozzárendelsz egy névtelen függvényt

(a kettő közt egyébként még az a különbség, hogy az a() hívás az első esetben bárhonnan hívható, a másodikban viszont csak a deklaráció után)

3) Mint a 2-es, csak arrow függvényt deklarálsz, ami másképp viselkedik, például a this értéke a függvényen belül más (sok esetben hasznosabb, ésszerűbb, jobb).

"Miért kéne egyféle dologra két lehetséges nyelvi elemet is használni?"

Tudom, ezt már idéztem, de megközelítem másik oldalról: A JS olyan nyelv, aminek nem igazán lehet módosítani a működését. Hiába volna jobb, nem módosíthatod azt, hogy miként működik a function kulcsszóval deklarált függvény, ezért kénytelen vagy új szintaxist hozzáadni. Hasonlóan ezért jött a var mellé a let, és nem a var működését módosították. Stb, stb.

Abban egyetértünk, hogy ez nagyon nem optimális, de legalább van érthető oka.

Gondolom az is nagy hülyeség, hogy van mindenféle ciklus: elöl tesztelős, hátul tesztelős, for, foreach, ...

A syntax sugar egy rossz dolog.

Nem, az egy jó dolog!
In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express.

Mi rossz van abban, ha valami könnyebben érthető vagy kifejezhető?

Amint egy koncepcióra van több szintakszis is, egyből előjön a hitvita: éppen itt melyik szintakszissal írjuk le ugyanazt az egy koncepciót.

Ez egyrészt igaz, másrészt a régebbi, rosszabb konstrukciót kellene elhagyni, de azt pedig kompatibilitási és egyéb okok miatt nem jó elhagyni.