Elm

Elm היא שפת תכנות, שמותאמת ספציפית ליצירת ממשקי משתמש גרפיים (GUI) לדפדפני אינטרנט. היא נוצרה בשנת 2012 על ידי אוון קזאפליקי (Evan Czaplicki), במסגרת עבודת התזה שלו. Elm היא שפת תכנות פונקציונלית, ופותחה תוך מתן דגש על שימושיות, ביצועים, ויכולות להתמודד עם שגיאות (robustness). בעמוד הבית של השפה, מובטח שלא תהיינה שגיאות בזמן ריצה, תודות לבדיקת הטיפוסים של המהדר של Elm. 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 היא דפוס ליצירת אפליקציות web אינטראקטיביות. אפליקציות ב-Elm בנויות כך באופן טבעי, אך סוגים אחרים של פרויקטים יכולים להשתמש בשיטה זו, בשל יעילותה. תוכנה ב-Elm מחולקת ל-3 חלקים: Model, View ו-Update (בקיצור : MVU). ה-Model אחראי על מצב האפליקציה, ה-View אחראי על החזרת המודל לתוך קובץ ה-HTML (דף האינטרנט), וה-Update מעדכן את ה-Model באמצעות שליחת הודעות אליו. קונספט זה מזכיר את תבנית Model-View-Controller (או בקיצור, MVC), אשר פופולרית בתכנות אפליקציות עם ממשקי משתמש גרפיים (GUI). בארכיטקטורת Elm, שליחת הודעות ל-Update היא הדרך היחידה לשנות את מצב האפליקציה. באפליקציות מורכבות יותר, הודעות ל-Update יכולות להגיע ממקורות שונים: אינטראקציה עם המשתמש, אתחול המודל, תגובה לאירועים (events) חיצוניים כגון שינוי גודל החלון ושעון המערכת, וכדומה. Elm לא תומכת ביצירת מחלקות, ולפיכך לא תומכת בעיקרון הפולימורפיזם המתבטא ביצירתן, כגון יצירת פונקציות אשר פועלות על מספר מחלקות המקיימות ממשק או יורשת ממחלקת אב מסוימת, או פעולות גנריות אשר יכולות לקבל כל סוג נתונים. לדוגמה, ב-Elm אין פעולת map גנרית, אשר מקבלת מבנה נתונים ופעולה, ומבצעת את הפעולה על כל אחד מהאיברים. במקום, ישנן פעולות ספציפיות לכל סוג נתונים, אשר רצות משם המודול של סוג הנתונים. לדוגמה, על מנת להריץ את פעולת ה-map ב-List וב-Set נקרא לפעולות 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 אתר האינטרנט הרשמי של Elm (באנגלית) Elm, ברשת החברתית אקס (טוויטר) Evan Czaplicki, Elm: Concurrent FRP for Functional GUIs, elm-lang.org, 30 במרץ 2012 ספריות קוד ב-Elm שנוצרו על ידי הקהילה (ארכיון) Set הוא מבנה נתונים שבו לכל איבר ישנו מופע אחד. כלומר, אין חזרה על איברים.