Jak nazwać funkcję podmieniającą całość na podzbiór?

0
somekind napisał(a):

Widzę, że fani serialu ciągle czekają na kolejne odcinki. ;)

@TomRiddle - tylko zastanów się, czy ktoś widzący kod po raz pierwszy na oczy, domyśli się po nazwie retain albo isolated co dana funkcja robi. Bo jak dla mnie, to te nazwy są równie wiele mówiące, co notHotDog. ;)

True, celna uwaga. Ale nie mogę jej nazwać removeAllExcept(), bo to brzmi jak hiper-wysokopoziomows funkcja która robi nie wiadomo co.

0

Żebym ja też miał 7 stron wątku na temat mojego code review :D

1
somekind napisał(a):

Widzę, że fani serialu ciągle czekają na kolejne odcinki. ;)

@TomRiddle - tylko zastanów się, czy ktoś widzący kod po raz pierwszy na oczy, domyśli się po nazwie retain albo isolated co dana funkcja robi. Bo jak dla mnie, to te nazwy są równie wiele mówiące, co notHotDog. ;)

Nazwałem ją substitute().

2

Dzięki za aktualizację. Dobrze że skończyło się bez cliff hangera : - )

3

@TomRiddle:

Nazwałem ją substitute().

o ja pierdziu - 7 stron :o
w ogóle taka funkcja nie powinna istnieć, funkcje powinny być prawie zawsze pure i nic nie powinna podmieniać tylko zwracać nowy obiekt a o starym możesz ewentualnie zapomnieć. Zamieniając słowo "podmienić" na "wyciągnąć"

Funkcja wyciągająca pojedynczą klatkę z filmu - extract?
Funkcja wyciągająca jedno zdanie z postu. - extract
Funkcja wyciągająca jedną literę ze słowa. - extract
Funkcja wyciągająca jeden obiekt ze sceny 3d - extract / pick / find?
Funkcja wyciągająca jeden plik z folderu - ?? find?
Funkcja wyciągająca folder z archiwum - odpowiedź jest w programach do dekompresji - extract
Funkcja wyciągająca wycinek obrazka - tu jednak crop
Funkcja wyciągająca 2 ze 123 - nie rozumiem tego przykładu
Funckja wyciągająca jedno zwierze z farmy - extract / pick / find

substitute to podmienić, ale w sensie zamiennikiem, sugeruje że nowy obiekt można użyć w miejscu starego co prawdopodobnie nie jest prawdą
7 stron i wybrałeś "substitute"...

0
obscurity napisał(a):

w ogóle taka funkcja nie powinna istnieć, funkcje powinny być prawie zawsze pure i nic nie powinna podmieniać tylko zwracać nowy obiekt a o starym możesz ewentualnie zapomnieć.

I dokładnie taka moja funkcja jest. Zwraca kompletnie nowy obiekt, tylko że z lekko zmienionym "wnętrzem". Nie wiem skąd ten pomysł że zrobiłbym nie immutable obiekty.

Funkcja wyciągająca pojedynczą klatkę z filmu - extract?
Funkcja wyciągająca jedno zdanie z postu. - extract
Funkcja wyciągająca jedną literę ze słowa. - extract
Funkcja wyciągająca jeden obiekt ze sceny 3d - extract / pick / find?
Funkcja wyciągająca jeden plik z folderu - ?? find?
Funkcja wyciągająca folder z archiwum - odpowiedź jest w programach do dekompresji - extract
Funkcja wyciągająca wycinek obrazka - tu jednak crop
Funkcja wyciągająca 2 ze 123 - nie rozumiem tego przykładu
Funckja wyciągająca jedno zwierze z farmy - extract / pick / find

To teraz znajdź jedno wspólne słowo na te wszystkie przypadki ;)

substitute to podmienić, ale w sensie zamiennikiem, sugeruje że nowy obiekt można użyć w miejscu starego co prawdopodobnie nie jest prawdą

No i to dokładnie robi moja funkcja. Podmienia cały obiekt jego elementem. I w moim przypadku, nowy obiekt dokładnie można użyć w miejscu starego ;)

0

Czy możesz przedstawić sygnaturę tej funkcji? Typy argumentów, generyki (ograniczenia).
Najlepiej w notacji haskellowej, ale coś jak Java/C#/Scala/TS/Kotlin też będzie ok.

