Programowanie milczące - Tacit programming

Programowanie milczące , zwane również stylem bezpunktowym , to paradygmat programowania, w którym definicje funkcji nie identyfikują argumentów (lub „punktów”), na których działają. Zamiast tego definicje składają się jedynie na inne funkcje, wśród których są kombinatory, które manipulują argumentami. Programowanie milczące jest przedmiotem zainteresowania teoretycznego, ponieważ ścisłe użycie kompozycji skutkuje programami, które są dobrze przystosowane do rozumowania równań . Jest to również naturalny styl niektórych języków programowania , w tym APL i jego pochodnych oraz języków konkatenacyjnych, takich jak Forth . Brak nazewnictwa argumentów sprawia, że ​​styl bezpunktowy ma opinię niepotrzebnie niejasnego, stąd epitet „styl bezcelowy”.

UNIX skryptowy wykorzystuje paradygmat z rur .

Kluczową ideą w programowaniu milczącym jest pomoc w działaniu na odpowiednim poziomie abstrakcji.

Przykłady

Pyton

Programowanie milczące można zilustrować następującym kodem Pythona . Sekwencja operacji, takich jak:

def example(x):
    y = foo(x)
    z = bar(y)
    w = baz(z)
    return w

... jest napisane w stylu bezpunktowym jako kompozycja ciągu funkcji, bez parametrów:

from functools import partial, reduce
def compose(*fns):
    return partial(reduce, lambda v, fn: fn(v), fns)

example = compose(foo, bar, baz)

Dla bardziej złożonego przykładu kod Haskella p = ((.) f) . gmożna przetłumaczyć jako:

p = partial(compose, partial(compose, f), g)


Programowanie funkcjonalne

Prostym przykładem (w Haskell ) jest program, który oblicza sumę listy liczb. Możemy zdefiniować funkcję sum rekursywnie za pomocą wskazanego stylu (por. programowanie na poziomie wartości ) jako:

sum (x:xs) = x + sum xs
sum [] = 0

Korzystając z zakładki możemy to jednak zastąpić:

sum xs = foldr (+) 0 xs

A wtedy argument nie jest potrzebny, więc upraszcza się to

sum = foldr (+) 0

co jest bezpunktowe.

Inny przykład wykorzystuje kompozycję funkcji :

p x y z = f (g x y) z

Poniższy pseudokod podobny do Haskella pokazuje, jak zredukować definicję funkcji do jej bezpunktowego odpowiednika:

p = \x -> \y -> \z -> f (g x y) z
  = \x -> \y -> f (g x y)
  = \x -> \y -> (f . (g x)) y
  = \x -> f . (g x)
  (* Here the infix compose operator "." is used as a curried function. *)
  = \x -> ((.) f) (g x)
  = \x -> (((.) f) . g) x

p = ((.) f) . g

Na koniec, aby zobaczyć złożony przykład, wyobraź sobie program do filtrowania map, który pobiera listę, stosuje do niej funkcję, a następnie filtruje elementy na podstawie kryterium

mf criteria operator list = filter criteria (map operator list)

Można to wyrazić bezpunktowo jako

mf = (. map) . (.) . filter

Zauważ, że, jak wspomniano wcześniej, punkty w „bezpunktów” odnoszą się do argumentów, a nie do użycia kropek; powszechne nieporozumienie.

Napisano kilka programów, które automatycznie konwertują wyrażenia Haskella na formę bezpunktową.

Rodzina APL

W J , ten sam rodzaj kodu bezpunktowego występuje w funkcji służącej do obliczania średniej z listy (tablicy) liczb:

avg=: +/ % #

+/sumuje elementy tablicy przez mapowanie ( /) sumowania ( +) na tablicę. %dzieli sumę przez liczbę elementów ( #) w tablicy.

Wzór Eulera wyrażony milcząco:

cos =: 2 o. ]
sin =: 1 o. ]
Euler =: ^@j. = cos j. sin

( j.jest funkcją pierwotną, której definicja monadyczna to 0j1razy x i której definicja diadyczna to x+0j1×y.) Te same obliczenia milczące wyrażone w Dyalog APL :

avg  + ÷ 

cos  2  
sin  1  
j    {0  +0j1×}  ⍝ this part is not tacit
Euler  *j = cos j sin

Oparte na stosie

W językach programowania zorientowanych na stos (i konkatenatywnych , z których większość jest oparta na stosie), powszechnie stosowane są metody bezpunktowe. Na przykład procedura obliczania liczb Fibonacciego może wyglądać w PostScript tak :

/fib
{
   dup dup 1 eq exch 0 eq or not
   {
      dup 1 sub fib
      exch 2 sub fib
      add
   } if
} def

Potok uniksowy

W skryptach uniksowych funkcjami są programy komputerowe, które odbierają dane ze standardowego wejścia i wysyłają wyniki na standardowe wyjście . Na przykład,

sort | uniq -c | sort -rn

to milcząca lub bezpunktowa kompozycja, która zwraca liczebności swoich argumentów i argumentów w kolejności malejącej liczebności. 'sort' i 'uniq' są funkcjami, '-c' i '-rn' sterują funkcjami, ale argumenty nie są wymienione. Rura '|' jest operatorem kompozycji.

Ze względu na sposób działania potoków zwykle możliwe jest przekazywanie tylko jednego „argumentu” naraz w postaci pary standardowych strumieni wejścia/wyjścia. Chociaż dodatkowe deskryptory plików można otwierać z nazwanych potoków , nie jest to już styl bezpunktowy.

Zobacz też

Bibliografia

Linki zewnętrzne