14 סיבות מצוינות לשימוש ב- F #

F # היא שפת תכנות מוקלדת מאוד, פונקציונאלית, המאפשרת לך לפתור בעיות מורכבות על ידי כתיבת קוד פשוט. מבוסס על ML ובנוי על .NET Framework, F # מציע יכולת פעולה הדדית טובה, ניידות ומהירות זמן ריצה, כמו גם את "חמשת ה- Cs" - נוחות, נוחות, נכונות, מקביליות ושלמות.

F # היה בתחילה זמין רק ב- Windows, כפרויקט Microsoft Research, אך כעת זו שפה מהשורה הראשונה במספר פלטפורמות. אתה יכול להשתמש ב- F # ב- Mac ובלינוקס עם תמיכה בכלי ב- Xamarin Studio, MonoDevelop, Emacs ואחרים; ב- Windows עם Visual Studio, Xamarin Studio ו- Emacs; ובמכשירי Android ו- iOS ובאינטרנט באמצעות HTML5. בנוסף לתכנות למטרות כלליות, F # חל על קוד GPU, ביג דאטה, משחקים ועוד.

מדוע להשתמש ב- F #? תן לי לתת לך 14 סיבות.

F # הוא אינטראקטיבי

אחד היתרונות של F # הוא שיש לו REPL אינטראקטיבי (קריאה, הערכה, הדפסה, לולאה) שבו אתה יכול לנסות את הקוד, כפי שמוצג בתמונת המסך למטה. עם כיוון השעון, מלמעלה משמאל, אנו רואים F # חלונות אינטראקטיביים מ- Visual Studio ב- Windows, מ- TryFSharp הפועל ב- Chrome ומ- Xamarin Studio פועל ב- Mac OS X. הדבר ;;אומר ל- F # Interactive להעריך מה הקלדת; ב- TryFSharp כפתור "הפעלה" שולח את אותו האות. שימוש ב- REPL כדי לאסוף ולבדוק קוד לפני שהוא נכנס לתוכנית מלאה גם מאיץ את הפיתוח וגם מפחית באגים.

F # מיועד לתסריט

F # יכול לשמש כשפת תסריט כמו גם כשפת תכנות. להלן נראה מדגם Visual Studio בו סקריפט F # טוען ארבעה קבצי F # ותפתח שתי ספריות .NET לפני ביצוע קוד משלו. הסימון [|…|]המשמש כאן מכריז על מערך. הסימון |>הוא צינור קדימה, המעביר את תוצאת הצד השמאלי לפונקציה בצד ימין. השורות החדשות כאן אינן משמעותיות מבחינה תחבירית. הם פשוט הופכים את הקוד לקל יותר לקריאה מאשר ביטויי צינור שלמים בשורה אחת.

F # הוא פונקציונלי

F # תומך במבני תכנות פונקציונליים כגון התייחסות לפונקציות כאל ערכים, שימוש בפונקציות ללא שם בביטויים, קומפוזיציה של פונקציות ליצירת פונקציות חדשות, פונקציות קארי והגדרה מרומזת של פונקציות באמצעות יישום חלקי של ארגומנטים של פונקציות. בצילום המסך העליון שלמטה אנו מגדירים addפונקציה ומשתמשים בה . גוף הפונקציה מוטה (כמו Python) וסוגי הארגומנטים מוסברים כמספרים שלמים בגלל +האופרטור. בצילום המסך התחתון, אנו מספקים הסברים מסוג אחרי שם טיעון באמצעות נקודותיים שם סוג, כך F # יודע כי phraseהוא stringסוג.

F # הוא תמציתי

הקוד שלהלן הוא אלגוריתם דמוי Quicksort המיושם ב- F # (על ידי סקוט וולאשין). recהמילה מראה כי תפקידו הוא רקורסיבית. match..withהתחביר הוא switchהצהרה על סטרואידים, עם |מקרים מעידים. זה []מציין רשימה ריקה. firstElemו otherElementsנוצרים באופן אוטומטי.

שים לב שאין הצהרות סוג המוזכרות בשום מקום בקוד, כלומר הפונקציה יכולה למיין רשימות המכילות כל סוג התומך במפעילי השוואה. funמילת המפתח היא להגדרת תפקיד למבדה אנונימיים.

