LISP - Hızlı Kılavuz

John McCarthy, FORTRAN'ın geliştirilmesinden kısa bir süre sonra 1958'de LISP'yi icat etti. İlk olarak Steve Russell tarafından bir IBM 704 bilgisayarında uygulandı.

Sembolik bilgileri etkili bir şekilde işlediği için özellikle Yapay Zeka programları için uygundur.

Common Lisp, 1980'lerde ve 1990'larda, ZetaLisp ve NIL (Lisp'in Yeni Uygulaması) gibi Maclisp'in halefleri olan çeşitli uygulama gruplarının çalışmalarını birleştirmek amacıyla ortaya çıktı.

Belirli bir uygulama için kolayca genişletilebilen ortak bir dil görevi görür.

Ortak LISP'de yazılan programlar, kelime uzunluğu vb. Gibi makineye özgü özelliklere bağlı değildir.

Ortak LISP'nin Özellikleri

  • Makineden bağımsızdır

  • Yinelemeli tasarım metodolojisi ve kolay genişletilebilirlik kullanır.

  • Programların dinamik olarak güncellenmesine izin verir.

  • Üst düzey hata ayıklama sağlar.

  • Gelişmiş nesne yönelimli programlama sağlar.

  • Kullanışlı bir makro sistem sağlar.

  • Nesneler, yapılar, listeler, vektörler, ayarlanabilir diziler, karma tablolar ve semboller gibi çok çeşitli veri türleri sağlar.

  • İfade tabanlıdır.

  • Nesneye yönelik bir durum sistemi sağlar.

  • Eksiksiz bir G / Ç kitaplığı sağlar.

  • Kapsamlı kontrol yapıları sağlar.

LISP'de Yerleşik Uygulamalar

Lisp'te yerleşik büyük başarılı uygulamalar.

  • Emacs

  • G2

  • AutoCad

  • Igor Oymacı

  • Yahoo Mağazası

Yerel Ortam Kurulumu

Hala Lisp programlama dili için ortamınızı kurmaya istekli iseniz, bilgisayarınızda bulunan şu iki yazılıma ihtiyacınız vardır, (a) Metin Düzenleyicisi ve (b) Lisp Yürütücüsü.

Metin düzeltici

Bu, programınızı yazmak için kullanılacaktır. Birkaç düzenleyicinin örnekleri arasında Windows Not Defteri, İşletim Sistemi Düzenleme komutu, Kısa, Epsilon, EMACS ve vim veya vi bulunur.

Metin düzenleyicinin adı ve sürümü farklı işletim sistemlerine göre değişebilir. Örneğin, Not Defteri Windows'ta kullanılacak ve vim veya vi, Linux veya UNIX'in yanı sıra Windows'ta da kullanılabilir.

Düzenleyicinizle oluşturduğunuz dosyalara kaynak dosyalar denir ve program kaynak kodunu içerir. Lisp programlarının kaynak dosyaları genellikle ".lisp".

Programlamanıza başlamadan önce, bir metin düzenleyiciniz olduğundan ve bir bilgisayar programı yazmak için yeterli deneyime sahip olduğunuzdan, onu bir dosyaya kaydettiğinizden ve sonunda onu çalıştırdığınızdan emin olun.

Lisp Yürütücüsü

Kaynak dosyada yazılan kaynak kodu, programınız için okunabilir kaynaktır. Makine diline dönüşmesi için "çalıştırılması" gerekir, böylece CPU'nuz programı verilen talimatlara göre gerçekten çalıştırabilir.

Bu Lisp programlama dili, kaynak kodunuzu son çalıştırılabilir programa yürütmek için kullanılacaktır. Bir programlama dili hakkında temel bilgiye sahip olduğunuzu varsayıyorum.

CLISP, Windows'ta LISP'yi kurmak için kullanılan GNU Common LISP multi-architechtural derleyicisidir. Windows sürümü, Windows altında MingW kullanarak bir unix ortamını taklit eder. Yükleyici bununla ilgilenir ve Windows PATH değişkenine otomatik olarak clisp ekler.

Windows için en son CLISP'i buradan edinebilirsiniz - https://sourceforge.net/projects/clisp/files/latest/download

Varsayılan olarak, satır satır yorumlayıcı için Başlat Menüsünde bir kısayol oluşturur.

CLISP nasıl kullanılır

Yükleme sırasında, clisp (ÖNERİLEN) seçeneğini seçerseniz, PATH değişkeninize otomatik olarak eklenir. Bu, yeni bir Komut İstemi penceresi açıp derleyiciyi açmak için "clisp" yazabileceğiniz anlamına gelir.

Bir * .lisp veya * .lsp dosyasını çalıştırmak için, sadece -

clisp hello.lisp

LISP ifadelerine sembolik ifadeler veya s-ifadeleri denir. S-ifadeleri üç geçerli nesneden, atomlardan, listelerden ve dizelerden oluşur.

Herhangi bir s-ifadesi geçerli bir programdır.

LISP programları bir interpreter veya olarak compiled code.

Yorumlayıcı, aynı zamanda okuma-değerlendirme-yazdırma döngüsü (REPL) olarak da adlandırılan tekrarlanan bir döngüde kaynak kodunu kontrol eder. Program kodunu okur, değerlendirir ve programın döndürdüğü değerleri yazdırır.

Basit Bir Program

7, 9 ve 11 numaralı üç sayının toplamını bulmak için bir s-ifadesi yazalım. Bunu yapmak için, yorumlayıcı komut istemine yazabiliriz.

(+ 7 9 11)

LISP sonucu verir -

27

Aynı programı derlenmiş bir kodla çalıştırmak isterseniz, myprog.lisp adlı bir LISP kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (+ 7 9 11))

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

27

LISP Önek Gösterimini Kullanır

LISP'nin kullandığını fark etmiş olabilirsiniz prefix notation.

Yukarıdaki programda + sembolü, sayıların toplanması işlemi için işlev adı olarak çalışır.

Önek gösteriminde operatörler, işlenenlerinden önce yazılır. Örneğin, ifade,

a * ( b + c ) / d

olarak yazılacak -

(/ (* a (+ b c) ) d)

Başka bir örnek alalım, 60 o F Fahrenheit sıcaklığını santigrat ölçeğine dönüştürmek için kod yazalım -

Bu dönüşüm için matematiksel ifade şöyle olacaktır:

(60 * 9 / 5) + 32

Main.lisp adlı bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write(+ (* (/ 9 5) 60) 32))

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç şu şekildedir

140

LISP Programlarının Değerlendirilmesi

LISP programlarının değerlendirilmesi iki bölümden oluşur -

  • Program metninin bir okuyucu programı tarafından Lisp nesnelerine çevrilmesi

  • Dilin anlambiliminin bu nesneler açısından bir değerlendirici program tarafından uygulanması

Değerlendirme süreci aşağıdaki adımları gerçekleştirir -

  • Okuyucu, karakter dizilerini LISP nesnelerine çevirir veya s-expressions.

  • Değerlendirici, Lisp'in sözdizimini tanımlar formss-ifadelerinden oluşturulmuştur. Bu ikinci değerlendirme düzeyi, hangisi olduğunu belirleyen bir sözdizimi tanımlars-expressions LISP formlarıdır.

  • Değerlendirici, bağımsız değişken olarak geçerli bir LISP formunu alan ve bir değer döndüren bir işlev olarak çalışır. LISP ifadesini parantez içine koymamızın nedeni budur, çünkü tüm ifadeyi / formu değerlendiriciye argüman olarak gönderiyoruz.

'Merhaba Dünya' Programı

Yeni bir programlama dili öğrenmek, tüm dünyayı o dilde nasıl selamlayacağınızı öğrenene kadar pek işe yaramaz, değil mi!

Bu nedenle, lütfen main.lisp adlı yeni kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write-line "Hello World")

(write-line "I am at 'Tutorials Point'! Learning LISP")

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

Hello World

I am at 'Tutorials Point'! Learning LISP

LISP'deki Temel Yapı Taşları

LISP programları, üç temel yapı taşından oluşur -

  • atom
  • list
  • string

Bir atombitişik karakterlerden oluşan bir sayı veya dizedir. Sayılar ve özel karakterler içerir.

Aşağıda bazı geçerli atomların örnekleri verilmiştir -

hello-from-tutorials-point
name
123008907
*hello*
Block#221
abc123

Bir list bir atom dizisidir ve / veya parantez içine alınmış diğer listelerdir.

Aşağıda bazı geçerli listelere örnekler verilmiştir -

( i am a list)
(a ( a b c) d e fgh)
(father tom ( susan bill joe))
(sun mon tue wed thur fri sat)
( )

Bir string çift ​​tırnak içine alınmış bir karakter grubudur.

Aşağıda bazı geçerli dizelerin örnekleri verilmiştir -

" I am a string"
"a ba c d efg #$%^&!"
"Please enter the following details :"
"Hello from 'Tutorials Point'! "

Yorum Ekleme

Noktalı virgül simgesi (;) bir açıklama satırını belirtmek için kullanılır.

Örneğin,

(write-line "Hello World") ; greet the world

; tell them your whereabouts

(write-line "I am at 'Tutorials Point'! Learning LISP")

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

Hello World

I am at 'Tutorials Point'! Learning LISP

Bir Sonrakine Geçmeden Önce Bazı Önemli Noktalar

Aşağıda dikkat edilmesi gereken önemli noktalardan bazıları verilmiştir -

  • LISP'deki temel sayısal işlemler +, -, * ve /

  • LISP, f (x) işlev çağrısını (fx) olarak temsil eder, örneğin cos (45) cos 45 olarak yazılır

  • LISP ifadeleri büyük / küçük harfe duyarlı değildir, cos 45 veya COS 45 aynıdır.

  • LISP, bir işlevin argümanları dahil her şeyi değerlendirmeye çalışır. Yalnızca üç tür öğe sabittir ve her zaman kendi değerlerini döndürür

    • Numbers

    • Mektup t, bu mantıksal doğru anlamına gelir.

    • Değer nil, bu, mantıksal yanlış ve boş bir liste anlamına gelir.

LISP Formları Hakkında Biraz Daha Fazla Bilgi

Bir önceki bölümde, LISP kodunun değerlendirme sürecinin aşağıdaki adımlardan geçtiğinden bahsetmiştik.

  • Okuyucu, karakter dizilerini LISP nesnelerine çevirir veya s-expressions.

  • Değerlendirici, Lisp'in sözdizimini tanımlar formss-ifadelerinden oluşturulmuştur. Bu ikinci değerlendirme düzeyi, hangi s-ifadelerinin LISP formları olduğunu belirleyen bir sözdizimi tanımlar.

Şimdi, bir LISP formları olabilir.

  • Bir atom
  • Boş veya liste dışı
  • İlk öğesi olarak bir sembole sahip herhangi bir liste

Değerlendirici, bağımsız değişken olarak geçerli bir LISP formunu alan ve bir değer döndüren bir işlev olarak çalışır. Bu, koymamızın nedeniLISP expression in parenthesis, çünkü tüm ifadeyi / formu değerlendiriciye argüman olarak gönderiyoruz.

LISP'de Adlandırma Kuralları

Ad veya semboller, boşluk, açık ve kapalı parantezler, çift ve tek tırnak işaretleri, ters eğik çizgi, virgül, iki nokta üst üste, noktalı virgül ve dikey çubuk dışında herhangi bir sayıda alfasayısal karakterden oluşabilir. Bu karakterleri bir adda kullanmak için, çıkış karakterini (\) kullanmanız gerekir.

Bir isim rakamlara sahip olabilir, ancak tamamen rakamlardan oluşmayabilir, çünkü o zaman bir sayı olarak okunur. Benzer şekilde, bir adda dönemler olabilir, ancak tamamen dönemlerden oluşamaz.

Tek Tırnak İşaretinin Kullanımı

LISP, işlev bağımsız değişkenleri ve liste üyeleri dahil her şeyi değerlendirir.

Bazen, atomları veya listeleri tam anlamıyla almamız gerekir ve bunların işlev çağrıları olarak değerlendirilmesini veya ele alınmasını istemeyiz.

Bunu yapmak için atomun veya listenin önüne tek bir tırnak işareti koymamız gerekir.

Aşağıdaki örnek bunu göstermektedir.

Main.lisp adlı bir dosya oluşturun ve içine aşağıdaki kodu yazın.

(write-line "single quote used, it inhibits evaluation")
(write '(* 2 3))
(write-line " ")
(write-line "single quote not used, so expression evaluated")
(write (* 2 3))

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

single quote used, it inhibits evaluation
(* 2 3) 
single quote not used, so expression evaluated
6

LISP'de değişkenler yazılmaz, ancak veri nesneleri yazılır.

LISP veri türleri olarak kategorize edilebilir.

  • Scalar types - örneğin sayı türleri, karakterler, semboller vb.

  • Data structures - örneğin listeler, vektörler, bit vektörler ve dizeler.

Açıkça belirtmediğiniz sürece, herhangi bir değişken herhangi bir LISP nesnesini değeri olarak alabilir.

Bir LISP değişkeni için bir veri türü belirtmek gerekli olmasa da, belirli döngü genişletmelerinde, yöntem bildirimlerinde ve sonraki bölümlerde tartışacağımız diğer bazı durumlarda yardımcı olur.

Veri türleri bir hiyerarşi içinde düzenlenmiştir. Bir veri türü, bir LISP nesneleri kümesidir ve birçok nesne bu tür bir kümeye ait olabilir.

typep yüklem, bir nesnenin belirli bir türe ait olup olmadığını bulmak için kullanılır.

type-of işlev, belirli bir nesnenin veri türünü döndürür.

LISP'de Tip Tanımlayıcıları

Tür belirleyicileri, veri türleri için sistem tanımlı sembollerdir.

dizi Fixnum paket basit dizgi
atom yüzen yol adı basit vektör
Bignum işlevi rasgele durum tek şamandıra
bit karma tablo oran standart karakter
bit vektör tamsayı akılcı Akış
karakter anahtar kelime okunabilir dizi
[Yaygın] liste sıra [string-char]
derlenmiş işlev uzun şamandıra kısa şamandıra sembol
karmaşık nill imzalı bayt t
Eksileri boş basit dizi işaretsiz bayt
çift ​​yüzer numara basit bit vektör vektör

Bu sistem tanımlı türlerin yanı sıra, kendi veri türlerinizi oluşturabilirsiniz. Bir yapı türü kullanılarak tanımlandığındadefstruct işlev, yapı türünün adı geçerli bir tür simgesi haline gelir.

örnek 1

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq x 10)
(setq y 34.567)
(setq ch nil)
(setq n 123.78)
(setq bg 11.0e+4)
(setq r 124/2)

(print x)
(print y)
(print n)
(print ch)
(print bg)
(print r)

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

10 
34.567 
123.78 
NIL 
110000.0 
62

Örnek 2

Ardından, önceki örnekte kullanılan değişkenlerin türlerini kontrol edelim. Main adlı yeni kaynak kodu dosyası oluşturun. lisp ve içine aşağıdaki kodu yazın.

(defvar x 10)
(defvar y 34.567)
(defvar ch nil)
(defvar n 123.78)
(defvar bg 11.0e+4)
(defvar r 124/2)

(print (type-of x))
(print (type-of y))
(print (type-of n))
(print (type-of ch))
(print (type-of bg))
(print (type-of r))

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

(INTEGER 0 281474976710655) 
SINGLE-FLOAT 
SINGLE-FLOAT 
NULL 
SINGLE-FLOAT 
(INTEGER 0 281474976710655)

Makrolar, standart LISP'nin sözdizimini genişletmenize izin verir.

Teknik olarak, makro, bağımsız değişken olarak s-ifadesini alan ve daha sonra değerlendirilecek olan bir LISP formu döndüren bir işlevdir.

Bir Makro Tanımlama

LISP'de adlandırılmış bir makro, adlı başka bir makro kullanılarak tanımlanır defmacro. Bir makro tanımlamak için sözdizimi -

(defmacro macro-name (parameter-list))
"Optional documentation string."
body-form

Makro tanımı, makronun adından, bir parametre listesinden, isteğe bağlı bir dokümantasyon dizisinden ve makro tarafından gerçekleştirilecek işi tanımlayan bir Lisp ifadeleri gövdesinden oluşur.

Misal

Bir sayı alıp değerini 10 olarak ayarlayacak setTo10 adında basit bir makro yazalım.

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defmacro setTo10(num)
(setq num 10)(print num))
(setq x 25)
(print x)
(setTo10 x)

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

25
10

LISP'de her değişken bir symbol. Değişkenin adı, sembolün adıdır ve sembolün saklama hücresinde saklanır.

Global Değişkenler

Global değişkenler, LISP sistemi boyunca kalıcı değerlere sahiptir ve yeni bir değer belirtilinceye kadar yürürlükte kalır.

Global değişkenler genellikle defvar inşa etmek.

Örneğin

(defvar x 234)
(write x)

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç

234

LISP'de değişkenler için tür bildirimi olmadığından, doğrudan bir sembol için bir değer belirtirsiniz. setq inşa etmek.

Örneğin

->(setq x 10)

Yukarıdaki ifade, 10 değerini x değişkenine atar. Sembolün kendisini bir ifade olarak kullanarak değişkene başvurabilirsiniz.

symbol-value işlevi, sembol saklama yerinde saklanan değeri çıkarmanıza izin verir.

