• 0
محمد سمير

Clojure

سؤال

Clojure

- هي لغة دالية (Functional) و هو توجه أكاديمي حتى وقت قريب حيث أن التوجه الذي يحكم السوق هو توجه اللغات كائنية التوجه(Object Oriented) مثل جافا و C#.

- تواجدت بعض اللغات الدالية منذ وقت طويل مثل Haskell و اللغة القديمة قدم C و هي Lisp و لكن لم يكتب لهم النجاح في عالم الشركات حتى وقت قريب بالرغم من تميز هذه اللغات.

- في الوقت الحالي بدأت اللغات الدالية بالعودة للساحة من جديد في صورة أو أخرى مثل Scala, F#, Clojure, Haskell, scheme, python, ruby مع الاعتراف بأن بعض هذه اللغات يملك قابلية الكتابة بمنهجي الدالية و كائنية التوجه.

- حتى أن اللغات العتيدة في مسألة كائنية التوجه أضيف لها بعض من خصائص اللغات الدالية مثل ما حدث مع C# 4 و ما سيحدث مع Java 7 and 8.

- Clojure هي نكهة من نكهات Lisp و Lisp هي لغة قديمة قوية جميلة لكنها أبداً لم تصبح توجه عام بالنسبة للمبرمجين رغم أنها الاختيار الأول لكتابة برامج الذكاء الاصطناعي و من المبادئ البسيطة ل Lisp و التي ورثتها Clojure عنها هي أن شفرة البرنامج نفسها تعتبر معلومات "Code as Data" و لذلك تحاط جميع أكواد Clojure بأقواس لأن كل جملة من أكواد Clojure تعتبر List.

- سنفترض معرفتك بجافا .. إذن أنت معتاد على كود بهذا الشكل:

myObj.doSomething(anArg);

مع Clojure نفس الكود سيكتب بهذا الشكل:

(do-something my-obj an-arg)

و هذا يدعى prefix notation.

- كما تلاحظ فإن الكود محاط بأقواس (و هذا ربما العيب الوحيد الذي يؤخذ على Clojure و من قبلها Lispلكثرة الأقواس الناتجة من الكتابة).

- مثال آخر على ال prefix notation:

(+ 2 3)

- نلاحظ أن علامة الجمع في بداية الدالة لأنها هي نفسها الدالة و الرقمين بعدها هما معطيات الدالة.

ما الذي ستحصل عليه مع Clojure:

- closures

- List comprehension

- Software Transactional Memory

- Lazy sequence

- Code as Data

- Immutable data structures

- Dynamicity

- Macros

أنواع البيانات في Clojure:

- Arbitrary precision integers - 12345678987654

- Doubles 1.234 , BigDecimals 1.234M

- Ratios - 22/7

- Strings - “fred” , Characters - \a \b \c

- Symbols - fred ethel , Keywords - :fred :ethel

- Booleans - true false , Null – nil

- Regex patterns #”a*b”

:Clojureهيكلة البيانات في

• Lists - singly linked, grow at front

(1 2 3 4 5), (fred ethel lucy), (list 1 2 3)

• Vectors - indexed access, grow at end

[1 2 3 4 5], [fred ethel lucy]

• Maps - key/value associations

{:a 1, :b 2, :c 3}, {1 “ethel” 2 “fred”}

• Sets #{fred ethel lucy}

• Everything Nests

مثال للكود و شكله:

هذا الكود لعمل نافذة بمساحة 300*300 بيكسل مع زر و مربع نص و عنوان.


(import '(javax.swing JFrame JPanel JLabel JButton JTextArea))

(doto (JFrame. "Test")
(.setContentPane (doto (JPanel.)
(.setSize 300 300)
(.add (JLabel. "Label 1"))
(.add (JTextArea. ))
(.add (JButton. "Click"))))
.pack
(.setVisible true)
(.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE))

المراجع:

6

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

23 إجابة على هذا السؤال .

  • 0

هذه هي الأشياء المهمة

- closures

- List comprehension

- Software Transactional Memory

- Lazy sequence

- Code as Data

- Immutable data structures

- Dynamicity

- Macros

هلا أمكنك تقديم نبذة مختصرة عن هذه الأشياء :)

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

من عيني يا علاء.

- First-class functions

مع Clojure يمكن تمرير الدوال كمتغيرات لدوال أخرى.

- Closures

و متعارف عليها أيضاً باسم lambda expression

