
הצעת pre-RFC: ארגומנטים בעלי שם ואופציונליים ב-Rust
כותב הבלוג botahamec.dev טוען שהחיסרון הגדול של Rust הוא היעדרם של ארגומנטים בעלי שם ואופציונליים. הפוסט משווה בין Dart, C# ו-TypeScript ומציע pre-RFC משלו לפתרון הבעיה.
בפוסט ב-botahamec.dev טוען הכותב שהחיסרון המעצבן ביותר ב-Rust הוא היעדרם של ארגומנטים בעלי שם וארגומנטים אופציונליים. הוא מונה את השפות שהוא "סובל" — Rust, C#, TypeScript, Dart ו-Python — ומציין שב-Rust קשה להשיג ארגומנטים בעלי שם יותר מבכולן. הפוסט מסתיים בהצעת pre-RFC משלו.
כיצד מתמודדות שפות אחרות
Dart, שתוכננה לממשקים גרפיים שבהם לרכיבים פרמטרים אופציונליים רבים, עוטפת פרמטרים בעלי שם בסוגריים מסולסלים ומאפשרת ערכי ברירת מחדל, סימון `required` וארגומנטים מיקומיים אופציונליים בסוגריים מרובעים — לדעת הכותב זה הפתרון הטוב ביותר מבין השפות שנדונו. ב-C# כל פרמטר יכול לקבל שם או ערך ברירת מחדל, כל עוד אלה באים אחרי פרמטרי החובה, ואפשר להעביר ארגומנטים בעלי שם בסדר שונה. ב-TypeScript פרמטרים מיקומיים אופציונליים עובדים היטב, אך ארגומנטים בעלי שם דורשים פירוק של אובייקט אנונימי יחיד, כך ששמות השדות נכתבים פעמיים — עודף מילולי שהכותב אינו אוהב.
מה עולה ל-Rust מהיעדרם
הדרך המקובלת ב-Rust היא מבנה פרמטרים ייעודי שמממש `Default`, עם סיום הקריאה ב-`..Default::default()`. הכותב טוען שזה גרוע אף מגישת TypeScript: הטיפוסים אינם אנונימיים, ערכי ברירת מחדל השונים מברירת המחדל של הטיפוס מחייבים כתיבת פונקציה שלמה, והשיטה עובדת רק כשכל הפרמטרים מקבלים ברירת מחדל.
עבור שלושה פרמטרים אופציונליים — קיבולת, פונקציית גיבוב ומקצה זיכרון — ל-`HashMap` שבספריית התקן יש שמונה בנאים, ובהם `new`, `with_capacity`, `with_hasher` ו-`with_capacity_and_hasher` עם וריאנטים מסוג `_in`, ומספר הפונקציות גדל באופן מעריכי. גם בלבול בסדר קל: ב-`fn print(text: &str, bold: bool, italics: bool, underline: bool)` החלפה בין הארגומנט השני לשלישי תהפוך את הטקסט למודגש בלי ששמים לב.
ההצעה של הכותב
ה-pre-RFC הופך את השמות לאופציונליים באמצעות מילת המפתח `pub` לפני שם הפרמטר — `fn print_labeled_measurement(pub value: i32, pub unit_label: char = 'm')` — ואז אפשר לקרוא `print_labeled_measurement(value: 5)`. ארגומנטים בעלי שם חייבים לבוא אחרי המיקומיים, אך אפשר לסדר אותם מחדש ביניהם, ומותר לתת להם ערכי ברירת מחדל: בפונקציות `const` נדרש ביטוי קבוע, ובפונקציות רגילות ברירת המחדל מחושבת בעת ההצרה. טריטים רשאים להשתמש בפרמטרים בעלי שם, ומימושים חייבים לחזור על השמות, אך למתודות של טריט אסור לקבל ערכי ברירת מחדל. מצביעים לפונקציות וטריטים של `Fn` נשארים מיקומיים.
הצעות אחרות ושאלות פתוחות
הכותב סוקר גם הצעות שלדעתו גרועות יותר: ערכי ברירת מחדל לשדות מבנה (כבר ב-Nightly Rust, וכותב הפוסט כתב ספריית polyfill בשם `feluments`), רשומות מבניות, שצוות השפה קבע שקשה מדי לממש, pre-RFC ארוך מפורום Rust Internals שהציע העמסה במקום ערכי ברירת מחדל, תחביר עם נקודה בהתחלה (RFC משנת 2020 שלא אושר) והעתקה של גישת C#. משום שהשמות אופציונליים, הבטיחות נשארת תלויה במשמעת: הוא מציע לינט של Clippy או חיוב שמות במהדורה עתידית. נותרו פתוחות שאלות הסדר, הבחירה ב-`pub` והשאלה אם ערכי ברירת מחדל חייבים תמיד להיות `const`.
SiTech — פיתוח אתרים בכוח ה-AI
אנחנו בונים אתרים מהירים ומודרניים ומשלבים AI בתהליכי עבודה אמיתיים. יש לכם פרויקט או שאלה? נשמח לעזור.