(pamiętam, że miałem nie czytać tego wątku, ale ta strona wygląda ok)

0
jarekr000000 napisał(a):

Czy możesz przedstawić sygnaturę tej funkcji? Typy argumentów, generyki (ograniczenia).

Najlepiej w notacji haskellowej, ale coś jak Java/C#/Scala/TS/Kotlin też będzie ok.

interface Entity {
}

interface Builder {
  A substitute(Entity entity); // tej nazwy szukałem
}

class A {
  List<Entity> getEntities();
  Builder forEntity(Filter<x> jakiśFilterNieIstotne);
}

class B implements Entity {
}

class C implements Entity {
}

a use-case:

Entity c = new C();
Entity b = new B(new Entity(), c, new Entity());
A a = new A(b);

A cleanA1 = a.forEntity(x).substitute(c); // "x" to jakiś predykat, wyciągnie b
A cleanA2 = new A(c);

Dwie ostatnie linijki powinny mieć taki sam efekt.

cleanA1.getEntities(); // [c];
cleanA2.getEntities(); // [c];

Innymi słowy, dostaję new A(new B(new C())), i chcę użyć takiej funkcji na tym, żebym dostał new A(new C()).

0

Trochę zgaduję że masz immutable strukturę w stylu drzewka i chcesz ją przetransformować (transform), przekonwertować (convert) lub zredagować (redact) podmieniając jakiś węzeł (replace) na inny zachowując resztę struktury. Częstym rozwiązaniem jest zrobienie wizytatora który odwiedzi wszystkie elementy i zwróci nowy lub stary węzeł w zależności od warunku. W C# masz przykładowo ReplacingExpressionVisitor do przepisywania wyrażeń które są immutable - wtedy piszesz tylko wizytator który łączy Twoje "forEntity" i "substitute" w proste wyrażenie które może być lambdą typu:

x => x is B ? c : x

i potem tylko wykonujesz ReplacingVisitor.Execute(a) i dostajesz co chciałeś. Tu masz kod ReplacingExpressionVisitora z EF Core https://github.com/dotnet/efcore/blob/main/src/EFCore/Query/ReplacingExpressionVisitor.cs może coś natchnie
i jakiś artykuł https://www.lihaoyi.com/post/ZeroOverheadTreeProcessingwiththeVisitorPattern.html

0
TomRiddle napisał(a):

..

Innymi słowy, dostaję new A(new B(new C())), i chcę użyć takiej funkcji na tym, żebym dostał new A(new C()).
...

Hmm, czyli dostajesz obiekt i wypruwasz z niego stan wewnętrzny, żeby coś później z tym stanem wewnętrzny zrobić?

0
yarel napisał(a):

Hmm, czyli dostajesz obiekt i wypruwasz z niego stan wewnętrzny,

Trochę tak.

żeby coś później z tym stanem wewnętrzny zrobić?

A jakie to ma znaczenie co potem z nim zrobię? :D Potrzebuję new A(new C()) zamiast new A(new B(new C())), ale chcę to uniezależnić od instancji.

0

@TomRiddle: czyli tak jakby łamiesz/obchodzisz 'information hiding', więc przeciwieństwem tego słowa mogło by być expose. To tak by podtrzymać dyskusję ;)

0
yarel napisał(a):

@TomRiddle: czyli tak jakby łamiesz/obchodzisz 'information hiding', więc przeciwieństwem tego słowa mogło by być expose.

Mógłby, gdyby C było "expose"d jakby "na świat", ale ono jest "exposed" tylko w A więc nie pasuje.

0
TomRiddle napisał(a):

I dokładnie taka moja funkcja jest. Zwraca kompletnie nowy obiekt, tylko że z lekko zmienionym "wnętrzem". Nie wiem skąd ten pomysł że zrobiłbym nie immutable obiekty.

Przepraszam, ale nie rozumiem. W takiej sytuacji - czyli gdy zwracasz nowy obiekt, zawierający podzbiór elementów pierwotnego obiektu spełniających pewien predykat - IMO to się powinno nazywać filter. Ewentualnie subset. W notacji Kotlinowej, bo Haskellowej nie znam a z Javową mi się nie chce, wyglądałoby to mniej więcej tak:

