Լիսպ

**Լիսպը** (LISP, անգլ. **LIS**t **P**rocessing – «ցուցակների մշակման լեզու») ծրագրավորման լեզուների ընտանիք է, որում տվյալներն ու ծրագրերը ներկայացվում է գծային ցուցակների միջոցով։
Լիսպի հիմնադիր Ջոն ՄակՔարտին զբաղվում էր արհեստական ինտելեկտի հետազոտություններով և նրա կողմից ստեղծված լեզուն հանդիսանում է արհեստական ինտելեկտի մոդելավորման հիմնական միջոցներից մեկը։

Ավանդական լիսպում օգտագործվում է տիպերի դինամիկ համակարգը։ Լեզուն համարվում է ֆունկցիոնալ, սակայն ունի սիմվոլների մշակման լիարժեք համակարգ, որը թույլ է տալիս իրականացնել օբեկտ-կողմնորոշվածություն, որի օրինակ է CLOS պլատֆորման։

## Ճարտարապետություն և շարահյուսություն
### Լեզվի հիմնական տարրերը

Լեզվի հիմնական տարրեր են հանդիսանում սիմվոլները, ատոմները և դրանցից կառուցված ցուցակները՝ S-արտահայտությունները։

Լիսպում սիմվոլը օբեկտ է մեքենայական հիշողության մեջ, որը հանդիսանում է սլոթերի ամբողջականություն և պահում է հղումներ։ Սլոթերի մի մասն ունի լեզվի կողմից նախապես որոշված նշանակություն.
* անուն – նիշերի տող, ըստ որի ծրագիրը կարող է հղվել տվյալ սիմվոլի վրա։
* Ֆունկցիոնալ սլոթ – սիմվոլի հետ կապակցված լամբդա արտահայտություն։ Երբ ծրագրում սիմվոլին դիմելու հնարավորությունը շարահյուսորեն համապատասխանում է ֆունկցիայի կանչի, հաշվարկվում է սիմվոլի հետ կապված լամբդա արտահայտություն։
* արժեք – օբեկտ մեքենայական հիշողության մեջ, որը կարելի է մեկնաբանել ինչպես տվյալները։ Երբ ծրագիրը սիմվոլին դիմում է որպես փոփոխականի, ստանում է տվյալ սլոթի արժեքը։

Սլոթերի հավաքածուն դինամիկ ընդլայնվող է և կարող է օգտագործվել որպես սիմվոլի անկախ հատկությունների ցուցակ։	

Ատոմները սիմվոլներն են և թվերը։ Թվերը չեն հանդիսանում լիսպի սիմվոլներ, քանի որ կարող են ընդունել միայն սեփական թվային արժեքը։ Բայց միաժամանակ թվերը կարող են սլոթերին հավասար ընդգրկվել ցուցակների մեջ։ Դրանով ել պայմանավորված է դրանց միավորումը միասնական կատեգորիայի մեջ։

Լիսպում տվյալների հիմնական կառուցվածքը ատոմների դինամիկ ցուցակն է, որը ռեկուրսիվ սահմանվում է որպես “գլուխ”-օբեկտ և նրան ամրացված ցուցակ-“պոչ”: Քանի որ գլուխն իր հերթին կարող է լինել ցուցակ, ցուցակը փաստացի հանդիսանում է ծառի մոդել ( վերին մակարդակի ցուցակ – արմատ, դրա մեջ մտնող ենթացուցակներ – ճյուղեր, ատոմներ – տերևներ )։ Ատոմների և ցուցակների համար լեզուն օգտագործում է պարզ, փակագծերով շարահյուսություն. սիմվոլը ներկայացվում է անունով, թիվը՝ իր արժեքով, իսկ ցուցակը՝ կլոր փակագծերում գրված ատոմների և ցուցակների հաջորդականությամբ։

Ցուցակում կարող են ընդգրկված լինել ցանկացած տիպի էլեմենտներ՝ այդ թվում նաև ցուցակներ։ Օրինակ.


```lisp
(1 3/7 'foo #'+)
```


