Pomysł jest inspirowany faktem, że operatory takie jak +, -,% itd. Mogą być postrzegane jako funkcje z przekazanym jednym lub dwoma argumentami i bez efektów ubocznych. Zakładając, że ja lub ktoś inny pisze język, który zatrzymuje przekazywanie więcej niż dwóch argumentów, a także działa tylko poprzez wartość zwracaną:
a) czy taki język prowadziłby do łatwiejszego do zrozumienia kodu?
b) czy przepływ kodu byłby jaśniejszy? (zmuszony do większej liczby kroków, potencjalnie mniej interakcji „ukrytych”
c) czy ograniczenia sprawiłyby, że język byłby wyjątkowo nieporęczny w przypadku bardziej złożonych programów.
d) (premia) wszelkie inne komentarze na temat zalet / wad
Uwaga:
Trzeba by jeszcze podjąć dwie decyzje - pierwsza dotyczy tego, czy zezwolić na wprowadzanie danych przez użytkownika poza main () lub jego odpowiednikiem, a także jaka będzie reguła dotycząca tego, co dzieje się przy przekazywaniu tablic / struktur. Na przykład, jeśli ktoś chce, aby jedna funkcja dodawała wiele wartości, mógłby obejść to ograniczenie, łącząc je w tablicę. Można to zatrzymać, uniemożliwiając interakcję tablicy lub struktury z samym sobą, co nadal pozwala na przykład na dzielenie każdej liczby przez inną liczbę, w zależności od jej pozycji.
result = f(a)(b)…(z)
. Dotyczy to rodziny języków ML, takich jak Haskell, ale także koncepcyjnie w innych językach, takich jak Lisp, JavaScript lub Perl.Odpowiedzi:
Robert C. Martin w swojej książce „Clean Code” zdecydowanie zaleca korzystanie z funkcji z maksymalnie 0, 1 lub 2 parametrami, więc przynajmniej jeden doświadczony autor książki uważa, że kod staje się bardziej przejrzysty przy użyciu tego stylu (jednak na pewno nie tutaj ultimative autorytet, a jego opinie są dyskusyjne).
Tam, gdzie Bob Martin jest IMHO poprawny, to: funkcje z 3 lub więcej parametrami są często wskaźnikami zapachu kodu. W wielu przypadkach parametry mogą być grupowane razem, tworząc połączony typ danych, w innych przypadkach może to być wskaźnik dla funkcji, która po prostu robi za dużo.
Jednak nie sądzę, że dobrym pomysłem byłoby wymyślenie nowego języka w tym celu:
jeśli naprawdę chcesz egzekwować taką regułę w całym kodzie, potrzebujesz tylko narzędzia do analizy kodu dla istniejącego języka, nie musisz wymyślać do tego zupełnie nowego języka (na przykład dla C # można by użyć czegoś takiego jak „fxcop” ).
czasami łączenie parametrów z nowym typem po prostu nie wydaje się warte wysiłku lub byłoby czystą sztuczną kombinacją. Zobacz na przykład tę
File.Open
metodę ze środowiska .Net. Wymaga czterech parametrów i jestem pewien, że projektanci tego API zrobili to celowo, ponieważ uważali, że byłby to najbardziej praktyczny sposób na zapewnienie różnych parametrów funkcji.czasami zdarzają się sytuacje w świecie rzeczywistym, w których więcej niż 2 parametry upraszczają sprawy ze względów technicznych (na przykład, gdy potrzebujesz mapowania 1: 1 do istniejącego interfejsu API, w którym obowiązują proste typy danych i nie można łączyć różnych parametry w jeden obiekt niestandardowy)
źródło
Istnieje wiele języków, które już działają w ten sposób, np. Haskell. W Haskell każda funkcja pobiera dokładnie jeden argument i zwraca dokładnie jedną wartość.
Zawsze jest możliwe zastąpienie funkcji, która przyjmuje n argumentów, funkcją, która przyjmuje n-1 argumentów i zwraca funkcję, która przyjmuje argument ostateczny. Stosując to rekurencyjnie, zawsze można zastąpić funkcję, która pobiera dowolną liczbę argumentów, funkcją, która przyjmuje dokładnie jeden argument. I ta transformacja może być wykonana mechanicznie za pomocą algorytmu.
Nazywa się to Frege-Schönfinkeling, Schönfinkeling, Schönfinkel-Currying lub Currying, po Haskell Curry, który intensywnie badał go w latach 50. XX wieku, Mojżesz Schönfinkel, który opisał go w 1924 roku, i Gottlob Frege, który zapowiedział go w 1893 roku.
Innymi słowy, ograniczenie liczby argumentów ma dokładnie zerowy wpływ.
źródło
f *(call_with: a,b,c,d,e)
Przeciążenie,call_with :
aby rozpocząć łańcuch,,
przedłużyć łańcuch i*
na LHS, aby wywołaćf
, przekazując mu każdą zawartość łańcucha pojedynczo. Wystarczająco słaby system przeciążania operatora sprawia, że składnia jest uciążliwa, ale jest to wina systemu przeciążania operatora bardziej niż cokolwiek innego.W ciągu ostatnich kilku tygodni spędziłem trochę czasu próbując nauczyć się języka komputerowego J. W J prawie wszystko jest operatorem, więc dostajesz tylko „monady” (funkcje, które mają tylko jeden argument) i „dyady” (funkcje z dokładnie dwoma argumentami). Jeśli potrzebujesz więcej argumentów, musisz albo podać je w tablicy, albo podać w „polach”.
J może być bardzo zwięzły, ale podobnie jak jego poprzednik APL, może być również bardzo tajemniczy - ale jest to głównie wynikiem dążenia twórcy do naśladowania matematycznej zwięzłości. Możliwe jest zwiększenie czytelności programu J przy użyciu nazw zamiast znaków do tworzenia operatorów.
źródło
Język oparty na tym, w jaki sposób ogranicza programistę, zależy od założenia, że programista rozumie potrzeby każdego programisty lepiej niż sam programista. Są przypadki, w których jest to faktycznie ważne. Na przykład ograniczenia w programowaniu wielowątkowym wymagające synchronizacji przy użyciu muteksów i semaforów są przez wielu uważane za „dobre”, ponieważ większość programistów zupełnie nie zdaje sobie sprawy z leżących u ich podstaw złożoności specyficznych dla maszyny, które te ograniczenia przed nimi ukrywają. Podobnie, niewielu chce w pełni zrozumieć niuanse wielowątkowych algorytmów odśmiecania; język, który po prostu nie pozwala złamać algorytmu GC, jest lepszy niż język, który zmusza programistę do rozpoznania zbyt wielu niuansów.
Musisz uzasadnić argument, dlaczego jako programista języka rozumiesz przekazywanie argumentów o wiele lepiej niż programiści używający twojego języka, że warto zapobiegać im, robiąc rzeczy, które uważasz za szkodliwe. Myślę, że byłby to trudny argument.
Trzeba też wiedzieć, że programiści będą obejść swoje ograniczenia. Jeśli potrzebują 3 lub więcej argumentów, użyją technik takich jak curry, aby zamienić je w wywołania o mniejszej liczbie argumentów. Jednak często wiąże się to z kosztem czytelności, a nie z jej poprawą.
Większość języków, które znam z tego rodzaju regułami, to esolangi, języki zaprojektowane w celu wykazania, że rzeczywiście możesz działać z ograniczonym zestawem funkcji. W szczególności esolangi, w których każdy znak jest kodem operacyjnym, mają tendencję do ograniczania liczby argumentów, po prostu dlatego, że muszą utrzymywać krótką listę kodów operacyjnych.
źródło
Będziesz potrzebował dwóch rzeczy:
Dodam matematyczny przykład, aby wyjaśnić odpowiedź napisaną przez Jörga W. Mittaga .
Rozważ funkcję Gaussa .
Funkcja Gaussa ma dwa parametry dla swojego kształtu, a mianowicie średnią (środkową pozycję krzywej) i wariancję (związaną z szerokością impulsu krzywej). Oprócz dwóch parametrów należy również podać wartość zmiennej swobodnej
x
, aby ją ocenić.W pierwszym etapie zaprojektujemy funkcję Gaussa, która przyjmuje wszystkie trzy parametry, a mianowicie średnią, wariancję i zmienną swobodną.
W drugim kroku tworzymy złożony typ danych, który łączy średnią i wariancję w jedną rzecz.
W trzecim kroku tworzymy parametryzację funkcji Gaussa, tworząc zamknięcie funkcji Gaussa związanej ze złożonym typem danych, który utworzyliśmy w drugim kroku.
Na koniec oceniamy zamknięcie utworzone w trzecim kroku, przekazując mu wartość zmiennej swobodnej
x
.Struktura jest zatem:
źródło
W prawie każdym języku programowania możesz przekazać jakiś typ listy, tablicy, krotki, zapisu lub obiektu jako jedyny argument. Jego jedynym celem jest przechowywanie innych przedmiotów zamiast indywidualnego przekazywania ich do funkcji. Niektóre środowiska IDE Java mają nawet funkcję „ Wyodrębnij obiekt parametru ”. Wewnętrznie Java implementuje zmienną liczbę argumentów, tworząc i przekazując tablicę.
Jeśli naprawdę chcesz robić to, o czym mówisz, w najczystszej postaci, musisz spojrzeć na rachunek lambda. To jest dokładnie to, co opisujesz. Możesz go wyszukiwać w Internecie, ale opis, który miał dla mnie sens, znajdował się w Typach i językach programowania .
Spójrz na języki programowania Haskell i ML (ML jest prostszy). Oba są oparte na rachunku lambda i koncepcyjnie mają tylko jeden parametr na funkcję (jeśli trochę się zmrużysz).
Przedmiotem 2 Josha Blocha jest: „Zastanów się nad konstruktorem w obliczu wielu parametrów konstruktora”. Możesz zobaczyć, jak to się dzieje , ale przyjemność jest pracować z API napisanym w ten sposób.
Niektóre języki nazwały parametry, co jest innym podejściem, które znacznie ułatwia nawigację po dużych podpisach metod. Kotlin nazwał na przykład argumenty .
źródło