Category Archives: Lifestream
nasser-torabzade starred reactivemanifesto/reactivemanifesto
آداب بیقراریِ حین سفر
فهرستی از ۶۰ کتاب خوبی که خواندهام
بهمن دارالشفایی: نمایشگاه کتاب از فردا (چهارشنبه) شروع میشود و تا شنبه بیست و ششم ادامه دارد. من هم مثل پارسال همهی روزها در غرفهی نشر ماهی هستم. پارسال همین موقع ۵۰ کتابی را که دوست داشتم پیشنهاد کردم. امسال هم یک فهرست ۶۰ تایی تهیه کردهام که شاید در روزهای نمایشگاه یا غیر آن به دردتان بخورد.دو سه تا نکته. یکی اینکه از فهرست پارسال حدود ۱۰ کتاب حذف کردهام و حدود ۲۰ کتاب جدید به فهرست اضافه کردهام. دوم اینکه اینها همه کتابهای خوبی که خواندهام نیستند. تا جایی که حافظه و کتابخانه و آرشیو وبلاگ یاری کرده، نوشتهام. البته که همهی این کتابها را خواندهام و آنهایی که پنج ستاره دادهام به نظرم بسیار باارزش بودهاند. دیگر اینکه با اینکه نزدیک نصف این کتابها از نشر ماهی هستند اما مطمئن باشید که ستارههای جلو کتابها نظر واقعیام است.
اینکه کتابهای ماهی در این فهرست بیشتر از بقیه ناشرها هستند دو دلیل دارد: یکی اینکه با سلیقه و معیارهای من، ماهی واقعا کتابهای خوبی چاپ میکند و دوم اینکه طبعاً چون من الان با نشر ماهی همکاری میکنم و از سالها پیش هم با این نشر رابطهی نزدیکی داشتهام بیشتر از بقیهی ناشرها در معرض کتابهای ماهی بودهام و تعداد بیشتری از کتابهایش را خواندهام (این را هم بگویم که کیفیت کار ماهی اصلیترین دلیل همکاری من با این نشر است). ضمناً اشکالات فونت و فاصلهی سطرها و ... را به بزرگی خودتان ببخشید که هر کار کردم درست نشد.
اول فهرست را مینویسم و بعد مشخصات و توضیحی کوتاه در بارهی هر کتاب:
نشر ماهی (۵ ستاره): موشها و آدمها، ظلمت در نیمروز، دوست بازیافته، گیرنده شناخته نشد، میکهارته اینجا بود، نگذار به بادبادکها شلیک کنند، فلسفه سیاسی، میشائیل کلهاس، اختناق ایران، محاکمه، بیگانه.
نشرهای دیگر (۵ ستاره): سووشون، به یاد کاتالونیا، تاریخ چیست؟ (خوارزمی)،همنوایی شبانه ارکستر چوبها، آنا کارنینا، بیست و یک داستان از نویسندگان معاصر فرانسه (نیلوفر)، بازمانده روز، یک گفتوگو با نجف دریابندری (کارنامه)، دفتر بزرگ (مروارید)، زمین سوخته (معین)، تاریخ سیاسی بیست و پنج ساله ایران (رسا)، پاگرد (افق)، دنیای کوچک دنکامیلو (پرواز)، قمارباز (چشمه)، اشغال تصویر سیزدهم (روایت فتح)، سور بز (علم)، کپنهاگ (نیلا)، مکتب در فرایند تکامل (کویر)، تومار شیخ شرزین (روشنگران)، فلسفه علم (فرهنگ معاصر)، ناپدیدشدگان (ققنوس)، انقلاب مشروطه ایران (بیستون)، چهرههایی از پدرم (قطره)، جدال با جهل (ثالث).
نشر ماهی (۴ و نیم ستاره): از من نخواهید لبخند بزنم، کنسانسیا، سوءظن، رویای آدم مضحک، زندگینامه آیزایا برلین، خانواده پاسکوآل دوآرته، تیستوی سبزانگشتی، بر بال بحران، مکتب دیکتاتورها، مترجم دردها، فاشیسم، بینام، عطر گوابا، گزارش یک مرگ، همزاد.
نشرهای دیگر (۴ و نیم ستاره): مدرک (مروارید)، آینههای دردار، سه نفر در برف (نیلوفر)، مجموعه آثار جین آستین، و نیچه گریه کرد (نی)، بالاخره این زندگی مال کیه؟ (کارنامه)، مردی که گورش گم شد (چشمه)، سهرابکشان (روشنگران)، جامعهشناسی دین (حکمت)، در جستجوی فردی (لوح فکر).
۱. دفتر بزرگ (۵ ستاره)
آگوتا کریستوف، اصغر نوری، نشر مروارید، ۸۵۰۰ تومان
یکی از تاثیرگذاریترین کتابهایی که به عمرم خواندهام. ماجرای دو برادر دوقلوی ۱۰ ساله در آستانه جنگ جهانی دوم. کتاب بسیار ساده است ولی در عین حال صحنههایی دارد که در یاد آدم حک میشوند. پیشنهاد میکنم حتما بخوانیدش. این کتاب قسمت اول از یک سهگانه است که دو تای دیگر را هم انتشارات مروارید منتشر کرده. آن دو تا هم خیلی خوبند ولی به نظرم این یکی چیز دیگری است.
۲. موشها و آدمها (۵ ستاره)
جان استاینبک، سروش حبیبی، نشر ماهی، ۵۵۰۰ تومان
یکی از بهترین و تاثیرگذارترین کتابهایی است که در سالهای اخیر خواندهام. کتاب آنقدر ساده است که وقتی میخواندمش نمیفهمیدم چه چیزیش اینقدر من را گرفته. این روزها به چند نفر از اطرافیانم دادم و آنها هم خیلی خوششان آمد. جان استاینبک که نیازی به تعریف ندارد و به نظر من سروش حبیبی در ترجمه این کتاب شاهکار کرده. رضا رضایی (مترجم) هم میگفت به نظرش این کتاب یکی از بهترین نمونههای تاریخ ترجمه فارسی است. کل کتاب ۱۵۰ صفحه (در قطع جیبی) است و خواندنش دو سه ساعت بیشتر وقت نمیبرد. پیشنهاد میکنم از دستش ندهید.
۳. زمین سوخته (۵ ستاره)
احمد محمود، انتشارات معین، ۱۲۰۰۰ تومان
اولین کتابی بود که از احمد محمود خواندم. خیلی دوستش داشتم و خوشحالم که چند کتاب دیگر دارد و تازه به عقیده خیلیها زمین سوخته بهترین کارش نیست. زمین سوخته از اولین نمونههای ادبیات جنگ است و به عقیده خیلیها بهترین نمونه آن. محمود زمین سوخته را آذر ۶۰ نوشته، یعنی وقتی حدود یک سال از جنگ گذشته بوده و مثلاً خرمشهر هنوز در اشغال عراق بوده. داستان در اهواز میگذرد و زندگی اهوازیها را از دو سه روز قبل از شروع جنگ تا دو سه ماه بعد از آن روایت میکند. خود محمود اهوازی است و تا حدود ۳۰ سالگیاش در این شهر زندگی کرده. خلاصه که انگار این چند هفته را در یکی از محلههای اهواز و زیر موشکباران و بمباران زندگی میکنید. جز تصویر کردن آنچه جنگ داشته بر سر مردم میآورده، دید خوبی هم از وضع مملکت در آن روزهای هنوز انقلابی و حتی نگاه مردم به انقلاب میدهد. و اینکه کتاب در همان روزها نوشته شده و نه بعدتر و با فرضها و قضاوتهای تغییر کرده، خیلی خواندنیترش میکند.
۴. تاریخ سیاسی بیستوپنج ساله ایران (۵ ستاره)
غلامرضا نجاتی، انتشارات رسا، ۲۰ هزار تومان
تاریخ سیاسی ایران از کودتای ۳۲ تا انقلاب ۵۷. نویسنده کتاب وکیل موسسان نهضت آزادی (آقای طالقانی، یدالله سحابی و مهدی بازرگان) در دادگاه زمان شاه بوده و خودش هم به همین دلیل چند سالی زندان بوده. من این کتاب را سالها پیش خواندم و به نظرم برای آشنایی کلی با تاریخ پهلوی دوم کتاب بسیار خوبی است. حدود ۱۰۰۰ صفحه است و تصویر کلی نسبتا جامعی از اوضاع آن دوره، مبارزات و نهایتا شکلگیری انقلاب میدهد. نویسنده طبعا با جریان نهضت آزادی (مصدقیهای مسلمان) همدلی دارد اما به نظرم در مجموع کتاب منصفانهای نوشته. چند سالی از آخرین چاپ این کتاب میگذرد و به همین دلیل به نسبت حجمش واقعا ارزان است. ضمن اینکه در کتابفروشیها راحت پیدا نمیشود و نمایشگاه فرصت خوبی برای خریدنش است.
۵. ظلمت در نیمروز (۵ ستاره)
آرتور کوستلر، مژده دقیقی، نشر ماهی، ۱۲ هزار تومان
ماجرای (نیمهخیالی) یکی از رهبران انقلاب شوروی که حالا در دوره استالین بازداشت شده. کل کتاب روایت روزهای زندان و بازجویی و محاکمه روباشف است. ممکن از بیرون به نظر بیاید یک کتاب تبلیغی ضدکمونیستی است ولی این کتاب واقعا فراتر از اینهاست. روایت تردیدهای روباشف در کنار ظلمی که به او میشود واقعا خواندنی است. این را هم بگویم که در کتاب خبری از شکنجه یا صحنههای آزاردهنده نیست.
۶. پاگرد (۵ ستاره)
محمدحسن شهسواری، نشر افق، ۳۰۰۰ تومان
یکی از بهترین رمانهای ایرانی که خواندهام. داستان از آنجا شروع میشود که در جریان درگیریهای جلوی دانشگاه در روزهای بعد از ۱۸ تیر ۷۸، یکی از کسانی که خانهاش همان حوالی است کسانی را که از دست انصار فرار میکنند در خانهاش پناه میدهد و هر کدام این آدمها قصهای دارند. البته فصلهای مختلف رمان در زمانهای مختلف میگذرند و ما به این ترتیب با بخشی از گذشته این شخصیتها (البته بیشتر یکی دوتایشان) آشنا میشویم.
۷. دنیای کوچک دن کامیلو (۵ ستاره)
جیووانی گوارسکی، جمشید ارجمند، نشر کتاب پرواز، ۱۰ هزار تومان
این کتاب از معدود کتابهایی است که با خیال راحت به همه توصیهاش میکنم و برای خیلیها هم هدیه گرفتهامش. کتاب دو شخصیت اصلی دارد. کشیش و شهردار یک دهکده (قصبه) کوچک در ایتالیای اوایل قرن بیستم. پهپونه (شهردار مزبور) مثل بیشتر شهردارهای آن زمان ایتالیا کمونیست است. البته یک کمونیست بیسواد. دنکامیلو هم که کشیش ده است. این دو تا با هم لج اند و در عین حال همدیگر را خیلی دوست دارند. کل کتاب ماجرای کلکلهای این دو تاست. هر قصه هم چند صفحه بیشتر نیست و تقریباً مستقل است.
۸. دوست بازیافته (۵ ستاره)
فرد اولمن، مهدی سحابی، نشر ماهی، ۵۰۰۰ تومان
یکی از بهترین کتابهایی که در سالیان اخیر خواندهام. به خیلی از دوستانم هم هدیه دادهامش و آنها هم دوست داشتهاند. ماجرا در آلمان پیش و در طول جنگ جهانی دوم میگذرد و درباره تغییر رفتار آلمانیها با یهودیان این کشور است. توصیه میکنم پایانش را زودتر نخوانید که بخش مهمی از جذابیت داستان به پایانش است.
۹. بازمانده روز (۵ ستاره)
کازوئو ایشیگورو، نجف دریابندری، نشر کارنامه، ۲۰ هزار تومان
شاهکار ترجمه.
۱۰. گیرنده شناخته نشد (۵ ستاره)
کاترین کرسمن تیلور، بهمن دارالشفایی، نشر ماهی، ۳۵۰۰ تومان
کتاب کوچکی که خودم ترجمه کردهام. طبعا به نظرم عالی بوده که ترجمهاش کردم. شرح نامهنگاری دو دوست ۴۰ ساله آلمانی است که سالها در امریکا با هم دوست و همکار بودهاند و حالا یکیشان به آلمان برگشته. آن هم درست زمانی که هیتلر دارد به قدرت میرسد. دوستی آنها تحت تاثیر اختلاف نظرهای سیاسی تغییر میکند و الی آخر. خواندنش کمتر از یک ساعت وقت میگیرد.
۱۱. قمارباز (۵ ستاره)
فیودور داستایفسکی، سروش حبیبی، نشر چشمه، ۱۲ هزار تومان
این کتاب را نخوانده بودم چون شنیده بودم ترجمههای موجودش خیلی بد هستند تا اینکه سروش حبیبی دست به کار شد و مستقیم از روسی ترجمهاش کرد. واقعا نمیدانم این کتاب چه داشت که من اینقدر از خواندنش لذت بردم و مسحور شدم که چطور یک نویسنده قرن نوزدهمی میتواند با موضوعی معمولی که کلی نصیحت که لایش چپانده اینطور ۲۵۰ صفحه من را دنبال خودش بکشاند.
۱۲. میکهارته اینجا بود (۵ ستاره)
باربارا پارک، نازنین دیهیمی، نشر ماهی، ۶۵۰۰ تومان
کتابی بسیار خواندنی برای همه کسانی که مرگ عزیزی را تجربه کردهاند. روایت دختری ۱۳ ساله از مواجهه با مرگ برادر ۱۲ سالهاش در یک تصادف. دو سه کتاب دیگر هم از باربارا پارک خواندهام و به نظرم تسلط عجیبی دارد در خودش را جای شخصیت کودک یا نوجوان گذاشتن و از دید او به مسئله نگاه کردن. کتاب با اینکه برای نوجوانان نوشته برای هر کسی که فقدانی را تجربه کرده -یعنی تقریبا همه ما- بسیار خواندنی است. از متن کتاب: «حال من بهتر نشده بود. تا ابد هم بهتر نمیشد. اصلا راستش را بخواهید «بهتر شدن» به نظرم بیغیرتی بود. و برای اینکه مطمئن شوم به بهترین شکلی افسرده هستم و به میک وفادار ماندهام، در راه برگشتن به اتاقم دم در اتاق میک توی راهرو ایستادم. از شب تصادف به بعد دیگر آنجا نایستاده بودم. حالت آن اتاق برایم کاملا فرق کرده بود...»
۱۳. سووشون (۵ ستاره)
سیمین دانشور، انتشارات خوارزمی، ۱۲۰۰۰ تومان
داستان در یکی از شهرهای استان فارس در اوایل پهلوی دوم میگذرد. جنگ جهانی دوم تمام شده و انگلیسیها در جنوب ایران جولان میدهند. یوسف یکی از فئودالهای منطقه است که جلوی انگلیسیها و حاکم شهر ایستاده و راوی کل داستان، زری همسر یوسف است. سووشون از آن کتابهایی بود که هم دلم میخواست چندین ساعت پشت سر هم بخوانمش و هم دلم نمیخواست که تمام شود. من خیلی دوستش داشتم. شخصیتها و فضاها و قصه داستان برایم دوستداشتنی بودند. ضمن اینکه کلی با فضای ایران و فارس و تا حدودی عشایر در دهه ۱۳۲۰ آشنایم کرد.
۱۴. نگذار به بادبادکها شلیک کنند (۵ ستاره)
فریده چیچکاوغلو، فرهاد سخا، نشر ماهی، ۶۵۰۰ تومان
کتاب چندین نامه است. از زبان یک پسر چندساله که در زندان بزرگ شده، چون مادرش زندانی است. او به یکی از زندانیها که دختری جوان و زندانی سیاسی بوده و اخیرا آزاد شده، نامه مینویسد و ماجراهای زندان را برایش تعریف میکند.
خود نویسنده چند سالی زندانی سیاسی بوده. این کتاب را ۲۵ سال پیش نوشته و همان موقع به فارسی ترجمه و یک بار چاپ شده. چند ماه پیش دوستم اسماعیل توصیه کرد بخوانمش و به همکارانم در نشر ماهی پیشنهاد چاپ دوبارهاش را بدهم. دوستم صنم کمک کرد که مترجم را در استانبول پیدا کنیم و بعد هم ادامه کارها.
۱۵. اشغال، تصویر سیزدهم (۵ ستاره)
محمدرضا ابوالحسنی، انتشارات روایت فتح
کتاب روايت ۴۵ روز مقاومت در خرمشهر است. مقاومتی که به سقوط اين شهر منجر شد و کمتر از دو سال بعد از آن خرمشهر در غياب بيشتر کسانی که ۴۵ روز به آب و آتش زدند تا نشود آنچه شد، از دست عراقیها بيرون آمد. این کتاب ۱۳ تصوير است از آن روزها که از لابهلای خاطرات آنهايی که ماندهاند بازسازی شده است. کمحجم است و بسیار خواندنی.
۱۶. کپنهاگ (۵ ستاره)
مایکل فرین، حمید احیاء، انتشارات نیلا، ۹۶ صفحه، ۵۰۰۰ تومن
نمایشنامهای درباره دیدار چند دقیقهای نیلز بور و هایزنبرگ در سال ۱۹۴۱ در کپنهاگ. دیداری که در عالم واقع بین این استاد و شاگرد سابق اتفاق افتاده و تا مدتها (و هنوز) دقیقاً معلوم نیست که در آن دیدار چه بین این دو نفر گذشته. دو نفری که از بزرگترین دانشمندان اتمی زمان خودشان و حتی کل قن بیستم بوده اند. آن هم درست در زمانی که بمب اتم داشته ساخته میشده. معرفی مفصلتر
۱۷. فلسفه سیاسی (۵ ستاره)
دیوید میلر، بهمن دارالشفایی، نشر ماهی، ۸۰۰۰ تومان
ترجمه من از یکی از عناوین مجموعه مختصرمفید انتشارات اکسفورد. به نظر من یکی از بهترین عناوین این مجموعه است و یکی از بهترین کتابهایی که در زمینه فلسفه سیاسی به فارسی ترجمه شده (نه چون من ترجمهاش کردهام خوب است بلکه برعکس. یعنی چون به نظرم خیلی خوب بوده ترجمهاش کردهام). کتاب اصلا تخصصی نیست و به نظر من هر کسی که به مسائل سیاسی در معنای عامش فکر میکند از خواندن این کتاب کلی چیز یاد خواهد گرفت و لذت خواهد برد.
۱۸. سور بز (۵ ستاره)
ماریو بارگاس یوسا، عبدالله کوثری، ۶۲۳ صفحه، ۲۸ هزار تومان
رمانی سیاسی - تاریخی درباره دوران حکومت تروخیو، دیکتاتور جمهوری دومینیکن در دهههای میانی قرن بیستم، و ماجرای ترور او. من خودم به خاطر اسمش مدتها سراغ این کتاب نرفته بودم ولی وقتی دستش گرفتم نمیتوانم زمین بگذارمش. معرفی کاملتر
۱۹. به یاد کاتالونیا (۵ ستاره)
جورج اورول، عزتالله فولادوند، انتشارات خوارزمی، ۱۲۰۰۰ تومان
روایت جورج اورول از چند ماه حضورش در جبهههای جنگ داخلی اسپانیا و جنگیدن در کنار آنارشیستها (یا شاید هم سوسیالیستها؛ دقیق یادم نیست). هم موضوع برای من خیلی جالب بود، هم قلم اورول عالی است و هم ترجمه فولادوند.
۲۰. میشائیل کلهاس و سه داستان دیگر (۵ ستاره)
هاینریش فون کلایست، محمود حدادی، نشر ماهی، ۱۸۴ صفحه، ۶۵۰۰ تومان
داستان ظلمی که در آلمان فرن هجدهم به یک آدم معمولی میرود و او میایستد تا حقش را بگیرد و چون هیچ راه معقولی پیدا نمیکند، کم کم میشود یک شورشی تمام و کمال. کتاب عالی نوشته شده و کافکا و هرمان هسه هم تعریفهای شدید و غلیظی ازش کردهاند. اگر «رگتایم» نوشته ای. ال. دکتروف را هم خواندهاید بدانید که دکتروف خط اصلی داستانش را از این داستان گرفته و حتی اسم شخصیت اصلی داستانش (کلهاس واکر) هم از میشائیل کلهاس گرفته شده. البته باید بگویم ترجمه کتاب چندان خوب نیست ولی به نظرم داستان آنقدر خوب است که همین ترجمه هم به خواندن میارزد. معرفی کاملتر
۲۱. همنوایی شبانه ارکستر چوبها (۵ ستاره) رضا قاسمی، نشر نیلوفر، ۷۵۰۰ تومان
قاعدتاً همهتان تا حالا این رمان را خواندهاید. ولی اگر مثل من هر بار به هر دلیلی نشده که سراغش بروید، پیشنهاد میکنم که این کار را بکنید. بالاخره بعد از مدتها یک «رمان» به زبان فارسی خواندم. یک سری از منتقدان این کتاب را بهترین کتاب داستانی دهه ۸۰ هم دانستهاند که به نظرم انتخاب بیربطی نیست.
۲۲. مکتب در فرایند تکامل (۵ ستاره)
حسین مدرسی طباطبایی، ترجمه هاشم ایزدپناه، انتشارات کویر، ۱۳۵۰۰ تومان
کتابی درباره تاریخ تکوین شیعه در سه قرن اول. کلی اطلاعات جالب از امامان شیعه دارد. اطلاعاتی متفاوت با روایت رسمی که در کتابهای درسی میخوانیم و بعد هم در خانوادهها و بیشتر جلسههای مذهبی و رادیو و تلویزیون میشنویم. آن هم اطلاعاتی که به نظر میرسد در درون خود علمای شیعه تا حد زیادی پدیزفته شده است و انگار حکومت ایران یکی از روایتهای شیعه را دارد به عنوان تنها روایت معتبر به همه ما میقبولاند. معرفی کاملتر
۲۳. اختناق ایران (۵ ستاره)
مورگان شوستر، حسن افشار، نشر ماهی، ۱۲ هزار تومان
کتابی که مورگان شوستر، مستشار آمریکایی در ایران در سالهای بعد از مشروطه، درباره دوره حضورش در ایران نوشته. یکی از بهترین منابع درباره سالهای مشروطه دوم (بعد از استبداد صغیر) و فهمیدن نقش مخرب در درجه اول روسیه و در درجه دوم انگلیس در شکست مشروطه. اصل انگلیسی کتاب. معرفی کاملتر
۲۴. یک گفتوگو با نجف دریابندری (۵ ستاره)
ناصر حریری، نشر کارنامه، ۵۰۰۰ تومان
شیرینزبانتر از نجف دریابندری کم داریم. اگر به کتاب و نشر و تاریخ و فرهنگ و اینجور چیزها علاقه دارید خواندن این گفتوگوی مفصل با نجف واقعا لذتبخش است.
۲۵. تومار شیخ شرزین (۵ ستاره) بهرام بیضایی، انتشارات روشنگران و مطالعات زنان من کلاً کارهای بهرام بیضایی را دوست دارم، اما این یکی از بهترین نمایشنامههایی بود که ازش خواندم.
۲۶. فلسفه علم (۵ ستاره)
سمیر اکاشا، هومن پناهنده، انتشارات فرهنگ معاصر، ۲۱۲ صفحه٬ ۴۵۰۰ تومان
این کتاب هم از همان مجموعه «مقدمههای بسیار کوتاه» انتشارات آکسفورد است که من «فلسفه سیاسی» و «سیاست»اش را ترجمه کردهام. البته این را نه نشر ماهی، که فرهنگ معاصر منتشر کرده. من فکر میکنم هر کسی که دورهای از زندگیاش با علم (در درجه اول فیزیک و بعد شیمی و ریاضی و همه علوم دیگر) سر و کار داشته و کمی، فقط کمی، علاقه هم به آنها داشته (یعنی مثلاً هر کسی که مهندسی خوانده) از خواندن این کتاب لذت میبرد. حتی فکر میکنم اگر صرفاً به استدلال و منطق هم علاقه داشته باشید این کتاب برایتان جذاب خواهد بود. از ترجمه روان و کمنقص آقای پناهنده هم هر چه بگویم کم گفتهام. آقای پناهنده فکر کنم یکی از دقیقترین و ماهرترین ویراستاران ایران است و این ترجمهاش هم بدون اغراق یکی از بهترین و روانترین ترجمههایی بود که من اخیراً خواندهام.
۲۷. محاکمه (۵ ستاره)
فرانتس کافکا، علی اصغر حداد، نشر ماهی، ۲۷۰ صفحه، ۱۱ هزار تومان
کلاسیکها که نیاز به معرفی ندارند. یک داستان تکاندهنده. یک آدم عادی بیگناه که یک روز صبح دو نفر میآیند توی خانهاش و برای محاکمه میبرندش و تا آخر هم نمیفهمد برای چی دارند محاکمهاش میکنند.
۲۸. آنا کارنینا (۵ ستاره)
لئون تولستوی، سروش حبیبی، نشر نیلوفر، ۳۸ هزار تومان
تنها کتاب از این فهرست که هنوز تا ته نخواندهامش. ولی خب ۳۰۰-۴۰۰ صفحهای خواندهام و میتوانم بگویم واقعا الکی نیست که کتابی میشود شاهکار و کلاسیک و ... یک رمان واقعی با چندین خط داستانی که همهشان در طول هزار صفحه با جزئیات پیش میروند و اصلا هم خستهکننده نمیشوند.
۲۹. ناپدیدشدگان (۵ ستاره)
آریل دورفمن، احمد گلشیری، نشر آفرینگان (ققنوس)، ۹۵۰۰ تومان
اسم اصلی کتاب بیوهها است. این کتاب در یونان دوره سرهنگان میگذرد و درباره روستایی است که مردانش یکی یکی ناپدید میشوند و بعد جنازهشان در رودخانه پیدا میشود. کتاب از جایی شروع میشود که زنان روستا برخاستهاند و از مقامهای نظامی روستا میخواهند که جواب بدهند. دورفمن در کتاب خاطراتش توضیح میدهد که برای اینکه این کتاب بتواند در شیلی چاپ شود مکان داستان را به یونان برده و قرار بوده کتاب با یک اسم مستغار منتشر شود و گونتر گراس بگوید این داستان را یک نویسنده ناشناس یونانی نوشته که در دوره سرهنگان کشته شده و بعد هم یک نویسنده معروف اسپانیاییزبان به اسپانیایی ترجمهاش کند و با این عنوان در شیلی منتشر شود. البته نهایتاً این پروژه اجرا نمیشود و کتاب بعد از چند سال با اسم خود دورفمن در شیلی چاپ میشود.
۳۰. انقلاب مشروطه ایران (۵ ستاره)
ژانت آفاری، ترجمه رضا رضایی، نشر بیستون، ۲۰ هزار تومان
ژانت آفاری از محققان مهم تاریخ جنبشهای اجتماعی ایران است و در این کتاب سعی کرده نقش سازمانهای مردمی را در انقلاب کشف کند و چون همیشه تاریخ از زاویه دید حاکمان و سیاستمداران نوشته میشده برای این کار مجبور بوده کلی خاطرات و اسناد ریز و درشت را بخواند. در این کتاب خیلی بیشتر از آنکه اسم سید محمد طباطبایی روحانی بزرگ مشروطه اورده شود اسم اعضای انجمنهای شهری تبریز و رشت و تهران را میبینیم. در صورتی که مثلاً در کتاب کسروی یا تاریخ بیداری کاملاً برعکس است. اگر این کتاب را بخوانید به وضوح میبینید که ایرانیها حدود صد سال پیش چقدر جلو بودند و در بعضی زمینهها حتی از الآن هم جلوتر بودند.
جنبشهای زنان در عصر مشروطه -که به گفته بعضی خارجیها از جنبشهای همدوره اروپاییشان مترقیتر بودند- متفکران سوسیال دموکرات -که الآن در ایران کلاً خبری ازشان نیست- انجمنهای مردمی و خیلی نهادهای دیگر که شاید خیلیهامان فکر میکنیم هیچ وقت در ایران نبوده در عصر مشروطه وجود داشته. کلاً وقتی این کتاب را میخواندم فکر میکردم چقدر اشتباهات سیاستمداران ما شبیه اشتباهات اسلاف مشروطهچیشان بوده و چقدر مرتجعین ایرانی شبیه نمونههای صد سال پیششان هستند و چقدر اختلافها و دعواها همان است. شنیدهام حدود پانزده سال پیش که این کتاب چاپ شد سعید حجاریان به شاخه جوانان جبهه مشارکت توصیه کرده آن را در برنامه مطالعهشان بگذارند و آنها هم چنین کردهاند و چقد توصیه خوبی بوده.
۳۱. چهرههایی از پدرم (۵ ستاره)
ثمین باغچهبان، نشر قطره، ۳۵۰۰ تومان کتابی که ثمین باغچهبان درباره پدرش جبار باغچهبان نوشته. فکر کنم همین دو تا اسم کافی باشند و من چیزی بیشتر برای ترغیب به خواندن این کتاب ندارم که بگویم. روایت این اراده عجیب و غریب جبار باغچهبان واقعاً خواندنی است.
۳۲. بیست و یک داستان از نویسندگان معاصر فرانسه (۵ ستاره)
ترجمه ابوالحسن نجفی، انتشارات نیلوفر، ۱۸۰۰۰ تومان
دلیل اصلی که این کتاب را پیشنهاد میکنم ترجمه نجفی است. من کلا داستان کوتاه دوست ندارم ولی واقعا از خواندن این کتاب لذت بردم که دلیل اصلیش برای من ترجمه روان نجفی بود. اگر معیار خوب بودن ترجمه را این بگیریم که ترجمه کاملا فارسی باشد و از ساخت غیرفارسی هیچ اثری در آن نباشد، به نظرم ابوالحسن نجفی بهترین مترجم ایران است.
۳۳. جدال با جهل؛ گفتگو با بهرام بیضایی (۵ ستاره) نوشابه امیری، نشر ثالث، ۶۰۰۰ تومان
بهرام بیضایی یکی از روشنفکرترین ایرانیهایی است که میشناسم. روشنفکر در معنای واقعی کلمه. یعنی اینکه ذهن نقادی دارد. نوشابه امیری سوالهای خوبی کرده و جوابهای بیضایی هم واقعاً خواندنی هستند. کتاب کمحجمی است و تقریباً مطمئنم از خواندنش پشیمان نمیشوید.
۳۴. بیگانه (۵ ستاره) آلبر کامو، خشایار دیهیمی، نشر ماهی، ۷۰۰۰ تومان
فکر میکنم این کتاب دیگر واقعاً نیاز به تعریف ندارد. فقط این را بگویم که خشایار دیهیمی عاشق کامو است و به دیوار دفترش هم یک پوستر از کامو زده. میدانم این ترجمه با عشق انجام شده. البته آقای دیهیمی به فرانسه مسلط نیست، اما میدانم که متن اصلی فرانسه و چند ترجمه انگلیسی مختلف از بیگانه را جلویش داشت و کتاب را ترجمه کرد. خلاصه که داستان عالی، ترجمه عالی، چاپ هم عالی.
۳۵. تاریخ چیست؟ (۵ ستاره)
ای. اچ. کار، حسن کامشاد، انتشارات خوارزمی، ۱۱ هزار تومان
اگر اهل تاریخ خواندن هستید این کتاب را بخوانید. توضیحی از یکی از مهمترین مورخان قرن بیستم درباره تاریخنگاری و نقش مورخ و ...
***
۳۶. از من نخواهید لبخند بزنم (۴ و نیم ستاره)
باربارا پارک، نازنین دیهیمی، نشر ماهی، ۶۵۰۰ تومان
اگر بچه طلاق یا زوج بچهدار طلاقگرفته اطرافتان دارید این کتاب را بهشان پیشنهاد کنید. به نظرم مسئله مواجه شدن یک کودک/نوجوان ۱۱ ساله با طلاق پدر و مادرش از زاویه دید کودک را خیلی خوب نشان داده. بقیه کتابهای مجموعه هم که درباره مواجه شدن یککودک همین سنی با ازدواج مجدد مادر، حسادت به برادر کوچکتر و مرگ برادر هستند خیلی خواندنیاند.
۳۷. مدرک (۴ و نیم ستاره)
آگوتا کریستوف، اصغر نوری، نشر مروارید، ۸۵۰۰ تومان
قسمت دوم از سهگانهای که «دفتر بزرگ» اولیش است. آن دو برادر حالا سی و چند ساله شدهاند. این هم خیلی خواندنی است ولی نه به تاثیرگذاری اولی. قسمت سوم این سهگانه (دروغ سوم) هم از دیروز توزیع شده و من هنوز نخواندهامش.
۳۸. کنستانسیا (۴ و نیم ستاره)
کارلوس فوئنتس، عبدالله کوثری، نشر ماهی، ۴۵۰۰ تومان
اگر ادبیات آمریکای لاتین و آن فضاهای عجیبش را دوست دارید این یکی از بهترین نمونههایش است که خیلی خوب هم ترجمه شده. فضایی شبیه آئورا دارد، ولی نه آنقدر جادویی.
۳۹. آینههای دردار (۴ و نیم ستاره)
هوشنگ گلشیری، نشر نیلوفر، ۳۵۰۰ تومان
نویسندهای برای چند جلسه کتابخوان و سخنرانی از ایران به اروپا میرود و در آنجا به چند دوست از جمله یکی از عشقهای دوران نوجوانیاش روبرو میشود.
۴۰. سوءظن (۴ و نیم ستاره)
فریدریش دورنمات، محمود حسینیزاد، نشر ماهی، ۵۵۰۰ تومان
یک داستان پلیسی-جنایی دیگر که هیچ ربطی به ژانر پلیسی-جنایی ندارد و مثلا من که اگر داستان پلیسی دوست ندارم خیلی از خواندنش لذت بردم. پلیس اصلی داستان پیرمردی است به نام برلاخ. یک پیرمرد نسبتاً لجباز، مریضِ روبهموت و بسیار جذاب. بیشتر از این نمیتوانم درباره داستان بنویسم، چون در خواندن داستان جنایی آدم هرچه کمتر اطلاعات داشته باشد بیشتر لذت میبرد. داستان در سوئیس و در اولین سالهای بعد از جنگ جهانی دوم میگذرد و مایه سیاسی دارد. «قول» و «قاضی و جلادش» از همین نویسنده و مترجم و ناشر هم خواندنی هستند.
۴۱. سه نفر در برف (۴ و نیم ستاره)
رمان درباره میلیونری است که لباس مبدل گدایان میپوشد و به هتل گرانقیمتی میرود و ... اما داستان به این سرراستی که به نظر میرسد نیست و مهمتر اینکه فضای داستان در مجموع شاد است.
۴۲. رویای آدم مضحک (۴ و نیم ستاره)
فیودور داستایفسکی، رضا رضایی، نشر ماهی، ۷۵۰۰ تومان
هفت داستان کوتاه خواندنی از داستایفسکی. با ترجمهای خوب.
۴۳. مجموعه آثار جین آستین (۴ و نیم ستاره)
جین آستین، رضا رضایی، نشر نی
رضا رضایی از حدود ده سال پیش شروع کرد به ترجمه آثار نویسندههای زن قرن نوزدهمی انگلیس. اول شش کتاب از جین آستین و بعد هفت کتاب از خواهران برونته. حالا هم دارد ۹ کتاب از جورج الیوت ترجمه میکند. من دو سه تا از کتابهای آستین را خواندهام و واقعا دوست داشتهام. اگر مثل من کارهای کلاسیک را دوست دارید، این بهترین نمونههای ادبیات کلاسیک انگلستان را از دست ندهید.
۴۴. زندگینامه آیزایا برلین (۴ و نیم ستاره)
مایکل ایگناتیف، عبدالله کوثری، نشر ماهی، ۵۶۸ صفحه، ۱۱۵۰۰ تومان
ایگناتیف چندین سال هر روز با برلین مصاحبه میکرده تا این زندگینامه را بنویسد. با اینکه من علاقه خیلی ویژهای به برلین ندارم ولی خواندن زندگینامهاش لذتبخش و آموزنده بود. بخصوص به جهت تنوع کارهایی که در زندگی کرده. از خبرنگاری و کار دانشگاهی بگیر تا فلسفه و کار برای سازمانهای جاسوسی و ارتباط با سازمانهای صهیونیستی. ضمنا چون چاپ اول کتاب مال پیش از گران شدن دلار است قیمت کتاب به نسبت حجمش واقعا ارزان است. قیمت این کتاب اگر همین الان تجدیدچاپ شود دستکم دو برابر خواهد بود.
۴۵. بالاخره این زندگی مال کیه؟ (۴ و نیم ستاره)
برایان کلارک، احمد کساییپور، نشر کارنامه، ۱۴۰ صفحه، ۹۵۰۰ تومان
یک نمایشنامه. یک مجسمهساز تصادف میکند و هم زن و بچهاش را از دست میدهد و هم از گردن به پایین فلج میشود. این آقا میخواهد بمیرد و چون خودش نمیتواند هیچ کاری بکند، دیگران باید بکشندش. کل این نمایشنامه کوتاه، بحثهای این آقاست با دکترها و پرستارها و خدمه بیمارستان، و کار حتی به دادگاه و قاضی هم میکشد. معرفی کاملتر
۴۶. خانواده پاسکوآل دوآرته (۴ و نیم ستاره)
کامیلو خوسه میلا، فرهاد غبرایی، نشر ماهی، ۱۹۳ صفحه (جیبی)، ۶ هزار تومان
ماجرای زندگی یک اسپانیایی روستایی. تکاندهنده و در خیلی جاها دردناک. فکر نکنید که در آن قالب آشنای روستایی زحمتکش و ارباب ظالم نوشته شده. اساساً فضای دیگری دارد. واقعا هم خوب نوشته شده. نویسندهاش سال ۱۹۸۹ نوبل گرفته.
۴۷.مردی که گورش گم شد (۴ و نیم ستاره)
حافظ خیاوی، نشر چشمه، ۹۶ صفحه، ۳۵۰۰ تومان
مجموعهای از ۷ داستان کوتاه با حال و هواهای مختلف، که بیشترشان برای من دوست داشتنی و دلچسب بودند. مثل خیلی از داستان کوتاههای فارسی که خواندهام بازی صرف با کلام نیستند. این مجموعه در سال ۸۶ یکی دو تا جایزه هم برده.
۴۸. تیستوی سبزانگستی (۴ و نیم ستاره)
موریس دروئون، للی گلستان، نشر ماهی، ۷۵۰۰ تومان
یک کتاب نوجوان ضدجنگ که من هم از خواندنش لذت بردم. کتاب را بار اول انتشارات کانون پرورش فکری در سال ۱۳۵۱ منتشر کرد ولی از چند سال پیش نشر ماهی تجدیدچاپش میکند.
۴۹. و نیچه گریه کرد (۴ و نیم ستاره) اروین یالوم، مهشید میرمعزی، نشر نی، ۱۳۸۰۰ تومان
کتابی که شخصیتهای اصلیاش نیچه، دختری که نیچه عاشقش است، یک روانکاو معروف همدوره او که پزشک معالج نیچه است، همسر روانکاو و فروید هستند. نمیدانم چقدرش واقعی است و چقدرش داستان. اما خیلی خوشخوان است و آدم را هم حسابی درگیر میکند.
۵۰. بر بال بحران؛ زندگی سیاسی علی امینی (۴ و نیم ستاره)
ایرج امینی، نشر ماهی، ۱۵ هزار تومان
علی امینی از ردهبالاترین رجال سیاسی پهلوی بوده. شاید همتراز قوام و مصدق. از آنهایی که شاه همیشه ازشان میترسیده که یک وقت جایش را بگیرند. پسر خانم فخرالدوله (همان کسی که رضا شاه گفته بود قاجار اگر یک مرد داشته باشد خانم فخرادوله است) و نوه امینالدوله صدراعظم. با اینکه کتاب را ایرج، پسر علی امینی، نوشته اما یک تحقیق تاریخی واقعی است. یعنی صرفاً نیامده خاطرات یا یادداشتهای پدرش را کتاب کند. رفته اسناد و مدارک را گشته و با آدمهای درگیر گفتگو کرده. البته در نهایت نمیتوان نگاه در کل مثبت پسر به پدر را نادیده گرفت. کتاب نسبتاً مفصلی است، اما اگر به تاریخ معاصر علاقه دارید بسیار خواندنی است. فقط یک نکته و آن هم اینکه صرفاً با خواندن این کتاب نمیتوانید تصویر دقیقی از دورههایی که دربارهاش صحبت میشود، بخصوص بعد کودتا که امینی دورهای نخستوزیر شد، بدست بیاورید. یا شاید حتی باعث شود تصویر نادرستی از فضای سیاسی آن زمان در ذهنتان شکل بگیرد. چون هر چه باشد این کتاب با محوریت فعالیتهای سیاسی علی امینی نوشته شده و طبیعتاً بعضی از بخشهای مهم سیاست آن روزها در این کتاب غایب یا خیلی کمرنگ است. این هم از آن کتابهایی است که اگر تجدیدچاپ شود کلی گرانتر میشود.
۵۱. سهرابکشان (۴ و نیم ستاره)
بهرام بیضایی، انتشارات روشنگران و مطالعات زنان این هم خیلی خوب بود.
۵۲. مکتب دیکتاتورها (۴ و نیم ستاره)
اینیاتسیو سیلونه، مهدی سحابی، نشر ماهی، ۷۰۰۰ تومان
به نقل از پشت جلد کتاب: "در آستانه جنگ جهانی دوم، یک جوجهدیکتاتور آمریکایی به اروپا آمده تا از تجارب طولانی اروپاییها در زمینه دیکتاتوری درس بگیرد، به آمریکا برگردد و در آنجا هم یک نظام استبدادی برقرار کند. برای فراگیری شگردها و رموز دیکتاتوری به سراغ کسی میرود که عمری را در مبارزه با استبداد گذرانده است، چرا که منطق حکم میکند که «حقیقت از زبان دشمن شنیده شود». مکتب دیکتاتورها ... شرح این جلسات درس دیکتاتور آمریکایی است." مکتب دیکتاتورها را اینیاتسیو سیلونه نوشته که مدتی نایب رئیس حزب کمونیست ایتالیا بوده و با قدرت گرفتن استالین در شوروی، از حزب استعفا داده و آمده بیرون.
۵۳. در جستجوی فردی (۴ و نیم ستاره)
آریل دورفمان، عبدالله کوثری، انتشارات لوح فکر، ۵۰۰۰ تومان
۵۴. جامعهشناسی دین (۴ و نیم ستاره)
۵۵. مترجم دردها (۴ و نیم ستاره)
جومپا لاهیری، امیرمهدی حقیقت، نشر ماهی، ۱۶۰۰۰ تومان
مترجم دردها اولین کتاب لاهیری است و مجموعهای از ۹ داستان کوتاه. من ۶ تایشان را خواندهام و واقعاً لذت بردهام. مخصوصاً دو سه تاش خیلی تکاندهنده بودند. مثلاً اولین داستان مجموعه (موضوع موقت) یا خود داستان مترجم دردها. لاهیری برای مترجم دردها در سال ۲۰۰۰ جایزه پولیتزر گرفت.
۵۶. فاشیسم (۴ و نیم ستاره)
کوین پاسمور، علی معظمی، نشر ماهی، ۴۵۰۰ تومان
از مجموعه مختصر مفید. خواندنی است با ترجمهای خوب.
۵۷. بینام (چهار و نیم ستاره)
۵۸. عطر گوابا؛ گفتگوبا گابریل گارسیا مارکز (چهار و نیم ستاره)
۵۹. گزارش یک مرگ (۴ و نیم ستاره)
***
و در نهایت یک پیشنهاد ویژه. اولین رمانی که خواهرم نوشته و پارسال چاپ شد. نمیگویم عالی است ولی مطمئنم از خیلی از رمانهای ایرانی که چاپ میشود بهتر و خواندنیتر است. حداقل خیالم راحت است که حوصلهتان از خواندنش سر نمیرود:
این یکی را هم کامل نخواندهام ولی اگر به جنگ ایران و عراق علاقه دارد، پیشنهادش میکنم:
کامنتها
مهدی فرجی
کاروان ها در سکوت و دزدها در قال و قیل
سال ها این دشت نشنیده است آوای رحیل
کوچ کردن قصه شد، مردانه ماندن یک خیال
کودکان افسانه می بافند از مردان ایل
بوی رخوت راه های دشت را پر کرده است
روز باران گله را خوابانده چوپان در مسیل
غرق در افسون فرعونی کسی راهی نشد
پا به پای اعتقاد هیچ موسایی به نیل
بر زمین تا چشم می بیند مترسک کاشتند
در فراسوی زمان مُردند مردان اصیل
انتهای هیچ راهی منزلی پیدا نبود
جاده ها آزرده از یک امتداد بی دلیل
Understand JavaScript Callback Functions and Use Them
(Learn JavaScript Higher-order Functions, aka Callback Functions)
In JavaScript, functions are first-class objects; that is, functions are of the type Object and they can be used in a first-class manner like any other object (String, Array, Number, etc.) since they are in fact objects themselves. They can be “stored in variables, passed as arguments to functions, created within functions, and returned from functions”1.
Our Career Paths and Courses Website Is Now Live
New UPDATE: June 8, 2015
Enrollment for our Career Paths is well underway. Enroll now. Career Path 1: Junior JavaScript Developer and Career Path 3: Modern Frontend Developer are already full (you may still get a spot if you join the wait list now).
The second cohort for Career Path 5: Modern Fullstack Developer is also full. The second cohort starts immediately after the first cohort of Career Path 3 graduates.
Because functions are first-class objects, we can pass a function as an argument in another function and later execute that passed-in function or even return it to be executed later. This is the essence of using callback functions in JavaScript. In the rest of this article we will learn everything about JavaScript callback functions. Callback functions are probably the most widely used functional programming technique in JavaScript, and you can find them in just about every piece of JavaScript and jQuery code, yet they remain mysterious to many JavaScript developers. The mystery will be no more, by the time you finish reading this article.
Callback functions are derived from a programming paradigm known as functional programming. At a fundamental level, functional programming specifies the use of functions as arguments. Functional programming was—and still is, though to a much lesser extent today—seen as an esoteric technique of specially trained, master programmers.
Fortunately, the techniques of functional programming have been elucidated so that mere mortals like you and me can understand and use them with ease. One of the chief techniques in functional programming happens to be callback functions. As you will read shortly, implementing callback functions is as easy as passing regular variables as arguments. This technique is so simple that I wonder why it is mostly covered in advanced JavaScript topics.
What is a Callback or Higher-order Function?
A callback function, also known as a higher-order function, is a function that is passed to another function (let’s call this other function “otherFunction”) as a parameter, and the callback function is called (or executed) inside the otherFunction. A callback function is essentially a pattern (an established solution to a common problem), and therefore, the use of a callback function is also known as a callback pattern.
Consider this common use of a callback function in jQuery:
//Note that the item in the click method's parameter is a function, not a variable.
//The item is a callback function
$("#btn_1").click(function() {
alert("Btn 1 Clicked");
});
As you see in the preceding example, we pass a function as a parameter to the click method. And the click method will call (or execute) the callback function we passed to it. This example illustrates a typical use of callback functions in JavaScript, and one widely used in jQuery.
Ruminate on this other classic example of callback functions in basic JavaScript:
var friends = ["Mike", "Stacy", "Andy", "Rick"];
friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick
});
Again, note the way we pass an anonymous function (a function without a name) to the forEach method as a parameter.
So far we have passed anonymous functions as a parameter to other functions or methods. Lets now understand how callbacks work before we look at more concrete examples and start making our own callback functions.
How Callback Functions Work?
We can pass functions around like variables and return them in functions and use them in other functions. When we pass a callback function as an argument to another function, we are only passing the function definition. We are not executing the function in the parameter. In other words, we aren’t passing the function with the trailing pair of executing parenthesis () like we do when we are executing a function.
And since the containing function has the callback function in its parameter as a function definition, it can execute the callback anytime.
Note that the callback function is not executed immediately. It is “called back” (hence the name) at some specified point inside the containing function’s body. So, even though the first jQuery example looked like this:
//The anonymous function is not being executed there in the parameter.
//The item is a callback function
$("#btn_1").click(function() {
alert("Btn 1 Clicked");
});
the anonymous function will be called later inside the function body. Even without a name, it can still be accessed later via the arguments object by the containing function.
Callback Functions Are Closures
When we pass a callback function as an argument to another function, the callback is executed at some point inside the containing function’s body just as if the callback were defined in the containing function. This means the callback is a closure. Read my post, Understand JavaScript Closures With Ease for more on closures. As we know, closures have access to the containing function’s scope, so the callback function can access the containing functions’ variables, and even the variables from the global scope.
Basic Principles when Implementing Callback Functions
While uncomplicated, callback functions have a few noteworthy principles we should be familiar with when implementing them.
Use Named OR Anonymous Functions as Callbacks
In the earlier jQuery and forEach examples, we used anonymous functions that were defined in the parameter of the containing function. That is one of the common patterns for using callback functions. Another popular pattern is to declare a named function and pass the name of that function to the parameter. Consider this:
// global variable
var allUserData = [];
// generic logStuff function that prints to console
function logStuff (userData) {
if ( typeof userData === "string")
{
console.log(userData);
}
else if ( typeof userData === "object")
{
for (var item in userData) {
console.log(item + ": " + userData[item]);
}
}
}
// A function that takes two parameters, the last one a callback function
function getInput (options, callback) {
allUserData.push (options);
callback (options);
}
// When we call the getInput function, we pass logStuff as a parameter.
// So logStuff will be the function that will called back (or executed) inside the getInput function
getInput ({name:"Rich", speciality:"JavaScript"}, logStuff);
// name: Rich
// speciality: JavaScript
Pass Parameters to Callback Functions
Since the callback function is just a normal function when it is executed, we can pass parameters to it. We can pass any of the containing function’s properties (or global properties) as parameters to the callback function. In the preceding example, we pass options as a parameter to the callback function. Let’s pass a global variable and a local variable:
//Global variable
var generalLastName = "Clinton";
function getInput (options, callback) {
allUserData.push (options);
// Pass the global variable generalLastName to the callback function
callback (generalLastName, options);
}
Make Sure Callback is a Function Before Executing It
It is always wise to check that the callback function passed in the parameter is indeed a function before calling it. Also, it is good practice to make the callback function optional.
Let’s refactor the getInput function from the previous example to ensure these checks are in place.
function getInput(options, callback) {
allUserData.push(options);
// Make sure the callback is a function
if (typeof callback === "function") {
// Call it, since we have confirmed it is callable
callback(options);
}
}
Without the check in place, if the getInput function is called either without the callback function as a parameter or in place of a function a non-function is passed, our code will result in a runtime error.
Problem When Using Methods With The this Object as Callbacks
When the callback function is a method that uses the this object, we have to modify how we execute the callback function to preserve the this object context. Or else the this object will either point to the global window object (in the browser), if callback was passed to a global function. Or it will point to the object of the containing method.
Let’s explore this in code:
// Define an object with some properties and a method
// We will later pass the method as a callback function to another function
var clientData = {
id: 094545,
fullName: "Not Set",
// setUserName is a method on the clientData object
setUserName: function (firstName, lastName) {
// this refers to the fullName property in this object
this.fullName = firstName + " " + lastName;
}
}
function getUserInput(firstName, lastName, callback) {
// Do other stuff to validate firstName/lastName here
// Now save the names
callback (firstName, lastName);
}
In the following code example, when clientData.setUserName is executed, this.fullName will not set the fullName property on the clientData object. Instead, it will set fullName on the window object, since getUserInput is a global function. This happens because the this object in the global function points to the window object.
getUserInput ("Barack", "Obama", clientData.setUserName);
console.log (clientData.fullName);// Not Set
// The fullName property was initialized on the window object
console.log (window.fullName); // Barack Obama
Use the Call or Apply Function To Preserve this
We can fix the preceding problem by using the Call or Apply function (we will discuss these in a full blog post later). For now, know that every function in JavaScript has two methods: Call and Apply. And these methods are used to set the this object inside the function and to pass arguments to the functions.
Call takes the value to be used as the this object inside the function as the first parameter, and the remaining arguments to be passed to the function are passed individually (separated by commas of course). The Apply function’s first parameter is also the value to be used as the this object inside the function, while the last parameter is an array of values (or the arguments object) to pass to the function.
This sounds complex, but lets see how easy it is to use Apply or Call. To fix the problem in the previous example, we will use the Apply function thus:
//Note that we have added an extra parameter for the callback object, called "callbackObj"
function getUserInput(firstName, lastName, callback, callbackObj) {
// Do other stuff to validate name here
// The use of the Apply function below will set the this object to be callbackObj
callback.apply (callbackObj, [firstName, lastName]);
}
With the Apply function setting the this object correctly, we can now correctly execute the callback and have it set the fullName property correctly on the clientData object:
// We pass the clientData.setUserName method and the clientData object as parameters. The clientData object will be used by the Apply function to set the this object
getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
// the fullName property on the clientData was correctly set
console.log (clientData.fullName); // Barack Obama
We would have also used the Call function, but in this case we used the Apply function.
Multiple Callback Functions Allowed
We can pass more than one callback functions into the parameter of a function, just like we can pass more than one variable. Here is a classic example with jQuery’s AJAX function:
function successCallback() {
// Do stuff before send
}
function successCallback() {
// Do stuff if success message received
}
function completeCallback() {
// Do stuff upon completion
}
function errorCallback() {
// Do stuff if error received
}
$.ajax({
url:"http://fiddle.jshell.net/favicon.png",
success:successCallback,
complete:completeCallback,
error:errorCallback
});
“Callback Hell” Problem And Solution
In asynchronous code execution, which is simply execution of code in any order, sometimes it is common to have numerous levels of callback functions to the extent that you have code that looks like the following. The messy code below is called callback hell because of the difficulty of following the code due to the many callbacks. I took this example from the node-mongodb-native, a MongoDB driver for Node.js. [2]. The example code below is just for demonstration:
var p_client = new Db('integration_tests_20', new Server("127.0.0.1", 27017, {}), {'pk':CustomPKFactory});
p_client.open(function(err, p_client) {
p_client.dropDatabase(function(err, done) {
p_client.createCollection('test_custom_key', function(err, collection) {
collection.insert({'a':1}, function(err, docs) {
collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}, function(err, cursor) {
cursor.toArray(function(err, items) {
test.assertEquals(1, items.length);
// Let's close the db
p_client.close();
});
});
});
});
});
});
You are not likely to encounter this problem often in your code, but when you do—and you will from time to time—here are two solutions to this problem. [3]
- Name your functions and declare them and pass just the name of the function as the callback, instead of defining an anonymous function in the parameter of the main function.
- Modularity: Separate your code into modules, so you can export a section of code that does a particular job. Then you can import that module into your larger application.
Make Your Own Callback Functions
Now that you completely (I think you do; if not it is a quick reread :)) understand everything about JavaScript callback functions and you have seen that using callback functions are rather simple yet powerful, you should look at your own code for opportunities to use callback functions, for they will allow you to:
- Do not repeat code (DRY—Do Not Repeat Yourself)
- Implement better abstraction where you can have more generic functions that are versatile (can handle all sorts of functionalities)
- Have better maintainability
- Have more readable code
- Have more specialized functions.
It is rather easy to make your own callback functions. In the following example, I could have created one function to do all the work: retrieve the user data, create a generic poem with the data, and greet the user. This would have been a messy function with much if/else statements and, even still, it would have been very limited and incapable of carrying out other functionalities the application might need with the user data.
Instead, I left the implementation for added functionality up to the callback functions, so that the main function that retrieves the user data can perform virtually any task with the user data by simply passing the user’s full name and gender as parameters to the callback function and then executing the callback function.
In short, the getUserInput function is versatile: it can execute all sorts of callback functions with myriad of functionalities.
// First, setup the generic poem creator function; it will be the callback function in the getUserInput function below.
function genericPoemMaker(name, gender) {
console.log(name + " is finer than fine wine.");
console.log("Altruistic and noble for the modern time.");
console.log("Always admirably adorned with the latest style.");
console.log("A " + gender + " of unfortunate tragedies who still manages a perpetual smile");
}
//The callback, which is the last item in the parameter, will be our genericPoemMaker function we defined above.
function getUserInput(firstName, lastName, gender, callback) {
var fullName = firstName + " " + lastName;
// Make sure the callback is a function
if (typeof callback === "function") {
// Execute the callback function and pass the parameters to it
callback(fullName, gender);
}
}
Call the getUserInput function and pass the genericPoemMaker function as a callback:
getUserInput("Michael", "Fassbender", "Man", genericPoemMaker);
// Output
/* Michael Fassbender is finer than fine wine.
Altruistic and noble for the modern time.
Always admirably adorned with the latest style.
A Man of unfortunate tragedies who still manages a perpetual smile.
*/
Because the getUserInput function is only handling the retrieving of data, we can pass any callback to it. For example, we can pass a greetUser function like this:
function greetUser(customerName, sex) {
var salutation = sex && sex === "Man" ? "Mr." : "Ms.";
console.log("Hello, " + salutation + " " + customerName);
}
// Pass the greetUser function as a callback to getUserInput
getUserInput("Bill", "Gates", "Man", greetUser);
// And this is the output
Hello, Mr. Bill Gates
We called the same getUserInput function as we did before, but this time it performed a completely different task.
As you see, callback functions afford much versatility. And even though the preceding example is relatively simple, imagine how much work you can save yourself and how well abstracted your code will be if you start using callback functions. Go for it. Do it in the monings; do it in the evenings; do it when you are down; do it when you are k
Note the following ways we frequently use callback functions in JavaScript, especially in modern web application development, in libraries, and in frameworks:
- For asynchronous execution (such as reading files, and making HTTP requests)
- In Event Listeners/Handlers
- In setTimeout and setInterval methods
- For Generalization: code conciseness
Final Words
JavaScript callback functions are wonderful and powerful to use and they provide great benefits to your web applications and code. You should use them when the need arises; look for ways to refactor your code for Abstraction, Maintainability, and Readability with callback functions.
See you next time, and remember to keep coming back because JavaScriptIsSexy.com has much to teach you and you have much to learn.
Notes
- http://c2.com/cgi/wiki?FirstClass
- https://github.com/mongodb/node-mongodb-native
- http://callbackhell.com/
- JavaScript Patterns
by Stoyan Stefanov (Sep 28, 2010)
nasser-torabzade starred astoilkov/jsblocks
DecorateThis, jsRequest, ODataAngularResources
DecorateThis
DecorateThis (GitHub: mako-taco/DecorateThis, License: Apache 2.0, npm: decorate-this) by Jake Scott is the first library to my knowledge that takes advantage of ES7 decorators. Decorators allow you to annotate classes and properties.
An example of a decorator is @readonly:
class Person {
@readonly
name() { return `${this.first} ${this.last}` }
}
This is far less complex than the older Object.defineProperty syntax:
Object.defineProperty(Person.prototype, 'name', {
value: specifiedFunction,
enumerable: false,
configurable: true,
writable: true
});
The DecorateThis module provides some very handy decorators for argument type checking, including:
- Memoization:
@memoized - Type validation: primitive types
@param(Number), and a classTis checked with@param(T) - Duck type checks:
@param({ hello: String, info: { age: Number, color: String } });
If these checks fail type errors are thrown, which means you'll need exception handlers for places where these checks should be caught and handled gracefully.
jsRequest
Bruno Panuto and Danilo Valente have been working on a JavaScript file loader called jsRequest (GitHub: danilo-valente/jsRequest, License: MIT) since back in 2013. It handles asynchronous loading, and the syntax supports loading multiple files with a chained API:
jsRequest
.load('myScript.js')
.load('http://code.jquery.com/jquery-1.10.2.js')
.load('file:///C:/myFile.js');
It supports extra options that allow success and failure callbacks to be supplied, and it also has a progress callback. If you need to order requests, then you can use the wait method.
jsRequest tracks the request history, so if you need to check what files have been loaded you can inspect the jsRequest.history object.
ODataAngularResources
I recently wrote about OData Server, and Raphael Atallah sent in ODataAngularResources (GitHub: devnixs/ODataAngularResources, License: MIT), a fork of Angular's $resource that allows making OData queries using a fluent API.
Once you've added the dependency, you can do cool stuff like this:
var User = $odataresource('/user/:userId', { userId:'@id' });
var myUsers = User.odata()
.filter('Name', 'John')
.query();
You can also use top, orderBy, and skip, and request single elements. The readme has full examples including details on how to create more complex queries with predicates.
ADT Streams
More libraries are starting to blend ideas from functional programming, streams, and reactive programming. Yassine Elouafi sent in ADT Streams (License: MIT, npm: adtstream), a library that offers a stream API using promises and algebraic data types. It has methods for wrapping other streams, like Stream.fromReadable for use with Node's Readable streams, Stream.fromEmitter for objects that extend EventEmitter, and Stream.fromDomEvent for working with DOM events in the browser.
There are utility methods, like Stream.seq for yielding elements from a sequence over time. The blog post, Promises + FP = Beautiful Streams explains each of the library's methods with examples first in Haskell and then in JavaScript. It also has some background on streams and reactive programming:
The basic idea is that you can represent different asynchronous data like events or http responses by an unifying concept called observable collections. Then you can manipulate those collections by standard array operations like map, filter, reduce, forEach ...etc.
By using Yassine's library, you can compose streams with different sources: you can mix events and readable streams with the same API.
The author also wrote From callback to (Future -> Functor -> Monad), which argues why callbacks are not composable and alternative solutions:
With composition, you never hit a wall, because you must always ask yourself "What is the return value of this function?", or put another way "What is the meaning of this thing?"
I don't mind using callbacks in my code. In fact, callbacks are great for things such as representing side effects or event notification, but once your start using them to manage your control flow, you're trapped, why? because they do not compose.
Both of these posts will be of interest to you if you're a JavaScript programmer without much functional or reactive programming experience.
by: Noukka Signe
mirrors | reflection
Nodal: An ES6 API Server
Sometimes I feel like client-side developers are adopting ES6 faster than server-side developers. I certainly have projects where the client uses ES6 and the Node server code is more ES5, mainly because I don't really want to use a transpiler on the server, although I sometimes do like to use Harmony flags.
Alternatively, I could use io.js. Keith Horwood recently sent in a new module that aims to provide an API server and web framework that takes advantage of ES6 features. It's called Nodal (GitHub: keithwhor/nodal, License: MIT, npm: nodal) and currently runs on io.js.
Nodal includes support for models, controllers, templates, migrations, routing, and query composition. It has a command-line tool for creating RESTful resources, and it's designed to work with PostgreSQL.
The example code makes heavy use of new language features like const and classes. The result is very Rails/Django-like. Here's a snippet of a model class:
module.exports = (function() {
'use strict';
const Nodal = require('nodal');
class Person extends Nodal.Model {
__preInitialize__() {}
__postInitialize__() {}
}
Person.prototype.schema = Nodal.my.Schema.models.Person;
Person.prototype.externalInterface = [
'id',
'name',
'age',
'created_at'
];
return Person;
})();
It doesn't have the same kind of auto-loading magic that you see in Rails -- notice the Nodal module is loaded explicitly. It still feels like idiomatic JavaScript rather than using ES6 to pretend to be something else.
Nodal doesn't use an external ORM, it actually has its own models backed by any-db-postgres. That means Keith is developing features like model relationships. I've tried to develop my own ORM before, and the ORMs I've used before have been very mixed in terms of quality and consistency between releases, so I don't envy the work he has ahead. However, the idea of a RESTful web framework that takes advantage of ES6 for code organisation and clarity is interesting, so let's see what he does with it!
nasser-torabzade starred julianshapiro/blast
Generators vs Fibers
Both ES6 generators and node-fibers can be used to block a coroutine while waiting on some I/O without blocking the entire process.
This means that you can wait for an I/O result within your code but still have the performance benefits of the single-threaded, non-blocking I/O model you all know and love.
Both can do this for arbitrarily deep call stacks. The main difference between the capabilities of the two is how explicit the syntax is. It's the classic battle between wanting to be safe while wanting to be flexible.
Generators - Safe, but Annoyingly Explicit
In code that uses generators there is a technique whereby a library will yield continuables or promises and the generator runner will pass in the callback, suspend the generator body, and resume when the callback gets called.
I will use my library, gen-run, in these examples because it's very simple and is the one I know best. There are many others I link to in the gen-run credits.
The Server
We'll start out by writing a simple HTTP server that uses generators to power the request handling logic. It could look something like this.
The Handler
Initially when we write our programs, we often use canned data or otherwise have less I/O to perform to accomplish the given task. In this example, we're using a simple module that returns the result directly.
Now our main app logic can be written. Remember that the server expects us to be in a generator so let's write the logic as a generator.
We want each result to be tagged with the request count as it came into the server. A simple shared variable that gets incremented at the beginning of each request should do the trick.
You can call this with as many concurrent requests as you want. Each will have the correct requestCount because of run-to-finish semantics of JavaScript. Even inside the bodies of generators, arbitrary function calls can't suspend your code.
Modified Handler
Now suppose that down the line, our query function needed to actually do things and perform some I/O.
First we'll change the query function to return a continuable and/or accept a callback. This is a common pattern for many node libraries that need to perform I/O.
We thought ahead and put the body of our handler in a generator to ease the transition, but that function call needs to change. The query function now returns a continuable or expects a callback last. Our handler function can now look like this.
Now we have that big bright yield keyword in there. We can see plainly that our requestCount variable is in danger of a race condition. What happens if a second request comes in while we're still waiting on the query from the first request? They will clobber each other and both requests will be marked as #3, that's what!
Good thing we were forced to change our calling syntax to help us see the danger.
Modified Again
Another transform we could have done is re-write query as a generator itself allowing for deep coroutines with function* at every definition and yield* at every call.
In this case we insert a delegating yield* instead of a plain yield and it works the same as the previous change.
In summary, generators allow for all kinds of nice tricks where you can block on I/O without actually blocking the process, however these require invasive changes to your code (much the same as callbacks act today).
Fibers - Powerful, but Flexible
Long before generators landed in V8 and node.js, Marcel released a library known as node-fibers. This clever little library allows you to use full coroutines in any version of node that the addon compiles against.
I'll repeat the same examples here, but using fibers instead of generators for easy comparison.
The Server
Our server is slightly different because the fiber API is quite different than the gen-run and generator APIs.
We create a fiber for our code to run in. With fibers there is no distinction between generators, iterators, or normal functions. They are all just vanilla functions. Also this means there is no yield or yield*. Only normal function calls.
Also within the body of the fiber, try..catch works just like it does with sync code because the code is blocking within this fiber.
The Handler
We'll start out again with a simple handler. We'll use the same exact query function from before and the same handleRequest except this one is a plain function.
The world is great, everything works and there is no race condition because nobody actually ever suspends the fiber.
The Change
Now again, imagine that some time down the line, the authors of the query function need to perform some I/O to accomplish its task. Well in this case they know they are running inside a fiber. (And even if they didn't know this, they could detect it).
So the only code change required to make query block on I/O is local to the query function.
That's it. The rest of the code will continue to work as before. You test it locally and everything works great. You didn't have to change the signature of any other function that consumed this library.
Then you push this code to production where the server hits a higher concurrency load and people start complaining that their requestCounts aren't always accurate. The problem you discover after many hours of painful debugging is that the query function back in handleRequest that didn't need to be changed syntacticly did change behavior. It suspended the fiber and let other concurrent requests clobber the shared requestCount variable.
Lesson Learned
Next time you complain that adding an async feature to a library causes all consumers of this API to be changed as well, remember that along with that pain is protection. You can't have the protection without the pain.
Both styles of coroutines are powerful with unique strengths and weaknesses.
Safety or flexibility, choose one.