תן לרשימת המוצרים החוזרים

   רשימת התאמות עם

   | [] -> // אם הרשימה ריקה

        [] // להחזיר רשימה ריקה

   | firstElem :: otherElements -> // אם הרשימה אינה ריקה 

        תנו ל- smallerelements = // לחלץ את הקטנים יותר

            אלמנטים אחרים            

            |> List.filter (fun e -> e <firstElem)

            |> quicksort // ולמיין אותם

        תנו ל- LargeElements = // לחלץ את הגדולים

            אלמנטים אחרים

            |> List.filter (fun e -> e> = firstElem)

            |> quicksort // ולמיין אותם

        // שלב את 3 החלקים לרשימה חדשה והחזיר אותה

        List.concat [smallerElements; [firstElem]; Elements גדולים יותר]

//מִבְחָן

printfn "% A" (quicksort [1; 5; 23; 18; 9; 1; 3])

לשם השוואה, עיין בהטמעת ה- C # המסורתית להלן.

מחלקה ציבורית QuickSortHelper

{

   רשימה סטטית ציבורית QuickSort (ערכי רשימה)

      איפה T: IC השוואה

   {

      if (values.Count == 0)

      {

         להחזיר רשימה חדשה ();

      }

      // קבל את האלמנט הראשון

      T firstElement = ערכים [0];

      // להשיג את האלמנטים הקטנים והגדולים יותר

      var smallerElements = רשימה חדשה ();

      var largeElements = רשימה חדשה ();

      עבור (int i = 1; i <values.Count; i ++) // i מתחיל ב- 1

      {// לא 0!

         var elem = ערכים [i];

         אם (elem.CompareTo (firstElement) <0)

         {

            smallerElements.Add (elem);

         }

         אַחֵר

         {

            LargeElements.Add (elem);

         }

      }

      // להחזיר את התוצאה

      var result = רשימה חדשה ();

      result.AddRange (QuickSort (smallerElements.ToList ()));

      תוצאה.הוסף (firstElement);

      result.AddRange (QuickSort (largeElements.ToList ()));

      תוצאת החזרה;

   }

}

תוכלו להבחין בכמות נוספת של קוד C # בהשוואה לקוד F #. 

F # הוא ממש תמציתי

לדברי סקוט וולאשין, גרסת ה- Quicksort המוצגת להלן - כל ארבע השורות שלה - כוללת את המראה התמציתי האופייני של F # שנכתב על ידי קודן פונקציונאלי מנוסה. כמובן שהוא יהיה הראשון לציין שזה לא מסתדר במקום. לקח לי מספר קריאות כדי להבין את הקוד, אבל זה היה שווה את הזמן.

תן rec quicksort2 = פונקציה

   | [] -> []                        

   | ראשית :: מנוחה ->

        תנו למנוחה קטנה יותר, גדולה יותר = List.partition ((> =) ראשית)

        List.concat [quicksort2 קטן יותר; [ראשון]; quicksort2 גדול יותר]

// קוד בדיקה 

printfn "% A" (quicksort2 [1; 5; 23; 18; 9; 1; 3])

בקצרה, המקרה הראשון מחזיר רשימה ריקה אם היא עוברת, ומספקת קריטריון יציאה; המקרה השני מחלק את הרשימה לאלמנט הראשון ואת השאר, תוך הקצאת רשימת המשנה החל מהערך הקטן יותר לרשימת smallerהמשנה השנייה larger. בתוך השרשור של sublists, הפונקציה רקורסיבי ממיינת את smallerואת largerרשימות.

F # מפחית באגים באמצעות הקלדה חזקה

בניגוד ל- JavaScript, Ruby ו- Python, F # מוקלדת בחוזקה ולא מוקלדת באופן דינמי. בניגוד ל- C ו- C ++, שגם הם מוקלדים מאוד, אך דורשים הצהרה על כל הסוגים, F # מבצע הסקת סוג במידת האפשר. כאשר אין אפשרות להסיק סוג, אך צריך לדעת את הסוג, המהדר F # יזרוק שגיאה ויציע שתספק הערת סוג, כפי שהיינו צריכים לעשות בדוגמה קודמת (phrase:string)לוויכוח toHackerTalkלפונקציה. תפיסת אי התאמה בין סוג בזמן הידור מבטלת מחלקה שלמה של שגיאות זמן ריצה אליהן נוטות שפות שהוקלדו באופן דינמי.

