Şimdi Lisp'in inanılmaz güçlü bir özelliğini öğreneceğiz: TILSIM yaratmak!
SPEL (ki biz tilsim olarak isimlendirdik), "Semantic Program Enhancement Logic" yani "Anlamlandırılmış Program Geliştirme Mantığı"nın kısaltmasıdır ve kendi bilgisayar dünyamızın kodunda yeni bir davranış stili yaratmamıza olanak sağlayarak Lisp dilini temel seviyede değiştirip ihtiyaçarımız doğrultusunda davranışlarını ayarlayabilmemizi sağlar- Lisp'in büyü gibi olan kısmı budur. TILSIM'ları kullanıma açmak için öncelikle Lisp derleyicimizde TILSIM'ları aktif hale getirmemiz gerekir (Bu satır için endişe etmeyin- ileri seviye Lispçiler buraya tıklamalı.)
|
(defmacro deftilsim (&rest geriye-kalanlar) `(defmacro ,@geriye-kalanlar))
|
Artık kullanıma açıldıklarına göre ilk tilsim'ımızı yaratalım, adı da yürü olsun:
|
(deftilsim yürü (yön)
`(bir-yönde-yürü ',yön))
|
Bu kodun yaptığı şey, derleyiciye yürü kelimesinin gerçekte yürü kelimesi olmadığını ve aslında onun bir-yönde-yürü demek olduğunu ve yön'ün önünde aslında -biz görmesek de- bir kesme işareti olduğunu söylemek. Esasen kodumuz derlenmeden önce onu başka bir şeye çevirecek olan bazı özel kodları programımız ve derleyici arasında bir yerlere sokuşturabiliriz.
|
Bu fonksiyonun daha önce yazdığımız yol-tarif-et koduna ne kadar çok benzediğine dikkat edin: Lisp'te birbirine neredeyse eş derecede benzeyen sadece kod ve veri değildir, kod ve derleyiciye özel komutlar (TILSIMlar) da benzeşir- Gayet tutarlı ve net bir tasarım! Haydi yeni tilsim'ımızı deneyelim:
|
(yürü dogu)
==> (|BÜYÜCÜNÜN| EVINDEKI BIR OTURMA ODASINDASINIZ.
KANEPEDE HORUL HORUL UYUYAN BIR |BÜYÜCÜ| VAR.
BATI ILE KAPI ARASINDA BIR YOL VAR.
USTKAT ILE MERDIVEN ARASINDA BIR YOL VAR.
ZEMINDE BIR VISKI-SISESI |GÖRÜYORSUNUZ.|
ZEMINDE BIR KOVA |GÖRÜYORSUNUZ.|)
Çok daha iyi!
Şimdi dünyamızda nesneleri kaldırmamızı saplayacak komutu yaratacağız:
|
(defun nesneyi-al (nesne)
(cond ((is-at nesne *yer* *nesne-yerleri*)
(push (list nesne 'body) *nesne-yerleri*)
`(simdi bir ,nesne tasiyorsunuz))
(t '(onu alamazsiniz.))))
|
Bu fonksiyon nesnenin gerçekten de o an ki yerimizin zemininde olup olmadığına bakar- eğer öyleyse yeni yeri (kullanıcının bedenini) listeye iter (itmek burda listeye yeni bir eleman eklemek manasındadır, bunu öyle yapar ki assoc komutu bunu görür ve bir önceki yeri gizler.) ve bize başarıp başaramadığını söyleyen bir cümle döndürür.
Şimdi bu komutu daha kolay kullanmamızı sağlayacak bir başka TILSIM yaratalım:
|
(deftilsim al (nesne)
`(nesneyi-al ',nesne))
|
Şimdi yeni TILSIMımızı deneyelim:
|
(al viski-sisesi)
==> (SIMDI BIR VISKI-SISESI TASIYORSUNUZ)
Şimdi bir kaç işe yarar komut daha ekleyelim- İlk önce taşıdığımız nesneleri listeleyen bir komut:
|
(defun envanter ()
(remove-if-not (lambda (x)
(is-at x 'body *nesne-yerleri*))
*nesneler*))
|
Şimdiyse belli bir nesneye sahip olup olmadığımızı söyleyecek bir komut:
|
(defun sahip (nesne)
(member nesne (envanter)))
|