PL/I

PL/I (קרי: "פי אל ואן", קיצור של Programming Language One) היא שפת תכנות אימפרטיבית, פרוצדורלית, שפותחה באמצע שנות ה-60 על ידי חברת IBM. השפה נועדה להחליף את שתי השפות הנפוצות באותו זמן, FORTRAN ו-COBOL. בעוד ששפת פורטרן נועדה לשימושים מדעיים, ואילו קובול נועדה לשימושים מסחריים, PL/I נועדה להיות שפת תכנות למטרות כלליות - "הכל עבור כולם" - ולשמש ליישומים מדעיים, הנדסיים ומסחריים ואף לתכנות מערכות.

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

כיום PL/I איננה בשימוש נפוץ. בין הסיבות לכך מקובל למנות את גודלה העצום (מילות מפתח רבות, מבנים תחביריים רבים, ומספר עודף של טיפוסי נתונים בסיסיים המובנים בשפה) המקשה על לימוד השפה; וכן הקושי לכתוב לה מהדר יעיל, תכונה שהביאה לכך שמהדרים יעילים היו מסחריים ויקרים.

לשפת PL/I דיאלקטים רבים, ורבים מתוכם (לדוגמה PL/M) מבוססים על הרעיון של צמצום של השפה, כך שתהיה קלה יותר ללמידה והידור.

היסטוריה
בשנות ה-50 ותחילת שנות ה-60 מתכנתים עבור יישומים מסחריים ומדעיים השתמשו בחומרה שונה ובשפות תכנות שונות. עבור יישומים מדעיים תכנתו בעיקר בשפת פורטרן, וכן (במידה מעטה) במספר שפות נוספות כגון GIP, ALGOL, GEORGE ועוד. יישומים מסחריים פותחו בעיקר בקובול. המחשב IBM System/360 פותח על מנת לתת מענה לשתי קבוצות המשתמשים, ולכן IBM חיפשה גם שפת תכנות שתיתן מענה מספק עבורן. ב-IBM קיוו להרחיב את שפת פורטרן כך שתתן מענה גם ליישומים מסחריים. בשנת 1963 התגבשה ועדה של חברי IBM שהחלה לתכנן הרחבה של שפת פורטרן. הם לא הצליחו להתגבר על המגבלות הקיימות בשפה, ולכן החליטו לתכנן שפה חדשה לחלוטין, שתתבסס במידת-מה על שפת אלגול שפורסמה זמן לא רב קודם לכן.

השפה הייתה אמורה להיקרא NPL (ראשי תיבות של New Programming Language) אך למניעת בלבול עם שמה של המעבדה הפיזיקלית של בריטניה (National Physical Laboratory) שונה השם תחילה ל- MPPL (MultiPurpose Programming Language), ולאחר מכן ל-PL/I, כאשר I מסמנת את הייצוג בספרות רומיות לספרה 1.

ההגדרה הראשונה של השפה פורסמה בשנת 1964. השפה הוגדרה פורמלית במספר צעדים: בשנת 1965 פורסם מדריך למשתמש, בשנת 1967 פורסמו דרישות פורמליות לשפה, ובשנת 1976 התקבל תקן עבורה. הפצת המהדר לשפה החלה בשנת 1966.

השפה פותחה לסביבת IBM Mainframe, ובמהלך השנים נוצרו גם גרסאות יוניקס, Windows ו- OpenVMS שלה. כיום PL/I אינה מהווה שפה שבה מקובל לפתח מערכות חדשות, אף שחברת IBM ממשיכה לפתח את השפה וליצור גרסאות חדשות שלה, ועדיין פועלות בהצלחה מערכות שנכתבו בעבר בשפה זו.

עם התפתחות התכנות המובנה, בשנות ה-70, אמצה PL/I את עקרונותיו, ונוספו לה מבני בקרה המאפשרים כתיבה לפי עקרונות אלה.

