|
|
|
СЪВЕТИ
|
Въведение в Lisp/Scheme под Gnu/Linux
|
|
|
|
|
|
от M.Petrov(16-06-2007)
рейтинг (19)
[ добре ]
[ зле ]
Вариант за отпечатване Въведение в Lisp/Scheme
Написана от M. Petrov(благодарности на : http://www.dhstudio.eu)
Статията „Въведените в Lisp/Scheme“ е написана за
потребителите на Gnu/Linux. Инсталацията на DrScheme под
Gnu/Linux (Debian 3.1/4.0) се извършва по следния начин:
apt-get install drscheme.
Lisp e разработен от Джон Маккарти през 1958 г. докато е
бил в MIT (Massachusetts Institute of Technology). Lisp е
базиран на Ламбда- смятането въведено от Алонсо Чърч през
1930 година. Името на Lisp произхожда от "Lisp
Processing". Lisp има доста голям брой диалекти
като най- популярни са: Common Lisp и Scheme. Той бързо
става един от най- популярните програмни езици за изкуствен
интелект. Ние ще разгледаме диалекта Scheme които е бил
разработен през 1970 година от Гай Стиили и Джерард
Джей Сусман. Езика Scheme има два дефинирани стандарта:
Официалния IEEE стандарт и стандарта наречен Revisedn Report
on the Algorithmic Language Scheme които е абревиатура от
RnRS, където n е номер на ревизия. Сегашния стандарт е R5RS
и R6RS е в процес на разработка. Приложението което ще
ползваме в GNU/Linux ще бъдe: drscheme
1.0 Оператори и Операнди
Съставна част от повечето езици са неговите оператори и
операнди. Основните оператори са: /, *, +, - .Нека
разгледаме следния пример за събиране на две числа
използвайки оператори и операнди:
Пример 1.
> (+ 5 4)
9
Основните оператори ползват следния синтаксис:
(<оператор> <операнд1> <операнд2>
<операнд N>)
Термините оператори, процедури и функции имат еднозначно
значение както и термините аргумент и операнд. Сложността
при употребата на оператори може да се увеличи при
употребата на повече от един оператор в съставянето на
конкретен израз. Пример за израз използващ повече от един
оператор е следния:
Пример 2.
> (+ 5 (* 3 2))
11
Пример 3.
> (+ 5 (/ 14 2))
12
Пример 4.
> (+ (* 1 2) (- (+ 3 4) (/ 6 3)))
7
Нека разгледаме подробно действието което извършва пример
2. Разгледания пример 2 казва следното: събери числото 5 с
числото получено от умножението на числата 3 и 2 и изведи
получения резултат .
2.0 Идентификатори, Празни места и Коментари
Идентификаторите са последователност от букви, числа и
следните символи: ! $ % & * + - . / : < = > ? @ ^ _
~
Целта на празните места е да направят кода по- лесен за
четене. Пример с използване на празни места може да видите в
следния Scheme израз:
Пример 5.
> (* (+ 1 2 )
(+ (- 13 3) ))
30
Коментарите са една фундаментална част във всеки програмен
език. Коментарите също благоприятстват за по- голямата
четливост на кода. Използването на коментари предразполага
използването и разработването на кода от всеки
програмист. Коментарите в Scheme се означават със ' ; '.
Всеки текст разположен от ';' до края на реда се
игнорира от компилатора. В Scheme няма коментари опериращи
на повече от един ред.
3.Фундаментални типове
В Scheme има девет типа. Ние ще разгледаме основните:
булеви, числа, низове и символи.
3.1 Булев тип
При употребата на булеви типове е необходимо да се знае,
че този тип извежда „истина“ или „лъжа“. Истината при
използването на булев тип се отбелязва със „#t“, а лъжата
със „#f“ . Нека следваме изречената мъдрост „Хиляди думи се
равняват на един поглед“ и разгледаме следните примери:
Пример 6.
> (boolean? 3.14)
#f
> (number? 131)
#t
> (boolean? #t)
#f
> (boolean? #f)
#t
Различни булеви оператори включват и, или и не:
Пример 7.
> (and #f #t)
#f
> (or #f #t)
#t
> (and (not #f) (or #f #t))
#t
3.2 Числа
Числовите типове имат няколко подтипа като: number,
complex, real, rational, и integer. За да разберете
точността на конкретно число може да ползвате : exact?“ или
„inexact?“. Нека разгледаме следните примери:
Пример 8.
> (/ 4 7)
4/7
> (number? (/ 4 7))
#t
> (rational? (/ 4 7))
#t
> (integer? (/ 4 7))
#f
> (exact? (/ 4 7))
#t
> (inexact? (/ 4 7))
#f
> (sqrt (/ 4 7))
0.7559289460184545
> (exact? (sqrt (/ 4 7)))
#f
> (inexact? (sqrt (/ 4 7)))
#t
3.3 Низове
Низ е разположения текст между двойни кавички „“. В
низовете е възможна употребата на специални символи
благодарение на „\“ . Много често използвани са низовете и
функциите опериращи с тях. Често срещани низ функции са:
substring, string-ref.
Пример 9.
> (substring "www.dhstudio.eu" 4 15)
"dhstudio.eu"
> (substring "testing" 4 7)
"ing"
> (substring "www.dhstudio.eu" 4)
"dhstudio.eu"
> (string-ref "testing" 3)
#\t
3.4 Символи
Употребата на символи увеличава размера на структурите
данни които езика обработва. За работа със символи се
употребява предиката eq? известен също като предикат за
идентичност. Дефиницията за идентичност на два символа
гласи, че двата символа трябва да се състоят от едни и същи
знаци записани в един и същ ред. Нека разгледаме синтаксиса
на предиката eq ?
Пример 10.
> (eq? m1 m2)
Семантиката на предиката eq? се базира на истина и лъжа
т.е. ако: символните изрази m1 и m2 са оценени като едни и
съши изрази то резултата е #t (true/истина) докато в
противен случай е #f (false/лъжа). Често срещан е предиката
symbol? , който има за цел да оцени конкретен обект и да
изведе #t (true/лъжа) , ако обекта е символ и обратното.
Примера по- долу илюстрира действието на предиката
symbol?
Пример 11.
> (symbol? 10)
#f
> (symbol? 'martin)
#t
4.0 Променливи
Деклариране на глобални променливи се извършва с оператора
define. Стойността на променливата по- рано указана с
оператора define може да бъде променяна с оператора set! .
Следния пример изобразява изказаното до момента.
Пример 12.
> (define sbor 26)
> (set! Sbor (+ 20 5))
> sbor
25
5.0 Списъци
Числата, низовете, символите и булевите константи (#t |
#f) се наричат също атоми. Основна конструкция на лиспо-
подобните функционални езици е S- изразът. S- изразът се
нарича точкова двойка или само двойка.
Дефиниция за S- израз:
1.> Всеки атом е S- израз
2.> Ако A и B са S- изрази, то (A.B) е S- израз
3.> S- Израз се определя само по правилата 1> и
2>
Чрез точкова двойка се „слепват“ два обекта и се конструира
съставен обект. Графично изобразено слепване на два обекта
изглежда по следния начин:
*****************************
* първи обект * втори
обект *
*****************************
Лявата част на клетката съдържа първия обект, а дясната
част втория обект. Нека разгледаме пример за двойката (9 .
8)
Пример 13.
*************
* 9
* 8 *
*************
Нека разгледа малко по- усложнен пример на двойката
((2.3).(4.5))
Пример 14.
*************
************* *************
* 2 * 3
* -> * <- *
-> * <- * 4
* 5 *
*************
************* *************
Дефиниране на списък в Scheme се извършва със примитивната
процедура list. Пример за дефиниране на списък:
Пример 15.
> (define dhstudio.eu ( list 'm 'a 'r 't 'i 'n) )
> dhstudio.eu
(m a r t i n)
Във всеки лиспо- подобен език са вградени средства за
реализиране на двойки и работа с тях. В Scheme тези средства
са фундаменталните процедури cons, car и cdr.
5.1 Процедура cons
Процедурата cons е съкращение от construct или конструктор
на двойки. Конструктора има сравнително лесен синтаксис от
вида: (cons b2 c3), където cons e използваната процедура, а
b2, c3 са изрази чиито оценки са S-изрази, т.е. атоми или
точкови двойки. Семантиката на процедура cons се наблюдава в
следващия разгледан пример които конструира двойки:
Пример 16.
> (define b1 10)
> (define c2 20)
> (cons b1 c2)
(10 . 20)
5.2 Процедура car
Идеята на процедурата car е да намери първия обект на
двойка или списък. Семантиката и синтаксис на разглежданата
процедура car най- лесно се обяснява със следния пример
които извежда първи елемент от списък:
Пример 17.
> (define testlist (list 0 1 2 3 4 5 6 7 8 9 ))
> (car testlist)
0
Предходния пример изобразява извеждане първи член на
списък.
Пример 18.
> (define a 10) (define b 20)
> (define c (cons a b) )
> (cаr c)
20
Предходния пример извежда първия обект на двойка.
5.3 Процедура cdr
Процедурата cdr е реципрочна на car, т.е. нейната идея е
да изведе втория обект от списък или двойка. Семантиката и
синтаксиса е аналогичен на процедурата car. Следния пример
изобразява действието на процедурата cdr:
Пример 19.
(define a 10) (define b 20)
(define c (cons a b) )
(cdr c)
5.4 Процедура append
Действието което извършва текущата процедура append е
конкатенация на списъци. Конкатенация на списъци може да
наблюдаваме в следния пример:
Пример 20.
> (define a(list 1 2 3 )) (define b(list 4 5 6 ) )
> (append a b)
(1 2 3 4 5 6)
5.5 Процедура reverse
Процедурата reverse (обръщане) обръща елементите на
списък. Нека разгледаме следния пример за процедурата
reverse:
Пример 21.
> (define a(list 1 2 3 ))
> (reverse a)
(3 2 1)
6.0 Фундаментални контролни структури
6.1 Контролна структура cond (short for conditional)
Структурата cond има за цел да оцени конкретен израз и да
върне резултат (истина | лъжа ). Синтаксиса на структурата
cond e следния:
(cond
(<condition1> <expression1>)
(<condition2> <expression2>)
...
(else <expressionN>))
Следния пример онагледява целта на контролната структура
cond.
Пример 22.
> (define (abs1 x)
> (cond ((> x 0) x)
> ((= x 0) 0)
> (else (- 0 x)) ))
6.2 Процедура „case“
Процедура „case“ е подобна на switch при C/C++/Java.
Процедурата дефинира предварително конкретен брой варианти
които могат да бъдат избирани. Синтаксиса и семантиката на
процедура „case“ може да наблюдаваме във следния пример:
Пример 23.
define get-type
(lambda (data)
(case data
((0 1 2 3 4 5 6 7 8 9) 'digit)
((#\A #\E #\I #\O #\U #\Y #\a #\e #\i
#\o #\u #\y) 'vowel)
(else
(if (and (char? data)
(char-alphabetic? data))
'consonant
'other)))))
> (get-type "Hawaii")
other
> (get-type 5)
digit
> (get-type #\o)
vowel
> (get-type #\s)
consonant
6.3 Процедура „or“
Scheme процедурата „or“ се обяснява доста добре в следния
пример:
Пример 24.
> (or #f #f #f #f)
#f
> (or #f 42 #f)
42
> (or #t #f)
#t
6.4 Процедура „and“
Scheme процедурата „and“ се обяснява доста добре в следния
пример:
Пример 25.
> (and #t #t #t #t)
#t
> (and #t 3.14 'squirrel)
squirrel
> (and 'false '() #f 'only-the-#f-is-false)
#f
> (and 'false '() 'only-the-#f-is-false)
only-the-#f-is-false
6.5 Процедура if
Процедурата if е подобна на процедурата cond. Scheme
процедурата „if“ се обяснява доста добре в следния
пример:
Пример 26.
(define (chislo num)
> ( cond
> ((> num 0)
"Polojitelno")
> ((< num 0)
"Otricatelno")
> ((= num 0) "Rawno na 0")
> (else "zero")))
> (chislo 10)
"Polojitelno"
> (chislo 0)
"Rawno na 0"
> (chislo -1)
"Otricatelno"
Scheme e доста интересен и забавен диалект на Lisp успяващ
да ни заинтригува със своята красота и ясно. Scheme си
остава напълно подходящ език за учебни цели, но също така
намира и други приложения.
СЪДЪРЖАНИЕ
1.0 Оператори и Операнди
2.0 Идентификатори, Празни места и Коментари
3.0 Фундаментални типове
3.1 Булев тип
3.2 Числа
3.3 Низове
3.4 Символи
4.0 Променливи.
5.0 Списъци
5.1 Процедура cons
5.2 Процедура car
5.3 Процедура cdr
5.4 Процедура append
6.0 Фундаментални контролни структури
6.1 Контролна структура cond (short for conditional)
6.2 Процедура „case“
6.3 Процедура „or“
6.4 Процедура „and“
6.5 Процедура if
БИБЛИОГРАФИЯ
1. Езици за функционално и логическо програмиране, М.
Тодорова
2. http://cs.gettysburg.edu/~tneller/cs341...
3. http://www.scheme.com/tspl3/
<< | >>
|
|
|
|
|
Евала! От: Мирчо Мирев <mircho __@__ linux-bg< dot >org> На: 17-06-2007@8:55 GMT+2 Оценка: 1/НеутраленМного благодаря, че написа статия за този прекрасен език и как да се ползва под Линукс.
[Отговори на този коментар] браво От: ники На: 17-06-2007@15:49 GMT+2 Оценка: 1/Неутралентъкмо имам изпит по това чудо след 1 седмица :)
[Отговори на този коментар] друга имплементация От: Димитър Трендафилов На: 17-06-2007@17:12 GMT+2 Оценка: 1/НеутраленСамо да спомена още една реализация на Scheme за ГНУ / Линукс - mit-scheme.
[Отговори на този коментар]
Към: друга имплементация От: bat'Serjo На: 18-06-2007@6:42 GMT+2 Оценка: 1/НеутраленПълен шит. Не разбирам що за мазохист трябва да си за да пишеш на език с толкова отвратителен синтаксис. Ако езика беше толкова як и незаменим, не мислите ли че сега щеше да е език номер едно? Лисп не предлага абсолютно нищо ново, нито революционно (освен грозен синтаксис). Няма нещо което да се направи на лисп и да не може да се направи на питон или смалталк на същия ако не и по малък брой редове. Аре големите фенове на тази боза моля предизвиквам ви дайте един истински пример за 'мощта' на този език.
П.С. Изкуствен интелект мискуствен интелект. Аре дайте ми код на невронна мержа писанa на лисп, или още по добре вземете разгледайте какъв език се използва в момента за изследване на ИИ http://pyrorobotics.org/ . Аре стига сме живели в миналото и най-вече в 70 години.
[Отговори на този коментар]
Към: Към: друга имплементация От: Мирчо Мирев <mircho __@__ linux-bg__dot__org> На: 18-06-2007@7:22 GMT+2 Оценка: 1/НеутраленЕх, младежо.
[Отговори на този коментар]
Ех, какъв език! КрасУта! От: Димитър Жеков <jimmy__at__is-vn< dot >bg> На: 19-06-2007@6:32 GMT+2 Оценка: 1/Неутрален(lambda (*<8-]= *<8-[= ) (or *<8-]= *<8-[= ))
(defun :-] (<) (= < 2))
(defun !(!)(if(and(funcall(lambda(!)(if(and '(< 0)(< ! 2))1 nil))(1+ !))
(not(null '(lambda(!)(if(< 1 !)t nil)))))1(* !(!(1- !)))))
Красота, нали?.. ;-) LISP е нещо като ADA и HURD - много хубаво, само дето по някаква причина не го използват много-много. С изключение на работещите с EMACS, естествено - забележителен редактор, с около 700 основни клавиша и комбинации...
Впрочем на APL може да се напише още по-завързан код. При него каквото и да натракаш от клавиатурата - все някак ще се изпълни. :-)
[Отговори на този коментар]
Към: Ех, какъв език! КрасУта! От: Bongo На: 19-06-2007@10:25 GMT+2 Оценка: 1/НеутраленНаучете нещо за Лисп преди да сипете плюнки и сополи. Препоръчвам ви Practical Common Lisp на Peter Siebel, например.
Или опитайте да почетете малко CLTL2 -- ще разберете колко много не разбирате.
Common Lisp е особен език -- много по-различен от всичко което можете да видите в целия Алголоподобен свят. Нищо чудно, че изглежда странен и неудобен на алголооформения ум -- нещата просто се правят по различен начин. Не се опитвайте да "превеждате" C++ на Лисп (резултатите обикновено са посредствени).
Не се заяждам -- наистина погледнете Practical Common Lisp (достъпна е свободно). Ще откриете удивителни неща и ще видите, че Лисперите са прави като твърдят че "съвременните" езици за програмиране вървят натам където Common Lisp отдавна е пристигнал.
Относно Scheme -- това е другата философия в Лисп -- минималистчната. За разлика от Common Lisp, който е наводнен със специални случаи, изключения, архаични форми (които не е препоръчително да се използват), Scheme се стреми към минимализъм и яснота. Синтаксисът на scheme може да бъде научен за един ден. Аз харесвам простотата на Scheme, но предпочитам по-богатия Common Lisp. И определено от езиците на които съм работил, Common Lisp е езикът, който ме е научил н най-много неща.
Определено си заслужава.
[Отговори на този коментар]
Към: Към: Ех, какъв език! КрасУта! От: icokanov <hristo_kanov __@__ abv[ точка ]bg> На: 19-06-2007@15:47 GMT+2 Оценка: 1/НеутраленМного хубава статия.
[Отговори на този коментар] Към: Към: Ех, какъв език! КрасУта! От: Димитър Жеков <jimmy (a) is-vn __точка__ bg> На: 20-06-2007@7:29 GMT+2 Оценка: 1/НеутраленЕ хайде, хайде, обикновен език с еднотипни обекти, в случая функции (нещо средно между математически и програмни). Ако използваше нормалната нотация вместо перверзната Полска, сигурно дори щеше да е популярен. От изчислителния модел, на който е базиран, по никакъв начин не следва че трябва да използва префиксна нотация, нито че тя дава каквито и да е предимства. За капак и операторите не си знаят броя аргументи, и като се почнат едни скоби - до пето-шесто ниво отиват за прости изрази.
Лично аз съм имал съмнителното удоволствие да работя и на стекови езици, и на симулативни, и синтаксиса на LISP (не концепцията) искрено ме разсмива. :-)))))
[Отговори на този коментар]
Абе ей! От: Stash На: 11-07-2007@20:07 GMT+2 Оценка: 1/НеутраленЕзика си е супер наскоро и аз се запознах с него и останах супер щастлив че съм се докоснал до него. Статията си я бива да кажем си е супер :).
П.П. Още една реализаци я на common LISP - clisp аз лично на нея писах и останах доволен. има я в дебиан поне аз там я ползвах
А за тези който руптаят , я помислете този език какво е дал на съвременните езици ?
И моля не отричайте миналото и него забравяйте!
А'е поздрави
[Отговори на този коментар] Къв синтаксис ве! От: Вельо На: 13-11-2007@21:43 GMT+2 Оценка: 1/НеутраленСкъпи приятелю, лисп не се използва широко просто, защото никой още не е измислил достатъчно добър компилатор, който да изкарва ефикасен машинен код. Дори между отделните компилатори на лисп се забелязват големи разминавания в ефикасността на машинния код. Последно като четох, мисля че коммон лисп се държеше най-добре.
А защо езикът е хубав:
1. Ами опитай се за 3 мин да започнеш да пишеш обектно ориентирано на С, не С++ с неговите глезотиики. Аз това съм го правил на Скийм.
2. Надявам се да си чувал някога за функционално програмиране и с какво то се оличава от императивното. Пробвай да напишеш една истински фунционална програма на друг език, после ще видиш, че с лисп това става 10 пъти по-бързо.
3. Имаше едно сравнение м/у лисп и с. Резултата беше, че прохрамите, написани на лисп вървят 10 пъти по-бавно, от тези на с, но за сметка на това времето за написването им е 10 пъти по-малко, отколкото на с. И нищо чудно с все пак си е асемблер от малко по-висок клас.
Поздрави!
[Отговори на този коментар] Към: Към: друга имплементация От: Вельо На: 13-11-2007@21:45 GMT+2 Оценка: 1/НеутраленСкъпи приятелю, лисп не се използва широко просто, защото никой още не е измислил достатъчно добър компилатор, който да изкарва ефикасен машинен код. Дори между отделните компилатори на лисп се забелязват големи разминавания в ефикасността на машинния код. Последно като четох, мисля че коммон лисп се държеше най-добре.
А защо езикът е хубав:
1. Ами опитай се за 3 мин да започнеш да пишеш обектно ориентирано на С, не С++ с неговите глезотиики. Аз това съм го правил на Скийм.
2. Надявам се да си чувал някога за функционално програмиране и с какво то се оличава от императивното. Пробвай да напишеш една истински фунционална програма на друг език, после ще видиш, че с лисп това става 10 пъти по-бързо.
3. Имаше едно сравнение м/у лисп и с. Резултата беше, че прохрамите, написани на лисп вървят 10 пъти по-бавно, от тези на с, но за сметка на това времето за написването им е 10 пъти по-малко, отколкото на с. И нищо чудно с все пак си е асемблер от малко по-висок клас.
Поздрави!
[Отговори на този коментар] lala От: h2 На: 22-04-2008@5:57 GMT+2 Оценка: 1/Неутраленhttp://software-lab.de/radical.pdf
*LIST processing :)
A ne kakto aftora e sburkal v nachaloto na
statiqta.
I ne e chak tolkova neveroqtno, ima si
bezplatna knijka za Scheme, koqto te uchi kak
da programirash. Tuka e predstaveno chast ot
syntaxisa.
[Отговори на този коментар]
|
|
|
|
|
|
|
|