LISP NOTLARI

NEDEN BU NOTLAR VAR

LISP programlama literatürüne altın harflerle geçen. Yapay zeka uygulamalarından genel uygulamalara kadar kullanılabilen bir dildir. Bir Java, C / C++ programcısı olarak LISP dilini bende yeni öğrenen biriyim. LISP evet öğrenmesi nispeten zor (ki bu göreceli bir durum, temel konuları 2 saatte öğrenmek mümkün) olan bir dildir. Fakat liste tabanlı bir dil ile her türlü programlama stratejisinin aynı anda yürütülebilir olması da enteresandır (lisp sanılanın aksine sadece liste tabanlı işlemler yapmaz, sayılar, semboller, ağaçlar, kümeler, diziler, stringler, structlar bulunmaktadır). Bir lisper olmamama rağmen ben de öğrenirken ve geliştirirken notlar tutmaya karar verdim, çünkü türkçe kaynak bulmak zor kendi notlarıma geri bakarak daha hızlı çalışıp hafızama almak kolay oluyor. Ayrıca Önce okumak, sonra program yazmak ve sonra da konuyu anladığım şekli ile dile getirmek benim öğrenme sitilim. Aynı yoldan geçmek isteyecek kimseler bu kaynağı okuyarak güzel bir başlangıç yapabilirler diye düşünüyorum. Notlarımın kesin doğru olduğunu söylemek yanlış olacaktır. Bu yazı serisini okuyanlar için iyi bir kaynak bulmalarını tavsiye ederim.


NASIL BİR MANTIKLA KONULAR SIRALANACAK

Kendi öğrenme sıramı birebir göreceksiniz ve öğrenirken yazdığım tüm satırları göreceksiniz. Pek çok kitaptan aynı anda öğrenmeye çalışıyorum. Bu nedenle benim öğrediÄŸim sıra ile notlarıma ulacaÅŸaksınız. Bir nevi tutorial ÅŸeklinde konular ardı ardına gelecek. Stuart C Shapiro – Common Lisp – An Interactive Approch kitabı, David J. Cooper Jr. Basic Lisp Techniques kitabı ve Peter Siebel, Pratical Common Lisp kitabı ilk kısımlarında notlarımın onemli yerlerini oluÅŸtururdu. Peter Norving Good Lisp Programing Style notları son bölümlerde program oluÅŸturma stratejimin deÄŸiÅŸmesine nasıl sebep olduÄŸunu göreceksiniz.

