תכנות פונקציונלי – הבדלי גרסאות

תוכן שנמחק תוכן שנוסף
מ תקלדה
דוגמאות לפונקציות ממעלה גבוהה
שורה 13:
 
ישנו דמיון מסוים בין תכנות פונקציונלי ל[[תכנות לוגי]], אך האחרון עוסק במבנים כלליים יותר - [[יחס]]ים מול [[פונקציה|פונקציות]] שהן מקרה פרטי של יחסים.
 
תכנות פונקציונלי נקרא "טהור" אם אין בו שינוי מצב, כלומר אין בו [[משתנה (תכנות)|משתנים]] או אובייקטים שמשנים את מצבם הפנימי. כל עיבוד מידע נעשה על ידי יצירת ערכים חדשים כנדרש. כתיבה כזו מקלה על הוכחות נכונות ה[[תוכנה]] ביחס למפרטיה. שינוי מצב של המערכת נקרא "תופעות לוואי". מכיוון שכל תקשורת של תוכנית עם העולם החיצון (קלט/פלט) משנה מצב של אובייקט ומסיבות נוספות, של נוחות או יעילות, גם שפות פונקציונליות "טהורות" כוללות תופעות לוואי, אך חלקן מרכזות את המבנים בעלי "תופעות הלוואי" במקום מוגדר, לדוגמה, במבנה שנקרא [[מונדה (מדעי המחשב)|מונדה]].
 
== פונקציות כערכים לכל דבר ==
פונקציות בשפות פונקציונלית הן עצמים בעלי קיום בלתי תלוי משל עצמם, כלומר הן [[ערך (מדעי המחשב)|ערכים]] לכל דבר, כמו [[מספר|מספרים]] או מחרוזות. ניתן לשלוח אותן לפונקציות אחרות כפרמטרים, והן יכולות לשמש כערכי החזרה.
 
===העברת פונקציה כפרמטר===
תכנות פונקציונלי נקרא "טהור" אם אין בו שינוי מצב, כלומר אין בו [[משתנה (תכנות)|משתנים]] או אובייקטים שמשנים את מצבם הפנימי. כל עיבוד מידע נעשה על ידי יצירת ערכים חדשים כנדרש. כתיבה כזו מקלה על הוכחות נכונות ה[[תוכנה]] ביחס למפרטיה. שינוי מצב של המערכת נקרא "תופעות לוואי". מכיוון שכל תקשורת של תוכנית עם העולם החיצון (קלט/פלט) משנה מצב של אובייקט ומסיבות נוספות, של נוחות או יעילות, גם שפות פונקציונליות "טהורות" כוללות תופעות לוואי, אך חלקן מרכזות את המבנים בעלי "תופעות הלוואי" במקום מוגדר, לדוגמה, במבנה שנקרא [[מונדה (מדעי המחשב)|מונדה]].
פונקציה המקבלת פונקציה כפרמטר נקראת "פונקציה מסדר גבוה". שלוש דוגמאות לפונקציות חשובות מסדר גבוה: map, filter, reduce.
 
* map, המקבלת פונקציה ורשימה, ומפעילה את הפונקציה על כל איבר ברשימה. הקוד הבא בשפת ML מגדיר פונקציה המעלה את הפרמטר שלה בריבוע, ומעביר אותו לmap:
<source lang="ocaml">
- fun square x = x*x;
val square = fn : int -> int
- map square [1,2,3];
val it = [1,4,9] : int list
</source>
* filter, המקבלת פונקציה p (המחזירה true/false) ורשימה, ומחזירה רשימה ללא האיברים עבורן הפונקציה p החזירה false. דוגמה בשפת ML:
<source lang="ocaml">
- fun odd x = x mod 2 = 0;
val odd = fn : int -> bool
- List.filter odd [1,2,3,4];
val it = [2,4] : int list
</source>
* reduce (או foldl, קיצור של fold left), המקבלת אופרטור בינארי op, איבר אדיש a0, ורשימה של איברים a1, a2,... an, ומחזירה את תוצאת הפעולה a0 op a1 op a2... op an:
<source lang="ocaml">
- foldl op+ 0 [1,2,3,4];
val it = 10 : int
</source>
=== List Comprehension ===
שימוש משולב בפונקציות map ו-filter יחד עם ביטויי למבדא הוא נפוץ כל כך שבשפות מסויימות קיים תחביר מיוחד עבורו. אם בשפת ML כותבים:
<source lang="ocaml">
map (fn x => x*x) (List.filter (fn x => x mod 2 = 0) [1,2,3,4]);
</source>
אזי בשפת Haskell ניתן לכתוב בצורה המזכירה הגדרה מתמטית של [[קבוצה (מתמטיקה)|קבוצה]] (האופרטור -> מסמן שייכות):
<source lang="haskell">
[ x*x | x <- [1,2,3,4], x `mod` 2 == 0 ]
</source>
המבנה הופיע לראשונה בשפת [[NPL (שפת תכנות)|NPL]] והוא קיים, בין היתר, בשפות [[Haskell]],{{כ}} [[Erlang]]{{כ}}, [[F#|#F]], ואף בשפות לא פונקציונליות ביסודן כגון [[פייתון (שפת תכנות)|פייתון]], [[C#|#C]] (כחלק מ Linq).
== דוגמאות ==