הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

מימוש חלקי בסקאלה דרך מיקסינים

08/07/2024

התבנית הבאה עזרה לי לארגן מחדש קצת קוד (נו, הרבה קוד) ולחלק אותו מקובץ אחד להרבה קבצים קטנים יותר, מה שגם עזר בבדיקות. נתחיל עם דוגמה פשוטה ונתבונן בקוד הבא:

class MyBigHandler {
  def handle(message: String): String =
    message match
      case "error" => "Handling error"
      case "warning" => "Handling warning"
      case "info" => "Handling info"
      case "zzz" => "MyHandler"
      case _ => "Unhandled message"
}

אז זה קל יש בסך הכל פונקציה אחת שמטפלת בכל מיני סוגים של הודעות. אבל נדמיין שההודעות מחולקות לקבוצות ושיש המון הודעות וקוד הטיפול בכל קבוצה צריך פונקציות עזר משותפות ואין ממש קשר בין הקבוצות. במצב כזה נרצה לפצל את ה match לקבצים וכל קובץ יהיה אחראי על קבוצת הודעות. ופה באים לעזרתנו ה Mixins. זה הקוד אחרי אירגון מחדש:

trait MessageHandler {
  def handle(message: String): String = "Unhandled Message"
}

trait ErrorHandler extends MessageHandler {
  abstract override def handle(message: String): String = message match {
    case "error" => "Handling error"
    case _ => super.handle(message)
  }
}

trait WarningHandler extends MessageHandler {
  abstract override def handle(message: String): String = message match {
    case "warning" => "Handling warning"
    case _ => super.handle(message)
  }
}

trait InfoHandler extends MessageHandler {
  abstract override def handle(message: String): String = message match {
    case "info" => "Handling info"
    case _ => super.handle(message)
  }
}

class MyHandler extends MessageHandler
  with ErrorHandler
  with WarningHandler
  with InfoHandler {

  override def handle(message: String): String =
    message match
      case "zzz" => "MyHandler"
      case _ => super.handle(message)
}

כל trait מטפל בהודעות שרלוונטיות עבורו ויכול לשבת בקובץ נפרד עם אוביקט של פונקציות עזר. ה Handler הוא פשוט הרכבה של כל המיקסינים ויכול להוסיף מימוש משלו לדברים שלא היה להם מקום באף מיקסין ועכשיו הרבה יותר קל לשלב את הטיפול בכל קבוצת הודעות גם במחלקות אחרות או לכתוב בדיקות לכל קבוצה בנפרד.

תחזוקה ו GPT

07/07/2024

מנועי GPT הפכו לחלק אינטגרלי מאינסוף אפליקציות חדשות שיוצאות כולל כמה פרויקטים שהייתי מעורב בהם. הפיתוח תמיד מאתגר כי אנחנו אף פעם לא יודעים מה בדיוק יענה ה AI, ויש צורך גם לנקות את הקלט לפני שפונים אליו וגם לנקות את הטקסט שחוזר ממנו אבל בסוף אחרי מספיק Prompt Engineering אפשר להגיע לתוצאה טובה.

השבוע לראשונה (לפחות עבורי) נתקלתי באתגר חדש - והוא שינוי במנוע ה GPT עצמו שגרם לפרומפט שכבר עבד להפסיק לעבוד.

אני משווה את זה לעבודה מול שירותי צד-שלישי מסורתיים ורוצה לבכות - כל API חיצוני מולו אני עובד כולל מספר גירסה. כשיש שינוי הוא תמיד יזום. ה AI אומנם כולל מזהה מודל, אבל עדכונים למודל לא תמיד מתורגמים לגירסה חדשה. אין גם Release Notes שכולל את רשימת כל הדברים שהשתנו או מדריך שידרוג לפרומפטים. מרגע שהחלטת לשלב AI בפרויקט עליך להקפיד לעקוב כל הזמן אחרי התשובות שמתקבלות, לזהות מתי פרומפטים מסוימים מפסיקים לעבוד ולהעלות תיקון, תמיד מאוחר מדי.

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

יתרונות וחסרונות של למידה ממושחקת

06/07/2024

בשנים האחרונות הרעיון של Gamified Learning תפס תאוצה ומהווה אלטרנטיבה לשיטות למידה ישנות יותר. כשבאים עם ציפיות נכונות מנגנונים כאלה יכולים להיות מהפכניים ולקדם אותנו יותר מכל טכניקה אחרת. בפוסט זה אנסה להבין אתכם את המאפיינים של שיטת הלמידה הממושחקת ואשתף מהניסיון שלי מה עבד.

המשך קריאה

