Ortak Lisp - Common Lisp

Ortak Lisp
paradigma Çoklu paradigma : prosedürel , işlevsel , nesne yönelimli , meta , yansıtıcı , genel
Aile Lisp
Tarafından tasarlandı Scott Fahlman , Richard P. Gabriel , David A. Moon , Kent Pitman , Guy Steele , Dan Weinreb
geliştirici ANSI X3J13 komitesi
İlk ortaya çıktı ANSI Common Lisp için 1984 (37 yıl önce) , 1994 (27 yıl önce) ( 1984 ) ( 1994 )
Yazma disiplini Dinamik , güçlü
Kapsam Sözcüksel, isteğe bağlı olarak dinamik
işletim sistemi Çapraz platform
Dosya adı uzantıları .lisp, .lsp, .l, .cl, .fasl
İnternet sitesi ortak lisp .net
Başlıca uygulamalar
Allegro CL , ABCL , CLISP , Clozure CL , CMUCL , ECL , GCL , LispWorks , Scieneer CL , SBCL , simgecilik Common Lisp
lehçeler
CLtL1, CLtL2, ANSI Ortak Lisp
Tarafından etkilenmiş
Lisp , Lisp Makine Lisp , Maclisp , Şema , Interlisp
Etkilenen
Clojure , Dylan , Emacs Lisp , EuLisp , ISLISP , *Lisp , AutoLisp , Julia , Moose , R , SKILL , SubL

Common Lisp ( CL ), ANSI standart belgesi ANSI INCITS 226-1994 (S20018) (eski adıyla X3.226-1994 (R1999) ) içinde yayınlanan Lisp programlama dilinin bir lehçesidir . Köprü bağlantılı bir HTML sürümü olan Common Lisp HyperSpec , ANSI Common Lisp standardından türetilmiştir.

Common Lisp dili, Maclisp'in standartlaştırılmış ve geliştirilmiş bir halefi olarak geliştirildi . 1980'lerin başında birkaç grup MacLisp'in çeşitli ardılları üzerinde zaten çalışıyordu: Lisp Machine Lisp (diğer adıyla ZetaLisp), Spice Lisp , NIL ve S-1 Lisp . Common Lisp, bu MacLisp lehçelerinin özelliklerini birleştirmeye, standartlaştırmaya ve genişletmeye çalıştı. Common Lisp bir uygulama değil, bir dil belirtimidir . Ücretsiz ve açık kaynaklı yazılımlar ve tescilli ürünler dahil olmak üzere Common Lisp standardının çeşitli uygulamaları mevcuttur . Common Lisp, genel amaçlı, çok paradigmalı bir programlama dilidir . Prosedürel , işlevsel ve nesne yönelimli programlama paradigmalarının bir kombinasyonunu destekler . Bir olarak dinamik programlama dili , bu evrimsel ve kolaylaştırır artan yazılım geliştirme yinelemeli ile, derleme verimli çalışma zamanı programlara. Bu artımlı geliştirme, genellikle çalışan uygulamayı kesintiye uğratmadan etkileşimli olarak yapılır.

Ayrıca , derleyicinin daha verimli kod oluşturmasına izin vermek için daha sonraki profil oluşturma ve optimizasyon aşamalarında gerektiğinde eklenebilen isteğe bağlı tür açıklama ve dökümünü de destekler . Örneğin , donanım ve uygulama tarafından desteklenen bir aralıkta kutusuz bir tamsayı fixnumtutabilir , bu da büyük tamsayılardan veya rastgele kesinlik türlerinden daha verimli aritmetik sağlar. Benzer şekilde, derleyiciye, optimize bildirimleri kullanılarak, modül başına veya işlev başına hangi tür güvenlik seviyesinin istendiği söylenebilir .

Common Lisp, çoklu yöntemleri ve yöntem kombinasyonlarını destekleyen bir nesne sistemi olan CLOS'u içerir . Genellikle bir Metanesne Protokolü ile uygulanır .

Common Lisp, Lisp makroları (kod dönüşümleri) ve okuyucu makroları (karakterler için giriş ayrıştırıcıları ) gibi standart özellikler aracılığıyla genişletilebilir .

Common Lisp, Maclisp ve John McCarthy'nin orijinal Lisp'i ile kısmi geriye dönük uyumluluk sağlar . Bu, eski Lisp yazılımının Common Lisp'e taşınmasına izin verir.

Tarih

Common Lisp üzerindeki çalışmalar, ARPA yöneticisi Bob Engelmore'un tek bir topluluk standardı Lisp lehçesi geliştirme girişiminden sonra 1981'de başladı. İlk dil tasarımının çoğu elektronik posta yoluyla yapıldı. 1982'de Guy L. Steele Jr. , LISP ve fonksiyonel programlama üzerine 1982 ACM Sempozyumu'nda Common Lisp'e ilk genel bakışı verdi.

