Funksional proqramlaşdırma nədir və nə üçün vacibdir?
Funksional proqramlaşdırmadan elə danışırlar ki, sanki bu, dil nəzəriyyəçiləri üçün akademik məşğələdir. Bu isə təəssüf doğurur, çünki onun əsasında duran ideya həqiqətən praktikdir: kodunuzda gözlənilmədən dəyişə bilən şeylər nə qədər az olsa, arxasınca qaçmalı olduğunuz xətalar da bir o qədər az olar. Vəssalam. Qalan hər şey detallardır.
Əsas ideya: saf funksiyalar
Saf funksiya eyni giriş verildikdə həmişə eyni nəticəni qaytaran və bunu edərkən özündən kənarda heç nəyi dəyişməyən funksiyadır. Qlobal dəyişəni dəyişdirmək yoxdur, verilənlər bazasına yazmaq yoxdur, günün saatından asılılıq yoxdur. Sadəcə: giriş daxil olur, nəticə çıxır, başqa heç nə baş vermir.
Bunu obyektyönümlü kod bazasındakı tipik funksiya ilə müqayisə edin: o, verilənlər bazasından oxuya, paylaşılan obyekti dəyişdirə, jurnala nəsə yaza və dəyər qaytara bilər — eyni anda dörd fərqli iş baş verir, onların hər biri səhv gedə bilər və heç biri funksiyanın çağırıldığı yerə baxmaqla aydın görünmür.
Dəyişməzlik: dəyişməyən verilənlər
Funksional proqramlaşdırma həm də dəyişməz verilənlərə böyük əhəmiyyət verir — dəyəri yaratdıqdan sonra onu yerindəcə dəyişdirmirsiniz. Dəyişdirilmiş versiya lazımdır? Əvəzində yenisini yaradırsınız. Bu, israfçılıq kimi səslənir, ta ki alternativi nəzərdən keçirənə qədər: verilənlərin on müxtəlif yerdən dəyişdirilə bildiyi kod bazasında xətaya hansının səbəb olduğunu tapmaq üçün onunu da yoxlamalısınız. Verilənlərin yaradıldıqdan sonra dəyişdirilə bilmədiyi kod bazasında isə bu xəta kateqoriyası sadəcə mövcud deyil.
Bu, gündəlik işdə niyə həqiqətən vacibdir
- Test etmək daha asandır. Saf funksiya girişlərindən başqa heç bir hazırlıq tələb etmir — verilənlər bazasını imitasiya etmək, cari vaxtı saxtalaşdırmaq lazım deyil. Çağırırsınız, nəticəni yoxlayırsınız.
- Anlamaq daha asandır. Funksiyanın nə etdiyini onu oxumaqla başa düşə bilərsiniz — onun verilənlərinə başqa nəyin toxuna biləcəyini görmək üçün kod bazasının qalan hissəsini izləməyə ehtiyac yoxdur.
- Daha təhlükəsiz paralellik. Paralellik xətalarının böyük hissəsi iki şeyin eyni verilənləri eyni vaxtda dəyişdirməsindən yaranır. Dəyişməz verilənlər bu xəta sinfini struktur baxımından qeyri-mümkün edir.
- Daha proqnozlaşdırıla bilən sazlama. Vəziyyət gözlənilmədən dəyişə bilmədikdə «bu dəyər niyə dəyişdi?» sualının mümkün cavabları siyahısı xeyli qısalır.
Faydalanmaq üçün «funksional dil» lazım deyil
Haskell və Clojure kimi dillər əsasdan funksional proqramlaşdırma üzərində qurulub, lakin bu ideyalardan real fayda götürmək üçün dili dəyişməyə ehtiyac yoxdur. JavaScript, Python, Java və əksər müasir dillər saf funksiyalar yazmağı və məqsədəuyğun olan yerdə verilənlərə dəyişməz kimi yanaşmağı dəstəkləyir — map, filter və reduce kimi massiv metodları əslində maskalanmış funksional proqramlaşdırmadır və əksər proqramçılar bunu belə adlandırmadan onlardan daim istifadə edir.
Praktik nəticə «hər şeyi funksional üslubda yenidən yazın» deyil. Nəticə belədir: dizaynı əyib-bükmədən funksiyanı saf, verilənlərini isə dəyişməz edə bildiyiniz yerdə bunu edin. Gözləmədiyiniz bir yerdə dəyişmiş vəziyyəti sazlamağa ölçüləcək dərəcədə az vaxt sərf edəcəksiniz.
Hazırladığımız fərdi proqram təminatına bu prinsipləri məhz ona görə tətbiq edirik ki, test edilməsi və anlaşılması daha asan olan kod canlı mühitdə daha az sınır — bu isə müştəri üçün ilk gün yox, istifadəyə verildikdən altı ay sonra daha çox əhəmiyyət kəsb edir.