מה יש ב Gem הזה?

05/07/2024

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

ה"לפני" וה"אחרי" כאן מאוד בולט- אנשים שעדיין לא עלו את המדרגה הזאת יחפשו למצוא פיתרונות קיימים או לבנות מאפס בעזרת ChatGPT ופיתרונות מ Stack Overflow. כשדברים לא עובדים הם יחפשו הודעות שגיאה ברשת וינסו להתקין גירסאות אחרות של הספריה או ספריות אחרות שפותרות את הבעיה.

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

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

אקוסיסטם, אינטראופ ותחביר

03/07/2024

שלושת השיקולים שלי בבחירת שפת תכנות לפרויקט הבא, ולפי סדר חשיבות:

  1. אקוסיסטם - כי הדבר הכי חשוב שאוכל לעבוד עם ספריות מתקדמות ורלוונטיות לעולם התוכן בו אני בונה.

  2. אינטראופ - כי אם האקוסיסטם לא מספיק טוב יהיה נחמד להשלים פערים משפות אחרות.

  3. תחביר - כי אחרי שיש לי את כל הכלים לבנות את מה שאני רוצה עדיף שאהנה מהכתיבה עצמה.

לפעמים אנחנו חושבים שאינטראופ יעזור להתמודד עם אקוסיסטם חלש או שתחביר טוב יגרום לזה שיהיה לי כיף לכתוב לעצמי את הכלים (או את העטיפות כדי לשפר את האינטראופ). בפרויקטים שכתבתי עד עכשיו זה לא היה המצב.

פיתרון Advent Of Code 2023 יום 20 בסקאלה

02/07/2024

יום עשרים של Advent Of Code הוא אחד התרגילים עם הרבה יותר מדי טקסט, הרבה יותר מדי קוד והרבה יותר מדי עבודה ידנית. בקיצור לא תרגיל שאוכל אי פעם להשתמש בו בקורסים ולא תרגיל שנהניתי ממנו במיוחד. אבל יש גם כאלה בחיים. בואו נראה את המשימה והפיתרון בקצרה. לינק לתרגיל: https://adventofcode.com/2023/day/20

המשך קריאה

קוד זה אנשים

01/07/2024

שאלו אנשים בהאקרניוז מה הקוד הכי טוב שעבדתם עליו?

ציפיתי למצוא שם יצירות אומנות של מקודדים גאונים שישבו במערה וכתבו קוד שנראה כמו קסם. אנשים כמו מרקוס פרסונס (היוצר של מיינקרפט), לינוס טורוולדס או בראם מולנאר.

במקום זה יש אוסף מרשים של אנשים אמיתיים שאומרים: הקוד הטוב ביותר שיצא לי לעבוד עליו נכתב על ידי קבוצה של מתכנתים ברמות מיומנות שונות שדאגו לתקשורת טובה אחד עם השני. אנשים שכיבדו אחד את השני, שהקשיבו, ושהביאו חשיבה ביקורתית ויצירתיות למקום העבודה.

וזה הגיוני - כשיושב מתכנת על מהחלל וצריך לכתוב לבד קוד שכל האנשים בצוות (שזה רק הוא) יכולים להבין זה בעצם לכתוב קוד שהוא יכול להבין באותו רגע, מה שלא מבטיח הרבה מבחינת היכולת לקרוא את הקוד. אבל כשיש לך 3-4 אנשים שיושבים על הקוד וכולם צריכים להבין את הקוד של כל האחרים, אנחנו כבר במשחק אחר מבחינת דרישות התקשורת מה שמוביל כמובן לרמה הרבה יותר גבוהה של התוצאה.

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

כלים או קטגוריות

30/06/2024

ג'ודי לי פרסמה רשימה של 20 כלים שכל מתכנת ומתכנתת צריכים להכיר. היא כללה את הכלים הבאים: VS Code, Copilot, Docker, Kubernetes, Postman, Jira, Slack, Figma, Node.js, Webpack, Terraform, VS Code Live Share, Sentry, SonarQube, Prometheus, Grafana, Ansible, Elasticsearch, CircleCI, Tailwind CSS.

כשמקבלים כזאת רשימה יש כמה שאלות שכדאי לשאול לפני שצוללים ללמוד את הכלים (אם בכלל צריך):

  1. למי הרשימה מיועדת? איזה סוג מפתחים ירצו את הכלים האלה?

  2. מה המטרה של כל כלי? האם יש כלים אחרים עדיפים שאני כבר עובד איתם?

  3. איפה ההזדמנות שלי לשפר את הפרודוקטיביות?

  4. איפה ההזדמנות שלי ללמוד יכולות חדשות?

