שפות שמבוססות על בלוקים שונות משפות שמבוססות על טקסט במספר דרכים, בעיקר כי הן מיועדות למשתמשים מתחילים. ריכזנו כאן רשימה של דברים שכדאי לקחת בחשבון כשאתם מתכננים שפה משלכם שמבוססת על בלוקים.
שימוש ברשימות שמתחילות בספרה אחת
מתכנתים מתחילים מגיבים בצורה שלילית כשהם נתקלים ברשימות שמתחילות ב-0 בפעם הראשונה. כתוצאה מכך, Blockly פועל בהתאם ל-Lua ול-Lambda Moo, ומתחיל את האינדקס של רשימות ומחרוזות בספרה אחת.
לשימושים מתקדמים יותר ב-Blockly, יש תמיכה ברשימות שמתחילות בספרה אפס כדי להקל על המעבר לטקסט. לקהלים צעירים יותר או לקהלים מתחילים, עדיין מומלץ להוסיף לאינדקס לפי תחילית אחת.
המלצה: המספר 1 הוא המספר הראשון.
תמיכה בכללי שמות ליברליים
מתכנתים מתחילים לא מצפים ש-location_X
ו-location_x
הם משתנים שונים. כתוצאה מכך, Blockly פועל לפי הדוגמה של BASIC ו-HTML, ומשתנים ופונקציות לא תלוים באותיות רישיות. ב-Scratch נעשה שימוש בגישה מתוחכמת יותר (כפי שמוצג בצד שמאל), והמערכת מבדילה בין אותיות רישיות לאותיות רגילות בשמות המשתנים, אבל לא בבדיקות השוויון.
בנוסף, ב-Blockly אין דרישה שהמשתנים והפונקציות יהיו תואמים לסכימה הרגילה של [_A-Za-z][_A-Za-z0-9]*
. אפשר לתת למשתנה שם כמו List
of zip codes
או רשימת מיקודים
.
המלצה: התעלמות מהאותיות הרישיות, הרשאה לכל השמות.
הפיכת כל המשתנים למשתנים גלובליים
גם למתכנתים מתחילים קשה להבין את ההיקף. כתוצאה מכך, Blockly פועלת כמו Scratch ומגדירה את כל המשתנים כגלובלים. החיסרון היחיד של משתנים גלובליים הוא שהחזרה על עצמה (recursion) מורכבת יותר (צריך לדחוף ולשלוף משתנים לרשימה), אבל זו טכניקת תכנות שמעבר להיקף של משתמשי היעד של Blockly.
המלצה: ההיקף לא רלוונטי, כדאי להשאיר אותו לטיפול מאוחר יותר.
איך מטפלים בערכים אופציונליים של חזרה
פונקציות רבות בתכנות מבוססת-טקסט מבצעות פעולה ואז מחזירות ערך.
יכול להיות שייעשה שימוש בערך המוחזר הזה, ויכול להיות שלא. דוגמה לכך היא הפונקציה pop()
של סטאק. יכול להיות שיקראו ל-Pop כדי לקבל ולהסיר את האלמנט האחרון, או רק כדי להסיר את האלמנט האחרון בלי להתחשב בערך המוחזר.
var last = stack.pop(); // Get and remove last element.
stack.pop(); // Just remove last element.
שפות מבוססות-בלוקים בדרך כלל לא מתאימות להתעלמות מערך החזרה. בלוק ערך צריך להתחבר למשהו שמקבל את הערך. יש כמה אסטרטגיות לטיפול בבעיה הזו.
א) עוקפים את הבעיה. ברוב השפות שמבוססות על בלוקים, השפה תוכננה כך שלא יהיו מקרים כאלה. לדוגמה, ב-Scratch אין בלוקים שיש להם גם תופעות לוואי וגם ערך מוחזר.
ב) יש לספק שני בלוקים. אם אין בעיה עם מקום בכלי, פתרון פשוט הוא לספק שניים מכל בלוק מהסוג הזה, אחד עם ערך מוחזר ואחד בלי. החיסרון הוא שזה עלול להוביל לתיבת כלים מבלבלת עם הרבה בלוקים כמעט זהים.
ג) מוטציה של בלוק אחד. אפשר להשתמש בתפריט נפתח, בתיבת סימון או בכל אמצעי אחר שמאפשר למשתמש לבחור אם יהיה ערך החזרה או לא. לאחר מכן, הצורה של הבלוק משתנה בהתאם לאפשרויות שלו. דוגמה לכך מופיעה בבלוק הגישה לרשימה ב-Blockly.
ד) נהנים מהערך. בגרסה הראשונה של App Inventor נוצר בלוק צינור מיוחד שבלע כל ערך מחובר. המשתמשים לא הבינו את הקונספט, ולכן בגרסה השנייה של App Inventor הסרנו את הבלוק של צינור ההעברה והמלצנו למשתמשים להקצות את הערך למשתנה חד-פעמי.
המלצה: לכל אסטרטגיה יש יתרונות וחסרונות, לכן כדאי לבחור את האסטרטגיה שמתאימה למשתמשים שלכם.
יצירת קוד קריא
משתמשי Blockly מתקדמים אמורים להיות מסוגלים להסתכל על הקוד שנוצר (JavaScript, Python, PHP, Lua, Dart וכו') ולזהות באופן מיידי את התוכנית שכתבו. לכן צריך להשקיע מאמץ נוסף כדי לשמור על הקריאוּת של הקוד שנוצר על ידי המכונה. סוגריים מיותרים, משתנים מספריים, רווחים קטנים מדי ותבניות קוד מפורטות מדי – כל אלה מפריעים ליצירת קוד אלגנטי. הקוד שנוצר צריך לכלול הערות ותואמות להנחיות הסגנון של Google.
המלצה: גאים בקוד שנוצר. מציגים אותה למשתמש.
לקבל את ההבדלים בין השפות
תופעת לוואי של הרצון לקוד נקי היא שההתנהגות של Blockly מוגדרת במידה רבה לפי האופן שבו מתנהגת השפה המתורגמת. שפת הפלט הנפוצה ביותר היא JavaScript, אבל אם Blockly יתבצע הידור חוצה לשפה אחרת, אין לנסות באופן לא סביר לשמר את ההתנהגות המדויקת בשתי השפות. לדוגמה, ב-JavaScript מחרוזת ריקה היא false, ואילו ב-Lua היא true. הגדרת דפוס התנהגות יחיד לקוד של Blockly שיתבצע ללא קשר לשפת היעד תוביל לקוד שלא ניתן לתחזק שנראה כאילו הוא יצא ממנגנון הידור GWT.
המלצה: Blockly היא לא שפה, צריך לאפשר לשפה הקיימת להשפיע על ההתנהגות.