OpenLisp

OpenLisp היא שפת תכנות ממשפחת שפות ה־Lisp. היא פותחה על ידי כריסטיאן ג'וליאן מתאגיד Eligis בשנת 1988. היא כתובה בשפת C ובשפת Lisp, ורצה על רוב מערכות ההפעלה הפופולריות. OpenLisp היא מרובת פרידגמות, כלומר, השפה תומכת במספר עקרונות תכנותיים שונים (למשל תכנות פונקציונלי, תכנות אימפרטיבי ותכנות מונחה-עצמים). היות שאחת ממטרות השפה היא להשתלב באפליקציות בשפות תכנות פופולריות יותר כגון C, , Java, Visual Basic וכו', OpenLisp משומשת פעמים רבות כספריה (בשפות מבית מיקרוסופט – כ־dll).

== ממשק משתמש ==
ניתן להריץ את OpenLisp במצב קונסולה – במערכת ההפעלה windows בשורת הפקודה ובמערכות הפעלה ממשפחת Unix כגון MacOS ו־Linux ב־Terminal.
<syntaxhighlight lang="lisp">
;; OpenLisp v10.x.y (Build: XXXX) by C. Jullien [Jan 01 20xx - 10:49:13]
 ;; Copyright (c) Eligis - 1988-20xx.
 ;; System 'sysname' (64-bit, 8 CPU) on 'hostname', ASCII.
 ;; God thank you, OpenLisp is back again!
 ? (fib 20)
 ;; elapsed time = 0.003s, (0 gc).
 = 6765
 ? _
