כך תשפרו את יכולות התכנות שלכם ב-JS
הדרך אל האושר עוברת דרך Go – שפה סטטית פונקציונלית, שחולקת נקודות דמיון עם JS אבל פותרת דברים קצת אחרת
בשנים האחרונות הפכה Node.js לאחת הפלטפורמות הנפוצות ביותר לכתיבת קוד צד-שרת. היכולת להשתמש בשפה אחת (JS) בשביל לקודד גם לשרת וגם לדפדפן קורצת מאוד להרבה מתכנתים ומנהלי פיתוח מכיוון שעל פניו הצוות צריך להכיר רק שפה אחת – JS. זה כמובן גם עוזר בגיוס מפתחים, כי JS היא סוג של שפת בסיס בעולם הווב, ומתכנת שיודע אותה יוכל להשתלב בחברה שעובדת עם Node.js בצורה מהירה וטובה.
ועדיין, JS היא שפה שלא קל ללמוד מהר וביסודיות, ומתכנתים רבים מכירים אותה באופן שטחי בלבד, דרך הפלטפורמות שבהן הם משתמשים (אנגולר, אקספרס וכיו״ב). המצב הזה מוביל לסוג של פסאודו-התמקצעות – מומחי ריאקט, MEAN או אנגולר, במקום התמקצעות בשפה עצמה או בפרקטיקות תכנות כלליות שאינן קשורות בהכרח לשפה אחת.
אם אתם מתחברים לרעיון ש-JS היא שפה שקשה להתמקצע בה ולבעיה שמתכנתי JS ממוקדים לרוב בפלטפורמה ולא בשפה, אני רוצה להציע לכם דרך מעניינת לשפר את יכולות הקידוד שלכם או של הצוות שלכם ב-JS – תלמדו Go.
אני אתן לכם רגע להרים גבה, ועוד אחד כדי להוריד אותה.
הדמיון בין Go ל-JavaScript
למי שלא מכיר, Go היא שפה סטטית, שנוצרה בידי גוגל ומיועדת לפתרון בעיות שנפתרות בדרך כלל על ידי שימוש ב C/C++. אתם יכולים לחשוב עליה כחלופה מודרנית ל-C++, בלי כל הלכלוך והמטען.
על פניו אין שום קשר בין Go ובין JS, אך כשבוחנים את הנושא לעומק אפשר למצוא כמה נקודות דמיון בין שתי השפות (סבלנות, עוד רגע אפרט), שעוזרות לנו לקבל פרספקטיבה על הדרכים שבהן Go עושה דברים אחרת ולבחון איך ניתן לאמץ את הגישה של Go לקידוד ב-JS.
– נקודת הדמיון הראשונה היא ששתי השפות הן פונקציונליות; כאלה שבהן רכיב הפונקציה הוא אזרח מדרגה ראשונה. זה אומר שכשאנחנו ניגשים לפתור בעיה, אנחנו לא מנסים למדל אותה כאוסף של התנהגויות (מחלקות), אלא כאוסף של פעולות (פונקציות). יש כמובן תמיכה מלאה בפונקציות אנונימיות, קריאה אסינכרונית לפונקציות והעברה של פונקציות כפרמטרים של פונקציות אחרות (וואו, הרבה פונקציות).
– נקודת הדמיון הבאה היא גישת החבילות של שתי השפות: קוד שאמור לטפל בבעיה מסוימת יכול להיות ארוז כחבילה עצמאית, עם הכרזה מפורשת לגבי הפונקציונליות שהחבילה מחצינה (export ב-JS).
– נקודת הדמיון השלישית היא מודל הירושה/הרחבה שאותו חולקות שתי השפות. גם JS וגם Go מאפשרות הרחבה של אובייקטים על ידי מיזוג אובייקט אב, ועל אף שהמימוש מעט שונה, העיקרון מספיק דומה בשתיהן כדי שנרגיש ״בבית״.
אז מה היה לנו? שתי שפות, אחת דינמית ואחת סטטית, שתיהן פונקציונליות, מבוססות חבילות ובעלות מודל ירושה/הרחבה דומה.
אז מה אנחנו יכולים ללמוד מכך? אם נשים בצד לרגע את היתרונות של קידוד בשפה סטטית על פני דינמית (כן, אני יודע יש גם חסרונות), כמתכנתי JS יש כמה דברים שאנחנו יכולים ללמוד מ-Go כדי לשפר את יכולות הקידוד שלנו.
טיפול בשגיאות – ב-Go אין יכולת לעשות try/catch. כל שגיאה פוטנציאלית חייבת להיות מטופלת באופן כלשהו; כל פונקציה שעשויה לחוות שגיאה אמורה להחזיר את השגיאה הזו הלאה לטיפול. התוצאה היא קוד שתמיד מוכן לגרוע מכל, ומבהיר לנו בדיוק היכן דברים הולכים להסתבך. יתרה מכך, בגלל שאי אפשר להדחיק שגיאות עם try/catch, תיקון באגים אומר תיקון של הבעיה עצמה ולא טאטוא שלה מתחת לשטיח. מכירים את השורה מהמנון הצופים ״היה נכון, נכון תמיד״? אז כזה, רק בקוד.
פשטות – בניגוד ל-JS, שהתרחבה עם השנים וקיבלה צרור תקנים שהכניסו עוד יכולות לשפה, Go תוכננה מאפס בעידן מודרני, בלי שאריות מיותרות משנות ה-90 או מטענים רגשיים של מלחמת פלטפורמות. הגישה ב-Go אומרת שפשוט זה טוב ושיש דרך אחת לעשות משהו.
למשל, ב-Go יש רק דרך אחת לכתוב לולאות ויש רק דרך אחת לכתוב תנאים. התוצאה היא קוד שלא מנסה להתחכם בדרך לפתרון הבעיה, ואפילו אם הוא (הקוד) קצת יותר מילולי וארוך, תמיד ברור מה כתוב שם. כשקוראים קוד Go אין התלבטות של ״רגע, זו לולאה? על מה בדיוק היא עוברת? מה היא עושה?״. התוצאה היא קוד ממוקד פתרון במקום קוד ממוקד תחביר, ובגלל זה קל יותר כמתכנתים לדמיין את הפתרון ולהביע אותו.
עבודה אסינכרונית – ל-Go יש תמיכה פנטסטית במודל עבודה אסינכרוני באמצעות מנגנון שנקרא Go routines. אבל, בגלל שב-Go עבודה אסינכרונית נעשית ב-threads, יש משמעות רבה יותר לשינוי מצבים וערכים של משתנים בתוכנית שלנו ולדרך שבה אותן פונקציות מתקשרות עם התכנית הראשית.
הדרך של Go לטפל בזה היא באמצעות מנגנון משלים שנקרא channels, שמאפשרים תקשורת אסינכרונית בין פונקציות במודל שדומה ל-message bus. היופי במנגנון הזה הוא שניתן לממש אותו ב-JS בקלות יחסית, ולכתוב קוד אסינכרוני בעל השפעות ברורות וצפויות על מצב התכנית שלנו. בנוסף, השיטה הזו גורמת לנו להתייחס לקוד אסינכרוני קצת אחרת, כי היא מעודדת מימוש של פונקציות אטומיות עם מטרה, תוצאה, השפעה ברורה והפרדה בין הלוגיקה ואמצעי התקשורת עם הפונקציה, כך שקל יותר לכתוב בדיקות לקוד, גם אם בסוף הוא רץ בצורה אסינכרונית.
אם הגעתם עד כאן והסתקרנתם, אני מזמין אתכם להציץ בשני אתרים נפלאים שיאפשרו לכם לחוות וללמוד קצת Go בלי להתקין שם דבר:
• Go by Example – שמכיל אוסף דוגמאות פשוטות לשימוש באבני הבניין של שפה
• Go Playground – עורך קוד אינטראקטיבי ל-Go, בדומה ל JSFiddle ודומיו, שמאפשר לכתוב ולהריץ תכניות Go בדפדפן
חשוב לציין שהדברים נכונים לא רק ל-JS, ושהסיבה שבחרתי ב-JS כמקור השוואה היא נקודות הדמיון בינה ובין Go. לדעתי, הן עוזרות להמחיש את השוני בין השתיים, ובמקביל מציבות אותנו על קרקע מוכרת (רק בגלל ש-JS יחסית מוכרת ונפוצה).
הכותב הוא CTO בחברת Quicklizard. בכנס Geektime Code הקרוב, שיתקיים ב-6 ביוני בגני התערוכה בתל אביב, יעביר זהר הרצאה שסוקרת מספר תחומים נוספים בהם Go יכולה לעזור לשפר את יכולות התכנות
הגב
8 תגובות על "כך תשפרו את יכולות התכנות שלכם ב-JS"
* היי, אנחנו אוהבים תגובות!
תיקונים, תגובות קוטלות וכמובן תגובות מפרגנות - בכיף.
חופש הביטוי הוא ערך עליון, אבל לא נוכל להשלים עם תגובות שכוללות הסתה, הוצאת דיבה, תגובות שכוללות מידע המפר את תנאי השימוש של Geektime, תגובות שחורגות מהטעם הטוב ותגובות שהן בניגוד לדין. תגובות כאלו יימחקו מייד.
נראה כמו כתבה על Go, עם השוואה מינימלית לJS למרות דימיון רב יותר לשפות אחרות, הכותרת קצת מטעה.
JS מתפקדת לרוב כevent-driven language, לעומת Go שפחות מתאימה לתבנית הזו.
מנגנון הירושה שונה מאוד מJS ולדעתי דומה יותר לC#/Java, עם מימוש Interfaces(אמנם ללא הכרזה) וEmbedding.
יש עוד המון שפות שבהן ניתן להעביר פונקציות כפרמטרים לפונקציות(אפילו C# עם Action/Func).
ומה זה אומר שלמפתחי JS כדאי ללמוד על Concurrency מGo? זה פיצ'ר שלא קיים בJS.
בכל מקרה לדעתי כדאי לכל חובבי התכנות ללמוד Go, שפה מעניינת וחדשנית.
אולי קצת אוברקיל, אבל אם מישהו רוצה ללמוד תכנות כקונספט (ולא רק כ- means to an end) שילמד שפת תכנות, לא JS. יש שפות תכנות שנוצרו עם חזון ברור, ושעצם למידתן מכריח אותך לרכוש מושגים בסיסיים בתכנות, ובמיוחד design patterns.
ההמלצה האישית שלי (התאהבות ממבט ראשון) היא Scala. עקומת לימוד די תלולה, אבל ברגע שאתה נכנס לזה אתה לא מבין איך אפשר לכתוב בשפות אחרות. את Go לא ניסיתי אבל היא בהחלט ברשימה שלי.
באופן כללי, אם אתה רוצה לגייס "מפתח", ואתה לוקח את המועמד/ת שבקורות החיים שלו/ה יש ידע רק ב- JS, אתה לא תקבל את מה שאתה מחפש.
אם אתה חושב שכתיבת קוד JavaScript איכותי לא דורשת ממך ידע בארכיטקטורת תוכנה, תעלה על הדלוריאן ותקפוץ לשנת 2018. "שילמד שפת תכנות, לא JS". רייט.
בנוסף, המשפט האחרון בתגובה שלך הוא ערימה של בולשיט. יחסית למישהו שעובד בתחום שבו הוא אמור לחדש את עצמו כל הזמן, אתה נשמע לי כמו מישהו שתקוע אי שם ב-2005.
בוריס, לגיטימי מאוד לא להסכים ולהביע את עמדתך. פחות לגיטימי להשתמש במילים כמו ״בולשיט״ ולהעביר ביקורת חד-צדדית על משתתפי הדיון. זה לא תורם ומאוד אשמח אם בעתיד תביע את עמדתך והרעיונות שלך באופן שמכבד את הדיון והמשתתפים.
נראה לי שהנקודה קצת התפספסה. אני לא מדבר על תכנות כקונספט ו design patterns בכוונה, אלא על גישה לכתיבת קוד ואיך פרקטיקות מ Go יכולות לעזור לשפר את יכולות התכנות. ההקבלה ל JS נעשתה בעיקר בגלל נפוצותה ובגלל היותה שפה פונקציונלית כמו Go. נושא גיוס מפתחים ואיכות מועמדים הוא נושא נפרד לחלוטין, שבכוונה נמנעתי מלהכנס אליו.