site logo
  • Կայքի մասին
  • Ծրագրավորում
  • Ժեշտ
  • Անվտանգություն
  • Հարց ու Պատասխան (ՀուՊ)
Սեպտեմբեր 14, 2012  |  By armenbadal In

Լիսպ (Lisp)

lisp

Երբ ես սկսում եմ ոգևորված պատմել Lisp-ի մասին, բերելով նրա առավելություններից այս կամ այն օրինակը, լսողների մեջ անպայման գտնվում է մեկը, որ հարցնում է, թե ո՞ւմ է այն պետք, կամ որտե՞ղ է այն օգտագործվում: Իհարկե, Lisp-ը չունի Java-ի կամ C-ի տարածվածությունը  (տես. TIOBE Programming Community Index), բայց Lisp-ը, իմ կարծիքով, ոչ միայն ծրագրավորման լեզու է, այն ոչ միայն գործիք է ծրագրավորողի ձեռքին, այլ նաև այն մտածելակերպ է, փիլիսոփայական նոր մոտեցում: 

Ես չեմ կարծում, որ երբևէ առիթ կունենամ Lisp-ն օգտագործել որևէ կոմերցիոն նախագծում: Բայց Lisp-ի ուսումնասիրության արդյունքում իմ աշխատանքը (C, Java, Tcl, C++, Bash լեզուներով) դարձավ ավելի հասկանալի, ավելի պարզ, ավելի հուսալի: Թերևս հենց սրա համար արժե իմանալ (կամ գոնե ծանոթ լինել) Lisp լեզուն:

Ֆունկցիայի սահմանում – defun

Ֆունկցիաները սահմանվում են defun հատուկ մակրոսի միջոցով: Այն ստանում է սահմանվելիք ֆունկցիայի անունը, պարամետրերի ցուցակը և մարմինը: Մարմինը կարող է բաղկացած լինել մեկ կամ մի քանի արտահայտություններից: Օրինակ, հետևյալ ֆունկցիան մի տողում արտածում է 0-ից n թվերը, իսկ հաջորդ տողում արտածում է այդ նույն թվերի քառակուսիները.

(defun f (n)
  (dotimes (i n)
    (format t "~d " i))
  (terpri)
  (dotimes (i n)
    (format t "~d " (* i i)))
  (terpri))
Ֆունկցիայի անունն է f, արգումենտների ցուցակը պարունակում է միայ n անունը, իսկ ֆունկցիայի մարմինը բաղկացած է չորս արտահայտություններից:
Եթե f ֆունկցիան կանչենք 10 արգումենտով, ապա կստանանք հետևյալ պատկերը.
(f 10)
0 1 2 3 4 5 6 7 8 9 
0 1 4 9 16 25 36 49 64 81 
NIL

Վերջին NIL-ը f ֆունկցիայի վերադարձրած արժեքն է. քանի որ Lisp ֆունկցիաները որպես արժեք վերադարձնում են իրենց մարմնում վերջին հաշվարկված արտահայտության արժեքը, այս դեպքում դա terpri ֆունկցիայի արժեքն է:

Ցուցակներ – list, nth, car, cdr …

Lisp լեզվի ցուցակներկ կառուցվում են list հրամանով, որին հետևում է ցուցակի տարրերի թվարկումը: Օրինակ (list 2 (* 2 2) (+ 2 3)) արտահայտության կատարումը վերադարձնում է (2 4 5) ցուցակը: Ցուցակի տարրերին կարելի է դիմել nth ֆունկցիանի միջոցով, այն ստանում է տարրի համարը և ցուցակը, ապա վերադարձնում է պահանջված տարրը: Օրինակ, (nth 2 ‘(0 1 2 3 4)) արտահայտության արժեքն է 2 թիվը: Ցուցակների հետ աշխատելիս շատ հաճախ է պետք լինում ստանալ ցուցակի առաջին տարրը կամ առաջին տարրին հաջորդող տարրերի ցուցակը: Այդ նպատակին են ծառայում համապատասխանաբար car և cdr ֆունկցիաները: Օրինակ,
(car ‘(a b c d e f))
A
(cdr ‘(a b c d e f))
(B C D E F)

Գրենք մի ֆունկցիա, որ ստանում է թվերից բաղկացած ցուցակ և տպում է ցուցակի տարրերի գումարը:

(defun sumof (x)
  (if (null x)
    0
    (+ (car x) (sumof (cdr x)))))
