Czy funkcje wyższego rzędu zapewniają większą moc programowaniu funkcjonalnemu?

13

Zadałem podobne pytanie na cstheory.SE .

Zgodnie z tą odpowiedzią na Stackoverflow istnieje algorytm, który w nieliniowym czystym funkcjonalnym języku programowania ma złożoność , podczas gdy tym samym algorytmem w programowaniu imperatywnym jest Ω ( n ) . Dodanie lenistwa do języka FP spowodowałoby, że algorytm Ω ( n ) .Ω(nlogn)Ω(n)Ω(n)

Czy istnieje równoważna relacja porównująca język FP z funkcjami wyższego rzędu i bez nich? Czy to wciąż Turing Complete? Jeśli tak, to czy brak wyższego porządku w FP sprawia, że ​​język jest mniej „mocny” lub wydajny?

vz0
źródło
Który język FP?
reinierpost
Funkcje wyższego rzędu i leniwa ocena to nie to samo, afaik. Więc o co ci chodzi?
Raphael

Odpowiedzi:

11

W funkcjonalnym języku programowania, który jest wystarczająco wydajny (na przykład z typami danych do implementacji zamknięć ), można wyeliminować wszystkie zastosowania wyższego rzędu poprzez transformację defunkcjonalizacji . Ponieważ ta metoda jest używana do kompilacji tego rodzaju języka, można zasadnie założyć, że nie wpływa to na wydajność i że w tym ustawieniu wyższa kolejność nie zmniejsza mocy języka. Wpływa to jednak na sposób pisania kodu.

Jeśli jednak język nie jest wystarczająco mocny, to tak, wyższy porządek zapewnia moc ekspresji. Rozważ rachunek lambda: bez żadnej funkcji wyższego rzędu naprawdę nie może nic zrobić, głównie dlatego, że najbardziej podstawowe typy danych (liczby całkowite, logiczne) są implementowane za pomocą funkcji.

Podsumowując, to naprawdę zależy od języka.


Powyżej jest moja odpowiedź. Poniżej komentarz na temat zwykłego założenia dotyczącego języków imperatywnych.

Ω(nlogn)Ω(n)Ω(n)

nO(1)O(logn)O(logm)mmnmn

O(1)

jmad
źródło
4

To zależy od tego, co rozumiesz przez ekspresję.

Oto argument, że wyższy porządek coś dodaje: w językach pierwszego rzędu rekurencja pierwotna nie wystarcza do wyrażenia funkcji Ackermanna . Jednak w obecności funkcji wyższego rzędu wystarczy prymitywna rekurencja:

Ackermann 0=λx.x+1Ackermann (m+1)=Iter (Ackermann m)Iter f 0=f 1Iter f (n+1)=f (Iter f n)

Definiuje to funkcję Ackermanna przy użyciu tylko pierwotnej rekurencji.

IterIterNkNkIter(NN)(NN)

Martin Berger
źródło