Czy nazwał ktoś już paradygmat w którym zakazane jest pobieranie wartości niejawnie?

1

Wpadł mi do głowy pewien pomysł, i zastanawiam się czy ktoś już kiedyś wpadł na taki pomysł, i czy to zostało już nazwane.

Otóż chodzi o to, że sporo aplikacji wykorzystystuje niektóre dane niejawnie. Chodzi o to że wołamy jakąś funkcję, i z jej sygnatury nie wynika w żaden sposób że ona czegoś używa. Może to być:

  • pola statyczne jakiejś klasy
  • zmienne globalne (co w sumie koncepcyjnie jest tożsame z polami statyczynmi)
  • jakieś elementy systemu operacyjnego, jak locale, czas, ip, hostname, etc.
  • elementy runtime'u, jak cwd, argv, zmienne środowiskowe

Chciałbym napisać aplikację w taki sposób, żeby żadna klasa ani funkcja nie brała takich rzeczy niejawnie - tzn. żeby wszystko było przekazane przez parametry w dół, a jeśli coś musi odczytać systemowy element, to powinna to być jakaś klasa, tylko po to, jak np SystemTime, której instancje tez się przekazuje "z góry na dół" przez parametry. Myślę że jest to jaknajbardziej wykonalne.

W takim paradygmacie:

  • używanie elementów systemowych byłoby dozwolone tylko jeśli ten dostęp jest w implementacji polimorficznej, (np funkcji albo instancji klasy), którą można przekazać przez parametry "z góry".
  • używanie elementów z runtimeu byłoby dozwolone tylko w main(), i należałoby je w pakować w polimorficzne elementy (jak funkcje i klasy), i przekazanie ich dalej parametrami
  • dostęp do pól statycznych byłby dozwolony tylko w obrębie jednej klasy, w taki sposób żeby jej zachowanie nigdy nie wpłynęło na różne instancje tej klasy (czyli mogłyby być użyte tylko np do optymalizacji),
  • no a zmienne globalne, to wiadomo, zawsze zakazane (w tym paradygmacie).

Taki paradygmat też trochę niewewlowałby potrzebę takich rozwiązań jak kontenery DI, bo jeśli wszystko jest przekazywane "z góry na dół" przez parametry, to żadne "wspomagacze wstrzykiwania zal." nie są potrzebne.

I tak się zastanawiam, czy takie podejście - które można by nazwać paradygmatem, bo jest to jakiś nałożony constraint, (tak samo jak programowanie strukturalne np) czy on jest już jakoś nazwany, słyszał ktoś o czymś takim?

I tak, rozumiem że ten pomysł, lokalnie możnaby nazwać że to jest właściwie to samo co "Dependency Injection". Tylko dwie rzeczy: po pierwsze DI się odnosi do wstrzykiwania rzeczy przez konstruktor, a ja tutaj opisuje case w którym to nie musi być konstruktor tylko dowolny parametr. A po drugie, nie jestem pewien czy "Dependency Injection" nie odnosi się tylko do małych miejsc (np klasa), a nie do całej aplikacji. Czy jak powiem "Moja aplikacja opiera się na Dependency Injection", to czy na tej podstawie ktoś by się domyślił że każdy jeden element, dana czy call jest przekazany przez parametry z góry na dół?

3

Myślisz nad tym, aby to jakoś wymusić? To chyba statyczna analiza. Generalnie staram się zawsze tak pisać - ułatwia testowanie; nazwałbym to paradygmat kodu testowalnego:)

6

Nie znam się, ale czy w haskellu i innych stricte funkcyjnych językach z grubsza tak to nie wygląda?

0
lion137 napisał(a):

Myślisz nad tym, aby to jakoś wymusić?

Nie, to by było bez sensu.

To chyba statyczna analiza.

No, na pewno.

Generalnie staram się zawsze tak pisać - ułatwia testowanie; nazwałbym to paradygmat kodu testowalnego:)

Jest masa zalet, nie tylko to.

W pytaniu, przypomnę, chodzi o to czy coś takiego już istnieje?

