Jump to content

Search the Community

Showing results for tags 'clojure'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • ფორუმი
    • ფორუმი
    • ზოგადი დისკუსიები
    • ტუტორიალი/Tutorial
    • მათემატიკა
    • ბიბლიოთეკა
    • კრიპტოგრაფია
    • კიბერ უსაფრთხოება
    • ელექტროინჟინერია
  • პროგრამები
    • დიზანის & 3D მოდელირება
    • პროგრამები/ software
    • დაცვა
  • Visual Studio
    • Visual Studio
    • C#
    • C და C++
    • ASP.NET/WPF/MVC
    • WCF
    • Quick Basic / Visual Basic
  • Web Development
    • HTML & CSS
    • Bootstrap
    • PHP & MySQL
    • Javascript
    • AngularJS
    • სხვადასხვა
    • SEO
    • ძრავების მიმოხილვა
  • Development
    • JAVA
    • Perl
    • Python
    • ბაზები
    • Other
    • Game Developer
    • მობილურის დეველოპერი
  • IT-Support
    • Unix/Linux
    • MS Windows
    • Apple /MAC
    • Android
    • Network
    • კომპიუტერის არქიტექტურა
  • ყიდვა-გაყიდვა/შეკვეთები
    • ყიდვა-გაყიდვა
    • შეკვეთები

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


ლოკაცია


ინტერესები