ցուցակը բաղկացած է ամբողջ թվից, կոտորակից, foo սիմվոլից և գումարման ֆունկցիայի վրա ցուցչից։

Արտահայտություններն իրենցից ներկայացնում են պրեֆիքս գրառմամբ ցուցակներ. Առաջին էլեմենտը պետք է լինի ֆունկցիա, օպերատոր կամ մակրոս։

Թվաբանական արտահայտությունները նույնպես գրառվում են այդ սկզբունքով, օրինակ


```lisp
(+ 4 (* 2 3))
```


արտահայտությունը վերադարձնում է 10 ( ինֆիքս գրառումն է 2 * 3 + 4 )։
 s_expression ::= atomic_symbol | "(" s_expression "." s_expression ")" | list 
 list ::= "(" s_expression { s_expression } ")" 
 atomic_symbol ::= letter atom_part 
 atom_part ::= empty | letter atom_part | number atom_part 
 letter ::= "a" | "b" | " ..." | "z" 
 number ::= "1" | "2" | " ..." | "9" 
 empty ::= " "

Լիսպով գրված ծրագրի առանձնահատկությունն այն է, որ տվյալները և ցանկացած բարդության կոդ բնութագրվում է վերը նշված պարզ քերականությամբ։

## Բազային սիմվոլներ, օպերատորներ և ֆունկցիաներ

Լիսպի վերջին իրագործումներն ունեն բազմաթիվ ֆունկցիաներ, մակրոսներ և օպերատորներ։ Այստեղ ներկայացված են նրանք, որոնք կազմում են ցուցակների հետ աշխատելու և լիսպով ֆունկցիոնալ ծրագրեր ստեղծելու հիմնական բազիսը։

### T  և NIL

Լիսպի ներկառուցված սիմվոլ – հաստատուններ, որոնք ցույց են տալիս տրամաբանական արտահայտության ճշմարիտ կամ կեղծ լինելը համապատասխանաբար։

NIL սիմվոլն ունի ևս մեկ կիրառում – այն նաև կարող է նշանակել դատարկ ցուցակ։

### LIST

Հետևյալ ֆունկցիան վերադարձնում է իր արգումենտների ցուցակը.


```lisp
(list 1 3/7 'foo) ==>> (1 3/7 'foo)
```


(այստեղ, նաև հաջորդ օրինակներում «`==>>`» նշանակումը ցույց է տալիս որ ձախ մասի հաշվարկի արդյունքում վերադարձվում է աջ մասում գրվածը)։ Եթե արգումենտ չկա, վերադարձվում է դատարկ ցուցակ.


```lisp
(list) ; ==>> NIL
```


Եթե որևէ արգումենտ իրենից ներկայացնում է արտահայտություն, ապա սկզբում հաշվարկվում է դրա արժեքը.


```lisp
(list 1 2 (list 1 2))  ; ==>> (1 2 (1 2))
```


### QUOTE

Լիսպի ինտերպրետատորը, մուտքում ստանալով ցուցակ կամ սիմվոլ, փորձում է այն հաշվել։ Եթե անհրաժեշտ է, որ ինտերպրետատորը չհաշվարկի արժեք, այլ վերցնի սիմվոլը կամ ցուցակն այնպես, ինչպես կա, պետք է կիրառել QUOTE.


```lisp
(list 1 2 (quote (list 1 2)))  ; ==>> (1 2 (LIST 1 2))
(quote (list 1 2 (list 1 2))) ; ==>> (LIST 1 2 (LIST 1 2))
```


`QUOTE`–ի լրիվ կանչի ձևի փոխարեն կարելի է արտահայտությունից առաջ ուղղակի ապաթարց դնել.


```lisp
(list 1 2 '(list 1 2))  ; ==>> (1 2 (LIST 1 2))
```


### EVAL

Այս ֆունկցիան հենց լիսպի ինտերպրետատորն է։ Այն `QUOTE`֊ի հակադիրն է և հաշվում է իր արգումենտի արժեքը։ Օրինակ.


```lisp
(eval '(list 1 2 '(list 1 2)))         ; ==>> (1 2 (LIST 1 2))
(eval '(list 1 2 (eval '(list 1 2))))  ; ==>> (1 2 (1 2))
```