Örneğin

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq x 10)
(setq y 20)
(format t "x = ~2d y = ~2d ~%" x y)

(setq x 100)
(setq y 200)
(format t "x = ~2d y = ~2d" x y)

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç olur.

x = 10 y = 20 
x = 100 y = 200

Yerel Değişkenler

Yerel değişkenler, belirli bir prosedür içinde tanımlanır. Bir işlev tanımında bağımsız değişken olarak adlandırılan parametreler de yerel değişkenlerdir. Yerel değişkenlere yalnızca ilgili işlev içinde erişilebilir.

Global değişkenler gibi, yerel değişkenler de setq inşa etmek.

Başka iki yapı var - let ve prog yerel değişkenler oluşturmak için.

Let yapısı aşağıdaki sözdizimine sahiptir.

(let ((var1  val1) (var2  val2).. (varn  valn))<s-expressions>)

Burada var1, var2, ..varn değişken isimleridir ve val1, val2, .. valn ilgili değişkenlere atanan ilk değerlerdir.

Ne zaman letçalıştırılır, her değişkene ilgili değer atanır ve son olarak s-ifadesi değerlendirilir. Değerlendirilen son ifadenin değeri döndürülür.

Bir değişken için bir başlangıç ​​değeri dahil etmezseniz, nil.

