clojure se-radio.net interview with rich hickey (ترجمه مصاحبه رادیو مهندسی...

31
افزار نرم مهندسی رادیو با کلوژر سازندهکی هی ریچ مصاحبه([email protected]) الدین زین جهانگیر: ترجمه کلوژر، آقای ماهمان م. کنیم صحبتClojure مورد در خواهیم می ما بار این: مارکوس. استکی هی ریچ. بزنید حرف خودتان مورد در اید، ساخته که آنچه مورد در صحبت از قبل لطفا کهنامیک دیسی نوی برنامه زبان یک ام، نوشته را کلوژر و هستمکی هی ریچ من خوب: ریچ اصلیژگی وی چهار شود، می اجرا( نت دات به مربوطی اجرایمحیط)CLR وJVM رویزبانی میVM یک توسط که شده طراحی طوری و است لیسپ بر مبتنی زبان یک دارد،.JVM ند مان دارد میزبان پلتفرم باکی نزدی رابطهبراین بنا شود، و محض توابع وری ناپذی تغییر روی و است( توابع برمبتنی) functional عمدتا. استتمرکز مزمانی هم رویین همچن دارد، تاکید ناپذیر تغییر های داده ساختمانزمان هم برنامه یک م در که اند شده طراحی طوری زبان های جنبهام تم. باشند داشته درستی(semantic) معنای. کرد خواهیمنکاش ک بیشتر آن مورد در بعدا: مارکوس شماره برنامه ایم، داشته لیسپ مورد در ای برنامه قب ما کهند بداندگانن خوان خواهم می صحبت مختصر صورت به لیسپ مقدمات مورد در استمکن م ماانکه همچن. گابریل با۸۴ . کنیم ارایه لیسپ از کاملی معرفیینجا ا نداریم بنا وقت ضیق خاطر بهما ا کنیم،. کنید رجوع۸۴ برنامه به بایست می کلی صورت بهاقل نیستید آشنا لیسپ با اگر. کنید معرفیجمالی ا صورت به را لیسپ اگر است خوبی فکر نظرم به این علیرغم ریچ، به که دارد دیگرسی نوی برنامه زبانهای با تفاوتی چه هستند، چه لیسپ اصلی مبانی. میشود تلقی خاص زبان یک افراداری بسی نظر از آن خاطر

Upload: jahangir-zinedine

Post on 07-Aug-2015

190 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مصاحبه ریچ هیکی سازنده کلوژر با رادیو مهندسی نرم افزار([email protected])ترجمه: جهانگیر زین الدین

مارکوس: این بار ما می خواهیم در مورد Clojure صحبت کنیم. مهمان ما آقای کلوژر،

ریچ هیکی است.لطفا قبل از صحبت در مورد آنچه که ساخته اید، در مورد خودتان حرف بزنید.

ریچ: خوب من ریچ هیکی هستم و کلوژر را نوشته ام، یک زبان برنامه نویسی دینامیک که روی JVM و CLR(محیط اجرایی مربوط به دات نت) اجرا می شود، چهار ویژگی اصلی

دارد، یک زبان مبتنی بر لیسپ است و طوری طراحی شده که توسط یک VM میزبانی .JVM شود، بنابراین رابطه نزدیکی با پلتفرم میزبان دارد مانند

عمدتا functional (مبتنی بر توابع) است و روی تغییر ناپذیری و توابع محض و ساختمان داده های تغییر ناپذیر تاکید دارد، همچنین روی همزمانی متمرکز است.

تمام جنبه های زبان طوری طراحی شده اند که در منت یک برنامه همزمان معنای(semantic) درستی داشته باشند.

مارکوس: بعدا در مورد آن بیشتر کنکاش خواهیم کرد.

می خواهم خوانندگان بدانند که ما قبال برنامه ای در مورد لیسپ داشته ایم، برنامه شماره ۸۴ با گابریل. همچنانکه ما ممکن است در مورد مقدمات لیسپ به صورت مختصر صحبت

کنیم، اما به خاطر ضیق وقت بنا نداریم اینجا معرفی کاملی از لیسپ ارایه کنیم.اگر با لیسپ آشنا نیستید الاقل به صورت کلی می بایست به برنامه ۸۴ رجوع کنید.

ریچ، علیرغم این به نظرم فکر خوبی است اگر لیسپ را به صورت اجمالی معرفی کنید. مبانی اصلی لیسپ چه هستند، چه تفاوتی با زبانهای برنامه نویسی دیگر دارد که به

خاطر آن از نظر بسیاری افراد یک زبان خاص تلقی میشود.

Page 2: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

ریچ: خوب، سوال آخر احتماال بهترین سوال است، بسیاری از چیزها که لیسپ ابداع کرده است در زبان های دیگر نیز به صورت گسترده وجود دارد. فکر می کنم آنچه که لیسپ را

منحصر به فرد می کند، این است که برنامه به صورت ساختمان داده به کامپایلر عرضه

می شود، پس کامپایلر لیسپ منت را کامپایل نمی کند بلکه ساختمان داده ها را کامپایل می کند، و زمانی که شما با لیسپ(کلوژر) برنامه ای می نویسید در واقع با ساختمان

داده ها و از طریق آنها برنامه می نویسید.اگر شما متنی را در فایلی ذخیره می کنید در واقع داده های عینی را ذخیره می کنید.

پس تفاوت این با زبانهایی که برنامه را ترجمه می کنند و از روی آن AST می سازند که

به نوعی یک ساختمان داده است که به کامپایلر عرضه میشود، چیست؟این موضوع خیلی مرتبط است با اینکه آیا آن AST از چیزهایی ساخته شده که برنامه

شما معموال با آن سر و کار دارد، در یک برنامه لیسپ و به طور خاص در کلوژر، داده های عینی چیزهایی هستند که شما به صورت روزمره از انها استفاده می کنید.

map ،vector و list، پس کتابخانه بزرگی برای کار با آنها وجود دارد، آنها کتابخانه های خاصی برای کار با AST نیستند بلکه کتابخانه های معمولی متعلق به زبان هستند، که بدین معنی است که الزم نیست برنامه خاص یا عجیبی برای دستکاری AST بنویسید.

مارکوس: پس برنامه نویسی و فرا-برنامه نویسی(meta programming) هر دو یک

چیز هستند!

ریچ: دقیقا، تفاوتی وجود ندارد، و این بسیار مهم است، اگر شما قبال با کتابخانه ای API کار کرده باشید که شی گرا بوده باشد، می فهمید که دارید یک AST مربوط به

خاص را می خوانید، اما زمانی که کد مربوط به یک ماکرو را در لیسپ یا کلوژر می

خوانید کدهای کامال معمولی برای پردازش دادها هستند.

Page 3: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: خوب شما از چه ساختمان داده های دیگری استفاده کرده اید که پیشتر در

مورد آنها صحبت کردید، چون لیسپ به نظر فقط لیست های تو در تو است، درست است؟

ریچ: این برای لیسپ به صورت سنتی درست است، اما در کلوژر چندین ساختمان داده دیگر وجود دارد که همگی در اولویت باالیی قرار دارند و مانند لیست درجه یک محسوب

.(hash table)که شبیه جداول درهم سازی است map و vector ،می شونددر نحو زبان فرم هایی وجود دارند که بر مبنای همین ساختمان داده ها ساخته شده اند،

گاهی مبتنی بر vector ها و گاهی mapها.

مارکوس: شما می دانید و در برنامه ۸۴ هم آمده که لیسپ زبان جدیدی نیست و یک

رویکرد قدیمی است و در زمینه های خاصی با موفقیت مورد استفاده قرار کرفته است اما هیچگاه یکی از زبانهای اصلی مورد استفاده عموم نبوده است. شما چه فکری می کنید،‌

چرا این اتفاق نیافتاده است؟ و سوال بعدی اینکه چرا شما در سال ۲۰۰۹ یا ۲۰۱۰ لیسپ خودتان را ساختید؟

ریچ: هاها، اینها دو سوال مجزا هستند، من مطمئن نیستم که لیسپ برای استفاده عموم طراحی شده باشد، آن زمان که بوجود آمده برای کاربران ارشد طراحی شده مانند

محققین و افراد بسیار باهوش که سعی می کردند مسایل بسیار سخت را حل کنند و لیسپ کامال اهرم مناسبی برای تالشهای آنها بود. به عنوان یک فرد شما قدرت

باورنکردنی ای به واسطه لیسپ داشتید. ما همه می دانیم که برنامه نویسی در مقیاس بزرگ یک فعالیت اجتماعی است که افراد دیگری هم در آن درگیر هستند، کتابخانه های

برنامه نویسی در آن دخیل هستند و به طور خاص بسیار مهم است که بتوانید با کتابخانه هایی که دیگران به همان زبان یا به زبان دیگری نوشته اند تعامل کنید.

این یکی از زمینه هایی است که لیسپ به طور سنتی در آن خوب عمل نکرده است چون این محدوده ها و رویکردها بیشتر شبیه جزیره اند، جزیره هایی با درختها و مناظر زیبا،

Page 4: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

اما به خوبی به جاهای دیگر دنیا وصل نیستند. عوامل اجتماعی و تاریخی دیگری وجود دارند که مربوط به هوش مصنوعی هستند، مرگ آن در دهه ۸۰ و ۹۰ که با عدم اقبال به

لیسپ همراه شد، اما لیسپ قدرتش را از دست نداد، برای اینکه به سوال دوم شما برسم،

که چرا من امروز اینکار را کرده ام؟ ویژگی دومی که لیسپ دارد هنوز منحصر به فرد است چون برنامه ها همان ساختمان داده ها هستند شما می توانید برنامه هایی بنویسید

که آن برنامه ها به نوبه خود برنامه بنویسند. و جنبه مهم دیگر لیسپ این است که وقتی کامپایلر لیسپ برنامه شما را ارزیابی می کند، به ماکروها که برنامه های کوچک دیگری

هستند اجازه می دهد در حین کامپایل اجرا شوند که بدین معنی است که برنامه های

شما که برنامه می نویسند، می توانند با کامپایلر یکپارچه شوند.

مارکوس: فکر می کنم این یک خاصیت بسیار مهم است، چون چندان سخت نیست که

Eclipse AST API استفاده کند که یک برنامه جاوا تولید کند، برنامه ای نوشت که از ‌شاید به اندازه کلوژر راحت نباشد هر چند این موضوع سلیقه ای است، اما اینکه قادر

باشید آنرا در فرآیند تبدیل یا کامپایل اضافه کنید باعث می شود این کار بسیار بی

دردسر و یکپارچه باشد و این مهم است.

ریچ: درست است، این ویژگی ای را مهیا میکند که موسوم به گسترش پذیری نحو زبان(syntactic extensibility) است که چیز قدرتمندی است و برای برنامه ها مهم

است، همانطور که انتزاع تابع مهم است، ما نمی خواهیم یک چیز را چندین بار بنویسیم،

می خواهیم یکبار بنویسیم و از آنها استفاده مجدد کنیم. الگوهای زیادی در نرم افزار وجود دارد که به درستی توسط آبجکت ها و متدها کپسوله نمی شود، مثال ساده در جاوا بلوک کد try است، الگوهایی که شما مجبورید آنها را مدام تکرار کنید چون ابزاری برای

کپسوله کردن آن ندارید که از آن طریق تکرار را از بین ببرید.

به نظر من این امکان چیز بسیار ارزشمندی است و هنوز ارزش دنبال کردن دارد. کاری که من می خواستم انجام دهم ساخنت لیسپی بود که نکات قوتش پا بر جا باشد اما مشکل

Page 5: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

جزیره بودن آن را حل کند. کلوژر چون یک زبان میزبانی شده است و روی جزییات پیاده سازی نشده است مانند یک ویژگی است و در دسترس است بدین معنی است که به

عنوان یک زبان جدید به تمام کتابخانه های جاوا دسترسی کامل دارد و توان باالیی برای تعامل با برنامه های جاوا دارد و شما بالفاصله از جزیره بودن رها شده اید.

مارکوس: من بعدا به این موضوع بر میگردم اما االن می خواهم مختصر در مورد فرا-

برنامه نویسی(meta programming) صحبت کنم. گسترش پذیری نحو خصیصه ی مهمی است و مقیاس شما برای سنجش قدرت زبانهایی مانند لیسپ بود. اما اگر من

بخواهم نقش وکیل مدافع شیطان را بازی کنم خواهم گفت که اصال لیسپ نحوی ندارد، اگر همه چیز در زبان لیست است پس نمایش هر چیزی به عنوان لیست کار ساده ای است، البته که من دارم اغراق می کنم اما آنچه که می خواهم بگویم این است که این

واقعیت که لیسپ از نظر نحوی قابل گسترش است و رشد می کند با وجود اینکه بسیار قدیمی است، به این خاطر است که لیست نحو و دستور زبان جزیی دارد و شاید بتوان

گفت اصال نحوی ندارد.انجام این کارها در زبانهای دیگر مانند جاوا ممکن نیست به خاطر استقالل ابزار فرا-

برنامه نویسی، حال این خاصیت چقدر مهم است اگر شما بخواهید آن را توضیح دهید.

ریچ: این بحث بسیار مهم است، سیستم های فرا-برنامه نویسی زیادی وجود دارند که استفاده از آنها به اندازه لیسپ ساده است، این موضوع ربطی به این ندارد که در لیسپ

همه چیز لیست است، در واقع در کلوژر همه چیز لیست نیست و این موضوع مهمی است چرا که اگر همه چیز لیست است باعث میشود همه چیز پیچیده تر شود و لیست دچار

سربار اضافی شود. چون نحو زبان وجود دارد اما در نمایش کاراکتر ها نیست، کاراکتر ها برای نمایش ساختمان داده ها هستند، نحو در تعبیر آن ساختمان داده ها مستتر

است.

Page 6: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: نحو در سطح کلمات است.

ریچ: نه باالتر در سطح لیست ها و بردارهای تو در تو. این واقعیت که نحو زبان، ساختمان داده است و زمانی که شما مبدلی می نویسید دوباره ساختمان داده های

جدیدی می سازید و اینها همان ساختمان دادهای ساده موجود و تعبیه شده در سیستم هستند باعث می شود فرا-برنامه نویسی بی نهایت ساده شود.

مارکوس: شما گفتید که مخاطب لیسپ دانشمندان بودند که روی هوش مصنوعی کار می

کردند، مخاطبان کلوژر چه کسانی اند؟ برنامه نویسان جاوا، لیسپ؟

ریچ: فکر می کنم هر برنامه نویسی با ذهنی به اندازه کافی باز کار کردن با لیسپ را تجربه ای جالب و هیجان انگیز خواهد یافت، تجربه من اینگونه بوده است، من بیش از یک دهه با سی پالس پالس و جاوا و سی شارپ کار کرده ام، لیسپ به طرز باور نکردنی ای شما را تواناتر می کند و فکر می کنم برداشت اولیه اکثرا افراد در مورد لیسپ غیر واقعی است چرا که هسته اصلی کلوژر بسیار ساده تر از جاوا است. آنچه که مشاهده میکنید

این است که زبان بسیار ساده و موجز است اما بالقوه بسیار قوی تر از جاوا است.

مارکوس: این بحث به خاطر این پیش می‌ آید که هر کسی برداشتی از سادگی دارد، شما

ممکن است بگویید لیسپ ساده است چرا که نحو بسیار ساده و موجزی دارد و تنها (orthogonal)شامل چند انتزاع است که پیشتر در مورد آن گفتید، ساختاری متعامد

دارد، می توانید برنامه هایی بنویسید که برنامه ای بنویسند که برنامه بنویسد، اما شخص دیگری می گوید جاوا ساده است چرا که راه مشخص است و ما اجزای برنامه

نویسی مشخصی داریم و ما در برهوت رها نشده ایم و در یک مسیر از پیش تعیین شده

Page 7: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

قرار می گیریم که ممکن است تحت عنوان سادگی تعبیر شود، نمی دانم می خواستم چه بگویم!

ریچ: من فکر میکنم منظور اکثر افراد در آنجا آشنایی(familiarity) است، وقتی شما دست یک نفر را در خیابان بگیرید و برنامه Hello World در جاوا را به او نشان می

دهید اگر شما واقعا بخواهید هر خط آن برنامه را برای او توضیح دهید خواهید فهمید که جاوا چقدر پیچیده است. ما فقط با آن راحتیم اما اصال ساده نیست. اما وقتی که من در مورد سادگی لیسپ و کلوژر به صورت صحبت می کنم، منظورم سادگی نحو زبان نیست

هر چند نحو ساده ای دارد منظورم عدم وجود پیچیدگی های پنهان و ضمنی است که دقیقا چیزی که ما را اذیت می کند.

مارکوس: من باید بگویم که من تجربه عملی با لیسپ ندارم اما می توانم انچه را که می

گویید بفهمم. دوست دارم چهار هفته ای وقت بگذارم و کار معنا داری با لیسپ انجام دهم تا تجربه کسب کنم. دو هفته پیش ما کنفرانسی در مورد DSL ها داشتیم و حدود ده

نفری جمع شده بودیم که در مورد ابزار و امکانات و زبانها برای ساخنت DSL صحبت کنیم، و یکی از جمع تعدادی مثال state machine مارتین فاولر را نشان داد و کدها

بسیار تمیز و زیبا بود. من می فهمم شما چه میگویید اما نمی توانم آنرا به واسطه فقدان

تجربه کار با لیسپ تایید و تحسین کنم و به همین خاطر است که ممکن است کمی مردد و بد بین به نظر برسم اما قصدم این نیست.

ریچ: من قطعا بحث آشنایی را تایید می کنم. این یک جنبه مهم و یک مانع است که افراد باید از آن رد شوند اگر می خواهند کشف کنند که آن طرف مانع چیست و چه امکاناتی

مهیاست، اما این موضوع بیشتر به آشنایی مربوط است تا به سادگی.

Page 8: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: من از همین استدالل استفاده می کنم آنگاه که می خواهم افراد را قانع کنم که

از ویرایشگرهای کد MPS Projector به جای ASCII استفاده کنند، شما باید باور کنید که چمن های آن طرف سبزترند و باید این سختی را تحمل کنید.

خوب کلوژر چه تفاوتی با لیسپ کالسیک یا نرمال دارد، شما قبال گفتید که به خوبی با VM یکپارچه شده است که به آن هم می رسیم اما از نظر زبان چه تفاوتهایی وجود دارد؟

ریچ: دو تفاوت اصلی وجود دارد،‌ یکی اینکه در لیسپ سنتی ساختمان داده های اصلی تغییرپذیرند، آنها cons را دارند که همان لیست است، hashtable و دیگر ساختار داده

های مدرن اما همه آنها تغییرپذیرند. چون من می خواستم همه ساختمان داده های اصلی در کلوژر تغییرناپذیر باشند، به همین خاطر نمی توانستم کلوژر را بر مبنای

scheme یا common lisp بسازم. زمینه بعدی تفاوت این است که لیسپ بسیار قدیمی است و scheme همینطور و در واقع

Polymorphic API و Interface آنها قبل از بوجود آمدن مفاهیم مدرنی مانندDesign به وجود آمده اند، لیسپ زمانی ارایه شد که دستورات شرطی جزو ابداعات

جدید در برنامه نویسی بود. API کلوژر مبتنی بر یک سری انتزاعات ساخته شده است در حالی که در لیسپ سنتی توابع کتابخانه ای برای کار کردن با لیست، به صورت جدایی vector و map ناپذیری به یک ساختمان داده متصل شده اند همچنانکه توابع مربوط به

ها همینطور هستند، در حالی که در کلوژر انتزاعی برای همه ساختمان داده ها وجود دارد و تمام کدهای مربوط به کتابخانه ها با توجه به این موضوع نوشته شده اند، شما می

توانید فکر کنید که شبیه اینترفیس های جاوا هستند، همچنانکه واقعا در الیه های زیرین اینترفیس های جاوا هستند. این بدین معنی است که کتابخانه مربوط به sequence ها با

همه داده هایی که به صورت سری remote هستند یا اینکه می توانند به صورت سری نمایش داده شوند، کار می کند. این بسیار مهم است شما حاال می توانید از کد های

کتابخانه، موثرتر استفاده کنید و شما را توانمندتر می سازد. اینها دو تفاوت اصلی هستند.

Page 9: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس:

common lisp خواص شی گرایی دارد هر چند که این شی گرایی با آنچه ما در زبانهای اصلی دیگر می شناسیم تفاوت دارد، آیا شما هم این را دارید، می توان کالس

تعریف کرد؟ و چه تفاوتهایی با کالس های جاوا دارند یا شاید تفاوتی ندارند؟

ریچ: شما دو کار می توانید انجام دهید، می توانید اینترفیس و کالسهایی تعریف کنید که در واقع همان اینترفیس و کالس های جاوا هستند و برای تعامل با جاوا ساخته شده اند

و همچنین به عنوان ابزاری برای انتزاع. در نسخه بعدی مفهومی به نام پروتکل وجود دارد که شبیه اینترفیس های جاوا هستند با این مزیت که می توانید کالس های موجود را که

کنترلی روی آنها ندارید، گسترش دهید و در یک پروتکل شرکت دهید، در حالی که در اینترفیس ها شما مجبورید که کالسی مشتق کنید. این مکانیسم اصلی انتزاع است، هر

چند این شی گرا نیست اگر بخواهید از دیدگاه شی گرایی سنتی به موضوع نگاه کنید، چون اکثر افراد به آبجکت به عنوان یک چیز قابل تغییر که حاوی وضعیت هایی است فکر می کنند، هر چند کلوژر همچنان این امکان را نیز از طریق تعامل با جاوا فراهم می کند.

مارکوس: پس انتزاع اصلی که شما می خواهید در کلوژر بسازید ساختمان داده ها به

همراه توابعی است که روی آنها کار میکنند.

ریچ: درست است، در پروتکل ها شما همچنان قادر خواهید بود مجموعه ای از توابع با اسم را به عنوان انتزاع ها تعریف کنید و رفتار چند ریختی را داشته باشید. من چند

ریختی را دوست دارم و فکر میکنم شما می توانید به شی گرایی افتخار کنید که توانسته آن را خوب ارائه کند.

Page 10: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: آیا پروتکل ها به عنوان آداپتوری برای سایر ساختمان داده هایی کار می کنند

که هنوز این رفتارها را به صورت مستقیم پیاده سازی نکرده اند؟

ریچ: آنها شبیه آداپتور ها هستند با این تفاوت که نیازی به wrapperها نیست.

مارکوس: پس کامپایلر اینجا حرکتی انجام می دهد که نیازی به wrapper نیست.

ریچ: بله.

مارکوس: این مرا به سوالی رهمنون می کند که من آنرا قبال جواب داده ام، این زبان

کامپایل می شود نه تفسیر.

ریچ: درست است در کلوژر مفسری وجود ندارد. شما لود دینامیک دارید و REPL هم دارید. فقط هر چیزی در زمان لود کامپایل می شود.

مارکوس:

REPL مخفف read-eval-print-loop است.

ریچ: بله یک رابط تعاملی است که می توان همان لحظه کد نوشت و نتیجه آنرا دید.

Page 11: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: آیا شما در مورد سرعت عملکرد کلوژر نسبت به جاوا بررسی ای انجام داده اید؟

ریچ: بله، در مورد فراخوانی متدهای معمولی سرعت به همان اندازه جاوا است،‌ چون همان byte code است، تفاوت بزرگ با جاوا در این است که در کلوژر اعداد همیشه

BigLong استفاده می کنید و این box شده اند، پس شما همیشه از BigInteger و ‌سربار خواهد داشت، و به وضوح پیداست که عملیات ریاضی با آنها کندتر است. اما شما در توابع می توانید انواع داده ابتدایی جاوا را تعریف کنید مانند int و long، و عملیات ریاضی با آنها به همان سرعت جاوا است. البته که طبقات متفاوتی وجود دارد چون لیسپ به صورت پیش فرض اعداد صحیح بزرگ را به انواع داده ی بزرگتر برای

نگهداری نتایج عملیات تبدیل میکند(به جای سرریز شدن)، کلوژر سه نوع عملیات ریاضی ارائه می کند، یکی این است که گفته شد، دیگری عملیات native روی داده های ابتدایی انجام می دهد و سرریزی را چک می کند که استفاده از آن امن است و نوع سوم اساسا بد است و آن همانی است که جاوا انجام می دهد، جاوا سرریزی پنهانی دارد، شما اگر

این را می خواهید این سریعترین است و در کلوژر در دسترس است.

مارکوس: حال بیاید در مورد رویکرد کلوژر به همزمانی حرف بزنیم، چرا که اوال این روزها

همزمانی عموما موضوع جالبی است عالوه بر اینکه این موضوع یکی از انگیزه های شما و از ویژگی طراحی این زبان بوده است، یکی از دالیلی که کلوژر با همزمانی جفت و جور

است این است که ساختمان داده ها تغییرناپذیرند، می توانید کمی در مورد آن صحبت

کنید.

ریچ: بله حتما، من می خواهم دقیقا از همینجا شروع کنم، به صورت کلی رویکرد کلوژر به ساختمان داده ها، شی گرایی و همزمانی به شدت به هم پیوسته اند، و اینها همه ناشی

از دردسرهایی است که ما در رابطه با وضعیت(state) داشته ایم.

Page 12: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: من فکر می کنم سخنرانی شما در مورد زمان را دیده ام، یادم نیست دقیقا در

QCon بود یا جای دیگری.

ریچ: بله در JVM Language Summit بود.بله این دقیقا توجیه وجود کلوژر است، حتی اگر شما همزمانی نداشته باشید، برنامه های

شی گرای بزرگ با پیچیدگی رو به افزایشی دست به گریبان خواهند بود وقتی که گراف بزرگی از آبجکت های تغییرپذیر را می سازند و تالش برای فهمیدن و به خاطر سپردن

اینکه وقتی یک متد را فراخوانی می کنید چه اتفاقی رخ می دهد و اثرات جانبی آن چه ها هستند و چه تاثیراتی در کجاها دارند، بسیار سخت خواهد بود.

مارکوس: آیا این فقط به این خاطر است که اتفاقات داخل سیستم اثرات جانبی دارند؟ یا

شما به چیز نامعلوم یا غریب دیگری اشاره دارید؟

ریچ: نه من دارم در مورد آبجکت های تغییرپذیر حرف می زنم با این سادگی که اگر به شما یک آبجکت تغییرپذیر بدهند می توانید به عنوان یک مقدار به آن رفرنس داشته

باشید؟ آیا شما می توانید مطمئن باشید که اگر بعدا دوباره به آن مراجعه کنید همان

است و کسی آنرا تغییر نداده است؟ این مفاهیم در برنامه نویسی شی گرا در هم آمیخته

شده اند و از این دیدگاه این مشکل بزرگی است.

مارکوس: من می توانم به خاطر بیاورم از کنفرانس JVM Language Summit که این

تفاوت بین وضعیت و شناسه(state and identity) است.

ریچ: بله درست است.

Page 13: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: شی در طول زمان بدون تغییر باقی می ماند اما مقدار و وضعیت آن تغییر می

کند.

ریچ: پس اگر شما قادر باشید که آن مقادیر را نگه دارید آنگاه بخش بسیار بزرگی از برنامه اتان مستقل از شناسه ها(identity)(بخشی که تغییر می کند) خواهد بود.

مارکوس: به کالم دیگر شما مقادیر را نگهداری می کنید نه شناسه ها را.

ریچ: بله می توانید مقادیر را به سادگی نگه دارید و بدون نگرانی روی آنها محاسبات انجام دهید. و ما باید بیشتر اینکار را انجام دهیم، فکر می کنم وقتی ما شروع به برنامه

نویسی شی گرا کردیم و کالس ها را ساختیم و تصمیم گرفتیم که اعضای کالس را به

صورت پیش فرض قابل تغییر قرار دهیم ما بسیار بیشتر از آنچه نیاز بود تغییر داشتیم و حذف این همه امکان تغییر کار سختی خواهد بود. کلوژر رویکردی برعکس دارد و می

گوید بیایید با مقادیر برنامه نویسی را شروع کنیم که تغییر نمی کنند و تا آنجایی که ممکن است با آنها کار کنیم و تنها بعد از آنکه به شناسه ها نیاز داشتیم آنگاه با آنها به صورت مستقل برخورد خواهیم کرد و تالش خواهیم کرد که تصمیمات متعامد و صحیحی

درباره موضوعات اتخاذ کنیم. پس با برنامه نویسی از طریق مقادیر شروع می کنیم،که به سوال اول شما برمیگردد که چگونه می خواهید چیزهای بزرگتر از اعداد و رشته ها

را به صورت مقدار نمایش دهید، شما به ساختمان داده های کارآمدی نیاز دارید که به طور مثال collection ها را به صورت مقدار نمایش دهید یا حتی چیزهای کوچکتر مانند

آبجکت ها، برای همین کلوژر مجموعه ای از ساختمان داده ها دارد که موسوم به ساختمان داده های پایدار است، پایدار به معنی ذخیره شدن در دیسک نیست در این

مورد پایداری به معنای ساختمان داده ای است که تغییرناپذیر است، و اگر بخواهید آنرا تغییر دهید یک نسخه جدید از آن را تولید خواهید کرد.

Page 14: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: یک کپی دیگر از آن!

ریچ: نه چون ویژگی دیگر این ساختمان داده ها این است که آنها سرعت را برای شما تضمین می کنند، ضمانت O، یعنی اضافه کردن با پیچیدگی log(n) خواهد بود.

مارکوس: اجازه دهید اینطور بگویم که از نظر مفهومی به نظر میرسد که داده ها تماما

کپی شده اند اما به روشی هوشمندانه تر این کار انجام میشود.

ریچ: دقیقا و این همان نکته اصلی است،‌ و الزم است اینها را بگوییم چون برداشت اولیه افراد این است که داده ها کپی میشوند و این نمی تواند کارآمد باشد اما این اتفاق نمی

افتد.در ساختمان داده های پایدار شما یک نسخه جدید می سازید و این از نظر سرعت

تضمین شده است، پس بنا نیست که داده ها کپی شوند چرا که اگر شما تعهد داده اید

O(n) است و بخواهید دادها را کپی کنید این کار log(n) که پیچیدگی این عملیاتخواهد بود.

ویژگی های دیگر ساختمان داده ها این است که نسخه قبلی همچنان در دسترس است، و از بین نرفته است یا تنزلی پیدا نکرده است پس سرعت نسخه قبلی همان است که بود.

چرا که الگوهایی برای پایداری وجود دارد که باعث میشود نسخه قدیمی به مرور تنزل پیدا کند، به واسطه روشی که این نسخه ها ساختارشان را به همدیگر به اشتراک گذاشته اند.

پس همه نسخه ها به یک اندازه خوب هستند.

زمانی که شما همه اینها را دارید، کلی ابزار متفاوت برای برنامه نوبسی دارید، نگهداری مقادیر ساده است، ذخیره سازی، undo(برگشت عملیات)، پشته ها (stack) همه

ارزان به دست می آیند، انجام طراحی عملیات به صورت بازگشتی ارزان است، و مواجهه با همزمانی راحت خواهد بود، چون همه مقادیر تغییرناپذیرند، آنها نیازی به قفل کردن یا

چیز دیگری ندارند برای اینکه در یک محیط همزمان مورد استفاده قرار گیرند.

Page 15: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: به نظرم می ارزد که پنج دقیقه ای دیگر روی این ساختمان داده های پایدار

زمان صرف کنیم، چرا که من آنها را فراموش کرده بودم و اگر یادتان باشد اصال جزو موضوعاتی نبود که قرار بود در مورد آنها صحبت کنیم،‌ اما خیلی نکات مهمی در مورد

آنها وجود دارد.

فرض کنید که من یک عبارت ساده دارم که یک عدد ضربدر حاصل جمع در عدد دیگر

میشود چیزی شبیه به یک ساختمان داده درختی، (۴+۳)*۲ حاال ۴ را با ۵ عوض می

کنم، به صورت ساده انگارانه من باید کل درخت را کپی کنم و این اتفاق نمی افتد، لطفا بگویید چه اتفاقی می افتد که شما یک کپی دیگر دارید اما کپی ای انجام نمی دهید؟

ریچ: اگر ما ساده ترین ساختمان داده پایدار را در نظر بگیریم یک لیست پیوندی یک طرفه است، اگر ما یک لیست با اعضای B ،A و C داشته باشیم و بخواهیم یک عضو به اول

آن اضافه کنیم مثال X، شما یک گره جدید می سازید و آنرا به لیست من وصل می کنید با مقدار دهی انتهای آن.

مارکوس: در این مورد ساده است، موافقم.

ریچ: اما نکته مهم اشتراک ساختار است، انتهای لیست شما با تمام لیست من ساختارشان را به اشتراک گذاشته اند.

مارکوس: و چون من نمی توانم هیچ چیز را تغییر دهم، این نمی تواند باعث ایجاد مشکلی

شود، مثال این اتفاق که کسی یکی از داده های مرا تغییر دهد پیش نمی آید.

ریچ: دقیقا و این نکته مهم بعدی است، چون من نمیتوانم لیست ام را تغییر دهم، پس نمی توانم لیست تو را هم دچار مشکل کنم. و برای اعمال این اصل به تمام ساختمان داده

Page 16: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

های دیگر، باید لیست را رها کرده و سراغ درخت بروید و این بدین معنی است که تمام ساختمان داده های کلوژر مانند hashmap یا vector همه درخت هستند. به همین

خاطر برای این کار الزم است تنها مسیری را کپی کنید که شامل بخشی است که آن را تغییر داده اید، به جای کل درخت.

مثال اگر شما بخواهید یک vector را با آرایه نمایش دهید، چاره ای جز این نخواهید داشت که کل آرایه را کپی کنید.

مارکوس: از دیدگاهی می توان درخت را به عنوان تعدای لیست پیوندی در نظر گرفت و هر

گره به یک انتها چندین انتها دارد و این یک درخت می سازد.

ریچ: بله می توانید، هر چند پیاده سازی آن اینطور نیست

مارکوس: بله منظورم از نظر مفهمومی است.

ریچ: بله و به همین خاطر بود که من با لیست شروع کردم، اساسا شما یک زنجیره از چیزها را دارید و با استفاده از درخت، تغییر هر برگی از این درخت تنها نیازمند تغییر یک مسیر به ریشه است و نه چیز دیگری، و نسخه جدید همه چیزش شبیه نسخه قبلی

است به جز این مسیر جدید.

پس ساختمان داده های کلوژر درختهایی از آرایه ها هستند، بنابراین ضریب شاخه

شاخه شدن باالیی دارند و عمق بسیار کمی دارند، و به همین خاطر سرعت باالیی دارند.پس اینگونه کار می کنند.

Page 17: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: پس شما هیچ چیز را به اشتراک نمی گذارید و همه چیز تغییرناپذیر است پس

نیازی به قفل کردن ندارید، و همه مشکالت مربوط به قفل گذاری بالفاصله حل می شود.اما مردم می پرسند اگر شما هیچ چیز را تغییر نمی دهید پس برنامه شما چگونه کار می

کند، در یک زمان خاص شما الزم است که چیزی را تغییر دهید مانند یک پایگاه داده یا چیزی که باید تغییر کند. آیا شما با این موضوع مواجه میشوید،‌ و اگر بلی، چگونه؟

ریچ: این یکی دیگر از نکات مهم در مورد کلوژر است، کلوژر تالش نمی کند به شما بگوید که میتوانید تنها با توابع محض و ساختمان داده ای تغییرناپذیر برنامه بنویسد،‌

چرا که برنامه های واقعی که در طول زمان مشغول ارائه سرویس هستند و با دنیای بیرون در ارتباط اند دارای وضعیت هستند، پس چگونه اینکار را انجام میدهید؟

نکته مهم فهم تفاوت بین مقادیر و شناسه ها است، که من در طول زمان در مورد آن صحبت خواهم کرد.

مثالی که در اینجا می زنم این است که برنامه ای را در نظر بگیرید که مردم از طریق نام کاربری و رمز به آن وارد شده و خارج می شوند. مجموعه افرادی که وارد شده اند یک

مجموعه است.در یک برنامه سنتی شما فرضتان این است که این مجموعه تغییرپذیر است، وقتی کسی

وارد میشود شما آن مجموعه را تغییر میدهید، و این یک مشکل بزرگ دارد، اینکه کسی به نسخه قدیمی آن نگاه می کند و روی آن foreach می زند و بعد خطای تغییر

همزمان(concurrent modification exception) می گیرد. اما آنچه که دقیقا اتفاق می افتد این است که شناسه ای وجود دارد چیزی که شما اسم

روی آن میگذارید(مجموعه افرادی که وارد سیستم شده اند) که در هر لحظه ای از زمان مقداری دارد، و شما هر کدام از آن مقادیر را به عنوان collection ی تغییرناپذیر نمایش

می دهید، پس تنها کاری که الزم است انجام دهید این است که مطمئن شوید که یک رابطه ترتیبی بین ایده «مجموعه کاربران وارد شده» از یک مجموعه و یک «مقدار خاص»

Page 18: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

وجود دارد و این تنها به یک ساختمان داده ی اتمیک نیاز دارد، که رفرنسی به آن مقدار است و آن رفرنس چیزی است که محتوایش عوض میشود.

مارکوس: اجازه دهید سعی کنم که بازگو کنم، کلوژر چیزی به اسم اتم در اختیار ما قرار

میدهد،‌ درست است؟

ریچ: این یکی از انتخابهای ممکن است.

مارکوس: اتم یک wrapper دور یک مقدار است، مقداری که در اتم قرار دارد می تواند

در طول زمان عوض شود، یک شناسه در اختیار شما قرار می دهد و دسترسی سریالی و ترتیبی را به داده داخل خودش ضمانت می کند.

ریچ: درست است و من آن را یک سطح باالتر می برم، اتم یکی از نمونه های انواع رفرنس موجود در کلوژر است، و انواع رفرنسی، همه به خاطر یک مشکل است که وجود دارند و

آن ابزاری برای نمایش شناسه است و ابزاری برای مدیریت زمان و ترتیب وضعیت هایی که همراه آن شناسه است.

مارکوس: یک مثال برای ما بزنید، چگونه کار میکند؟

ریچ: شما می توانید آنها را جعبه های کوچکی در نظر آورید که در داخل آن جعبه مقداری وجود دارد و منظور از مقدار چیزی است که تغییر نمی کند، پس مجموعه افرادی

که وارد سیستم شده اند یک جعبه است و در هر زمانی داخل جعبه یک ساختمان داده تغییرناپذیر وجود دارد و وقتی که میخواهید یک کاربر اضافه کنید، شما آن مقدار

Page 19: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

تغییرناپذیر را می گیرید و تابعی روی آن فراخوانی می کنید و یک مقدار تغییرناپذیر دیگر تولید میکند که همان مجموعه به اضافه کاربر جدید است و این مقدار جدید را داخل جعبه

می گذارید.

مارکوس: اگر دو نفر همزمان از دو نخ اجرایی اینکار را انجام دهند، مشکل همزمانی

برای شما رخ خواهد داد!

ریچ: مگر اینکه این انواع رفرنس معانی همزمانی را با خود داشته باشند. این کار آنهاست. نکته این است که شما دو مشکل را مجزا ببینید، ما دیگر در مورد مشکل تغییر

یک collection و قرار دادن یک چیز جدید در آن صحبت نمی کنیم. اینها توابعی هستند

که روی مقادیر کار می کنند، چیزی که باقی می ماند این است که ما چگونه از یک وضعیت به وضعیت بعدی میرویم (که هر وضعیت یک مقدار دارد) بدون اینکه با هم برخورد

کنیم.

مارکوس: از نظر API این موضوع چگونه به نظر می رسد؟

ریچ: همه انواع رفرنس یک شکل دارند، و یک مدل یکتا برای تغییر وضعیت وجود دارد. بدین شکل که شما یک رفرنس دارید که مقداری درخود دارد، شما برای آن رفرنس یک تابع

میفرستید که تابع مربوط به آن مقداری است که داخل رفرنس است که ممکن است این تابع آرگومانهای دیگری هم داشته باشد، نوع رفرنس مسئول این است که تابع را بگیرد،

آن را به مقدار داخلش اعمال کند و حاصل عملیات را به عنوان وضعیت بعدی خودش قرار دهد.

Page 20: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: رفرنس اطمینان میدهد که تنها یک نفر اینکار را در لحظه انجام می دهد

ریچ: در نتیجه شما باید توابع درجه یک را در زبان داشته باشید تا بتوانید آن تابع را به عنوان آرگومان برای کس دیگری بفرستید، سپس معانی(semantic) متقاوتی برای این

دارید که این تغییر کی و چگونه اتقاق می افتد. تغییر می تواند همزمان یا ناهمزمان باشد (همان لحظه اتفاق بیافتد یا بعدا)، شما می توانید بخواهید تابع اعمال شود و

زمانی که انجام شد شما باخبر شوید یا اینکه می توانید بگویید اینکار را بعدا انجام بده و به کارتان ادامه دهید.

تفاوتهایی اینجا وجود دارد، تفاوتهایی در این وجود دارد که آیا این تغییری که قصد انجام آن را دارید یک رفرنس را متاثر می کند یا شامل هماهنگی برای تغییر چند رفرنس است.

مارکوس: پس شما یک wrapper دیگر هم دارید که اینکار هماهنگی را انجام می دهد!

ریچ: رفرنس های متفاوتی وجود دارد که معانی(semantic) متفاوتی دارند ما در اینجا اتم ها ساده ترین شکل هستند، آنها در مورد سه گونه از آنها صحبت خواهیم کرد،‌

synchronous هستند و اتمیک هستند یک واحد کاری می تواند تنها شامل یک اتم در آن واحد باشد، agent ها، مانند اتم ها هستند، اتمیک هستند و یک واحد کاری می تواند

تنها شامل یک agent در آن واحد باشد ولی آنها asynchronous هستند، زمانی که برای یک agent یک تابع را می فرستید، آن تابع در آینده اعمال خواهد شد و کنترل

بالفاصله به برنامه شما بر میگردد، و agent آن تابعی را که برای او فرستاده شده از

طریق استخر نخ ها (thread pool) پردازش میکند اما ضمانت می کند که این عملیات به ترتیب انجام خواهد شد.

و نهایتا پیچیده ترین نوع رفرنس ref است، ref ها تنها در تراکنش ها تغییر می کنند و آنها هم synchronous و هم هماهنگ شده (coordinated) هستند، پس شما می

Page 21: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

توانید یک واحد کاری داشته باشید که شامل چند ref باشد، چیزی که مثال زمانی به آن نیاز دارید که بخواهید آیتمی را از یک دسته درآورده و به دسته دیگری اضافه کنید.

مارکوس: پس برای اینکار یک تراکنش باز می کنید و هر دو ref را در آن تغییر می دهید.

ریچ: این سیستم خوبی است چرا که شما همه عملیات را به توابع محض برده اید و اگر بخواهید تابعی را تست کنید که مثال آیتمی را به دسته ای اضافه میکند شما نیازی به

mock کردن چیزی ندارید، وضعیتی در آن تابع نخواهید داشت، و به آن نیازی ندارید، یک تابع محض دارید. پس تست این تابع بسیار ساده خواهد بود چون چیزی در مورد

تغییر وضعیت در آن نیست. سپس شما مساله دیگری خواهید داشت و آن این است که حاال که من یک تابع را برای یک ref فرستادم می خواهم مطمئن باشم که در محیط

همزمان به صورت امنی اجرا خواهد شد. این دو مساله از هم مجزا شده اند،‌ می توانید همه این معانی متفاوت را شبیه هم کنید، مدل تغییر وضعیت، ارسال یک تابع به رفرنس ها

همه یکی هستند.

مارکوس: یکی از چیزهایی که این روز ها در مورد کلوژر صحبت می شود در مورد همین

موضوع است: حافظه تراکنشی.

ریچ: آخرین نوع انواع رفرنس ها، ref ها از این طریق پیاده سازی شده اند، بله.

Page 22: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: ما قبال در مورد حافظه تراکنشی برنامه ای داشته ایم هرچند شماره آن را به

خاطر نمی آورم.

ریچ: باید بگویم که رویکرد کلوژر به حافظه تراکنشی نرم افزاری بسیار متفاوت است از آنچه که در مقاالت یا گفتگوها دیده اید، افراد زیادی روی این موضوع کار کرده اند با این

هدف که به شما اجازه دهند کد موجودتان را نگه دارید (که آبجکت های تغییرپذیر را

دستکاری می کند) اما آن عملیات را در یک تراکنش قرار دهید و نیازی به استفاده از قفل

ها نداشته باشید.من شخصا طرفدار چنین رویکردی نیستم و فکر می کنم این روش نمی تواند کار را

انجام نمی دهد، روش کلوژر بسیار متفاوت است، اینجا ما روی برنامه نویسی با مقادیر تاکید داریم، استفاده از توابع محض، استفاده از مقادیر برای aggregateها پس اندازه

ای که ما با آن کار می کنیم بزرگتر است(coarse granularity) و از روش کنترل همزمانی مبتنی بر چند نسخه ای بودن در الیه های زیرین استفاده می کند، پس کامال

متفاوت است.

مارکوس: شما این واقعیت را آشکار کردید که می توان بعضی مقادیر را در داخل تراکنش

ها تغییر داد، پس شما تالشی برای شفاف کردن انجام نمی دهید.

ریچ: نه، شفافیت در این مورد چیز خوبی نیست.

مارکوس: موافقم.

Page 23: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: می خواهم حرف دهن شما بگذارم، با فرض اینکه پشتیبانی موجه از زمان،

مقدار، شناسه و همزمانی دالیل اصلی برای ساخنت کلوژر بوده اند. آیا اینکار با اضافه کردن یک کتابخانه یا فریم ورک به یک زبان موجود ممکن نبود؟

به عبارت دیگر چرا چنین چیزهایی نیاز به پشتیبانی شدن در سطح یک زبان نیاز دارند؟

ریچ: در واقع کلوژر یک کتابخانه است، یک کتابخانه است که به جاوا نوشته شده است و می توان از آن در جاوا استفاده کرد.

موضوع زبان این است که باعث می شود استفاده از این مفاهیم طبیعی(idiomatic) و

STM(Software راحت باشد، شما می توانید دقیقا از همین انواع رفرنس و(Transactional Memory و ساختمان داده های کلوژر در جاوا استفاده کنید.

مارکوس: بله اما شما تلف می شوید اگر بخواهید این همه anonymous را در کالس

ها به عنوان تابع تعریف کنید.

ریچ: در مورد توابع، عدم پشتیبانی کتابخانه هایی که به صورت طبیعی بتوان با استفاده از مقادیر برنامه نوشت، باید مقادیر بازگشتی را به متغییر دیگری انتساب دهید،‌ این

روش طبیعی انجام کار نیست، پس عدم وجود idiom ها و پشتیبانی زبان بدین معنی

است که شما باید از همان کدهای زیربنایی جاوا استفاده کنید و این بسیار سخت

خواهد بود در مقایسه با کلوژر، جایی که همه اینها عملکرد طبیعی سیستم است، و این کاری است که شما به صورت پیش فرض در کلوژر انجام میدهید، زمانی که شما برنامه

کلوژر می نویسید و از این ساختمان داده ها استفاده می کنید همواره دارید به این روش برنامه می نویسید. این چیزی نیست که شما بعدها مجبور به انجام آن شوید، و این چیز

خوبی است چرا که وقتی نیاز و عالقه به همزمانی را متوجه شوید الزم نیست چیزی را تغییر دهید، شما پیشتر کار درست را انجام داده اید.

Page 24: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: من تعریف شما از زبان را بسیار پسندیدم، چرا که من همواره با آن دست به

گریبانم، من با DSL ها کار میکنم و افراد همیشه از من می پرسند که تفاوت میان زبان و API چیست، چرا من به یک زبان نیاز دارم وقتی که می توانم همه چیز را با دستوراتی

مانند Insert و … بیان کنم. نکته این است که می خواهیم مفاهیم طبیعی باشند و بیان درست آنها ساده باشد،‌ این یک تعریف بسیار خوب است.

ریچ: بله و به همین دلیل است که همه این اجزای مستقل کلوژر با هم طراحی شده اند طوری که همه این جنبه ها با هم خوب کار کنند.

مارکوس: آخرین سوال فنی قبل از اینکه بخواهیم در مورد استقبال از زبان و اجتماع

کاربران کلوژر صحبت کنیم، یکی دیگر از روشهای مدیریت وضعیت در زبانهای تابعی دیگر Monad است، فکر می کنم قبال در se-radio با Eric Meyer در این باره حرف

زده ایم، آیا این موضوع در کلوژر نقشی دارد؟

ریچ: کتابخانه هایی برای اینکار وجود دارد، اما من فکر می کنم Monad مساله مربوط به شناسه ها را به صورت مبنایی حل نمی کند، شما نمیتوانید از Monad برای مساله مجموعه کابران وارد شده به سیستم استفاده کنید (برنامه ای که در طول زمان زیادی در

Haskell حال اجرا بوده و اجزای مختلف برنامه درگیر بوده است)، و به همین خاطردارای STM و MVar است. اینها را دارد چون این روشی است که می توانید چند نخ کنترل مستقل را با هم هماهنگ کنید، Monad برای حالتی است که تنها یک نخ کنترل

دارید.

مارکوس: بله Monad ربطی به همزمانی ندارد.

Page 25: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

ریچ: پس شما در Haskell نمی توانید از یک ساختار مشابه برای هر دو کار استفاده کنید، مطمئن نیستم که آیا همیشه این ساختار صحیحی خواهد بود. به عالوه با وجود

اینکه کتابخانه هایی برای کلوژر برای اینکار وجود دارد، این مفهوم در Haskell بسیار قوی تر است به خاطر سیستم انواعی(type system) که دارد.

مارکوس: شاید این سوال من باشد، آیا سیستم انواع شما از Monad آگاه است،‌ پس

پاسخ خیر است و استفاده از آن طبیعی به نظر نمی رسد!

ریچ: بله همینطور است، اما با ماکروها مشکل حل میشود، نکته اصلی این است که Haskell قابلیت استنتاج انواع روی انواع برگشتی توابع را دارد و این یک ویژگی

بسیار مهم برای Monad است.

مارکوس: کلوژر دارای انواع دینامیک است، درست است؟ پس شما نمی توانید استنتاج

نوع Monad را انجام دهید، درست است؟

ریچ: خوب، کلوژر استنتاج محلی انجام می دهد، برای مثال برای اینکه کد جاوا را بدون استفاده از بازتاب(reflection) فراخوانی کرد، ما نیاز داریم که انواع را بدانیم.

اما در کلوژر (به نسبت جاوا) شما خیلی کمتر به انواع نیاز دارید، چرا که اگر کمی اطالعات پیدا کند، قادر خواهد بود انواع حاصله این عبارت و فراخوانی را استنتاج کند

که خود می تواند ورودی یک فراخوانی دیگر باشد و در نتیجه انواع ورودی آن فراخوانی را نیز استنتاج کرده است.

مارکوس: پس آیا دارای سیستم انواع ایستا است یا مرغابی گونه(duck typing)؟ :-)

ریچ: اینها انتخاب های صفر و یکی نیستند.

Page 26: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: اگر استنتاج انواع توسط کامپایلر انجام میشود پس مرغابی گونه نیست.

این سیستم، ایستا است که استنتاج انواع هم به آن تزریق شده است.

ریچ: تفاوت اینها به اجبار کردن این قواعد برمی گردد، اگر بتوانم انواع را استنتاج کنم از آن برای تولید کد بهتر استفاده می کنم در غیر اینصورت آن را غیر مجاز نمی دانم که

بدین معنی است که شما کد بازتابی خواهید داشت که در زمان اجرا ممکن است متوجه شود که اصال متدی با آن اسم وجود ندارد.

مارکوس: آهان! پس بدین معنی است که می توانید اطالعات مربوط به انواع را در کلوژر

تعیین کنید و اگر این اطالعات موجود باشد آن کد کامپایل می شود برخالف حالتی که کد بازتابی تولید میشود.

ریچ: شما باید خیلی دقیق باشید چرا که این کد کامپایل میشود و دقیقا عین جاوا اجرا می شود. در مقابل کد شما مجاز به پذیرفنت انواع مختلف نخواهد بود، این تنها

مکانیسمی برای بهینه سازی است نه برای رد کردن برخی عبارات اجرایی. این کار

بررسی و اطمینان از صحت انواع نیست.

مارکوس: ولی اگر این اطالعات را فراهم کنید کد بهتری تولید خواهد شد.

ریچ: و به درد تعامل با جاوا هم می خورد.

مارکوس: آیا موضوع فنی ای در مورد زبان وجود دارد که من فراموش کرده باشم بپرسم و

شما دوست داشته باشید در مورد آن صحبت کنید؟

Page 27: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

ریچ: فنی؟

مارکوس: بله مثال یک ویژگی جالب زبان یا …

ریچ: نه، در درون کلوژر بسیار بسیار ساده است، و در واقع این یکی از چیزهایی است که من می خواهم افراد در مورد کلوژر بدانند که از نظر فرم محاسباتی بی نهایت ساده

است،‌ قواعد زیادی وجود ندارد، قواعد نحوی زیادی وجود ندارد، مخصوصا در مورد نحو،

زبان فوق العاده ساده است.

مارکوس: خوب، بیاید در مورد موضوعات نرم صحبت کنیم، استقبال و پذیرش کلوژر در

بازار(به جای zoo) زبانهایی که روی JVM در طول دو سه سال اخیر آمده اند، چگونه بوده است؟

ریچ: به صورت قابل توجه ای خوب عمل کرده است با توجه به اینکه جدیدترین زبانی است که به این مجموعه اضافه شده است، لیست ایمیل گوگل دارای ۳۳۰۰ عضو است، این

خیلی چشمگیر است، پذیرش و استفاده از زبان، افراد شغل هایی تحت این عنوان پیدا می کنند، شرکت ها از آن استفاده می کنند، با شرکت های نوپا شروع شد اما االن

کاربردهایی در زمینه های دیگر مانند تحلیل و دیگر جاهای متفاوت می بینیم.

مارکوس: آیا سناریوی استفاده معمولی و عمومی ای دارد؟ جایی که استفاده از کلوژر

واقعا مناسب است؟

ریچ: می دانید، یکی از بزرگترین چیزها برای من این بوده که زبان طوری طراحی شده که همه کاره باشد و در زمینه های بسیار گوناگونی موارد استفاده ی مختلفی داشته است.

Page 28: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

یکی از زمینه هایی که اگر بخواهم به عنوان یک زمینه داغ و پرطرفدار نام ببرم، استفاده شرکت FlightCaster برای کار یادگیری ماشین بوده است که روی خوشه ای از Hadoop اجرا می شود، و کتابخانه هایی وجود دارد برای یکپارچه شدن با دیگر

کتابخانه های آماری کلوژر به اسم encounter، این زمینه االن داغ است جایی که اکثرا به صورت سنتی از R استفاده می شده است که آن را به برنامه نویس می داده اند تا آن را به محیط عملیاتی ببرد، حال می توانند از کلوژر استفاده کنند برای اینکه با داده های

حجیم کار کنند و مدلی را که بدست می آورند می توانند مستقیما در محیط عملیاتی مورد استفاده قرار دهند. این زمینه ای است که ترکانده است (-: اما برای برنامه نویسی وب و

پایگاه داده ها و سیستم های انتقال پیغام نیز به کار می رود.

مارکوس: اما می توان گفت که توان خود را جایی نشان می دهد که نیاز باشد الگوریتم

های غیر جزیی و سنگینی به صورت همزمان اجرا شود.

ریچ: می تواند اینطور باشد اما شاید بتوانید متوجه شوید که امکانات مربوط به برنامه نویسی همزمان کلوژر کمتر از آنچه فکر می کنید به کار گرفته شده است، نمی خواهم

بگویم که این امکانات صرفا فوت و فن هستند، این زبان بسیار بیان راحتی دارد و با اکو سیستم JVM سازگاری دارد پس حجم عظیمی از کتابخانه ها وجود دارد که می توانید

از آنها بهره ببرید و افراد بدین واسطه بسیار سریعتر و کارآمدتر برنامه می نویسند، و این مهم است.

مارکوس: کتاب هم دارد که نویسنده آن Stuart Halloway است.

ریچ: بله.

Page 29: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

Manning دو کتاب دیگر هم در راه است، می توانید دسترسی زودهنگام آنها را ازدریافت کنید، یکی Clojure in Action است و دیگری Joy of Clojure است.

مارکوس: آیا شما در آنها دخیل بوده اید؟

ریچ: نه.

مارکوس: تعجب کردم.

ریچ: من مشغول کلوژر هستم.شاید یک وقتی اینکار را بکنم اما االن خیلی مشغله دارم.

مارکوس: به نظرم این نشانه خوبی است.

ریچ: اجتماع برنامه نویسان عالی است، لیست ایمیل بزرگ است و بگذارید نگاه کنم ۲۳۰ نفر در IRC حضور دارند، اینها همه معیارهایی هستند، کمک گرفنت از دیگران کار

راحتی است، افراد عمدتا دوستانه برخورد می کنند، شروع آسان است.

مارکوس: خیلی خوب است.

پس تنها مشکل پیدا کردن مشتری است الاقل برای من اینطور است. که بخواهد از کلوژر

استفاده کند به جای زبانهای اصلی. که به نظرم در بعضی محیط ها همچنان یک چالش

است که افراد را قانع کرد.

Page 30: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

ریچ: فقط به آنها بگویید که تنها می خواهیم از یک کتابخانه جاوا استفاده کنیم که نام آن کلوژر است، مانند همه کتابخانه های دیگر یک فایل jar است.

پذیرش سطوح مختلفی در صنایع مختلف دارد، بستگی به سطح محافظه کاری دارد و

اینکه دارند چه کار می کنند، اما جالب است که می بینیم به صورت گسترده ای به کار گرفته میشود.

مارکوس: ابزار برنامه نویسی آن چطور است، IDE ها، برجسته کننده نحو زبان و …

ریچ: قطعا. در واقع بسیار خوب است، Emacs اگر که آن را می پسندید، به صورت سنتی جای مناسبی برای برنامه نویسی لیسپ است، اگر از IDE های سنتی خوشتان Enclosure بسیار خوب پشتیبانی می کند، پروژه ای که نام آن Netbeans ،می آیداست، کامل کردن کد برای کلوژر و جاوا را دارد، یکپارچگی بسیار خوبی با جاوا دارد،

Intellij قرار گرفته است، به همین شکل IDE آن در REPL ،برجسته کننده نحو دارد

خوب از کلوژر پشتیبانی می کند، نوع پروژه کلوژر وجود دارد، بچه های Intellij آن را درست کرده اند، و کارشان را بسیار خوب انجام داده اند، Eclipse هم به تازگی از

کلوژر حمایت می کند، خالصه کلی انتخاب وجود دارد.

مارکوس: شما اگر این سه تا را داشته باشید پس دیگر مشکلی وجود ندارد.

ریچ: بله و البته کلوژر در زیرساخت بایت کد با JVM مشترک است پس همه ابزار های رفع خطا و بررسی عملکرد جاوا برای کلوژر هم کار خواهند کرد.

مارکوس: در سطح سورس کد؟

ریچ: بله.

Page 31: Clojure se-radio.net Interview with Rich Hickey (ترجمه مصاحبه رادیو مهندسی نرم افزار با ریچ هیکی )

مارکوس: خوب این همه چیزی بود که من آماده کرده بودم، چیزی برای اضافه کردن دارید؟

ریچ: نه فقط می خواهم که افراد آن را امتحان کنند، و به گروه گوگل بپیوندند و IRC اگر کمک می خواهید.

مارکوس: خوب از اینکه در این برنامه حضور یافتید متشکرم.

ریچ: از دعوت شما ممنونم.