### CAR
Վերադարձնում է ցուցակի գլուխը՝ առաջին տարրը.


```lisp
(car '(A B C D))     ; ==>> A
(car '((A B)(C D)))  ; ==>> (A B)
```


Բացառություն.

```lisp
(car NIL) ==>> NIL
```


Ֆունկցիոնալ ծրագրավորման մեջ դատարկ ցուցակի գագաթի արժեքն անորոշություն է, բայց լիսպում ընդունված է, որ դատարկ ցուցակի և՛ գլուխը, և՛ պոչը հավասար են `NIL`։

### CDR

Վերադարձնում է ցուցակի պոչը։ Օրինակ.
 (CDR '(A B C D)) ==>> (B C D)
 (CDR '((A B)(C D))) ==>> ((C D))
 (CDR NIL) ==>> NIL

### C?R
Այստեղ `?`-ի փոխարեն կարող է լինել 2 – ից 4 “A” և “D” տառ՝ ցանկացած կոմբինացիայով։ Այսինքն հնարավոր են CDDDDR, CADAR, CADDR և այլն։ Այդպիսի ֆունկցիայի կանչին համապատասխանում է CAR և CDR ֆունկցիաների ներդրված կանչին, օրինակ (CADAR '((A B C) D E F)) –ին համապատասխանում է 

```lisp
(car (cdr (car '((A B C) D E F))))  ; ==>> վերադարձնում է B–ի արժեքը։
```


### CONS
Որպես արգումենտ ընդունում է գլուխ և պոչ և դրանցից կառուցում է ցուցակ կամ կետային զույգ, եթե արգումենտներն ատոմներ են։

```lisp
(cons 'A '(B C D))      ; ==>> (A B C D) - միացնում է ատոմը ցուցակին
(cons '(A B) '((C D)))  ; ==>> ((A B) (C D)) - միացնում է մի ցուցակը մյուսի գագաթից
(cons 'A 'B)            ; ==>> (A . B) - ստեղծում է կետային զույգ 2 ատոմներից
```


### COND
Պայմանի ընդհանրացված կառուցվածք։ Ունի հետևյալ տեսքը.


```lisp
(cond ((պայման1) (արտահայտություն1)) ((պայման2) (արտահայտություն2)) … )
```


Հաջորդաբար հաշվարկվում են պայման1, պայման2, և այլն, այնքան, մինչև N – րդ պայմանը ճշմարիտ լինի։ Ապա հաշվարկվում է արտահայտությունN–ը և դրա արժեքը վերադարձվում է որպես `cond`-ի կանչի արդյունք։ Եթե ճշմարիտ պայման չկա վերադարձվում է `NIL`։ Սովորաբար որպես երջին պայման կիրառում են `T`–ն, որն ապահովում է, որ եթե ոչ մի պայման ճշմարիտ չէ, ապա կկատարվի վերջին արտահայտությունը։ Դա համապատասխանում է իմպերատիվ ծրագրավորման լեզուներում ELSE – օպերատորին։

### DEFUN
Կառուցվածք է, որը թույլ է տալիս սահմանել ֆունկցիա և ունի հետևյալ ընդհանրացված տեսքը.


```lisp
(defun անուն (պարամետր1  պարամետր2 …) արտահայտություն  արտահայտություն  …)
```


* Անուն – ֆունկցիայի անուն։
* Պարամետր1, և այլն, հաջորդականությունը – ֆունկցիայի ֆորմալ պարամետրեր։

Արտահայտություն1, և այլն, հաջորդականությունը – հաշվարկվող արտահայտություններ, որոնցում կարող են օգտագործվել ֆորմալ պարամետրերը և գլոբալ փոփոխականները։ Ֆունկցիայի կանչի ժամանակ արտահայտությունները հաշվարկվում են հաջորդաբար և որպես ֆունկցիայի վերադարձվող արժեք ծառայում է վերջին արտահայտության հաշվարկից ստացված արդյունքը։

## Հղումներ

Կատեգորիա:Ծրագրավորում
Կատեգորիա:Ամերիկյան հայտնագործություններ