Elm

Elm היא שפת תכנות פונקציונלי המתקמפלת ל-JavaScript על ידי המהדר של Elm ומותאמת באופן ייחודי לפיתוח אתרים ויישומים אינטראקטיביים עבור דפדפני אינטרנט כולל יצירת ממשקי משתמש גרפיים (GUI). השפה פותחה על בסיס תפיסה איכותית ודגש על פשטות, שימושיות, ביצועים, ויציבות בזמן ריצה. שפת התכנות Elm כשפת תכנות בסגנון של תכנות פונקציונלי מאופיינת במינימום שגיאות בזמן ריצה בפועל, הודעות שגיאה ידידותיות, עיבוד מחדש אמין וניהול גרסאות סמנטיות נאכף אוטומטית עבור כל חבילות Elm. השפה נוצרה בשנת 2012 על ידי אוון קזאפליקי (Evan Czaplicki) במסגרת עבודת התזה שלו.

 היסטוריה 
Elm תוכננה במקור בשנת 2012 על ידי אוון קזאפליקי במסגרת התזה שלו. הגרסה הראשונה של Elm הגיעה עם דוגמאות קוד רבות ועורך קוד מקוון. אוון הצטרף ל-Prezi בשנת 2013 על מנת לעבוד שם בפיתוח Elm, ובשנת 2016 עבר ל-NoRedInk כמפתח קוד פתוח. באותה השנה גם הקים את הארגון "Elm Software Foundation".

המימוש הראשוני של המהדר של Elm התמקד ב-HTML, CSS ו-Javascript. סט הכלים של השפה הורחב, ונוספו REPL (כתיבת קוד בקונסולה באמצעות הרצה של שורה אחר שורה, או בשמה המלא: Read Eval Print Loop), מנהל חבילות, דיבאגר (מנפה שגיאות) שניתן להריצו גם לאחור, ומתקינים לשפה אשר זמינים למערכות ההפעלה macOS ו-Windows. בנוסף, ל-Elm יש ספריות קוד אשר נוצרו על ידי הקהילה , וכן עורך קוד מקוון מתקדם – Ellie, שניתן לשמור בו עבודה ולייבא ספריות קוד שיצרה הקהילה.

 ארכיטקטורת Elm 
ארכיטקטורת Elm מבוססת תבנית ליצירת תוכנות אינטראקטיביות כגון אפליקציות אינטרנטיות ומשחקים. תוכנה ב-Elm מחולקת ל-3 חלקים: View ,Model ו-Update (בקיצור: MVU). תוכנות ב-Elm בנויות כך באופן טבעי, אך סוגים אחרים של פרויקטים (בעיקר front-end) יכולים גם להשתמש בשיטה זו, בשל יעילותה. ה-Model אחראי על מצב האפליקציה, ה-View אחראי על החזרת המודל לתוך קובץ ה-HTML (דף האינטרנט), וה-Update מעדכן את ה-Model באמצעות שליחת הודעות אליו. רעיון זה מזכיר את תבנית Model-View-Controller (או בקיצור, MVC), אשר פופולרית בתכנות אפליקציות עם ממשקי משתמש גרפיים (GUI).

בארכיטקטורת Elm, שליחת הודעות ל-Update היא הדרך היחידה לשנות את מצב התוכנה/אפליקציה. באפליקציות מורכבות יותר, הודעות ל-Update יכולות להגיע ממקורות שונים: אינטראקציה עם המשתמש, אתחול המודל, תגובה לאירועים (events) חיצוניים כגון שינוי גודל החלון ושעון המערכת, ועוד.

 מגבלות השפה 
Elm לא תומכת ביצירת מחלקות, ולפיכך לא תומכת בעיקרון הפולימורפיזם המתבטא ביצירתן, כגון יצירת פונקציות אשר פועלות על מספר מחלקות המקיימות ממשק או יורשת ממחלקת אב מסוימת, או פעולות גנריות אשר יכולות לקבל כל סוג נתונים. לדוגמה, ב-Elm אין פעולת map גנרית, אשר מקבלת מבנה נתונים ופעולה, ומבצעת את הפעולה על כל אחד מהאיברים. במקום, ישנן פעולות ספציפיות לכל סוג נתונים, אשר רצות משם המודול של סוג הנתונים. לדוגמה, על מנת להריץ את פעולת ה-map ב-List וב-SetSet הוא מבנה נתונים שבו לכל איבר ישנו מופע אחד. כלומר, אין חזרה על איברים. נקרא לפעולות List.map ו-Set.map בהתאמה. לעומת זאת, בשפות פונקציונליות אחרות כגון Haskell או PureScript, ישנה פעולת Set אחת לכל סוגי הנתונים. בשל כך, קיבל קזאפליקי (מפתח השפה) בקשות ליצירת פיצ'ר שכזה ב-Elm משנת 2015 והלאה (ייתכן שמוקדם יותר). בנוסף לכך, כפי שהוצג על ידי כותב הספר "Elm In Action", בפרויקטים גדולים נדרשת חזרה על מקטעי קוד דומים ואף זהים, וכך המתכנת נדרש לכתוב קוד רב, עבור עבודה יחסית מועטה. מקטעי קוד אלו נקראים boilerplate code .

 דוגמאות קוד 
-- This is a single line comment

{- This is a multi-line comment.
 It can span multiple lines.
-}

{- It is possible to {- nest -} multi-line comments -}

-- Here we define a value named ''greeting''. The type is inferred as a String.
greeting =
 "Hello World!"

 -- It is best to add type annotations to top-level declarations.
hello : String
hello =
 "Hi there."

-- Functions are declared the same way, with arguments following the function name.
add x y =
 x + y

-- Again, it is best to add type annotations.
hypotenuse : Float -> Float -> Float
hypotenuse a b =
 sqrt (a^2 + b^2)

-- Functions are also curried; here we've curried the multiplication
-- infix operator with a `2`
multiplyBy2 : number -> number
multiplyBy2 =
 (*) 2

-- If-expressions are used to branch on values
absoluteValue : number -> number
absoluteValue number =
 if number < 0 then negate number else number

 -- Records are used to hold values with named fields
book : { title : String, author : String, pages : Int }
book =
 { title = "Steppenwolf"
, author = "Hesse"
, pages = 237
 }

-- Record access is done with `.`
title : String
title =
 book.title

-- Record access `.` can also be used as a function
author : String
author =
 .author book

-- We can create entirely new types with the `type` keyword.
-- The following value represents a binary tree.
type Tree a
 = Empty
 | Node a (Tree a) (Tree a)

-- It is possible to inspect these types with case-expressions.
depth : Tree a -> Int
depth tree =
 case tree of
 Empty ->
 0

 Node value left right ->
 1 + max (depth left) (depth right)

 ראו גם 
 Ocaml
 F#
 Haskell

 קישורים חיצוניים 


הערות שוליים

קטגוריה:שפות תכנות פונקציונליות
קטגוריה:תוכנות שהושקו ב-2012