הטלגרם בוט הראשון שלי
השבוע כתבתי לראשונה בוט טלגרם (זמין בקוד פתוח - קישור בהמשך הפוסט) אז אם גם אתם מתכננים או מחפשים דרך קלה לגשת לזה מקווה שהפוסט הזה ייתן לכם מוטיבציה.
טיפים קצרים וחדשות למתכנתים
השבוע כתבתי לראשונה בוט טלגרם (זמין בקוד פתוח - קישור בהמשך הפוסט) אז אם גם אתם מתכננים או מחפשים דרך קלה לגשת לזה מקווה שהפוסט הזה ייתן לכם מוטיבציה.
אני יודע שאני קצת חופר לכם על תכנות פונקציונאלי בימים האחרונים אבל מקווה שזה לטובה. כי העניין עם תכנות פונקציונאלי (או כל פרדיגמה אחרת שאתם לומדים) הוא שאנחנו תמיד מחפשים לחשוב איך זה מתקשר לדברים שאנחנו כבר יודעים. איך אפשר לכתוב את הקוד שרציתי לכתוב באליקסיר או ליספ, ואז שואלים את השאלות הלא נכונות.
אני מקווה שהדוגמאות הקטנות האלה מדי פעם יעזרו לכם להבין את צורת המחשבה והגישה, ואת הרעיון שכשאתם באים לכתוב קוד פונקציונאלי המטרה שלכם היא לחשוב קודם כל מה הדרך הפונקציונאלית לכתוב את התוכנית ורק אחר כך לגשת לכתוב את הקוד.
אז הנה דוגמא קצרה להיום על היפוך סדר המילים במשפט. כך נראה קוד JavaScript שמקבל משפט כפרמטר בשורת הפקודה ומדפיס את אותו משפט בסדר מילים הפוך:
sentence = process.argv[2];
result = [];
words = sentence.split(/\W+/);
for (let i=words.length - 1; i >= 0; i--) {
result.push(words[i]);
}
console.log(result.join(" "));
אבל המעבר לתכנות פונקציונאלי משנה את התוכנית לחלוטין - ולא רק בגלל שפת התכנות. הנה אותו הקוד באליקסיר:
System.argv
|> List.first
|> String.split
|> Enum.reverse
|> Enum.join(" ")
|> IO.inspect
זה נראה קצת לא קריא במבט ראשון אז בואו נסתכל על זה יחד ואחרי זה נחזור לכתוב את הגירסא הפונקציונאלית של JavaScript. מסתבר שבאליקסיר אין לולאות for ואי אפשר להוסיף אלמנטים למערכים כי כל מבני הנתונים בשפה הם Immutable. מגבלה זו מכריחה אותנו לכתוב קוד די שונה.
הדבר השני שיש באליקסיר הוא אופרטור ה Pipeline (שאולי יגיע בקרוב גם ל JavaScript). בגלל שאנחנו מפעילים המון פונקציות הם יצרו קיצור ובמקום לכתוב:
List.first(System.argv)
אפשר לכתוב את הדבר הזה שעושה בדיוק את אותו דבר:
System.argv |> List.first
כל שורה לוקחת את התוצאה של השורה שלפניה ופועלת עליה כלומר מעבירה את התוצאה של הפקודה הקודמת בתור פרמטר ראשון לפונקציה.
עכשיו בחזרה לקוד: הגירסא הפונקציונאלית צריכה לתאר איזה פעולות עושים על המידע ובאמצעות הרכבת פעולות מגיעה לתוצאה כמעט בלי חישובי ביניים. במקרה שלנו יש 5 פעולות בסיסיות:
החשיבה הפונקציונאלית לא מבוססת על לולאות ושינויי משתנים אלא על פעולות ומידע. כשאתם יכולים לנסח התנהגות בצורה של הרכבה של פעולות בסיסיות אתם מתקרבים לצורת החשיבה הנכונה. ואיך מתרגמים את זה בחזרה ל JavaScript? די בקלות:
console.log(
process.argv[2]
.split(/\W+/)
.reverse()
.join(" ")
)
הקוד הבא ב perl מקבל רשימה של מספרים ובכל סיבוב מגדיל אחד מהם באקראי עד שכל המספרים גדולים מאלף (וכן אני יודע שיש לכם אלף רעיונות יותר יעילים לממש את זה. זאת לא הנקודה כאן):
use v5.18;
use List::Util qw/min max/;
my @numbers = <>;
my $rounds = 0;
while (min(@numbers) < 1000) {
my $idx = int(rand(@numbers));
$numbers[$idx]++;
$rounds += 1;
}
say "@numbers";
say "took $rounds rounds";
מסתבר שיש בקוד קסם אחד שדי קשה לתרגם לשפות אחרות. הקוד הבא נראה כמו גירסת רובי של אותו המנגנון:
numbers = ARGF.readlines.map(&:to_i)
rounds = 0
while numbers.min < 1000
idx = rand(numbers.size)
numbers[idx]++
rounds += 1
end
puts "#{numbers}"
puts "took #{rounds} rounds"
נסו להריץ ותגלו שהקוד ב Ruby אף פעם לא מסתיים. זה די ברור כשנזכרים שאין ++ בשפת רובי. אז מה כן קרה שם? הנה הגירסא שיותר קל לקרוא:
numbers = ARGF.readlines.map(&:to_i)
rounds = 0
while numbers.min < 1000
idx = rand(numbers.size)
numbers[idx] + (+rounds += 1)
end
puts "#{numbers}"
puts "took #{rounds} rounds"
בהיעדר השמה של ערך חדש למערך כל המספרים נשארים בערכם המקורי בכל האיטרציות ולכן אף פעם לא עוברים את האלף.
אני עדיין אוהב את רובי אין ספק בכלל, אבל הייתי שמח אם היתה יודעת לתת לי פידבק יותר טוב על הטעויות שלי (או יותר טוב אם היתה כוללת את ++).
בתחילת השנה מייקל וסטרט התחיל לפרסם ספריית קוד פתוח חדשה לעבודה עם Immutable Data Structures. הספריה נקראת Immer ומאז הפכה לפיתרון יציב ואף זכתה לברכות מדן אברמוב. בואו ניקח כמה דוגמאות כדי להבין מהי ובמה היא טובה יותר מ Immutable.JS הוותיקה.
בתור מתכנתים מאוד קשה לנו לראות את האפקט של כל שורת קוד על ביצועי המערכת או לדמיין איך שורה מסוימת תעמוד בעומס. קבלו כמה טיפים שיעזרו לכתוב קוד חזק יותר ולמצוא מהר יותר את הטעויות.
אחת הבעיות עם ענפים שחיים יותר מדי זמן היא שככל שעובר יותר זמן בין הפיצול מהענף הראשי למיזוג חזרה, כך שני הענפים מתרחקים יותר אחד מהשני ונוצרים קונפליקטים בקוד שלהם. הפקודה יכולה לעזור לנו להתמודד עם קונפליקטים אלה ולהשתלב טוב בשיטת עבודה נקייה יותר.
לולאות בתכנות פונקציונאלי בנויות אחרת מאשר לולאות של תכנות אימפרטיבי מאחר ותפקידן לעזור לנו להתמקד בפונקציה והקלט שלה. בואו נראה את ההבדל ומה הופך לולאה לפונקציונאלית.
כשהתחלתי ללכת למפגשים של קבוצת מתכנתי perl כבר במפגש השני בו השתתפתי אמר לי סויר שהמדיניות אצלם זה שאין דבר כזה אורחים. אם אתה בא אתה צריך לדבר. בפעם השלישית כבר עליתי על הבמה וההרצאות שהעברתי שם חיזקו את הידע שלי בשפה יותר מכל מיטאפ אחר שהייתי בו.
אחרי שלושה חודשים של וובינרים אני שמח לספר שהחודש את רוב הוובינרים תעבירו אתם. אנשים שמוכנים לקחת את הסיכון, לעמוד מול קהל (וירטואלי - אבל עדיין אנשים אמיתיים) ולשתף מהידע שלהם. אנשים שמוכנים להתאמץ כדי ללמוד ולהשתפר.
ואני בטוח שבעמידה (או ישיבה) שלכם עם המיקרופון יהיו רגעים מלחיצים, יהיו רגעים שלא בדיוק תדעו מה לענות ויהיו רגעים שתרצו להפסיק את ההקלטה ולברוח. אני יודע שלי יש כאלה. ואחרי כל שעה כזו אני שמח שסיימתי אותה והולך לקרוא על כל הנושאים שלא ידעתי להתיחס אליהם.
אז ההצעה שלי למנוי שנתי באתר לכל מי שמעביר או מעבירה כאן וובינר עדיין בתוקף ותישאר כך. ועכשיו תורכם: שלחו מייל או השאירו פרטים בדף צור קשר. מבטיח לעזור להתכונן, ומבטיח שלא תתחרטו.
תשתיות פיתוח עמוד-יחיד מודרניות משתמשות לפעמים בסימן סולמית כדי לדעת באיזה עמוד אנחנו נמצאים. מאיפה הגיע, למה צריך אותו והאם אפשר בלעדיו? טוב ששאלתם.
לא משנה מה הבעיה שמולכם - כמעט תמיד אפשר למצוא יותר מגישה אחת לפיתרון. וכמעט תמיד לכל גישה יהיו את היתרונות והחסרונות שלה ואת האתגרים שלה, וכמעט תמיד לא משנה באיזה גישה תבחרו תצטרכו לעבור כמה מכשולים לא פשוטים בכלל עד שהתוכנית תעבוד כמו שצריך.
אנגולר או ריאקט? מיקרו סרביסס או מונולית? אפליקציה או אתר? שרת ייעודי או Serverless?
כן כנראה אחת הדרכים היא קצת יותר טובה מהשניה, אבל גם כנראה שאין לכם כרגע מספיק נתונים כדי לדעת איזה.
במקום לבזבז זמן על חיפושים קחו את זו שאתם יודעים איך להתקדם בה ותתחילו משם. אחרי שהקוד יעבוד יהיה לנו הרבה יותר קל לשכתב או לשפר אותו.
נ.ב. אני עדיין פותר עם חברים את Advent Of Code האחרון, בקבוצת לימוד באווירה טובה ובעברית. אם אתם רוצים דרך בטוחה לשפר את מיומנויות התכנות שלכם דרך פיתרון בעיות מדליקות ועזרה לחברים בבעיות אלה מוזמנים בחום להצטרף. החידה הנוכחית מחכה לכם כאן: