Trait a konstruktor

Re:Trait a konstruktor
« Odpověď #30 kdy: 21. 12. 2020, 16:56:19 »
im, ze je tam rozdil, ale nevidim ze by u toho traitu ta zavislost byla mene priznana.

Podle mě ses zaměřil na obecný význam slova "závislost", ale ne na skutečnou funkci DI třeba v tom konstruktoru. Trait řeší chování celé třídy (typu), DI rozhoduje o situaci či chování konkrétní instance.

Přesně. Navíc DI je zpravidla runtime kdežto traity compile time. Někdy potřebujeme to a jindy ono.

Me slo o pojem "priznani zavislosti". S durazem na priznani. Prijde mi to, ze to neprimo znamena u traitu zavislost neni, nebo ze neni videt. Coz je podle me zavadejici. DI je o tom, ze si nemusim vyrabet nastroj kterym neco udelam, ale nekdo mi ho doda. Ale musim vedet jak to pouzit. O traitu toho ja moc vedet nemusim, protoze ja ho nemusim pouzivat, ale v compile time na nej stejne deklaruju zavislost.


BoneFlute

  • *****
  • 1 647
    • Zobrazit profil
Re:Trait a konstruktor
« Odpověď #31 kdy: 21. 12. 2020, 17:55:09 »
im, ze je tam rozdil, ale nevidim ze by u toho traitu ta zavislost byla mene priznana.

Podle mě ses zaměřil na obecný význam slova "závislost", ale ne na skutečnou funkci DI třeba v tom konstruktoru. Trait řeší chování celé třídy (typu), DI rozhoduje o situaci či chování konkrétní instance.

Přesně. Navíc DI je zpravidla runtime kdežto traity compile time. Někdy potřebujeme to a jindy ono.

Me slo o pojem "priznani zavislosti". S durazem na priznani. Prijde mi to, ze to neprimo znamena u traitu zavislost neni, nebo ze neni videt. Coz je podle me zavadejici. DI je o tom, ze si nemusim vyrabet nastroj kterym neco udelam, ale nekdo mi ho doda. Ale musim vedet jak to pouzit. O traitu toho ja moc vedet nemusim, protoze ja ho nemusim pouzivat, ale v compile time na nej stejne deklaruju zavislost.

Trait souvisí s DI asi stejně jako souvisí s DI funkce str_concat() v následujícím kódu:
Kód: [Vybrat]
class Foo {
    string format(s :  string) : string {
       return str_concat("[", s, "]")
    }
}
Je to závislost? Je. Je přiznaná či nepřiznaná? Eee... Mluvil by někdo normální o tom jako o DI?

BoneFlute

  • *****
  • 1 647
    • Zobrazit profil
Re:Trait a konstruktor
« Odpověď #32 kdy: 21. 12. 2020, 18:14:02 »
Dotty (Scala 3) podporuje parametrizované traity. (A také "intersection types", které mohou při práci s traity přijít vhod.)

Kód: [Vybrat]
trait Polite(text: String) {
  val greeting = init(text)
  def greet(name: String) = s"$greeting $name!"
  private def init(s: String) = s"${text.toUpperCase},"
}

trait Curious(val question: String)

class MessageStyle(g: String) extends Polite(g) with Curious("How are you?")

def composeMessage(data: Polite & Curious, name: String): String = {
  s"${data.greet(name)}\n${data.question}"
}