אגב, letאיגודי F # אינם ניתנים לשינוי אלא אם כן אתה מצהיר עליהם במפורש mutable.

ל- F # קבוצה גדולה ונבחרת של אובייקטים, כולל רשימה, מחרוזת ומערך

כפי שניתן לראות מתוך IntelliSense למטה, ל- F # יש מודולי רשימה עשירים, מחרוזת ומערך המבוססים על .NET Framework. מהבחינה הזו, זו גם שפה מונחית עצמים, למרות שזו קודם כל שפה פונקציונאלית. שים לב שזה לא משנה אם אתה משתמש בשם המודול או שם משתנה שהוקלד - כאשר אתה מוסיף את הנקודה, פונקציות החבר יופיעו. יש אנשים שטוענים כי שימוש במפורש בשם המודול הוא סגנון טוב יותר לשפה פונקציונאלית מאשר משתנים מנוקדים, אך אני לא קונה את הטיעון הזה לגמרי.

F # שימושי עבור MapReduce

MapReduce הוא תהליך יעיל דו-שלבי המשמש לעיתים קרובות בביג-נתונים, ונתמך במפורש ב- Hadoop. בדוגמה F # זו, אנו ממפים ומצמצמים רשימה של מספרים שלמים. ראשית אנו מסננים את הרשימה למספרים הזוגיים, ואז מכפילים כל מספר ולבסוף לוקחים את סכום כל האלמנטים ברשימה כדי לצבור או להקטין את התוצאה. List.mapהיא פונקציה עוצמתית מסדר גבוה יותר; פונקציה מסדר גבוה יותר היא פונקציה שלוקחת פונקציה אחרת כטיעון. בנוסף לרשימות ומערכים, F # תומך ברשומות, רצפים, ספקי סוגי נתונים ו- LINQ (שאילתה משולבת בשפה).

ל- F # רשומות

רשומות F # מייצגות אגרגטים פשוטים של ערכים בעלי שם, אופציונלי עם חברים. בדוגמה שלהלן, ראשית אנו מגדירים Bookסוג רשומה עם ארבעה ערכים בעלי שם, ואז אנו יוצרים רשומה באמצעות אותם ארבעה שמות. מהדר F # מסמל נכון את Bookהסוג על ידי התאמת השמות.

רשומות F # יכולות להיות בעלות ערכים אופציונליים

לא תמיד רשומות צריכות לכלול את כל הערכים ששמם נקרא. אם אתה נותן ערך optionמאפיין את התכונה כאשר אתה מגדיר את הסוג, ניתן להשאיר אותו מחוץ לרשומה. כאשר אתה מגדיר ערך אופציונלי, הוא יכול להיות None, שמתפתל כ- null, או Someשאחריו יכול להיות הערך שברצונך להגדיר. שדות רשומה נבדלים מהמחלקות בכך שהם נחשפים אוטומטית כמאפיינים. מחלקות ומבנים ב- F # הם מחלקות ומבני .NET, תואמים ל- C # ו- Visual Basic .NET, אז אני אוותר על דוגמאות.

ל- F # יש רצפים

רצף ב- F # הוא סדרה הגיונית של אלמנטים מכל סוג אחד. רצפים שימושיים במיוחד כאשר יש לך אוסף נתונים מסודר גדול, אך לא בהכרח מצפה להשתמש בכל האלמנטים. רכיבי רצף בודדים מחושבים רק כנדרש, כך שרצף יכול לספק ביצועים טובים יותר מאשר רשימה במצבים בהם לא נעשה שימוש בכל האלמנטים. Seqמודול מספק תמיכה עבור מניפולציות מעורבות רצפים. בתמונה למטה אנו מדגימים רצפים פשוטים, רצפים עם ביטויים ורצפים עם פילטרים.

F # תומכת בספקי נתונים וב- LINQ