Misal

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(let ((x 'a) (y 'b)(z 'c))
(format t "x = ~a y = ~a z = ~a" x y z))

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç olur.

x = A y = B z = C

prog construct ayrıca ilk argüman olarak yerel değişkenlerin listesine sahiptir ve bunu, prog, ve herhangi bir sayıda s-ifadesi.

prog işlev, s-ifadelerinin listesini sırayla çalıştırır ve adında bir işlev çağrısıyla karşılaşmadığı sürece nil değerini döndürür return. Sonra argümanı return işlev değerlendirilir ve döndürülür.

Misal

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(prog ((x '(a b c))(y '(1 2 3))(z '(p q 10)))
(format t "x = ~a y = ~a z = ~a" x y z))

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç olur.

x = (A B C) y = (1 2 3) z = (P Q 10)

LISP'de sabitler, program yürütülürken değerlerini asla değiştirmeyen değişkenlerdir. Sabitler, kullanılarak bildirilirdefconstant inşa etmek.

Misal

Aşağıdaki örnek, bir genel sabit PI bildirmeyi ve daha sonra bu değeri , bir dairenin alanını hesaplayan alan-daire adlı bir işlev içinde kullanmayı gösterir .

defun yapı, bir işlevi tanımlamak için kullanılır, biz ona Functions bölüm.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defconstant PI 3.141592)
(defun area-circle(rad)
   (terpri)
   (format t "Radius: ~5f" rad)
   (format t "~%Area: ~10f" (* PI rad rad)))
(area-circle 10)

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç olur.

Radius:  10.0
Area:   314.1592

Operatör, derleyiciye belirli matematiksel veya mantıksal işlemleri gerçekleştirmesini söyleyen bir semboldür. LISP, çeşitli işlevler, makrolar ve diğer yapılarla desteklenen veriler üzerinde çok sayıda işleme izin verir.

Veriler üzerinde izin verilen işlemler şu şekilde kategorize edilebilir:

  • Aritmetik işlemler
  • Karşılaştırma İşlemleri
  • Mantıksal İşlemler
  • Bitsel İşlemler

Aritmetik işlemler

Aşağıdaki tablo, LISP tarafından desteklenen tüm aritmetik işleçleri göstermektedir. Değişken varsayA 10 ve değişken tutar B 20 tutar sonra -

Show Examples

Şebeke Açıklama Misal
+ İki işlenen ekler (+ AB) 30 verecek
- İlk işlenenden ikinci işleneni çıkarır (- AB) -10 verecektir
* Her iki işleneni de çarpar (* AB) 200 verecek
/ Payı, pay azaltıcıya böler (/ BA) 2 verir
mod, rem Modül İşleci ve bir tamsayı bölmesinden sonra kalanı (mod BA) 0 verecek
incf Arttırma operatörü, belirtilen ikinci bağımsız değişkenle tamsayı değerini artırır (A 3 dahil) 13 verecektir
decf Azaltma operatörü, belirtilen ikinci bağımsız değişken kadar tamsayı değerini azaltır (decf A 4) 9 verir

Karşılaştırma İşlemleri

Aşağıdaki tablo, LISP tarafından desteklenen ve sayılar arasında karşılaştırma yapan tüm ilişkisel operatörleri göstermektedir. Bununla birlikte, diğer dillerdeki ilişkisel operatörlerin aksine, LISP karşılaştırma operatörleri ikiden fazla işlenen alabilir ve yalnızca sayılar üzerinde çalışırlar.

Değişken varsay A 10 ve değişken tutar B 20 tutar, sonra -

Show Examples

Şebeke Açıklama Misal
= İşlenenlerin değerlerinin hepsinin eşit olup olmadığını kontrol eder, evet ise koşul doğru olur. (= AB) doğru değil.
/ = İşlenenlerin değerlerinin tümünün farklı olup olmadığını kontrol eder, değerler eşit değilse koşul doğru olur. (/ = AB) doğrudur.
> İşlenenlerin değerlerinin tekdüze olarak azalıp azalmadığını kontrol eder. (> AB) doğru değil.
< İşlenenlerin değerlerinin monoton olarak artıp artmadığını kontrol eder. (<AB) doğrudur.
> = Herhangi bir sol işlenenin değerinin bir sonraki sağ işlenenin değerinden büyük veya ona eşit olup olmadığını kontrol eder, evet ise koşul doğru olur. (> = AB) doğru değil.
<= Herhangi bir sol işlenenin değerinin sağ işlenenin değerinden küçük veya ona eşit olup olmadığını kontrol eder, evet ise koşul doğru olur. (<= AB) doğrudur.
max İki veya daha fazla argümanı karşılaştırır ve maksimum değeri döndürür. (maks AB), 20 değerini döndürür
min İki veya daha fazla argümanı karşılaştırır ve minimum değeri döndürür. (dk AB), 10 değerini döndürür

Boole Değerlerinde Mantıksal İşlemler

Common LISP, üç mantıksal operatör sağlar: and, or, ve notBoolean değerleri üzerinde çalışır. VarsaymakA sıfır değerine sahiptir ve B 5 değerine sahipse -

Show Examples

Şebeke Açıklama Misal
ve Herhangi bir sayıda argüman alır. Argümanlar soldan sağa doğru değerlendirilir. Tüm bağımsız değişkenler sıfır olmayan olarak değerlendirilirse, son bağımsız değişkenin değeri döndürülür. Aksi takdirde nil döndürülür. (ve AB) NIL döndürür.
veya Herhangi bir sayıda argüman alır. Bağımsız değişkenler sıfır olmayan olarak değerlendirilene kadar soldan sağa değerlendirilir, bu durumda bağımsız değişken değeri döndürülür, aksi takdirde döndürürnil. (veya AB) 5 döndürür.
değil Bir argüman alır ve geri döner t argüman değerlendirilirse nil. (A değil) T döndürür.

Sayılarda Bitsel İşlemler

Bitsel operatörler bitler üzerinde çalışır ve bit bit işlem gerçekleştirir. Bitsel ve, or, ve xor işlemleri için doğruluk tabloları aşağıdaki gibidir -

Show Examples

p q p ve q p veya q p xor q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
Assume if A = 60; and B = 13; now in binary format they will be as follows:
A = 0011 1100
B = 0000 1101
-----------------
A and B = 0000 1100
A or B = 0011 1101
A xor B = 0011 0001
not A  = 1100 0011

LISP tarafından desteklenen Bitwise operatörleri aşağıdaki tabloda listelenmiştir. Değişken varsayA 60 ve değişken tutar B 13 tutar, sonra -

Şebeke Açıklama Misal
logand Bu, argümanlarının bit bazında mantıksal AND'sini döndürür. Herhangi bir argüman verilmemişse, sonuç bu işlem için bir özdeşlik olan -1'dir. (logand ab)) 12 verecektir
Logior Bu, argümanlarının bit-bazında mantıksal KAPSAYICI VEYA'ını döndürür. Herhangi bir argüman verilmemişse, sonuç sıfırdır ve bu işlem için bir kimliktir. (logior ab) 61 verecektir
logxor Bu, argümanlarının bit bazında mantıksal HARİÇ VEYA HARİÇ VEYA değerini döndürür. Herhangi bir argüman verilmemişse, sonuç sıfırdır ve bu işlem için bir kimliktir. (logxor ab) 49 verecektir
Lognor Bu, argümanlarının bit bazında NOT değerini döndürür. Herhangi bir argüman verilmemişse, sonuç bu işlem için bir özdeşlik olan -1'dir. (lognor ab) -62 verir,
logeqv Bu, argümanlarının bit bazında mantıksal EŞDEĞERİNİ (dışlayıcı ne olarak da bilinir) döndürür. Herhangi bir argüman verilmemişse, sonuç bu işlem için bir özdeşlik olan -1'dir. (logeqv ab) -50 verir

Karar verme yapıları, programcının, program tarafından değerlendirilecek veya test edilecek bir veya daha fazla koşulu, koşulun doğru olduğu belirlenirse yürütülecek bir ifade veya ifadeyle birlikte belirtmesini ve isteğe bağlı olarak, koşulun doğru olması durumunda yürütülecek diğer ifadeleri gerektirir. yanlış olduğu belirlenir.

Aşağıda, programlama dillerinin çoğunda bulunan tipik bir karar verme yapısının genel biçimi verilmiştir -

LISP, aşağıdaki karar verme yapılarını sağlar. Ayrıntılarını kontrol etmek için aşağıdaki bağlantıları tıklayın.

Sr.No. İnşa ve Açıklama
1 koşul

Bu yapı, birden çok test eylemi cümlesini kontrol etmek için kullanılır. Diğer programlama dillerindeki iç içe geçmiş if ifadeleriyle karşılaştırılabilir.

2 Eğer

İf yapısının çeşitli biçimleri vardır. En basit haliyle, bunu bir test maddesi, bir test eylemi ve diğer bazı müteakip eylem (ler) izler. Test koşulu doğru olarak değerlendirilirse, aksi takdirde test eylemi yürütülür, sonuçtaki madde değerlendirilir.

3 ne zaman

En basit şekliyle, bunu bir test maddesi ve bir test eylemi izler. Test koşulu doğru olarak değerlendirilirse, aksi takdirde test eylemi yürütülür, sonuçtaki madde değerlendirilir.

4 durum

Bu yapı, koşul yapısı gibi birden çok test eylemi cümlesi uygular. Bununla birlikte, bir anahtar formu değerlendirir ve bu anahtar formun değerlendirilmesine dayalı olarak birden çok eylem maddesine izin verir.

Bir kod bloğu bloğunu defalarca çalıştırmanız gerektiğinde bir durum olabilir. Bir döngü deyimi, bir deyimi veya deyim grubunu birden çok kez yürütmemize izin verir ve aşağıdaki, programlama dillerinin çoğunda bir döngü deyiminin genel biçimidir.

LISP, döngü gereksinimlerini karşılamak için aşağıdaki yapı türlerini sağlar. Ayrıntılarını kontrol etmek için aşağıdaki bağlantıları tıklayın.

Sr.No. İnşa ve Açıklama
1 döngü

loopyapı, LISP tarafından sağlanan en basit yineleme biçimidir. En basit haliyle, bazı ifadeleri bulana kadar tekrar tekrar çalıştırmanıza izin verir.return Beyan.

2 döngü için

Oluşturma döngüsü, diğer dillerde en yaygın olan döngü benzeri yineleme uygulamanıza olanak tanır.

3 yapmak

Do yapısı, LISP kullanarak yineleme yapmak için de kullanılır. Yapılandırılmış bir yineleme biçimi sağlar.

4 nokta zamanları

Dotimes yapısı, bazı sabit sayıda yineleme için döngüye izin verir.

5 yapılacaklar listesi

Dolist yapısı, bir listenin her öğesi boyunca yinelemeye izin verir.

Bloktan Sorunsuz Bir Şekilde Çıkma

block ve return-from herhangi bir hata durumunda herhangi bir iç içe bloktan zarif bir şekilde çıkmanızı sağlar.

blockişlevi, sıfır veya daha fazla ifadeden oluşan bir gövdeye sahip adlandırılmış bir blok oluşturmanıza olanak sağlar. Sözdizimi -

(block block-name(
...
...
))

return-from işlev bir blok adı ve isteğe bağlı (varsayılan sıfırdır) bir dönüş değeri alır.

Aşağıdaki örnek bunu göstermektedir -

Misal

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın -

(defun demo-function (flag)
   (print 'entering-outer-block)
   
   (block outer-block
      (print 'entering-inner-block)
      (print (block inner-block

         (if flag
            (return-from outer-block 3)
            (return-from inner-block 5)
         )

         (print 'This-wil--not-be-printed))
      )

      (print 'left-inner-block)
      (print 'leaving-outer-block)
   t)
)
(demo-function t)
(terpri)
(demo-function nil)

Yürüt düğmesine tıkladığınızda veya Ctrl + E tuşlarına bastığınızda, LISP bunu hemen yürütür ve döndürülen sonuç -

ENTERING-OUTER-BLOCK 
ENTERING-INNER-BLOCK 

ENTERING-OUTER-BLOCK 
ENTERING-INNER-BLOCK 
5 
LEFT-INNER-BLOCK 
LEAVING-OUTER-BLOCK

Bir işlev, birlikte bir görevi yerine getiren bir grup deyimdir.

Kodunuzu ayrı işlevlere bölebilirsiniz. Kodunuzu farklı işlevler arasında nasıl böleceğiniz size bağlıdır, ancak mantıksal olarak bölme genellikle her işlevin belirli bir görevi yerine getirmesidir.

LISP'de Fonksiyonları Tanımlama

Adlı makro defunfonksiyonları tanımlamak için kullanılır. defun makronun üç bağımsız değişkene ihtiyacı vardır -

  • Fonksiyonun adı
  • Fonksiyonun parametreleri
  • İşlevin gövdesi

Defun için sözdizimi -

(defun name (parameter-list) "Optional documentation string." body)

Konsepti basit örneklerle gösterelim.

örnek 1

Dört sayının ortalamasını basacak averagenum adlı bir fonksiyon yazalım . Bu numaraları parametre olarak göndereceğiz.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun averagenum (n1 n2 n3 n4)
   (/ ( + n1 n2 n3 n4) 4)
)
(write(averagenum 10 20 30 40))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

25

Örnek 2

Çemberin yarıçapı argüman olarak verildiğinde çemberin alanını hesaplayacak bir fonksiyon tanımlayalım ve çağıralım.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun area-circle(rad)
   "Calculates area of a circle with given radius"
   (terpri)
   (format t "Radius: ~5f" rad)
   (format t "~%Area: ~10f" (* 3.141592 rad rad))
)
(area-circle 10)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Radius:  10.0
Area:   314.1592

Lütfen unutmayın -

  • Parametre olarak boş bir liste sağlayabilirsiniz; bu, işlevin argüman almadığı, listenin boş olduğu ve () olarak yazıldığı anlamına gelir.

  • LISP ayrıca isteğe bağlı, çoklu ve anahtar sözcük argümanlarına da izin verir.

  • Dokümantasyon dizisi, fonksiyonun amacını açıklar. İşlevin adı ile ilişkilendirilir ve şu kullanılarak elde edilebilir:documentation işlevi.

  • İşlevin gövdesi, herhangi bir sayıda Lisp ifadesinden oluşabilir.

  • Gövdedeki son ifadenin değeri, işlevin değeri olarak döndürülür.

  • Ayrıca, işlevden bir değer döndürebilirsiniz. return-from özel operatör.

Yukarıdaki kavramları kısaca tartışalım. Ayrıntıları bulmak için aşağıdaki bağlantıları tıklayın -

  • Opsiyonel Parametreler

  • Dinlenme Parametreleri

  • Anahtar Kelime Parametreleri

  • Bir Fonksiyondan Değerleri Döndürme

  • Lambda İşlevleri

  • Eşleme İşlevleri

Tahminler, bazı belirli koşullar için bağımsız değişkenlerini test eden ve koşul yanlışsa veya koşul doğruysa sıfır olmayan bir değer döndüren işlevlerdir.

Aşağıdaki tablo en sık kullanılan bazı yüklemleri göstermektedir -

Sr.No. Dayanak ve Açıklama
1

atom

Bir bağımsız değişken alır ve bağımsız değişken bir atom ise t, aksi takdirde sıfır döndürür.

2

equal

İki argüman alır ve geri döner t yapısal olarak eşitlerse veya nil aksi takdirde.

3

eq

İki argüman alır ve geri döner t aynı özdeş nesneler ise, aynı hafıza konumunu paylaşıyorlarsa veya nil aksi takdirde.

4

eql

İki argüman alır ve geri döner t eğer argümanlar eqveya aynı türde ve aynı değere sahip sayılarsa veya aynı karakteri temsil eden karakter nesneleri ise veya nil aksi takdirde.

5

evenp

Bir sayısal argüman alır ve geri döner t bağımsız değişken çift sayı ise veya nil aksi takdirde.

6

oddp

Bir sayısal argüman alır ve geri döner t bağımsız değişken tek sayı ise veya nil aksi takdirde.

7

zerop

Bir sayısal argüman alır ve geri döner t argüman sıfırsa veya nil aksi takdirde.

8

null

Bir argüman alır ve geri döner t bağımsız değişken sıfır olarak değerlendirilirse, aksi takdirde döndürür nil.

9

listp

Bir argüman alır ve geri döner t bağımsız değişken bir liste olarak değerlendirilirse, aksi takdirde döndürür nil.

10

greaterp

Bir veya daha fazla argüman alır ve geri döner t Ya tek bir argüman varsa veya argümanlar art arda soldan sağa doğru daha büyükse veya nil aksi takdirde.

11

lessp

Bir veya daha fazla argüman alır ve geri döner t Ya tek bir argüman varsa veya argümanlar art arda soldan sağa doğru daha küçükse veya nil aksi takdirde.

12

numberp

Bir argüman alır ve geri döner t argüman bir sayı ise veya nil aksi takdirde.

13

symbolp

Bir argüman alır ve geri döner t eğer argüman bir sembol ise, aksi halde geri döner nil.

14

integerp

Bir argüman alır ve geri döner t bağımsız değişken bir tamsayı ise, aksi takdirde döndürür nil.

15

rationalp

Bir argüman alır ve geri döner t argüman rasyonel sayı ise, bir oran veya bir sayı, aksi takdirde döndürür nil.

16

floatp

Bir argüman alır ve geri döner t bağımsız değişken bir kayan noktalı sayı ise, aksi takdirde döndürür nil.

17

realp

Bir argüman alır ve geri döner t bağımsız değişken gerçek bir sayı ise, aksi takdirde döndürür nil.

18

complexp

Bir argüman alır ve geri döner t bağımsız değişken karmaşık bir sayı ise, aksi takdirde döndürür nil.

19

characterp

Bir argüman alır ve geri döner t argüman bir karakter ise, aksi takdirde döndürür nil.

20

stringp

Bir argüman alır ve geri döner t argüman bir dizge nesnesiyse, aksi takdirde döndürür nil.

21

arrayp

Bir argüman alır ve geri döner t argüman bir dizi nesnesiyse, aksi takdirde döndürür nil.

22

packagep

Bir argüman alır ve geri döner t argüman bir paketse, aksi takdirde geri döner nil.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (atom 'abcd))
(terpri)
(write (equal 'a 'b))
(terpri)
(write (evenp 10))
(terpri)
(write (evenp 7 ))
(terpri)
(write (oddp 7 ))
(terpri)
(write (zerop 0.0000000001))
(terpri)
(write (eq 3 3.0 ))
(terpri)
(write (equal 3 3.0 ))
(terpri)
(write (null nil ))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

T
NIL
T
NIL
T
NIL
NIL
NIL
T

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun factorial (num)
   (cond ((zerop num) 1)
      (t ( * num (factorial (- num 1))))
   )
)
(setq n 6)
(format t "~% Factorial ~d is: ~d" n (factorial n))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Factorial 6 is: 720

Common Lisp birkaç çeşit sayı tanımlar. number veri türü, LISP tarafından desteklenen çeşitli sayı türlerini içerir.

LISP tarafından desteklenen numara türleri şunlardır:

  • Integers
  • Ratios
  • Kayan nokta sayıları
  • Karışık sayılar

Aşağıdaki diyagram, LISP'de bulunan sayı hiyerarşisini ve çeşitli sayısal veri türlerini göstermektedir -

LISP'de Çeşitli Sayısal Türler

Aşağıdaki tablo, LISP'de bulunan çeşitli numara türü verilerini açıklamaktadır -

Sr.No. Veri türü ve Açıklama
1

fixnum

Bu veri türü, çok büyük olmayan ve çoğunlukla -215 ila 215-1 aralığındaki tam sayıları temsil eder (makineye bağlıdır)

2

bignum

Bunlar, LISP için ayrılan bellek miktarı ile sınırlı boyuta sahip çok büyük sayılardır, sabit sayılar değildirler.

3

ratio

Pay / payda formundaki iki sayının oranını temsil eder. / İşlevi, bağımsız değişkenleri tam sayı olduğunda, sonucu daima oranlarda üretir.

4

float

Tam sayı olmayan sayıları temsil eder. Artan hassasiyete sahip dört kayan veri türü vardır.

5

complex

#C ile gösterilen karmaşık sayıları temsil eder. Gerçek ve sanal kısımlar hem rasyonel hem de kayan nokta sayıları olabilir.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (/ 1 2))
(terpri)
(write ( + (/ 1 2) (/ 3 4)))
(terpri)
(write ( + #c( 1 2) #c( 3 -4)))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

1/2
5/4
#C(4 -2)

Sayı İşlevleri

Aşağıdaki tablo yaygın olarak kullanılan bazı sayısal işlevleri açıklamaktadır -

Sr.No. İşlev ve Açıklama
1

+, -, *, /

İlgili aritmetik işlemler

2

sin, cos, tan, acos, asin, atan

İlgili trigonometrik fonksiyonlar.

3

sinh, cosh, tanh, acosh, asinh, atanh

İlgili hiperbolik işlevler.

4

exp

Üs alma işlevi. E x'i hesaplar

5

expt

Üs alma fonksiyonu, hem temel hem de güç alır.

6

sqrt

Bir sayının karekökünü hesaplar.

7

log

Logaritmik fonksiyon. Bir parametre verilir, sonra doğal logaritmasını hesaplar, aksi takdirde ikinci parametre temel olarak kullanılır.

8

conjugate

Bir sayının karmaşık eşleniğini hesaplar. Gerçek sayı olması durumunda, sayının kendisini döndürür.

9

abs

Bir sayının mutlak değerini (veya büyüklüğünü) döndürür.

10

gcd

Verilen sayıların en büyük ortak bölenini hesaplar.

11

lcm

Verilen sayıların en küçük ortak katını hesaplar.

12

isqrt

Belirli bir doğal sayının tam karekökünden küçük veya ona eşit en büyük tamsayıyı verir.

13

floor, ceiling, truncate, round

Tüm bu işlevler sayı olarak iki bağımsız değişken alır ve bölümü döndürür; floor orandan büyük olmayan en büyük tamsayıyı döndürür, ceiling orandan büyük olan daha küçük tamsayıyı seçer, truncate Oranın mutlak değerinden daha küçük olan en büyük mutlak değere sahip oran olarak aynı işaretin tamsayısını seçer ve round orana en yakın olan bir tamsayı seçer.

14

ffloor, fceiling, ftruncate, fround

Yukarıdakinin aynısını yapar, ancak bölümü kayan nokta sayısı olarak döndürür.

15

mod, rem

Bölme işleminde kalanı döndürür.

16

float

Gerçek bir sayıyı kayan noktalı sayıya dönüştürür.

17

rational, rationalize

Gerçek bir sayıyı rasyonel sayıya çevirir.

18

numerator, denominator

Rasyonel bir sayının ilgili kısımlarını verir.

19

realpart, imagpart

Karmaşık bir sayının gerçek ve sanal kısmını döndürür.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (/ 45 78))
(terpri)
(write (floor 45 78))
(terpri)
(write (/ 3456 75))
(terpri)
(write (floor 3456 75))
(terpri)
(write (ceiling 3456 75))
(terpri)
(write (truncate 3456 75))
(terpri)
(write (round 3456 75))
(terpri)
(write (ffloor 3456 75))
(terpri)
(write (fceiling 3456 75))
(terpri)
(write (ftruncate 3456 75))
(terpri)
(write (fround 3456 75))
(terpri)
(write (mod 3456 75))
(terpri)
(setq c (complex 6 7))
(write c)
(terpri)
(write (complex 5 -9))
(terpri)
(write (realpart c))
(terpri)
(write (imagpart c))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

15/26
0
1152/25
46
47
46
46
46.0
47.0
46.0
46.0
6
#C(6 7)
#C(5 -9)
6
7

LISP'de karakterler veri nesneleri olarak temsil edilir. character.

# \ Karakterinden önce gelen bir karakter nesnesini karakterin kendisinden önce gösterebilirsiniz. Örneğin, # \ a, a karakteri anlamına gelir.

Boşluk ve diğer özel karakterler, karakterin adından önce # \ gelecek şekilde gösterilebilir. Örneğin, # \ SPACE, boşluk karakterini temsil eder.

Aşağıdaki örnek bunu göstermektedir -

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write 'a)
(terpri)
(write #\a)
(terpri)
(write-char #\a)
(terpri)
(write-char 'a)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

A
#\a
a
*** - WRITE-CHAR: argument A is not a character

Özel karakterler

Ortak LISP, kodunuzda aşağıdaki özel karakterlerin kullanılmasına izin verir. Yarı standart karakterler olarak adlandırılırlar.

  • #\Backspace
  • #\Tab
  • #\Linefeed
  • #\Page
  • #\Return
  • #\Rubout

Karakter Karşılaştırma İşlevleri

<Ve> gibi sayısal karşılaştırma işlevleri ve operatörler karakterler üzerinde çalışmaz. Common LISP, kodunuzdaki karakterleri karşılaştırmak için başka iki işlev seti sağlar.

Bir küme büyük / küçük harfe duyarlıdır ve diğeri büyük / küçük harfe duyarlı değildir.

Aşağıdaki tablo işlevleri göstermektedir -

Büyük / Küçük Harfe Duyarlı İşlevler Büyük / Küçük Harfe Duyarlı Olmayan İşlevler Açıklama
char = char-eşit İşlenenlerin değerlerinin hepsinin eşit olup olmadığını kontrol eder, evet ise koşul doğru olur.
char / = char-eşit değil İşlenenlerin değerlerinin tümünün farklı olup olmadığını kontrol eder, değerler eşit değilse koşul doğru olur.
karakter < char-lessp İşlenenlerin değerlerinin tekdüze olarak azalıp azalmadığını kontrol eder.
karakter> char-büyükp İşlenenlerin değerlerinin monoton olarak artıp artmadığını kontrol eder.
karakter <= char-not-büyükp Herhangi bir sol işlenenin değerinin bir sonraki sağ işlenenin değerinden büyük veya ona eşit olup olmadığını kontrol eder, evet ise koşul doğru olur.
char> = char-not-lessp Herhangi bir sol işlenenin değerinin sağ işlenenin değerinden küçük veya ona eşit olup olmadığını kontrol eder, evet ise koşul doğru olur.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

; case-sensitive comparison
(write (char= #\a #\b))
(terpri)
(write (char= #\a #\a))
(terpri)
(write (char= #\a #\A))
(terpri)
   
;case-insensitive comparision
(write (char-equal #\a #\A))
(terpri)
(write (char-equal #\a #\b))
(terpri)
(write (char-lessp #\a #\b #\c))
(terpri)
(write (char-greaterp #\a #\b #\c))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

NIL
T
NIL
T
NIL
T
NIL

LISP, tek veya çok boyutlu dizileri kullanarak make-arrayişlevi. Bir dizi, herhangi bir LISP nesnesini kendi elemanları olarak saklayabilir.

Tüm diziler bitişik bellek konumlarından oluşur. En düşük adres ilk öğeye ve en yüksek adres son öğeye karşılık gelir.

Bir dizinin boyutlarının sayısına sıralaması denir.

LISP'de, bir dizi öğesi, negatif olmayan bir tamsayı dizini dizisi tarafından belirtilir. Dizinin uzunluğu, dizinin derecesine eşit olmalıdır. Endeksleme sıfırdan başlar.

Örneğin, dizim adında 10 hücreli bir dizi oluşturmak için şunu yazabiliriz -

(setf my-array (make-array '(10)))

Aref işlevi, hücrelerin içeriğine erişime izin verir. Dizinin adı ve dizin değeri olmak üzere iki bağımsız değişken alır.

Örneğin, onuncu hücrenin içeriğine erişmek için şunu yazıyoruz -

(aref my-array 9)

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (setf my-array (make-array '(10))))
(terpri)
(setf (aref my-array 0) 25)
(setf (aref my-array 1) 23)
(setf (aref my-array 2) 45)
(setf (aref my-array 3) 10)
(setf (aref my-array 4) 20)
(setf (aref my-array 5) 17)
(setf (aref my-array 6) 25)
(setf (aref my-array 7) 19)
(setf (aref my-array 8) 67)
(setf (aref my-array 9) 30)
(write my-array)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)
#(25 23 45 10 20 17 25 19 67 30)

Örnek 2

3'e 3 bir dizi oluşturalım.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setf x (make-array '(3 3) 
   :initial-contents '((0 1 2 ) (3 4 5) (6 7 8)))
)
(write x)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#2A((0 1 2) (3 4 5) (6 7 8))

Örnek 3

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq a (make-array '(4 3)))
(dotimes (i 4)
   (dotimes (j 3)
      (setf (aref a i j) (list i 'x j '= (* i j)))
   )
)
(dotimes (i 4)
   (dotimes (j 3)
      (print (aref a i j))
   )
)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(0 X 0 = 0) 
(0 X 1 = 0) 
(0 X 2 = 0) 
(1 X 0 = 0) 
(1 X 1 = 1) 
(1 X 2 = 2) 
(2 X 0 = 0) 
(2 X 1 = 2) 
(2 X 2 = 4) 
(3 X 0 = 0) 
(3 X 1 = 3) 
(3 X 2 = 6)

Make-array işlevi için tam sözdizimi

Make-array işlevi başka birçok argüman alır. Bu işlevin tam sözdizimine bakalım -

make-array dimensions :element-type :initial-element :initial-contents :adjustable :fill-pointer  :displaced-to :displaced-index-offset

Boyutlar bağımsız değişkeninin dışında , diğer tüm bağımsız değişkenler anahtar sözcüklerdir. Aşağıdaki tablo, argümanların kısa açıklamasını sağlar.

Sr.No. Argüman ve Açıklama
1

dimensions

Dizinin boyutlarını verir. Tek boyutlu dizi için bir sayı ve çok boyutlu dizi için bir listedir.

2

:element-type

Tür belirleyicidir, varsayılan değer T'dir, yani herhangi bir tür

3

:initial-element

İlk elemanların değeri. Tüm elemanların belirli bir değerle başlatıldığı bir dizi oluşturacaktır.

4

:initial-content

Nesne olarak ilk içerik.

5

:adjustable

Temel belleği yeniden boyutlandırılabilen yeniden boyutlandırılabilir (veya ayarlanabilir) bir vektör oluşturmaya yardımcı olur. Argüman, dizinin ayarlanabilir olup olmadığını gösteren bir Boole değeridir, varsayılan değer NIL'dir.

6

:fill-pointer

Yeniden boyutlandırılabilir bir vektörde gerçekte depolanan öğelerin sayısını izler.

7

:displaced-to

İçeriğini belirtilen diziyle paylaşan yer değiştirmiş bir dizi veya paylaşılan dizi oluşturmaya yardımcı olur. Her iki dizi de aynı eleman türüne sahip olmalıdır. : Displaced-to seçeneği: initial-element veya: initial-content seçeneğiyle kullanılamaz. Bu bağımsız değişken varsayılan olarak sıfırdır.

8

:displaced-index-offset

Oluşturulan paylaşılan dizinin indeks ofsetini verir.

Örnek 4

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq myarray (make-array '(3 2 3) 
   :initial-contents 
   '(((a b c) (1 2 3)) 
      ((d e f) (4 5 6)) 
      ((g h i) (7 8 9)) 
   ))
) 
(setq array2 (make-array 4 :displaced-to myarray :displaced-index-offset 2)) 
(write myarray)
(terpri)
(write array2)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#3A(((A B C) (1 2 3)) ((D E F) (4 5 6)) ((G H I) (7 8 9)))
#(C 1 2 3)

Yer değiştiren dizi iki boyutlu ise -

(setq myarray (make-array '(3 2 3) 
   :initial-contents 
   '(((a b c) (1 2 3)) 
      ((d e f) (4 5 6)) 
      ((g h i) (7 8 9)) 
   ))
) 
(setq array2 (make-array '(3 2) :displaced-to myarray :displaced-index-offset 2)) 
(write myarray)
(terpri)
(write array2)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#3A(((A B C) (1 2 3)) ((D E F) (4 5 6)) ((G H I) (7 8 9)))
#2A((C 1) (2 3) (D E))

Yer değiştirmiş indeks ofsetini 5 olarak değiştirelim -

(setq myarray (make-array '(3 2 3) 
   :initial-contents 
   '(((a b c) (1 2 3)) 
      ((d e f) (4 5 6)) 
      ((g h i) (7 8 9)) 
   ))
) 
(setq array2 (make-array '(3 2) :displaced-to myarray :displaced-index-offset 5)) 
(write myarray)
(terpri)
(write array2)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#3A(((A B C) (1 2 3)) ((D E F) (4 5 6)) ((G H I) (7 8 9)))
#2A((3 D) (E F) (4 5))

Örnek 5

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

;a one dimensional array with 5 elements, 
;initail value 5
(write (make-array 5 :initial-element 5))
(terpri)

;two dimensional array, with initial element a
(write (make-array '(2 3) :initial-element 'a))
(terpri)

;an array of capacity 14, but fill pointer 5, is 5
(write(length (make-array 14 :fill-pointer 5)))
(terpri)

;however its length is 14
(write (array-dimensions (make-array 14 :fill-pointer 5)))
(terpri)

; a bit array with all initial elements set to 1
(write(make-array 10 :element-type 'bit :initial-element 1))
(terpri)

; a character array with all initial elements set to a
; is a string actually
(write(make-array 10 :element-type 'character :initial-element #\a)) 
(terpri)

; a two dimensional array with initial values a
(setq myarray (make-array '(2 2) :initial-element 'a :adjustable t))
(write myarray)
(terpri)

;readjusting the array
(adjust-array myarray '(1 3) :initial-element 'b) 
(write myarray)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(5 5 5 5 5)
#2A((A A A) (A A A))
5
(14)
#*1111111111
"aaaaaaaaaa"
#2A((A A) (A A))
#2A((A A B))

Common Lisp'teki dizeler vektörlerdir, yani tek boyutlu karakter dizisidir.

Dize değişmezleri çift tırnak içine alınır. Çift tırnak karakteri (") ve çıkış karakteri (\) dışında, karakter kümesinin desteklediği herhangi bir karakter, bir dizge oluşturmak için çift tırnak içine alınabilir. Ancak, bunları bir ters eğik çizgi (\) ile önleyerek ekleyebilirsiniz.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write-line "Hello World")
(write-line "Welcome to Tutorials Point")

;escaping the double quote character
(write-line "Welcome to \"Tutorials Point\"")

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Hello World
Welcome to Tutorials Point
Welcome to "Tutorials Point"

Dize Karşılaştırma İşlevleri

<Ve> gibi sayısal karşılaştırma işlevleri ve operatörler dizeler üzerinde çalışmaz. Common LISP, kodunuzdaki dizeleri karşılaştırmak için başka iki işlev kümesi sağlar. Bir küme büyük / küçük harfe duyarlıdır ve diğeri büyük / küçük harfe duyarlı değildir.

Aşağıdaki tablo işlevleri göstermektedir -

Büyük / Küçük Harfe Duyarlı İşlevler Büyük / Küçük Harfe Duyarlı Olmayan İşlevler Açıklama
string = dize eşit İşlenenlerin değerlerinin hepsinin eşit olup olmadığını kontrol eder, evet ise koşul doğru olur.
string / = string-not-equal İşlenenlerin değerlerinin tümünün farklı olup olmadığını kontrol eder, değerler eşit değilse koşul doğru olur.
string < telsiz İşlenenlerin değerlerinin tekdüze olarak azalıp azalmadığını kontrol eder.
dize> string-büyükp İşlenenlerin değerlerinin monoton olarak artıp artmadığını kontrol eder.
string <= string-büyük değil Herhangi bir sol işlenenin değerinin bir sonraki sağ işlenenin değerinden büyük veya ona eşit olup olmadığını kontrol eder, evet ise koşul doğru olur.
string> = string-not-lessp Herhangi bir sol işlenenin değerinin sağ işlenenin değerinden küçük veya ona eşit olup olmadığını kontrol eder, evet ise koşul doğru olur.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

; case-sensitive comparison
(write (string= "this is test" "This is test"))
(terpri)
(write (string> "this is test" "This is test"))
(terpri)
(write (string< "this is test" "This is test"))
(terpri)

;case-insensitive comparision
(write (string-equal "this is test" "This is test"))
(terpri)
(write (string-greaterp "this is test" "This is test"))
(terpri)
(write (string-lessp "this is test" "This is test"))
(terpri)

;checking non-equal
(write (string/= "this is test" "this is Test"))
(terpri)
(write (string-not-equal "this is test" "This is test"))
(terpri)
(write (string/= "lisp" "lisping"))
(terpri)
(write (string/= "decent" "decency"))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

NIL
0
NIL
T
NIL
NIL
8
NIL
4
5

Durum Kontrol İşlevleri

Aşağıdaki tablo, durum kontrol işlevlerini açıklamaktadır -

Sr.No. İşlev ve Açıklama
1

string-upcase

Dizeyi büyük harfe dönüştürür

2

string-downcase

Dizeyi küçük harfe dönüştürür

3

string-capitalize

Dizedeki her kelimeyi büyük harf yapar

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write-line (string-upcase "a big hello from tutorials point"))
(write-line (string-capitalize "a big hello from tutorials point"))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

A BIG HELLO FROM TUTORIALS POINT
A Big Hello From Tutorials Point

Dizeleri Kırpma

Aşağıdaki tablo, dizi kırpma işlevlerini açıklamaktadır -

Sr.No. İşlev ve Açıklama
1

string-trim

İlk bağımsız değişken olarak bir karakter dizesi ve ikinci bağımsız değişken olarak bir dize alır ve ilk bağımsız değişkendeki tüm karakterlerin bağımsız değişken dizesinden kaldırıldığı bir alt dize döndürür.

2

String-left-trim

İlk bağımsız değişken olarak bir karakter dizesi ve ikinci bağımsız değişken olarak bir dize alır ve ilk bağımsız değişkendeki tüm karakterlerin bağımsız değişken dizesinin başından kaldırıldığı bir alt dize döndürür.

3

String-right-trim

İlk bağımsız değişken olarak bir dize karakter (ler) i ve ikinci bağımsız değişken olarak bir dize alır ve ilk bağımsız değişkendeki tüm karakterlerin bağımsız değişken dizesinin sonundan kaldırıldığı bir alt dize döndürür.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write-line (string-trim " " "   a big hello from tutorials point   "))
(write-line (string-left-trim " " "   a big hello from tutorials point   "))
(write-line (string-right-trim " " "   a big hello from tutorials point   "))
(write-line (string-trim " a" "   a big hello from tutorials point   "))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

a big hello from tutorials point
a big hello from tutorials point   
   a big hello from tutorials point
big hello from tutorials point

Diğer String Fonksiyonları

LISP'deki dizeler dizilerdir ve dolayısıyla dizilerdir. Bu veri türlerini önümüzdeki eğitimlerde ele alacağız. Diziler ve diziler için geçerli olan tüm işlevler dizeler için de geçerlidir. Bununla birlikte, yaygın olarak kullanılan bazı işlevleri çeşitli örnekler kullanarak göstereceğiz.

Uzunluk Hesaplanıyor

length işlevi bir dizenin uzunluğunu hesaplar.

Alt dizeyi ayıklama

subseq işlev, belirli bir dizinde başlayan ve belirli bir bitiş dizinine veya dizenin sonuna kadar devam eden bir alt dizge (dizge de bir dizi olduğu için) döndürür.

Bir Dizedeki Bir Karaktere Erişim

char işlevi, bir dizenin tek tek karakterlerine erişim sağlar.

Example

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (length "Hello World"))
(terpri)
(write-line (subseq "Hello World" 6))
(write (char "Hello World" 6))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

11
World
#\W

Dizelerin Sıralanması ve Birleştirilmesi

sortişlevi bir dizenin sıralanmasına izin verir. Bir dizi (vektör veya dize) ve iki bağımsız değişkenli bir yüklem alır ve dizinin sıralanmış bir sürümünü döndürür.

merge fonksiyon, iki dizi ve bir yüklem alır ve yüklemeye göre iki dizinin birleştirilmesiyle üretilen bir dizi döndürür.

Example

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

;sorting the strings
(write (sort (vector "Amal" "Akbar" "Anthony") #'string<))
(terpri)

;merging the strings
(write (merge 'vector (vector "Rishi" "Zara" "Priyanka") 
   (vector "Anju" "Anuj" "Avni") #'string<))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#("Akbar" "Amal" "Anthony")
#("Anju" "Anuj" "Avni" "Rishi" "Zara" "Priyanka")

Bir Dizeyi Ters Çevirme

reverse işlev bir dizeyi ters çevirir.

Örneğin, main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write-line (reverse "Are we not drawn onward, we few, drawn onward to new era"))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

are wen ot drawno nward ,wef ew ,drawno nward ton ew erA

Dizeleri Birleştirme

Concatenate işlevi iki dizeyi birleştirir. Bu genel bir dizi işlevidir ve sonuç türünü ilk bağımsız değişken olarak sağlamalısınız.

Örneğin, main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write-line (concatenate 'string "Are we not drawn onward, " "we few, drawn onward to new era"))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Are we not drawn onward, we few, drawn onward to new era

Sıra, LISP'de soyut bir veri türüdür. Vektörler ve listeler, bu veri türünün iki somut alt tipidir. Sıralı veri türünde tanımlanan tüm işlevler aslında tüm vektörlere ve liste türlerine uygulanır.

Bu bölümde, diziler üzerinde en sık kullanılan işlevleri tartışacağız.

Dizileri (yani vektörler ve listeler) değiştirmenin çeşitli yollarına başlamadan önce, mevcut tüm işlevlerin listesine bir göz atalım.

Sıra Oluşturma

Make-sequence işlevi, herhangi bir türden bir dizi oluşturmanıza olanak sağlar. Bu işlevin sözdizimi -

make-sequence sqtype sqsize &key :initial-element

Bu, sqtype türünde ve uzunluk sqsize türünde bir dizi oluşturur .

İsteğe bağlı olarak : initial-element argümanını kullanarak bazı değerler belirtebilirsiniz , ardından her bir element bu değerle başlatılacaktır.

Örneğin, main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (make-sequence '(vector float) 
   10 
   :initial-element 1.0))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)

Dizilerde Genel İşlevler

Sr.No. İşlev ve Açıklama
1

elt

Bir tamsayı indeksi aracılığıyla bireysel öğelere erişim sağlar.

2

length

Bir dizinin uzunluğunu döndürür.

3

subseq

Belirli bir dizinden başlayıp belirli bir bitiş dizinine veya dizinin sonuna kadar devam ederek alt diziyi çıkararak bir alt dizi döndürür.

4

copy-seq

Bağımsız değişkeniyle aynı öğeleri içeren bir dizi döndürür.

5

fill

Bir dizinin birden çok öğesini tek bir değere ayarlamak için kullanılır.

6

replace

İki sekans alır ve ilk argüman sekansı, ikinci argüman sekansından ardışık elemanların ona kopyalanmasıyla yıkıcı bir şekilde değiştirilir.

7

count

Bir öğe ve bir sıra alır ve öğenin dizide görünme sayısını döndürür.

8

reverse

Argümanın aynı öğelerini içeren ancak ters sırada bir dizi döndürür.

9

nreverse

Sırayla aynı öğeleri içeren ancak ters sırayla aynı sırayı döndürür.

10

concatenate

Herhangi bir sayıda dizinin birleştirilmesini içeren yeni bir dizi oluşturur.

11

position

Bir öğeyi ve sırayı alır ve sıradaki veya sıfırdaki öğenin dizinini döndürür.

12

find

Bir öğe ve bir sıra alır. Sıradaki öğeyi bulur ve döndürür, bulunamazsa sıfır döndürür.

13

sort

Bir dizi ve iki bağımsız değişkenli bir yüklem alır ve dizinin sıralanmış bir sürümünü döndürür.

14

merge

İki dizi ve bir yüklem alır ve yüklemeye göre iki dizinin birleştirilmesiyle üretilen bir dizi döndürür.

15

map

Bir n bağımsız değişken işlevini ve n dizi alır ve işlevi dizilerin sonraki öğelerine uygulamanın sonucunu içeren yeni bir dizi döndürür.

16

some

Bir yüklemi bağımsız değişken olarak alır ve bağımsız değişken dizisi üzerinde yineler ve yüklem tarafından döndürülen ilk NIL olmayan değeri döndürür veya yüklem hiçbir zaman karşılanmazsa yanlış döndürür.

17

every

Bir yüklemi bir argüman olarak alır ve argüman dizisi üzerinde yineler, sonlanır, yüklem başarısız olur olmaz yanlış döndürür. Yüklem her zaman tatmin edilirse, doğru döndürür.

18

notany

Bir yüklemi bir argüman olarak alır ve argüman dizisi üzerinde yineler ve yüklem tatmin olur olmaz yanlış veya hiç değilse doğru olur.

19

notevery

Bir yüklemi bir argüman olarak alır ve argüman dizisi üzerinde yineler ve yüklem her zaman karşılanırsa yüklem başarısız olur olmaz doğru veya yanlış döndürür.

20

reduce

Tek bir diziyi eşler, önce dizinin ilk iki öğesine ve ardından işlev tarafından döndürülen değere ve dizinin sonraki öğelerine iki bağımsız değişkenli bir işlev uygular.

21

search

Bazı testleri karşılayan bir veya daha fazla öğeyi bulmak için bir dizi arar.

22

remove

Bir öğeyi ve bir diziyi alır ve kaldırılan öğe örnekleriyle diziyi döndürür.

23

delete

Bu aynı zamanda bir öğeyi ve bir diziyi alır ve öğe dışında aynı öğelere sahip olan argüman dizisi ile aynı türde bir dizi döndürür.

24

substitute

Yeni bir öğeyi, mevcut bir öğeyi ve bir diziyi alır ve yeni öğeyle değiştirilen mevcut öğenin örnekleriyle bir sıra döndürür.

25

nsubstitute

Yeni bir öğeyi, mevcut bir öğeyi ve bir sıralamayı alır ve aynı sırayı, yeni öğeyle değiştirilen mevcut öğenin örnekleriyle döndürür.

26

mismatch

İki sıra alır ve ilk eşleşmeyen öğe çiftinin dizinini döndürür.

Standart Sıra Fonksiyonu Anahtar Kelime Bağımsız Değişkenleri

Argüman Anlam Varsayılan değer
:Ölçek Öğeyi (veya: anahtar işlevi tarafından çıkarılan değeri) öğeyle karşılaştırmak için kullanılan iki bağımsız değişkenli bir işlevdir. EQL
: anahtar Gerçek sıra öğesinden anahtar değerini çıkarmak için tek bağımsız değişkenli işlev. NIL, öğeyi olduğu gibi kullanmak anlamına gelir. NIL
:Başlat Alt dizinin başlangıç ​​dizini (dahil). 0
:son Alt dizinin bitiş endeksi (hariç). NIL, dizinin sonunu belirtir. NIL
: sondan Doğruysa, dizi uçtan başa ters sırayla geçilir. NIL
:Miktar Kaldırılacak veya değiştirilecek öğelerin sayısını gösteren numara veya tümünü belirtmek için NIL (yalnızca KALDIR ve YEDEK). NIL

Diziler üzerinde çalışan bu işlevlerde argüman olarak kullanılan çeşitli işlevleri ve anahtar sözcükleri tartıştık. Sonraki bölümlerde örneklerle bu fonksiyonları nasıl kullanacağımızı göreceğiz.

Uzunluk ve Eleman Bulma

length işlev bir dizinin uzunluğunu döndürür ve elt işlevi, bir tamsayı dizini kullanarak tek tek öğelere erişmenizi sağlar.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq x (vector 'a 'b 'c 'd 'e))
(write (length x))
(terpri)
(write (elt x 3))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

5
D

Dizileri Değiştirme

Bazı dizi işlevleri, dizi boyunca yinelemeye izin verir ve belirli öğeleri açık döngüler yazmadan arama, kaldırma, sayma veya filtreleme gibi bazı işlemleri gerçekleştirir.

Aşağıdaki örnek bunu göstermektedir -

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (count 7 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (remove 5 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (delete 5 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (substitute 10 7 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (find 7 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (position 5 '(1 5 6 7 8 9 2 7 3 4 5)))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

2
(1 6 7 8 9 2 7 3 4)
(1 6 7 8 9 2 7 3 4)
(1 5 6 10 8 9 2 10 3 4 5)
7
1

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (delete-if #'oddp '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (delete-if #'evenp '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (remove-if #'evenp '(1 5 6 7 8 9 2 7 3 4 5) :count 1 :from-end t))
(terpri)
(setq x (vector 'a 'b 'c 'd 'e 'f 'g))
(fill x 'p :start 1 :end 4)
(write x)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(6 8 2 4)
(1 5 7 9 7 3 5)
(1 5 6 7 8 9 2 7 3 5)
#(A P P P E F G)

Dizileri Sıralama ve Birleştirme

Sıralama işlevleri bir dizi ve iki bağımsız değişkenli bir yüklem alır ve dizinin sıralı bir sürümünü döndürür.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (sort '(2 4 7 3 9 1 5 4 6 3 8) #'<))
(terpri)
(write (sort '(2 4 7 3 9 1 5 4 6 3 8) #'>))
(terpri)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(1 2 3 3 4 4 5 6 7 8 9)
(9 8 7 6 5 4 4 3 3 2 1)

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (merge 'vector #(1 3 5) #(2 4 6) #'<))
(terpri)
(write (merge 'list #(1 3 5) #(2 4 6) #'<))
(terpri)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(1 2 3 4 5 6)
(1 2 3 4 5 6)

Sıra Tahminleri

Every, some, notany ve her değil işlevlere dizi yüklemleri denir.

Bu işlevler, diziler üzerinde yinelenir ve Boole koşulunu test eder.

Tüm bu işlevler, ilk bağımsız değişken olarak bir yüklem alır ve geri kalan bağımsız değişkenler dizilerdir.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (every #'evenp #(2 4 6 8 10)))
(terpri)
(write (some #'evenp #(2 4 6 8 10 13 14)))
(terpri)
(write (every #'evenp #(2 4 6 8 10 13 14)))
(terpri)
(write (notany #'evenp #(2 4 6 8 10)))
(terpri)
(write (notevery #'evenp #(2 4 6 8 10 13 14)))
(terpri)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

T
T
NIL
NIL
T

Eşleme Dizileri

Haritalama fonksiyonlarını zaten tartışmıştık. Benzer şekildemap işlevi, bir veya daha fazla dizinin sonraki öğelerine bir işlevi uygulamanıza izin verir.

map işlev, bir n bağımsız değişken işlevini ve n dizi alır ve işlevi dizilerin sonraki öğelerine uyguladıktan sonra yeni bir dizi döndürür.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (map 'vector #'* #(2 3 4 5) #(3 5 4 8)))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(6 15 16 40)

Listeler, geleneksel LISP'deki en önemli ve birincil bileşik veri yapısı olmuştur. Günümüzün Ortak LISP'si vektör, karma tablo, sınıflar veya yapılar gibi diğer veri yapılarını sağlar.

Listeler tek bağlantılı listelerdir. LISP'de listeler, adı verilen basit bir kayıt yapısının zinciri olarak oluşturulur.cons birbirine bağlı.

Eksileri Kayıt Yapısı

Bir cons adı verilen iki bileşeni içeren bir kayıt yapısıdır. car ve cdr.

Eksileri hücreleri veya eksileri, işlev kullanılarak oluşturulan değer çiftleridir. cons.

consfunction iki argüman alır ve iki değeri içeren yeni bir eksiler hücresi döndürür. Bu değerler her tür nesneye referans olabilir.

İkinci değer sıfır değilse veya başka bir eks hücresi değilse, değerler parantez içinde noktalı bir çift olarak yazdırılır.

Bir eksper hücresindeki iki değere car ve cdr. car işlevi, ilk değere erişmek için kullanılır ve cdr işlevi ikinci değere erişmek için kullanılır.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (cons 1 2))
(terpri)
(write (cons 'a 'b))
(terpri)
(write (cons 1 nil))
(terpri)
(write (cons 1 (cons 2 nil)))
(terpri)
(write (cons 1 (cons 2 (cons 3 nil))))
(terpri)
(write (cons 'a (cons 'b (cons 'c nil))))
(terpri)
(write ( car (cons 'a (cons 'b (cons 'c nil)))))
(terpri)
(write ( cdr (cons 'a (cons 'b (cons 'c nil)))))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(1 . 2)
(A . B)
(1)
(1 2)
(1 2 3)
(A B C)
A
(B C)

Yukarıdaki örnek, eksiler yapılarının tek bir bağlantılı liste oluşturmak için nasıl kullanılabileceğini gösterir, örneğin liste (ABC) cdr'leri ile birbirine bağlanmış üç kons hücresinden oluşur .

Şematik olarak şu şekilde ifade edilebilir:

LISP'deki listeler

Eks hücreleri listeleri oluşturmak için kullanılabilir, ancak iç içe geçmiş bir listeden bir liste oluşturmak consişlev çağrıları en iyi çözüm olamaz. list işlevi daha çok LISP'de liste oluşturmak için kullanılır.

List işlevi herhangi bir sayıda argüman alabilir ve bir işlev olduğu için argümanlarını değerlendirir.

first ve restfonksiyonlar, bir listenin ilk öğesini ve geri kalan kısmını verir. Aşağıdaki örnekler kavramları göstermektedir.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (list 1 2))
(terpri)
(write (list 'a 'b))
(terpri)
(write (list 1 nil))
(terpri)
(write (list 1 2 3))
(terpri)
(write (list 'a 'b 'c))
(terpri)
(write (list 3 4 'a (car '(b . c)) (* 4 -2)))
(terpri)
(write (list (list 'a 'b) (list 'c 'd 'e)))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(1 2)
(A B)
(1 NIL)
(1 2 3)
(A B C)
(3 4 A B -8)
((A B) (C D E))

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun my-library (title author rating availability)
   (list :title title :author author :rating rating :availabilty availability)
)

(write (getf (my-library "Hunger Game" "Collins" 9 t) :title))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

"Hunger Game"

İşleyiş İşlevlerini Listele

Aşağıdaki tablo, yaygın olarak kullanılan bazı liste işleme işlevlerini göstermektedir.

Sr.No. İşlev ve Açıklama
1

car

Bir listeyi bağımsız değişken olarak alır ve ilk öğesini döndürür.

2

cdr

Bağımsız değişken olarak bir liste alır ve ilk elemanı olmayan bir liste döndürür

3

cons

Bir öğe ve bir liste olmak üzere iki bağımsız değişken alır ve ilk sırada eklenen öğenin olduğu bir liste döndürür.

4

list

Herhangi bir sayıda bağımsız değişken alır ve listenin üye öğeleri olarak bağımsız değişkenleri içeren bir liste döndürür.

5

append

İki veya daha fazla listeyi birde birleştirir.

6

last

Bir liste alır ve son elemanı içeren bir liste döndürür.

7

member

İlk bağımsız değişken ikinci bağımsız değişkenin üyesiyse, ikincisi bir liste olması gereken iki bağımsız değişken alır ve ardından ilk bağımsız değişkenle başlayan listenin geri kalanını döndürür.

8

reverse

Bir liste alır ve en üstteki elemanların ters sırada olduğu bir listeyi döndürür.

Lütfen tüm sıralama işlevlerinin listelere uygulanabileceğini unutmayın.

Örnek 3

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (car '(a b c d e f)))
(terpri)
(write (cdr '(a b c d e f)))
(terpri)
(write (cons 'a '(b c)))
(terpri)
(write (list 'a '(b c) '(e f)))
(terpri)
(write (append '(b c) '(e f) '(p q) '() '(g)))
(terpri)
(write (last '(a b c d (e f))))
(terpri)
(write (reverse '(a b c d (e f))))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

A
(B C D E F)
(A B C)
(A (B C) (E F))
(B C E F P Q G)
((E F))
((E F) D C B A)

Araba ve cdr İşlevlerinin Birleştirilmesi

car ve cdr işlevler ve bunların kombinasyonları, bir listenin herhangi bir belirli öğesinin / üyesinin çıkarılmasına izin verir.

Ancak, car ve cdr işlevlerinin dizileri, car için a harfi ve cdr için d harfi c ve r harfleri içinde birleştirilerek kısaltılabilir.

Örneğin, işlev çağrılarının sırasını kısaltmak için cadadr yazabiliriz - car cdr car cdr.

Böylece, (cadadr '(a (cd) (efg))) d döndürür

Örnek 4

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (cadadr '(a (c d) (e f g))))
(terpri)
(write (caar (list (list 'a 'b) 'c)))   
(terpri)
(write (cadr (list (list 1 2) (list 3 4))))
(terpri)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

D
A
(3 4)

LISP'de sembol, veri nesnelerini temsil eden bir isimdir ve ilginç bir şekilde aynı zamanda bir veri nesnesidir.

Sembolleri özel kılan şey, property listveya plist.

Emlak Listeleri

LISP, sembollere özellikler atamanıza izin verir. Örneğin, bir 'kişi' nesnemiz olsun. Bu 'kişi' nesnesinin ad, cinsiyet, boy, kilo, adres, meslek vb. Özelliklere sahip olmasını isteriz. Özellik, bir nitelik adı gibidir.

Bir özellik listesi, çift sayıda (muhtemelen sıfır) eleman içeren bir liste olarak uygulanır. Listedeki her öğe çifti bir giriş oluşturur; ilk öğeindicator, ve ikincisi value.

Bir sembol oluşturulduğunda, özellik listesi başlangıçta boştur. Özellikler kullanılarak oluşturulurget içinde setf form.

Örneğin, aşağıdaki ifadeler (sembol) 'kitap' adlı bir nesneye başlık, yazar ve yayıncı özellikleri ve ilgili değerleri atamamıza izin verir.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (setf (get 'books'title) '(Gone with the Wind)))
(terpri)
(write (setf (get 'books 'author) '(Margaret Michel)))
(terpri)
(write (setf (get 'books 'publisher) '(Warner Books)))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(GONE WITH THE WIND)
(MARGARET MICHEL)
(WARNER BOOKS)

Çeşitli özellik listesi işlevleri, özellikler atamanıza ve bir sembolün özelliklerini almanıza, değiştirmenize veya kaldırmanıza olanak tanır.

getişlev, belirli bir gösterge için sembolün özellik listesini döndürür. Aşağıdaki sözdizimine sahiptir -

get symbol indicator &optional default

getfonksiyon, belirtilen gösterge için verilen sembolün özellik listesini arar, bulunursa karşılık gelen değeri döndürür; aksi takdirde varsayılan döndürülür (veya varsayılan bir değer belirtilmezse nil).

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setf (get 'books 'title) '(Gone with the Wind))
(setf (get 'books 'author) '(Margaret Micheal))
(setf (get 'books 'publisher) '(Warner Books))

(write (get 'books 'title))
(terpri)
(write (get 'books 'author))
(terpri)
(write (get 'books 'publisher))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(GONE WITH THE WIND)
(MARGARET MICHEAL)
(WARNER BOOKS)

symbol-plist işlevi, bir sembolün tüm özelliklerini görmenizi sağlar.

Örnek 3

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setf (get 'annie 'age) 43)
(setf (get 'annie 'job) 'accountant)
(setf (get 'annie 'sex) 'female)
(setf (get 'annie 'children) 3)

(terpri)
(write (symbol-plist 'annie))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(CHILDREN 3 SEX FEMALE JOB ACCOUNTANT AGE 43)

remprop işlevi, belirtilen özelliği bir sembolden kaldırır.

Örnek 4

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setf (get 'annie 'age) 43)
(setf (get 'annie 'job) 'accountant)
(setf (get 'annie 'sex) 'female)
(setf (get 'annie 'children) 3)

(terpri)
(write (symbol-plist 'annie))
(remprop 'annie 'age)
(terpri)
(write (symbol-plist 'annie))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(CHILDREN 3 SEX FEMALE JOB ACCOUNTANT AGE 43)
(CHILDREN 3 SEX FEMALE JOB ACCOUNTANT)

Vektörler tek boyutlu dizilerdir, dolayısıyla bir dizi alt tipidir. Vektörler ve listeler topluca diziler olarak adlandırılır. Bu nedenle şimdiye kadar tartıştığımız tüm dizi jenerik fonksiyonlar ve dizi fonksiyonları vektörler üzerinde çalışır.

Vektör Oluşturma

Vektör işlevi, belirli değerlere sahip sabit boyutlu vektörler oluşturmanıza olanak tanır. Herhangi bir sayıda bağımsız değişken alır ve bu bağımsız değişkenleri içeren bir vektör döndürür.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setf v1 (vector 1 2 3 4 5))
(setf v2 #(a b c d e))
(setf v3 (vector 'p 'q 'r 's 't))

(write v1)
(terpri)
(write v2)
(terpri)
(write v3)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(1 2 3 4 5)
#(A B C D E)
#(P Q R S T)

LISP'in vektörler için değişmez gösterim olarak # (...) sözdizimini kullandığını lütfen unutmayın. Bu # (...) sözdizimini kodunuzda değişmez vektörler oluşturmak ve eklemek için kullanabilirsiniz.

Ancak, bunlar gerçek vektörlerdir, bu nedenle onları değiştirmek LISP'de tanımlanmamıştır. Bu nedenle, programlama için her zamanvector işlev veya daha genel işlev make-array değiştirmeyi planladığınız vektörler oluşturmak için.

make-arrayfonksiyon, bir vektör oluşturmanın daha genel bir yoludur. Vektör öğelerine,aref işlevi.

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq a (make-array 5 :initial-element 0))
(setq b (make-array 5 :initial-element 2))

(dotimes (i 5)
   (setf (aref a i) i))
   
(write a)
(terpri)
(write b)
(terpri)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#(0 1 2 3 4)
#(2 2 2 2 2)

İşaretçiyi Doldur

make-array işlevi yeniden boyutlandırılabilir bir vektör oluşturmanıza olanak sağlar.

fill-pointerfonksiyonun argümanı, vektörde gerçekten depolanan elemanların sayısını takip eder. Vektöre bir öğe eklediğinizde doldurulacak bir sonraki konumun dizinidir.

vector-pushişlevi, yeniden boyutlandırılabilir bir vektörün sonuna bir öğe eklemenizi sağlar. Dolgu işaretçisini 1 artırır.

vector-pop işlevi en son itilen öğeyi döndürür ve dolgu işaretçisini 1 azaltır.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq a (make-array 5 :fill-pointer 0))
(write a)

(vector-push 'a a)
(vector-push 'b a)
(vector-push 'c a)

(terpri)
(write a)
(terpri)

(vector-push 'd a)
(vector-push 'e a)

;this will not be entered as the vector limit is 5
(vector-push 'f a)

(write a)
(terpri)

(vector-pop a)
(vector-pop a)
(vector-pop a)

(write a)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#()
#(A B C)
#(A B C D E)
#(A B)

Vektörler sekanslardır, tüm sekans fonksiyonları vektörler için uygulanabilir. Vektör fonksiyonları için lütfen diziler bölümüne bakın.

Common Lisp set veri türü sağlamaz. Bununla birlikte, bir listede ayar işlemlerinin gerçekleştirilmesine izin veren bir dizi işlev sağlar.

Çeşitli kriterlere göre bir listedeki öğeleri ekleyebilir, kaldırabilir ve arayabilirsiniz. Ayrıca birleştirme, kesişim ve farklı ayarlama gibi çeşitli ayar işlemlerini de gerçekleştirebilirsiniz.

LISP'de Setleri Uygulama

Kümeler, benzer listeler genellikle eksiler hücreleri açısından uygulanır. Bununla birlikte, tam da bu nedenle, setler büyüdükçe set işlemleri daha az verimli hale gelir.

adjoinişlevi bir küme oluşturmanıza izin verir. Bir öğeyi ve bir kümeyi temsil eden bir listeyi alır ve öğeyi ve orijinal kümedeki tüm öğeleri içeren kümeyi temsil eden bir liste döndürür.

adjoinfonksiyon önce verilen listedeki öğeyi arar, eğer bulunursa, ardından orijinal listeyi döndürür; aksi halde yeni bir mahkum hücresi yaratır.car öğe olarak ve cdr orijinal listeyi gösterir ve bu yeni listeyi döndürür.

adjoin işlevi de alır :key ve :testanahtar kelime argümanları. Bu argümanlar, öğenin orijinal listede olup olmadığını kontrol etmek için kullanılır.

Adjoin işlevi orijinal listeyi değiştirmediğinden, listenin kendisinde bir değişiklik yapmak için ya adjoin tarafından döndürülen değeri orijinal listeye atamalısınız ya da makroyu kullanabilirsiniz. pushnew Sete bir öğe eklemek için.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

; creating myset as an empty list
(defparameter *myset* ())
(adjoin 1 *myset*)
(adjoin 2 *myset*)

; adjoin did not change the original set
;so it remains same
(write *myset*)
(terpri)
(setf *myset* (adjoin 1 *myset*))
(setf *myset* (adjoin 2 *myset*))

;now the original set is changed
(write *myset*)
(terpri)

;adding an existing value
(pushnew 2 *myset*)

;no duplicate allowed
(write *myset*)
(terpri)

;pushing a new value
(pushnew 3 *myset*)
(write *myset*)
(terpri)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

NIL
(2 1)
(2 1)
(3 2 1)

Üyelik Kontrol Ediliyor

Üye işlev grubu, bir elemanın bir kümenin üyesi olup olmadığını kontrol etmenize olanak sağlar.

Aşağıdakiler, bu işlevlerin sözdizimleridir -

member item list &key :test :test-not :key 
member-if predicate list &key :key 
member-if-not predicate list &key :key

Bu işlevler, testi karşılayan belirli bir öğe için verilen listede arama yapar. Böyle bir öğe bulunmazsa, işlevler dönernil. Aksi takdirde, ilk eleman olarak eleman içeren listenin kuyruğu döndürülür.

Arama yalnızca en üst düzeyde yapılır.

Bu işlevler yüklemler olarak kullanılabilir.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(write (member 'zara '(ayan abdul zara riyan nuha)))
(terpri)
(write (member-if #'evenp '(3 7 2 5/3 'a)))
(terpri)
(write (member-if-not #'numberp '(3 7 2 5/3 'a 'b 'c)))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(ZARA RIYAN NUHA)
(2 5/3 'A)
('A 'B 'C)

Birlik Ayarla

İşlevlerin birleşim grubu, bir test temelinde bu işlevlere bağımsız değişken olarak sağlanan iki listede küme birleşimi gerçekleştirmenize olanak tanır.

Aşağıdakiler, bu işlevlerin sözdizimleridir -

union list1 list2 &key :test :test-not :key 
nunion list1 list2 &key :test :test-not :key

unionişlevi iki liste alır ve listelerden herhangi birinde bulunan tüm öğeleri içeren yeni bir liste döndürür. Çoğaltmalar varsa, iade listesinde üyenin sadece bir kopyası tutulur.

nunion işlevi aynı işlemi gerçekleştirir ancak bağımsız değişken listelerini yok edebilir.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq set1 (union '(a b c) '(c d e)))
(setq set2 (union '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)
)
       
(setq set3 (union '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)))
)
(write set1)
(terpri)
(write set2)
(terpri)
(write set3)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(A B C D E)
(#(F H) #(5 6 7) #(A B) #(G H))
(#(A B) #(5 6 7) #(F H) #(5 6 7) #(A B) #(G H))

Lütfen aklınızda bulundurun

Birleştirme işlevi beklendiği gibi çalışmaz :test-not #'mismatchüç vektörün listesi için argümanlar. Bunun nedeni, listelerin eksiler hücrelerinden oluşması ve görünüşe göre değerler bize aynı görünse de,cdrHücrelerin bir kısmı eşleşmiyor, bu yüzden LISP yorumlayıcısı / derleyicisi ile tam olarak aynı değiller. Sebep bu; Listeler kullanılarak büyük kümelerin uygulanması tavsiye edilmez. Yine de küçük setler için iyi çalışıyor.

Kesişimi Ayarla

İşlevlerin kesişim grubu, bir test temelinde bu işlevlere bağımsız değişken olarak sağlanan iki listede kesişim gerçekleştirmenize olanak tanır.

Aşağıdakiler, bu işlevlerin sözdizimleridir -

intersection list1 list2 &key :test :test-not :key 
nintersection list1 list2 &key :test :test-not :key

Bu işlevler iki liste alır ve her iki bağımsız değişken listesinde bulunan tüm öğeleri içeren yeni bir liste döndürür. Her iki listede de yinelenen girişler varsa, gereksiz girişler sonuçta görünebilir veya görünmeyebilir.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq set1 (intersection '(a b c) '(c d e)))
(setq set2 (intersection '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)
)
       
(setq set3 (intersection '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)))
)
(write set1)
(terpri)
(write set2)
(terpri)
(write set3)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(C)
(#(A B) #(5 6 7))
NIL

Kesişme işlevi, kesişimin yıkıcı versiyonudur, yani orijinal listeleri yok edebilir.

Farkı Ayarla

Küme farkı işlev grubu, bir test temelinde bu işlevlere bağımsız değişken olarak sağlanan iki listede küme farkı gerçekleştirmenize olanak tanır.

Aşağıdakiler, bu işlevlerin sözdizimleridir -

set-difference list1 list2 &key :test :test-not :key 
nset-difference list1 list2 &key :test :test-not :key

Set-fark işlevi, ilk listenin ikinci listede görünmeyen öğelerinin bir listesini döndürür.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq set1 (set-difference '(a b c) '(c d e)))
(setq set2 (set-difference '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)) :test-not #'mismatch)
)
(setq set3 (set-difference '(#(a b) #(5 6 7) #(f h)) 
   '(#(5 6 7) #(a b) #(g h)))
)
(write set1)
(terpri)
(write set2)
(terpri)
(write set3)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(A B)
(#(F H))
(#(A B) #(5 6 7) #(F H))

Ağaç veri yapılarını, liste listeleri olarak eksiler hücrelerinden oluşturabilirsiniz.

Ağaç yapılarını uygulamak için, ikili ağaçlar için ön sipariş, sıra ve son sipariş gibi belirli bir sırayla eksiler hücrelerinden geçecek işlevler tasarlamanız gerekecektir.

Liste Listesi Olarak Ağaç

Aşağıdaki liste listesini oluşturan eksiler hücresinden oluşan bir ağaç yapısını düşünelim:

((1 2) (3 4) (5 6)).

Şematik olarak şu şekilde ifade edilebilir:

LISP'de Ağaç İşlevleri

Çoğunlukla kendi özel ihtiyaçlarınıza göre kendi ağaç işlevlerinizi yazmanız gerekecek olsa da, LISP kullanabileceğiniz bazı ağaç işlevleri sağlar.

Tüm liste işlevlerinin yanı sıra, aşağıdaki işlevler özellikle ağaç yapılarında çalışır -

Sr.No. İşlev ve Açıklama
1

copy-tree x ve isteğe bağlı vecp

Eksi hücresi ağacının bir kopyasını döndürür x. Hem araba hem de cdr yönlerini özyinelemeli olarak kopyalar. X bir eksiler hücresi değilse, işlev yalnızca x'i değişmemiş olarak döndürür. İsteğe bağlı vecp argümanı doğruysa, bu işlev vektörleri (özyinelemeli olarak) ve eksi hücreleri kopyalar.

2

tree-equal xy & key: test: test-not: anahtar

İki hücre hücresini karşılaştırır. X ve y her ikisi de eks hücreleriyse, arabaları ve cdr'leri özyinelemeli olarak karşılaştırılır. Ne x ne de y bir eksper hücresi değilse, eql ile veya belirtilen teste göre karşılaştırılırlar. : Key işlevi, belirtilirse, her iki ağacın öğelerine de uygulanır.

3

subst yeni eski ağaç ve anahtar: test: test-not: anahtar

Bu verilen eski öğenin oluşumlarını yerine yeni öğenin, ağacın eksileri hücrelerin bir ağaç.

4

nsubst yeni eski ağaç ve anahtar: test: test-not: anahtar

Subst ile aynı şekilde çalışır, ancak orijinal ağacı yok eder.

5

sublis alist ağacı ve anahtar: test: test-not: anahtar

O bir dernek liste alır dışında subst gibi çalışır alist eski yeni çiftlerinin. Ağacın her bir öğesi (varsa: anahtar işlevini uyguladıktan sonra) alist arabaları ile karşılaştırılır; eşleşirse, karşılık gelen cdr ile değiştirilir.

6

nsublis alist ağacı ve anahtar: test: test-not: anahtar

Sublis ile aynı şekilde çalışır, ancak yıkıcı bir versiyondur.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq lst (list '(1 2) '(3 4) '(5 6)))
(setq mylst (copy-list lst))
(setq tr (copy-tree lst))

(write lst)
(terpri)
(write mylst)
(terpri)
(write tr)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

((1 2) (3 4) (5 6))
((1 2) (3 4) (5 6))
((1 2) (3 4) (5 6))

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq tr '((1 2 (3 4 5) ((7 8) (7 8 9)))))
(write tr)
(setq trs (subst 7 1 tr))
(terpri)
(write trs)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

((1 2 (3 4 5) ((7 8) (7 8 9))))
((7 2 (3 4 5) ((7 8) (7 8 9))))

Kendi Ağacınızı Oluşturmak

LISP'de bulunan liste işlevlerini kullanarak kendi ağacımızı oluşturmaya çalışalım.

Önce bazı verileri içeren yeni bir düğüm oluşturalım

(defun make-tree (item)
   "it creates a new node with item."
   (cons (cons item nil) nil)
)

Sonra ağaca bir çocuk düğüm ekleyelim - bu iki ağaç düğümü alacak ve ikinci ağacı ilkinin çocuğu olarak ekleyecektir.

(defun add-child (tree child)
   (setf (car tree) (append (car tree) child))
   tree)

Bu işlev, belirli bir ağacın ilk çocuğunu döndürür - bir ağaç düğümünü alır ve bu düğümün herhangi bir alt düğümü yoksa, o düğümün ilk çocuğunu veya nil'i döndürür.

(defun first-child (tree)
   (if (null tree)
      nil
      (cdr (car tree))
   )
)

Bu işlev, belirli bir düğümün sonraki kardeşini döndürecektir - argüman olarak bir ağaç düğümünü alır ve düğümün hiç yoksa sonraki kardeş düğüme veya nil'e bir başvuru döndürür.

(defun next-sibling (tree)
   (cdr tree)
)

Son olarak, bilgiyi bir düğümde döndürmek için bir işleve ihtiyacımız var -

(defun data (tree)
   (car (car tree))
)

Misal

Bu örnek, yukarıdaki işlevleri kullanır -

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun make-tree (item)
   "it creates a new node with item."
   (cons (cons item nil) nil)
)
(defun first-child (tree)
   (if (null tree)
      nil
      (cdr (car tree))
   )
)

(defun next-sibling (tree)
   (cdr tree)
)
(defun data (tree)
   (car (car tree))
)
(defun add-child (tree child)
   (setf (car tree) (append (car tree) child))
   tree
)

(setq tr '((1 2 (3 4 5) ((7 8) (7 8 9)))))
(setq mytree (make-tree 10))

(write (data mytree))
(terpri)
(write (first-child tr))
(terpri)
(setq newtree (add-child tr mytree))
(terpri)
(write newtree)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

10
(2 (3 4 5) ((7 8) (7 8 9)))

((1 2 (3 4 5) ((7 8) (7 8 9)) (10)))

Karma tablo veri yapısı, aşağıdakilerin bir koleksiyonunu temsil eder: key-and-valueanahtarın karma koduna göre düzenlenen çiftler. Koleksiyondaki öğelere erişmek için anahtarı kullanır.

Bir anahtar kullanarak öğelere erişmeniz gerektiğinde bir karma tablo kullanılır ve kullanışlı bir anahtar değeri tanımlayabilirsiniz. Karma tablosundaki her öğenin bir anahtar / değer çifti vardır. Anahtar, koleksiyondaki öğelere erişmek için kullanılır.

LISP'de Hash Tablosu Oluşturma

Ortak LISP'de, karma tablo genel amaçlı bir koleksiyondur. Keyfi nesneleri anahtar veya dizin olarak kullanabilirsiniz.

Bir hash tablosunda bir değer depoladığınızda, bir anahtar / değer çifti oluşturur ve bu anahtarın altında depolarsınız. Daha sonra aynı anahtarı kullanarak değeri hash tablosundan alabilirsiniz. Bir anahtarda yeni bir değer saklayabilmenize rağmen, her anahtar tek bir değerle eşleşir.

LISP'deki karma tablolar, anahtarların karşılaştırılma şekline bağlı olarak üç tipe ayrılabilir - eq, eql veya eşit. Karma tablosu LISP nesnelerinde karma hale getirilirse, anahtarlar eq veya eql ile karşılaştırılır. Ağaç yapısında hash tablo hash'i varsa, eşit kullanılarak karşılaştırılır.

make-hash-tableişlevi, bir karma tablo oluşturmak için kullanılır. Bu işlevin sözdizimi -

make-hash-table &key :test :size :rehash-size :rehash-threshold

Nerede -

  • key argüman anahtarı sağlar.

  • :testbağımsız değişken anahtarların nasıl karşılaştırılacağını belirler - üç değerden birine sahip olmalıdır: # 'eq, #' eql veya # 'eşit veya üç sembolden biri eq, eql veya equ. Belirtilmezse, eql varsayılır.

  • :sizeargüman, karma tablonun başlangıç ​​boyutunu ayarlar. Bu, sıfırdan büyük bir tam sayı olmalıdır.

  • :rehash-sizebağımsız değişken, karma tablo dolduğunda boyutunun ne kadar artırılacağını belirtir. Bu, eklenecek girişlerin sayısı olan sıfırdan büyük bir tamsayı olabilir veya yeni boyutun eski boyuta oranı olan 1'den büyük bir kayan nokta sayısı olabilir. Bu bağımsız değişken için varsayılan değer uygulamaya bağlıdır.

  • :rehash-thresholdargüman, karma tablonun büyümeden önce ne kadar dolu olabileceğini belirtir. Bu, sıfırdan büyük ve şundan küçük bir tamsayı olabilir: rehash-size (bu durumda, tablo her büyütüldüğünde ölçeklenir) veya sıfır ile 1 arasında bir kayan nokta sayısı olabilir. Bunun için varsayılan değer argüman uygulamaya bağlıdır.

Ayrıca, hash-table işlevini bağımsız değişken olmadan da çağırabilirsiniz.

Öğeleri Karma Tablosundan Alma ve Karma Tablosuna Ekleme

gethashişlevi, anahtarını arayarak karma tablodan bir öğeyi alır. Anahtarı bulamazsa sıfır döndürür.

Aşağıdaki sözdizimine sahiptir -

gethash key hash-table &optional default

nerede -

  • anahtar: ilişkili anahtardır

  • hash-table: aranacak karma tablodur

  • default: Girdi bulunamazsa döndürülecek değerdir, belirtilmezse sıfırdır.

gethash işlev aslında iki değer döndürür; ikincisi, bir girdi bulunursa doğru olan ve hiçbir girdi bulunmadıysa yanlış olan bir yüklem değeridir.

Karma tablosuna bir öğe eklemek için, setf ile birlikte işlev gethash işlevi.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq empList (make-hash-table)) 
(setf (gethash '001 empList) '(Charlie Brown))
(setf (gethash '002 empList) '(Freddie Seal)) 
(write (gethash '001 empList)) 
(terpri)
(write (gethash '002 empList))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(CHARLIE BROWN)
(FREDDIE SEAL)

Bir Girişin Kaldırılması

remhashişlevi, karma tablodaki belirli bir anahtar için herhangi bir girişi kaldırır. Bu, bir giriş varsa doğru, yoksa yanlış olan bir yüklemdir.

Bu işlevin sözdizimi -

remhash key hash-table

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq empList (make-hash-table)) 
(setf (gethash '001 empList) '(Charlie Brown))
(setf (gethash '002 empList) '(Freddie Seal)) 
(setf (gethash '003 empList) '(Mark Mongoose)) 

(write (gethash '001 empList)) 
(terpri)
(write (gethash '002 empList)) 
(terpri)
(write (gethash '003 empList))  
(remhash '003 empList)
(terpri)
(write (gethash '003 empList))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

(CHARLIE BROWN)
(FREDDIE SEAL)
(MARK MONGOOSE)
NIL

Maphash Fonksiyonu

maphash işlevi, bir karma tablosundaki her bir anahtar / değer çiftine belirli bir işlevi uygulamanıza olanak tanır.

İki argüman alır - fonksiyon ve bir hash tablosu ve hash tablosundaki her anahtar / değer çifti için fonksiyonu bir kez çağırır.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(setq empList (make-hash-table)) 
(setf (gethash '001 empList) '(Charlie Brown))
(setf (gethash '002 empList) '(Freddie Seal)) 
(setf (gethash '003 empList) '(Mark Mongoose)) 

(maphash #'(lambda (k v) (format t "~a => ~a~%" k v)) empList)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

3 => (MARK MONGOOSE)
2 => (FREDDIE SEAL)
1 => (CHARLIE BROWN)

Ortak LISP, çok sayıda giriş-çıkış işlevi sağlar. Biçim işlevini ve çıktı için yazdırma işlevini zaten kullandık. Bu bölümde, LISP'de sağlanan en sık kullanılan giriş-çıkış işlevlerinden bazılarına bakacağız.

Giriş Fonksiyonları

Aşağıdaki tablo, LISP'nin en sık kullanılan giriş işlevlerini göstermektedir -

Sr.No. İşlev ve Açıklama
1

read& isteğe bağlı girdi akışı eof-error-p eof-value recursive-p

Giriş akışından bir Lisp nesnesinin basılı temsilini okur, karşılık gelen bir Lisp nesnesi oluşturur ve nesneyi döndürür.

2

read-preserving-whitespace& isteğe bağlı yayın içi eof-error-p eof-value recursive-p

Genişletilmiş belirteci tam olarak hangi karakterin sonlandırdığını belirlemenin istendiği bazı özel durumlarda kullanılır.

3

read-line& isteğe bağlı girdi akışı eof-error-p eof-value recursive-p

Bir satırsonu ile biten bir metin satırında okur.

4

read-char& isteğe bağlı girdi akışı eof-error-p eof-value recursive-p

Girdi akımından bir karakter alır ve onu bir karakter nesnesi olarak döndürür.

5

unread-char karakter ve isteğe bağlı giriş akışı

Giriş akışından en son okunan karakteri giriş akışının önüne koyar.

6

peek-char& isteğe bağlı gözetleme tipi girdi akışı eof-error-p eof-value recursive-p

Girdi akışından okunacak bir sonraki karakteri girdi akışından çıkarmadan döndürür.

7

listenve isteğe bağlı giriş akışı

Yüklem listen giriş akışından hemen elde edilebilen bir karakter varsa doğrudur, yoksa yanlıştır.

8

read-char-no-hang& isteğe bağlı girdi akışı eof-error-p eof-value recursive-p

Benzer read-char, ancak bir karakter almazsa, bir karakteri beklemez, hemen sıfır döndürür.

9

clear-inputve isteğe bağlı giriş akışı

Giriş akışıyla ilişkili tüm tamponlu girdileri temizler .

10

read-from-string dize ve isteğe bağlı eof-error-p eof-değeri & anahtar: başlangıç: bitiş: beyaz-boşluğu koru

Dizinin karakterlerini art arda alır ve bir LISP nesnesi oluşturur ve nesneyi döndürür. Ayrıca, duruma göre dizedeki okunmayan ilk karakterin dizinini veya dizenin uzunluğunu (veya uzunluk +1) döndürür.

11

parse-integer string & key: start: end: radix: gereksiz yere izin verilir

Start ve: end ile ayrılmış dizenin alt dizesini inceler (dizenin varsayılan başlangıcı ve sonu). Boşluk karakterlerini atlar ve ardından bir tamsayıyı ayrıştırmaya çalışır.

12

read-byte ikili giriş akışı ve isteğe bağlı eof-error-p eof-değeri

İkili giriş akışından bir bayt okur ve onu bir tamsayı biçiminde döndürür.

Klavyeden Giriş Okuma

readişlevi klavyeden giriş almak için kullanılır. Herhangi bir tartışma gerektirmeyebilir.

Örneğin, kod parçacığını düşünün -

(write ( + 15.0 (read)))

Kullanıcının STDIN Girişinden 10.2 girdiğini varsayalım,

25.2

Okuma işlevi, bir giriş akışındaki karakterleri okur ve bunları Lisp nesnelerinin temsilleri olarak ayrıştırarak yorumlar.

Misal

Main.lisp adlı yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın -

; the function AreaOfCircle
; calculates area of a circle
; when the radius is input from keyboard

(defun AreaOfCircle()
(terpri)
(princ "Enter Radius: ")
(setq radius (read))
(setq area (* 3.1416 radius radius))
(princ "Area: ")
(write area))
(AreaOfCircle)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Enter Radius: 5 (STDIN Input)
Area: 78.53999

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(with-input-from-string (stream "Welcome to Tutorials Point!")
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (peek-char nil stream nil 'the-end))
   (values)
)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#\W 
#\e 
#\l 
#\c 
#\o 
#\m 
#\e 
#\Space 
#\t 
#\o 
#\Space

Çıktı Fonksiyonları

LISP'deki tüm çıktı işlevleri , çıktının gönderildiği çıktı akışı adı verilen isteğe bağlı bir bağımsız değişken alır . Belirtilmediyse veya sıfırsa, çıktı akışı varsayılan olarak * standart çıktı * değişkeninin değerine ayarlanır.

Aşağıdaki tablo, LISP'nin en sık kullanılan çıktı işlevlerini göstermektedir -

Sr.No. İşlev ve Açıklama
1

write nesne ve anahtar: akım: kaçış: radix: taban: daire: güzel: seviye: uzunluk: durum: gensym: dizi

write nesne ve anahtar: akım: kaçış: radix: taban: daire: güzel: seviye: uzunluk: durum: gensym: dizi: okunabilir: sağ kenar boşluğu: miser-genişlik: satırlar: pprint-dispatch

Her ikisi de nesneyi: stream tarafından belirtilen çıkış akışına yazar, bu da varsayılan olarak * standard-output * değerine ayarlanır. Diğer değerler varsayılan olarak yazdırma için karşılık gelen global değişkenlere ayarlanır.

2

prin1 nesne ve isteğe bağlı çıktı akışı

print nesne ve isteğe bağlı çıktı akışı

pprint nesne ve isteğe bağlı çıktı akışı

princ nesne ve isteğe bağlı çıktı akışı

Tüm bu işlevler, nesnenin basılı temsilini çıktı akışına çıkarır . Ancak, aşağıdaki farklılıklar var -

  • prin1, nesneyi değeri olarak döndürür.

  • print, nesneyi önceki satırsonu ve ardından bir boşlukla yazdırır. Nesneyi döndürür.

  • pprint, sondaki boşluğun çıkarılması dışında tıpkı print gibidir.

  • Princ, çıktının kaçış karakteri olmaması dışında aynı prin1 gibidir

3

write-to-string nesne ve anahtar : kaçış: radix: taban: daire: güzel: seviye: uzunluk: durum: gensym: dizi

write-to-string nesne ve anahtar: kaçış: radix: taban: daire: güzel: seviye: uzunluk: durum: gensym: dizi: okunabilir: sağ kenar boşluğu: miser-genişlik: satırlar: pprint-dispatch

prin1-to-string nesne

princ-to-string nesne

Nesne etkin bir şekilde yazdırılır ve çıktı karakterleri döndürülen bir dizge haline getirilir.

4

write-char karakter ve isteğe bağlı çıktı akışı

Çıktı akışına karakteri çıkarır ve karakteri döndürür.

5

write-string dize ve isteğe bağlı çıkış akışı & anahtar: başlangıç: bitiş

Bu bir Belirtilen altdizgenin karakterleri yazar dize kadar çıktı-stream.

6

write-line dize ve isteğe bağlı çıkış akışı & anahtar: başlangıç: bitiş

Yazma dizesi ile aynı şekilde çalışır, ancak daha sonra yeni bir satır çıkarır.

7

terprive isteğe bağlı çıktı akışı

Çıkış akışına yeni bir satır çıkarır .

8

fresh-lineve isteğe bağlı çıktı akışı

yalnızca akım bir satırın başlangıcında değilse bir satırsonu çıkarır.

9

finish-outputve isteğe bağlı çıktı akışı

force-outputve isteğe bağlı çıktı akışı

clear-outputve isteğe bağlı çıktı akışı

  • İşlev finish-output çıktı akışına gönderilen tüm çıktının hedefine ulaştığından emin olmaya çalışır ve ancak o zaman nil döndürür.

  • İşlev force-output herhangi bir dahili tamponun boşaltılmasını başlatır, ancak tamamlanmasını veya onaylanmasını beklemeden sıfır döndürür.

  • İşlev clear-output hedefe devam etmek için mümkün olduğunca az çıktıya izin vermek için devam etmekte olan herhangi bir bekleyen çıktı işlemini iptal etmeye çalışır.

10

write-byte tamsayı ikili çıkış akışı

Tamsayının değerini bir bayt yazar .

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

; this program inputs a numbers and doubles it
(defun DoubleNumber()
   (terpri)
   (princ "Enter Number : ")
   (setq n1 (read))
   (setq doubled (* 2.0 n1))
   (princ "The Number: ")
   (write n1)
   (terpri)
   (princ "The Number Doubled: ")
   (write doubled)
)
(DoubleNumber)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Enter Number : 3456.78 (STDIN Input)
The Number: 3456.78
The Number Doubled: 6913.56

Biçimlendirilmiş Çıktı

İşlev formatgüzel biçimlendirilmiş metin üretmek için kullanılır. Aşağıdaki sözdizimine sahiptir -

format destination control-string &rest arguments

nerede,

  • hedef standart çıktıdır
  • control-string, çıktısı alınacak karakterleri ve baskı direktifini tutar.

Bir format directive yaklaşık işareti (~), virgülle ayrılmış isteğe bağlı önek parametreleri, isteğe bağlı iki nokta (:) ve at-işareti (@) değiştiricileri ve bunun ne tür bir yönerge olduğunu gösteren tek bir karakterden oluşur.

Önek parametreleri genellikle tamsayılardır ve isteğe bağlı olarak işaretli ondalık sayılar olarak belirtilir.

Aşağıdaki tablo, yaygın olarak kullanılan direktiflerin kısa açıklamasını sağlar -

Sr.No. Yönerge ve Açıklama
1

~A

Ardından ASCII bağımsız değişkenleri gelir.

2

~S

Ardından S-ifadeleri gelir.

3

~D

Ondalık argümanlar için.

4

~B

İkili argümanlar için.

5

~O

Sekizlik argümanlar için.

6

~X

Onaltılık argümanlar için.

7

~C

Karakter argümanları için.

8

~F

Sabit biçimli kayan noktalı argümanlar için.

9

~E

Üstel kayan nokta argümanları.

10

~$

Dolar ve kayan nokta argümanları.

11

~%

Yeni bir satır yazdırılır.

12

~*

Sonraki argüman yok sayılır.

13

~?

Dolaylı. Sonraki bağımsız değişken bir dizge ve ondan sonraki bağımsız değişken bir liste olmalıdır.

Misal

Bir çemberin alanını hesaplayan programı yeniden yazalım -

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun AreaOfCircle()
   (terpri)
   (princ "Enter Radius: ")
   (setq radius (read))
   (setq area (* 3.1416 radius radius))
   (format t "Radius: = ~F~% Area = ~F" radius area)
)
(AreaOfCircle)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Enter Radius: 10.234 (STDIN Input)
Radius: = 10.234
Area = 329.03473

Standart girdi ve çıkışın ortak LISP tarafından nasıl ele alındığını tartıştık. Tüm bu işlevler, metin ve ikili dosyalardan okumak ve bunlara yazmak için de çalışır. Bu durumda tek fark, kullandığımız akışın standart girdi veya çıktı değil, dosyalara yazmak veya dosyalardan okumak için özel bir amaç için oluşturulmuş bir akış olmasıdır.

Bu bölümde, LISP'in veri depolamak için metin veya ikili dosyaları nasıl oluşturabileceğini, açabileceğini, kapatabileceğini göreceğiz.

Bir dosya, bir metin dosyası veya ikili dosya olması fark etmez, bir bayt dizisini temsil eder. Bu bölüm sizi dosya yönetimi için önemli işlevler / makrolar konusunda yönlendirecektir.

Dosyaları Açma

Kullanabilirsiniz openyeni bir dosya oluşturma veya mevcut bir dosyayı açma işlevi. Bir dosyayı açmak için en temel işlevdir. Ancakwith-open-file bu bölümde daha sonra göreceğimiz gibi genellikle daha kullanışlıdır ve daha yaygın olarak kullanılır.

Bir dosya açıldığında, onu LISP ortamında temsil edecek bir akış nesnesi oluşturulur. Akış üzerindeki tüm işlemler, temelde dosyadaki işlemlere eşdeğerdir.

İçin sözdizimi open işlev -

open filename &key :direction :element-type :if-exists :if-does-not-exist :external-format

nerede,

  • Dosya adı argümanı dosyanın adı açılmış veya oluşturulan gerekmektedir.

  • Anahtar kelime argümanlar akışı ve hata işleme yolları türünü belirtin.

  • :direction anahtar kelime, akışın girişi mi, çıkışı mı yoksa her ikisini birden mi işleyeceğini belirtir, aşağıdaki değerleri alır -

    • : girdi - giriş akışları için (varsayılan değer)

    • : output - çıktı akışları için

    • : io - çift yönlü akışlar için

    • : probe - sadece bir dosyanın varlığını kontrol etmek için; akış açılır ve sonra kapatılır.

  • :element-type akış için işlem biriminin türünü belirtir.

  • :if-existsargüman: direction: output veya: io ise ve belirtilen adda bir dosya zaten mevcutsa gerçekleştirilecek eylemi belirtir. Yön: input veya: prob ise, bu argüman yok sayılır. Aşağıdaki değerleri alır -

    • : hata - bir hata bildirir.

    • : yeni-sürüm - aynı ada ancak daha büyük sürüm numarasına sahip yeni bir dosya oluşturur.

    • : rename - mevcut dosyayı yeniden adlandırır.

    • : yeniden adlandır ve sil - mevcut dosyayı yeniden adlandırır ve ardından siler.

    • : append - mevcut dosyaya eklenir.

    • : yerini alır - mevcut dosyanın yerini alır.

    • nil - bir dosya oluşturmaz veya bir akım bile başarısızlığı belirtmek için sıfır döndürür.

  • :if-does-not-existargüman, belirtilen adda bir dosya halihazırda mevcut değilse yapılacak eylemi belirtir. Aşağıdaki değerleri alır -

    • : hata - bir hata bildirir.

    • : oluştur - belirtilen adla boş bir dosya oluşturur ve onu kullanır.

    • nil - bir dosya veya hatta bir akış oluşturmaz, bunun yerine başarısızlığı belirtmek için nil döndürür.

  • :external-format argüman, dosyalardaki karakterleri temsil etmek için uygulama tarafından tanınan bir şema belirtir.

Örneğin, / tmp klasöründe saklanan dosyam.txt adlı bir dosyayı şu şekilde açabilirsiniz:

(open "/tmp/myfile.txt")

Dosyalara Yazma ve Dosyalardan Okuma

with-open-fileokuma / yazma işlemiyle ilişkili akım değişkenini kullanarak bir dosyaya okumaya veya yazmaya izin verir. İş bittiğinde, dosyayı otomatik olarak kapatır. Kullanımı son derece uygundur.

Aşağıdaki sözdizimine sahiptir -

with-open-file (stream filename {options}*)
   {declaration}* {form}*
  • dosya adı, açılacak dosyanın adıdır; bir dize, yol adı veya akış olabilir.

  • Seçenekleri fonksiyonu açıkken için anahtar kelime argümanları ile aynıdır.

örnek 1

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(with-open-file (stream "/tmp/myfile.txt" :direction :output)
   (format stream "Welcome to Tutorials Point!")
   (terpri stream)
   (format stream "This is a tutorials database")
   (terpri stream)
   (format stream "Submit your Tutorials, White Papers and Articles into our Tutorials   Directory.")
)

Lütfen önceki bölümde tartışılan terpri ve format gibi tüm girdi-çıktı işlevlerinin burada oluşturduğumuz dosyaya yazmak için çalıştığını unutmayın.

Kodu çalıştırdığınızda hiçbir şey döndürmez; ancak verilerimiz dosyaya yazılır. :direction :output anahtar kelimeler bunu yapmamıza izin verir.

Ancak, bu dosyadan şunu kullanarak okuyabiliriz read-line işlevi.

Örnek 2

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(let ((in (open "/tmp/myfile.txt" :if-does-not-exist nil)))
   (when in
      (loop for line = (read-line in nil)
      
      while line do (format t "~a~%" line))
      (close in)
   )
)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Welcome to Tutorials Point!
This is a tutorials database
Submit your Tutorials, White Papers and Articles into our Tutorials Directory.

Dosya Kapatılıyor

close işlevi bir akışı kapatır.

Yapılar, farklı türlerdeki veri öğelerini birleştirmenize olanak tanıyan kullanıcı tanımlı veri türlerinden biridir.

Yapılar bir kaydı temsil etmek için kullanılır. Kitaplarınızı bir kütüphanede takip etmek istediğinizi varsayalım. Her kitapla ilgili aşağıdaki öznitelikleri izlemek isteyebilirsiniz -

  • Title
  • Author
  • Subject
  • Kitap kimliği

Bir Yapının Tanımlanması

defstructLISP'deki makro, soyut bir kayıt yapısı tanımlamanıza izin verir. defstruct ifadesi, programınız için birden fazla üye içeren yeni bir veri türünü tanımlar.

Formatını tartışmak için defstructmakrosu, Kitap yapısının tanımını yazalım. Kitap yapısını şu şekilde tanımlayabiliriz:

(defstruct book 
   title 
   author 
   subject 
   book-id 
)

lütfen aklınızda bulundurun

  • Yukarıdaki beyan, dörtlü bir kitap yapısı oluşturur. named components. Yani yaratılan her kitap bu yapının bir nesnesi olacak.

  • Kitap-başlığı, kitap-yazarı, kitap-konu ve kitap-kitap-kimliği adlı dört işlevi tanımlar; bunlar bir bağımsız değişken, bir kitap yapısı alır ve kitabın başlığını, yazarını, konusunu ve kitap kimliğini döndürür. nesne. Bu işlevlereaccess functions.

  • Sembol kitabı bir veri türü haline gelir ve bunu kullanarak kontrol edebilirsiniz. typep yüklem.

  • Ayrıca adında örtük bir işlev de olacaktır. book-p, bu bir yüklemdir ve argümanı bir kitapsa ve aksi takdirde yanlışsa doğru olacaktır.

  • Adlı başka bir örtük işlev make-book bir constructor, bu, çağrıldığında, erişim işlevleriyle kullanıma uygun, dört bileşenli bir veri yapısı oluşturacaktır.

  • #S syntax bir yapıyı ifade eder ve bunu bir kitabın örneklerini okumak veya yazdırmak için kullanabilirsiniz.

  • Bir bağımsız değişkenin kopya kitabı adlı örtük bir işlev de bu şekilde tanımlanır. Bir kitap nesnesini alır ve ilkinin kopyası olan başka bir kitap nesnesi oluşturur. Bu fonksiyonacopier function.

  • Kullanabilirsiniz setf örneğin bir kitabın bileşenlerini değiştirmek

(setf (book-book-id book3) 100)

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defstruct book 
   title 
   author 
   subject 
   book-id 
)

( setq book1 (make-book :title "C Programming"
   :author "Nuha Ali" 
   :subject "C-Programming Tutorial"
   :book-id "478")
)

( setq book2 (make-book :title "Telecom Billing"
   :author "Zara Ali" 
   :subject "C-Programming Tutorial"
   :book-id "501")
) 

(write book1)
(terpri)
(write book2)
(setq book3( copy-book book1))
(setf (book-book-id book3) 100) 
(terpri)
(write book3)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

#S(BOOK :TITLE "C Programming" :AUTHOR "Nuha Ali" :SUBJECT "C-Programming Tutorial" :BOOK-ID "478")
#S(BOOK :TITLE "Telecom Billing" :AUTHOR "Zara Ali" :SUBJECT "C-Programming Tutorial" :BOOK-ID "501")
#S(BOOK :TITLE "C Programming" :AUTHOR "Nuha Ali" :SUBJECT "C-Programming Tutorial" :BOOK-ID 100)

Genel anlamda programlama dilleri terimi, bir dizi ismi diğerinden ayrı tutmanın bir yolunu sağlamak için tasarlanmıştır. Bir pakette beyan edilen semboller, başka bir pakette belirtilen aynı sembollerle çelişmez. Bu şekilde paketler, bağımsız kod modülleri arasındaki adlandırma çakışmalarını azaltır.

LISP okuyucu, bulduğu tüm sembollerin bir tablosunu tutar. Yeni bir karakter dizisi bulduğunda yeni bir sembol oluşturur ve sembol tablosunda depolar. Bu tabloya paket denir.

Mevcut paket özel değişken * paket * ile belirtilir.

LISP'de önceden tanımlanmış iki paket vardır -

  • common-lisp - tanımlanan tüm fonksiyonlar ve değişkenler için semboller içerir.

  • common-lisp-user- Common-lisp paketini ve diğer tüm paketleri düzenleme ve hata ayıklama araçlarıyla kullanır; kısaca cl-user denir

LISP'de Paket İşlevleri

Aşağıdaki tablo, paketleri oluşturmak, kullanmak ve işlemek için en sık kullanılan işlevleri göstermektedir -

Sr.No. İşlev ve Açıklama
1

make-package paket adı ve anahtar: takma adlar: kullanım

Belirtilen paket adıyla yeni bir paket oluşturur ve döndürür.

2

in-package paket adı ve anahtar: takma adlar: kullanım

Paketi güncel hale getirir.

3

in-package isim

Bu makro, * paketin * 'in bir sembol veya dize olması gereken paket adlı pakete ayarlanmasına neden olur.

4

find-package isim

Bir paket arar. Bu isim veya rumuz ile paket iade edilir; böyle bir paket yoksa, bul-paketi nil döndürür.

5

rename-package paket yeni adı ve isteğe bağlı yeni takma adlar

bir paketi yeniden adlandırır.

6

list-all-packages

Bu işlev, Lisp sisteminde mevcut olan tüm paketlerin bir listesini döndürür.

7

delete-package paket

Bir paketi siler.

Bir LISP Paketi Oluşturma

defpackageişlevi, kullanıcı tanımlı bir paket oluşturmak için kullanılır. Aşağıdaki sözdizimine sahiptir -

(defpackage :package-name
   (:use :common-lisp ...)
   (:export :symbol1 :symbol2 ...)
)

Nerede,

  • paket-adı, paketin adıdır.

  • : Use anahtar sözcüğü, bu paketin ihtiyaç duyduğu paketleri, yani bu paketteki kod tarafından kullanılan işlevleri tanımlayan paketleri belirtir.

  • : Export anahtar sözcüğü, bu pakette harici olan sembolleri belirtir.

make-packageişlevi ayrıca bir paket oluşturmak için kullanılır. Bu işlevin sözdizimi -

make-package package-name &key :nicknames :use

bağımsız değişkenler ve anahtar sözcükler öncekiyle aynı anlama sahiptir.

Bir Paketin Kullanılması

Bir paket oluşturduktan sonra, bu paketteki kodu mevcut paket yaparak kullanabilirsiniz. in-package makrosu, bir paketi ortamda güncel hale getirir.

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(make-package :tom)
(make-package :dick)
(make-package :harry)
(in-package tom)
(defun hello () 
   (write-line "Hello! This is Tom's Tutorials Point")
)

(hello)
(in-package dick)
(defun hello () 
   (write-line "Hello! This is Dick's Tutorials Point")
)

(hello)
(in-package harry)
(defun hello () 
   (write-line "Hello! This is Harry's Tutorials Point")
)

(hello)
(in-package tom)
(hello)
(in-package dick)
(hello)
(in-package harry)
(hello)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Hello! This is Tom's Tutorials Point
Hello! This is Dick's Tutorials Point
Hello! This is Harry's Tutorials Point

Bir Paketi Silme

delete-packagemakrosu bir paketi silmenizi sağlar. Aşağıdaki örnek bunu göstermektedir -

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(make-package :tom)
(make-package :dick)
(make-package :harry)
(in-package tom)
(defun hello () 
   (write-line "Hello! This is Tom's Tutorials Point")
)

(in-package dick)
(defun hello () 
   (write-line "Hello! This is Dick's Tutorials Point")
)

(in-package harry)
(defun hello () 
   (write-line "Hello! This is Harry's Tutorials Point")
)

(in-package tom)
(hello)
(in-package dick)
(hello)
(in-package harry)
(hello)
(delete-package tom)
(in-package tom)
(hello)

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Hello! This is Tom's Tutorials Point
Hello! This is Dick's Tutorials Point
Hello! This is Harry's Tutorials Point
*** - EVAL: variable TOM has no value

Ortak LISP terminolojisinde, istisnalara koşullar denir.

Aslında, koşullar geleneksel programlama dillerindeki istisnalardan daha geneldir, çünkü condition işlev çağrı yığınının çeşitli düzeylerini etkileyebilecek herhangi bir oluşumu, hatayı veya olmadığını gösterir.

LISP'deki durum işleme mekanizması, bu tür durumları, çağrı yığınındaki üst düzey kodun çalışmaya devam ederken uyarı sinyali vermek için (örneğin bir uyarı yazdırarak) koşulların kullanıldığı bir şekilde ele alır.

LISP'deki durum işleme sistemi üç bölümden oluşur -

  • Bir koşula işaret etme
  • Durumu ele almak
  • İşlemi yeniden başlatın

Bir Durumu Ele Alma

Buradaki kavramları açıklamak için sıfıra bölme koşulundan kaynaklanan bir durumu ele alalım.

Bir durumu ele almak için aşağıdaki adımları atmanız gerekir -

  • Define the Condition - "Bir koşul, sınıfı koşulun genel yapısını gösteren ve örnek verileri, koşulun sinyallenmesine yol açan belirli koşulların ayrıntıları hakkında bilgi taşıyan bir nesnedir".

    Koşul tanımlama makrosu, aşağıdaki sözdizimine sahip bir koşulu tanımlamak için kullanılır:

    (define-condition condition-name (error)
       ((text :initarg :text :reader text))
    )

    MAKE-CONDITION makrosu ile yeni koşul nesneleri oluşturulur; bu, yeni koşulun yuvalarını, :initargs argüman.

    Örneğimizde, aşağıdaki kod koşulu tanımlar -

    (define-condition on-division-by-zero (error)
       ((message :initarg :message :reader message))
    )
  • Writing the Handlers- bir koşul işleyici, üzerinde işaret edilen koşulu işlemek için kullanılan bir koddur. Genellikle, hata yapma işlevini çağıran üst düzey işlevlerden birinde yazılır. Bir koşul sinyal verildiğinde, sinyalleme mekanizması koşulun sınıfına göre uygun bir işleyici arar.

    Her işleyici şunlardan oluşur:

    • İşleyebileceği koşul türünü belirten tür belirticisi
    • Tek bir argüman alan bir işlev, koşul

    Bir koşul sinyallendiğinde, sinyalleme mekanizması, koşul tipiyle uyumlu en son kurulan işleyiciyi bulur ve onun işlevini çağırır.

    Makro handler-casebir koşul işleyici kurar. İşleyici vakasının temel formu -

    (handler-case expression error-clause*)

    Nerede, her bir hata cümlesinin biçimi -

    condition-type ([var]) code)
  • Restarting Phase

    Bu, programınızı hatalardan kurtaran koddur ve koşul işleyicileri daha sonra uygun bir yeniden başlatma çağrısı yaparak bir koşulu işleyebilir. Yeniden başlatma kodu genellikle orta düzey veya düşük düzey işlevlere yerleştirilir ve koşul işleyicileri uygulamanın üst düzeylerine yerleştirilir.

    handler-bindmakrosu, bir yeniden başlatma işlevi sağlamanıza ve işlev çağrı yığınını çözmeden alt düzey işlevlerde devam etmenize olanak tanır. Başka bir deyişle, kontrol akışı yine de alt düzey işlevde olacaktır.

    Temel formu handler-bind aşağıdaki gibidir -

    (handler-bind (binding*) form*)

    Her bağlamanın aşağıdakilerin bir listesi olduğu yerlerde -

    • bir koşul türü
    • bir bağımsız değişkenin işleyici işlevi

    invoke-restart makrosu, argüman olarak belirtilen adla en son bağlanan yeniden başlatma işlevini bulur ve çağırır.

    Birden çok yeniden başlatmaya sahip olabilirsiniz.

Misal

Bu örnekte, yukarıdaki kavramları, bölen bağımsız değişkeni sıfırsa bir hata koşulu oluşturacak bölme işlevi adlı bir işlev yazarak gösteriyoruz. Bundan çıkmanın üç yolunu sağlayan üç anonim fonksiyonumuz var - 1 değerini döndürerek, bölen 2'yi göndererek ve yeniden hesaplayarak veya 1'i döndürerek.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(define-condition on-division-by-zero (error)
   ((message :initarg :message :reader message))
)
   
(defun handle-infinity ()
   (restart-case
      (let ((result 0))
         (setf result (division-function 10 0))
         (format t "Value: ~a~%" result)
      )
      (just-continue () nil)
   )
)
     
(defun division-function (value1 value2)
   (restart-case
      (if (/= value2 0)
         (/ value1 value2)
         (error 'on-division-by-zero :message "denominator is zero")
      )

      (return-zero () 0)
      (return-value (r) r)
      (recalc-using (d) (division-function value1 d))
   )
)

(defun high-level-code ()
   (handler-bind
      (
         (on-division-by-zero
            #'(lambda (c)
               (format t "error signaled: ~a~%" (message c))
               (invoke-restart 'return-zero)
            )
         )
         (handle-infinity)
      )
   )
)

(handler-bind
   (
      (on-division-by-zero
         #'(lambda (c)
            (format t "error signaled: ~a~%" (message c))
            (invoke-restart 'return-value 1)
         )
      )
   )
   (handle-infinity)
)

(handler-bind
   (
      (on-division-by-zero
         #'(lambda (c)
            (format t "error signaled: ~a~%" (message c))
            (invoke-restart 'recalc-using 2)
         )
      )
   )
   (handle-infinity)
)

(handler-bind
   (
      (on-division-by-zero
         #'(lambda (c)
            (format t "error signaled: ~a~%" (message c))
            (invoke-restart 'just-continue)
         )
      )
   )
   (handle-infinity)
)

(format t "Done."))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

error signaled: denominator is zero
Value: 1
error signaled: denominator is zero
Value: 5
error signaled: denominator is zero
Done.

Yukarıda tartışıldığı gibi "Koşul Sistemi" dışında, Ortak LISP ayrıca bir hatayı bildirmek için çağrılabilecek çeşitli işlevler de sağlar. Bununla birlikte, sinyal verildiğinde bir hatanın ele alınması uygulamaya bağlıdır.

LISP'de Hata Sinyalleme İşlevleri

Aşağıdaki tablo, uyarıları, kesintileri, önemli olmayan ve önemli hataları gösteren yaygın olarak kullanılan işlevleri sağlar.

Kullanıcı programı bir hata mesajı (bir dizi) belirtir. İşlevler bu mesajı işler ve bunu kullanıcıya gösterebilir / göstermeyebilir.

Hata mesajları, format LISP sistemi bunları tercih ettiği stile göre halledeceğinden, başında veya sonunda bir satırsonu karakteri içermemelidir ve hatayı göstermesi gerekmez.

Sr.No. İşlev ve Açıklama
1

error format-string & rest argümanları

Ölümcül bir hatayı işaret ediyor. Bu tür bir hatadan devam etmek imkansızdır; bu nedenle hata asla arayana geri dönmez.

2

cerror Continue-format-string error-format-string & rest argümanları

Bir hatayı bildirir ve hata ayıklayıcıya girer. Ancak, hatayı çözdükten sonra programın hata ayıklayıcıdan devam etmesine izin verir.

3

warn format-string & rest argümanları

bir hata mesajı yazdırır ancak normalde hata ayıklayıcıya gitmez

4

break& isteğe bağlı biçim dizesi ve kalan bağımsız değişkenler

Mesajı yazdırır ve programlanmış hata işleme araçları tarafından herhangi bir müdahale olasılığına izin vermeden doğrudan hata ayıklayıcıya gider

Misal

Bu örnekte, faktöriyel işlevi bir sayının faktöriyelini hesaplar; ancak, bağımsız değişken negatifse, bir hata durumu ortaya çıkarır.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defun factorial (x)
   (cond ((or (not (typep x 'integer)) (minusp x))
      (error "~S is a negative number." x))
      ((zerop x) 1)
      (t (* x (factorial (- x 1))))
   )
)

(write(factorial 5))
(terpri)
(write(factorial -1))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

120
*** - -1 is a negative number.

Ortak LISP, nesne yönelimli programlamanın ilerlemesinden birkaç on yıl öncesine dayanıyordu. Bununla birlikte, nesne yönelimi daha sonraki bir aşamada buna dahil edildi.

Sınıfları Tanımlama

defclassmakrosu, kullanıcı tanımlı sınıflar oluşturmaya izin verir. Veri türü olarak bir sınıf oluşturur. Aşağıdaki sözdizimine sahiptir -

(defclass class-name (superclass-name*)
   (slot-description*)
   class-option*))

Yuvalar, verileri veya alanları depolayan değişkenlerdir.

Alan açıklaması, her seçeneğin bir anahtar sözcük ve ardından bir ad, ifade ve diğer seçenekler olduğu bir form (yuva adı yuva seçeneği *) içerir. En sık kullanılan yuva seçenekleri şunlardır:

  • :accessor fonksiyon adı

  • :initform ifade

  • :initarg sembol

Örneğin, üç yuva uzunluğu, genişliği ve yüksekliği olan bir Box sınıfı tanımlayalım.

(defclass Box () 
   (length 
   breadth 
   height)
)

Bir Yuvaya Erişim ve Okuma / Yazma Denetimi Sağlama

Yuvaların erişilebilen, okunabilen veya yazılabilen değerleri olmadıkça, sınıflar oldukça kullanışsızdır.

Belirtebilirsiniz accessorsbir sınıf tanımladığınızda her yuva için. Örneğin, Box sınıfımızı ele alalım -

(defclass Box ()
   ((length :accessor length)
      (breadth :accessor breadth)
      (height :accessor height)
   )
)

Ayrı olarak da belirtebilirsiniz accessor bir yuvayı okumak ve yazmak için isimler.

(defclass Box ()
   ((length :reader get-length :writer set-length)
      (breadth :reader get-breadth :writer set-breadth)
      (height :reader get-height :writer set-height)
   )
)

Bir Sınıfın Örneğini Oluşturma

Genel işlev make-instance bir sınıfın yeni bir örneğini oluşturur ve döndürür.

Aşağıdaki sözdizimine sahiptir -

(make-instance class {initarg value}*)

Misal

Üç yuva, uzunluk, genişlik ve yüksekliğe sahip bir Box sınıfı oluşturalım. Bu alanlardaki değerleri ayarlamak için üç yuva erişimcisi kullanacağız.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defclass box ()
   ((length :accessor box-length)
      (breadth :accessor box-breadth)
      (height :accessor box-height)
   )
)
(setf item (make-instance 'box))
(setf (box-length item) 10)
(setf (box-breadth item) 10)
(setf (box-height item) 5)
(format t "Length of the Box is ~d~%" (box-length item))
(format t "Breadth of the Box is ~d~%" (box-breadth item))
(format t "Height of the Box is ~d~%" (box-height item))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Length of the Box is 10
Breadth of the Box is 10
Height of the Box is 5

Bir Sınıf Yöntemi Tanımlama

defmethodmakrosu, sınıf içinde bir yöntem tanımlamanıza izin verir. Aşağıdaki örnek, Box sınıfımızı volume adlı bir yöntemi içerecek şekilde genişletir.

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defclass box ()
   ((length :accessor box-length)
      (breadth :accessor box-breadth)
      (height :accessor box-height)
      (volume :reader volume)
   )
)

; method calculating volume   

(defmethod volume ((object box))
   (* (box-length object) (box-breadth object)(box-height object))
)

 ;setting the values 

(setf item (make-instance 'box))
(setf (box-length item) 10)
(setf (box-breadth item) 10)
(setf (box-height item) 5)

; displaying values

(format t "Length of the Box is ~d~%" (box-length item))
(format t "Breadth of the Box is ~d~%" (box-breadth item))
(format t "Height of the Box is ~d~%" (box-height item))
(format t "Volume of the Box is ~d~%" (volume item))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Length of the Box is 10
Breadth of the Box is 10
Height of the Box is 5
Volume of the Box is 500

Miras

LISP, bir nesneyi başka bir nesne açısından tanımlamanıza izin verir. Bu denirinheritance.Yeni veya farklı özellikler ekleyerek türetilmiş bir sınıf oluşturabilirsiniz. Türetilmiş sınıf, üst sınıfın işlevlerini miras alır.

Aşağıdaki örnek bunu açıklıyor -

Misal

Main.lisp adında yeni bir kaynak kodu dosyası oluşturun ve içine aşağıdaki kodu yazın.

(defclass box ()
   ((length :accessor box-length)
      (breadth :accessor box-breadth)
      (height :accessor box-height)
      (volume :reader volume)
   )
)

; method calculating volume   
(defmethod volume ((object box))
   (* (box-length object) (box-breadth object)(box-height object))
)
  
;wooden-box class inherits the box class  
(defclass wooden-box (box)
((price :accessor box-price)))

;setting the values 
(setf item (make-instance 'wooden-box))
(setf (box-length item) 10)
(setf (box-breadth item) 10)
(setf (box-height item) 5)
(setf (box-price item) 1000)

; displaying values
(format t "Length of the Wooden Box is ~d~%" (box-length item))
(format t "Breadth of the Wooden Box is ~d~%" (box-breadth item))
(format t "Height of the Wooden Box is ~d~%" (box-height item))
(format t "Volume of the Wooden Box is ~d~%" (volume item))
(format t "Price of the Wooden Box is ~d~%" (box-price item))

Kodu çalıştırdığınızda, aşağıdaki sonucu döndürür -

Length of the Wooden Box is 10
Breadth of the Wooden Box is 10
Height of the Wooden Box is 5
Volume of the Wooden Box is 500
Price of the Wooden Box is 1000