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

ساختار و تفسیر برنامه‌های کامپیوتری

نوشتهٔ هرولد ابلسون و جرالد جی ساسمن · سال انتشار 1985

کتابی که نحوهٔ تدریس علوم کامپیوتر را برای یک نسل شکل داد — ساختن یک مفسر، یک ماشین ثباتی و یک سیستم پردازش جریان از صفر، بیش از هر آموزش فریم‌ورکی چیز یاد می‌دهد.

نقاط قوت

  • درکی واقعی از محاسبه از اصول اولیه می‌سازد، نه حفظ کردن نحو زبان
  • تمرین‌ها (ساخت مفسر خودت، ماشین ثباتی، ارزیاب تنبل) واقعاً شکل‌دهنده‌اند

نقاط ضعف

  • ناآشنایی با اسکیم برای خواننده‌ای که فقط زبان‌های امری رایج را می‌شناسد مانعی واقعی است
  • متراکم و کند پیش می‌رود — این متنی برای یک ترم است، نه یک آخر هفته

خلاصه کتاب

ادعای آغازین ابلسون و ساسمن لحن هر آنچه را که در ادامه می‌آید تعیین می‌کند: کتاب دربارهٔ یک زبان برنامه‌نویسی نیست، و علوم کامپیوتر واقعاً دربارهٔ کامپیوتر نیست. دربارهٔ تکنیک‌های مهار پیچیدگی در سیستم‌های بزرگ است، و زبانی که به کار می‌گیرد — گویش کوچکی از اسکیم که در یک بعدازظهر قابل آموزش است — دقیقاً به این دلیل انتخاب شده که از سر راه کنار برود. تقریباً هیچ نحوی برای یادگیری وجود ندارد، پس چیزی میان خواننده و موضوع اصلی نمی‌ایستد.

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

یک‌سوم پایانی جایی است که کتاب به چیزی غیر از یک متن برنامه‌نویسی تبدیل می‌شود. نویسندگان، پس از تثبیت اینکه برنامه‌ها داده‌اند، از خواننده می‌خواهند مفسری برای اسکیم در اسکیم بسازد — ارزیاب فرا-دوری — و بعد ادامه می‌دهند: یک ارزیاب تنبل، یک ارزیاب نامعین، یک زبان برنامه‌نویسی منطقی، یک ماشین ثباتی، و یک کامپایلر. نکتهٔ آموزشی این است که مرز میان «زبان» و «یک برنامه» بنیادین نیست. وقتی یک ارزیاب نوشته باشی، زبان فقط برنامهٔ دیگری است که می‌توانی تغییرش بدهی، و همین جابه‌جایی در دیدگاه، محمولهٔ واقعیِ کتاب است.

ایده‌های کلیدی

۱. انتزاع رویه‌ای و رویه‌های مرتبهٔ بالا

کتاب زود تثبیت می‌کند که نام و اینترفیس یک رویه بیشتر از بدنه‌اش اهمیت دارد — وقتی sqrt کار می‌کند، فراخواننده‌اش نه باید بداند و نه اهمیت بدهد که از روش نیوتن استفاده می‌کند. از آنجا به رویه‌هایی می‌رسد که رویه‌های دیگر می‌گیرند و برمی‌گردانند، که اجازه می‌دهد الگویی مثل «جمع یک سری» یک‌بار ثبت و بارها تخصصی شود، به‌جای اینکه برای هر مورد از نو نوشته شود.

برنامه‌ها باید برای خواندن آدم‌ها نوشته شوند، و فقط به‌طور جانبی برای اجرا توسط ماشین‌ها.

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

۲. بازگشت، تکرار، و شکل یک فرایند

یکی از تیزترین تمایزهای کتاب میان رویهٔ بازگشتی و فرایند بازگشتی است. رویه‌ای که خودش را صدا می‌زند ممکن است همچنان فرایندی تکراری تولید کند — فضای ثابت، بدون زنجیرهٔ روبه‌رشدِ عملیات معوق — اگر فراخوانی بازگشتی در موضع دنباله باشد. نکته این است که خواندن کد منبع کمتر از آنچه فکر می‌کنی به تو می‌گوید؛ آنچه اهمیت دارد شکل محاسبه‌ای است که در زمان اجرا باز می‌شود.

این استدلال دربارهٔ کارایی را از فرهنگ شفاهی («بازگشت کند است») به سمت چیزی قابل‌بررسی می‌برد: آیا این رویه کار معوق انباشته می‌کند، یا حالتش را در آرگومان‌هایش به جلو حمل می‌کند؟ آن سؤال به هر زبانی منتقل می‌شود، چه فراخوانی دنباله را بهینه کند چه نکند.

۳. داده به‌عنوان رویه، و معنای «بازنمایی»

کتاب زوج‌ها را — ساختار دادهٔ مرکب بنیادین — از هیچ چیزی جز یک بستار می‌سازد، و نشان می‌دهد «داده» و «رویه» در بنیاد دسته‌های متمایزی نیستند. هدف این نیست که کسی باید لیست‌ها را این‌طور پیاده کند، بلکه بیان نکته‌ای قوی‌تر است: اینکه یک ساختار داده چه هست خیلی کمتر از اینترفیسی که ارائه می‌دهد اهمیت دارد، چون همه‌چیز بالای اینترفیس از انتخاب زیرین مستقل است.