BaÅŸlangıçta Stuart C Shapiro – Common Lisp – An Interactive Approch hemen dile ısınmamı saÄŸladı. Bu nedenle ondan ilk kısımda fazlası ile faydalandım. Daha sonra Lisp dilinin aslında Lisp dili yazmak için en ideal dil olduÄŸuna iliÅŸkin yazılar okudukça en önemli konunun (ki ileri bir konu) makro yazmak olduÄŸunu düşündüm. Paul Graham’ın On Lisp adlı kitabı bu konuda sanırım tek geçilebilecek literatör. On Lisp sizi Lisp biliyor kabul ediyor. Bu kitabı anlamak için Paul Graham’ın ANSI Common Lisp kitabını da okuyarak hem yazarın diline yatkınlık elde etmek hemde standart dille konuyu özdeÅŸleÅŸÅŸtirmek istedim. Paul Graham Lisp Lehçelerini eski formu ile kullanıyor (nitekim common-lisp.net sitesindeki projelere baktığımda first ve rest yerine car ve cdr beni karşıladı. Notlarımın geri kalanında Ansi Common Lisp kitabı ile haşırneÅŸir oldum.

Türk lisp programcıları mail listesine üye oldum (cs-lisp@cs.bilgi.edu.tr). Hareketli bir liste olmamasına rağmen bir yazı yazdım Emre Bey (ileriseviye.org) cevap verdi. Kendisi Successful Lisp: How to Understand and Use Common Lisp, David B. Lamkins (http://www.psg.com/~dlamkins/sl/contents.html) kitabını tavsiye etti. ANSI Common Lisp kitabına ağırlık verek ara sıra bu kaynağa da baktım.

Notlarıma sadece göz atmak istiyorsanız sorun yok fakat gerçekten öğrenmek istiyorsanız yukarda saydığım kaynaklardan birine bakmak gerekli birşey. Lisp hususunda kimseye ahkam kesecek bilgi birikimim yok bu nedenle kendinizin daha cok araştırmanızı tavsiye ederim.

GEREKLİ ARAÇLAR

Lisp dünyasında Bir implimantasyon seçimi ile başlanır. Lisp C#, Java veya Visual Basic gibi al bu dil kuralları bunlarda geçerli IDE ve editörler denebilecek bir dil değildir. Tarihsel gelişimi çok uzun olduğundan dolayı farklı lisp yürütücüleri piyasaya çıkmıştır. MCL, SMCL, CUMUCL, Alegro CL en bilinenleridir. Aslında tüm olay Bunca farklı lisp yorumlayıcısına rağmen ortak bir Lisp dili kümesi olan Common Lispin ANSI standartı ile kurala bağlanmasıdır. Yukarda saydığım Lisp İmplimantasyonlarından biri seçilebilir.

Editör noktasında Notpad dahil her editör kullanılabilir. Ben ilk başlarda Emacs ile başlamak istiyorum. Emacs ile Lisp implimantasyonlarını konuşturan ara kütüphaneler var mesela SLIME bunlardan biri. CCL ile Emacsı aynı düzleme getren SLIME ile emacs üzerinde program yazılabilir. Günümüzde emasın C-x C-s gibi komutlarını da kullanmaya gerek yok.

Emacs ve CMUCL SLIME ayarlarını yapmak bir hayli ilk aÅŸamada sıkıcıdır. Peter Siebel, Pratical Common Lisp (http://www.gigamonkeys.com/book/ adresinden ulaşılabilir) kitabı bu noktada all in one box lisp çözümünü önermiÅŸ ben de bunla ilk satırlarımı yazmaya karar verdim. http://common-lisp.net/project/lispbox/ adresinden iÅŸletim sisteminize göre birini indirin sonra çalıştırın. (Windows için *.bat dosyası ÅŸeklinde) ekrana Emacs açılıyor ve SLIME çalışıp sizi konsola devrediyor. İlk uygulamalarımızı biz sadece Stuart C Shapiro – Common Lisp – An Interactive Approch kitabında da önerdiÄŸi gibi konsoldan yazacağız.

İleriki aşamalarda Lisp programlarınızı dosyaladığınızda Notpad++ faydalı bir yazma aracına dönüşebilir. Eclipse lisp eklentisi de mevcut. Eklentinin kurulumu ve güzel bir başlangıç http://www.ibm.com/developerworks/opensource/library/os-eclipse-lispcusp/ adresinde yer alıyor.

Common Lisp implimantasyonları farklı özellikler barındırabiliyor. Örneğin Alegro indirdiğinizde bir debuger bir editör ile bir nevi IDE ile size geliyor. Başlangıç için önemli bulmadığımdan şimdilik gerek olmadığını söyleyebilirim.

Lisp için Lisp ile implimantasyon yazmak Lisp kodlarını tam derlemek lisp ile derleyici veya yorumlayıcı yazmak hatta işletim sistemi (Genera) dahi yazmak mümkündür. Biz ilk programlarımınızı lispbox Emacs üzerinde sadece terminal etkileşimi ile yazacağız.

TERMİNAL İLE KONUŞMAK

LispBoxu indirin Eğer sisteminizi kurduğunuz yolda türkçe karakter olmasın benimkinde Ş harfi olduğundan ilk başta açmadı. C:lispbox içerisine genişlettim. (Şuan Windowstayım çünkü çoğu kullanıcı Windows kullanıyor aslında varsa yoksa open source) Lispbox.bat dosyasını çalıştırın. Emacs açıldı ve SLIME başladı Ekranda CL_USER> görüyorsunuz. Bu bizim Lisp arayüzümüz. Programları yazmayı öğrenmeden kuralları burada öğreneceğiz. Hello word yazalım.

CL_USER> (format t "Hello World")

Artık hep bu konsolu kullanacağız. Ben CL_USER> yazmak istemiyorum artık mantığı anladınız. Lispte bol miktarda () işaretleri göreceksiniz () yazmaya şimdiden alışın. Parantezler dünyası bu. Common Lisp öğreneceğiz. Başka bir lisp olan Scheme öğrenmek isteyen varda yollarımız burada ayrıldı. Konulara başlayabiliriz.

TEMEL KONULAR

SAYILAR

En bilinen değişken tipi sayıdan başlayalım Konsola herhangibir rakkam yazın aynı sonucu size geri döndürdüğünü görürsünüz. -4e5 1.2s-5 1.221 12 hepsi birer sayıdır. 32 bir integer, 1.12 bir float, 1.0e3 bir long fload 1.2d-4 bir double fload olur.

LİSTELER

Listeler. Lispte herÅŸey birer listedir (1 2 3 4) bir listedir. Dört elemanı vardır (2 4 2) de baÅŸka bir listedir. (1 (2 3) 3) de listedir ve üç elemanı vardır ikinci elemanı da bir listedir ve onunda iki elemanı vardır. Hatta lispte programların kendisi de birer listedir () ifadeleri arasındadır. Bir listenin ilk elemanı anlamlı bir lisp fonksiyonu ise liste program olarak çalışır ve ikinci elemanından sonuncu elemanına kadar iÅŸlemleri birinci elemandaki fonksiyon cinsinden yapar. EÄŸer ilk eleman tanımlı bir fonksiyon deÄŸilse bu durumda lisp onu liste olarak görür. Bu nedenle LISP LISt in Process kelimelerinden yani iÅŸleyen listeler ifadesinden gelir. () listesi boÅŸ bir listedir. (()) listesi ile bir elemanlı ve birinci elemanı boÅŸ olan bir listedir. Lisp listeleri iÅŸler demiÅŸtik bir ifadenin liste olduÄŸunu ve iÅŸlenmesini istemediÄŸimizi ‘ ifadesi ile belirtiriz. Yani konsola yukarıdaki ifadeleri ancak şöyle yazabilirsiniz ‘(1 (2 3) () 4) Dikkat ederseniz () ifadesi yerine NIL yazdı bu lisp dilinde BoÅŸ ifade demektir. Siz de ‘(1 (2 ()) nil 4 (())) ifadesini deneyiniz.

ARITMETİK

Listelerden bahsederken Her listenin aslında çalışabilir program olduğundan ve her listenin ilk ifadesinin komutu ihtiva ettiğinden bahsettik Şimdi aşağıdaki örnekleri deneyin ve böylece aritmatik işlem yapın

(+ 2 1)
(+ 1 3 2)
(- 3 1)
(- 5 1 2)
(* 2 3)
(* 2 3 4)
(/ 9 3)
(/ 27 3 3)
(/ 32.0 3)

Yukarıdaki bölme işlemini (/ 32 3) yaparsanız hata alırsınız float bölmeye ihtiyacınız var.

(/ 12 2)
(= 2 3)

İki ile üç eşit değil Nil aldık.

(= 2 2)

T DoÄŸru demek.

(< 2 3)
(sqrt 4)
(expt 2 3)


STRING İFADELER ve CHAR

String ifadeleri lispte “” iÅŸareti ile tanıtıyoruz. “Hello World!!” gibi. Tabi string bir ifade bir listeye girdi veya alt eleman olabilmekte. Stringlere özel fonksiyonlar da var.

(length "uzunlukun Kac Senin?")
(string= "Ali" "Veli")
(char "Abcdef" 3)
(char= (char "Hello" 1) #/e)

SYMBOL IFADELERİ

Konsola pi yazın. Size pi semblunun sayısal karşılığını verdi. Lisp bazı standart sembollerle gelir bunlar pi, *read-base*, *print-base*, *package*, T, NIL sembolleridir.

Lisp dilinde semboller birbirine büyük küçük harf önemi olmaksızın eşittirler.

(eql 'ali 'ALi)

Sembollerin isimleri Lisp makinesinde büyük harf olarak tutulur. Ama bu özel karakterlerle değiştirilebilir.

(symbol-name 'ali)
(symbol-name 'F\rank)
(symbol-name 'F|rank|)
(eql 'Frank 'F|ran|k)
(string= (symbol-name '|FranK|) "FranK")

Veri tipine bakarsak ‘pi bir sembol ve pi bir sayıdır. ‘pi sembolunu C programcıları pointer gibi düşünebilir.

(type-of 'pi)
(type-of pi)

Semboller aynı zamanda fonksiyonlar da olabilir.

(type-of '+)
(type-of (type-of "Hello"))


PAKETLER

Lisp programlama dili cok geniş programlar yazmaya uygun olacak şekilde ortaya konulmuştur. Paketleri Java programcıları Package C++ programcıları Namespace olarak düşünebilir. Bir pakette programcının yazdığı semboller sıra ile yer alır) *package* sembolu var olan paket bilgisini tutar. Tüm lisp sistemleri USER common lisp pek çok fonksiyonu ise LISP paketinde yer alır.

(describe 'pi)
(describe ’symbol-name)
(describe ’describe)

Paketi şöyle değiştirebilibiliyoruz.

(in-package 'LISP)
(describe 'user::frank)

yukarıda user paketindeki frank sembolüne atıfta bulunuldu. :: ifadesi paketin içini göstermekte kullanılıyor.

Dilersek bir de baÅŸka bir paketten import edebiliriz.

(import 'test::frank)
(package-name *package*)
(find-package "TEST")
(make-package "foo")


TEMEL LİSTE İŞLEMLERİ

Listelerle işlem yapmak Lisp için temel fonksiyonlardır. Bunlara bir bakalım.

(cons 'a 'b)

iki listeyi birleÅŸtiriyor.

(first '(1 3 2 5))
(rest '(1 3 2 5))
(equal '(1 2) '(3 4))
(lenght '(1 3 5 7))
(quote '(1 2 3 4)
(quote (1 2 3 4))

yukarıda yer alan örnekler temel lisp fonksiyonlarını bize vermiş oldu.

YALIN LISP PROGRAMCILIÄžI

KENDİ FONKSİYONLARINIZI TANIMLAMA

Lisp size bir liste olarak fonksiyon tanımlama olanağını verir.

(defun topla (a b) (+ a b))
(topla 2 3)

Lisp bir liste ile karşılaşınca ilk elemanın bir fonksiyon olup olmadığına bakar. Eğer bir fonksiyon ise liste fonksiyon olarak işler.

PAKETLERDE FONKSİYON KULLANIMI

(make-package 'X)
(in-package 'X)
(describe 'last)
(shadow 'last)
"Fonksiyonun bir kopyası oluşturuldu"
(describe 'last)
(defun last  (l) (first l))
(export 'last)
(in-package 'Common-Lisp-User)
(last '(1 2 3))
(X:last '(1 2 3))

Yukarıda yer alan örnek ile önce bir paket oluşturduk. Paketin içine lisp kütüphanesinden bir fonksiyon kopyalayıp bunu değiştirdik. Sonra da ana pakete dönüp tekrar fonksiyonu test ettik.

BAŞKA BİR GÜN İÇİN SAKLAMAK

Lisp programları sadece konsol komutları şeklinde oluşturulmaz. Lispr programları uzantısı lisp veya cl olan dosyalar olarak da kaydedilebilirler. Bunun için sıklıkla GNU EMACS kullanılmaktadır. Fakat günümüzde eclipse notpad++ da lisp programları yazmak için kullanılabilir.

Kullandığımız lispbox programı aslında Emacs üzerinde çalışan slime eklentisi ve CMUCL den ibarettir. Emacs için türkçe tutorial ve belgelerine Ali Çehreli tarafından verilen tutorial ile hazırlanabilirsiniz. Bunun için http://acehreli.org/TUTORIAL.html adresini ziyaret edebilirsiniz.

Kullandığımız lisp box için slime-repl clazurecl dosyasının aslında slime olduğunu farketmişsinizdir. File split window komutları ile ekranı ikiye bölün ve aşağıdaki pencereyi aktif edin. File visit new file ile açılan pencereye new.lisp yazın gördüğünüz gibi üst pencere new.lisp isimli dosya yer alıyor. Bu dosyay yeni bir lispr programı yazabilirsiniz.

Şimdi new.lisp dosyasına aşağıdakileri yazın.

(defun hello-word ()
	(format t "Hello, Word!"))

ve kaydedip slime ekranına şunu yazabilirsiniz.

(load "new")
(hello-word)

böylece lisp programımızı da kaydetme imkanımız olmuş oldu.

Standart bir lisp dosyasının şekli şöyledir.

() fonksiyon blokları dışundaki yorumlar ;;; ifadesi ile fonksiyonun içerisinde ;; ve aynı satır içinde satır sonuna kada ; ifadeleri ile yürür.

Bir dosya şu satırları içermesi kuvvetle faydalıdır

;;; çalışılacak paket tanımlanır.
(in-package 'paketsembol)
;;; shadowlar oluşturulur. Böylece semboller bu paket için rezerve edilir.
(shadow '(semboller))
;;; bir paket içerisinde hem shadowlar hemde impoertlar aynı anda olabilir.
(shadowing-import '(semboller))
;;; kullanılacak paketler belirtilir.
(use-package ;(paketisimleri))
;;; kullanılacak fonksiyonlar
(import '(semboller))
;;; paketten ihraç edilecekler
(export '(semboller))

Common Lisp yeni standartında ise paketlerin içine girmek zor olduğundan veya hangi paket olduğunundan yukarudaki gösterim şu hali almıştır.

(defpackage paket-adı
	(:shadow semoller)
	(:shadowing-inport-from paket sembol)
	(:use paketler)
	(:import-from paket sembol)
	(:export sembol))
(in-package paket-adı)

http://common-lisp.net/projects.shtml web adresinde de projelere bakarsanız yukardaki gösterimin daha sık kullanıldığını görürsünüz.

Harici bir lisp programını derlemek isterseniz

(compile-file "dosya")

şeklinde bir kullanımla karşılaşırsınız. New.lisp dosyasının compile hali fasl veya fsl veya w32fsl uzantılı olacaktır. Bu lullandığınız lisp yorumlayıcısı ile alakalıdır.

TÜR UYUMLULUKLARINI KONTROL ETMEK ve LOJİK

Yazdığınız değişkenin hangi türde olduğunu kontrol etmek isteyebilirsiniz. Örneğin

(integerp 5)
(numberp 2)
(floatp 4.2)
(characterp #\r)
(stringp "hello")
(symbolp 'p)
(packagep 'test)
(listp '(a b))

tür kontrolleri haricinde and, or, <, >, =, >=, <=, not işlemleri de yapabilirsiniz.

IF ve COND İFADESİ

Programlamanın vazgeçilmezi if ifadesi de Lisp dilinde mümkündür. Örneğin

(if (> 4 3) "yes" "no")

komutu mümkündür. Listenin üçüncü ifadesi T verisi ise dördüncü ifadesi ise NIL verisi ise gerçekleşir.

Diğer dillerden switch case olarak bildiğimiz yapı ise Lisp dilinde cond ile gerçekleşir. Örneğin

(defun sign (sayi)
	(cond 	((> sayi 0) 1)
		((= sayi 0) 0)
		((< sayi 0) -1)))

şeklinde işaret fonksiyonu tanımlanabilir. Burada cond komutunun aldığı her ifade else if olarak işlem görür.

YİNELEMELİ İŞLEMLER

Programlama işlerinde şartlı ifadelerden sonra en önemli işlem yinelemeli işlemlerdir. Biz bunları diğer dillerden for, for next, do, while, işlemleri olarak bilmekteyiz. Tabi Lisp (bu yazıdaki tabirle Common Lisp) bunu kendince bir metot ile yapmaktadır.

Yinelemeli işlemlerin türleri vardır birtanesi öz yinelemeli işlemlerdir. Bir factoriel fonksiyonu yazarak bakalım

(defun fact (n) 
	(if (= n 0) 1 
		(* n (fact (- n 1)))))
(fact 2332)

yukarıdaki fonksiyonu şöyle de yazabiliriz

(defun fact (n)
	(if (zerop n) 1
		(* n (fact (1- n)))))

farkedeceğiniz gibi zerop ve 1- birer hazır defundur bunlara bakalım.

;;; (= n 0)
(zerop n)
;;;(+ n 1)
(1+ n)
;;;(- n 1)
(1- n)

Bu noktada şöyle bir sıkıntı ile karşılaşıyoruz.

(fact -2)

yukarıdaki komut kesin bir hataya sebep oluyor. Bu hatayı assert ile yazarak giderebiliriz.

(defun fact (n) 
	"factoriel alan program."
	(assert (and (integerp n) (>= n 0))
		(n) "assert oluÅŸtu.")
	(if (zerop n) 1 (* n (fact (1- n)))))

Aynı uygulama mantığını listeler ile de kurgulamak mümkündür.

(make-package 'hello)
(in-package 'hello)
(shadow 'length)
(defun length (l) 
	(assert (listp l) (l)
		"Liste tipinde olmalı ~S degil" l)
	(if (null l) 0
		(1+ (length l))))

başka bir örnek

(shadow 'member)
(defun member (obj lst)
	(assert (listp lst) (lst) "liste degil")
	(cond 	((null lst) nil)
		((eql obj (first lst)) t)
		(t (member obj (rest lst)))))

Listemizin aynısını veren bir fonksiyon yazarsak

(defun this-list (lst)
	(check-type lst list)
	(if (null lst) '()
		(cons (first lst) (this-list (rest lst)))))

Burada check-type fonksiyonunu da görmüş olduk. Bu fonksiyon içeriğin tipini onaylamanıza yardımcı olur. Copy adındaki geçerli lisp sözcüğü ile aynıdır.

(defun addend (lst1 lst2)
	"Listeleri birleÅŸtir"
	(chack-type lst1 list)
	(chack-type lst2 list)
	(if (null lst1) lst2
		(cons (first lst1) (addend (rest lst1) lst2))))

CAR BİR ARABA MI CDR O ZAMAN ÇEKİCİ NEDİR ANSI?

Bu noktaya kadar Stuart C Shapiro – Common Lisp – An Interactive Approch ile çalışmıştım ÅŸimdi Paul Graham’ın ANSI Common Lisp kitabını teÄŸmin ettim. Daha ziyade bu konulardan devam edeceÄŸim. Yukarıda tutmuÅŸ olduÄŸum notları bir kenara yazın. Listelerin neler olduÄŸunu sayıları gördük. Fakat Modula gibi dillerden geçme first ve rest takıları ile tanışmak bizi her ne kadar hızlandırdı ise de ilk fark ettiÄŸim bunların genel kullanımda olmadıkları. ANSI bir standart ve Common Lisp standartı. Tüm lisp derleyici ve yorumlayıcıları destekliyor. Dile bu ÅŸekli ile hükmektem de iÅŸimize geliyor. Kısaca ANSI olunca Common Lispe nolmuÅŸ bakalım.
Terimler geleneksel lisp isimlerine dönüşmüş.

  • Diziler ve Strucklar gibi yapılar var.
  • Åžartlı ifadeler geliÅŸtirilmiÅŸ. Döngüler eklenmiÅŸ
  • CLOS (OOP programlamak için) dilin bir parçası olmuÅŸ.

Pek de iyi olmuş. ANSI Common Lisp standartı ve daha da güzel olan Hyperspeck dosyasına http://www.lispworks.com/documentation/common-lisp.html adresinden ulaşabilirsiniz.

Şimdi ufak hatırlatmalarla ilerlemeye davam edelim.

QUOTE VE LIST

(quote (1 2 3 4))

bize direkt listeyi verir Ansi bize bunu tek sembole götürmemizde yardımcı olur ‘ sembolunu kısaca kullanabiliriz.

'(1 2 3 4)

Liste yaratmak için list takısı kullanılır.

(list 'a 'b 3)

iki liste bloÄŸunu birleÅŸtirmek isteyebiliriz.

(car 'a '(1 2 3))

Bu liste bloğundaki ilk elemana ANSI geleneğe uyarak car (first yerine) geri kalanına cdr (rest yerine) ile ulaşır.

(car '(1 2 3))
(cdr '(1 2 3))

türleri onaylamak için daha once de gördüğümüz şekilde tür sonuna p ekini koyar.

(listp '(1 2 3))
(null nil)

defun if cond ifadeleri halen vardır. (öğrendiklerimiz baki)

GİRİŞ ÇIKIŞ

Ekrana şu şekli ile çıkış alabiliriz

(format t "~A sayısı ~A'nın kareköküdür. ~%" 3 (* 3 3))

ekrandan giriş almanın en kolay yolu read kullanmaktır.

(read)


KOD BLOKLARI

Pratik kod blokları let ile yapılır

(let 	((x 1)
	(y 2))
		(+ x y)

let iki dizi alır ilk dizi değişkenler ve değerlerinden oluşan bir çifttir. İkinci gurup ide çıktıyı ifade eder.

Birden çok satır içeren değişkensiz kod blokları progn ile tanımlanır.

(progn 
	(+ 2 3)
	(setf a (* 2 4)))

DEĞİŞKENLER SABİTLER

Lispte global değişkenler *isim* şeklindedir. Şöyle tanımlanır.

(defparamater *glopt* 99)

sabitler ise

(defconstant limasol 3)

Global değişken ve sabitler bound tipindedir. Tanımlanıp tanımlanmadıkları şöyle test edilebilir.

(boundp '*globt*)

Lispte değişkenler setf ile atanır.

(setf a '(1 2 3 4 5))
(setf a (remove 1 a))

bir değişkenin tipi aynı zamanda bir semboldur Değişken tipi şöyle kontrol edilebilir.

(typep 23 'integer)

DÖNGÜLER

Döngüler do, dolist ve dotimes ile yapılır.

(do 	((i 1 (+ i 1)) ; i değeri birden başlıyor ve artıyor
 	(j 5 (- i 1)) ; j de 3den başlıyor ve birer azalıyor
	((or (zerop i) (zerop j)) 'done) ; bitiş şartı.
		(format t "~A ve ~A~%" i j))
(dolist 	(obj '(1 2 3 4 5))
	(format t "~A ~%" obj))
(dotimes (val 5 1) ; 5 ten baÅŸla azalarak 1 e var
	(setf a (cons val a)))

FONKSİYONLAR

Bir sembolun fonksiyon olarak (defun) tanımlandıktan sonra işleme alınması (form durumu haricinde) için

(function +)

kullanılır. Function quote gibi bir ifade ile ilişkilidir. # simfesi funtion anlamına gelir.

#'+

satırı bir toplama fonksiyonu döndürür. İşlemi apply ile yapabiliriz.

(apply #'+ '(1 2 3))

apply her zaman liste alır ama son ifadenin liste olmaı yeterlidir

(apply #'+ 1 '(2 3))

apply yerine fonksiyonu direkt çağırmak için funcall da kullanılabilir. Funcall parametreleri sıralı alır (form gibi)

(funcall #'+ 1 2 3)

Lamda ise tek satırlık fonksiyon oluşturmaya yarar. Örneğin

(lambda (x y) ;deÄŸiÅŸkenler
	(+ x y))

form ÅŸeklinde yazarsak

((lambda (x y) (+ x y)) 1 2)

olur. Bu form şekli aynı zamanda şudur.

(funcall #'(lambda (x y) (+ x y)) 1 2)

HEPSİ BU KADAR MI?

Tabii hepsi bu kadar değil. Fakat söylenen o ki bu kadar bilince program yazmaya başlayabiliyormuşuz.

Not yazmayı uzatmayı sevmiyorum bir sonraki not kağıdımı çıkartıp listeler, ağaçlar, kümeler, diziler, sekanslar, structlar hakkındaki notlarımı yazacağım. Üç dört not sonra makrolara gelebilirim. (O zaman makroları yüzeysel geçeceğim taa ki On Lisp okuyana kadar). Şimdilik kalemimi defterimin kenarına sıkıştırıyorum. Bir iki kere bu notlarımı okuyup hazmedip sonraki üniteleri (bir seferde 2-3 başlık) okuyup sonra program yazıp sonra gene not tutacağım. Tabi notların geri kalanı kişisel sitemde www.okanakyuz.com adresinde yer alacak.