بعضی وقت ها که وب گردی میکنم عبارت clojure رو با هوش مصنوعی خیلی میبینم . حتی در خیلی از آگهی های استخدامی دیدم که برنامه نویس clojure برای هوش مصنوعی خواستن و در خود ایرانم دو تا آگهی دیدم که شرکت های مالی دنبال برنامه نویس clojure بودن . علتش چیه ؟ آیا این زبان در زمینه هوش مصنوعی قابلیتهای قدرتمندی داره ؟ اگر داره علتش چیه ؟
لیسپ در تاریخ برنامه نویسی برای هوش مصنوعی ساخته شده و کلوژر هم از خانواده لیسپ هستش
دلیلی که لیسپ و از هر زبان دیگه ای متفاوت میکنه homoiconicity هستش
در لیسپ هر قسمت کد داده هست و برعکس و در نتیجه میشه در لیسپ ماکرو های نوشت که خود زبان و بصورت دینامیک تغییر میدهند که این در دامنه هوش مصنوعی کاربرد داره
اما در بازار کار امروز با machine learning و deep learning این تغییر دینامیک برنامه توسط مدل های machine learning انجام میشه و نیاز به تغییر خود زبان میزبان به مقدار گذشته نیست
امروزه پایتان زبان هوش مصنوعی شده
اصلاً اصطلاح “هوش مصنوعی” ابداع خود John McCarthy بود. زبان clojure هم که یکی از گویش های lisp محسوب میشه. پس کاملاً طبیعیه که ازش تو زمینۀ هوش مصنوعی زیاد استفاده بشه…
ولی به نظر من دلیل قدرت اصلی lisp (که باعث کاربردش تو هوش مصنوعی هم میشه) اینه که متکیه به حساب لاندا. اون چیزی که واقعاً شگفت انگیزه، lisp یا زبانهای برنامه نویسی مشابه دیگه نیستن، بلکه حساب لاندا ست. Haskell Curry معتقد بود زیرساخت تمام زبانهای طبیعی حساب لاندا ست. بعضی از ریاضیدانها معتقدن حساب لاندا در واقع همون زبان تفکره. حداقل اثبات شده که تمام ریاضیات و استدلالها رو میشه به وسیلۀ حساب لاندا (با قواعد واقعاً سادش) به طور خیلی دقیق بیان کرد.
این talk بطور مفصل در مورد تاریخ منطق و پیدایش lambda calculus صحبت میکنه
زبان lisp و گویشهاش، یه کم عجیب غریب نوشته میشن. منظورم سینتکس زبانه.
علت وجود اینهمه پرانتز، جنبهی ظاهری نیست، John McCarthy از این روش استفاده کرد برای اینکه سینتکس نوشتن کدهای زبان، مثل سینتکس نوشتن دیتاها باشه. (Code is data که توی کلوژر خیلی میشنویم)
این باعث شد قویترین Meta Programming ممکن رو داشته باشه. با زبانهای دیگه هم میشه meta programming انجام داد، ولی فقط اداشو در میارن!
دهههای ۷۰ و ۸۰ میلادی، اوج زمان متاپروگرامینگ بود. (نه صرفا با لیسپ) شرکتها با این روش، کد نویسیشون رو کمتر میکردن. اگه اشتباه نکنم، IBM برای برنامه نویسی تراشههاش ازش استفاده میکرد (کدهای اسمبلی generate میکرد). و این مساله که لیسپ خیلی توی متاپروگرامینگ قوی بوده، باعث معروف شدنش شده.
متاپروگرامینگ دو مدله. یا با یه زبان، کدهای یه زبان دیگه رو میسازیم، یا با یه زبان کدهای همین زبان رو میسازیم.
حالت اول رو تقریبا با هر زبان برنامه نویسی میشه انجام داد ولی حالت دوم، نیاز به قابلیتهای بیشتری داره. بهترین حالت هم code is data بودنه. ما با function خودمون یه دیتایی میسازیم که اگه توسط کامپیوتر اجرا بشه، واقعا یه کاری انجام میده (فقط دیتا نیست. عملگر هم هست)
زبان لیسپ، به عنوان یکی از قدیمیترین زبانها (دومین زبان سطح بالا، ۳۷سال قدیمیتر از C) بنیانگذار تعاریف زیادی بوده. یکیشون REPL هست. (Read, Evaluate, Print, Loop)
روش کارش هم که مشخصه. کدهایی که مینویسیم رو از این ۴مرحله میگذرونه:
۱. بخون
۲. اجرا کن
۳. نتیجه رو پرینت کن
۴. برگرد به ۱
با کنار هم گذاشتن code is data و repl، میتونیم به سیستمی برسیم که یه تابع، یه کدی میسازه و میفرسته به مرحلهی اجرا.
این خیلی با closure فرق میکنه. (که یه تابع، یه تابع دیگه رو return کنه) در اینجا ما یه کد رو میسازیم.
توضیحش یه کم سخته، با توجه به اینکه خودم توی این زمینه حرفهای نیستم و با توجه به اینکه نمیتونم با مثال توضیح بدم (میتونم macro بنویسم، ولی توضیح اینکه هر قسمتش چیکار میکنه، خودش یه فصل از یه کتابه)
خلاصه اینکه لیسپ به ما اجازه میده کد بسازیم و هیچ فرقی بین کدهایی که ما نوشتیم و کدهای خودش وجود نداره. از نظر اولیت و قدرت و سرعت و هرچیز دیگهای.
و به ما اجازه میده توابعی بسازیم که کلا سینتکسشون با کل زبان فرق داره. (یه چیز invalid بنویسیم که واقعا کار کنه) نمونش threading macro های کلوژر.
و در کل به ما اجازه میده کدی بسازیم که کد بسازه. نرمافزاری که با توجه به شرایط محیط (مثلا دیتای دیتابیس)، کد متفاوتی رو generate کنه و اون کد رو اجرا کنه.
این چیزیه که باعث شد lisp خیلی توی meta programming و AI مطرح بشه.
اما الآن کسی از این روشها استفاده نمیکنه. برنامه نویسها تنبل شدن و به machine learning رو آوردن.
یه دیتاست خیلی بزرگ جمع میکنن، میریزن توی یه کدی که خودشونم نمیدونن چیه (لایبرری و فریموورک زیاد وجود داره برای اینکار) و بعد از چند ساعت پردازش، یه خروجی میگیرن. که اون خروجی مثلا 99.95درصد مواقع درست کار میکنه. (خیلیوقتا از انسان دقیقتره)
اگه بخوام با رسم شکل توضیح بدم:
یه مقدار خیلی زیاد دیتا جمع میکنن، مثلا میرن به ۱۰۰۰۰۰ نفر یه سری برگهی A4 میدن. میگن اعداد ۰ تا ۹ رو در جای علامتگذاری شده بنویسید. مثلا هر نفر ۱۰ تا از این برگهها رو پر میکنه.
بعد این عکسها رو اسکن میکنن و اعداد رو برش میزنن و میریزن توی یه دیتاست با یه فورمتی که برای کارشون مناسبتره.
اون دیتاست حاوی یه عالمه عکسه که هرکدومشون مشخصه که کدوم عدده. یعنی ما میدونیم این عکس محتوی چه چیزیه. (چون خودمون اسکن کردیم و برش زدیم)
یه نرمافزار deep learning میسازیم (بین ۱۰ تا ۵۰ خط کد پایتون) و دیتاست رو بهش میدن.
کدشون (در بطن کار) یه سری if و else جنریت میکنه. مثلا اینطوری که اگه فلان پیکسل سیاه بود و فلان پیکسل سفید بود، این عدد یک هست. (خیلی مسخرهست ولی واقعا فقط یه کم پیچیدهتر از چیزیه که گفتم)
در کل هوش مصنوعی در دنیای امروزی، شده یه سری if و else که کامپیوتر زحمت ساختشو میکشه و تمام کاری که برنامه نویس انجام میده، اینه که برای بهبود نتیجهی این شبکههای عصبی، یه سری preprocess روی دیتاها انجام میده. (کار بی ارزشی نیست. اصلا هم راحت نیست)
مثلا عکس رو پردازش تصویر میکنیم که ببینیم اگه ۲تا دایره توی عکس هست، به احتمال زیاد عدد 8 هست. و در کنار دیتای پیکسلها، نتیجهی پردازش خودمون رو هم به شبکه میدیم. (اینطوری دقت کار خیلی بالاتر میره)
یا اینکه یه سری فیلتر و افکت روی عکسها ایجاد کنن که تعداد عکسهای دیتاست بیشتر بشه. مثلا از هر عکس یه ورژن با کنتراست بیشتر و یه ورژن با کنتراست کمتر و یه ورژن که یه کم چرخیده باشه میسازن.
بنابر این با سام عزیز موافقم که:
امروزه pyhon زبان هوش مصنوعی به حساب میاد.
ولی یه حس درونی بهم میگه اینکار اشتباهه. باید برگردیم به روشهای قدیمی گذشته. یه چیزی بهم میگه روشهای امروزی منطقی نیستن. هنوز نمیدونم چطوری، ولی باید راه درست رو توی رهنمودهای آقامون McCarthy پیدا کنیم
ویدیوی معرکهای بود!
Mast of you use programming languages that are invented!
So this is my invitation to you, to use programming languages that are discovered.
اگه کسی میدونه چطوری میشه T-shirt یارو رو خرید، به منم بگه
لازم اضافه کنم Philip Wadler یکی از برنامه نویس های اصلی زبان هسکل هستش
خیلی کامل و مفصل توضیح دادی دستت درد نکنه استفاده کردم ، راستی clojure تویه وب چه نقاط ضعف و قوتی داره ؟ کجاهاش لذت بخش و کجاهاش اعصاب خراب کنه ؟ کدوم فریمورکهای وبش خوبترن ؟
زبان هسکل رو تو فروم الکسیر خیلی دیدم و اکثرا خورههای برنامهنویسی و کله گندهها در موردش باهم بحث میکنند و سن و سواد من بهش قد نمیده و اتفاقا تو یکی از همون بحثها خوندم که شرکتهای نرم افزاری که برا هواپیما و… کد میزنن علاقه عجیبی به Lisp دارن
نقاط ضعف سراغ ندارم.
به شخصه پایتون رو گذاشتم کنار و دارم با Clojure کار میکنم. هم برای back-end و هم front-end که clojure-script زحتمشو میکشه.
استک وب پیشنهادی سمیر عزیز.
البته بحثهای دیگهای توی تاپیکهای متفرقه شکل گرفت که به نتایج بیشتری رسید:
من برای back-end از pedestal استفاده میکنم، برای دیتابیس java.jdbc
در front-end هم re-agent یه لایبرریه برای کار با react (خیلی بهتر از خود react هست و حتی راندمانش بالاتر از اینه که با js و react کد بزنیم) و re-frame (که خودش از re-agent استفاده میکنه و با معماری مهندسیش، ساخت SPAها رو خیلی راحت میکنه) در کنار اینا figwheel خیلی به ساده شدن ساخت front-end کمک میکنه، این ویدیو نشون میده برنامه نویسی واقعا باید چه شکلی باشه!) و برای دیباگ، احتمالا هیچ ابزاری در هیچ زبان و فریموورکی بهتر از 10x نیست. (فقط برای re-frame ساخته شده. جای دیگه نمیشه ازش استفاده کرد)
جا داره بگم «کاش سازندهی re-frame همونقدر که کد زدنش خوب بود، داکیومنت نوشتنش هم خوب بود.» خیلی پیچیده توضیح داده. مخصوصا توی walk through با توجه به کد پروژه که هیچچیز سر جاش نیست و همهی کد رو توی یه namespace نوشته.
در تمام زمینه ها یا فقط وب ؟
در کل این زبان clojure کجاها خوب میدرخشه ؟ کجاها تونسته راه باز کنه ؟ تو بیگ دیتا و… چقدر تا scala شدن فاصله داره ؟
در مورد بیگ دیتا و اپلکیشن های غیر وب چه جوریه ؟؟؟
من دو سه ساعتی به کدهای clojure نگاه کردم برخلاف ظاهرا ترسناک خیلی آسونه برعکس scala که اولش خوبه اما درگیر کار میشی تازه میفهمی از این زبون هیچی نفهمیدی !
یکی هم من نمیدونم درست فهمیدم یا نه اما کدهای clojure بنظر من خیلی خواناتر هستند.
****** راستی concurrency در Clojure چه جوریه ؟؟؟ اگر دوس داشته باشی ممنون میشم یه message passing ساده کدش رو بنویسی .
یه ویدیوی دیگه هم هست از سازندهی fighweel. صحبتهاش توی یه کنفرانسه.
خوب من کاملا جایگزینش نکردم با پایتون و الآن درحال یادگیری هستم و دارم وبکار میکنم. ولی احتمالا یه پروژهی دسکتاپ هم باهاش بزنم. (لایبرری seesaw برای کارهای gui)
زبان کلوژر با توجه به اینکه تبدیل به Bytecode جاوا میشه، میتونه روی هر سختافزاری که یه سیستم عامل نسبتا معقول داره اجرا بشه. از کامپیوتر و سرور تا کتابخوانهای kindle و set top boxها.
با توجه به functional بودن و immutability، به نظر من از جاوا بهتره. (نظر شخصیمه. از جاوا متنفرم. از OOP متنفرم.)
برای زمینههای دیگه مثل big data نظری ندارم. ولی هرجا که java استفاده شده، احتمالا clojure یه جایگزین مناسبه.
به خاطر اینکه نرمافزارهای تحت jvm خیلی طول میکشه تا باز بشن (برای استارت jvm حداقل ۱ ثانیه باید صبر کنیم) پس برای نرمافزارهای تحت ترمینال مناسب نیست. به هیچ عنوان!
کلوژر در نگاه اول ترسناکه، به خاطر همین سینتکس هست که به lisp میگن Secret alien language. (لوگو)
ولی در واقع simpleترین حالت ممکنه. هم از نظر منطق (که طول میکشه آدم بهش عادت کنه) و هم programming at large.
خوانایی کدهای کلوژر بالاست و حجم کدش هم خیلی پایینه (مثل پایتون!)
ولی یه نکتهای هست. اونم اینه که اکثر مواقع باید کدها رو از آخر به اول بخونیم. به خاطر نحوهی نوشتنش و پرانتزها.
یعنی از داخلیترین پرانتز اجرا میشه و یکی یکی میاد به خارجیترین پرانتز. دقیقا همونطوری که اولیت اجرای محاسبات توی ریاضی داریم:
(5 + 3 ) + (7 + (2 + 12) - 1)
(5 + 3 ) + (7 + 14 - 1)
8 + 20
25
با توجه به اینکه دیتا immutable هست و در طول برنامه تغییر نمیکنه، concurrency کاملا safe هست و بخشی از هستهی زبانه، سخت هم نیست. (clojure.core.async)
خوب، از اونجایی که دیتا، immutable هست، روش صحیح و اصلی کد زدن همین massage passing و البته recursion هست. (و GC به بهترین شکل کار خودشو انجام میده)
سادهترین مثال (نمیدونم درست باشه یا نه) multi-arrity functionها هستن. تابعی که میتونه ورودی بگیره یا نگیره! تابعی که میتونه یک یا چند ورودی بگیره.
(defn greet
([] (greet "you"))
([name] (print "Hello" name)))
(greet)
;; => Hello you
(greet "World")
;; => Hello World
این تابع اگه چیزی بهش فرستاده نشه، خط اولش اجرا میشه (و خودشو با یه آرگومان صدا میزنه) اگه چیزی بهش فرستاده بشه، خط دوم.
مثال دیگه:
(defn inc-num [num]
(println num)
(recur (inc num)))
(inc-num 1)
;; => 1
2
3
4
5
...
(برای tail-call میشه از recur استفاده کرد به جای اینکه تابع رو صدا بزنیم)
یا حالت کنترل شدش (که infinite loop نشه):
(defn inc-num [num]
(if (< num 10)
(recur (inc num))
(println num)))
(اگه خروجی if برابر با True باشه، خط اول اجرا میشه وگرنه خط دوم. else نداریم!)
شرط ما «اگر num کوچکتر از 10بود» هست. که توی کلوژر اینطوری نوشته میشه، چون در کلوژر عملگرهای جمع و ضرب و عملگرهای مقایسهای کوچکتر و بزرگتر و مساوی هم function به حساب میان.
کلا توی کلوژر ما ۲تا چیز داریم. یکی code هست و دیگری data که اگه دیتای ما یه شکل خاصی داشته باشه بهش میگیم code. (پیچیده شد ولی منظور همون code is data هست) چیز دیگهای نداریم.
این نکته رو بگم که توی کامیونیتی کلوژر، روش فکری به این صورته که framwork نداشته باشیم. (به خاطر محدودیتهای framwork) و با کنار هم گذاشتن ۴تا لایبرری کارمون رو انجام بدیم.
البته re-frame همونطور که از اسمش پیداست framework به حساب میاد (حداقل از دید سازندش) ولی سادهتر از چیزیه که ما به اسم فریموورک میشناسیم. شاید بتونم بگم مثل flask و bottle در پایتون هست، نه مثل django!
یادمه وقتی زبان گو اومد یکی از سازندههاش توئیت کرده بود که چقدر خوشحاله که زبان گو چیزی به اسم فریم ورک نداره و بعد ریلز رو مسخره کرده بود:laughing: الان کلی فریم ورک برا گو هست.
اقا دستت درد نکنه خیلی زحمت دادم بهت و حسابی استفاده کردم
هسکل آنقدر هم سخت نیست . باهاش یک کم کد کنی راه میوفتی
درود سام عزیز شما برای یکی که میخواد برنامه نویسی فانکشنال رو شروع کنه و خب به جنبه ی ریاضی این پارادایم هم علاقه منده پیشنهاد میکنید لیسپ رو شروع کنه یا هسکل رو؟؟؟
هسکل به نظرم گزینه بهتری اگر تئوری و ریاضیات FP بیشتر میخواهید یاد بگیرید
منابع زیادی برای شروع هسکل موجوده
Get Programming with Haskell
- Learn You A Haskell
- Haskell Programming From First Principles
من اول ولی با سکالا FP یاد گرفتم و بعضی سکالا برای یاد گیری ترجیح میدهند
در مورد اینکه چرا lisp به زبان هوش مصنوعی معروف شده دوستان زحمت کشیدن و توضیحات کاملی دادن. من فقط دوتا نکته رو اضافه کنم.
سام عزیز فرمودند که الان پایتون به عنوان زبان هوش مصنوعی شناخته می شه. به نظر من این فقط بخاطر این هست که استفاده از پایتون آسون هست و برای پردازش دیتا کتابخونه های مناسبی داره. در واقع تو زمان مناسب جای مناسبی بوده. وگرنه فکر نمی کنم بخاطر قابلیت های خود زبان باشه.
در مورد شروع FP هم خیلی پیشنهاد می کنم چند کتاب از زبان های مختلف بخونین. علاوه بر haskell که خیلی پیشنهاد می کنم و سام عزیز هم زحمت لینک کتاب رو کشیدن خیلی کتاب on lisp رو پیشنهاد می کنم http://www.paulgraham.com/onlisp.html
مورد آخر هم اینکه من اصلا سکالا رو برا شروع پیشنهاد نمی کنم. learning curve خیلی خشنی داره. تو تجربه کار قبلیم برنامه نویس هایی رو دیدم که از دنیای oop برای اولین بار وارد FP شدن و بنا به نیاز با سکالا شروع کردن. خیلی بهشون سخت گذشت و خیلی زمان برد تا یه چیزایی یاد بگرین.
دقیقا با نظرتون موافقم
پایتون بیشتر به خاطر راحتی کد و کتابخونه هایی که برای هوش تو این زبان ارایه کردن خودشو نشون داده نه صرفا توانایی ها و فیچرهای زبان
زبان هایی مثل پرولوگ و لیسپ تو بحث هوش مصنوعی بسیار توانمند هستن البته من شخصا لیسپ کار نکردم ولی تو بحث مسئله های طبیعی هوش روی پروژه ای با پرولوگ کار کردم
یه موردیم که از نظرم درست اشاره کردید شروع fp با اسکالا هست مخصوصا برای افرادی که از oop واردش می شن به خاطر فیچرهایی که این زبان داره گیج می شن و طول می کشه تا توجیه بشن چون می شه داخلش روال های مختلف کد رو تعریف کرد و کلا یادگیری زبان اسکالا یکم سخته البته این تغییر رویه از شی گرایی به فانکشنال بیشتر این طرز فکر رو ایجاد می کنه
خیلی ممنون از پاسختون . متاسفانه یا خوشبختانه در اسکالا برای حل مسئله n تا روش وجود داره و یادگیری کلی اسکالا سخته و خیلی زمان میبره که بشه گفت به این زبان مسلطم ! خیلی ممنون میشم توضیح بدید که از کتابخونه های جاوا یا اسکالا در کلوژور چقدر میشه استفاده میکرد ؟ چون من خیلی جاها خوندم که حتی خود spark هم با اینکه میشه در جاوا استفاده کرد اما مشکلات خاص خودشو داره و اگر اشتباه نکنم به این موضوع حتی یکی از برنامه نویسهای توئیترم اشاره کرده بود . در کلوژور آیا ممکنه لازم بشه از کتابخونه هایی مثل akka استفاده کرد یا نه ؟ مثل اسکالا با سرعت نوح کامپایل میشه ؟ اسکالا و جاوا فریم ورکهای زیادی برای وب سرویس و … دارن آیا کلوژور هم این چنینه ؟؟
در کل یک مقایسه کلی بکنید و نقاظ ضعف و قوتش رو بیان کنید لطف بزرگی میکنید ممنون