snowflake2137 napisał(a):

Nie znam się, ale czy w haskellu i innych stricte funkcyjnych językach z grubsza tak to nie wygląda?

Ale w haskellu chyba da się zadeklarować zmienne globalne? Tzn. można zadeklarować zmienne w top-level, i odnieść się potem do nich ze środka jakiejś nieskopoziomowej funkcji.

Poza tym, paradygmat funkcyjny narzuca inne ograniczenia również, takie jak niemutowalnośc zmiennych; a ja pytam tylko i wyłącznie o przekazywanie argumentów jawnie.

Już nie mówiąc o tym, że są wartości które są stałe, ale nadal nie chciałbym dostać się do nich niejawnie.

3
Riddle napisał(a):
snowflake2137 napisał(a):

Nie znam się, ale czy w haskellu i innych stricte funkcyjnych językach z grubsza tak to nie wygląda?

Ale w haskellu chyba da się zadeklarować zmienne globalne? Tzn. można zadeklarować zmienne w top-level, right?

Czy to jest wg Ciebie zadeklarowanie "zmiennej" top-level czy nie?

a = 42
f x = x * a

Zasadniczo zgadzam się ze @snowflake2137, cały opis brzmi jakby ktoś przepisywał zalety korzystania z Haskella i pure functions.

0
Saalin napisał(a):
Riddle napisał(a):
snowflake2137 napisał(a):

Nie znam się, ale czy w haskellu i innych stricte funkcyjnych językach z grubsza tak to nie wygląda?

Ale w haskellu chyba da się zadeklarować zmienne globalne? Tzn. można zadeklarować zmienne w top-level, right?

Czy to jest wg Ciebie zadeklarowanie "zmiennej" top-level czy nie?

a = 42
f x = x * a

Zasadniczo zgadzam się ze @snowflake2137, cały opis brzmi jakby ktoś przepisywał zalety korzystania z Haskella i pure functions.

W haskellu, językach funkcyjnych i "pure funkcjach" faktycznie taka wartość w runtime'ie się nie zmieni, więc nie ma z tym problemu.

Ale ja mówię o czymś innym.

Bo jeśli pracuję z takim kodem, refaktoruję go, i zmienię początkową wartość takiej zmiennej, to funkcje które z niej korzystają również zaczną działać inaczej niż działały. Nie ma przed tym w haskellu żadnej "ochrony". Dlatego to jest rozmowa trochę o innych rzeczach.

Z resztą odchodzicie od tematu, ja w wątku zapytałem tylko i wyłącznie czy "przekazywanie wartości tylko i wyłącznie przez argumenty, bez zmiennych globalnych, top-levelowych, statycznych, bez żadnych innych dodatkowych constraintów" zostało już jakoś nazwane, czy nie. Wierz lub nie, ale jestem świadom że istnieje coś takiego jak paradygmat funkcyjny, i jestem świadom takiego języka jak Haskell. Dziękuję bardzo za uwagę.

Ale chciałbym zwrócić uwagę odpowiadających na esencję mojego pytania, a tym pytaniem jest: czy takie coś już zostało nazwane? (i nie chodzi mi o FP, bo w FP są jeszcze inne dodatkowe constrainty).

0

znaczy chcesz mieć funkcje które nie wywołują żadnych innych funkcji?

2

Ja bym w skrócie powiedział że taki paradygmat to dobrze napisany kod :D I w dobrze napisanym kodzie każda zaleznośc która jest niepewna i chcemy ją podmienić do testów jednostkowych powinna być owrapowana w jakiegoś providera. Przykładem w Javie może być provader czasu. W Javie była dyskusja czy powinno się w kodzie pisać LocalDate.now() czy tez mieć LocalDateProvider, który jest interfejsem i można na potrzeby testów mieć własne implementacje dostarczające z góry ustalony czas. Przeciwnycy mówili iż to zbytnie pisanie kodu pod testy :D aż w bibliotece standardowej Javy dodano providera czasu :D

0
KamilAdam napisał(a):

Ja bym w skrócie powiedział że taki paradygmat to dobrze napisany kod :D

To samo można by powiedzieć o strukturalnym ;D Ja szukam po prostu konkretnej nazwy na to, i zastanawiam się czy coś takiego już zostało nazwane?

0
Riddle napisał(a):

To samo można by powiedzieć o strukturalnym ;D Ja szukam po prostu konkretnej nazwy na to, i zastanawiam się czy coś takiego już zostało nazwane?

Tylko iż w strukturalnym nie masz interfejsów, a w OOP masz interfejsy, w Haskellu masz TypeClassy czyli tez interfejsy, a w Clojurze masz multimetody czyli metody które mogą mieć wiele implementacji

0
KamilAdam napisał(a):
Riddle napisał(a):

To samo można by powiedzieć o strukturalnym ;D Ja szukam po prostu konkretnej nazwy na to, i zastanawiam się czy coś takiego już zostało nazwane?

Tylko iż w strukturalnym nie masz interfejsów, a w OOP masz interfejsy, w Haskellu masz TypeClassy czyli tez interfejsy, a w Clojurze masz multimetody czyli metody które mogą mieć wiele implementacji

Dobra, nieistotne.

Ja po prostu pytam czy takie coś zostało jakoś konkretnie nazwane, inaczej niż "dobry kod"?

5
Riddle napisał(a):

Bo jeśli pracuję z takim kodem, refaktoruję go, i zmienię początkową wartość takiej zmiennej, to funkcje które z niej korzystają również zaczną działać inaczej niż działały. Nie ma przed tym w haskellu żadnej "ochrony". Dlatego to jest rozmowa trochę o innych rzeczach.

Taka początkowa zmienna (de fakto stała) to po prostu funkcja.
Równie dobrze problem będziesz miał jak twój kod korzysta z funkcji f i ta funkcja się zmieni - też będzie działać inaczej.

Ale uwaga jest język, który problem rozwiązuje:
unisonlang - tu zmiana kodu funkcji, zmiennej (czyli funkcji stałej) nie zmienia niejawnie działania funkcji, które od tych zależą (nadal zależą od starego kodu).

0
jarekr000000 napisał(a):
Riddle napisał(a):

Bo jeśli pracuję z takim kodem, refaktoruję go, i zmienię początkową wartość takiej zmiennej, to funkcje które z niej korzystają również zaczną działać inaczej niż działały. Nie ma przed tym w haskellu żadnej "ochrony". Dlatego to jest rozmowa trochę o innych rzeczach.

Taka początkowa zmienna (de fakto stała) to po prostu funkcja.

No fakt.

Okej, faktycznie, stałe zmienne globalne mogą być, pod warunkiem że nie są inicjalizowane niczym niejawnym (inną globalną która jest zmienna, albo statyczną). Zwracam honor @Saalin.

jarekr000000 napisał(a):

Równie dobrze problem będziesz miał jak twój kod korzysta z funkcji f i ta funkcja się zmieni - też będzie działać inaczej.

Ale uwaga jest język, który problem rozwiązuje:
unisonlang - tu zmiana kodu funkcji, zmiennej (czyli funkcji stałej) nie zmienia niejawnie działania funkcji, które od tych zależą (nadal zależą od starego kodu).

Fajna ciekawostka.

Ale jednak nie to jest tematem watku - ja się zastanawiam czy takie coś jak "wszystko oprócz funkcji musi być przekazane jawnie" zostało jakoś nazwane?

0

Gdyby problem trochę podzielić, tzn. wsparcie na poziomie określonego języka programowania rozdzielić od podejścia do projektowania, to można na poziomie kodu iść w 'pure functional programming', a od strony projektu w kierunku modelu aktorów wymieniających wiadomości.

0
yarel napisał(a):

Gdyby problem trochę podzielić, tzn. wsparcie na poziomie określonego języka programowania rozdzielić od podejścia do projektowania, to można na poziomie kodu iść w 'pure functional programming', a od strony projektu w kierunku modelu aktorów wymieniających wiadomości.

Czyli w skrócie FP i OOP?

Te rzeczy dodają swoje constrainty - a ja szukam po prostu określenia na nieprzekazywanie niejawnie danych.

Rozumiem, że skoro tyle osób się wypowiedziało z innymi tematami, a nie z nazwą, to można założyć że coś takiego po prostu nie zostało jeszcze nazwane?

2
Riddle napisał(a):

Ale jednak nie to jest tematem watku - ja się zastanawiam czy takie coś jak "wszystko oprócz funkcji musi być przekazane jawnie" zostało jakoś nazwane?

Na pewno zwykłe pure functional programming spełnia to założenie.
Po prostu "wszystko" jest funkcją.

0
Riddle napisał(a):
yarel napisał(a):

Gdyby problem trochę podzielić, tzn. wsparcie na poziomie określonego języka programowania rozdzielić od podejścia do projektowania, to można na poziomie kodu iść w 'pure functional programming', a od strony projektu w kierunku modelu aktorów wymieniających wiadomości.

Czyli w skrócie FP i OOP?

OOP nie jest niezbędne. Aktora możesz inaczej zaimplementować.

Te rzeczy dodają swoje constrainty - a ja szukam po prostu określenia na nieprzekazywanie niejawnie danych.

A są paradygmaty nie dodające swoich constraintów? W FP masz Point-free Style / Tacit programming - nie ma argumentu, nie ma problemu nie jawnego przekazywania :-)

0
jarekr000000 napisał(a):
Riddle napisał(a):

Ale jednak nie to jest tematem watku - ja się zastanawiam czy takie coś jak "wszystko oprócz funkcji musi być przekazane jawnie" zostało jakoś nazwane?

Na pewno zwykłe pure functional programming spełnia to założenie.
Po prostu "wszystko" jest funkcją.

Ale programowanie funkcyjne ma swoje dodatkowe ograniczenia, jak np to że nie należy mutować zmiennych.

Ja szukam określenia tylko i wyłącznie na przekazywanie wartości tylko parametrami.

yarel napisał(a):

A są paradygmaty nie dodające swoich constraintów?

No nie ma :| Stąd nazwa paradygmat.

Ja szukam określenia na paradygmat, w którym chodzi tylko o nieprzekazywanie zmiennych. To że istnieją paradygmaty które mają to i jeszcze coś, to wiem że istnieją. Ja szukam nazwy która odnosi się tylko i wyłącznie do nie przekazywania argumentów w dół i nie dodaje żadnych innych konstraintów.

3
Riddle napisał(a):

Ale programowanie funkcyjne ma swoje dodatkowe ograniczenia, jak np to że nie należy mutować zmiennych.

Ja szukam określenia tylko i wyłącznie na przekazywanie wartości tylko parametrami.

Ale akurat jedno wynika z drugiego. Jeśli zmutujesz zmienną, to funkcja mimo użycia tych samych argumentów może dać inny wynik. (Nie jest deterministyczna).

0
jarekr000000 napisał(a):
Riddle napisał(a):

Ale programowanie funkcyjne ma swoje dodatkowe ograniczenia, jak np to że nie należy mutować zmiennych.

Ja szukam określenia tylko i wyłącznie na przekazywanie wartości tylko parametrami.

Ale akurat jedno wynika z drugiego. Jeśli zmutujesz zmienną, to funkcja mimo użycia tych samych argumentów może dać inny wynik. (Nie jest deterministyczna).

A proceduralny wynika z imperatywnego, a jakoś są dwie nazwy na to.

Więc skoro funkcyjny zawiera w sobie to, o czym pisze, to pewnie też ma jakąs nazwę i tej nazwy szukam. Jesli znasz taką - to się podziel, jesli nie to dzięki.

0
Riddle napisał(a):

Ja szukam określenia tylko i wyłącznie na przekazywanie wartości tylko parametrami.

Mając wskaźniki/referencje nie możesz być niczego pewien. Nie wiesz, czy funkcja przykładowo przepisze adres pola z argumentu wejściowego do innego pola.

To co piszesz ma sens i każdy sensowny programista dochodzi prędzeć czy póżniej, że mniejsze poleganie na kontekście jest słabe.

