15 kwietnia 2013

Literały funkcyjne w Scali

Teorii nigdy za wiele, a przy nauce programowania funkcyjnego w Clojure i Scali zauważam duże jej braki u mnie. Nadrabiam pomału zaległości.

Nieustannie pojawiający się termin literał funkcyjny (ang. function literal) zmusił mnie w końcu do spędzenia kilku chwil, aby dowiedzieć się, cóż takiego ten termin znaczy. Czym różni się definicja funkcji od literału funkcyjnego? A może ma to związek z funkcją anonimową?! I jeśli w ogóle istnieje różnica, jakie są zalety stosowania jednego nad drugie, a może i trzecie?

W artykule Literal (computer programming) na Wikipedii napisano:

"In computer science, a literal is a notation for representing a fixed value in source code."

Początkowo nie było to zbyt wymowne. Szczęśliwie, stan ten nie trwał długo i dodatkowych kilka źródeł pozwoliło mi w końcu zrozumieć pojęcie literału funkcyjnego.

W artykule Anonymous function na Wikipedii (przekierowuje z artykułu o literale funkcyjnym) napisano:

"In computer programming, an anonymous function (also function constant, function literal, or lambda function) is a function (or a subroutine) defined, and possibly called, without being bound to an identifier."

I dalej, w rozdziale 8 "Functions and Closures" w dostępnej bezpłatnie książce Programming in Scala, First Edition znajdziemy taki paragraf:

"A function literal is compiled into a class that when instantiated at runtime is a function value.[2] Thus the distinction between function literals and values is that function literals exist in the source code, whereas function values exist as objects at runtime. The distinction is much like that between classes (source code) and objects (runtime)."

Zatem literał to wartość, co w przypadku literałów funkcyjnych jest wartością (instancją) funkcyjną. Podobnie jak 5 jest literałem liczbowym dla typu Integer, albo "ciąg znaków" dla typu String, tak x => x * 2 lub (x, y) => x * y jest literałem funkcji jedno- i dwuargumentowej. Scala wspiera programowanie funkcyjne przez możliwość operowania funkcjami - przekazywanie jako wartość wejściowa (parametr wejściowy funkcji), czy wyjściowa (parametr zwracany przez funkcję) lub przypisanie do zmiennej (nadanie funkcji nazwy) i literał funkcyjny (na wejściu, wyjściu i podczas przypisania) tworzy się przez użycie znaku implikacji =>.

Warto zauważyć, że wielu mogłoby przyrównywać literał do stałej lub wręcz zmiennej. Tutaj ponownie za pomoc można uznać artykuł Literal (computer programming) na Wikipedii:

"In contrast to literals, variables or constants are symbols that can take on one of a class of fixed values, the constant being constrained not to change."

Bardziej to teoretyczne rozważania niż praktyczna wiedza, ale kto wie, czy i gdzie przyjdzie nam ją użyć. Wiedza uskrzydla, a poznanie znaczenia dość powszechnie używanego pojęcia pozwoli na zrozumienie czytanego tekstu i sprawną komunikację. Powodzenia przy praktycznym użyciu literałów funkcyjnych w Scali!