Skip to content

Witaj w Świecie Jutra!

  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
  • Home
  • Wszystko
  • Programowanie funkcyjne – wstęp
  • Programowanie
  • Wszystko

Programowanie funkcyjne – wstęp

Jakub Raczkowski 21 marca 2024

Tokarka przy pracy widziana "oczami" AI

Dawno, dawno temu… Za górami za lasami… W małym bieszczadzkim miasteczku pewien młody, pełen zapału chłopak odebrał swój upragniony dyplom inżyniera. Od teraz mógł projektować własne śrubki w AutoCAD’zie i samemu programować tokarki. Młodzieniec jeszcze wtedy nie wiedział, że to wszystko do niczego mu się w życiu nie przyda.

…aż do teraz.

Aby nadać kontekst dzisiejszemu wpisowi zacznijmy od małego wyjaśnienia przestoju na blogu. W chwili kiedy to piszę jestem w trakcie poznawania tajników frameworka Spring. Czytam książki, oglądam filmy, robię kurs i piszę własne przykłady. Jako, że mamy tu do czynienia z wiedzą całkiem zaawansowaną, to programiści od których ją pozyskuję do żółtodziobów nie należą; tworzą kod wysokiej jakości, bogaty w przeróżne skrótowce i biblioteki nieznane początkującym. Bardzo często korzystają z tzw. „programowania funkcyjnego” aby kosztem zwiększenia abstrakcyjności zyskać na zwięzłości kodu (czyli: „łatwiej się kod czyta, ale trudniej zrozumieć jak działa”).

Ale czym tak właściwie jest to „programowanie funkcyjne”?

FP (dalej będę posługiwał się tym skrótem odnoszącym się do angielskiej nazwy: Functional Programming) jest tak jakby przeciwieństwem OOP (Object Oriented Programming – Programowanie Zorientowane Obiektowo). Pisząc krótko:

OOP koncentruje uwagę na obiektach, a FP na funkcjach – czyli to co z tymi obiektami robimy.

Aby w pełni zrozumieć różnice obu podejść, będą potrzebne solidne przykłady, ale nie byłbym sobą gdybym nie zaczął od suchara dla rozluźnienia napięcia:

Do biura patentowego zgłasza się wynalazca. Przyniósł ze sobą pudełko z owalnym otworem. Kiedy urzędnik zapytał się co to jest, ten z uśmiechem odpowiada, że to nowoczesna maszyna do golenia. Najpierw przykłada się twarz do otworu, następnie wciska przycisk na obudowie, a system brzytew szybko pozbędzie się niechcianego zarostu.
Usłyszawszy te wyjaśnienia, urzędnik jest zaintrygowany, ale docieka szczegółów:
– No dobrze, ale jak to ma działać skoro każdy ma inne rysy twarzy?
Na co projektant wynalazku odpowiada, szczerze i z uśmiechem:

– Ach, tylko do pierwszego golenia!

W tej małej anegdotce mamy już pierwsze wskazówki jak wyglądają różnice pomiędzy OOP i FP. Programowanie obiektowe to profesjonalny golibroda/barber który inaczej podejdzie do każdego klienta, tymczasem programowanie funkcyjne to ta magiczna maszynka, która każdego opitoli na jedno kopyto.

Ale, ale! Ktoś może pomyśleć – acha, czyli OOP jest dobre, bo precyzyjne, a FP złe bo zautomatyzowane. No nie do końca.

Wyobraźmy sobie taśmę produkcyjną której zadaniem jest produkcja kostek do gry. Stoi przy niej 6 pracowników, każdy z własną wypalarką: do strony z jednym oczkiem, z dwoma i tak dalej aż do sześciu. Każda osoba ma jedno i tylko jedno zadanie – podniesienie kostki, przyłożenie wypalarki do odpowiedniej strony i odłożenie kostki z powrotem na taśmę, tak aby kolejna osoba mogła ozdobić następną ściankę.

I tak to idzie przez cały dzień, a ludzie jak to ludzie mają swoje charaktery i potrzeby. Gość od ścianki z trzema oczkami poszedł „na dwójkę” i produkcja stanęła na kilkanaście minut. Potem pracownik odpowiedzialny za „cztery oczka” doszedł do wniosku, że on swoją robotę robi bardzo szybko i w sumie to może od razu robić po dwie kostki na raz, z czego tę drugą bierze zanim jeszcze dostała jakiekolwiek wcześniejsze oczka, a potem jego poprzednicy nie wiedzą z której strony zacząć i zaczyna się kłótnia.

Linia produkcji kostek do gry, autorstwa AI.