Riddle napisał(a):

A proceduralny wynika z imperatywnego, a jakoś są dwie nazwy na to.

To podział historyczny. Programowanie imperatywne to if i goto. Programowanie proceduralne to funkcje/ify/pętle. W dzisiejszych czasach ten podział nie ma sensu, bo każdy język imperatywny jest proceduralny

0

to nie sprowadza się po prostu do terminów „pure functions” i „high-order function” obydwa terminy gwarantują ci to co chcesz i są minimalnym podzbiorem. Ew flow-based programming.

0
Riddle napisał(a):
  • jakieś elementy systemu operacyjnego, jak locale, czas, ip, hostname, etc.
  • elementy runtime'u, jak cwd, argv, zmienne środowiskowe

Jest takie określenie "dobre praktyki". No i kurczę, załóżmy, że piszesz bibliotekę open source. To dobrą praktyką będzie wydzielenie gdzieś w jednym miejscu projektu kodu, który używa elementy typu cwd, argv, zmienne środowiskowe czy jakieś elementy systemu operacyjnego, jak locale, czas, ip, hostname, etc., a w innych miejscach przyjmowanie tego jako parametr i tyle (zakładam zresztą, że to rozumiesz).

Niestety często w ekosystemie JS spotykam się z łamaniem dobrych praktyk przez biblioteki open source np. biblioteki, które robią coś niepozornego, ale są zależne albo od DOM albo od Node.js (czyli danej biblioteki mogę używać tylko w przeglądarce albo właśnie odwrotnie - tylko w Node.js, mimo że biblioteka mogłaby być napisana w taki sposób, żeby tego nie wymagać. Ale właśnie - ktoś nie pomyślał o uniezależnieniu od środowiska, w którym dana libka będzie wykorzystywana).

Chciałbym napisać aplikację w taki sposób, żeby żadna klasa ani funkcja nie brała takich rzeczy niejawnie

Jeszcze jest coś takiego jak system pozwoleń (permissions) - ale to bardziej dla apek niż klas - takie rzeczy funkcjonują w apkach mobilnych czy na stronach internetowych. Apki żadają (bezpośrednio albo w manifeście mają to opisane) pozwolenia np. do kamery i użytkownik musi zatwierdzić.

Chciałbym napisać aplikację w taki sposób, żeby żadna klasa ani funkcja nie brała takich rzeczy niejawnie

Może jakiś sandbox? WebAssembly na przykład.

0
LukeJL napisał(a):
Riddle napisał(a):
  • jakieś elementy systemu operacyjnego, jak locale, czas, ip, hostname, etc.
  • elementy runtime'u, jak cwd, argv, zmienne środowiskowe

Jest takie określenie "dobre praktyki". No i kurczę, załóżmy, że piszesz bibliotekę open source. To dobrą praktyką będzie wydzielenie gdzieś w jednym miejscu projektu kodu, który używa elementy typu cwd, argv, zmienne środowiskowe czy jakieś elementy systemu operacyjnego, jak locale, czas, ip, hostname, etc., a w innych miejscach przyjmowanie tego jako parametr i tyle (zakładam zresztą, że to rozumiesz).

Ale określenie "dobre praktyki" nie wskazuje jednoznacznie, na to o czym piszę.

Może jakiś sandbox? WebAssembly na przykład.

Ale do tego nie potrzeba nic specjalnego - da się to łatwo zrobić w każdym języku który wspiera polimofizm. Tylko chciałbym to jakoś nazwać, bo czuję że to się jakoś (chyba?) już nazywa, albo powinno nazywać. Jedyne określenia o jakich pomyślałem, to właśnie dependency injection albo pure functions; ale te określenia nie wskazują jednoznacznie na to co chcę.

Schadoow napisał(a):

to nie sprowadza się po prostu do terminów „pure functions” i „high-order function” obydwa terminy gwarantują ci to co chcesz i są minimalnym podzbiorem. Ew flow-based programming.