İlk dil belgeleri 1984'te Common Lisp the Language (CLtL1 olarak bilinir) olarak yayınlandı, ilk baskı. 1990'da yayınlanan ikinci bir baskı (CLtL2 olarak bilinir), ANSI Common Lisp standardizasyon süreci sırasında dilde yapılan birçok değişikliği içeriyordu: genişletilmiş LOOP sözdizimi, Common Lisp Nesne Sistemi, hata işleme için Koşul Sistemi, güzel yazıcı ve çok daha fazlası. Ancak CLtL2, nihai ANSI Common Lisp standardını tanımlamaz ve bu nedenle ANSI Common Lisp'in bir belgesi değildir. Nihai ANSI Common Lisp standardı daha sonra 1994'te yayınlandı. O zamandan beri standartta herhangi bir güncelleme yayınlanmadı. Common Lisp için çeşitli uzantılar ve iyileştirmeler (örnekler Unicode, Concurrency, CLOS tabanlı IO'dur) uygulamalar ve kitaplıklar tarafından sağlanmıştır.

Sözdizimi

Common Lisp, Lisp'in bir lehçesidir. Hem kodu hem de veri yapısını belirtmek için S-ifadelerini kullanır . Fonksiyon çağrıları, makro formları ve özel formlar, aşağıdaki örneklerde olduğu gibi önce operatörün adı ile listeler halinde yazılır:

 (+ 2 2)           ; adds 2 and 2, yielding 4. The function's name is '+'. Lisp has no operators as such.
 (defvar *x*)      ; Ensures that a variable *x* exists,
                   ; without giving it a value. The asterisks are part of
                   ; the name, by convention denoting a special (global) variable. 
                   ; The symbol *x* is also hereby endowed with the property that
                   ; subsequent bindings of it are dynamic, rather than lexical.
 (setf *x* 42.1)   ; Sets the variable *x* to the floating-point value 42.1
 ;; Define a function that squares a number:
 (defun square (x)
   (* x x))
 ;; Execute the function:
 (square 3)        ; Returns 9
 ;; The 'let' construct creates a scope for local variables. Here
 ;; the variable 'a' is bound to 6 and the variable 'b' is bound
 ;; to 4. Inside the 'let' is a 'body', where the last computed value is returned.
 ;; Here the result of adding a and b is returned from the 'let' expression.
 ;; The variables a and b have lexical scope, unless the symbols have been
 ;; marked as special variables (for instance by a prior DEFVAR).
 (let ((a 6)
       (b 4))
   (+ a b))        ; returns 10

Veri tipleri

Common Lisp'in birçok veri türü vardır .

skaler tipler

Sayı türleri arasında tamsayılar , oranlar , kayan noktalı sayılar ve karmaşık sayılar bulunur . Common Lisp , rastgele boyut ve kesinliğin sayısal değerlerini temsil etmek için büyük sayıları kullanır . Oran türü, kesirleri tam olarak temsil eder, bu özellik birçok dilde mevcut değildir. Common Lisp, uygun olduğu şekilde bu türler arasında sayısal değerleri otomatik olarak zorlar.

Common Lisp karakter tipi, ASCII karakterleriyle sınırlı değildir . Çoğu modern uygulama Unicode karakterlere izin verir .

Sembol tipi Lisp dillerine yaygındır, ancak büyük ölçüde bilinmemektedir dışarıda onları. Bir sembol, ad, değer, işlev, özellik listesi ve paket gibi birkaç bölümden oluşan benzersiz, adlandırılmış bir veri nesnesidir. Bunlardan değer hücresi ve fonksiyon hücresi en önemlileridir. Lisp'teki semboller genellikle diğer dillerdeki tanımlayıcılara benzer şekilde kullanılır: bir değişkenin değerini tutmak için; ancak başka birçok kullanım var. Normalde, bir sembol değerlendirildiğinde değeri döndürülür. Bazı semboller kendilerini değerlendirir, örneğin anahtar kelime paketindeki tüm semboller kendi kendini değerlendirir. Common Lisp'teki Boole değerleri, kendi kendini değerlendiren semboller T ve NIL ile temsil edilir. Common Lisp, semboller için 'paketler' adı verilen ad alanlarına sahiptir.

Skaler sayısal değerleri çeşitli şekillerde yuvarlamak için bir dizi fonksiyon mevcuttur . İşlev round, argümanı en yakın tamsayıya yuvarlar, ortadaki durumlar çift tam sayıya yuvarlanır. Fonksiyonlar truncate, floorve ceilingyuvarlak karşı sıfır, aşağı ya da yukarı sırasıyla. Tüm bu işlevler, atılan kesirli kısmı ikincil bir değer olarak döndürür. Örneğin, (floor -2.5)verim -3, 0,5; (ceiling -2.5)verim -2, −0.5; (round 2.5)verim 2, 0,5; ve (round 3.5)4, −0.5 verir.

Veri yapıları

Common Lisp'teki dizi türleri, listeleri, vektörleri, bit vektörlerini ve dizileri içerir. Herhangi bir dizi türü üzerinde çalışabilen birçok işlem vardır.

Hemen hemen tüm diğer Lisp lehçelerinde olduğu gibi, Common Lisp'teki listeler , bazen eksi hücreler veya çiftler olarak adlandırılan eksilerden oluşur . Eksileri, car ve cdr olarak adlandırılan iki yuvalı bir veri yapısıdır . Liste, bağlantılı bir eksiler zinciri veya boş listedir. Her eksinin arabası, listenin bir üyesine atıfta bulunur (muhtemelen başka bir liste). Her eksinin cdr'si bir sonraki eksiye atıfta bulunur—bir listedeki cdr nildeğeri ifade eden son eksiler hariç . Eksiler, ağaçları ve diğer karmaşık veri yapılarını uygulamak için de kolayca kullanılabilir; bunun yerine genellikle yapı veya sınıf örnekleri kullanılması tavsiye edilir. Ayrıca eksileri olan dairesel veri yapıları oluşturmak da mümkündür.

Common Lisp çok boyutlu dizileri destekler ve gerekirse ayarlanabilir dizileri dinamik olarak yeniden boyutlandırabilir . Matris matematiği için çok boyutlu diziler kullanılabilir. Bir vektör, tek boyutlu bir dizidir. Diziler, herhangi bir türü üye olarak taşıyabilir (aynı dizideki karışık türleri bile) veya bir bit vektöründe olduğu gibi belirli bir üye türünü içerecek şekilde özelleştirilebilir. Genellikle, yalnızca birkaç tür desteklenir. Birçok uygulama, kullanılan dizi türe özel olduğunda dizi işlevlerini optimize edebilir. Türe özel iki dizi türü standarttır: bir dize bir karakter vektörüdür, bit vektörü ise bir bit vektörüdür .

Hash tabloları , veri nesneleri arasındaki ilişkileri depolar. Anahtar veya değer olarak herhangi bir nesne kullanılabilir. Hash tabloları gerektiğinde otomatik olarak yeniden boyutlandırılır.

Paketler , bir programın bölümlerini ad alanlarına ayırmak için kullanılan sembol koleksiyonlarıdır . Bir paket, bazı sembolleri, genel bir arabirimin parçası olarak işaretleyerek dışa aktarabilir . Paketler diğer paketleri kullanabilir.

Yapılar kullanım içindeki, Cı- yapılar ve Pascal kayıtları, alanlar (denilen herhangi bir sayıda ve türü ile isteğe bağlı karmaşık veri yapılarını temsil yuva ). Yapılar tek mirasa izin verir.

Sınıflar yapılara benzer, ancak daha dinamik özellikler ve çoklu kalıtım sunar. (Bkz. CLOS ). Sınıflar Common Lisp'e geç eklendi ve yapılarla bazı kavramsal örtüşmeler var. Sınıflardan oluşturulan nesnelere Instances denir . Özel bir durum Genel İşlevler'dir. Genel İşlevler hem işlevler hem de örneklerdir.

Fonksiyonlar

Common Lisp birinci sınıf işlevleri destekler . Örneğin, diğer fonksiyonları argüman olarak alan veya fonksiyon döndüren fonksiyonlar yazmak mümkündür. Bu, çok genel işlemleri tanımlamayı mümkün kılar.

Common Lisp kitaplığı, büyük ölçüde bu tür üst düzey işlevlere dayanır. Örneğin, sortişlev, bağımsız değişken olarak ilişkisel bir işleci ve isteğe bağlı bir anahtar sözcük bağımsız değişkeni olarak anahtar işlevi alır. Bu, yalnızca herhangi bir veri türünü sıralamak için değil, aynı zamanda veri yapılarını bir anahtara göre sıralamak için de kullanılabilir.

 ;; Sorts the list using the > and < function as the relational operator.
 (sort (list 5 2 6 3 1 4) #'>)   ; Returns (6 5 4 3 2 1)
 (sort (list 5 2 6 3 1 4) #'<)   ; Returns (1 2 3 4 5 6)
 ;; Sorts the list according to the first element of each sub-list.
 (sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)   ; Returns ((3 B) (4 C) (9 A))

Fonksiyonlar için değerlendirme modeli çok basittir. Değerlendirici bir formla karşılaştığında (f a1 a2...)f adlı sembolün aşağıdakilerden biri olduğunu varsayar:

  1. Özel bir operatör (sabit bir listeye göre kolayca kontrol edilir)
  2. Bir makro operatörü (önceden tanımlanmış olmalıdır)
  3. Bir sembol veya sembolü ile başlayan bir alt form olabilen bir fonksiyonun (varsayılan) adı lambda.

f bir işlevin adıysa, a1, a2, ..., an bağımsız değişkenleri soldan sağa sırayla değerlendirilir ve işlev bulunur ve parametre olarak sağlanan bu değerlerle çağrılır.

Fonksiyonları tanımlama

Makrodefun bir işlev tanımı işlevi, herhangi bir argüman isimleri ve işlev gövdesinin adını veren fonksiyonlarını tanımlar:

 (defun square (x)
   (* x x))

İşlev tanımları , derleyiciye optimizasyon ayarları veya argümanların veri türleri hakkında ipuçları sağlayan, bildirimler olarak bilinen derleyici yönergelerini içerebilir . Ayrıca , Lisp sisteminin etkileşimli belgeler sağlamak için kullanabileceği belge dizileri ( belge dizileri ) içerebilirler:

 (defun square (x)
   "Calculates the square of the single-float x."
   (declare (single-float x) (optimize (speed 3) (debug 0) (safety 1)))
   (the single-float (* x x)))

Anonim işlevler ( işlev değişmezleri ) lambdaifadeler kullanılarak tanımlanır , örneğin (lambda (x) (* x x))argümanının karesini alan bir işlev için. Lisp programlama stili sıklıkla, bağımsız değişkenler olarak anonim işlevler sağlamanın yararlı olduğu daha yüksek dereceli işlevleri kullanır.

Yerel işlevler fletve ile tanımlanabilir labels.

 (flet ((square (x)
          (* x x)))
   (square 3))

Fonksiyonların tanımı ve manipülasyonu ile ilgili başka operatörler de vardır. Örneğin, compileoperatör ile bir fonksiyon derlenebilir . (Bazı Lisp sistemleri, derleme talimatı verilmediği sürece varsayılan olarak bir yorumlayıcı kullanarak işlevleri çalıştırır; diğerleri her işlevi derler).

Genel işlevleri ve yöntemleri tanımlama

Makro defgeneric, genel işlevleri tanımlar . Genel işlevler, bir yöntemler topluluğudur . Makro defmethod, yöntemleri tanımlar.

Metotlar, parametrelerini CLOS standart sınıfları , sistem sınıfları , yapı sınıfları veya bireysel nesneler üzerinde özelleştirebilir . Birçok tür için karşılık gelen sistem sınıfları vardır .

Genel bir işlev çağrıldığında, çoklu gönderim kullanılacak etkili yöntemi belirleyecektir.

 (defgeneric add (a b))
 (defmethod add ((a number) (b number))
   (+ a b))
 (defmethod add ((a vector) (b number))
   (map 'vector (lambda (n) (+ n b)) a))
 (defmethod add ((a vector) (b vector))
   (map 'vector #'+ a b))
(defmethod add ((a string) (b string))
  (concatenate 'string a b))
 (add 2 3)                   ; returns 5
 (add #(1 2 3 4) 7)          ; returns #(8 9 10 11)
 (add #(1 2 3 4) #(4 3 2 1)) ; returns #(5 5 5 5)
 (add "COMMON " "LISP")      ; returns "COMMON LISP"

Genel İşlevler de birinci sınıf bir veri türüdür . Genel İşlevler ve Yöntemler için yukarıda açıklanandan çok daha fazla özellik vardır.

işlev ad alanı

İşlev adları için ad alanı, veri değişkenleri için ad alanından ayrıdır. Bu, Common Lisp ve Scheme arasındaki temel farktır . Common Lisp için, fonksiyon ad isimlerini tanımlayan operatörleri dahil defun, flet, labels, defmethodve defgeneric.

Bir işlevi başka bir işleve bağımsız değişken olarak adıyla iletmek için function, genellikle olarak kısaltılan özel işleci kullanmanız gerekir #'. Yukarıdaki ilk sortörnek >, fonksiyon isim alanındaki sembol tarafından kod ile isimlendirilen fonksiyona atıfta bulunmaktadır #'>. Tersine, bu şekilde iletilen bir işlevi çağırmak için, funcalloperatör argüman üzerinde kullanılır.

Scheme'in değerlendirme modeli daha basittir: yalnızca bir ad alanı vardır ve formdaki tüm konumlar (herhangi bir sırayla) değerlendirilir – yalnızca argümanlar değil. Bu nedenle, bir lehçede yazılan kod, bazen diğerinde daha deneyimli programcılar için kafa karıştırıcı olabilir. Örneğin, birçok Common Lisp programcısı , fonksiyon adlarını yerel olarak gölgeleyeceğinden, Scheme'de sorunlara neden olabilecek liste veya dize gibi açıklayıcı değişken adları kullanmayı sever .

İşlevler için ayrı bir ad alanının bir avantaj olup olmadığı, Lisp topluluğunda bir çekişme kaynağıdır. Genellikle Lisp-1 vs. Lisp-2 tartışması olarak anılır . Lisp-1, Scheme'in modelini ve Lisp-2, Common Lisp'in modelini ifade eder. Bu isimler, Richard P. Gabriel ve Kent Pitman tarafından , iki yaklaşımı kapsamlı bir şekilde karşılaştıran 1988 tarihli bir makalede bulundu .

Çoklu dönüş değerleri

Common Lisp , herhangi bir ifadenin her zaman tek bir birincil değere sahip olduğu , ancak ilgili arayanlar tarafından alınabilecek ve incelenebilecek herhangi bir sayıda ikincil değere sahip olabileceği birden çok değer kavramını destekler . Bu kavram, ikincil değerler tamamen isteğe bağlı olduğundan ve özel bir yan kanal aracılığıyla iletildiğinden, bir liste değeri döndürmekten farklıdır. Bu, arayanların, ihtiyaçları yoksa orada bulunan ikincil değerlerden tamamen habersiz kalabilecekleri anlamına gelir ve bu, bazen yararlı olan, ancak her zaman gerekli olmayan bilgileri iletmek için mekanizmayı kullanmayı kolaylaştırır. Örneğin,

  • TRUNCATEİşlevi numarası verilen yuvarlar tamsayı sıfıra. Ancak, aynı zamanda ikincil bir değer olarak bir kalanı döndürür, bu da hangi değerin kesildiğini belirlemeyi çok kolaylaştırır. Ayrıca, Öklid bölünmesini önemsiz bir şekilde gerçekleştirmek için kullanılabilecek isteğe bağlı bir bölen parametresini de destekler :
(let ((x 1266778)
      (y 458))
  (multiple-value-bind (quotient remainder)
      (truncate x y)
    (format nil "~A divided by ~A is ~A remainder ~A" x y quotient remainder)))

;;;; => "1266778 divided by 458 is 2765 remainder 408"
  • GETHASHilişkisel bir haritadaki bir anahtarın değerini veya aksi takdirde varsayılan değeri ve değerin bulunup bulunmadığını gösteren ikincil bir boole değerini döndürür. Bu nedenle, değerin bulunup bulunmadığını veya varsayılan olarak sağlanıp sağlanmadığını umursamayan kod, onu olduğu gibi kullanabilir, ancak böyle bir ayrım önemli olduğunda, ikincil boolean'ı inceleyebilir ve uygun şekilde tepki verebilir. Her iki kullanım durumu da aynı çağrı tarafından desteklenir ve hiçbiri diğeri tarafından gereksiz yere yüklenmez veya kısıtlanmaz. Bu özelliğin dil düzeyinde olması, diğer dillerde olduğu gibi anahtarın varlığını kontrol etme veya onu null ile karşılaştırma ihtiyacını ortadan kaldırır .
(defun get-answer (library)
  (gethash 'answer library 42))

(defun the-answer-1 (library)
  (format nil "The answer is ~A" (get-answer library)))
;;;; Returns "The answer is 42" if ANSWER not present in LIBRARY

(defun the-answer-2 (library)
  (multiple-value-bind (answer sure-p)
      (get-answer library)
    (if (not sure-p)
        "I don't know"
     (format nil "The answer is ~A" answer))))
;;;; Returns "I don't know" if ANSWER not present in LIBRARY

Birden çok değer, en yaygın olanı MULTIPLE-VALUE-BINDikincil değerlere erişmek ve VALUESbirden çok değer döndürmek için özel form olan bir avuç standart form tarafından desteklenir :

(defun magic-eight-ball ()
  "Return an outlook prediction, with the probability as a secondary value"
  (values "Outlook good" (random 1.0)))

;;;; => "Outlook good"
;;;; => 0.3187

Diğer çeşitler

Common Lisp'teki diğer veri türleri şunları içerir:

  • Yol adları , dosya sistemindeki dosyaları ve dizinleri temsil eder . Common Lisp yol adı özelliği, çoğu işletim sisteminin dosya adlandırma kurallarından daha geneldir ve Lisp programlarının dosyalara erişimini çeşitli sistemler arasında geniş ölçüde taşınabilir hale getirir.
  • Giriş ve çıkış akışları , terminal veya açık dosyalar gibi ikili veya metinsel verilerin kaynaklarını ve havuzlarını temsil eder.
  • Common Lisp, yerleşik bir sözde rastgele sayı üretecine (PRNG) sahiptir. Rastgele durum nesneleri, yeniden kullanılabilir sözde rasgele sayı kaynaklarını temsil eder ve kullanıcının PRNG'yi tohumlamasına veya bir diziyi yeniden oynatmasına izin verir.
  • Koşullar , bir programın yanıt verebileceği hataları, istisnaları ve diğer "ilginç" olayları temsil etmek için kullanılan bir türdür.
  • Sınıflar olan birinci sınıf nesneleri ve kendilerini adı sınıfların örnekleri olan metaobject sınıfları ( metaclasses kısaca).
  • Okunabilir tablolar , Common Lisp okuyucusunun kaynak kod metnini nasıl ayrıştırdığını kontrol eden bir nesne türüdür. Programcı, kod okunurken hangi okunabilir tablonun kullanımda olduğunu kontrol ederek dilin sözdizimini değiştirebilir veya genişletebilir.

Kapsam

Diğer birçok programlama dilindeki programlar gibi, Common Lisp programları da değişkenlere, işlevlere ve diğer birçok varlık türüne atıfta bulunmak için adları kullanır. Adlandırılmış referanslar kapsama tabidir.

Bir ad ile adın atıfta bulunduğu varlık arasındaki ilişkiye bağlama denir.

Kapsam, bir adın belirli bir bağlayıcılığa sahip olduğunun belirlendiği koşullar kümesini ifade eder.

Kapsam belirleyicileri

Common Lisp'te kapsamı belirleyen koşullar şunları içerir:

  • bir ifade içindeki bir referansın konumu. Bir bileşiğin en soldaki konumuysa, özel bir operatöre veya bir makroya veya işlev bağlamaya, aksi takdirde değişken bağlamaya veya başka bir şeye atıfta bulunur.
  • referansın yer aldığı ifade türü. Örneğin, (go x)kontrolün etikete aktarılması anlamına xgelirken (print x), değişkene atıfta bulunur x. xEtiket gövdesi etiketleri değişken adlarından ayrı bir ad alanında olduğundan, her iki kapsamı da program metninin aynı bölgesinde etkin olabilir. Özel bir form veya makro form, sözdizimindeki tüm sembollerin anlamları üzerinde tam kontrole sahiptir. Örneğin (defclass x (a b) ()), bir sınıf tanımında, (a b)temel sınıfların bir listesidir, bu nedenle bu adlar sınıf adları alanında aranır ve xmevcut bir bağlamaya referans değil, türetilmiş yeni bir sınıfın adıdır. itibaren ave b. Bu gerçekler tamamen defclass. Bu ifadeyle ilgili tek genel gerçek defclass, bir makro bağlamaya atıfta bulunmasıdır; diğer her şey bağlı defclass.
  • referansın program metni içindeki yeri. Örneğin, değişkene bir başvuru, için xbir bağlamayı lettanımlayan a gibi bir bağlama yapısının içine alınmışsa, başvuru xbu bağlama tarafından oluşturulan kapsamdadır.
  • bir değişken referansı için, bir değişken sembolünün yerel veya global olarak özel olarak bildirilmiş olup olmadığı. Bu, başvurunun sözlüksel bir ortamda mı yoksa dinamik bir ortamda mı çözüleceğini belirler.
  • başvurunun çözümlendiği ortamın belirli örneği. Bir ortam, sembolleri bağlamalara eşleyen bir çalışma zamanı sözlüğüdür. Her tür referans kendi tür ortamını kullanır. Sözlüksel değişkenlere yapılan referanslar, sözlüksel bir ortamda vb. çözülür. Aynı referansla birden fazla ortam ilişkilendirilebilir. Örneğin, özyineleme veya birden çok iş parçacığının kullanılması sayesinde, aynı işlevin birden çok aktivasyonu aynı anda mevcut olabilir. Bu etkinleştirmeler aynı program metnini paylaşır, ancak her birinin kendi sözcüksel ortam örneği vardır.

Bir sembolün neyi ifade ettiğini anlamak için Common Lisp programcısı ne tür bir referansın ifade edildiğini, değişken bir referans ise ne tür bir kapsam kullandığını (dinamik ve sözcüksel kapsam) ve ayrıca çalışma zamanı durumunu bilmelidir: referansın hangi ortamda çözüldüğü, bağlama nerede ortama dahil edildi, vb.

Çevre türleri

küresel

Lisp'teki bazı ortamlar küresel olarak yaygındır. Örneğin, yeni bir tip tanımlansa, bundan sonra her yerde bilinir. Bu türe yapılan referanslar, bu küresel ortamda aranır.

Dinamik

Common Lisp'teki bir ortam türü dinamik ortamdır. Bu ortamda oluşturulan bağlamaların dinamik kapsamı vardır; bu, bir letblok gibi bazı yapıların yürütülmesinin başlangıcında bir bağlamanın kurulduğu ve bu yapının yürütülmesini bitirdiğinde ortadan kalktığı anlamına gelir: ömrü, dinamik etkinleştirme ve devre dışı bırakmaya bağlıdır. bir blok. Ancak, dinamik bir bağlama yalnızca bu blok içinde görünmez; o bloktan çağrılan tüm işlevler tarafından da görülebilir. Bu tür görünürlük, belirsiz kapsam olarak bilinir. Dinamik kapsam (bir bloğun etkinleştirilmesi ve devre dışı bırakılmasına bağlı yaşam süresi) ve belirsiz kapsam (o bloktan çağrılan tüm işlevler tarafından görülebilir) sergileyen bağlamaların dinamik kapsama sahip olduğu söylenir.

Common Lisp, özel değişkenler olarak da adlandırılan dinamik kapsamlı değişkenleri destekler. Yeniden başlatmalar ve yakalama etiketleri gibi bazı diğer bağlama türleri de zorunlu olarak dinamik olarak kapsamlandırılır. İşlev bağlamaları kullanılarak dinamik olarak kapsam oluşturulamaz flet(yalnızca sözcüksel olarak kapsamlandırılmış işlev bağlamaları sağlar), ancak işlev nesneleri (Common Lisp'te birinci düzey bir nesne) letdinamik kapsamdaki değişkenlere atanabilir , dinamik kapsamda kullanılarak bağlanabilir ve ardından using funcallveya olarak adlandırılabilir APPLY.

Dinamik kapsam, global değişkenlere referans netliği ve disiplin kattığı için son derece kullanışlıdır . Bilgisayar biliminde küresel değişkenler potansiyel hata kaynakları olarak hoş karşılanmaz, çünkü modüller arasında istenmeyen, şaşırtıcı etkileşimlere yol açan geçici, gizli iletişim kanallarına yol açabilirler.

Common Lisp'te, yalnızca üst düzey bağlamaya sahip özel bir değişken, diğer programlama dillerindeki global bir değişken gibi davranır. İçinde yeni bir değer saklanabilir ve bu değer, üst düzey bağlamada bulunanın yerini alır. Global bir değişkenin değerinin dikkatsizce değiştirilmesi, global değişkenlerin kullanılmasından kaynaklanan hataların merkezinde yer alır. Ancak, özel bir değişkenle çalışmanın başka bir yolu, ona bir ifade içinde yeni, yerel bir bağlama vermektir. Buna bazen değişkeni "yeniden bağlama" denir. Dinamik olarak kapsamlı bir değişkeni bağlamak, geçici olarak o değişken için yeni bir bellek konumu oluşturur ve adı bu konumla ilişkilendirir. Bu bağlama etkinken, bu değişkene yapılan tüm başvurular yeni bağlamaya başvurur; önceki bağlama gizlidir. Bağlama ifadesinin yürütülmesi sona erdiğinde, geçici bellek konumu gider ve orijinal değer bozulmadan eski bağlama ortaya çıkar. Elbette, aynı değişken için birden çok dinamik bağlama iç içe yerleştirilebilir.

Çoklu iş parçacığını destekleyen Common Lisp uygulamalarında, dinamik kapsamlar her yürütme iş parçacığına özeldir. Böylece özel değişkenler, iş parçacığı yerel depolaması için bir soyutlama işlevi görür. Bir iş parçacığı özel bir değişkeni yeniden bağlarsa, bu yeniden bağlamanın diğer iş parçacıklarındaki o değişken üzerinde hiçbir etkisi olmaz. Bir bağlamada saklanan değer, yalnızca o bağlamayı oluşturan iş parçacığı tarafından alınabilir. Her iş parçacığı bazı özel değişken bağlarsa *x*, o zaman *x*iş parçacığı yerel depolama gibi davranır. Rebind olmayan threadler arasında *x*sıradan bir global gibi davranır: bu threadlerin hepsi aynı üst düzey bağlamaya atıfta bulunur *x*.

Dinamik değişkenler, yürütme bağlamını, ekstra bir işlev parametresi olarak görünmek zorunda kalmadan dolaylı olarak işlevden işleve geçirilen ek bağlam bilgileriyle genişletmek için kullanılabilir. Bu, özellikle, kontrol aktarımının, ek verileri iletmek için fazladan parametrelerle genişletilemeyen, ilgisiz kod katmanlarından geçmesi gerektiğinde kullanışlıdır. Bunun gibi bir durum genellikle global bir değişken gerektirir. Bu global değişken kaydedilmeli ve geri yüklenmelidir, böylece şema özyineleme altında kırılmaz: dinamik değişken yeniden bağlama bununla ilgilenir. Ve bu değişken iş parçacığı yerel hale getirilmelidir (veya büyük bir muteks kullanılmalıdır), böylece şema iş parçacıkları altında kırılmaz: dinamik kapsam uygulamaları bununla da ilgilenebilir.

Common Lisp kitaplığında birçok standart özel değişken vardır. Örneğin, tüm standart G/Ç akışları, iyi bilinen özel değişkenlerin üst düzey bağlantılarında depolanır. Standart çıktı akışı *standart çıktıda* saklanır.

Bir foo fonksiyonunun standart çıktıya yazdığını varsayalım:

  (defun foo ()
    (format t "Hello, world"))

Çıktısını bir karakter dizisinde yakalamak için *standart çıktı* bir dizi akımına bağlanabilir ve şöyle çağrılabilir:

  (with-output-to-string (*standard-output*)
    (foo))
 -> "Hello, world" ; gathered output returned as a string

sözlüksel

Common Lisp, sözcüksel ortamları destekler. Biçimsel olarak, sözlüksel bir ortamdaki bağlamaların sözcüksel kapsamı vardır ve ad alanının türüne bağlı olarak belirsiz bir kapsam veya dinamik bir kapsam olabilir. Sözlüksel kapsam , görünürlüğün fiziksel olarak bağlamanın oluşturulduğu blokla sınırlı olduğu anlamına gelir. Bu bloğa metinsel olarak (yani sözlüksel olarak) gömülü olmayan referanslar, bu bağlamayı görmezler.

Bir TAGBODY'deki etiketlerin sözcüksel kapsamı vardır. (GO X) ifadesi, X etiketini içeren bir TAGBODY'ye gömülü değilse hatalıdır. Ancak, TAGBODY yürütmesini sonlandırdığında etiket bağlamaları kaybolur, çünkü dinamik kapsamları vardır. Söz konusu kod bloğu, bir sözlüksel kapatmanın çağrılmasıyla yeniden girilirse , bu kapatmanın gövdesinin GO aracılığıyla kontrolü bir etikete aktarmaya çalışması geçersizdir:

  (defvar *stashed*) ;; will hold a function

  (tagbody
    (setf *stashed* (lambda () (go some-label)))
    (go end-label) ;; skip the (print "Hello")
   some-label
    (print "Hello")
   end-label)
  -> NIL

TAGBODY yürütüldüğünde, ilk olarak *stashed* özel değişkeninde bir işlevi saklayan setf formunu değerlendirir. Ardından (son etikete git) kontrolü uç etikete aktarır ve kodu atlar ("Merhaba" yazdır). Son etiket, etiket gövdesinin sonunda olduğundan, etiket gövdesi sona erer ve NIL verir. Önceden hatırlanan işlevin şimdi çağrıldığını varsayalım:

  (funcall *stashed*) ;; Error!

Bu durum hatalıdır. Bir uygulamanın yanıtı, "GO: SOME-LABEL etiketi için etiket gövdesi zaten kaldı" mesajını içeren bir hata koşuludur. İşlev, etiket gövdesine sözcüksel olarak gömülü olan ve etikete çözümlenen değerlendirmeye (bir etikete git) çalıştı. Ancak, etiket gövdesi yürütülmüyor (kapsamı sona ermiştir) ve bu nedenle kontrol aktarımı gerçekleşemez.

Lisp'teki yerel işlev bağlamalarının sözcüksel kapsamı vardır ve değişken bağlamaların da varsayılan olarak sözcüksel kapsamı vardır. GO etiketlerinin aksine, bunların her ikisi de belirsiz bir kapsama sahiptir. Sözcüksel bir işlev veya değişken bağlama kurulduğunda, bu bağlama, söz konusu bağlamayı kuran yapı sona erdikten sonra bile, kendisine yapılan referanslar mümkün olduğu sürece var olmaya devam eder. Sözcüksel kapanışlar sayesinde, kuruluş yapıları sona erdikten sonra sözcüksel değişkenlere ve işlevlere referanslar mümkündür .

Sözcüksel bağlama, Common Lisp değişkenleri için varsayılan bağlama modudur. Tek bir sembol için, yerel bir bildirimle veya genel bir bildirimle dinamik kapsama geçirilebilir. Sonuncusu, DEFVAR veya DEFPARAMETER gibi bir yapının kullanımı yoluyla dolaylı olarak meydana gelebilir. O özel programlama Common Lisp önemli kongre olduğunu (yani dinamik kapsamlı) değişkenleri yıldız işareti ile başlar ve bitiş adları vardır desene * "denir içinde kulaklık kongre". Bu kurala uyulursa, bu kural, özel değişkenler için etkin bir şekilde ayrı bir ad alanı oluşturur, böylece sözcüksel olması amaçlanan değişkenler yanlışlıkla özel hale getirilmez.

Sözcüksel kapsam birkaç nedenden dolayı yararlıdır.

İlk olarak, çalışma zamanı ortam yapısı nispeten basit olduğundan, değişkenlere ve işlevlere yapılan başvurular verimli makine koduna derlenebilir. Çoğu durumda, depolamayı yığmak için optimize edilebilir, bu nedenle sözcük kapsamlarının açılması ve kapatılması minimum ek yüke sahiptir. Tam kapatmaların oluşturulması gerektiği durumlarda bile, kapatma ortamına erişim hala verimlidir; tipik olarak her bir değişken, bir bağlama vektörüne bir ofset haline gelir ve bu nedenle bir değişken referansı, bir taban artı ofset adresleme modu ile basit bir yükleme veya depolama talimatı haline gelir .

İkinci olarak, sözcüksel kapsam (belirsiz bir kapsamla birleştirilmiş) sözcüksel kapanışa yol açar , bu da sırayla işlevsel programlamanın kökünde yer alan birinci sınıf nesneler olan işlevlerin kullanımına odaklanan bütün bir programlama paradigması yaratır.

Üçüncüsü, belki de en önemlisi, sözlüksel kapanışlardan yararlanılmasa bile, sözcüksel kapsamın kullanılması program modüllerini istenmeyen etkileşimlerden yalıtır. Sınırlı görünürlükleri nedeniyle, sözcüksel değişkenler özeldir. Bir modül A bir X değişkenini bağlar ve başka bir modül B'yi çağırırsa, B'deki X'e yapılan başvurular yanlışlıkla A'daki X'e çözülmez. B'nin X'e erişimi yoktur. Bir değişken aracılığıyla disiplinli etkileşimlerin olduğu durumlar için Arzu edilen, Common Lisp özel değişkenler sağlar. Özel değişkenler, bir A modülünün, A'dan çağrılan başka bir B modülü tarafından görülebilen bir X değişkeni için bir bağlama kurmasına izin verir. Bunu yapabilmek bir avantajdır ve bunun olmasını engelleyebilmek de bir avantajdır; sonuç olarak, Common Lisp hem sözcüksel hem de dinamik kapsamı destekler .

makrolar

Lisp'teki bir makro , kullanımdaki bir işleve yüzeysel olarak benzer. Ancak, değerlendirilen bir ifadeyi temsil etmekten çok, program kaynak kodunun bir dönüşümünü temsil eder. Makro, çevrelediği kaynağı argümanlar olarak alır, onları parametrelerine bağlar ve yeni bir kaynak formu hesaplar. Bu yeni form bir makro da kullanabilir. Makro genişletme, yeni kaynak form bir makro kullanmayana kadar tekrarlanır. Son hesaplanan form, çalışma zamanında yürütülen kaynak koddur.

Lisp'te makroların tipik kullanımları:

  • yeni kontrol yapıları (örnek: döngü yapıları, dallanma yapıları)
  • kapsam belirleme ve bağlama yapıları
  • karmaşık ve tekrarlanan kaynak kodu için basitleştirilmiş sözdizimi
  • derleme zamanı yan etkileri olan üst düzey tanımlayıcı formlar
  • veriye dayalı programlama
  • gömülü etki alanına özgü diller (örnekler: SQL , HTML , Prolog )
  • örtük sonuçlandırma formları

Çeşitli standart Common Lisp özelliklerinin de makro olarak uygulanması gerekir, örneğin:

  • setfatama/erişim operatörlerinin özel derleme zamanı genişletmelerine izin vermek için standart soyutlama
  • with-accessors, with-slots, with-open-fileVe diğer benzer WITHmakrolar
  • Uygulamaya bağlı olarak ifveya conddiğerinin üzerine inşa edilmiş bir makro, özel operatör; whenve unlessmakrolardan oluşur
  • loopEtki alanına özgü güçlü dil

Makrolar, defmacro makrosu tarafından tanımlanır . Özel operatör makroleti , yerel (sözlük olarak kapsamlı) makroların tanımlanmasına izin verir. define-symbol-macro ve symbol-macrolet kullanarak semboller için makrolar tanımlamak da mümkündür .

Paul Graham'ın On Lisp adlı kitabı , Common Lisp'te makroların kullanımını ayrıntılı olarak açıklar. Doug Hoyte'nin Let Over Lambda adlı kitabı , "Makrolar, lisp'in bir programlama dili olarak sahip olduğu en büyük avantaj ve herhangi bir programlama dilinin en büyük avantajıdır" iddiasıyla makrolar hakkındaki tartışmayı genişletiyor. Hoyte, makroların yinelemeli gelişiminin birkaç örneğini sunar.

Yeni bir kontrol yapısı tanımlamak için bir makro kullanan örnek

Makrolar, Lisp programcılarının dilde yeni sözdizimsel formlar oluşturmasına olanak tanır. Tipik bir kullanım, yeni kontrol yapıları oluşturmaktır. Örnek makro bir untildöngü yapısı sağlar. Sözdizimi:

(until test form*)

Şuna kadar makro tanımı :

(defmacro until (test &body body)
  (let ((start-tag (gensym "START"))
        (end-tag   (gensym "END")))
    `(tagbody ,start-tag
              (when ,test (go ,end-tag))
              (progn ,@body)
              (go ,start-tag)
              ,end-tag)))

tagbody , etiketleri adlandırma ve bu etiketlere atlamak için go formunu kullanma yeteneği sağlayan ilkel bir Common Lisp özel operatörüdür . Geri alıntı ` , önünde virgül bulunan formların değerinin doldurulduğu kod şablonları sağlayan bir gösterim sağlar . Önünde virgül ve imza bulunan formlar eklenir . Etiket gövdesi formu bitiş koşulunu test eder. Koşul doğruysa bitiş etiketine atlar. Aksi takdirde sağlanan gövde kodu yürütülür ve ardından başlangıç ​​etiketine atlar.

Yukarıda kullanılmasının bir örneği kadar makro:

(until (= (random 10) 0)
  (write-line "Hello"))

Kod, macroexpand-1 işlevi kullanılarak genişletilebilir . Yukarıdaki örnek için genişleme şöyle görünür:

(TAGBODY
 #:START1136
 (WHEN (ZEROP (RANDOM 10))
   (GO #:END1137))
 (PROGN (WRITE-LINE "hello"))
 (GO #:START1136)
 #:END1137)

Makro genişletme sırasında değişken testinin değeri (= (rastgele 10) 0) ve değişken gövdesinin değeri ((yazma satırı "Merhaba")) . Gövde, formların bir listesidir.

Semboller genellikle otomatik olarak büyütülür. Genişletme, TAGBODY'yi iki etiketle kullanır. Bu etiketlerin sembolleri GENSYM tarafından hesaplanmıştır ve herhangi bir pakete dahil edilmemiştir. İki go formu, atlamak için bu etiketleri kullanır. Yana tagbody Common Lisp (ve makro) bir ilkel operatörüdür, bu başka bir şeye genişletilmiş edilmeyecektir. Genişletilmiş form , aynı zamanda genişletilecek olan When makrosunu kullanır . Bir kaynak formu tamamen genişletmeye kod yürüyüşü denir .

Tam genişletilmiş (in yürüdü ) şeklinde olduğunda bir şekilde ilkel ile değiştirildiği takdirde :

(TAGBODY
 #:START1136
 (IF (ZEROP (RANDOM 10))
     (PROGN (GO #:END1137))
   NIL)
 (PROGN (WRITE-LINE "hello"))
 (GO #:START1136))
 #:END1137)

Tüm makrolar, onları içeren kaynak kodun normal olarak değerlendirilebilmesi veya derlenebilmesi için genişletilmelidir. Makrolar, S-ifadelerini kabul eden ve döndüren işlevler olarak kabul edilebilir – soyut sözdizimi ağaçlarına benzer , ancak bunlarla sınırlı değildir. Bu işlevler, nihai kaynak kodunu üretmek için değerlendiriciden veya derleyiciden önce çağrılır. Makrolar normal Common Lisp ile yazılır ve mevcut herhangi bir Common Lisp (veya üçüncü taraf) operatörünü kullanabilir.

Değişken yakalama ve gölgeleme

Common Lisp makroları , makro genişletme gövdesindeki sembollerin çağrı bağlamındakilerle çakıştığı ve programcının çeşitli sembollerin özel anlamlara sahip olduğu makrolar oluşturmasına olanak tanıyan , yaygın olarak değişken yakalama olarak adlandırılan şeye sahiptir . Vadeli değişken yakalama tüm ad operatör ve fonksiyon ad, tagbody etiket ad, av etiketine, durumu işleyicisi ve yeniden başlatma ad dahil istenmeyen yakalama, savunmasız oldukları için biraz, yanıltıcıdır.

Değişken yakalama , yazılım kusurlarına neden olabilir. Bu, aşağıdaki iki yoldan biriyle olur:

  • İlk olarak, bir makro genişletme, makro yazarının global bir ad alanında çözeceğini varsaydığı bir sembolik referansı istemeden yapabilir, ancak makronun genişletildiği kod, bu referansı çalan yerel, gölgeli bir tanım sağlar. Bu tip 1 yakalama olarak adlandırılsın.
  • İkinci yol, tip 2 yakalama, tam tersidir: makronun argümanlarından bazıları, makro çağıran tarafından sağlanan kod parçalarıdır ve bu kod parçaları, çevreleyen bağlamalara referans verecek şekilde yazılır. Ancak makro, bu kod parçalarını, yanlışlıkla bu referanslardan bazılarını yakalayan kendi bağlantılarını tanımlayan bir genişletmeye ekler.

Lisp'in Scheme lehçesi, her iki tür yakalama problemini de ortadan kaldıran referans şeffaflığı sağlayan bir makro yazma sistemi sağlar. Bu tür bir makro sistem, özellikle savunucuları (bu sorunu otomatik olarak çözmeyen makro sistemleri hijyenik olarak kabul eden) tarafından bazen "hijyenik" olarak adlandırılır.

Common Lisp'te makro hijyen iki farklı yoldan biriyle sağlanır.

Bir yaklaşım gensyms kullanmaktır : yakalama tehdidi olmaksızın bir makro genişlemede kullanılabilen garantili-benzersiz semboller. Bir makro tanımında gensyms kullanımı manuel bir angaryadır, ancak gensyms örneğini ve kullanımını basitleştiren makrolar yazılabilir. Gensyms, tip 2 yakalamayı kolayca çözer, ancak aynı şekilde tip 1 yakalama için geçerli değildir, çünkü makro genişletme, referanslarını yakalayan çevreleyen koddaki karışan sembolleri yeniden adlandıramaz. Gensyms, makro genişletmenin ihtiyaç duyduğu global semboller için kararlı takma adlar sağlamak için kullanılabilir. Makro genişletmesi, iyi bilinen adlar yerine bu gizli takma adları kullanır, bu nedenle iyi bilinen adların yeniden tanımlanmasının makro üzerinde hiçbir kötü etkisi olmaz.

Başka bir yaklaşım paketleri kullanmaktır. Kendi paketinde tanımlanan bir makro, genişletmesinde o paketteki dahili sembolleri kullanabilir. Paketlerin kullanımı tip 1 ve tip 2 yakalama ile ilgilidir.

Ancak paketler, standart Common Lisp işlevlerine ve operatörlerine yapılan başvuruların tip 1 yakalamasını çözmez. Bunun nedeni, yakalama problemlerini çözmek için paketlerin kullanımının özel sembollerin (bir pakette içe aktarılmayan veya diğer paketlerde başka şekilde görünür kılınmayan semboller) kullanımı etrafında dönmesidir. Oysa Common Lisp kitaplığı sembolleri haricidir ve sıklıkla kullanıcı tanımlı paketlere aktarılır veya bu paketlerde görünür hale getirilir.

Aşağıdaki, bir makronun genişletilmesinde meydana gelen, işleç ad alanında istenmeyen yakalama örneğidir:

 ;; expansion of UNTIL makes liberal use of DO
 (defmacro until (expression &body body)
   `(do () (,expression) ,@body))

 ;; macrolet establishes lexical operator binding for DO
 (macrolet ((do (...) ... something else ...))
   (until (= (random 10) 0) (write-line "Hello")))

untilMakro çağrıları bir forma genişleyecektir doamaçlanmaktadır standart Common Lisp makro başvurmak için do. Ancak bu bağlamda dotamamen farklı bir anlama sahip olabilir, bu nedenle untildüzgün çalışmayabilir.

Common Lisp, standart işleçlerin ve işlevlerin yeniden tanımlanmasını yasaklayarak gölgelenme sorununu çözer. Standart operatörü yeniden tanımladığı için do, önceki aslında, uygulamaların onu teşhis etmesine ve reddetmesine izin veren, uygun olmayan Common Lisp'in bir parçasıdır.

Durum sistemi

Condition sistemi sorumludur istisna işleme Common Lisp. Sağladığı koşulları , işleyici ler ve yeniden başlatma s. Koşullar , istisnai bir durumu (örneğin bir hata) açıklayan nesnelerdir. Bir koşul bildirilirse, Common Lisp sistemi bu koşul tipi için bir işleyici arar ve işleyiciyi çağırır. İşleyicisi artık böyle bir şart tipi ve durum nesnenin parçası olarak sağlanan diğer ilgili bilgileri gibi bilgileri kullanarak, Yeniden başlatma ve otomatik olarak geçerli sorunu onarmak için bu yeniden kullanılması birini arayın ve uygun yeniden başlatma işlevini çağırabilirsiniz.

Bu yeniden başlatmalar, kod tarafından işlenmezlerse, kullanıcılara sunulabilir (örneğin, bir hata ayıklayıcınınki gibi bir kullanıcı arabiriminin parçası olarak), böylece kullanıcı mevcut yeniden başlatmalardan birini seçip çağırabilir. Koşul işleyici hata bağlamında (yığın çözülmeden) çağrıldığından, diğer istisna işleme sistemlerinin mevcut rutini zaten sonlandırdığı birçok durumda tam hata kurtarma mümkündür. Hata ayıklayıcının kendisi de *debugger-hook*dinamik değişken kullanılarak özelleştirilebilir veya değiştirilebilir . Sonlandırıcılar gibi çözmeye karşı koruma formlarında bulunan kod da istisnaya rağmen uygun şekilde yürütülecektir.

Aşağıdaki örnekte ( Symbolics Genera kullanılarak ), kullanıcı , dosya mevcut olmadığında Read-Değerlendirme-Baskı-LOOP'dan ( REPL ) çağrılan bir Lisp fonksiyon testinde bir dosyayı açmaya çalışır . Lisp sistemi dört yeniden başlatma sunar. Kullanıcı, farklı bir yol adı yeniden başlatma kullanarak Yeniden Dene AÇ'ı seçer ve farklı bir yol adı girer (lispm-int.lisp yerine lispm-init.lisp). Kullanıcı kodu herhangi bir hata işleme kodu içermiyor. Hata işleme ve yeniden başlatma kodunun tamamı, kullanıcı kodunu sonlandırmadan hatayı işleyebilen ve onarabilen Lisp sistemi tarafından sağlanır.

Command: (test ">zippy>lispm-int.lisp")

Error: The file was not found.
       For lispm:>zippy>lispm-int.lisp.newest

LMFS:OPEN-LOCAL-LMFS-1
   Arg 0: #P"lispm:>zippy>lispm-int.lisp.newest"

s-A, <Resume>: Retry OPEN of lispm:>zippy>lispm-int.lisp.newest
s-B:           Retry OPEN using a different pathname
s-C, <Abort>:  Return to Lisp Top Level in a TELNET server
s-D:           Restart process TELNET terminal

-> Retry OPEN using a different pathname
Use what pathname instead [default lispm:>zippy>lispm-int.lisp.newest]:
   lispm:>zippy>lispm-init.lisp.newest

...the program continues

Ortak Lisp Nesne Sistemi (CLOS)

Common Lisp, herhangi bir dilde mevcut olan en güçlü nesne sistemlerinden biri olan Common Lisp Object System veya CLOS olan nesne yönelimli programlama için bir araç takımı içerir . Örneğin, Peter Norvig , CLOS'un özellikleriyle (Multiple Inheritance, Mixins, Multimethods, Metaclasses, Method kombinasyonları, vb.) dinamik bir dilde kaç Tasarım Modelinin uygulanmasının daha basit olduğunu açıklıyor . Nesne yönelimli programlama için Common Lisp'e çeşitli uzantıların ANSI Common Lisp standardına dahil edilmesi önerildi, ancak sonunda CLOS Common Lisp için standart nesne sistemi olarak kabul edildi. CLOS, çoklu gönderim ve çoklu kalıtım içeren dinamik bir nesne sistemidir ve C++ veya Java gibi statik dillerde bulunan OOP tesislerinden kökten farklıdır . Dinamik bir nesne sistemi olarak CLOS, çalışma zamanında genel işlevlerde ve sınıflarda değişikliklere izin verir. Yöntemler eklenebilir ve kaldırılabilir, sınıflar eklenebilir ve yeniden tanımlanabilir, sınıf değişiklikleri için nesneler güncellenebilir ve nesnelerin sınıfı değiştirilebilir.

CLOS, ANSI Common Lisp'e entegre edilmiştir. Genel işlevler, normal işlevler gibi kullanılabilir ve birinci sınıf bir veri türüdür. Her CLOS sınıfı, Common Lisp tipi sisteme entegre edilmiştir. Birçok Common Lisp türünün karşılık gelen bir sınıfı vardır. Common Lisp için CLOS'un daha fazla potansiyel kullanımı vardır. Spesifikasyon, koşulların CLOS ile uygulanıp uygulanmadığını söylemez. Yol adları ve akışlar CLOS ile uygulanabilir. ANSI Common Lisp için CLOS'un bu diğer kullanım olanakları standardın bir parçası değildir. Gerçek Common Lisp uygulamaları, yol adları, akışlar, girdi-çıktı, koşullar, CLOS'un kendisinin uygulanması ve daha fazlası için CLOS'u kullanır.

Derleyici ve yorumlayıcı

Bir Lisp yorumlayıcısı, s-ifadelerinden okunan Lisp nesneleri (listeler, semboller, sayılar, ...) olarak sağlanan Lisp kaynak kodunu doğrudan yürütür. Bir Lisp derleyicisi , Lisp kaynak kodundan bayt kodu veya makine kodu üretir . Common Lisp, hem bireysel Lisp işlevlerinin bellekte derlenmesine hem de tüm dosyaların harici olarak depolanan derlenmiş koda ( fasl dosyaları) derlenmesine izin verir .

Daha önceki Lisp lehçelerinin birkaç uygulaması hem bir yorumlayıcı hem de bir derleyici sağladı. Ne yazık ki çoğu zaman anlambilim farklıydı. Bu önceki Lisps'ler, derleyicide sözcüksel kapsam belirlemeyi ve yorumlayıcıda dinamik kapsam belirlemeyi uyguladı. Common Lisp, hem yorumlayıcının hem de derleyicinin varsayılan olarak sözcüksel kapsam kullanmasını gerektirir. Common Lisp standardı hem yorumlayıcının hem de derleyicinin anlamını tanımlar. Derleyici, bireysel işlevler için derleme işlevi ve dosyalar için derleme dosyası işlevi kullanılarak çağrılabilir . Common Lisp, tür bildirimlerine izin verir ve derleyici kod oluşturma ilkesini etkilemenin yollarını sağlar. Sonuncusu için çeşitli optimizasyon nitelikleri 0 (önemli değil) ile 3 (en önemli) arasında değerler verilebilir: hız , boşluk , güvenlik , hata ayıklama ve derleme hızı .

Lisp kodunu değerlendirmek için bir fonksiyon da vardır: eval. evalkodu, diğer bazı dillerde olduğu gibi metin dizeleri olarak değil, önceden ayrıştırılmış s-ifadeleri olarak alır. Bu şekilde kod, listeler ve semboller oluşturmak için olağan Lisp işlevleriyle oluşturulabilir ve daha sonra bu kod, işlevle değerlendirilebilir eval. Birkaç Common Lisp uygulaması (Clozure CL ve SBCL gibi) evalderleyicilerini kullanarak uygulanmaktadır . Bu şekilde kod, işlev kullanılarak değerlendirilmesine rağmen derlenir eval.

Dosya derleyicisi, compile-file işlevi kullanılarak çağrılır . Derlenmiş kodla oluşturulan dosyaya fasl ( hızlı yüklemeden ) dosyası denir . Bu fasl dosyaları ve ayrıca kaynak kod dosyaları, işlev yüküyle birlikte çalışan bir Common Lisp sistemine yüklenebilir . Uygulamaya bağlı olarak, dosya derleyici bayt kodu (örneğin Java Sanal Makinesi için ), C dili kodu (daha sonra bir C derleyicisi ile derlenir) veya doğrudan yerel kod üretir .

Common Lisp uygulamaları, kod tamamen derlenmiş olsa bile etkileşimli olarak kullanılabilir. Yorumlanan dil fikri bu nedenle etkileşimli Common Lisp için geçerli değildir.

Dil, okuma zamanı, derleme zamanı, yükleme zamanı ve çalışma zamanı arasında bir ayrım yapar ve kullanıcı kodunun, istenen adımda istenen işlem türünü gerçekleştirmek için bu ayrımı yapmasına da izin verir.

Bazı özel operatörler, özellikle etkileşimli geliştirmeye uygun hale getirilmiştir; örneğin, defvarönceden bağlı değilse, yalnızca sağlanan değişkene bir değer atayacak defparameter, her zaman atamayı gerçekleştirecektir. Bu ayrım, canlı bir görüntüdeki kodu etkileşimli olarak değerlendirirken, derlerken ve yüklerken kullanışlıdır.

Derleyicilerin ve yorumlayıcıların yazılmasına yardımcı olmak için bazı özellikler de sağlanmıştır. Semboller birinci seviye nesnelerden oluşur ve doğrudan kullanıcı koduyla manipüle edilebilir. progvPaketler de manipulable ise özel operatör, programlı sözcük bağlantıları oluşturmanıza olanak sağlar. Lisp derleyicisi, dosyaları veya bireysel işlevleri derlemek için çalışma zamanında kullanılabilir. Bunlar, Lisp'i başka bir dil için ara derleyici veya yorumlayıcı olarak kullanmayı kolaylaştırır.

Kod örnekleri

doğum günü paradoksu

Aşağıdaki program, benzersiz doğum günleri olasılığının %50'den az olduğu bir odadaki en küçük insan sayısını hesaplar ( doğum günü paradoksu , burada 1 kişi için olasılık açıkça %100, 2 için 364/365, vb. ). Cevap 23'tür.

Kural olarak, Common Lisp'teki sabitler + karakterleriyle çevrelenir.

(defconstant +year-size+ 365)

(defun birthday-paradox (probability number-of-people)
  (let ((new-probability (* (/ (- +year-size+ number-of-people)
                               +year-size+)
                            probability)))
    (if (< new-probability 0.5)
        (1+ number-of-people)
        (birthday-paradox new-probability (1+ number-of-people)))))

REPL (Değerlendirme Yazdırma Döngüsünü Oku) kullanarak örnek işlevi çağırma :

CL-USER > (birthday-paradox 1.0 1)
23

Kişi nesneleri listesini sıralama

personBir kişinin adını ve yaşını görüntülemek için bir sınıf ve bir yöntem tanımlarız . Daha sonra bir grup insanı personnesneler listesi olarak tanımlarız . Sonra sıralanmış listeyi yineliyoruz.

(defclass person ()
  ((name :initarg :name :accessor person-name)
   (age  :initarg :age  :accessor person-age))
  (:documentation "The class PERSON with slots NAME and AGE."))

(defmethod display ((object person) stream)
  "Displaying a PERSON object to an output stream."
  (with-slots (name age) object
    (format stream "~a (~a)" name age)))

(defparameter *group*
  (list (make-instance 'person :name "Bob"   :age 33)
        (make-instance 'person :name "Chris" :age 16)
        (make-instance 'person :name "Ash"   :age 23))
  "A list of PERSON objects.")

(dolist (person (sort (copy-list *group*)
                      #'>
                      :key #'person-age))
  (display person *standard-output*)
  (terpri))

Üç ismi azalan yaşta yazdırır.

Bob (33)
Ash (23)
Chris (16)

kare alarak üs alma

LOOP makrosunun kullanımı gösterilmiştir:

(defun power (x n)
  (loop with result = 1
        while (plusp n)
        when (oddp n) do (setf result (* result x))
        do (setf x (* x x)
                 n (truncate n 2))
        finally (return result)))

Örnek kullanım:

CL-USER > (power 2 200)
1606938044258990275541962092341162602522202993782792835301376

Yerleşik üs ile karşılaştırın:

CL-USER > (= (expt 2 200) (power 2 200))
T

Mevcut mermilerin listesini bulun

WITH-OPEN-FILE, bir dosyayı açan ve bir akış sağlayan bir makrodur. Form döndüğünde dosya otomatik olarak kapatılır. FUNCALL bir fonksiyon nesnesini çağırır. LOOP, yüklemle eşleşen tüm satırları toplar.

(defun list-matching-lines (file predicate)
  "Returns a list of lines in file, for which the predicate applied to
 the line returns T."
  (with-open-file (stream file)
    (loop for line = (read-line stream nil nil)
          while line
          when (funcall predicate line)
          collect it)))

AVAILABLE-SHELLS işlevi, yüklem olarak bir yol adı ve anonim bir işlev ile yukarıdaki LIST-MATCHING-LINES işlevini çağırır. Yüklem, bir kabuğun veya NIL'nin yol adını döndürür (dize bir kabuğun dosya adı değilse).

(defun available-shells (&optional (file #p"/etc/shells"))
  (list-matching-lines
   file
   (lambda (line)
     (and (plusp (length line))
          (char= (char line 0) #\/)
          (pathname
           (string-right-trim '(#\space #\tab) line))))))

Örnek sonuçlar (Mac OS X 10.6'da):

CL-USER > (available-shells)
(#P"/bin/bash" #P"/bin/csh" #P"/bin/ksh" #P"/bin/sh" #P"/bin/tcsh" #P"/bin/zsh")

Diğer Lisp'lerle Karşılaştırma

Common Lisp, en sık Scheme ile karşılaştırılır ve onunla çelişir - sadece en popüler iki Lisp lehçesi oldukları için. Scheme CL'den önce gelir ve yalnızca aynı Lisp geleneğinden değil, aynı mühendislerden bazılarından gelir— Gerald Jay Sussman'ın Scheme'i birlikte tasarladığı Guy L. Steele , Common Lisp için standartlar komitesine başkanlık etti.

Common Lisp, belirli ürünlere gömülü uzantı dilleri olan Emacs Lisp ve AutoLISP gibi Lisp türevlerinin (sırasıyla GNU Emacs ve AutoCAD) aksine genel amaçlı bir programlama dilidir . Daha önceki birçok Lisps'in aksine, Common Lisp ( Scheme gibi ) hem yorumlanmış hem de derlenmiş kod için varsayılan olarak sözcüksel değişken kapsamını kullanır .

Kimin tasarımlar olarak Common Lisp-böyle katkıda Lisp sistemlerinin çoğu ZetaLisp ve Franz dinamik Lisp kullanılan kapsamlı onların tercüman değişkenleri ve lexically kendi derleyici değişkenleri kapsamlı. Scheme, Lisp'e yalnızca sözcüksel olarak kapsamlandırılmış değişkenlerin kullanımını tanıttı; ALGOL 68'den bir ilham . CL, dinamik olarak kapsamlı değişkenleri de destekler, ancak bunların açıkça "özel" olarak bildirilmesi gerekir. ANSI CL yorumlayıcıları ve derleyicileri arasında kapsam açısından hiçbir fark yoktur.

Common Lisp bazen bir Lisp-2 ve Scheme a Lisp-1 olarak adlandırılır ve CL'nin işlevler ve değişkenler için ayrı ad alanları kullanmasına atıfta bulunur. (Aslında CL, go etiketleri, blok adları ve anahtar sözcükler için olanlar gibi birçok ad alanına sahiptir loop). CL ve Scheme savunucuları arasında, birden fazla ad alanında yer alan ödünleşimler konusunda uzun süredir devam eden bir tartışma var. Şema'da, (genel olarak) işlevlerle çakışan değişken adları vermekten kaçınmak gerekir; Şema fonksiyonları sık argümanlar adında var lis, lstya lystöylesine olarak değil sistem fonksiyonu ile çatışmaya list. Bununla birlikte, CL'de, bir işlevi argüman olarak geçirirken, sortyukarıdaki örnekte olduğu gibi aynı zamanda yaygın bir olay olan işlev ad alanına açıkça başvurmak gerekir .

CL, boole değerlerinin işlenmesinde Scheme'den de farklıdır. Şema, doğruyu ve yanlışı temsil etmek için #t ve #f özel değerlerini kullanır. CL, NIL'in boş listeyi temsil etmesiyle birlikte, T ve NIL sembollerini kullanan eski Lisp kuralına uyar. CL'de, NIL olmayan herhangi bir değer, gibi koşullar tarafından doğru olarak kabul ifedilirken, Şema'da tüm #f olmayan değerler doğru olarak kabul edilir. Bu kurallar, her iki dilde bazı operatörlerin hem yüklem olarak (boolean değerli bir soruyu yanıtlama) hem de daha fazla hesaplama için yararlı bir değer döndürme olarak hizmet etmesine izin verir, ancak Şema'da Common Lisp'teki NIL'e eşdeğer olan '() değeri true olarak değerlendirilir. bir boole ifadesinde.

Son olarak, Scheme standartları belgeleri , CL standardının gerektirmediği kuyruk çağrısı optimizasyonunu gerektirir . Çoğu CL uygulaması, genellikle yalnızca programcı bir optimizasyon yönergesi kullandığında, kuyruk çağrısı optimizasyonu sunar. Bununla birlikte, yaygın CL kodlama stili, Scheme stilinin tercih ettiği her yerde bulunan özyineleme kullanımını desteklemez - bir Scheme programcısının kuyruk özyineleme ile ifade edeceği şeyi, bir CL kullanıcısı genellikle do, dolist, loop, veya (daha yakın zamanda) ile yinelemeli bir ifadeyle ifade ederdi . iteratepaket.

Uygulamalar

Kategori Common Lisp uygulamalarına bakın .

Common Lisp, tek bir uygulama ( Perl gibi) yerine bir belirtim ( Ada ve C gibi ) ile tanımlanır. Geçerli olarak farklılık gösterebilecekleri birçok uygulama ve standart ayrıntı alanları vardır.

Ek olarak, uygulamalar, standartta kapsanmayan işlevsellik sağlayan uzantılarla birlikte gelir:

  • Etkileşimli Üst Düzey (REPL)
  • Çöp toplama
  • Hata Ayıklayıcı, Step ve Müfettiş
  • Zayıf veri yapıları (karma tabloları)
  • Genişletilebilir diziler
  • Genişletilebilir DÖNGÜ
  • Ortam erişimi
  • CLOS Meta-nesne Protokolü
  • CLOS tabanlı genişletilebilir akışlar
  • CLOS tabanlı Kondisyon Sistemi
  • Ağ akışları
  • Kalıcı CLOS
  • Unicode desteği
  • Yabancı Dil Arayüzü (genellikle C'ye)
  • İşletim Sistemi arayüzü
  • Java Arayüzü
  • İş Parçacıkları ve Çoklu İşleme
  • Uygulama teslimi (uygulamalar, dinamik kitaplıklar)
  • Görüntülerin kaydedilmesi

Common Lisp uzantılarını taşınabilir bir şekilde desteklemek için ücretsiz ve açık kaynaklı yazılım kitaplıkları oluşturulmuştur ve bunlar en çok Common-Lisp.net ve CLOCC (Common Lisp Açık Kod Koleksiyonu) projelerinin depolarında bulunur.

Common Lisp uygulamaları, yerel kod derlemesi, bayt kodu derlemesi veya yorumlamanın herhangi bir karışımını kullanabilir. Common Lisp, artımlı derleyicileri , dosya derleyicilerini ve blok derleyicilerini desteklemek için tasarlanmıştır . Derlemeyi optimize etmek için standart bildirimler (işlev satır içi oluşturma veya tür uzmanlığı gibi) dil belirtiminde önerilmektedir. Çoğu Common Lisp uygulaması, kaynak kodunu yerel makine koduna derler . Bazı uygulamalar (optimize edilmiş) bağımsız uygulamalar oluşturabilir. Diğerleri , yerel koddan daha az verimli olan ancak ikili kod taşınabilirliğini kolaylaştıran yorumlanmış bayt kodunu derler . Bazı derleyiciler Common Lisp kodunu C koduna derler. Lisp'in tamamen yorumlanmış bir dil olduğu yanılgısı, büyük olasılıkla, Lisp ortamlarının etkileşimli bir komut istemi sağlaması ve bu kodun artımlı bir şekilde birer birer derlenmesinden kaynaklanmaktadır. Common Lisp ile artımlı derleme yaygın olarak kullanılmaktadır.

Bazı Unix merkezli uygulamaları ( CLISP , SBCL ) bir şekilde kullanılabilir komut dosyası dili ; yani, sistem tarafından bir Perl veya Unix kabuk yorumlayıcısı gibi şeffaf bir şekilde çağrılır .

Uygulamaların listesi

Ticari uygulamalar

Allegro Ortak Lisp
Microsoft Windows, FreeBSD, Linux, Apple macOS ve çeşitli UNIX varyantları için. Allegro CL, bir Entegre Geliştirme Ortamı (IDE) (Windows ve Linux için) ve uygulama teslimi için kapsamlı yetenekler sağlar.
Sıvı Ortak Lisp
eskiden Lucid Common Lisp olarak adlandırılırdı . Sadece bakım, yeni sürüm yok.
LispWorks
Microsoft Windows, FreeBSD, Linux, Apple macOS, iOS, Android ve çeşitli UNIX varyantları için. LispWorks, bir Entegre Geliştirme Ortamı (IDE) (çoğu platform için mevcuttur, ancak iOS ve Android için mevcut değildir) ve uygulama teslimi için kapsamlı yetenekler sağlar.
mocl
iOS, Android ve macOS için.
Açık Cins
DEC Alfa için.
Scieneer Common Lisp
yüksek performanslı bilimsel bilgi işlem için tasarlanmıştır.

Serbestçe yeniden dağıtılabilir uygulamalar

Silahlı Ayı Ortak Lisp (ABCL)
Java Sanal Makinesi üzerinde çalışan bir CL uygulaması . Java bayt kodu için bir derleyici içerir ve CL'den Java kitaplıklarına erişim sağlar. Eskiden sadece Armed Bear J Editor'ün bir parçasıydı .
CLISP
Bir bayt kodu derleme uygulaması, taşınabilir ve çeşitli Unix ve Unix benzeri sistemlerde ( macOS dahil ), Microsoft Windows ve diğer birçok sistemde çalışır.
Kapatma CL (CCL)
Başlangıçta Macintosh Common Lisp'in ücretsiz ve açık kaynaklı bir çatalı. Bu tarihten de anlaşılacağı gibi, CCL Macintosh için yazılmıştır, ancak Clozure CL artık macOS , FreeBSD , Linux , Solaris ve Windows üzerinde çalışmaktadır . Her platformda 32 ve 64 bit x86 bağlantı noktaları desteklenir. Ek olarak, Mac OS ve Linux için Power PC bağlantı noktaları vardır. CCL daha önce OpenMCL olarak biliniyordu, ancak Macintosh Common Lisp'in açık kaynak sürümüyle karıştırılmaması için bu ad artık kullanılmıyor.
CMUCL
Aslen Carnegie Mellon Üniversitesi'nden , şimdi bir grup gönüllü tarafından ücretsiz ve açık kaynaklı yazılım olarak sürdürülüyor . CMUCL, hızlı bir yerel kod derleyicisi kullanır. Intel x86 için Linux ve BSD'de mevcuttur ; Alfa için Linux ; Intel x86 ve PowerPC için macOS ; ve Solaris, IRIX ve HP-UX yerel platformlarında.
Corman Ortak Lisp
Microsoft Windows için. Ocak 2015'te Corman Lisp, MIT lisansı altında yayınlandı.
Yerleştirilebilir Common Lisp (ECL)
ECL, bir bayt kodu yorumlayıcısı ve derleyici içerir. Ayrıca bir C derleyicisi aracılığıyla Lisp kodunu makine koduna derleyebilir. ECL daha sonra Lisp kodunu C'ye derler, C kodunu bir C derleyicisiyle derler ve ardından ortaya çıkan makine kodunu yükleyebilir. ECL'yi C programlarına ve C kodunu Common Lisp programlarına gömmek de mümkündür .
GNU Ortak Lisp (GCL)
GNU Projesi Lisp derleyicisi. Henüz tam olarak ANSI uyumlu olmayan GCL, Maxima , AXIOM ve (tarihsel olarak) ACL2 dahil olmak üzere birçok büyük proje için tercih edilen uygulamadır . GCL, Linux üzerinde on bir farklı mimaride ve ayrıca Windows, Solaris ve FreeBSD altında çalışır .
Macintosh Common Lisp (MCL)
Mac OS X çalıştıran PowerPC işlemcili Apple Macintosh bilgisayarlar için Sürüm 5.2 açık kaynak kodludur. RMCL (MCL 5.2 tabanlı), Apple'ın Rosetta ikili çevirmeni kullanan Intel tabanlı Apple Macintosh bilgisayarlarda çalışır.
ManKai Ortak Lisp (MKCL)
ECL'nin bir dalı . MKCL, yoğun bir şekilde yeniden işlenmiş, yerel olarak çok iş parçacıklı, çalışma zamanı sistemi aracılığıyla güvenilirliği, kararlılığı ve genel kod kalitesini vurgular. Linux'ta MKCL, tamamen POSIX uyumlu bir çalışma zamanı sistemine sahiptir.
Movitz
Herhangi bir temel işletim sistemine güvenmeden x86 bilgisayarlar için bir Lisp ortamı uygular .
Poplog
Poplog, POP-11 ve isteğe bağlı olarak Prolog ve Standart ML (SML) ile karışık dil programlamaya izin veren bir CL sürümü uygular . Hepsi için uygulama dili, aşamalı olarak derlenen POP-11'dir. Ayrıca derleyici ile iletişim kuran entegre bir Emacs benzeri düzenleyiciye sahiptir.
Steel Bank Common Lisp (SBCL)
CMUCL'den bir şube . "Genel olarak konuşursak, SBCL, sürdürülebilirliğe daha fazla vurgu yaparak CMU CL'den ayrılır." SBCL, HP/UX dışında CMUCL'nin yaptığı platformlarda çalışır; ayrıca AMD64, PowerPC, SPARC, MIPS, Windows x86 için Linux üzerinde çalışır ve Windows AMD64 üzerinde çalışmak için deneysel desteğe sahiptir. SBCL, varsayılan olarak bir yorumlayıcı kullanmaz; kullanıcı yorumlayıcıyı açmadıkça tüm ifadeler yerel koda derlenir. SBCL derleyicisi, The Computer Language Benchmarks Game'in önceki bir sürümüne göre hızlı yerel kod üretir .
Ufasoft Ortak Lisp
C++ ile yazılmış çekirdekli Windows platformu için CLISP bağlantı noktası.

Diğer uygulamalar

Austin Kyoto Ortak Lisp
Bill Schelter tarafından Kyoto Common Lisp'in bir evrimi
Kelebek Ortak Lisp
BBN Butterfly çok işlemcili bilgisayar için Şema'da yazılmış bir uygulama
TIKLAYIN
Common Lisp to C derleyicisi
CLOE
Symbolics'ten PC'ler için Common Lisp
Codemist Common Lisp
bilgisayar cebir sistemi Axiom'un ticari versiyonu için kullanılır
ExperCommon Lisp
ExperTelligence tarafından Apple Macintosh için erken bir uygulama
Altın Ortak Lisp
GoldHill Inc. tarafından PC için bir uygulama.
Ibuki Ortak Lisp
Kyoto Common Lisp'in ticarileştirilmiş bir versiyonu
Kyoto Ortak Lisp
C'yi hedef dil olarak kullanan ilk Common Lisp derleyicisi. GCL, ECL ve MKCL, bu Common Lisp uygulamasından kaynaklanmaktadır.
L
IS Robotics tarafından geliştirilen gömülü sistemler için Common Lisp'in küçük bir versiyonu, şimdi iRobot
Lisp Makineleri ( Sembolik , TI ve Xerox'tan)
Yerel Lisp lehçelerine (Lisp Machine Lisp veya Interlisp) ek olarak Common Lisp uygulamaları sağladı. CLOS da mevcuttu. Symbolics, Common Lisp'in geliştirilmiş bir sürümünü sağlar.
Procyon Ortak Lisp
Franz tarafından Allegro CL'nin Windows bağlantı noktası için kullanılan Windows ve Mac OS için bir uygulama
Yıldız Safir Ortak LISP
PC için bir uygulama
alt L
Cyc bilgi tabanlı sistemin uygulanması için kullanılan bir Common Lisp çeşidi
Üst Düzey Ortak Lisp
eşzamanlı yürütme için erken bir uygulama
WCL
paylaşılan bir kitaplık uygulaması
VAX Ortak Lisp
Digital Equipment Corporation, üzerinde koştu o 'ın uygulanması VAX sistemleri çalıştıran VMS veya Ultrix
XLISP
David Betz tarafından yazılmış bir uygulama

Uygulamalar

Common Lisp, prototiplerin hızlı bir şekilde geliştirilmesi veya konuşlandırılmış uygulamalar için araştırma uygulamaları (genellikle Yapay Zeka'da ) geliştirmek için kullanılır.

Common Lisp, Yahoo! Başlangıçta Paul Graham'ı içeren ve daha sonra C++ ve Perl'de yeniden yazılan web-ticaret sitesini saklayın . Diğer dikkate değer örnekler şunları içerir:

Common Lisp'te yazılmış açık kaynaklı uygulamalar da vardır, örneğin:

Ayrıca bakınız

Referanslar

bibliyografya

Common Lisp (dil) veya Common Lisp ile programlama (özellikle AI programlama) hakkında yayınlanmış (veya yayınlanmak üzere olan) kitapların kronolojik listesi.

Dış bağlantılar