
היכרות ידידותית עם Racket: השפה המודרנית של משפחת Lisp
בבלוג geometridae.bearblog.dev פורסם מדריך ידידותי ל-Racket — השפה שממשיכה את מסורת Lisp מ-1958 ומאפשרת לקורא לכתוב עד סוף המדריך תחביר משל עצמו, כולל מאקרו ולולאה משלו.
מדריך ידידותי ל-Racket — הצאצא המודרני של אחת ממשפחות השפות הוותיקות והמוזרות ביותר בתכנות — פורסם בבלוג geometridae.bearblog.dev. ההבטחה של המחבר פשוטה: בסוף המדריך הקורא כבר יכתוב את התחביר של עצמו.
מ-Lisp ל-Scheme ול-Racket
Lisp נוצרה ב-1958 בידי ג'ון מקארתי ב-MIT. זוהי שפת הרמה הגבוהה השנייה בוותקה שעדיין בשימוש: רק Fortran (1957) מקדימה אותה בשנה אחת. Python הופיעה ב-1991 ו-JavaScript ב-1995.
דווקא ב-Lisp נולדו הרעיונות שכיום מכנים מודרניים: איסוף זבל, פונקציות כערכים ממעלה ראשונה, לולאת REPL, תנאים שמחזירים ערך והומואיקוניות — התכונה שלפיה הקוד עצמו הוא מבנה נתונים של השפה. בשנות ה-70 וה-80 Lisp אף רץ ישירות על חומרה, במכונות ה-Lisp של Symbolics ו-LMI. אחרי ״החורף של הבינה המלאכותית״ המימון יבש והשפה איבדה את מעמד הכוכב.
ב-1975 יצרו ג'רלד סאסמן וגאי סטיל את Scheme — Lisp מינימליסטי וכמעט מתמטי, שעליו נכתב הספר הקלאסי SICP. ב-1995 יצרה הקבוצה של מתיאס פלייזן את PLT Scheme, ששמה שונה ל-Racket ב-2010. כיום זו הרבה יותר מ-Scheme: זו שפה לבניית שפות, והמוטו הלא רשמי שלה הוא תכנות מונחה-שפה.
מי משתמש ב-Lisp היום
יותר אנשים ממה שנדמה. Clojure רץ בפרודקשן בבנקים, בחברות תעופה ובסטארטאפים — Nubank, הבנק הדיגיטלי הגדול באמריקה הלטינית, בנוי עליו. Common Lisp עם המהדר SBCL עדיין חי במערכות מומחה, בתכנון טיסות (ITA Software, שנרכשה בידי גוגל והפכה לבסיס של Google Flights) ובחישובים מדעיים.
מיליוני אנשים מריצים Lisp כל יום בלי לשים לב: העורך שלהם, Emacs, הוא מפרש Lisp. GNU Guix היא הפצת Linux שלמה שמוגדרת כולה ב-Scheme. ל-Racket יש כנס שנתי משלה, RacketCon, והיא משמשת לחקר שפות, לאימות פורמלי (Rosette), לטיפוגרפיה ולהוצאה לאור (Pollen). גם Lisp-ים חדשים ממשיכים להופיע: Fennel, Janet ו-Hy.
איך נראה הקוד
ההתקנה אורכת חמש דקות: מתקין מ-racket-lang.org וסביבת DrRacket, שבה כותבים הגדרות למעלה ומריצים REPL למטה. השורה הראשונה של הקובץ היא #lang racket — היא בוחרת את השפה, שהרי Racket היא מפעל של שפות.
כלל Lisp נכנס לשורה אחת: הכול הוא (אופרטור ארגומנט1 ארגומנט2…), בלי יוצאים מן הכלל. (+ 1 2) מחזיר 3, (* 3 (+ 2 2)) מחזיר 12, ו-(string-append "hello " "world") מחזיר את המחרוזת hello world. אין קדימות לאופרטורים ואין תחביר מיוחד; define יוצר קבוע או פונקציה, ו-lambda יוצר פונקציה אנונימית.
Lisp פירושה עיבוד רשימות: (first '(1 2 3)) מחזיר 1, (rest '(1 2 3)) מחזיר (2 3), ו-(cons 0 '(1 2 3)) מחזיר (0 1 2 3). עם map, filter ו-foldl אפשר לפתור את רוב בעיות הרשימות בלי לולאת for אחת. רקורסיה היא הסגנון הטבעי — עצרת נכתבת כך שמקרה הבסיס והצעד לקראתו נראים מיד — ובעזרת הספרייה 2htdp/image כמה שורות מספיקות כדי לצייר משולש סיירפינסקי.
השיא הוא מאקרו: הגרש ' הופך קוד לנתונים, ו-eval מריץ נתונים כקוד. באמצעות define-syntax-rule המדריך אף מוסיף לשפה לולאת while שאינה קיימת בה. אלן קי כינה את Lisp ״המשוואות של מקסוול של התוכנה״ — ליבה זעירה שממנה נגזר כל השאר. לקריאה נוספת ממליץ המחבר על How to Design Programs, The Racket Guide, Beautiful Racket ו-SICP.
SiTech — פיתוח אתרים בכוח ה-AI
אנחנו בונים אתרים מהירים ומודרניים ומשלבים AI בתהליכי עבודה אמיתיים. יש לכם פרויקט או שאלה? נשמח לעזור.