"higher-order function" to po prostu funkcja która przyjmuje inną funkcję, trochę jak dekorator w pythonie. Nie ma nigdzie w definicji HOF że te funkcje nie mogą brać niejawnie wartości skądś.

Natomiast "pure function" odnosi się do tego, że wynik funkcji zależy tylko od argumentów (czyli niby pasuje), oraz że funkcja nie ma side-efektów. Czyli jeśli mam funkcję, która mutuje argument to ona jest pure.

A w paradygmacie, o którym ja piszę i o którym od początku chodzi w wątku, chodzi tylko i wyłącznie o jeden constraint - jeden (żaden więcej), i tym constraintem miałoby być nie branie wartości niejawnie skądś. Czyli w tajemniczym paradygmacie X którego nazwy szukam (i chyba się nie doszukam) mutowanie argumentów byłoby dozwolone - bo ten argument przekazany byłby jawnie.

Mutowanie arugmentów to nie jest dobra praktyka, ale w tym paradygmacie o którym chodzi w temacie byłoby to dozwolone. I nazwy na ten paradygmat szukam. Jeśli masz pomysł, czy jakoś to się już nazywa, to podziel się. Jeśli nie, to dzięki za odpowiedź.

slsy napisał(a):

To co piszesz ma sens i każdy sensowny programista dochodzi prędzeć czy póżniej, że mniejsze poleganie na kontekście jest słabe.

Nie mam ochoty wchodzić w jakąś polemikę nie na temat. Więc jeśli "to coś", o czym piszesz, jakoś się nazywa 0 masz pomysł, to prosze podziel się. Jeśli nie, to dzięki za odpowiedź. Bo jedyne czego szukam to jest nazwa na paradygmat który nie pozwala na niejawny dostęp do danych.

0

A w paradygmacie, o którym ja piszę i o którym od początku chodzi w wątku, chodzi tylko i wyłącznie o jeden constraint - jeden (żaden więcej),

Ograniczenie - ok, ale do czego ten constraint miałby być dołożony?

0
yarel napisał(a):

A w paradygmacie, o którym ja piszę i o którym od początku chodzi w wątku, chodzi tylko i wyłącznie o jeden constraint - jeden (żaden więcej),

Ograniczenie - ok, ale do czego ten constraint miałby być dołożony?

Do całej aplikacji, tak jak inne paradygmaty.

2

To nazwij to output depeneds on input i skróc do ODI xD

Nawet ktoś uzywa takiej nazwy xD

https://www.linkedin.com/pulse/pure-functions-javascript-sumit-jangir
screenshot-20231017134730.png

0

No i się zbliżamy do czegoś.

Niestety google "odi paradigm" nie znajduje tego :/ Także to chyba nie jest rzecz.

0
Riddle napisał(a):
yarel napisał(a):

A w paradygmacie, o którym ja piszę i o którym od początku chodzi w wątku, chodzi tylko i wyłącznie o jeden constraint - jeden (żaden więcej),

Ograniczenie - ok, ale do czego ten constraint miałby być dołożony?

Do całej aplikacji, tak jak inne paradygmaty.

Jeśli żenisz różne paradygmaty w aplikacji to masz "multi-paradigm programming" i są języki, które to wspierają. Sam paradygmat nie wystarczy do "zakazania pobierania wartości niejawnie", jeśli język tego nie będzie wymuszał. Język musiałby być "purely <Paradygmat, który to wspiera>".

Może "value-level programming" jest takim paradygmatem? Ale znów, jeśli będzie język, który wspiera to value-level + OOP, to klops, obchodzisz ograniczenie na poziomie OOP :-)

Jaki problem rozwiązujesz, np. załóżmy, że nazwałeś ten paradygmat, co dalej? Przepisujesz appkę z OOP na coś innego?

5
Riddle napisał(a):

Więc skoro funkcyjny zawiera w sobie to, o czym pisze, to pewnie też ma jakąs nazwę i tej nazwy szukam. Jesli znasz taką - to się podziel, jesli nie to dzięki.

No to masz:
funkcje deterministyczne - zależą tylko od wejścia

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