להלן אנו משתמשים בעורך TryFSharp כדי לפתוח מערך נתונים מקוון מטאורולוגי Freebase ולשאול את ספק הנתונים עבור ציקלונים שרשמו את ערכי הרוח הגבוהים ביותר. query { }מיישמת תחביר LINQ עבור F #. השימוש ב- DLL זה ספציפי ל- TryFSharp. ב- Visual Studio, היית open Microsoft.FSharp.Data.TypeProvidersמשתמש בשירות ספק הנתונים המתאים.

התוצאה:

 [Hurricane Andrew; Hurricane Hugo; 1900 Galveston hurricane;

   Tropical Storm Allison; Cyclone Tracy; Hurricane Iniki; Hurricane Ivan;

   1999 Odisha cyclone; Hurricane Katrina; Typhoon Talim; Hurricane Rita;

   Typhoon Herb; Hurricane Wilma; Typhoon Vera; 1962 Pacific typhoon season;

   Typhoon Ike; Typhoon Mireille; Typhoon Babe; Tropical Storm Arlene;

   Hurricane Irene; Typhoon Zeb; Typhoon Maemi; Typhoon Bess; Typhoon Chanchu;

   Typhoon Patsy; Typhoon Ewiniar; Hurricane Ioke; Typhoon Xangsane;…

F # יכול לנתח את נתוני Hadoop

בדוגמה זו אנו משתמשים בעורך TryFsharp כדי לפתוח מופע של Hadoop Hive המכיל, בין קבוצות נתונים אחרות, מדידות של מאפייני פרחי קשתית העין, יחד עם ביאורי יחידות מידה. בהתאם לכך, אפשרנו את השימוש בהערות יחידה במאפייני ה- HiveTypeProvider.

חישוב זה מחזיר:

val avgPetalLength : float = 0.0374966443

F # עושה התאמת תבניות

matchהביטוי F # מספק שליטת הסתעפות המבוססת על השוואה של ביטוי עם קבוצת דפוסים. שורות 1-7 של הדוגמה שלמטה מגדירות isPalindromeפונקציה רקורסיבית . שורות 8-10 מגדירות פונקציית עטיפה isPalindromeהמכנה אותה בפעם הראשונה באמצעות המחרוזת כולה. מכיוון ש"אבא "הוא פלינדרום, thenסעיף שורה 9 יורה וחוזר Some s, matchוההצהרה בשורה 11 מייצרת" המחרוזת אבה היא פלינדרום ". _ patternקו 14 הוא מקרה ברירת המחדל.

match..|הצהרה # F יש יתרונות רבים על פני switch..caseאמירה ב- C #, C ++ ו- Java, שהחשוב בהם הוא שהיא גורמת באגים פחות.

F # תומך בתהליכי עבודה אסינכרוניים

ל- F # יש גישה לכל .NET Framework, אך יש לה גם תחביר משלה לתהליכי עבודה אסינכרוניים. async { expression }התחביר מגדיר חישוב החסימה אי. do!מילת מבצעת פעולה אסינכרונית ומחכה לתוצאה. let!מחכה מילה על מבצע אסינכרוני ומקצה את התוצאה. וזה use!מחכה למבצע אסינכרוני, מקצה את התוצאה, ומשחרר את המשאבים. Async.RunSynchronouslyמבצעת פעולה אסינכרונית ומחכה לתוצאה שלה. כדי להוסיף מקבילות, השתמש Async.Parallelבפונקציה שלוקחת רשימה של Asyncהאובייקטים, מגדירה את הקוד לכל Asyncאובייקט משימה שיפעל במקביל ומחזיר Asyncאובייקט שמייצג את החישוב המקביל. ואז מקטרים ​​את התוצאה אל Async.RunSynchronously. (הדוגמה שלהלן היא מF # להנאה ורווח .)

משאבי F #

למידע נוסף על F #, עקוב אחר הקישורים למטה.

  • נסה F #
  • F # להנאה ורווח
  • F # הפניה לשפה
  • תכנות פונקציונלי של העולם האמיתי
  • F # ספרים באמזון
  • נייר לבן מס '3
  • הפניות נוספות