אני מתחיל עם השאלה הראשונה - בגלל שהרשימה כוללת פריימוורק ל CSS, כלי לבאנדלינג של קבצי צד-לקוח וכלי עיצוב אני מבין שהיא מיועדת למפתחי צד-לקוח. בגלל כלי ה Deployment וה Monitoring אני מבין שהיא מיועדת ל DevOps ובגלל Node ו Elastic אני מבין שיש פה קריצה למפתחי צד שרת. חיבור כל ה-3 שם אותי במגרש של Full Stack Developers.

עכשיו בתור Full Stack Developer אני יכול להמשיך ולשאול האם אני באמת צריך את הכלים האלה דרך שלושת השאלות הבאות - מה המטרה של הכלי, איפה הזדמנות הלמידה ממנו והאם הוא באמת רלוונטי ל Workflow שלי. סריקה זריזה של הכלים מראה שלכל אחד מהם יש אלטרנטיבות לא פחות טובות וחשובות, ולכן אם היו שואלים אותי הייתי מארגן את הרשימה לפי נושאים:

  1. סביבת פיתוח - בין אם זה יהיה VS Code, הכלים של Jetbrains או vim, כדאי למצוא סביבת פיתוח שאתם אוהבים וכל הזמן לחפש סביבות חדשות.

  2. יועץ AI - יש לנו את ChatGPT, Claude וכמובן copilot, אבל גם את ה AI של פייסבוק וזה של גוגל ומיסטרל ורבים נוספים. כדאי להכיר כלים כאלה וללמוד איך לשלב אותם בצורה אפקטיבית ב Workflow שלנו.

  3. כלי Deployment ו CI/CD - חשוב להבין איך תוכנה עוברת מהמחשב שלנו לשרת או שרתים בענן ואיך היא מנוהלת שם. יש המון כלים שיכולים לעזור בזה כמו Docker, Kubernetes, Ansible, Terraform אבל גם Github Actions ורבים נוספים.

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

  5. בסיסי נתונים - יש המון סוגים של בסיסי נתונים מעניינים החל מ Postgresql הסטנדרטי דרך DynamoDB, Mongo, CouchDB, neo4j ורבים נוספים. כדאי להכיר כמה שיותר סוגים של בסיסי נתונים כדי להתאים את בסיס הנתונים למערכת.

  6. שפות פיתוח - מפתחי Full Stack רגילים לעבוד ב TypeScript גם בצד שרת וגם בצד לקוח וזה באמת מאוד נוח. היום בנוסף ל node.js יש גם את bun וגם את deno שמריצים TypeScript באופן זה. בנוסף יש עדיין הרבה שפות פיתוח שמתקמפלות ל JavaScript ומאפשרות בנייה של יישומי Full Stack בשפה אחת. נסו למצוא פריימוורקים כאלה ותראו איזה מהם מתאימים לפרויקט שלכם.

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

הפיצ'ר שעדיין חסר לי ברידאקס

29/06/2024

אחד הפיצ'רים שאני מאוד אוהב בריאייג'נט (גירסת הקלוז'ר של ריאקט) נקרא Cursors. זה קצת כמו useSelector של רידאקס אבל עם אפשרות לעדכן. לדוגמה:

(def state (reagent/atom {:foo {:bar "BAR"}
                          :baz "BAZ"
                          :quux "QUUX"}))
;; Now create a cursor
(def bar-cursor (reagent/cursor state [:foo :bar]))

(defn bar-component []
  (js/console.log "bar-component is rendering")
  [:div @bar-cursor])

התוכנית מגדירה משתנה אחד בשם state שבו מוחזק כל הסטייט של היישום (כמו ה store ברידאקס) ואז עוד משתנה בשם bar-cursor שהוא סוג של מצביע לתוך הסטייט. הקריאה מה cursor, קצת כמו קריאה מ store דרך useSelector יוצרת חיבור בין הקומפוננטה לחלק הזה בסטייט כך שכשהמידע בתוך הנתיב [:foo :bar] ישתנה גם הקומפוננטה תרונדר מחדש, אבל יש פה שני כוחות על שחסרים ברידאקס:

  1. ה cursor מיוצר מחוץ לקומפוננטות (לא כזה מלהיב, גם ברידאקס הייתי יכול להגדיר Selector בקובץ נפרד).

  2. אפשר לעדכן את ה State דרך ה Cursor.

היכולת השניה היא הדבר הגדול. ברידאקס בשביל להשיג אפקט דומה אני צריך להגדיר Reducer ו Action וכל ה Boilerplate.