Mówiąc prościej, ograniczenia oznaczają, że istnieje mniej poprawnych sposobów łączenia rzeczy, a pierwszorzędne funkcje ułatwiają rozróżnianie rzeczy, takich jak struktury pętli. Zapoznaj się z tą odpowiedzią , na przykład:
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
iterator.remove();
}
}
Jest to jedyny bezpieczny sposób w Javie, aby usunąć element z kolekcji podczas iteracji. Istnieje wiele sposobów, które wyglądają bardzo blisko, ale są błędne. Ludzie nieświadomi tej metody czasami przechodzą przez zawiły sposób, aby uniknąć problemu, na przykład poprzez iterację przez kopię.
Stworzenie tego generycznego nie jest trudne, więc będzie działać na więcej niż tylko kolekcjach Stringsif kodu , ale bez pierwszorzędnych funkcji nie można zastąpić predykatu (warunku wewnątrz ), więc ten kod ma tendencję do kopiowania i wklejania i nieznacznie zmodyfikowany.
Połącz pierwszorzędne funkcje, które dają ci możliwość przekazania predykatu jako parametru, z ograniczeniem niezmienności, co czyni go bardzo denerwującym, jeśli tego nie zrobisz, i wymyślisz proste bloki konstrukcyjne filter, jak w tym kodzie Scala robi to samo:
list filter (!_.isEmpty)
Pomyśl teraz o tym, co sprawdza system typów w czasie kompilacji w przypadku Scali, ale te kontrole są również wykonywane przez systemy typów dynamicznych przy pierwszym uruchomieniu:
listmusi być jakimś typem obsługującym filtermetodę, a mianowicie kolekcją.
- Elementy
listmuszą mieć isEmptymetodę, która zwraca wartość logiczną.
- Dane wyjściowe będą (potencjalnie) mniejszą kolekcją z tym samym typem elementów.
Po sprawdzeniu tych rzeczy, jakie inne sposoby mogą zostać zepsute przez programistę? Przypadkowo zapomniałem !, co spowodowało bardzo oczywistą awarię przypadku testowego. To właściwie jedyny błąd, jaki można popełnić, i popełniłem go tylko dlatego, że bezpośrednio tłumaczyłem z kodu, który przetestował warunek odwrotny.
Ten wzór powtarza się w kółko. Funkcje pierwszej klasy umożliwiają przekształcenie rzeczy w małe narzędzia wielokrotnego użytku z precyzyjną semantyką, ograniczenia takie jak niezmienność dają bodziec do tego, a sprawdzanie typu parametrów tych narzędzi nie pozostawia wiele miejsca na ich pomijanie.
Oczywiście wszystko zależy od programisty, który wie, że taka funkcja upraszczania filterjuż istnieje, i jest w stanie ją znaleźć lub rozpoznać korzyści wynikające z jej stworzenia. Spróbuj to zaimplementować wszędzie wszędzie, używając tylko rekurencji ogona, a wrócisz w tej samej łodzi złożoności co wersja imperatywna, tylko gorzej. Tylko dlatego, że można napisać bardzo prosty sposób, nie oznacza, że prosta wersja jest oczywista.