object Main extends App {
  val messageStyle = MessageStyle("hello")
  println(composeMessage(messageStyle, "World"))
}
(https://scastie.scala-lang.org/VCcgilMpRMWpnZ773wMJIw)

Hezký.

Žel, opět se musím zeptat: Jde nějak ještě když bych tomu chtěl přidat nějakou logiku? Tedy konstruktor MessageStyle přijme g, přepočítá ho, a teprve výsledek uloží do fieldu Polite(g).

Re:Trait a konstruktor
« Odpověď #33 kdy: 21. 12. 2020, 18:53:52 »
Žel, opět se musím zeptat: Jde nějak ještě když bych tomu chtěl přidat nějakou logiku? Tedy konstruktor MessageStyle přijme g, přepočítá ho, a teprve výsledek uloží do fieldu Polite(g).

Určitě. Pokud ta logika nemůže být až v traitu (metoda init v původním příkladu), dá se v argumentu traitu použít libovolný výraz (typicky funkce, metoda v přidruženém objektu, jednoduchý inline výraz).

Kód: [Vybrat]
trait T(val traitField: String)

def prepareArgumentForTrait(l: List[String]): String = l.mkString("")

class C(l: List[String]) extends T(prepareArgumentForTrait(l))

object Main extends App {
  val o = C(List("a", "b", "c"))
  println(o.traitField)
}
https://scastie.scala-lang.org/y9HBofuwRce6a37fWbXdpA

BoneFlute

  • *****
  • 1 647
    • Zobrazit profil
Re:Trait a konstruktor
« Odpověď #34 kdy: 21. 12. 2020, 19:01:08 »


Re:Trait a konstruktor
« Odpověď #35 kdy: 21. 12. 2020, 19:03:53 »
im, ze je tam rozdil, ale nevidim ze by u toho traitu ta zavislost byla mene priznana.

Podle mě ses zaměřil na obecný význam slova "závislost", ale ne na skutečnou funkci DI třeba v tom konstruktoru. Trait řeší chování celé třídy (typu), DI rozhoduje o situaci či chování konkrétní instance.

Přesně. Navíc DI je zpravidla runtime kdežto traity compile time. Někdy potřebujeme to a jindy ono.

Me slo o pojem "priznani zavislosti". S durazem na priznani. Prijde mi to, ze to neprimo znamena u traitu zavislost neni, nebo ze neni videt. Coz je podle me zavadejici. DI je o tom, ze si nemusim vyrabet nastroj kterym neco udelam, ale nekdo mi ho doda. Ale musim vedet jak to pouzit. O traitu toho ja moc vedet nemusim, protoze ja ho nemusim pouzivat, ale v compile time na nej stejne deklaruju zavislost.

Trait souvisí s DI asi stejně jako souvisí s DI funkce str_concat() v následujícím kódu:
Kód: [Vybrat]
class Foo {
    string format(s :  string) : string {
       return str_concat("[", s, "]")
    }
}
Je to závislost? Je. Je přiznaná či nepřiznaná? Eee... Mluvil by někdo normální o tom jako o DI?

Nemam pocit, ze bych nekde psal, ze trait souvisi s DI.
Jen se ohrazuju proti tvrzeni ze DI je o priznani zavislosti.

Pripad bez DI a bez traitu:
Potrebuju zatlouct hrebik... vyrobim si kladivo.

DI:
Potrebuju zatlouct hrebik... podej mi kladivo

Trait:
Potrebuju zatlouct hrebik... ja jsem mimo jine taky kladivo.

Vsude mam zavislost na kladivu. V prvnim a tretim pripade mam zavislost dokonce na konkretni implementaci. S DI se nekdo muze rozhodnout v runtimu jaky kladivo dostanu a zavisim jen na interfacu.

Z kontextu predpokladam, ze se bavime o "dependency injection" a ne o "dependency inversion".

BoneFlute

  • *****
  • 1 647
    • Zobrazit profil
Re:Trait a konstruktor
« Odpověď #36 kdy: 21. 12. 2020, 19:37:54 »
Nemam pocit, ze bych nekde psal, ze trait souvisi s DI.
V poho. Reagoval jsem na celé vlákno. Netušil jsem, že tuhle blbost někomu bude stát za to rozvíjet.

im, ze je tam rozdil, ale nevidim ze by u toho traitu ta zavislost byla mene priznana.

Podle mě ses zaměřil na obecný význam slova "závislost", ale ne na skutečnou funkci DI třeba v tom konstruktoru. Trait řeší chování celé třídy (typu), DI rozhoduje o situaci či chování konkrétní instance.

Přesně. Navíc DI je zpravidla runtime kdežto traity compile time. Někdy potřebujeme to a jindy ono.

Me slo o pojem "priznani zavislosti". S durazem na priznani. Prijde mi to, ze to neprimo znamena u traitu zavislost neni, nebo ze neni videt. Coz je podle me zavadejici. DI je o tom, ze si nemusim vyrabet nastroj kterym neco udelam, ale nekdo mi ho doda. Ale musim vedet jak to pouzit. O traitu toho ja moc vedet nemusim, protoze ja ho nemusim pouzivat, ale v compile time na nej stejne deklaruju zavislost.

Trait souvisí s DI asi stejně jako souvisí s DI funkce str_concat() v následujícím kódu:
Kód: [Vybrat]
class Foo {
    string format(s :  string) : string {
       return str_concat("[", s, "]")
    }
}
Je to závislost? Je. Je přiznaná či nepřiznaná? Eee... Mluvil by někdo normální o tom jako o DI?

Nemam pocit, ze bych nekde psal, ze trait souvisi s DI.
Jen se ohrazuju proti tvrzeni ze DI je o priznani zavislosti.

Pripad bez DI a bez traitu:
Potrebuju zatlouct hrebik... vyrobim si kladivo.

DI:
Potrebuju zatlouct hrebik... podej mi kladivo

Trait:
Potrebuju zatlouct hrebik... ja jsem mimo jine taky kladivo.

Vsude mam zavislost na kladivu. V prvnim a tretim pripade mam zavislost dokonce na konkretni implementaci. S DI se nekdo muze rozhodnout v runtimu jaky kladivo dostanu a zavisim jen na interfacu.

Z kontextu predpokladam, ze se bavime o "dependency injection" a ne o "dependency inversion".

Řekl bych, že takto to není. Trvám na tom, že DI (dependency injection) je o přiznání závislostí.

DI: abych mohl fungovat, dej mi kladivo
neDI: budu fungovat, kladivo si seženu

to je celé, víc v tom není.

Trait je úplně něco jiného. DI může respektovat, stejně jako nemusí.

Re:Trait a konstruktor
« Odpověď #37 kdy: 21. 12. 2020, 20:05:29 »
Nemam pocit, ze bych nekde psal, ze trait souvisi s DI.
V poho. Reagoval jsem na celé vlákno. Netušil jsem, že tuhle blbost někomu bude stát za to rozvíjet.

im, ze je tam rozdil, ale nevidim ze by u toho traitu ta zavislost byla mene priznana.

Podle mě ses zaměřil na obecný význam slova "závislost", ale ne na skutečnou funkci DI třeba v tom konstruktoru. Trait řeší chování celé třídy (typu), DI rozhoduje o situaci či chování konkrétní instance.

Přesně. Navíc DI je zpravidla runtime kdežto traity compile time. Někdy potřebujeme to a jindy ono.

Me slo o pojem "priznani zavislosti". S durazem na priznani. Prijde mi to, ze to neprimo znamena u traitu zavislost neni, nebo ze neni videt. Coz je podle me zavadejici. DI je o tom, ze si nemusim vyrabet nastroj kterym neco udelam, ale nekdo mi ho doda. Ale musim vedet jak to pouzit. O traitu toho ja moc vedet nemusim, protoze ja ho nemusim pouzivat, ale v compile time na nej stejne deklaruju zavislost.

Trait souvisí s DI asi stejně jako souvisí s DI funkce str_concat() v následujícím kódu:
Kód: [Vybrat]
class Foo {
    string format(s :  string) : string {
       return str_concat("[", s, "]")
    }
}
Je to závislost? Je. Je přiznaná či nepřiznaná? Eee... Mluvil by někdo normální o tom jako o DI?

Nemam pocit, ze bych nekde psal, ze trait souvisi s DI.
Jen se ohrazuju proti tvrzeni ze DI je o priznani zavislosti.

Pripad bez DI a bez traitu:
Potrebuju zatlouct hrebik... vyrobim si kladivo.

DI:
Potrebuju zatlouct hrebik... podej mi kladivo

Trait:
Potrebuju zatlouct hrebik... ja jsem mimo jine taky kladivo.

Vsude mam zavislost na kladivu. V prvnim a tretim pripade mam zavislost dokonce na konkretni implementaci. S DI se nekdo muze rozhodnout v runtimu jaky kladivo dostanu a zavisim jen na interfacu.

Z kontextu predpokladam, ze se bavime o "dependency injection" a ne o "dependency inversion".

Řekl bych, že takto to není. Trvám na tom, že DI (dependency injection) je o přiznání závislostí.

DI: abych mohl fungovat, dej mi kladivo
neDI: budu fungovat, kladivo si seženu

to je celé, víc v tom není.

Trait je úplně něco jiného. DI může respektovat, stejně jako nemusí.

Chapu. Ty mluvis o zavislosti ma dodavatelich kladiv a ne na kladivech.
Potom ano....

Ja si prekladam dependency injection jako injektaz zavislosti (kladivo) ne jako zavisla injektaz (dodavatel) to by potom spis byla dependent injection.

Mirnou oklikou zpet.... Nebylo by treba hezci aby ten koho obohacuju traitem o tom vubec nemusel vedet?

Re:Trait a konstruktor
« Odpověď #38 kdy: 21. 12. 2020, 21:15:04 »
Mirnou oklikou zpet.... Nebylo by treba hezci aby ten koho obohacuju traitem o tom vubec nemusel vedet?

Beru zpet, protoze vlastne nevim jak to udelat.... To co sem myslel nefunguje tak jak sem myslel...

BoneFlute

  • *****
  • 1 647
    • Zobrazit profil
Re:Trait a konstruktor
« Odpověď #39 kdy: 21. 12. 2020, 21:31:24 »
Mirnou oklikou zpet.... Nebylo by treba hezci aby ten koho obohacuju traitem o tom vubec nemusel vedet?

Beru zpet, protoze vlastne nevim jak to udelat.... To co sem myslel nefunguje tak jak sem myslel...

Nesplňuje to dědičnost nebo dekorátor?

Re:Trait a konstruktor
« Odpověď #40 kdy: 21. 12. 2020, 22:33:00 »
Mirnou oklikou zpet.... Nebylo by treba hezci aby ten koho obohacuju traitem o tom vubec nemusel vedet?

Beru zpet, protoze vlastne nevim jak to udelat.... To co sem myslel nefunguje tak jak sem myslel...

Nesplňuje to dědičnost nebo dekorátor?

Ne.
Tam zase ten kdo rozsiruje nebo dekoruje musi vedet koho rozsiruje nebo dekoruje.
To neni ono.

Mozna by to nejak slo, ale uz se mi nechce premyslet. A stejne pro to nemam asi prakticke vyuziti.
Trivialni idea je, ze mam treba nejakou mapu kde klice jsou nejaky jmena a hodnoty jsou treba funkce nebo ... hodnoty.
Typ je externe definovan (clojure/spec napr.)
A pak budu mit nejaky "trait/dekorator/neco..." ktery teda bude vedet, ze ma okraslovat nejakou mapu, ale uz nemusi znat co v te mape je. A prida svoji funkcnost do mapy associaci a rozsireni typu do externi definice.

A tady koncim, protoze nejak nevim jak takou "vygenerovanou" specifikaci typu pouzit jako treba parametr funkce.
Napadaji me jen samy vosklivosti.

Re:Trait a konstruktor
« Odpověď #41 kdy: 21. 12. 2020, 22:58:58 »
Mirnou oklikou zpet.... Nebylo by treba hezci aby ten koho obohacuju traitem o tom vubec nemusel vedet?
Beru zpet, protoze vlastne nevim jak to udelat.... To co sem myslel nefunguje tak jak sem myslel...

Přidávání čí změnu fieldů, metod, anotací či přidání implementací u třídy, ke které nemám zdroják, některé systémy umí. Třeba BrightspotCMD postavené nad Dari umí tzv. Modifications, Augmentations, Substitutions a Alterations  https://docs.brightspot.com/4.2/en/dari-guide/data-modeling/modifications.html Ta třída o své úpravě neví a runtime jí nahradí jinou implementací. Je to implementované v rámci té datové persistence v Dari. Určitě existují další pokusy o totéž, například v rámci runtime weavingu.  Používá se to poměrně dobře, ale je to pořád jen náhražka. Daleko lepší by bylo, pokud by to bylo součástí jazyka nebo standardního runtime.

Re:Trait a konstruktor
« Odpověď #42 kdy: 22. 12. 2020, 09:53:45 »
Dotty (Scala 3) podporuje parametrizované traity. (A také "intersection types", které mohou při práci s traity přijít vhod.)

Hmm, jaký pak zbývá rozdíl mezi trait a class kromě toho, že není možné dědit z více class najednou? Co by se stalo, kdyby se klíčové slovo class zrušilo a používaly se jen tyhle nové traity?

BoneFlute

  • *****
  • 1 647
    • Zobrazit profil
Re:Trait a konstruktor
« Odpověď #43 kdy: 22. 12. 2020, 20:16:21 »
Dotty (Scala 3) podporuje parametrizované traity. (A také "intersection types", které mohou při práci s traity přijít vhod.)

Hmm, jaký pak zbývá rozdíl mezi trait a class kromě toho, že není možné dědit z více class najednou? Co by se stalo, kdyby se klíčové slovo class zrušilo a používaly se jen tyhle nové traity?

Nevím jak Dotty, ale základní rozdíl mezi dědičností a traity je v té dědičnosti. Když máš objekt O, do kterého přidáš trait T, tak ten objekt O není tím T. (Maximálně tak T obsahuje.) Zatímco když O dědí od předka P, tak O je P.

Jako asi pro tebe nic nového, ale tohle je prostě ten rozdíl 1. To je všechno.



1/ Tak maximálně ještě, že metody z traitu se obvykle nepřetěžují, že se s tím trochu jinak pracuje, a tak.

Idris

  • *****
  • 1 423
    • Zobrazit profil
    • E-mail
Re:Trait a konstruktor
« Odpověď #44 kdy: 22. 12. 2020, 21:42:53 »
Dotty (Scala 3) podporuje parametrizované traity. (A také "intersection types", které mohou při práci s traity přijít vhod.)

Hmm, jaký pak zbývá rozdíl mezi trait a class kromě toho, že není možné dědit z více class najednou? Co by se stalo, kdyby se klíčové slovo class zrušilo a používaly se jen tyhle nové traity?

Nevím jak Dotty, ale základní rozdíl mezi dědičností a traity je v té dědičnosti. Když máš objekt O, do kterého přidáš trait T, tak ten objekt O není tím T. (Maximálně tak T obsahuje.) Zatímco když O dědí od předka P, tak O je P.

Jako asi pro tebe nic nového, ale tohle je prostě ten rozdíl 1. To je všechno.



1/ Tak maximálně ještě, že metody z traitu se obvykle nepřetěžují, že se s tím trochu jinak pracuje, a tak.
To je IMHO o detailech, v některých jazycích jsou traity v podstatě rozhraní s možností implementace (některých metod). Takto to dává docela smysl v praxi, akorát tvoji definici dědičnosti to (bohužel?) splňuje. Taky to je dobře sehrané s generickými typy.