הצלחה בתעשייה
ביחס לתכנון, PL/I לא עמדה ביעדים שהציבו מתכנניה.
PL/I התחרתה בעיקר בשלוש שפות:
FORTRAN, שהייתה השפה העיקרית ליישומים מדעיים.
COBOL, שהייתה השפה הנפוצה ליישומים מסחריים.
ALGOL, שפותחה מעט לפניה. אלגול התקבלה באקדמיה אך לא בתעשייה, אם כי השיגה תפוצת-מה באירופה.
PL/I נכשלה בניסיון להחליף את קובול ופורטרן, אך הצליחה (בעזרת כוח השוק של IBM, מפתחת השפה) להאפיל על שפת אלגול. עם זאת, ל-PL/I (בדומה לשפת קובול) השפעה מעטה על שפות שהופיעו אחריה, יחסית לפורטרן ואלגול.

אחד מהפרויקטים הראשונים שפותחו בשפת PL/I הוא מערכת ההפעלה Multics.

בשנות ה-70 זכתה PL/I לתפוצה רחבה יחסית, וכן נעשה בה שימוש במוסדות אקדמיים כשפה אותה לימדו (היא הוחלפה על ידי שפת פסקל, שתוכננה למטרה זאת, בסוף שנות ה-70). שפת PL/I נלמדה באוניברסיטאות בישראל (אלה שהעמידו מחשב IBM לרשות תלמידיהן) עד אמצע שנות ה-80. כמו כן, PL/I זכתה לתפוצה בגוש המזרחי, יותר מאשר בעולם המערבי.

מאפיינים
PL/I תומכת בתכנות פרוצדורלי, וזהו יתרון בולט שלה על COBOL, המתחרה העיקרית שלה בשנות ה-60 וה-70.

כלים שלראשונה הופיעו ב-PL/I:
תמיכה בתכנות מקבילי.
תמיכה ב-23 סוגי חריגות בזמן ריצה.
מצביע כטיפוס נתונים.
 ניהול זיכרון דינמי: משתנים חולקו לארבע קטגוריות מבחינת ניהול הזיכרון:
 AUTOMATIC: המשתנה נוצר עם הפעלת הפרוצדורה שבה הוא מוגדר, ונעלם עם סיום הפעלת הפרוצדורה. משתנים כאלה הם גם בעלי תחום הכרזה (Scope) מוגבל, תכונה התורמת לקריאות של התוכנית. ומגדילה את אוסף המזהים בהם המתכנת יכול להשתמש. מאפיין זה הוא ברירת מחדל להגדרת משתנה.
 STATIC: משתנה המתקיים במשך כל זמן פעולתה של התוכנית. בתוכניות שרצות תחת CICS אסור לשנות תוכן של משתנה כזה (כלומר מכיל תוכן קבוע).
 CONTROLLED: משתנה שהתוכנית קובעת מתי ייווצר ומתי יפנה את הזיכרון - משתנה כזה מוקצה באופן דינמי על גבי זיכרון הערימה. שפת PL/I איננה כוללת מנגנון איסוף זבל.
 BASED: משתנה המבוסס על הזיכרון שהוקצה למשתנה אחר. בעזרת קטגוריה זאת המתכנת יכול להגדיר מנגנון הקצאת זיכרון דינמי משלו, התפור לצורכי התוכנית.

יכולות נוספות:
 תמיכה ברקורסיה.
 אוסף נרחב של פונקציות (built-in functions) לעיבוד של מספרים, מחרוזות, מצביעים ועוד.

בשפה יש שימוש נרחב (יש הסבורים שמוגזם) בברירות מחדל בהגדרה של משתנים. משתנה שאינו מוגדר, יוגדר אוטומטית (בדומה לפורטרן) על ידי המהדר כ FIXED BIN (כלומר מספר בינארי בנקודה קבועה) כאשר שמו מתחיל באותיות I עד N ואחרת יוגדר כמשתנה FLOAT (נקודה צפה). עם זאת, רשימת כל המשתנים שלא הוגדרו מוצגת באזהרה של המהדר, כך שניתן לזהותם ולהגדירם. בהגדרה של משתנה אין צורך לתת את כל מאפייניו, משום שגם למאפיינים יש ברירות מחדל.