Tymczasem na sąsiedniej, eksperymentalnej linii wszystko robią maszyny. Z boku taśmociągu wystaje ramię z podłączoną wypalarką. Nachyla się na ustawioną wcześniej wysokość kostki i gdy ta przesuwając się na linii najeżdża na chwytak, zostaje automatycznie umieszczona w kleszczach, dociśnięta wypalarką, obrócona na kolejną ściankę do obrobienia i wypuszczona. Maszyny po prostu wykonują zadane wcześniej polecenia, przesuwają się tam gdzie im kazano, a to czy obiekt kostki trafi do podajnika nie znajduje się na liście ich problemów.

Jak mogliście się domyślić, każda osoba czy każde ramię maszyny to osobny wątek – w OOP musimy bardzo uważać żeby wątki się nie poplątały, stosować synchronizowane bloki, „atomowe” zmienne, dodatkowe warunki itp. Tymczasem FP jest z natury przyjazne pracy w środowisku wielowątkowym. Zobaczmy to na prostym przykładzie w Javie:

Dwie klasy i dwa różne podejścia do programowania.

Kod nie jest wymagający: mamy tutaj liczbę, która przyjęła postać obiektu typu „ObjectProgramming” który charakteryzuje się tylko tą wartością liczbową wstrzykniętą do konstruktora. Dostajemy również metodę „increment(int anyNumber)” która zwiększa wartość naszej jedynej zmiennej o nową wartość.

Z drugiej strony mamy klasę „FunctionalProgramming” która nie posiada żadnych swoich zmiennych, a jedynie metodę „sum(int number1, int number2)„. Jeśli użyjemy tych metod jednokrotnie z tymi samymi zmiennymi to wynik zawsze będzie ten sam:

ObjectProgramming oop = new ObjectProgramming(0);
oop.increment(1);
int a = oop.value;
int b = FunctionalProgramming.sum(0,1);

a == b;

Kiedy jednak operacje zostaną powtórzone, to widzimy, że obiekt „oop” zachowuje swój stan, natomiast funkcja sum() wciąż zwraca to samo. „Akcja” zaczyna się jednak dopiero gdy wpuścimy na arenę dodatkowe wątki, które będą ze sobą konkurować o dostęp do obiektu i próbować łapać go jeszcze zanim ich poprzednik ukończył swoją „obróbkę”;

Jak widać w konsoli – programowanie funkcyjne zawsze zwraca ten sam wynik, w przeciwieństwie do operacji na obiektach.

Ale czy każdy program można pisać samymi funkcjami?

Biorąc na tapet mój wcześniejszy projekt „ITCandidateEvaluator”, teoretycznie byłoby to możliwe. Tam wszystko obraca się wokół kandydatów, a dokładnie ich obiektów opisywanych takimi zmiennymi jak imię, wiek, data ewaluacji czy wynik. Podsumowując: same litery i cyfry. Umieszczając je w bazie danych i dokonując odpowiednich zapytań SQL-owych, inkrementacji i konkatenacji mógłbym sprawić, że klasa Kandydat stałaby się zbędna i została zastąpiona jakąś klasą typu Helper, bez zmiennych, za to ze statycznymi metodami przeliczającymi dane i aktualizującymi rekordy w bazie danych.

Pytanie: Co bym w ten sposób zyskał?

Cóż, bezpieczną pracę wielowątkową.. która w tym projekcie była mi jak psu na budę. Zbędna. Za to straciłbym kupę czasu na wymyślanie koła na nowo, kod byłby trudny do zrozumienia, wyjątkowo nieintuicyjny.

Programując maszyny CNC takie jak tokarki, frezarki, czy bardziej nowocześnie: drukarki 3D musimy myśleć funkcyjnie: ten element przesuń na pozycję (x,y,z) na czas t, następnie tamten element przesuwaj do góry po osi pionowej przy prędkości ustawionej na v, itd. To jaki obiekt właśnie obrabiamy nie musi być uwzględniane w kodzie.

Przeciwieństwem powyższego niech będzie gamedev, gdzie pisanie kodu fuknkcyjnie byłoby prostą drogą do obłędu. Jeszcze platformery z ludzikami z patyczków biegnącymi do przodu jakoś by się dało zakodować. Ale coś poważniejszego? Bronie, czary, postacie niezależne, elementy otoczenia, interfejs… to wszystko to są obiekty, które mają jakiś stan i opisujące go zmienne.

Podsumowując

Próbując pójść na zdrowy kompromis dokopujemy się do elementów programowania funkcyjnego wprowadzonego w Javie, wersji ósmej z 2014 roku. Lambdy, interfejsy funkcyjne, referencje metod, wreszcie strumienie.