// jako extension function, żeby nie zaciemniać klasami
fun <T> Kasztan<T>.filter(predicate: (T) -> Boolean): Kasztan<T>

// jako pure function, żeby nie zaciemniać klasami
fun <T> filter(set: Kasztan<T>, predicate: (T) -> Boolean): Kasztan<T>

// z klasowym zaciemnianiem
interface Kasztan<T> {
  fun filter (predicate: (T) -> Boolean): Kasztan<T>
}

Zresztą w jakichś szanujących się językach pewnie i tak pod spodem miałbyś prawilną kolekcję, zbiór lub cokolwiek na którym zrobiłbyś dokładnie to: filter, przepychając dalej predykat :)

TomRiddle napisał(a):

a use-case:

Entity c = new C();
Entity b = new B(new Entity(), c, new Entity());
A a = new A(b);

A cleanA1 = a.forEntity(x).substitute(c); // "x" to jakiś predykat, wyciągnie b
A cleanA2 = new A(c);

Dwie ostatnie linijki powinny mieć taki sam efekt.

cleanA1.getEntities(); // [c];
cleanA2.getEntities(); // [c];

Innymi słowy, dostaję new A(new B(new C())), i chcę użyć takiej funkcji na tym, żebym dostał new A(new C()).

Prawdę mówiąc use case dość abstrakcyjny. Dlaczego właściwie predykat nazywany jest Entity, a nie po imieniu Predicate? Łatwiej byłoby rozumować o tym use case. Ogółem jak dla mnie, przy obecnym nazewnictwie, absolutnie niejasne jest co ten kod robi bez czytania postów wyżej.

0
superdurszlak napisał(a):

Zresztą w jakichś szanujących się językach pewnie i tak pod spodem miałbyś prawilną kolekcję, zbiór lub cokolwiek na którym zrobiłbyś dokładnie to: filter, przepychając dalej predykat :)

Niektóre implementacje mają kolekcje, niektóre reprezentują brak zasobów (są puste), niektóre mają pojedynczą instacje.

Prawdę mówiąc use case dość abstrakcyjny.

Tak, dość abstrakcyjny, zgadzam się.

Dlaczego właściwie predykat nazywany jest Entity, a nie po imieniu Predicate? Łatwiej byłoby rozumować o tym use case. Ogółem jak dla mnie, przy obecnym nazewnictwie, absolutnie niejasne jest co ten kod robi bez czytania postów wyżej.

Dlatego że te obiekty nie są predykatami, tylko encjami :D Dlatego nazywają się Entity a nie Predicate. Predykat jest tylko użyty żeby wiedzieć którą encje wyciągnąć z encji encji.

0
TomRiddle napisał(a):

Niektóre implementacje mają kolekcje, niektóre reprezentują brak zasobów (są puste), niektóre mają pojedynczą instacje.

Nie szkodzi. Jeśli akurat pod spodem będzie kolekcja, to aplikujesz na kolekcję i zwracasz co tam potrzebujesz - nie wiem, czy np. otrzymując pod spodem pustą kolekcję chciałbyś zwrócić reprezentację braku zasobów, ale zakładam że tak. Nie szkodzi, i tak nie wycieka to chyba na zewnątrz?

0
superdurszlak napisał(a):
TomRiddle napisał(a):

Niektóre implementacje mają kolekcje, niektóre reprezentują brak zasobów (są puste), niektóre mają pojedynczą instacje.

Nie szkodzi. Jeśli akurat pod spodem będzie kolekcja, to aplikujesz na kolekcję i zwracasz co tam potrzebujesz - nie wiem, czy np. otrzymując pod spodem pustą kolekcję chciałbyś zwrócić reprezentację braku zasobów, ale zakładam że tak.

No tak.

Nie szkodzi, i tak nie wycieka to chyba na zewnątrz?

Nie wycieka. Efekt ma być taki sam jakbym zrobił zamiast new A(new B(new C()).substitute(nie istotne), to new A(new C()). Z zewnątrz te dwa podejścia powinny być nierozróżnialne.

Tak szczerze mówiąc, to to trochę irytujące że pytam tylko o nazwę funkcji; a jest mi zarzucane że łamię hermetyzację, że nie followuje wzorców, i że mam mutable state.

2

@superdurszlak: to raczej map a nie filter

1 użytkowników online, w tym zalogowanych: 0, gości: 1