תחביר
מאפיינים תחביריים של השפה:
תחביר השפה הוא דמוי-אנגלית, מאפיין שנלקח משפת COBOL, אך הוא קומפקטי במידה ניכרת מזה של COBOL.
פקודות מסתיימות בנקודה ופסיק (;), בדומה לשפות ממשפחת-אלגול.
פרוצדורות נפתחות במילה PROC ומסתיימות במילה END.
בלוקים נפתחים במילה BEGIN ומסתיימים במילה END.
האופרטור '=' משמש הן לפעולת השמה והן לפעולת השוואה, בתלות בהקשר שבו הוא נמצא.
כמקובל במרבית שפות התכנות, PL/I אינה מתירה הגדרה של מזהים (עבור משתנים ופרוצדורות) הכוללים רווחים. הפרדה בין מילים במזהה נעשית באמצעות מקף תחתון (למשל: NEXT_PRIME).

מילות מפתח
מילות המפתח של השפה אינן מילים שמורות, וניתן להשתמש בהם גם כמזהים. הקוד הבא, לדוגמה, חוקי (אם כי אינו מקובל):
IF IF = THEN THEN THEN = ELSE ELSE ELSE = IF;
בשורה זו נבדק האם ערכו של המשתנה IF זהה לערכו של המשתנה THEN. אם כן, מושם במשתנה THEN ערכו של המשתנה ELSE; אחרת מושם במשתנה ELSE ערכו של המשתנה IF. ניתן להבחין בכך שהמלים IF, THEN ו-ELSE משמשות גם כמילות מפתח בשפה, וגם כשמות של משתנים. המשמעות של כל מופע של מילה ספציפית נקבעת לפי ההקשר. מאפיין זה מסבך את שלב הניתוח הלקסיקלי של הקוד (השלב הראשון בהידור), כיוון שהמנתח הלקסיקלי, המבוסס על פי רוב על ביטויים רגולריים, איננו יכול לדעת אם המילה בה הוא נתקל משמשת כמזהה או כמילת מפתח.

חופש זה של PL/I הביא לכך שבהגדרת השפה עצמה לאותה מילה יש לעיתים שתי משמעויות, בהתאם להקשר. דוגמה: המילה FIXED משמשת במסגרת פקודת DECLARE להגדרה של משתנה בנקודה קבועה, ומשמשת גם כפונקציה המחזירה את החלק השלם של מספר (בדוגמת הקוד שלהלן מופיעה המילה בשתי משמעויותיה).

דוגמת קוד
תוכנית Hello World:
HELLO: PROCEDURE OPTIONS (MAIN);
/* A PROGRAM TO OUTPUT HELLO WORLD */
PUT SKIP LIST ('HELLO WORLD!');
END HELLO;

דוגמה לפונקציית PL/I הבודקת האם מספר נתון הוא מספר ראשוני:

PRIMALITY: PROC (NUMBER) RETURNS (BIT (1)); /* בדיקת ראשוניות של מספר */
DECLARE NUMBER FIXED (9); /* המספר הנבדק */
DECLARE F FIXED (9);
DO F=2 TO SQRT (NUMBER); /* לולאה עד שורש המספר הנבדק */
IF FIXED (NUMBER / F) * F = NUMBER
THEN RETURN ('0'B); /* המספר אינו ראשוני */
END;
RETURN ('1'B); /* המספר ראשוני */
END PRIMALITY;

קישורים חיצוניים 
 
 
 IBM PL/I Compilers for z/OS, AIX, MVS, VM and VSE
 Iron Spring Software, PL/I for Linux and OS/2
 Kednos PL/I for OpenVMS and Tru64

שפות תכנות
תוכנות מבית IBM