• בלוג
  • היום למדתי לא לסמוך על הקומפיילר של סקאלה

היום למדתי לא לסמוך על הקומפיילר של סקאלה

18/03/2024

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

import scala.jdk.CollectionConverters._

val m = Map("a" -> 10)
m.asJava.get("a", 2, 3)

התוצאה היא 0, למרות ש a נמצא במפה. אפשר לטעון ששני הפרמטרים האחרים בלבלו אותו אבל האמת שגם אם נעביר את המחרוזת a לכל הפרמטרים נקבל את אותו 0. הבעיה האמיתית כאן היא ש get של java.util.Map מצפה לקבל פרמטר אחד. העברת יותר פרמטרים לפונקציה היא טעות שהיתה צריכה להתגלות בזמן קומפילציה.

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

val m = Map("a" -> 10)
m.asJava.getOrDefault("a", 1, 2)

-- Error: ----------------------------------------------------------------------
2 |m.asJava.getOrDefault("a", 1, 2)
  |                              ^
  |too many arguments for method getOrDefault in trait Map: (x$0: Object, x$1: V): V
1 error found

אבל כשקומפיילר תופס בעיות רק ב 99% מהמקרים זה לפעמים יותר מתסכל מאשר שלא יתפוס בעיות בכלל.