if-ը մի հատուկ կառուցվածք է, որը կանչի ժամանակ ստանում է երեք արտահայտություն: Եթե առաջին արտահայտության արժեքը տարբեր է nil-ից ապա հաշվարկում և վերադարձնում է երկրորդ արտահայտության արժեքը, կակառակ դեպքում՝ երրորդինը: (if (> 2 1) 'a 'b) արտահայտության արժեքը A է, իսկ (if (not (> 2 1)) 'a 'b) արտահայտությանը՝ B: null պրեդիկատը ստուգում է ցուցակի զրոյական լինելը:
Մեկ այլ օրինակ. կազմենք մի ֆունկցիա, որը տրված n (n>=2) թվի համար կառուցում է Ֆիբոնաչիի առաջին n թվերի ցուցակը:
(defun fib-list (n)
  (if (= n 2)
    (list 1 1)
    (let* ((r (fib-list (1- n))) (m (length r)))
      (append r (list (+ (nth (- m 1) r) (nth (- m 2) r)))))))

let և let* կառուցվածքները ստեղծում են լեքսիկական (լոկալ) կապեր փոփոխականների համար: let-ի դեպքում այդ կապերը ստեղծվում են զուգահեռ, իսկ let*-ի դեպքում՝ ըստ թվարկման հաջորդականության: Բերված օրինակում օգտագործված է let* ձևը, քանի որ m փոփոխականին պետք է կապել r ցուցակի երկարությունը, իսկ let-ի դեպքում դա հնարավոր չէր լինի, որովհետև r և m անունները պետք է արժեք ստանային զուգահեռաբար:

append ֆունկցիան իր արգումենտում թվարկված ցուցակներից կառուցում է նոր ցուցակ՝ դրանք կցելով իրար:

Ֆայլեր – open, with-open-file …

ֆայլային հոսք ստեղծելու համար Lisp-ում նախատեսված է open ֆունկցիան, որ բացում է տրված անունով ֆայլը և վերադարձնում է նրա հետ կապված ֆայլային օբյեկտը: Օրինակ, հետևյալ ֆունկցիան ստեղծում է մի ֆայլ, որի ամեն մի տողում գրված է “Line i of text” (0 <= i < 10):

(defun text-file ()
  (let ((fout (open "abcd.txt" :direction :output)))
    (dotimes (i 10)
      (format fout "Line ~d of text~%" i))))
Նույն այդ ֆայլի պարունակությունը կարդալու և տերմինալին արտածելու համար արդեն ֆայլը պետք է բացել կարդալու համար՝ (open “abcd.txt” :direction :input):

Շարունակելի…

ՍկզբնԱղբյուր

Լիսպ (Lisp), 10.0 out of 10 based on 2 ratings
LISP Lisp և Common Lisp Լիսպ
Previous StoryՀարց ծրագրավորողներին
Next StoryՄիկո Հիփոնեն – Առցանց Հարձակումների Երեք Տեսակները

Comments: no replies

Join in: leave your comment Cancel Reply

(will not be shared)

Որոնում

Նշագրեր

*Nix-եր (18) android (17) C++ (19) C և C++ (27) Excel (10) html (10) Network Administration (16) System Administration (28) Windows 7 (14) Ալգորիթմներ (15) Անվտանգություն (29) ԳՆՈՒ/Լինուքս (16) Թեյնիկներին (57) Ժեշտ (44) Լակոնիկ (21) Լինուքս/Յունիքս հրամաններ (29) Լուսանկարչություն և մշակում (15) Խելախոսներ (19) Ծրագրավորման լեզուներ (16) Ծրագրավորում (64) Ծրագրեր (48) Հայականացում (28) Հումոր (11) Ուսումնական նյութեր (34) Սոցցանցային Հմտություններ (19) Վեբ (25) Վերլուծություն (10) Վորդպրես (21) ՏՏ և փիլիսոփայություն (21) Տվյալների բազաներ (12) Օպերացիոն համակարգեր (27) Օֆիսային ծրագրեր (22) անդրոիդ (16) բաշ (10) ինտերնետ (11) խելախոսներ (13) համացանց (15) հայատառ (10) հայերեն (11) հայերեն ստեղնաշար (11) հայկական սոֆթ (11) ստեղնաշար (10) սքրիփթ (14) վինդոուս (12) տեսանյութ (23)
Copyright ©2017 ThemeFuse. All Rights Reserved