Found 1 result

  1. GHOST_FATHER

    Clojure

    Clojure არის ახალი პროგრამირების ენა, რომელიც შესასრულებლად იყენებს ჯავა ვირტუალურ მანქანას. Clojure არის უფრო ძველი პროგრამირების ენის, ლისპის, დიალექტი. ეს დოკუმენტი წარმოადგენს მოკლე შესავალს Clojure პროგრამირების ენაში, განსაკუთრებით სასარგებლო ის იქნება მათვის, ვინც აქამდე C-ს მსგავს პროგრამირების ენას იყენებდა. C-ს მსგავს ენებში, ფუნქციის გამოძახება, როგორც წესი, ასე გამოიყურება: do_something_with(value1, value2)Clojure-ში იგივე ფუნქციის გამოძახება ასე გამოიყურება: (do-something-with value1 value2) აი რაშია Clojure განსხვავებული: ფრჩხილი იხსნება ფუნქციის სახელის მარცხნივ.არა გვაქვს პარამეტრებს შორის არანაირი გამყოფი (მაგალითად, მძიმე).მიღებულია, რომ სიტყვები ფუნქციის სახელში გაიყოს მოკლე ტირეებით.არც ისე ბევრი განსხვავებაა. აი როგორ გამოიყურება ორი რიცხვის შეკრება C-ს მსგავს ენაში: value1 + value2 აქ კი მოყვანილია, თუ როგორ გამოიყურება ეს Clojure-ში: (+ value1 value2) ამ შემთხვევაში კიდევ ერთი განსხვავებაა, პლიუსის ნიშანი მოდის პარამეტრების წინ. C-ს მსგავს ენაში პლიუსის ნიშანო ოპერატორია. Clojure-ში კი ის მხოლოდ ფუნქციაა, სახელად ‘+’. Clojure არ ჰყოფს "ოპერატორის" და "ფუნქციის" ცნებებს, როგორც ამას აკეთებენ C-ს მსგავსი ენები. ყველაფერი, რაც არის ოპერატორი C-ს მსგავს ენაში, Clojure-ში უნდა წარმოდგენილი იყოს ფუნქციის სახით. თუ თქვენი საყვარელ C-ს მსგავს ენას გამოვაცლით ყველა ოპერატორს, მაშინ ორი მნიშვნელობის დამატება ასე შეიძლება რომ გამოიყურებოდეს: add(value1, value2) რადგანაც ახლა თქვენი C-ს მსგავსი ენა არ შეიცავს ოპერატორებს, ის სიმბოლოები, რომლებიც ადრე ოპერატორისთვის გჭირდებოდათ, შეიძლება გამოიყენოთ ფუნქციის სახელად. მაგალითად, ასე: +(value1, value2) ახლა ეს დიდად არ განსხვავდება Clojure-ს შესაბამისი გამოსახულებისგან: (+ value1 value2) Clojure/Clojure-ს დაყენება Clojure-ს დასაყენების ორი გზა არსებობს: ოფიციალური რელიზიდან ან სუბვერსიის (Subversion) რეპოზიტორიუმიდან. აქ იგულისხმება, რომ თქვენ უკვე დაყენებული გაქვს ჯავას ვირტუალური მანქანა, და იცით როგორ გამოიყენოთ თქვენი სისტემის შესაბამისი ტერმინალის პროგრამა. დაყენება ოფიციალური რელიზიდან შედით http://clojure.org/-ს საწყის გვერდზე, გაჰყევით Download ბმულს, და გადმოიწერეთ Clojure-ს პაკეტი. სავარაუდოდ ეს არქივირებული (ZIP) ფაილია.განაარქივეთ ZIP ფაილი, თუ თქვენი ბრაუზერი ამას ავტომატურად არ აკეთებს.შემდეგ თქვენი ტერმინალით შედით ('cd' ბრძანების გამოყენებით) Clojure-ს განარქივებულ საქაღალდეში.შეიყვანეთ ტერმინალში ბრძანება: java -cp clojure.jar clojure.main.თქვენ უნდა დაინახოთ ბრძანების შეტყობინება: user=> დაყენება სუბვერსიის რეპოზიტორიუმიდან თუ თქვენ გაქვთ დაყენებული სუბვერსია (Subversion) და Ant, რეკომენდებულია, ნაცვლად რელიზის გადმოწერისა, თქვენით ამოიღოთ Clojure საწყისი კოდი რეპოზიტორიუმიდან. თქვენს სისტემაზე უკვე უნდა ეყენოს ჯავა 5, Ant და სუბვერსია. ასე შეგიძლიათ დაყენება ტერმინალის გამოყენებით: შეიყვანეთ ტერმინალში შემდეგი ბრძანებები:svn co https://clojure.svn.sourceforge.net/svnroot/clojure/trunk clojure cd clojureantjava -cp clojure.jar clojure.mainთქვენ უნდა დაინახოთ ბრძანების შეტყობინება: user=> ბრძანების შეტყობინება ცნიბილია სახელით REPL (Read-Evaluate-Print-Loop). REPL კითხულობს (Read) გამოსახულებებს, რომლებიც თქვენ შეგყავთ, აფასებს (Evaluate) მათ, ბეჭდავს (Print) შედეგს და ბრუნდება უკან (Loop) ახალი ბრძანების მისაღებად. Clojure-ში არის ორი ტიპის გამოსახულება: ატომები და სიები. ატომები გავს პრიმიტიულ ტიპებს სხვა პროგრამირების ენებში. გამოვიყენოთ REPL ზოგიერთი ატომის განსახილველად. რიცხვებიuser=> 5 5 რიცხვი 5 ფასდება და შედეგი გამოდის ეკრანზე. ბულის სიმბოლოებიაი სხვა ატომი: user=> true true Clojure-ში მხარდაჭერილია ბულის "ჭეშმარიტი" და "მცდარი" მნიშვნელობები, რომლებიც შესაბამისად ჩაიწერება როგორც true და false. Nilაი კიდევ ერთი მნიშვნელოვანი ატომი: user=> nil nil ეს არის Clojure-ს სახელი ცარიელი მნიშვნელობისთვის. ის შეესაბამება ჯავას null-ს. ტექსტიაი Clojure-ს ტექსტი: user=> "Hello, world!" "Hello, world!" Clojure ტექსტი იგივე წესებით განისაზღვრება, როგორც ჯავას ტექსტი, ასე მაგალითად "\t" წარმოადგენს ტაბულაციის სიმბოლოს. ჯავას API არის ძირითადი საშუალება ტექსტზე მოქმედებისა. სიმბოლოებისიმბოლოები არის სახელები რომლებიც ჩვეულებრივად ებმება მნიშვნელობას. თუმცა მნიშვნელობაზე მიბმა არაა აუცილებელი . სიმბოლოს აქვს შესაბამისი ობიექტი (არა მიბმული მნიშვნელობა), და ამ ობიექტის მისაღებად, სიმბოლოს სახელს წინ დაურთეთ ერთმაგი ბრჭყალი: user=> 'x x თუ თავად მნიშვნელობის მიღება გინდათ, გამოიყენეთ უშუალოდ სიმბოლოს სახელი: user=> x 1 თუ სიმბოლო არაა მნიშვნელობასთან მიბმული, თქვენ შეგიძლიათ ამ სიმბოლოს თავისთავად გამოყენება, მაგრამ შეცდომაა ამ სიმბოლოს მნიშვნელობის მიღების მცდელობა: user=> foo java.lang.Exception: Unable to resolve symbol: foo in this context ... კვანძი სიტყვებიკვანძი სიტყვები გვანან სიმბოლოებს, თუმცა ისინი არ ებმებიან მნიშვნელობებს და შეფასებისას საკუთარ თავს აბრუნებენ მნიშვნელობად. კვანძი სიტყვები ყოველთვის იწყებიან ორწერტილით (:). აი რამოდენიმე კვანძი სიტყვა: user=> :a :a user=> :_123 :_123 user=> :KEY :KEY კვანძი სიტყვები განსაკუთრებით მოსახერხებელია გამოვიყენოთ რუკებში, მნიშვნელობის გასაღებად. Clojure/სიები< Clojure ატომები შეიძლება დაჯგუფდეს სიებში. სიები შეიძლება იყოს ცარიელი ან შედგებოდეს რამდენიმე ატომისაგან, რომლებიც მოქცეულია ფრჩხილებში. სიის ელემენტები გამიჯნულია ცარიელი სიმბოლოთი (შესაძლებელია აგრეთვე მძიმით გამიჯვნაც). სიები შეიძლება გამოვიყენოთ მოქმედების შესასრულებლად, მაგალითად ასეთის: user=> (+ 3 3 3) 9 ამ ოპერაციით ხდება სამი რიცხვის შეჯამება. როდესაც Clojure აფასებს სიებს, სიის პირველი ელემენტი, რომელსაც ოპერატორს უწოდებენ, განსაზღვრავს შესასრულებელი ოპერაციის ტიპს. დანარჩენ ელემენტებს ეწოდებათ არგუმენტები. სია, რომელიც ასრულებს მოქმედებას ცნობილი ოპერატორით არის ფორმა. სულ სამი სახის ფორმა არსებობს: ფუნქციები, მაკროსები და სპეციალური ფორმები. სიის ელემენტები შეიძლება იყოს ატომები, სიები ან სხვა მონაცემთა სტრუქტურები რომლებიც შედიან Clojure-ში. user=> (list :foo (list 1 2 3) [4 5 6]) (:foo (1 2 3) [4 5 6]) თუმცა სია მოქმედების შესასრულებლად გამოიყენება, იგივე სინტაქსის გამოყენებით შეიძლება აგრეთვე მონაცემის წარმოდგენაც. არსებითი შედეგი იმისა, რომ კოდი და მონაცემი ერთი სინტაქსით განისაზღვრება არის შემდეგი დებულება: კოდზე შეგვიძლია იმდაგვარად ვიმოქმედოთ, როგორც მონაცემზე, რადგან კოდი -- მონაცემია. მონაცემთა სიის შესაქმენლად, გამოიყენეთ Clojure-ს ჩადგმული ოპერატორი, list: user=> (list 1 2 3) (1 2 3) user=> (list a b c) (a b c) user=> (list "one" "two" "three") ("one" "two" "three") Clojure-ს აგრეთვე აქვს უფრო მოკლე სინტაქსი მონაცემთა სიითვის. ამისათვის საკმარისია სიის წინ დაისვას ერთმაგი ბრჭყალი: user=> '(1 2 3) (1 2 3) თუმცა ამ ხერხით სიის შექმნას აქვს მცირედით განსხვავებული ეფექტი. სიის ყოველი ელემენტები შეუფასებელი რჩება. Clojure-ს ჩადგმული ოპერატორების დახმარებით შესაძლებელია მონაცემიდან მივიღოთ ინფორმაცია. შემდეგი გამოსახულება აბრუნებს მოცემული სიის პირველ ელემენტს. user=> (first '("one" "two" "three")) "one" შემდეგი ოპერაცია კი აბრუნებს ყველა ელემენტს გარდა პირველისა: user=> (rest '("one" "two" "three")) ("two" "three") Clojure/ვექტორები, რუკები და სიმრავლეები< Clojure სიების მონაცემთა ტიპის გარდა, Clojure გვაძლევს ვექტორების, რუკების და სიმრავლეების განსაზღვრის სინტაქს. ვექტორები არის ნულოვან-ინდექსიანი მასივები. აი მაგალითები: user=> [1 2 3] [1 2 3] user=> [] [] user=> ["a" "b" "c"] ["a" "b" "c"] user=> [:foo "bar" 3] [:foo "bar" 3] user=> [1 2 [10 20]] [1 2 [10 20]] ვექტორები ძალიან გვანან სიებს. განსხვავება არის საბაზისო მონაცემთა სტრუქტურაში. სიებს და ვექტორებს სხვადასხვა წარამადობა ახასიათებთ. კიდევ ერთი განსხვავებაა, რომ ვექტორის სინტაქსი არ იწვევს ოპერაციის შესრულებას. მხოლოდ სიის სინტაქსით შეიძლება ოპერაციის შესრულება. თქვენ აგრეთვე შეგიძლიათ ვექტორის შექმნა ელემენტების გადაცემით vector ოპერატორზე: user=> (vector 1 2 3) [1 2 3] რუკები განსაზღვრავენ უნიკალურ გასაღები-მნიშვნელობა წყვილების სიმრავლეს. user=> {"a" 1, "b" 2, "c" 3} {"a" 1, "b" 2, "c" 3} ეს რუკა აწყვილებს ტექსტს "a" რიცხვთან 1, "b" რიცხვთან 2, და "c" რიცხვთან 3. მძიმეები წყვილებს შორის არააუცილებელია, და საჭიროა კოდის კითხვადობის გასაზრდელად. Clojure მათ თითქმის ისევე განიხილავს როგორც ცარიელი ადგილის სიმბოლოს. მძიმის დასმა შეგიძლიათ გამოსახულების ელემენტებს შორის ნებისმიერ ადგილას: user=> {"a" 1 "b" 2 "c" 3} {"a" 1, "b" 2, "c" 3} user=> {"a", 1, "b", 2, "c", 3} {"a" 1, "b" 2, "c" 3} user=> {"a" 1 ,"b" 2 ,"c" 3} {"a" 1, "b" 2, "c" 3} დააკვრდით, რომ Clojure-მ იცის თუ სად იყო გამოყენებული მძიმეები, თუმცა ეს უფრო მეტი თავსებადობისთვის კეთდება მხოლოდ. როდესაც რუკა განსაზღვრულია, მისი მნიშვნელობების ამოღება შეგიძლიათ get ფორმის გამოყენებით: user=> (get {"a" 1, "b" 2, "c" 3} "a") 1 user=> (get {"a" 1, "b" 2, "c" 3} "b") 2 user=> (get {"a" 1, "b" 2, "c" 3} "c") 3 user=> (get {"a" 1, "b" 2, "c" 3} "d") nil თუმცა ამ ყველაფრის უფრო მარტივად მიღების გზაც არსებობს: user=> ({"a" 1, "b" 2, "c" 3} "a") 1 user=> ({"a" 1, "b" 2, "c" 3} "b") 2 user=> ({"a" 1, "b" 2, "c" 3} "c") 3 user=> ({"a" 1, "b" 2, "c" 3} "d") nil რუკები შეიძლება გამოვიყენოთ მათი გასაღების ფუნქციებად. ეს თავიდან ცოტა უცნაურია, მაგრამ ნელ-ნელა ეს აღნიშვნები სულ უფრო გასაგები გახდება. აი მესამე გზა, თუ როგორ მიიღოთ მნიშვნელობა გასაღებიდან: user=> (:a {:a 1, :b 2, :c 3}) 1 user=> (:b {:a 1, :b 2, :c 3}) 2 user=> (:c {:a 1, :b 2, :c 3}) 3 user=> (:d {:a 1, :b 2, :c 3}) nil მნიშვნელოვანია, რომ ბოლო ორი გამოყენების სცენარი კარგად იცოდეთ, იმიტომ რომ ისინი ხშირად შეგხვდებათ Clojure-ს პროგრამებში. Clojure/ცვლადების და ფუნქციების გამოცხადება defგლობალური ცვლადის განსაზღვრისთვის გამოიყენება def ფორმა: user=> (def x 5) #'user/x user=> x 5 user=> (+ 5 x) 10 user=> (def my-list '(1 2 3)) #'user/my-list user=> my-list (1 2 3) user=> (last my-list) 3 როდესაც ცვლადი იქმნება ხდება შემდეგი რამ. ის რასაც def აბრუნებს არის var, რომელიც არის ობიეტქი, რომელსაც აქვს მნიშვნელობა, მაგალითად 5. აგრეთვე იქმნება სიმბოლო, რომელიც ებმება ამ var-ს. defnფუნქციები შეიძლება შეიქმნას defn-ის გამოყენებით: user=> (defn election-year? [year] (zero? (rem year 4))) #'user/election-year? user=> (election-year? 2007) false user=> (election-year? 2008) true ფუნქცია არის ობიექტის ნაირსახეობა, რომლის გამოძახება შეიძლება. პირვალი არგუმენტი defn-ში არის ფუნქციის სახელი, რომელიც იქნება სიმბოლო, მიბმული ამ ფუნქციაზე. მეორე არგუმენტი არის ფუნქციის არგუმენტების სია. არგუმენტების სია ყოველთვის ვექტორით გამოისახება. defn-ის დარჩენილი არგუმენტები შეიძლება იყოს ერთი ან რამდენიმე გამოსახულება. ბოლო გამოსახულების შედეგი არის ფუნქციის დასაბრუნებელი მნიშვნელობა. fn-ის გამოყენებაანონიმური ფუნქცია შეიძლება შეიქმნას fn-ის გამოყენებით: user=> (fn [x] (+ x 1)) user.eval__2384$fn__2386@c4b579 user=> ((fn [x] (+ x 1)) 9) 10 რადგანაც ფუნქციები უბრალოდ ობიექტებია, ისინი შეიძლება სიმბოლოს მიებას (მიენიჭოს ცვლადს): user=> (def plus-one (fn [x] (+ x 1))) #'user/plus-one user=> (plus-one 9) 10 ფორმა defn სინამდვილეში არის მაკროსი, რომელსაც თავისი შიგთავსი გადაჰყვანს def + fn კომბინაციაში. doc ფორმათითქმის ყველა ფორმას Clojure-ში აქვს ჩადგმული დოკუმნეტაცია. თუ გინდათ სწრაფად გაიგოთ მეტი ფორმის შესახებ ინფორმაცია, გადაეცით ფორმის სახელი doc ფორმში: user=> (doc first) ------------------------- clojure/first ([coll]) Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil. nil ფუნქციის დოკუმენტირებაარსებობს ფუნქციის დოკუმენტირების რამოდენიმე გზე. აი უმარტივესი: user=> (defn plus-one "Returns a number one greater than x" [x] (+ x 1)) #'user/plus-one user=> (doc plus-one) ------------------------- user/plus-one ([x]) Returns a number one greater than x nil აი მეორე საშუალებაც: user=> (defn plus-one {:doc "Returns a number one greater than x"} [x] (+ x 1)) #'user/plus-one user=> (doc plus-one) ------------------------- user/plus-one ([x]) Returns a number one greater than x nilClojure/სპეციალური ფორმები< Clojure Clojure-ს აქვს რამდენიმე ჩადგმული ფორმა, რომლებსაც ერთობლიობაში სპეციალურ ფორმებს უწოდებენ. ამ თავში ჩვენ ვიხილავთ ძირითად სპეციალურ ფორმებ, აგრეთვე განვიხილავთ Clojure-ში შესაძლებელი დამატებითი გამოსახულების ტიპებს. str ფორმაstr ფორმა ორი ან მეტი მნიშვნელობის კონკატენაციისთვის გამოიყენება, რომელსაც ეს მნიშვნელობები საჭიროების შემთხვევაში ტექსტში გადაყავს (აკონვერტირებს): user=> (str "Hello," " world!") "Hello, world!" user=> (str 5) "5" user=> (str "Value: " 5) "Value: 5" if ფორმაif ფორმა იდენტურია if გამოსახულება C-ს მსგავს ენაში. user=> (if true "yes") "yes" user=> (if false "yes") nil user=> (if false "yes" "no") "no" user=> (if nil "yes" "no") "no" user=> (if "" true) true user=> (if 0 true) true user=> (if true "yes" "no") "yes" user=> (if (= 1 1) "yes" "no") "yes" user=> (if (= 1 1) (+ 2 3) (+ 5 5)) 5 user=> (if (= 1 2) (+ 2 3) (+ 5 5)) 10 თუ პირველი არგუმენტი, შეფასების და კონვერტირების შემდეგ, არის true, მაშინ გამოსახულება აბრუნებს მეორე არგუმენტს, წინააღმდეგ შემთხვევაში, მესამე არგუმენტი ბრუნდება. ბოლო, მესამე, არგუმენტი არააუცილებელია. Clojure-ში, როდესაც მნიშვნელობა კონვერტირდება, ის ყოველთვის არის true, თუ ის არ არის false ან nil. if ფორმა ძალიან წააგავს ? ოპერატორის მოქმედებას C-ს მსგავს ენებში: v = true ? 1 : 0 do ფორმაdo ფორმა გამოიყენება რამოდენიმე ოპერაციის თანმიმდევრობით შესასრულებლად. ფუნქციონალურ პროგრამირებაში ჩვეულებრივად გამოსახულებები შედიან სხვა გამოსახულების შემადგენლობაში ან შეიცავენ სხვა გამოსახულებებს, ასე რომ არ არის საჭიროება ერთი მეორეს მიყოლებით ოპერაციების შესრულების. კარგია, როდესაც გამოსახულება აბრუნებს მნიშვნელობას, რომელსაც შემდეგ გამოიყენებს შემცველი გამოსახულება. თუმცა არის შემთხვევები, როდესაც გამოსახულების დაბრუნებული მნიშვნელობა არ გამოიყენება. თუ ასეთი გამოსახულება მაინც რამე სასარგებლოს აკეთებს, ამბობენ, რომ მას აქვსგვერდითი ეფექტი. მაგალითისთვის, ჩაწერა სტანდარტულ გამოსასვლელზე ან ფაილში ან მონაცემთა ბაზაში, ყველა არის გვერდითი ეფექტების მაგალითი. Clojure-ში გვაქვს println ფორმა, სტანდარტულ გამოსავალზე ჩასაწერად. თუ გვინდა რომ println გამოვიყენოთ ისეთი გამოსახულების შიგნით, რომლის მნიშვნელობის გამოყენებას შემდეგ ვაპირებთ, ჩვენ ის უნდა ჩავდგათ do გამოსახულებაში: user=> (do (println "Hello.") (+ 2 2)) Hello. 4 user=> (do (println "Hello.") (println "Hello again.") (+ 2 2)) Hello. Hello again. 4 do ოპერაცია ასრულებს ყოველ გამოსახულებას თანმიმდევრობით და აბრუნებს ბოლო გამოსახულების მნიშვნელობას. do არ არის ერთადერთი, რომელიც გაძლევთ საშუალებას რამოდენიმე ოპერაცია თანმიმდევრობით შეასრულოთ. let, defn და fn ყველა იძლევა საშუალებას გააკეთოთ იგივე. ერთი რამ, რასაც უნდა მიეჩვიოთ, არის ის, რომ Clojure ფუნქციონალური ენაა. ყველა გამოსახულება Clojure-ში აბრუნებს მნიშვნელობას. ხშირად, ერთადერთი Clojure გამოსახულებამ შესაძლოა დაიკავოს რამოდენიმე ხაზი, სადაც C-ს მსგავსი პროგრამისტი დაწერდა იგივე ლოგიკას როგორც კოდის ბლოკს, შემდგარს რამოდენიმე გამოყოფილი გამოსახულებიდან. გამოყოფილი გამოსახულებები შესაძლოა ანიჭებდეს მნიშვნელობას ცვლადს, რომლიც შემდგომ გამოსახულებაში გამოიყენება. ფუნქციონალურ ენებში დაწერილი პროგრამებს აქვთ უფრო დიდი გამოსახულებები გაშლილი რამოდენიმე ხაზად, და არა რამოდენიმე ბლოკი დაყოფილი მცირე გამოსახულებებად.ასეთმა სტიმლმა შესაძლოა წაგართვათ დრო, სანამ მიეჩვევით, თუმცა რომ ისწავლით, ახალი სტილი ისეთივე ადვილია, როგორც ძველი. არის რამოდენიმე უპირატესობა ასე წეროთ თქვენი პროგრამები. when ფორმაwhen ფორმა გავს if ფორმას. განსხვავება ისაა რომ არა გვაქვს "else" პორობა, და შესაძლებელია რამოდენიმე გამოსახულების შესრულება თუ პირობა "ჭეშმარიტებაა". user=> (when nil "Should return 'nil'") nil user=> (when false "Should return 'nil'") nil user=> (when true "Yes") "Yes" user=> (when true 1) 1 user=> (when true 1 2 3) 3 user=> (when true (println "Hello, world") "Yes") Hello, world "Yes" user=> (when (= 5 (inc 4)) "Yes") "Yes" let ფორმაlet ოპერატორი გამოიყენება მნიშვნელობის განსაზღვრისათვის და ამ მნიშვნელობის გამოსაყენებლად შემადგენელ ოპერაციაში. user=> (let [x 2] (+ x 8)) 10 user=> (let [x 2 y 8] (+ x y)) 10 user=> (let [x 2 y 8] (= (+ x y) 10)) true user=> (let [x 3] (+ (* x x) 1)) 10 user=> (let [color "Red"] (str "Color is: " color)) "Color is: Red" user=> (let [color "Red" phrase (str "Color is: " color)] (str "Clojure says: " phrase)) "Clojure says: Color is: Red" let ფორმა ქმნის დროებით var-ს (x და y ამ შემთხვევაში), რომლის გამოყენება შეიძლება მხოლოდ let გამოსახულების შიგნით. ვექტორი გამოიყენება ამ var-ის და მისი მნიშვნელობის განსაზღვრისთვის, ვექტორი აგრეთვე გამოიყენება სხვა Clojure ფორმების მიერ დროებითი ცვლადების და მათი მნიშვნელობების განსაზღვისათვის. ვექტორი შეიცავს სახელი-მნიშვნელობის წყვილებს. Clojure/ინტეგრაცია ჯავასთან< Clojure Clojure-ს აქვს საშუელაბე გამოიყენოს ჯავას ობიექტები და პრიმიტივები. ამის ცოდნა აუცილებელია რთული პროგრამების დასაწერად. მოდით დავიწყოთ ჯავას java.util.Date ობიექტის შექმნით: user=> (new java.util.Date) Mon May 26 10:25:25 PDT 2008 Clojure ქმნის java.util.Date ობიექტს, შემდეგ იძახებს მის toString() მეთოდს, ამ ობიექტის ვიზუალურად წარმოდგენისთვის. ობიექტის კონსტრუქტორში არგუმენტების გადასაცემად, უბრალოდ ჩართეთ ისინი new გამოძახებაში: user=> (new StringBuffer "This is the initial value") This is the initial value ობიექტის მეთოდის გამოძახებისთვის გამოიყენეთ წერტილის (.) ფორმა: user=> (. (new java.util.Date) (toString)) "Mon May 26 11:12:15 PDT 2008" წერტილის ფორმა იყენებს წერტილის სიმბოლოს (.), როგორც ოპერატორს. მეორე არგუმენტია ობიექტი, რომლის მეთოდი უნდა გამოვიძახოთ. მესამე არგუემნტი არის სია, რომელიც შეიცავს მეთოდის სახელს და, თუ საჭიროა, მეთოდის არგუმენტებს: user=> (. (new java.util.HashMap) (containsKey "key")) false სტატიკური მეთოდები შესაძლებელია იგივე გზით გამოვიძახოთ: user=> (. Boolean (valueOf "true")) true კლასის და ეგზემპლარის ველებიც იგივენაირად გამოიძახება: user=> (. Integer MAX_VALUE) 2147483647 user=> (. Character TYPE) char </code> (წარმატებას გისურვებთ, სტანდარტულ ჯავა ბიბლიოთეკაში ეგზემპლარის <code>public</code> ველის პოვნაში :) განსხვავება აქ ისაა, რომ ველის სახელი არ არის მოქცეული ფრჩხილებში. ისევე როგორც ჯავა პროგრამაში, Clojure გაძლევთ საშუალებას კლასების იმპორტირების მოცემულ კონტექსტში, ასე რომ კლასის გამოძახებისას არ იქნება საჭირო მათი სრული სახელის დაწერა: <source lang="bash"> user=> (import '(java.io FileReader)) nil user=> (new FileReader "source.txt") java.io.FileReader@f784d7 იგივე კოდის შემოკლებული ვერსიაც არსებობს: user=> (import '(java.io FileReader)) nil user=> (FileReader. "source.txt") java.io.FileReader@f784d7 ერთი პაკეტიდან რამოდენიმე კლასის იმპორტირება ასე ხდება: user=> (import '(java.io File FileReader)) nil ზედა მაგალითში მოხდა როგორც File, ასევე FileReader კლასების იმპორტირება. თუ კლასები განსხვავებულ პაკეტებშია, გამოიყენეთ ასეთი სინტაქსი: user=> (import '(java.io File) '(java.util HashMap)) nil ან შეგიძლიათ ორი განცალკევებული import გამოსახულების გამოყენება: user=> (import '(java.io File)) nil user=> (import '(java.util HashMap)) nilClojure/ციკლები და იტერაციები< Clojure ქვემოთ ნაჩვენებია სამი ხერხი, თუ როგორ უნდა გავიაროთ ციკლი ინდექსით 0-დან 4-მდე (5 იტერაცია): user=> (loop [i 0] (when (< i 5) (println i) (recur (inc i)))) 0 1 2 3 4 nil user=> (dorun (for [i (range 0 5)] (println i))) 0 1 2 3 4 nil user=> (doseq i (range 0 5) (println i)) 0 1 2 3 4 nil პრიველი მაგალითი იყენებს loop ფორმას, რომელიც უზრუნველყოფს მაქსიმალურ მოქნილობას, თუმცა მოითხოვს ბევრ წერას. მეორე და მესამე მაგალითები არის თანმიმდევრობაზე იტერირების მაგალითები, რომელიც ციკლკის უფრო ხშირი მაგალითია. dorun და doseq გამოძახება ზღუდავს შემადგენელი ოპეტატორების მიერ მნიშვნელობის დაბრუნების შესაძლებლობას. მოდით შევხედოთ loop ფორმას უფრო ახლოდან: user=> (loop [i 0] (when (< i 5) (println "i:" i) (recur (inc i)))) i: 0 i: 1 i: 2 i: 3 i: 4 nil ამ მაგალითში დროებითი სიმბოლო i მიბმულია მნიშვნელობაზე 0. when გამოსახულება უყურებს, ეს მნიშვნელობა არის თუ არა 5-ზე ნაკლები. თუ ტესტი წარმატებულია, შიდა ორი გამოსახულება სრულდება. println გამოსახულება ბეჭდავს i-ს მნიშვნელობას. შემდეგ, recur სრულდება, რომელიც ავალებს ციკლს შესრულდეს კიდევ ერთხელ, i-ს ახალი მნიშვნელობით. (inc i) არის (+ i 1)-ს შემოკლება. recur-ის გარეშე, loop გამოსახულება ზუსტად ისევე იქცევა, როგორც შესაბამისი let გამოსახულება. Clojure/თანმიმდევრობები< Clojure თანმიმდევრობები (sequences) არსებითად არიას იდიომური Clojure პროგრამირების ბირთვი. თანმიმდევრობების და მათზე მომუშავე ფორმების გაგებით, თქვენ გადალახავთ ყველაზე რთულ ნაწილს, რომელიც საჭიროა სერიოზული Clojure პროგრამის წერაში. ერთი შეხედვით თანმიმდევრობები ისევე გამოიყურება, როგორც სხვა მონაცემთა სტრუქტურები. თუმცა, თანმიმდევრობა არ არის მონაცემთა სტრუქტურა. ის ინტერფეისია, ან ხედი, მონაცემთა სტრუქტურაში. თანმიმდევრობა შეიძლება გამოყვანილ იყოს კოლექციიდან. დამოკიდებულება კოლექციასა და თანმიმდევრობას შორის წააგავს დამოკიდებულებას მონამცემთა ბაზის ცხრილს და მონაცემთა ბაზის ხედს (view) შორის. Clojure-ს ოფიციალურ ვებ გვერდზე არის თანმიმდერობის შესანიშნავი განმარტება. მოდით, მივიღოთ თანმიმდევრობა ვექტორიდან: user=> (seq [1 2 3]) (1 2 3) ამ კოდს ვექტორი უბრალოდ სიაში კი არ გადაჰყავს. ის ქმნის ვექტორის თანმიმდევრობას. REPL (Read, Evaluate, Print, Loop), როდესაც ცდილობს ეკრანზე გამოიყვანას, თანმიმდევრობას სიის სახით გვიჩვენებს. ერთ-ერთი საშუალება REPL-ს აუკრძალოთ თანმიმდევრობის სიის სახით წარმოადგინოს, არის მოვაქციოთ ის სხვა გამოსახულებაში, რომელიც არ ცვლის თანმიმდევრობას. მაგალითად, გამოვიძახოთ მეთოდი ამ თანმიმდევრობაზე. ავიღოთ, მაგალითისთვის, getClass() მეთოდი: user=> (.getClass (seq [1 2 3])) clojure.lang.APersistentVector$Seq ის რაც დაბრუნდა არის APersistentVector$Seq, რაც არის ვექტორის მიმდევრობის კლასი. Clojure-ს ყველა ჩადგმულ სტრუქტურად აქვს მეთოდი თანმიმდევრობის მისაღებად. თანმიმდევრობის ინტერფეისი ფორმალურად არის clojure.lang.iSeq, ან უბრალოდ iSeq. firstგამოიყენეთ first, რომ მიიღოთ თანმიმდევრობის პირველი ელემენტი: user=> (first (seq [1 2 3])) 1 first-ს აგრეთვე შეუძლია არგუმენტად მიიღოს უშუალოდ ვექტორი, და არაცხადად გარდაქმნას ის თანმიმდევრობად: user=> (first [1 2 3]) 1 user=> (first ["a" "b" "c"]) "a" user=> (first '("A" "B" "C")) "A" user=> (first '(:a :b :c)) :a თანმიმდევრობის უმეტესი ფორმა ამ არაცხად კონვერტაციას აკეთებს, ასე რომ შეგიძლიათ გადასცეთ მათ ნებისმიერი კოლექცია რომელიც უზრუნველყოფსiSeq ინტერფეისს, რაც მოიცას Clojure-ს ყველა ჩადგმულ კოლექციის ტიპს. restrest გვაძლევს თანმიმდევრობას, რომელიც შეიცაცს საწყისი თანმიმდევრობის ყველა წევრს, გარდა პირველისა. user=> (rest [1 2 3]) (2 3) user=> (rest ["a" "b" "c"]) ("b" "c") user=> (rest '("A" "B" "C")) ("B" "C") user=> (rest [:a :b :c]) (:b :c) გაითვალისწინეთ, რომ არანაირი ახალი მონაცემთა სტრუქტურა არ იქმნება. rest მხოლოდ ქმნის ლოგიკურ სიას (თანმიმდევრობას). მომხმარებელზეა დამოკიდებული შექმნის თუ არა ის აქედან მონაცემთა სტრუქტურას. ზედა მაგალითებში, გამომძახებელია REPL, რომელიც ცდილობს თანმიმდევრობის სიაში გადაყვანას, რომ გამოიტანოს რამე გასაგები ეკრანზე. გამოთვლის დროს, კომპიუტერის რესურსების ხარჯვის მხრივ, თანმიმდევრობის შექმნა მეტად ეკონომიურია. conscons ქმნის ახალ თანმიმდევრობას პირველი არგუმენტის დამატებით მეორე არგუემნტის კოლექციაში. user=> (cons 1 [2 3]) (1 2 3) user=> (cons :a [:b :c]) (:a :b :c) აქაც იგივეა, არანაირი ახალი მონაცემთა სტრუქტურა არ იქმნება cons-ის მიერ. შედგებილი თანმიმდევრობა შინაგანად შედგება მხოლოდ პირველი და მეორე არგუმენტებზე რეფერენსებისგან (pointer). თუმცა მომხმარებლისთვის ისე ჩანს თითქოს ეს ერთიანი თანმიმდევრობაა.
×