أبسط تعريف لل closures هو أنها دوال معرفة داخل دوال, الدوال الداخلية تستخدم معطيات (متغيرات) الدالة الأم و تلك الدالة الداخلية (inner/anonymous function) لن يتم تنفيذها إلا عند استدعائها من الدالة الأم.

أقرب صورة لها في جافا هي anonymous inner classes.

- List comprehension

الفكرة باختصار هي إمكانية تنفيذ كود داخل List.

مثال:


[x (range 3), y (range 3), z (range 3)
:when (or (< x y z) (> x y z))]

هذه القائمة نتيجتها:

([0 1 2] [2 1 0])

للمزيد:

http://en.wikipedia.org/wiki/List_comprehension#Clojure

- Macros

الماكرو هو كود يكتبه المبرمج للتحكم و الإضافة لمترجم اللغة, بمعنى أنك تكتب للمترجم كيف يتعامل مع الكود في حالة معينة.

مثال من stackoverflow.com

(defmacro forever [& body] 
`(while true [email protected]))

user=> (forever (print "hi "))
hi hi hi hi hi hi hi hi hi hi hi ....

- Lazy sequence

أو Lazy Evaluation هو عدم الاهتمام بالكود و تنفيذه لحين طلب النتائج, نفترض أنك طلبت infinite loop لكي يتم تنفيذها في برنامجك , ما سيحدث هو أن Clojure سترجع نتيجة ال loop نتيجة فنتيجة بينما في جافا مثلاً قد تحصل على stack overflow.

للاستزادة:

http://en.wikipedia.org/wiki/Lazy_evaluation

- Immutable data structures ~ pure functions ~ no side effect

كل ما سبق يؤدي إلى نفس المعنى و نفس النتيجة, مخرجات الدالة دائماً ما تكون نفسها ما لم تتغير المدخلات أو المعطيات, و الميزة هي تجنب ما يدعى بال Boilerplate code.

- Software Transactional Memory

بصراحة لا أعرف الكثير عن كيفية عمل هذه الميكانيكية, كل ما أعرفه أنه مع هذه الخصائص (STM, Immutable data structure, no side effects) فإن Clojure تعتبر واحدة من أفضل اللغات للتعامل مع ال concurrent programming و ال multi-core CPUs أي أنها من أفضل اللغات للتعامل مع المستقبل.

للاستزادة:

http://clojure.org/concurrent_programming

- Metadata

تسمح Clojure بكتابة metadata و هي تمرير معلومات للمترجم عن البيانات أو الرموز symbols or data annotation, جرب تكتب هذا الكود

(meta print)

الناتج

{:ns #<Namespace clojure.core>, :name print, :file "clojure/core.clj", :line 2845, :arglists ([& more]), :added "1.0", :doc "Prints the object(s) to the output stream that is the current value\n  of *out*.  print and println produce output for human consumption."}

مثال عن كتابة metadata الخاصة بك:


(def v [1 2 3])
(def attributed-v (with-meta v {:source :trusted}))
(:source (meta attributed-v))
-> :trusted
(= v attributed-v)
-> true

للاستزادة في الموضوع ككل:

http://clojure.org/functional_programming

http://en.wikipedia.org/wiki/Clojure

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بيني وبينك لم أستطع فهم الكثير هنا

سأحاول بإذن الله في وقت الإجازة القادمة :)

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

محمد شكل ال functional programming بدأت تستهويك :cool:

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

علاء .. أنا الغلطان بسبب إختصاري المخل في الموضوع.. إن شاء الله يكون في توضيح أكثر مع الأمثلة القادمة.

أحمد.. لأني أبرمج علشان أتسلى و أستمتع بوقتي و أقضي وقت ظريف و أكون منتج يبقى لازم تكون functional :cool:

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

في موضوع جميل للأخ الفاضل عصام تحدث عن أخذ screen shot لسطح المكتب و شرح للمكتبات المستخدمة.

الموضوع هنا : http://www.arabteam2000-forum.com/index.php?showtopic=204329

و هذا هو كود جافا


import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.AWTException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;

public class CaptureScreen {
public static void main(String[] args) {
try {
Robot r = new Robot();
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle surfaceToCapture = new Rectangle(0, 0, (int)screenDimension.getWidth(), (int)screenDimension.getHeight());
BufferedImage capture = r.createScreenCapture(surfaceToCapture);
File imgFile = new File("screenCapture.png");
ImageIO.write(capture, "png", imgFile);
} catch (AWTException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

أفضل طريقة لتعلم لغة جديدة هي بمقارنة الكود الخاص بها بكود لغة أنت على دراية بها, لذلك ارفق لكم كود Clojure المكافئ لكود جافا بالأعلى:


(import '(java.awt AWTException Robot Rectangle Toolkit)
'(java.awt.image BufferedImage)
'(java.io File IOException)
'(javax.imageio ImageIO))
(defn screen-grab [file-name]
"Capture screen shot"
(let [img-type (second (re-find (re-matcher #"\.(\w+)$" file-name)))
capture (.createScreenCapture (Robot.)
(Rectangle. (.getScreenSize (Toolkit/getDefaultToolkit))))
file (File. file-name)]
(ImageIO/write capture img-type file)))

(screen-grab "test.png")

ملاحظات بسيطة للمساعدةفي فهم الكود:

- مثل Java فإن Clojure تستورد مكتبات Java ب import.

- تعريف الدالة يبدأ ب defn و هي إختصار كلمتي define function.

- معطيات الدالة توضع بين أقواس مربعة [ ].

- لأن Clojure مبنية على Lisp و Lisp ككلمة هي اختصار List Processing لذلك تحاط كل جملة من جمل الدالة بأقواس منحنية () مثل المستخدمة مع ال lists و هذا تطبيق مباشر لمبدأ "code as data".

- كلمة let للربط بين تعبير و صيغة تليه , أشبه ما تفعل بأنها تنشئ إختصارات و لا يجوز إعتبار أنها تنشئ متغيرات لأن التعبير المرتبط بإستخدام let لا يمكن تغييره متى أنشئ.

مثال:

(let [x 1])

مثال آخر:

(let [frame (.JFrame "Test")])

تقريباً مثلها مثل:

JFrame frame = JFrame("Test");

باقي الكود مثله مثل جافا باستثناء أننا حصلنا على نوع الملف الذي سنخزن الصورة فيه عن طريق الregular expressions من خلال الاسم الذي أمددنا به الدالة (screen-grab).

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

مممممممممممممممم

كنت أكره lisp عندما تعلمتها أيام الجامعة

ولا أعرف سبباً لهذا

بالمناسبة هل جربت كتابة شيفرات طويلة فيها يا محمد؟

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

حقاً يا علاء لم أكتب شيفرات طويلة عامة فجل إستخدامي للبرمجة scripting و برامج صغيرة لمساعدتي في عملي.

لكن إحقاقاً للحق ففلسفة ليسب و كلوجر من بعدها أن عدد كبير من الدوال الصغيرة أفضل من العكس .. أنت الوحيد القادر على كتابة spaghetti code أو readable code, و فعلاً كود كلوجر المكتوب بحرفية ذو مقروئية عالية عن تجربة من بعض مشاريع github.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

رداً على سؤالك أخي علاء, هذه مقالة جميلة يحكي فيها الكاتب عن تجربته مع Clojure لمدة عام و نجاحها في تلبية متطلباته - المقالة بالإنجليزية.

we have four Clojure projects totaling 14 kloc [by LOC here I mean "any line in a source file incl whitespace and comments"] of src and 16 kloc of tests, so about 30 kloc of Clojure total. The average source file is 172 lines and the longest in the whole code base is 725 lines. I don’t know what the average Java file size is but I’m sure it’s way more. This code base contains a SPARQL algebra representation and printing facility, an in-memory RDF graph library, a database metadata importer, two custom ontology generators, a SQL parser/printer, SPARQL to SQL query optimizer, database query, SPARQL endpoint, command-line tooling, federation engine shell, SPARQL endpoint client, and a nascent RIF rules parser and engine implementation. Fitting all that in 14 kloc seems pretty impressive to me. By comparison the Java code in the ARQ SPARQL AST data structure is 14 kloc.

http://tech.puredanger.com/2010/12/31/a-year-of-clojure/

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

والله يا محمد أنا لم أستطع التأقلم مع اللغات السكربتية بشكل عام

أحس أن عقلي غير قادر على استيعابها بالمطلق

لكن يبدو أن اللغة مهمة جداً لتطبيقات الذكاء الصناعي

هل لديك مجموعة دروس tutorial أو كتاب تنصح به لها

بالمناسبة هل هي تعمل على jvm?

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم و رحمة الله

والله يا محمد أنا لم أستطع التأقلم مع اللغات السكربتية بشكل عام

أحس أن عقلي غير قادر على استيعابها بالمطلق

الحاجة هي أخي الكريم الدافع لتعلم أي شيء, حتى مرحلة التعليم الجامعي نتعلم بمبدأ "just in case" نتعلم الكثير مما قد لانستخدمه, ثم تبدأ الحياة ما بعد الجامعية و يكون التعلم بمبدأ "just in time" نتعلم فقط ما نحتاجه .. لذلك اخلق لنفسك حاجة للغات السكريبتينج تتعلمها بسهولة لأنك حينها مضطر و المضطر يركب الصعب :)

مع كلوجر و مثيلاتها من اللغات يتحدث مستخدميها عن شيء يسمونه "AHaaa moment" يقابلونه مع تعلمها... هل تعرف حين يستعصي عليك شيء ثم تقدر على سبر أغواره فتنطق تلقائياً "أهههااااا" .. إنه الصوت المكافئ ل"وجدتها", لذلك لا يضرك إستعصائها عليك في أول الأمر فستجد الكثير من تلك اللحظات بعد ذلك ... أرجو ألا يكون إسهابي قد أخل بالمعنى.

بالنسبة لكلوجر فهي مبنية لتعمل على JVM مثلها مثل Jython و JRuby و Scala و هناك مشروع لعمل مترجم كلوجر يعمل على .NET و تتميز كلوجر بأنها تتكامل مع جافا بقوة و هناك مقولة لمبرمجها ريتش هيكي " don't fix java where java is good".

نأتي للمهم:

موقع تحميل Incanter و هو السبب الرئيس لتعلمي كلوجر .. سأفرد لهذا البرنامج الرد التالي إن شاء الله لأهميته

http://incanter.org/

http://incanter.org/downloads/

مع Incanter فستحصل على Clojure REPL لتجربة أكوادك

موقع يجمع دروس فيديو لكلوجر - بعضها مجاني و بعضها بمقابل:

http://alexott.net/en/clojure/video.html

http://www.youtube.com/user/briantwill#g/c/AC43CFB134E85266

مقدمة ظريفة جداً من مبرمج جافا عن كلوجر:

http://devblog.factual.com/

wikibooks غني عن التعريف:

http://en.wikibooks.org/wiki/Clojure_Programming

Clojure cheatsheet:

http://clojure.org/cheatsheet

tutorial متكامل يعيبه أنه لا يشمل النسخة الأحدث من كلوجر 1.2:

http://java.ociweb.com/mark/clojure/article.html

بالتوفيق

تم تعديل بواسطه محمد سمير
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

إضافة يامحمد اذا تسمح

كتاب Practical Clojure

http://apress.com/book/view/1430272317

بالإضافة للملفات الرسمية

http://clojure.org/Reference

وهنا clojure-clr

https://github.com/richhickey/clojure-clr

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

إضافة يامحمد اذا تسمح

كتاب Practical Clojure

http://apress.com/book/view/1430272317

بالإضافة للملفات الرسمية

http://clojure.org/Reference

وهنا clojure-clr

https://github.com/richhickey/clojure-clr

تسلم يا أحمد بارك الله فيك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

إكمالاً لإضافة أحمد,

Practical Clojure هو كتاب جميل يلتزم مقاربة الأمثلة البسيطة كطريقة للشرح لغته سهلة و لا يعيبه غير أنه متأخر عن أحدث إصدارات Clojure.

الكتاب الأقدم قليلاً كان (Programming Clojure (Pragmatic Programmers

http://pragprog.com/titles/shcloj/programming-clojure

أقدم و أصعب ويعتمد على الأمثلة المتصلة على طول الكتاب .. يعتبر كتاب متقدم و دسم و يفترض فيك أنك خبير جافا فدائماً ما يقارن ما يشرحه مع جافا

و هناك كتابين منتظر صدورهما خلال الأشهر القادمة:

The Joy of Clojure

http://joyofclojure.com/

http://www.manning.com/fogus/

Clojure in Action

http://www.manning.com/rathore/

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

المشكلة أنه لا يوجد شيء سيجعلني محتاج لها

مالم أعمل في شركة تعمل على هذه اللغة وهناك شيفرة مكتوبة سابقاً وسأضطر للتعديل عليها

أو أضطر للعمل على برنامج مفتوح المصادر مبني عليها

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخي علاء .. فكرت كثيراً في كيفية إقناعك بأهمية كلوجر بالذات و بقية اللغات التفاعلية أو الدالية بصورة عامة, ثم وجدت أني مخطئ إن حاولت, لغات البرمجة ليست إلا أدوات, إن أتقنت أداة و أعانتك تلك الأداة على أداء مهماتك فكفى بها.

لكن هل يمتلك الحرفي في أي حرفة أداة واحدة يؤدي بها كل أعماله؟ من الأفضل له أن يمتلك عدة أدوات في صندوق الأدوات خاصته, و ظني أن كلوجر ستكون إضافة جيدة لصندوق أدواتك.

2

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

حساب n factorial مع كلوجر:

بالعربية تدعى "عاملي س" أو "مضروب س" و هو حاصل ضرب جميع الأعداد الصحيحة الموجبة أقل من أو تساوي س.

س! = س * (س-1) * (س-2) * ....

http://en.wikipedia.org/wiki/Factorial

كالمعتاد سنضع كود جافا أولاً:

public class Factorial
{
// Evaluate n!
public static long factorial( int n )
{
if( n <= 1 ) // base case
return 1;
else
return n * factorial( n - 1 );
}

// Simple test program
public static void main( String [ ] args )
{
for( int i = 1; i <= 10; i++ )
System.out.println( factorial( i ) );
}
}

لأن الناتج long فهو محكوم في الحساب حتى 64 بت فقط و لحساب أرقام أكبر من 64 بت يمكنك إستخدام BigInteger و في هذه الحالة أنت محكوم بسعة الذاكرة فقط.

ماذا عن كلوجر؟

لن تختلف الفكرة كثيراً في كلوجر عن جافا, إليك الكود:


(defn factorial [n]
(if (= n 0)
1
(* n (factorial (– n 1)))))

ممكن كتابة هذا الكود في سطر واحد لكن في هذا الشكل سيكون أسهل في قراءته.

الجديد في هذا المثال سيكون جملة if:

(if (cond) result-if-true result-if-false)

ليس أكثر و لا أقل.

مع الكود بالأعلى ستقابل ب "StackOverFlow" عند أرقام أكبر من سعة ال stack عندك "ربما عند حساب أرقام أكبر من 6000 تقريباً" حيث يوصف هذا الكود بأنه "stack-consuming", يمكن علاج هذه المشكلة باستخدام دالة من دوال كلوجر التي تنتج lazy sequence "تم الحديث عنها في رد سابق" , سنستخدم الدالة range:

(defn factorial [n]
(reduce * (range 1 (inc n))))

كما أن هناك طريقة أخرى باستخدام Tail Recursion مع دالة recur , شرحهم في الرد القادم إن شاء الله.

2

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم و رحمة الله

الأخوة الأفاضل مشرفين و أعضاء, أحب أن أكمل كتابة عن كلوجر و مكتباتها (مواضيع مختلفة) فهل من المحبذ أن أكمل على هذا الموضوع أم أفرق العناوين المختلفة في مواضيع مختلفة؟ و هل من المفضل أن أنقل المواضيع إلى قسم "تقنيات جديدة" أم أبقيها هنا (على اعتبار أن هذا القسم لكل ما يتصل بال JVM)؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم و رحمة الله

الأخوة الأفاضل مشرفين و أعضاء, أحب أن أكمل كتابة عن كلوجر و مكتباتها (مواضيع مختلفة) فهل من المحبذ أن أكمل على هذا الموضوع أم أفرق العناوين المختلفة في مواضيع مختلفة؟ و هل من المفضل أن أنقل المواضيع إلى قسم "تقنيات جديدة" أم أبقيها هنا (على اعتبار أن هذا القسم لكل ما يتصل بال JVM)؟

أخ محمد،

أنا أتابع هذه اللغة منذ فترة ويمكنني أن أتشارك معك بالكتابة بالعربية عنها ان شئت بقدر ما يتاح لي من وقت.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

مرحبا بك أخي .. كم تمنيت أن يهتم بها عدد أكبر من المبرمجين العرب

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم أخ محمد،

لا أعتقد أنها ستنتشر كثيراً لا بين المبرمجين العرب ولا غيرهم. ولكنها لغة رائعة. بالمناسبة لقد وصلت لموضوعك منذ فترة عن طريق رابط على disclojure ولكني لاحظت انك كنت قد كتبته منذ شهور عديدة.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

محمد أعتقد أن قسم الأقسام الجديدة أنسب

دعنا نأخذ فكرة أكبر حول الموضوع

ونفكر فيما إذا كنا سنضيف للمجتمع الجافاوي :) أو سنرى أنها لها استقلاليتها

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .