[HK] Operator overloading

Ez a blogbejegyzés bár természetesen azért „ihletődött” mert bizonyos értelemben kapcsolatban áll a fejlesztés alatt álló nyelvemmel, de általánosabban szeretném megközelíteni a kérdést.

Arról van ugyanis szó, hogy a programnyelvem ESZMÉLETLENÜL HATALMAS mértékben támogatja azt az izémizét amit (különösen OOP nyelvekben) általában operator overloadingnak neveznek.

Igenám, de a kérdés az, attól hogy ez a lehetőség támogatva van, mennyire érdemes élni vele... Mikortól számít hasznosnak ez a „vele élés” és mikor számít már „visszaélésnek”, amikoris már inkább megnehezíti a munkát... És így tovább.

Mielőtt valaki azzal jönne hogy mit akarok én ilyesmivel a magam primitív kis nyelvében amikor az minden csak nem OOP jellegű hanem procedurális, hát elárulom hogy bár most ez még igaz, de cseppet se kizárt hogy ki lesz bővítve OOP jellegű ficsőrökkel is majd a jövőben... De NEM EZ A LÉNYEG. Ugyanis senki ne higgye hogy az operator overloading valami hű de új találmány ami csak a magas szintű nyelvekben létezik! Már az ősi Basic is ismerte... nyomokban legalábbis. Minden olyan nyelvben ugyanis ahol a + karakter nem csak számokat képes összeadni hanem stringeket is (azaz konkatenálást végez) ott tulajdonképpen operator overloadingról van szó, még ha ezt nem is kötik a Nagyérdemű orrára... Elég nyilvánvaló ugyanis hogy stringek konkatenálásának marhára semmi köze a számok körében értelmezett összeadás-fogalomhoz, itt egy teljesen más akármiről van szó, még akkor is ha a szimbólum ugyanúgy néz ki...

Tehát kinek mi a véleménye az operator overloadingról? Ki az aki szereti, ki az aki nem, és milyen mértékig tartjátok hasznosnak?

Szeretném tényleg ha ez a kérdés általános értelemben lenne megvitatva és trollkodásmentesen, szóval szakadjunk el a nyelvemtől most akkor is ha én nyitottam e blogot, jó? Igen, azért kérdem hogy segítsen nekem megtervezni a nyelvem szintaxisát, ami mindenképp úgyis olyan marad hogy NagyZ majd hányadéknak nevezi, de ettől még azért nem mindegy mennyire lesz az, és ez nagyban függ attól, mennyire használom majd ki az operator overloading lehetőségeit. Ennek ELLENÉRE, e topikban nem azt akarom megvitatni az ÉN nyelvemben mi meg hogy lesz, azt majd eldöntöm magam. Csak általánosságban szeretném e kérdést kitárgyalni.

Köszönöm előre is a résztvevőknek (már azoknak akik nem fognak trollkodni).

Hozzászólások

Amíg az operátor azt csinálja, amit ránézésre várnánk tőle (pl. object1 > object2 összehasonlítás mondjuk egy adott property alapján, vagy az általad említett string concat), addig oké. Amikor valami mélyebb logika van mögötte, akkor szerintem kerülendő, nagyon nehéz lesz utána harmadik félnek értelmezni a kódot.

Szeretném tényleg ha ez a kérdés általános értelemben lenne megvitatva és trollkodásmentesen, szóval szakadjunk el a nyelvemtől most akkor is ha én nyitottam e blogot, jó?

off: Mondjuk ezen lehet, hogy segítene, ha a 350 szavas posztból 281 szó nem a programnyelvedről és NagyZ-ről szólna. :)

Szerkesztve: 2020. 11. 10., k – 10:34

Szerintem az operator overloading valamilyen szinten elkerülhetetlen, ha kicsit is használható nyelvet akarsz. A számítógépnek az integer, a real és a double precision is teljesen különböző dolgok, elég baj lenne, ha az alábbi kódban három különböző jelet kellene használnom (Fortran-77, mert az kb. a legkisebb olyan nyelv, aminek a megértéséhez elég angolul tudni):

c  fortran szintaxis
      double precision r,s,t
      data y,z/1.0, 2.0/
      data s,t/1.0d, 2.0d/
      data  j,k/1,2/
      x = y + z
      i = j + k
      w = x - i
      r = s + t
c akkor már írjuk is ki
      write (*,10) x,w
      write (*,20) i
      write (*,30) r
 10   format (2f10.4)
 20   format (i4)
 30   format (d14.6)
 

Azt is láthatod, hogy a különböző típusok kiíratására is ugyanazt a write utasítást használtam, csak más format descriptorral, tehát statementek is vannak overloadingolva (ebben az ősi nyelvben a saját függvényeket és szubrutinokat nem lehet overloadingolni, az újabb nyelvekben lehet, C++-ban kifejezetten könnyedén, újabb Fortranokban kicsit macerásan), és az is elég hasznos. Én pl. a C++-ból hiányolom, hogy nem lehet saját operátorokat létrehozni (nem lenne rossz egy hatványozás, elemenkénti vagy sor-oszlop mátrixműveletek, etc.)

Az APL familiában jellemző, hogy ugyanaz a "kulcsszó" két jelentéssel is bír, ha csak a jobb oldalán van argumentum (monadic), vagy mindkettőn (dyadic) -- ami tekinthető egyfajta túlterhelésnek --, ám még ezen felül is előfordul, hogy típustól függően más a jelentés, lásd https://github.com/JohnEarnest/ok/blob/gh-pages/docs/Manual.md

Van aki ettől óckodik: t3x.org/klong/index.html

Mind a két nyelv ugyanabból az alomból származik, mindkettőt meg tudom érteni és el tudom fogadni.  Szerintem személyes preferencia dönt, elvi okok nem igazán léteznek. A fordítóprogram/értelmező írójának valószínűleg könnyebb dolga van, ha nem kell minden esetben az argumentumok típusával törődnie. Azt nem tudom, hogy az adott nyelv használójának mi a jobb. Az biztos, hogy kényelmesebb mátrixalgebra esetén egy csillag használata kényelmesebb a np.matmul(,) helyett.

AL

Én szeretem, de a használatára nagyon oda kell figyelni, nem szabad mindig engedni a csábításnak. 

Egyik véglet: Java. Itt nincs operator overloading... aha persze, de a string-eket mégis lehet +-al összefűzni, na mindegy. Persze felülbírálni nem lehet. Rohadtul utálom, mikor Java-ban pl. BigDecimal-okkal, mátrixokkal, ilyesmikkel kell aritmetikát végezni.

Másik véglet: Scala. Itt sincs operator overload, mivel nincsenek operátorok :) Na jó, Scala-ban bármilyen neve lehet a függvénynek, és infix notation-el is lehet hívni, így a műveleti jeleket is így lehet definiálni. Cserébe viszont egészen egzotikus szintaxist is össze lehet hozni, ami nem biztos, hogy javít a használhatóságon... Perl rulez!

Véleményem szerint ez is olyan, mint sok minden az életben: mértékkel fogyasztva jó. A Kotlin és a C# féle módszerekkel ki vagyok békülve.

Egyebkent van olyan, aki szerint jo, hogy a C++-ban a `()` operatort is felul lehet definialni?

Naná. Funktorokat lehet vele csinálni. Pl. a funktor előnye, hogy ha egy szubrutinnak egy függvényt kell átadni, akkor nem kell küzdeni, hogy ha a "változóján" kívül vannak még "paraméterei" akkor azt hogyan ad át (hanem berakod egy classba a paramétereket, és csinálsz neki egy () operátort), és azt adod át. Ezt a () overloadingolása nélkül C-en általában globális változóval, vagy Fortran-ban COMMON blokkal oldották meg, és az pl. nem thread-safe.

A másik, a Fortran-90-hez hasonló vektor-mátrix-kezelés: azért az elég jó, ha tudsz olyat, hogy

vec_a(":") = mat_B(":",7)

és ezzel bemásoltad a B mátrix 7-edik oszlopát az a vektorba. (Ez utóbbi Fortran-ban, ahol a nyelv része, vec_a(:) = mat_B(:,7) lenne.)

Szerintem nagyon hasznos. Egy aktuális kódnál kvaterniókkal kell dolgoznom. Az op. overloading-gal definiálni tudtam az alapvető műveleteket kvaterniók között (pl. összeadás, kivonás, szorzás) így ugyanúgy kezelhetem őket, mint bármelyik skalárt.