</syntaxhighlight>
בנוסף, ניתן לכתוב ולהריץ את OpenLisp באמצעות עורך הטקסט Emacs, או באמצעות סביבת פיתוח משולבת (תוכנת מחשב שמסייעת בתהליך התכנות וכוללת בדרך כלל עורך טקסט, מהדר, דיבאגר וכו') אשר תומכת בכך כגון LispIDE.

== היסטוריה ==
{| class="wikitable"
|+אבני דרך בפיתוח OpenLisp
!שנה
!גרסה
!פיצ'ר עיקרי
|-
|1988
|1.0
|OpenLisp החלה בשם MLisp (קיצור של Minimal Lisp) על מנת לערוך ניסויים על רעיונות משפת ISLISP
|-
|1993
|3.3
|שם השפה שונה ל-OpenLisp, ונוצר ההיסב הראשון למכונה של 64 סיביות (DEC Alpha OSF/1)
|-
|1994
|4.0
|השימוש המסחרי הראשון
|-
|1995
|4.5
|תמיכה ב-Socket Streams
|-
|1997
|5.7
|OpenLisp הפכה לשפה הראשונה ממשפחת Lisp אשר מימשה את התקן ISLISP ISO/IEC
|-
|1998
|5.8
|תמיכה אופציונלית ביוניקוד
|-
|2000
|6.6
|מהירות השפה הוכפלה פי 2.
|-
|2003
|7.5
|Lisp to C backend; able to compile an application with many Lisp files to a standalone executable; speed improved from 10x to 20x
|-
|2007
|8.7
|Changes to match ISO/IEC 13816:2007(E) revision
|-
|2010
|9.2
|Native integer arbitrary-precision arithmetic support
|-
|2020
|10.9
|הגרסה האחרונה
|}

== פיצ'רים ==
=== שרת אינטרנט ב-OpenLisp ===
<small>*הדוגמה הבאה נלקחה מהאתר הרשמי של מפתח שפת OpenLisp.</small> <syntaxhighlight lang="html">
#!/usr/bin/env openlisp -odsp
<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE html
 PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
 "DTD/xhtml1-frameset.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
 <title>OpenLisp Server Page Sample</title>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
 <meta http-equiv="Pragma" content="no-cache" />
 
 <meta name="Generator" content="OpenLisp Server Page" />
 <meta name="robots" content="noindex,follow" />
</head>

<body>
 <p>
 <?openlisp

 (require 'datetime)

 (let ((val (machine-info)))
 (format (standard-output) "~A on ~A~%" (current-date) (elt val 1)))
 ?>
 </p>
 <p>
 Openlisp v<?openlisp (prin (version)) ?> Server Page, computes Fib serie:
 <br />
 <br />
 <table border = "1"
 bordercolor = "#000000"
 cellpadding = "4"
 cellspacing = "1"
 >
 <tbody>
 <?openlisp

 ;; nice way to WEB around!!!

 (require 'cgi) ;; not really needed for this sample

 (defun fib (n)
	;; Standard function with integer argument
	(cond ((= n 1) 1)
 ((= n 2) 1)
 (t (+ (fib (1- n)) (fib (- n 2))))))

 (for ((i 1 (1+ i)))
 ((> i 20))
 (format (standard-output)
 "<tr><td>(fib ~D)</td><td>~D</td></tr>~%" i (fib i)))

 ?>
 </tbody>
 </table>
 </p>
</body>

</html>
</syntaxhighlight>בקטע הקוד לעיל, שילבנו את OpenLisp ב-HTML, כתבנו באופן רקורסיבי את סדרת פיבונאצ'י, והשתמשנו בפעולה זו. יש לשים לב כי בסביבה זו נכתוב את הקוד ב-OpenLisp בתוך התגית: <syntaxhighlight lang="lisp">
<?openlisp

?>
</syntaxhighlight>

== היסבים ==
משמעות המושג היסב במדעי המחשב הוא מימוש תוכנה בפלטפורמה מסוימת. לתוכנות עם היסבים למערכות הפעלה רבות, ישנו קהל משתמשים גדול יותר.

ל-OpenLisp ישנם יותר מ-90 היסבים<ref></ref> במערכות הפעלה ופלטפורמות שונות, כגון Windows, רוב מערכות ההפעלה ממשפחת יוניקס (במשפחה זו כלולים MacOS ולינוקס), DOS ועוד.

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

הגדרת פעולה רקורסיבית לסדרת פיבונאצ'י ב-OpenLisp:<syntaxhighlight lang="lisp">
(defun fib (n)
 (cond ((eq n 1) 1)
 ((eq n 2) 1)
 (t (+ (fib (- n 1)) (fib (- n 2))))))
</syntaxhighlight>פעולה זו תקבל מקום (אינדקס) בסדרת פיבונאצ'י ותחזיר את הערך במקום זה. בכל הרצה של הפעולה, אם האינדקס הנוכחי n שווה ל-1 או ל-2, ערך הביטוי יהיה 1. אחרת, הביטוי יצטמטם לסכום הזימון של הפעולה עם אינדקס n-1 וזימון של הפעולה עם אינדקס n-2, שכן זו ההגדרה הרקורסיבית של סדרת פיבונאצ'י: כל איבר שווה לסכום האיבר הקודם והאיבר הקודם לאיבר הקודם. ההתניה מבוצעת באמצעות אופרטור cond (המקביל של המילה השמורה "if" לצורך התניות בחלק מניבי Lisp).

המהדר מתרגם את קוד המקור לקוד ביניים, וכן מבצע אופטמיזציה בטכניקת Peephole Optimization. מצורף קוד הביניים לאחר האופטמיזציה:<syntaxhighlight lang="lisp">
 ((fentry fib 1 0 0)
 (param 0)
 (jeq _l004 '1)
 (jneq _l003 '2)
 (move a1 '1)
 (return)
 _l003
 (gsub1 a1)
 (recurse 1)
 (move a2 a1)
 (param 0)
 (gsub a1 '2)
 (recurse 1)
 (gadd a2 a1)
 _l004
 (return)
 (end))
</syntaxhighlight>לאחר מכן, מתורגם קוד הביניים לשפת התכנות C:<syntaxhighlight lang="c">
static POINTER
OLDEFCOMPILED1(olfib_00, p1) {
 POINTER a1;
 POINTER VOLATILE a2;

 ollapenter(SN_OLFIB_00);
 a1 = p1;
 if (eq(a1, olmakefix(1))) goto _l004;
 if (!eq(a1, olmakefix(2))) goto _l003;
 ollapleave(SN_OLFIB_00);
 return olmakefix(1);
_l003:
 a1 = ollapgsub(a1, olmakefix(1));
 a2 = olfib_00(a1);
 a1 = ollapgsub(p1, olmakefix(2));
 a1 = olfib_00(a1);
 a1 = ollapgadd(a2, a1);
_l004:
 ollapleave(SN_OLFIB_00);
 return a1;
}
</syntaxhighlight>

== משפחת שפות Lisp ==
{| class="wikitable"
|+ציר זמן של פיתוח ניבי Lisp
!1955
!1960
!1965
!1970
!1975
!1980
!1985
!1990
!1995
!2000
!2005
!2010
!2015
!2019
|-
! colspan="3" |LISP 1, 1.5, LISP 2<sup>(abandoned)</sup>
| colspan="10" |
|-
| colspan="2" |
! colspan="5" |Maclisp
| colspan="6" |
|-
| colspan="3" |
! colspan="5" |Interlisp
| colspan="5" |
|-
| colspan="4" |
! colspan="5" |Lisp Machine Lisp
| colspan="4" |
|-
| colspan="4" |
! colspan="4" |Scheme
! colspan="2" |R5RS
! colspan="1" |R6RS
! colspan="3" |R7RS small
|-
| colspan="4" |
! colspan="2" |NIL
|-
| colspan="5" |
! colspan="2" |Franz Lisp
|-
| colspan="5" |
! colspan="9" |Common Lisp
|-
| colspan="5" |
! colspan="9" |Le Lisp
|-
| colspan="6" |
! colspan="3" |T
| colspan="4" |
|-
| colspan="6" |
! colspan="8" |Chez Scheme
|-
| colspan="6" |
! colspan="8" |Emacs Lisp
|-
| colspan="6" |
! colspan="8" |AutoLISP
|-
| colspan="6" |
! colspan="8" |PicoLisp
|-
| colspan="7" |
! colspan="6" |EuLisp
|-
| colspan="7" |
! colspan="8" |ISLISP
|-
| colspan="7" |
! colspan="8" |OpenLisp
|-
| colspan="7" |
! colspan="4" |PLT Scheme
! colspan="3" |Racket
|-
| colspan="7" |
! colspan="7" |GNU Guile
|-
| colspan="9" |
! colspan="5" |Visual LISP
|-
| colspan="10" |
! colspan="2" |Qi, QiII
! colspan="2" |Shen
|-
| colspan="10" |
! colspan="4" |Clojure
|-
| colspan="10" |
! colspan="4" |Arc
|-
| colspan="10" |
! colspan="4" |LFE
|-
| colspan="11" |
! colspan="3" |Hy
|}

== מוסכמות כתיבה ==
=== אורך שורת הקוד ===
אם כי ניתן לכתוב מספר בלתי מוגבל של תווים בשורה, מומלץ לכתוב עד כ-80 תווים בשורה.

== מילות שמורות ופעולות ==
<small>*נלקח מן הדוקומנטציה של OpenLisp.</small>
{| class="wikitable"
|Symbol slot
|Define form
|Access form
|Modification form
|Test form
|Unbound form
|-
|name
|-
|symbol-name
|-
|-
|-
|-
|property list
|-
|symbol-plist
|set-symbol-plist
|-
|-
|-
|package
|defpackage
|symbol-package
|set-symbol-package
|-
|-
|-
|function
|defun
|symbol-function
|set-symbol-function
|fboundp
|fmakunbound
|-
|macro
|defmacro
|macro-function
|set-macro-function
|macro-function
|fmakunbound
|-
|dynamic value
|defdynamic
|symbol-value
|set-symbol-value
|boundp
|makunbound
|-
|global value
|defglobal
|symbol-global
|set-symbol-global
|gboundp
|gmakunbound
|-
|constant value
|defconstant
|symbol-global
|-
|constantp
|gmakunbound
|}

=== פעולות מובנות ב-OpenLisp ===

<code><set symbol value) -> <object)</code>

פעולת <code>set</code> משנה את הערך של משתנה דינמי בשם המשתנה (<code>symbol</code>) לערך הנתון (<code>value</code>).

<code>(<concat symbol<sub>1</sub> … symbol<sub>N</sub>) -> <symbol)</code>

<code>concat</code> (מהמילה concatenate) – מחזיר את השרשור של הערכים המוכנסים לפעולה. שרשור היא פעולה בינארית אשר מאגדת את שני האופרנדים. לדוגמה, כאשר נשרשר את המילה hello עם המילה world נקבל helloworld.

== קישורים חיצוניים ==
* 
[http://christian.jullien.free.fr/ OpenLisp, כריסטיאן ג'וליאן]

==הערות שוליים==

קטגוריה:ניבי Lisp