این به برنامه‌نویسیِ داده‌محور و عملیات عمومی می‌رسد — ارسال بر اساس نوع، طوری که همان عملیات روی بازنمایی‌هایی که بعداً اضافه می‌شوند کار کند، بدون تغییر کد موجود. این در اصل همان اصل باز/بسته است، که دهه‌ها پیش از نام‌گذاری‌اش، از اصول اولیه به آن رسیده‌اند.

۴. ارزیاب فرا-دوری

قطعهٔ مرکزی کتاب نوشتن یک مفسر اسکیم در اسکیم است. کوتاه است — چند صفحه — و قواعد ارزیابی را صریح می‌کند: eval بر اساس نوع عبارت ارسال می‌کند، apply آرگومان‌ها را در محیطی جدید به پارامترها می‌بندد، و بازگشت متقابل میان این دو همان زبان است.

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

برای چه کسی مفید است

  • برنامه‌نویسانی که می‌توانند چیز بسازند اما حس می‌کنند نمی‌فهمند زیرش چه خبر است — این کتابی است که آن شکاف را کامل‌تر از هر آموزش فریم‌ورکی می‌بندد.
  • هرکسی که می‌خواهد بفهمد مفسرها و کامپایلرها واقعاً چطور کار می‌کنند — چندتا می‌سازی، به‌جای اینکه دربارهٔ آن‌ها بخوانی.
  • توسعه‌دهندگان خودآموخته‌ای که دنبال پایهٔ نظری‌ای هستند که یک مدرک علوم کامپیوتر می‌دهد — این دو دهه همان برنامهٔ درسی در MIT بود.
  • خواننده‌هایی که از تمرین‌های سخت لذت می‌برند — مسائل خودِ دوره‌اند، نه تزئین، و ردکردنشان بیشتر ارزش را حذف می‌کند.
اگر به مهارت‌های عملی و فوراً کاربردی برای یک شغل نیاز داری — یک فریم‌ورک، یک خط استقرار، زبانی که بابتش استخدام می‌شوی — این آن کتاب نیست و ادعایش را هم ندارد. هیچ چیزی اینجا روی یک خط از آگهی شغلی نمی‌نشیند؛ بازدهی واقعی است اما غیرمستقیم و کند.
سختی‌اش واقعاً تند است، و یادگیری در تمرین‌ها زندگی می‌کند — خواننده‌ای که متن را می‌خواند و مسائل را رد می‌کند، در پایان به‌طرز غافلگیرکننده‌ای کم جذب کرده. به‌جای چند شب، به اندازهٔ یک ترم تلاش بودجه بگذار، و انتظار داشته باش ناآشنایی اسکیم فصل‌های اول را قابل‌توجه کند کند، اگر فقط با زبان‌های امریِ رایج کار کرده‌ای.

سؤالات پرتکرار

باید از قبل اسکیم یا لیسپ بلد باشم؟

نه — زبان از صفر معرفی می‌شود و کل نحوش در چند صفحه جا می‌گیرد، که دقیقاً دلیل انتخابش است. ناآشناییِ نماد پیشوندی و پرانتزها ظرف یک فصل از بین می‌رود؛ سختیِ کتاب در ایده‌هاست، نه در زبان.

با توجه به اینکه مال ۱۹۸۵ است، هنوز مرتبط است؟

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

این با یک کتاب برنامه‌نویسیِ عملیِ امروزی چطور مقایسه می‌شود؟

هدف‌های متفاوتی دارند. یک کتاب عملیِ امروزی سریع تو را در یک استک مشخص بهره‌ور می‌کند؛ SICP نحوهٔ فکرکردنت دربارهٔ برنامه‌ها را به‌طور کلی عوض می‌کند و تقریباً هیچ مهارت فوراً قابل‌فروشی نمی‌دهد. بیشتر آدم‌ها از هر دو بهره می‌برند، به این ترتیب فوریت اما ترتیب معکوس ماندگاری.

هنوز MIT از رویش تدریس می‌کند؟

نه — MIT در سال ۲۰۰۸ آن را با یک دورهٔ مقدماتیِ مبتنی بر پایتون جایگزین کرد، با این استدلال که مهندسیِ امروزی بیشتر ترکیب کتابخانه‌های بزرگ موجود است تا ساختن سیستم از عناصر اولیه. این استدلالی مشروع دربارهٔ برنامهٔ درسی است، نه ادعایی که محتوای کتاب غلط شده.

ضعف اصلیِ کتاب چیست؟

سرعت و سختی‌اش رهاکردنش را آسان می‌کند، و برای خواننده‌ای که گیر می‌کند داربست کمی ارائه می‌دهد — نه شیب ورودی ملایمی هست و نه میان‌بری از تمرین‌ها، که دقیقاً همان‌جایی است که بیشتر ارزشش ذخیره شده.

این مطلب برایتان مفید بود؟

شمارش آرا پس از ۵ رأی نمایش داده می‌شود.

بیشتر در همین دسته