Z wszystkimi tymi rzeczami miałem już styczność, ale do ich zmasterowania jeszcze mi daleko. Stąd pomysł na ten mini cykl gdzie po kolei – od przedstawienia paradygmatu w niniejszym tekście, aż po Stream API przekopiemy się szukając zrozumienia i nabrania wprawy w użytkowaniu owych narzędzi.

Bo temat nie jest łatwy.

Łatwo, to jest posłuchać Intellij’a i kliknąć „zamień na wyrażenie lambda” kiedy ci podpowiada w podobny sposób co ja swojej córce, która zapomniała do kwiatka dorysować listków. Tak to każdy potrafi. To, zaś co odróżnia profesjonalistę od „każdego”, to świadome korzystanie z wybranego narzędzia, z konkretnego powodu.

A czy ty też chcesz zostać profesjonalistą?

Jeśli, tak jak ja, też chcecie być profesjonalistami to zapraszam do kolejnego artykułu, poświęconego lambdzie, gdzie nauczymy się samodzielnie (i świadomie!) wstawiać „strzałeczki”.

To, co? Strzałeczka i do zobaczenia w następnym odcinku!

Tags: functional programming

Continue Reading

Previous: ITCandidateEvaluator – Podsumowanie
Next: Programowanie funkcyjne – Lambda

Related Stories

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025

Ze świata

  • Antyweb
  • Kwantowo
  • Dwóch po dwóch
Nowy iPhone rozładowywał się przez noc. Skuteczna okazała się tylko jedna procedura
To jeden z największych problemów na polu walki. Firma z USA wie, jak go rozwiązać
Zostawiasz ładowarkę w gniazdku? Sprawdź, ile prądu naprawdę zużywa
Nie działa Ci ChatGPT? W usługę trafiła poważna awaria
Xbox szuka sposobu na odbicie się od dna. Lekarstwem ma być ostatnia decyzja
Google Pixel 11a już bez tajemnic. Kilka kluczowych zmian
Garmin wydłuża czas pracy zegarków. Tę aktualizację warto pobrać
LEGO przygotowało prawdziwą ucztę dla kolekcjonerów. Ten zestaw zachwyca od pierwszego spojrzenia
Sony wyciska użytkowników PlayStation od lat. Dziw, że dopiero teraz zauważyliście
YouTube rozczarowuje użytkowników. Wszystkiemu winien nowy błąd
Śpisz z telefonem przy poduszce? Lepiej odłóż go w inne miejsce
Stworzył fizyczne wydania gier na Steama. Są dostępne na "kartridżach"
Złoto na strychu? Te stare telefony mogą być dziś warte fortunę
Thule EnRoute 12L – recenzja. Wypełnia lukę między nerką, a plecakiem podróżnym
HP blokuje nawet oryginalne tusze? Kontrowersje wokół aktualizacji drukarek narastają
"Polski ChatGPT" goni najlepszych. Jest świetny, ale ja nie kupuję w nim jednej rzeczy
Chcesz jeść mniej? Lepiej tak nie rób. Naukowcy obalili popularny mit
Spotify nadrabia zaległości. Potrzebna opcja trafi do aplikacji
Ta platforma VOD kpi sobie z Polaków. Nie tak to miało wyglądać
Garmin CIRQA na pierwszym zdjęciu. Premiera tuż za rogiem
SpudCell – syntetyczna komórka, która udaje życie
Mega upał, omega manipulacja
Coraz więcej dowodów, coraz mniej pewności
Matematyczno-restauracyjny dylemat Ryszarda
Silnik produkujący informacje zamiast spalin
Orzeczenie w sprawie En Arche v. Adam Adamczyk
To by było na tyle, jeśli chodzi o możliwość ugody z kreacjonistami
Ocalić od zapomnienia
Ostatni kwant
ALH 84001 – meteoryt, o którym mówiono nawet w Białym Domu
Tańszy Game Pass, droższy Steam Deck i Internet 0202122 – Odcinek #135
Elite Dangerous. Gra, z której odchodzi się po cichu
Gry zasługujące na adaptację filmową – Odcinek #134
Relacja z RePlay Fest 2026
Najlepsze intra i openingi w grach – Odcinek #133
AI, Star Trek, Rycerz Siedmiu Królestw, Festiwal dem na Steam Next Fest – Odcinek #132
Gry, filmy i seriale w 2025 i 2026 roku – Odcinek #131
30 lat konsoli PlayStation – Odcinek #130
Omawiamy serię The Walking Dead (gość: Stary Gracz)
Nikt nie potrzebuje cienkich smartfonów – Odcinek #129

To może cię zainteresować:

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025
Czym jest Swagger?
  • Programowanie

Czym jest Swagger?

22 lipca 2024
  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
Copyright © All rights reserved. | DarkNews by AF themes.