<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سعید نوری</title>
        <link>https://virgool.io/feed/@saeed__noori</link>
        <description>علاقه‌مند به فناوری، توسعه دهنده پایتون و بک‌اند در آینده‌ای دور یا نزدیک!</description>
        <language>fa</language>
        <pubDate>2026-06-17 02:59:57</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/67/avatar/avatar.png?height=120&amp;width=120</url>
            <title>سعید نوری</title>
            <link>https://virgool.io/@saeed__noori</link>
        </image>

                    <item>
                <title>بررسی حباب بلاکچین به صورت موردی (Augur)</title>
                <link>https://virgool.io/@saeed__noori/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%AD%D8%A8%D8%A7%D8%A8-%D8%A8%D9%84%D8%A7%DA%A9%DA%86%DB%8C%D9%86-%D8%A8%D9%87-%D8%B5%D9%88%D8%B1%D8%AA-%D9%85%D9%88%D8%B1%D8%AF%DB%8C-augur-qhbvrormht5s</link>
                <description>آگر (augur) یک بلاکچین نیست بلکه یه برنامه غیر متمرکز (DApp) روی بلاکچین اتریومه. پدیدآورندگان این برنامه فلسفه وجودی اون رو به این صورت تشریح کردن که همیشه مراجعه به خرد جمعی بهتر از مراجعه به یه آدم خبره در پیش‌بینی پدیده‌ها جواب میده. همونطور که از اسمش پیداست (augur به معنی فالگیره) این برنامه برای پیش‌بینی وقایع طراحی شده. اصول کارش اینجوریه که یه آدم میاد و با پرداخت توکن یه سوال مطرح می‌کنه ( مثلا: آیا قیمت بیتکوین تا انتهای سال ۲۰۱۸ به ۲۰ هزار دلار خواهد رسید؟) و گزینه‌های بله و خیر رو براش تعیین می‌کنه (سوالات چند گزینه‌ای هم وجود داره)، کاربران دیگه هم میان و با پرداخت توکن یکی از گزینه‌ها رو انتخاب می‌کنن. بعد از اینکه بازه زمانی سوال به پایان رسید و جواب سوال مشخص شد کاربرانی که جواب صحیح رو انتخاب کردن توکن جایزه می‌گیرن. پرداخت‌ها هم با اتر ( توکن بلاکچین اتریوم) انجام میشه هم با توکن داخلی برنامه که REP نام داره. در واقع میشه گفت این برنامه یه برنامه شرط‌بندی هست که کاربران بر روی جواب‌های سوالات شرط می‌بندن.معرفی و فروش اولیه توکن‌های این برنامه اواسط سال ۲۰۱۵ انجام شد و حدود ۳ سال طول کشید تا در اواسط سال ۲۰۱۸ برنامه نویس‌ها برنامه رو نوشتن و در اختیار کاربران قرار دادن. برای مشاهده آمار این برنامه می‌تونید به سایت dappradar.com مراجعه کنید. این سایت علاوه بر این برنامه آمار خیلی برنامه‌های غیر متمرکز دیگه رو که روی بلاکچین‌های اتریوم، ترون و ایاس اجرا میشه رو جمع‌آوری و منتشر می‌کنه. در تصویر زیر می‌تونین آمار ۲۴ ساعت گذشته این برنامه رو مشاهده کنین:آمار ۲۴ ساعت گذشته برنامه آگرو در تصویر زیر آمار کلی برنامه از زمان شروع به کار دیده میشه:آمار کلی برنامه آگرهمونطور که در تصویر اول دیده میشه در ۲۴ سال گذشته فقط ۲۱ نفر از این برنامه استفاده کردن و حدود ۳۳ اتر در این برنامه خرج شده. در تصویر دوم هم دیده میشه که به جز روز‌های اول شروع به کار برنامه تعداد کاربران روزانه برنامه حداکثر ۵۰ نفر بودن و اگه از اون دو تا قله بالای ۲۰۰۰ اتری بگذریم، این کاربران روزانه حداکثر ۲۰۰ اتر در این برنامه خرج کردن. اگه قیمت هر اتر رو بطور متوسط ۱۰۰ دلار در نظر بگیریم میشه حداکثر ۲۰ هزار دلار در روز.حالا سری به سایت coinmarketcap میزنیم. رتبه این برنامه در این سایت ۵۷ هست که در بین بیش از ۲۰۰۰ بلاکچین و برنامه رتبه خوبی محسوب میشه. در تصویر زیر می‌تونید آمار این برنامه رو در این سایت ببینید:آمار برنامه آگر در سایت coinmarketcapهمونطور که تصویر می‌بینید هر توکن این برنامه حدود ۷.۵ دلار قیمت داره و سرمایه‌گذارها فقط در ۲۴ ساعت گذشته حدود ۱.۵ میلیون دلار توکن‌های این برنامه رو خرید و فروش کردن.شاید یا توجه به عمر ۶ ماهه این برنامه الان یه کم زود باشه که در مورد موفقیت این برنامه قضاوت کنیم ولی برای یک برنامه که روزانه حداکثر ۵۰ نفر دارن ازش استفاده می‌کنن، خرید و فروش روزانه حدود یک ونیم میلیون دلار توکن این برنامه چیزی غیر از حباب و جوگیری نمی‌تونه باشه.اگر بلاکچین‌ها و برنامه‌هایی که در سایت coinmarketcap لیست شدن رو به صورت موردی بررسی کنید پی می‌برید که خیلی از اونها که از رتبه ۱۰۰ به بعد لیست شدن حتی یه محصول ارائه شده هم ندارن، بلکه بنیان‌گذاران اونها وعده وعید‌هایی دادن و عرضه اولیه سکه‌ها رو انجام دادن، سرمایه‌گذارها هم بر اساس این وعده وعید‌ها دارن میلیون‌ها دلار سکه‌های این بلاکچین‌ها رو می‌خرن. این کار بیشتر شبیه شرط‌بندی رو قیمت توکن این بلاکچین‌ها ست تا سرمایه‌گذاری رو یک محصول ارزشمند که قراره در آینده زندگی آدم‌ها رو متحول کنه.</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Fri, 21 Dec 2018 13:38:13 +0330</pubDate>
            </item>
                    <item>
                <title>بررسی حباب بلاکچین به صورت موردی(Siacoin)</title>
                <link>https://virgool.io/blockchain/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%AD%D8%A8%D8%A7%D8%A8-%D8%A8%D9%84%D8%A7%DA%A9%DA%86%DB%8C%D9%86-%D8%A8%D9%87-%D8%B5%D9%88%D8%B1%D8%AA-%D9%85%D9%88%D8%B1%D8%AF%DB%8Csiacoin-plwminzbyfqu</link>
                <description>تو یک ماه گذشته این سوال واسه من وجود داشت که حباب بلاکچین چقدره؟ و ارزش واقعی هر کدام از این بلاکچین‌ها چقدره؟ بررسی این موضوع برای خیلی از بلاک‌چین‌ها سخته چون خیلی‌هاشون آمار دقیقی از هزینه‌ها و سود شرکت‌شون نمیدن. ولی امروز یه بلاکچین پیدا کردم که آمار دقیق و جالبی داره. اسم این بلاکچین سیاکوین (Siacoin) هست. کاری که این بلاکچین انجام میده یه کار واضح هست که در دنیای فناوری معادل‌های زیادی داره:  « سیستم ‌ذخیره ابری ». درنتیجه مقایسه این بلاکچین با شرکت‌های فناوری و برآورد میزان ارزشش کار راحتیه. روند کار این بلاکچین اینجوریه که کاربرانی که قسمتی از هارد دیسک کامپیوترشون که خالیه رو اجاره میدن و یه عده کاربر دیگه این فضای آزاد رو اجاره می‌کنن تا فایل‌هاشون رو ذخیره کنن و در مقابل توکن این بلاکچین یعنی سیاکوین (SC) می‌پردازن.رتبه این بلاکچین در سایت coinmarketcap روی عدد ۴۶ هست که در بین بیش از ۲۰۰۰ بلاکچین رتبه خوبی محسوب می‌شه. این بلاکچین خیلی از داده‌های آماریش رو روی سایت  siastats.info منتشر می‌کنه. اسکرین‌شات قسمتی از سایت که مربوط به آمار فضای ذخیره سازی هست رو تو تصویر زیر می‌بینین:آمار فضای ذخیره‌سازی بلاکچین سیاکوینو در تصویر زیر هم می‌تونین میزان استفاده یک ماه اخیر از فضای ذخیره‌سازی رو ببینین:میزان استفاده روزانه از فضای ذخیره‌سازی بلاکچین در یک ماه اخیرهمونطور که تو تصاویر دیده می‌شه کل فضای ‌ذخیره‌سازی این بلاکچین حدود ۳۲۰۰ ترابایته و فضای استفاده شده اون در یک ماه گذشته حداکثر حدود ۲۳۰ ترابایت بوده. اگه این آمار  رو یه میانگین واسه تمام دوران عمر این بلاکچین در نظر بگیریم، با توجه به عمر ۳.۵ ساله این بلاکچین این آمار بسیار پایین و ناامید کننده محسوب میشه. حالا سری به سایت siahub.info  می‌زنیم که لیست سرورها ( در واقع هارد دیسک‌های کاربرهای اجاره دهنده) و قیمت‌ها رو نوشته. تو تصویر زیر قسمتی از این آمار رو می‌بینین:لیست سرورهای بلاکچین سیاکوین همونطور که در قسمت بالای تصویر می‌بینین میزان اجاره‌‌بهای ماهانه هر ترابایت به صورت میانگین ۰.۱ (یک دهم) دلاره. اگه این عدد رو ضرب در ۲۳۰ ترابایت کنیم و حاصل رو ضرب در ۱۲ کنیم میزان درآمد ناخالص این بلاکچین ۲۷۶ دلار در سال میشه.حالا به سایت coinmarketcap میریم و  نگاهی به آمار این بلاکچین می‌ندازیم: سرمایه‌گذارها فقط در ۲۴ ساعت گذشته حدود ۱۲۰۰۰۰۰ (یک میلیون و دویست هزار) دلار توکن این بلاکچین رو خرید و فروش کردن.تو خود حدیت مفصل خوان از این مجمل!</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Fri, 07 Dec 2018 20:44:37 +0330</pubDate>
            </item>
                    <item>
                <title>بهترین زبان برنامه‌نویسی برای نوشتن برنامه‌های با بازدهی بالا</title>
                <link>https://virgool.io/@saeed__noori/%D8%A8%D9%87%D8%AA%D8%B1%DB%8C%D9%86-%D8%B2%D8%A8%D8%A7%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%86%D9%88%D8%B4%D8%AA%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%87%D8%A7%DB%8C-%D8%A8%D8%A7-%D8%A8%D8%A7%D8%B2%D8%AF%D9%87%DB%8C-%D8%A8%D8%A7%D9%84%D8%A7-uo5idbp4tkch</link>
                <description>من هنوز امیدوار هستم که دنیای زبان‌های برنامه‌نویسی دچار تحول شود. من از نوشتن با زبان‌های سی یا جاوا خسته شده‌ام، من زبان‌های بهتری می‌خواهم.من به طور خاص به چیزی که «برنامه‌نویسی با بهره‌وری بالا» نامیده‌ام علاقه‌مندم. من می‌خواهم زبانی را انتخاب کنم که بیشترین استفاده را از سخت‌افزار کنم. برنامه‌نویسی در پایتون یا جاوا اسکریپت جالب است اما بعضی وقت‌ها پیش می‌آید که برای نوشتن یک برنامه باید از سخت‌افزار خالص استفاده کنید.به همین منظور من لیست زبان‌های مورد نظر را محدود به «زبان‌های برنامه‌نویسی سیستمی» کرده‌ام که عبارتند از سوئیفت (Swift)، راست (Rust)، گو (Go)، سی پلاس پلاس و سی. این زبان‌ها برای چیزی بیشتر از ساختن برنامه‌های کاربردی مناسب هستند، یعنی موتورهای پایگاه داده، سرورها و چیزهایی مانند این‌ها. همه این‌ زبان‌ها کامپایلری هستند که این ویژگی باعث می‌شود بهره‌وری برنامه‌های تولیدی بیشتر شود.من فکر می‌کنم همه برنامه‌نویسان با این موضوع که سی و سی پلاس پلاس زبان‌های برنامه‌نویسی سیستمی هستند موافق هستند، در حالی که واجد شرایط بودن زبان‌های سوئیفت و گو مورد بحث است. آیا شما یک سیستم عامل را با گو می‌نویسید؟ من همچین کاری نمی‌کنم. اما مثل اینکه ویکیپدیا همه‌ی این زبان‌ها را جزو زبان‌های برنامه‌نویسی سیستمی طبقه‌بندی کرده است.من زبان اسمبلی را از لیست حذف کرده‌ام چون نمی‌توانم تصور کنم که به صورت روزانه از این زبان استفاده کنم. این زبان فقط در جاهایی که مقدار کمی کد نیاز است کاربرد دارد (احتمالا در نرم‌افزار‌های تعبیه شده).من قصد دارم زبان‌های راست ، D و Nim  را نیز حذف کنم زیرا این زبان‌ها تعداد بسیار کمی کاربر دارند. برنامه‌نویسی یک کار اجتماعی است، اگر کسی نباشد که از کد شما استفاده کند دیگر مهم نیست که کد شما چقدر سریع اجرا می‌شود. من فکر می‌کنم این زبان‌ها زبان‌های خیلی جالبی هستند ولی تا وقتی که تعداد زیادی کاربر از این زبان‌ها استفاده نکنند من آنها را در لیست قرار نمی‌دهم. زبان فرترن هم به دلیل مشابهی از لیست بیرون گذارده می‌شود، هر چند که این زبان کاربران پیگیری دارد ولی حوزه عملکرد این زبان محدود و اختصاصی است.من همچنین زبان‌های غیر سیستمی مانند پی‌اچ‌پی، جاوا اسکریپت،متلب، روبی، آر و پایتون را در لیست قرار نداده‌ام زیرا هر چند که این زبان‌ها می‌توانند سریع باشند ولی هیچکدام از آنها به صورت اختصاصی برای بازدهی بالا طراحی نشده‌اند. آنها برای منظور‌های خاصی به مقدار کافی سریع هستند ولی محدودیت‌های بزرگی هم دارند، مثلا جاوا اسکریپت و پایتون به صورت بومی از مولتی-تردینگ پشتیبانی نمی‌کنند.جاوا و سی شارپ موارد جالبی هستند. هر دوی این زبان‌ها به عنوان زبان‌های برنامه نویسی سیستمی توصیف و استفاده شده‌اند. شواهد حاکی از ان است که جاوا می‌تواند برای ساخت سیستم‌هایی که می‌توانند بسیار خوب عمل کنند استفاده شود. اما من فکر می‌کنم که اجرا در یک ماشین مجازی (JVM,CLR) یک محدودیت بزرگ است زیرا شما هرگز نمی‌توانید به سخت‌افزار خالص دسترسی داشته باشید. من اسکالا را هم جزو دسته‌بندی جاوا حساب کرده‌ام.تعداد زیادی زبان دیگر هم وجود دارد که آنها را ذکر نکرده‌ام زیرا هیچکدام از آنها نخواهند توانست به اندازه کافی کاربر جذب کنند.اجازه دهید بعضی از ویژگی های پسندیده برای برنامه نویسی با بازدهی بالا را ذکر کنم که زبان‌های برنامه‌نویسی جاری در آنها عملکرد خوبی داشته‌اند:۱- سیستم‌عامل‌ها به وسیله سی و سی پلاس پلاس ساخته شده‌اند. علاوه بر این خیلی از کتابخانه‌های مهم برای زبان سی اینترفیس دارند، این بدان معنا است که توانایی فراخواندن توابع زبان سی با کمترین سربار در بعضی موارد مهم است. هر چند که زبان گو به شما اجازه می‌دهد که توابع زبان سی را فراخوانی کنید ولی این کار سربار زیادی را به عملکرد تحمیل می‌کند. همه‌ی زبان‌های دیگر می‌توانند توابع زبان سی را با کمترین سربار فراخوانی کنند.برنده آشکار: سی و سی پلاس پلاسبازیکن خوب: سوئیفتبازنده: گو۲- اگر چه این قابل بحث است اما من فکر می‌کنم زبانی که مدیریت حافظه دستی دارد احتمالا در کارایی بهتر عمل می‌کند. در سیستم‌های مدرن، مدیریت حافظه نیز اغلب یک سربار مهم است. زبان‌های سی و سی پلاس پلاس مدیریت حافظه دستی دارند. سوئیفت سیستم شمارشگر ارجاع دارد که حالتی از مدیریت مدرن حافظه است، اما با این مزیت که کاملا جبری است یعنی وقتی که داده از محدوده‌اش خارج می‌شود حافظه بازپس‌ گرفته می‌شود. اگر چه شمارش ارجاع هم سربار دارد، مخصوصا در زمینه مولتی‌تردینگ. زبان گو زباله‌روب نسلی (generational garbage collection) دارد همانند جاوا و سی‌شارپ. این بدان معنا است که این زباله‌روب هر از گاهی برنامه را برای بازپس‌گیری حافظه متوقف می‌کند، هر چند که این زباله‌روب طوری بهینه شده است که توقف‌ها کوتاه باشد. این بهینه‌سازی کار پسندیده‌ای است زیرا توقف برنامه مطلوب نیست. من نمی‌دانم کدام روش را ترجیح می‌دهم؟ روش سوئیفت یا روش گو.برنده: سی و سی پلاس پلاسبازند: گو و سوئیفت۳- پردازنده کامپیوترهای ما تعداد زیادی هسته دارد. برنامه‌نویسی پارالل مهم است. ما ترجبح می‌دهیم که زبان برنامه‌نویسی ما برنامه‌نویسی چند هسته‌ای را به خوبی پشیبانی کند. من فکر می‌کنم که زبان گو در این زمینه به صورت واضح دست بالا را دارد. اگر چه هر آنچه که می‌شود با گو در مورد چند هسته‌ای انجام داد را می شود با زبان سی نیز انجام داد ولی این کار به راحتی زبان گو نیست. تا جایی که من می‌دانم زبان سوئیفت یک روش استاندارد در مورد استفاده از چند هسته دارد که «توزیع‌کننده مرکزی بزرگ» نامیده می‌شود. این زبان همچنین Operation/OperationQueue را برای سطوح بالاتر مولتی-تردینگ دارد. این ممکن است خوب باشد اما نمی‌تواند با قابلیت‌های موجود در دیگر زبان‌های لیست رقابت کند.نام بردن ویژه: گوبرنده: سی و سی پلاس پلاسبازنده: سوئیفت۴- برای کارایی بالا، یک زبان برنامه نویسی خوب باید یک ویژگی به نام «قابلیت تشخیص آسان کارایی» را داشته باشد. این بدان معنی است وقتی شما به یک قطعه کد نگاه می‌کنید باید بتوانید پیش‌بینی کنید که این قطعه کد با چه سرعتی اجرا می‌شود. اگر بخواهم صادق باشم باید بگویم که این کار در طول زمان بسیار سخت‌تر شده است و ما مجبور شده‌ایم که بیشتر و بیشتر به بنچمارک‌ها تکیه کنیم. اگر چه برای زبان‌های ساده‌تر مثل سی و گو بیش‌بینی کارایی کد‌ها را راحت‌‌تر کرده‌اند. در واقع هر چه زبان گسترده‌تر می‌شود کامپایل کد‌های آن در سرتان سخت تر می‌شود.برنده: سی و گوبازنده: سوئیفت و سی پلاس پلاس۵- پردازنده‌های ما دستورالعمل‌های جالب جدیدی دارند مثل دستورالعمل‌های SIMD. این دستورالعمل‌ها باید به آسانی از طریق زبان‌های برنامه‌نویسی در دسترس باشند. هیچ زبان برنامه‌نویسی برای برنامه‌ نوشتن با چیزی مثل SIMD آسان نیست اما زبان‌های سی و سی پلاس پلاس به طور واضحی بر دیگران برتری دارند. در زبان گو شما می‌توانید توابع را با زبان اسمبلی بنویسید و سپس این توابع را در گو فراخوانی کنید اما این کار سربار زیادی را بر کارایی تحمیل می‌کند. سوئیفت به صورت آشکاری در این زمینه بهتر است، برای این زبان یک پکیچ بنام simd وجود دارد ولی این پکیج فقط در سیستم عامل مک کار می‌کند.برنده: سی و سی پلاس پلاسبازنده: گو و سوئیفت۶- ده‌ها سال گذشته است و هنوز یک روش فراگیر برای مدیریت وابستگی‌ها در زبان سی وجود ندارد. همچنین هیچ روش استاندردی برای ساخت (build) برنامه‌ها وجود ندارد. البته IDE شما اضافه کردن وابستگی ها و ساخت برنامه را تسهیل می‌کند اما داشتن چیزی که در زبان برنامه‌نویسی به صورت توکار وجود داشته باشد کار را بسیار راحت‌تر می‌کند. در زبان‌های گو و سوئیفت یک روش چند-پلتفرم استاندارد برای اضافه کردن وابستگی‌ها، ساخت برنامه و تست برنامه وجود دارد.برند: گو و سوئیفت ( نام بردن ویژه از گو)بازنده: سی و سی پلاس پلاسدر جدول زیر تحلیل خودم را خلاصه کرده‌ام:اگر من به منظور برنامه‌نویسی با کارایی بالا استخدام شوم، هر کدام از زبان‌های بالا به من «تحمیل» شود من خوشحال خواهم بود. همه‌ی آنها گزینه‌های خوبی هستند. همه‌ی آنها با سرعت زیادی در حال بهتر شدن هستند، به عنوان مثال من فکر می‌کنم زبان گو از زمانی که من آن را آموخته‌ام به میزان خیره کننده‌ای پیشرفت کرده است.منبع: lemire.meاین مطلب همچنین در این لینک در وبسایت شخصی من انتشار یافته است.</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Wed, 04 Oct 2017 02:28:19 +0330</pubDate>
            </item>
                    <item>
                <title>طلوع، افول، و خیزش دوباره برنامه‌نویسی تابعی</title>
                <link>https://virgool.io/@saeed__noori/%D8%B7%D9%84%D9%88%D8%B9-%D8%A7%D9%81%D9%88%D9%84-%D9%88-%D8%AE%DB%8C%D8%B2%D8%B4-%D8%AF%D9%88%D8%A8%D8%A7%D8%B1%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AA%D8%A7%D8%A8%D8%B9%DB%8C-sm99lqkquruv</link>
                <description>وقتی که من حدودا ۶ ساله بودم مقدار زیادی از وقتم را به بازی‌های کامپیوتری همراه با بهترین دوستم می‌گذارندم. خانواده او یک اتاق پر از کامپیوتر داشتند، برای من آنها بسیار جذاب و جاویی بودند، من وقت زیادی را در جستجوی بازی‌های مختلف می‌گذراندم. یک روز من از دوستم پرسیدم: چطوری یک بازی بسازیم؟او چیزی در این باره نمی‌دانست در نتیجه ما از پدرش سوال کردیم. پدرش یک کتاب از یک قفسه بلند برای ما پایین آورد، کتاب در مورد نوشتن بازی با زبان بیسیک بود. از همان جا سفر من در دنیای برنامه‌نویسی شروع شد. زمانی که در مدرسه به ما جبر یاد می‌دادند من از قبل آن را بلد بودم زیرا برنامه‌نویسی بر پایه جبر بنا نهاده شده است.طلوع برنامه‌نویسی تابعیدر ابتدای علم کامپیوتر، خیلی قبل‌تر از آنکه قسمت اعظم علم کامپیوتر در کامپیوترها پیاده سازی شود، دو نفر از بزرگ‌ترین دانشمندان کامپیوتر زندگی می‌کردند: آلونزو چرچ و آلن تورینگ. آنها دو مدل جامع مختلف (اما معادل) از علم محاسبه را ابداع کردند. هر دو مدل می‌توانستند هر چیزی که قابل محاسبه باشد را محاسبه کنند (به همین دلیل جامع بودند).آلونزو چرچ حساب لامبدا را اختراع کرد. حساب لامبدا یک مدل جامع از محاسبه است که بر پایه به کارگیری توابع است. آلن تورینگ به خاطر ابداع ماشین تورینگ مشهور شده است. ماشین تورینگ یه مدل جامع از محاسبه است که به صورت تئوری یک ابزار را تعریف می‌کند که سمبل‌ها را بر روی یک نوار دستکاری می‌کند.این دو دانشمند با همکاری همدیگر نشان دادند که حساب لامبدا و ماشین تورینگ از لحاظ عملکرد معادل هم هستند.حساب لامبدا تماماً در مورد ترکیب توابع است. فکر کردن در مورد ترکیب توابع یک راه کاملا واضح و گویا برای ساخت نرم‌افزار ترکیبی است. در این مقاله ما قصد داریم در مورد اهمیت ترکیب توابع در طراحی نرم‌افزار بحث کنیم.حساب لامبدا سه ویژگی برجسته دارد:توابع همیشه بدون نام هستند. در جاوا اسکریپت طرف راست معادله const sum = (x, y) =&gt; x + y یک تابع بدون نام است یعنی این قسمت: x, y) =&gt; x + y)توابع در حساب لامبدا همیشه فقط یک ورودی می‌گیرند. اگر شما نیاز دارید که بیشتر از یک ورودی به تایع بدهید، تابع ورودی اول را می‌گیرد و یک تابع برمی‌گرداند که ورودی دوم را می‌گیرد، و به همین منوال تمام ورودی‌ها گرفته می‌شوند. تابع چندگانه x, y) =&gt; x + y) می‌تواند به صورت تابع یگانه x=&gt;y=&gt;x+y بیان شود. این تغییر شکل از تابع چندگانه به تابع یگانه اصطلاحاً کاری کردن (Currying) نامیده می‌شود.توابع عناصر درجه یک هستند. این یعنی توابع می‌توانند به عنوان ورودی توابع دیگر استفاده شوند، همچنین توابع می‌توانند به عنوان خروجی توابع دیگر را برگردانند.این ویژگی‌ها با همدیگر یک دستورالعمل ساده اما گویا را برای نوشتن نرم‌افزار با استفاده از توابع به عنوان قطعات اصلی می‌سازند. در جاوا اسکریپت توابع بدون نام و توابع کاری شده ویژگی‌های اختیاری هستند. در حالی که جاوا اسکریپت اصلی‌ترین ویژگی‌های حساب لامبدا را پشتیبانی می‌کند اما برنامه‌نویس را به استفاده از آنها مجبور نمی‌کند.روش کلاسیک ترکیب توابع اینجوری است که خروجی یک تابع به عنوان ورودی تابع دیگر استفاده می‌شود. به عنوان مثال ترکیب زیر:f.gمی‌تواند اینطوری نوشته شود:compose2 = f =&gt; g =&gt; x =&gt; f(g(x))در مثال زیر شما می‌توانید نحوه استفاده از ترکیب توابع را ببینید:double = n =&gt; n * 2inc = n =&gt; n + 1  compose2(double)(inc)(3)تابع compose2 تابع double را به عنوان آرگومان اول و تابع inc را به عنوان دوم می‌گیرد و ترکیب این دو تابع را بر روی آرگومان سوم یعنی عدد ۳ اعمال می‌کند.عبارت صدا زدن تایع یعنی عبارت:compose2(double)(inc)(3)در واقع فراخوانی سه تابع مختلف است:اولین فراخوانی تابع double را پاس می‌دهد و یک تابع جدید برمی‌گرداند.تابع بازگردانده شده تابع inc را می گیرد و یک تابع جدید را برمی‌گرداند.تابع برگردانده شده از مرحله دوم عدد ۳ را می‌گیرد و ((f(g(x را معین می‌کند یعنی عبارت ((double(inc(3متغیر x برابر با ۳ می‌شود و به تابع inc پاس داده می‌شود.حاصل(inc(3 برابر با ۴ می‌شود.حاصل (double(4 برابر با ۸ می‌شود.عدد ۸ به عنوان خروجی تابع برگشت داده می‌شود.هنگامی که نرم‌افزار نوشته می‌شود می‌تواند با یک گراف ترکیب توابع نشان داده شود. مثال زیر ا در نظر بگیرید:append = s1 =&gt; s2 =&gt; s1 + s2append(&#039;Hello, &#039;)(&#039;world!&#039;)شما می‌توانید مثال بالا را به صورت بصری مثل زیر نشان دهید:حساب لامبدا در طراحی نرم‌افزار بسیار با نفوذ بود و تا قبل از حدود سال ۱۹۸۰ تعداد زیادی از شرکت‌های صاحب نام در عرصه کامپیوتر نرم افزارها را با استفاده از ترکیب توابع می‌ساختند. زبان لیسپ در سال ۱۹۵۸ ساخته شد و به میزان زیادی  تحت تاثیر حساب لامبدا بود. امروزه لیسپ دومین زبان قدیمی دنیا است که هنوز به صورت گسترده استفاده می‌شود.من با لیسپ از طریق AutoLISP آشنا شدم. AutoLISP یک زبان اسکریپتی است که درمشهورترین نرم‌افزار  طراحی جهان یعنیاتوکد استفاده می‌شود. اتوکد آنقدر فراگیر است که تقریبا تمام برنامه‌های طراحی دیگر از AutoLISP به منظور سازگاری با اتوکد پشتیبانی می‌کنند. لیسپ همچنین یکی از زبان‌های آموزشی فراگیر در چارت درسی علوم کامپیوتر است به سه دلیل:سادگی آن باعث می‌شود یادگیری آن راحت باشد. یادگیری سینتکس لیسپ حدود یک روز طول می‌کشد.لیسپ تماما در مورد ترکیب توابع است و ترکیب توابع یک راه کارا در نوشتن نرم‌افزارهاست.بهترین مقاله‌ای که من در علوم کامپیوتر می‌شناسم از لیسپ استفاده کرده است: ساختار و تفسیر برنامه‌های کامپیوتری.افول برنامه‌نویسی تابعیزمانی بین سال‌های ۱۹۷۰ تا ۱۹۸۰، راهی که با آن نرم‌افزارها نوشته می‌شدند از ترکیب توابع جدا شد و تبدیل شد به دستورالعمل‌های خطی که کامپیوتر از آنها پیروی می‌کرد. سپس برنامه‌نویسی شی‌گرا از راه رسید. شی‌گرایی یک ایده عالی در مورد کپسوله‌سازی اجزا و ارسال پیام‌ها بود که توسط زبان‌های مشهور تحریف شد و تبدیل شد یک ایده وحشتناک از ارث‌بری سلسله مراتب و رابطه is-a برای استفاده مجدد.برنامه‌نویسی تابعی به حاشیه رانده شد که یا توسط گیک‌ترین برنامه‌نویس‌ها استفاده می‌شد یا استادان دانشگاه‌ها و یا توسط بعضی از دانشجویان خوش‌شانس که از دنیای تسخیر شده توسط جاوا طی سال‌های ۱۹۹۰ تا ۲۰۱۰ گریخته بودند. برای اغلب ما به مدت ۳۰ سال متوالی نوشتن برنامه‌ها یک کابوس بود. سال‌های سیاه!خیزش دوباره برنامه‌نویسی تابعیحدود سال ۲۰۱۰ یک چیز عالی شروع به اتفاق افتادن کرد: جاوا اسکریپت منفجر شد! تا قبل از سال ۲۰۰۶ جاوا اسکریپت به عنوان یک زبان اسباب‌بازی تلقی می‌شد که با آن انمیشن‌های جالب به صفحات وب اضافه می‌کردند، اما جاوا اسکریپت ویژگی‌های قدرتمندی را در خودش پنهان کرده بود، به عنوان مثال مهم‌ترین ویژگی‌های حساب لامبدا. مردم در تاریکی شروع کردند به پچ‌پچ کردن در مورد یک چیز جالب جدید که «برنامه‌نویسی تابعی» نامیده می‌شد.در سال ۲۰۱۵ ایده ساخت برنامه‌ها با استفاده از ترکیب توابع دوباره فراگیر شده بود. برای اینکه این کار ساده‌تر شود جاوا اسکریپت بعد از یک دهه اولین به روز رسانی عمده را دریافت کرد و توابع فلشی (arrow functions) به آن اضافه شد که این توابع کار ساختن و خواندن توابع، کاری کردن و عبارت‌های لامبدا را تسهیل کردند.توابعی فلشی مانند سوخت راکت‌ها برای انفجار برنامه‌نویسی تابعی در جاوا اسکریپت بودند. امروزه کم هستند برنامه‌های بزرگی که در ساخت آنها از تکنیک‌های برنامه‌نویسی تابعی استفاده نشده باشد.ترکیب توابع یک روش ساده، کارا و گویا برای مدل کردن رفتار نرم‌افزار است. پروسه ترکیب توایعِ کوچک و جبری برای ساخت قطعات بزرگتر نرم‌افزار برنامه‌ای را تولید می‌کند که سازماندهی، فهم، دیباگ، توسعه، تست و نگهداری آن آسان‌تر است.منبع: medium.comاین مطلب همچنین در این لینک در وبسایت شخصی من انتشار یافته است.</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Sat, 30 Sep 2017 12:35:27 +0330</pubDate>
            </item>
                    <item>
                <title>چرا من عاشق زبان گو (Go) هستم</title>
                <link>https://virgool.io/@saeed__noori/%DA%86%D8%B1%D8%A7-%D9%85%D9%86-%D8%B9%D8%A7%D8%B4%D9%82-%D8%B2%D8%A8%D8%A7%D9%86-%DA%AF%D9%88-go-%D9%87%D8%B3%D8%AA%D9%85-qhehzc8miqod</link>
                <description>من عاشق زبان برنامه‌نویسی گو هستم، یا مانند آنچه که بعضی می‌گویند: گولنگ. گو یک زبان ساده و عالی است.من برای اولین بار حدود ژانویه ۲۰۱۶ با گو کار کردم. در آن زمان من چندان در مورد گو فکر نمی‌کردم. در آن زمان من سعی می‌کردم مهارت‌های برنامه‌نویسی‌ام را بهتر کنم و گو را برای انجام یک پروژه انتخاب کردم.حتی یک سال قبل هم گو یک چیز درخشان بود. وقتی با مفاهیم کلی گو آشنا شدم برنامه‌نویسی با گو برایم تبدیل به یک کار سرراست شد.من یک تکه کد مهم برای شرکتی که در آن کار می‌‌کنم یعنی Visuallead نوشتم که هنوز به خوبی کار می‌کند بدون اینکه هیچگونه هزینه نگهداری به ما تحمیل کند.اخیرا من دوباره با گو کار کردم  و حس کردم  بهتر است که طی یک مقاله دلایل اینکه عاشق گو هستم را بنویسم.محیط GOPATHاین یکی از اولین چیزهایی است که وقتی شما می‌خواهید با گو شروع به برنامه‌ نویسی کنید باید تنظیم کنید.پوشه GOPATH خودتان را هر جای کامپیوتر که می‌خواهید بسازید و در داخل آن پوشه‌های bin، src و pkg را بسازید. حالا شما آماده نوشتن کد هستید.// How the directory structure looks like:go- bin- pkg- srcمن در پوشه خانه خودم برای هر زبان برنامه‌نویسی که با آن کار می‌کنم یک پوشه ساخته‌ام. پوشه خانه من پر از پوشه‌هایی شبیه اینها است:chefcppelixirelmgojavascriptmeteorocamlphppythonscalهیچکدام از این زبان‌ها غیر از گو همچین ساختار پوشه‌ای را تحمیل نمی‌کند. گو شما را مجبور می‌کند که یک پوشه ریشه برای تمام فایل های پروژه بسازید. این کار دلایل خوبی دارد که در ادامه این مقاله گفته می‌شود.برنامه نوشته شده با گو آیا می‌خواهید که با گو یک برنامه جدید بسازید؟ این کار آسان است. به مسیر پوشه GOPATH/src بروید، یک پوشه جدید بسازید، یک فایل جدید به نام file.go بسازید، فایل را در ویرایشگر باز کنید، پکیج را main بنامید، یک تابع جدید به نام {} ()func main بنویسید، و کار تمام است. از این لحظه به بعد همه امکانات گو در اختیار شماست.ما بعداً در مورد امکانات گو حرف خواهیم زد اما اول اجازه دهید که در مورد ماژول‌های گو حرف بزنیم.ماژول‌های گومن سیستم ماژول‌ها را در گو به عنوان یک جایگزین برای سیستم کلاس‌ها در شی‌گرایی می‌بینم. زبان گو ماژول‌هایش را پکیج می‌نامد، در نتیجه از الان به بعد هر وقت ما از پکیج نام بردیم منظورمان ماژول است و برعکس.Module == Package == Moduleدر زبان گو هر پوشه‌ای که می‌سازید تبدیل به یک پکیج می‌شود. یک پکیج می‌تواند تبدیل به یک برنامه شود اگر اسمش main باشد. این کمک می‌کند که با استفاده از جداسازی طبیعی، قطعات کد را از لحاظ منطقی مدیریت کنیم.در برنامه‌ اخیرم من باید چند خط کد را در چند فایل دستکاری می‌کردم و بعد از تمام شدن کارم آنها را به AWS S3 آپلود می‌کردم. ساختار برنامه من اینجوری بود:src- my_app- - main.go- - main_test.go- - uploader- - - uploader.go- - - uploader_test.go- - replace_file_lines- - - replace.go- - - replace_test.go- - - strings_util.go- - - strings_util_test.goفایل‌های test.go_  برای اجرای یونیت تست در زبان گو استفاده می شوند. زبان گو یک فریمورک تست در هسته خودش دارد.همچنین برای کسانی که از دنیای زبان‌های شی‌گرا آمده‌اند این ساختار کمک می‌کند که فکر کنیم که هر پوشه یک کلاس استاتیک کامل است، و هر متغیر و هر تابع در داخل فایل‌های go. یک خصیصه یا متد است. در زیر مثالی از فایل replace.go را می بینید:package replace_file_lines  import (  // ...)  // Variables that begin with an uppercase is exposedvar PublicVariable int = 42// While those that begin with loweracse are private to the modulevar privateVariable int = 0  // Function that begins with an uppercase is exposedfunc Replace(oldFilePath, outputFilePath, with, what string) { // ... }  // Function that begins with an uppercase is exposedfunc PublicFunction(/* .. */) {  // ...)  // While lowercase names makes functions private to the modulefunc privateFunction(/* .. */) {  // ...)اگر در هر پوشه بیشتر از یک فایل go. وجود داشته باشد همه ی متغیرها و متدها در سرتاسر پکیج‌ به اشتراک گذاشته می‌شوند، حتی آنهایی که خصوصی هستند. این کار کمک می‌کند که یک پکیج را به قسمت‌های کوچکتر تقسیم کنیم و مجبور نباشیم یک تک‌فایل بزرگ داشته باشیم.بدون اینکه به دعوای شی‌گرایی در مقابل برنامه‌نویسی تابعی و رویه‌‌ای بپردازیم، اینجا مهم است که بدانیم که طراحان زبان گو تصمیم گرفتند که شکل کلاسیک کلاس‌ها را در زبان گو پیاده‌سازی نکنند و بجای آن از structها و اینترفیس‌ها  و البته پکیج‌ها استفاده کنند.برنامه gofmt زبان گو برای اینکه متن کد‌ها چه شکلی باشد قرارداد‌های مخصوص به خودش را دارد. یعنی شکل نوشتار هر خط از کد از قبل تعیین شده است. قالب‌بندی سورس‌کد‌های نوشته شده به زبان گو توسط برنامه gofmt انجام می‌گیرد. این به توسعه‌دهندگان اجازه می‌دهد که به جای اینکه بر سر مکان کروشه‌ها با هم بحث کنند، روی نوشتن کد تمرکز کنند.دعوای قدیمی بر سر مکان کروشه‌ها:برای کسب اطلاعات بیشتر به این لینک مراجعه کنید. ‌‌‌‌ساز و کار import در زبان گوایمپورت‌ها در زبان گو همیشه نسبت به مسیر GOPATH/src سنجیده می‌شوند. من نمی‌توانم بگویم که این تصمیم چقدر مرا از سردرگمی نجات داده است.وقتی که شما با دیگر زبان‌ها کار می‌کنید شما می‌توانید در ایمپورت‌ها هم از مسیرهای نسبی استفاده کنید و هم مسیرهای مطلق. یا حتی یک ایمپورت عجیب را جوری تنظیم کنید که یک فایل را از جایی که هیچ‌کس نمی‌داند کجاست ایمپورت کند ( دارم به تو نگاه می‌کنم پایتون!).زبان گو این مشکل را با یک روش منحصر به فرد حل کرده است. همه‌ی ایمپورت‌ها، بدون توجه به اینکه در چه فایلی هستند، همیشه نسبت به مسیر GOPATH/src سنجیده می‌شوند. در نتیجه در برنامه من ایمپورت‌های فایل main این شکلی می‌شوند:package main import (	&quot;my_app/replace_file_lines&quot;	&quot;my_app/uploader&quot;	// ...)پوشه my_app در پوشه src قرار دارد، در نتیجه ما باید ابتدا آن را ذکر کنیم سپس پکیج‌هایی که در پوشه my_app هستند مثل replace_file_lines و uploader را ایمپورت می‌کنیم. دقت کنید که ما تک‌فایل‌ها را ایمپورت نکرده‌ایم بلکه همه‌ی پکیج را ایمپورت کرده‌ایم. این بسیار عالی کار می‌کند و باعث هیچگونه سردرگمی نمی‌شود.علاوه بر این، گولنگ کامپایل نمی‌شود تا زمانی که شما از تمام پکیج‌هایی که ایمپورت کرده‌اید استفاده کنید. این ویژگی کمک می‌کند که بفهمید که همه‌ی پکیج‌های ایمپورت شده واقعا استفاده شده‌اند.سیستم دریافت پکیج‌ها در گولنگبخش ایمپورت ما را به ویژگی جالب بعدی زبان گو راهنمایی می‌کند: ویژگی go get . در حالی که دیگر زبان‌ها از سیستم مدیریت بسته‌ npm متعلق به جاوا اسکریپت تاثیر گرفته‌اند، زبان گو از مخازن گیت (git) به عنوان مدیریت بسته استفاده می‌کند.این چگونه کار می‌کند؟من قبلا در این مقاله در مورد آپلود به s3 نوشته‌ام، برای انجام این کار من به AWS SDK نیاز دارم. برای دریافت AWS SDK کافی است که ترمینال را باز کنم و دستور زیر را تایپ کنم:go get github.com/aws/aws-sdk-goدر اینجا چه اتفاقی می‌افتد؟ اتفاق خاصی نمی‌افتد، گولنگ مخزن را از لینک https://github.com/aws/aws-sdk-go دانلود می‌کند و در پوشه GOPATH/src می‌ریزد. بعد از این کار همه آنچه که برای استفاده ازaws-sdk نیاز دارید این است که آن را ایمپورت کنید:package uploader import (	&quot;github.com/aws/aws-sdk-go/service/s3&quot;	&quot;github.com/aws/aws-sdk-go/aws/session&quot;	&quot;github.com/aws/aws-sdk-go/aws&quot;	// ...)آیا به خاطر می‌آورید که همه‌ی ایمپورت‌ها نسبت به مسیر GOPATH/src سنجیده می‌شوند؟ از آنجا می‌توانید متوجه شوید که برای مثال پکیج s3  حالا در مسیرGOPATH/src/github.com/aws/aws-sdk-go/services/s3 قرار دارد.سیستم بسته بندی و ساخت گولنگ ما تا اینجا بر روی پوشه GOPATH/src تمرکز کرده بودیم، اما حالا وقتش رسیده است که به پوشه‌های دیگر یعنی GOPATH/pkg و GOPATH/bin بپردازیم.گولنگ یک زبان کامپایلری است یعنی کد قبل از اجرا باید کامپایل شود. سرعت کامپایل گولنگ بالا ست، اما گولنگ چگونه این کار را انجام می‌دهد؟هر بار که شما کد را برای اجرا کامپایل می‌کنید گولنگ یک فایل a. در پوشه GOPATH/pkg در همان مسیری که پکیج شما قرار دارد می‌سازد. این بدان معنی است که به عنوان مثال اگر شما aws-sdk را کامپایل کنید، این پکیج یک بار کامپایل می‌شود و بین همه‌ی قسمت‌های دیگر کد به اشتراک گذاشته می‌شود.البته این تنها دلیل اینکه گولنگ خیلی سریع کامپایل می‌شود نیست. اما این یک خلاصه بود که به شما کمک کند که نقش پوشه GOPATH/pkg را درک کنید.نقش پوشه GOPATH/bin چیست؟ وقتی که شما دستور go install را اجرا می‌کنید گولنگ یک فایل باینری می‌سازد و آن را در پوشه GOPATH/bin قرار می‌دهد. این فایل باینری نامش را از پوشه پکیج اصلی می‌گیرد ( در مثال ما my-app ).چرا این اینقدر عالی است؟ چون شما می‌توانید GOPATH/bin را به مسیر اصلی سیستم‌عامل خودتان اضافه کنید و همه‌ی فایل‌های اجرایی که شما می‌سازید از طریق خط فرمان در دسترس هستند.سیستم ساخت چند-پلتفرمه گولنگآيآ می‌خواهید برای سیستم‌عاملی غیر از سیستم‌عاملی هم‌اکنون در آن کدنویسی می‌کنید فایل اجرایی بسازید؟ خب نگران نباشید، شما برای اینکه برای ویندوز فایل بسازید به یک سیستم ویندوزی احتیاج ندارید. گولنگ نیاز شما را پوشش می‌دهد.فقط کافی است دستور زیر را در ترمینال اجرا کنید:GOOS=windows GOARCH=amd64 go installگولنگ یک فایل اجرایی آماده به کار در ماشین ویندوزی را تولید می‌کند. فایل exe. در مسیر  GOPATH/bin/windows_amd64/my_app.exe قرار می‌گیرد. مثل آب خوردن!زبان گولنگهدف گولنگ این است که یک زبان ساده باشد.من این پست را که پرسیده است چرا گولنگ طراحی نشده است که یک زبان فانکشنال باشد را دوست دارم. برنامه‌نویس‌هایی که در گوگل کار می‌کنند در اوایل کارشان هستند و بیشتر با زبان‌های رویه‌ای به خصوص زبان C آشنایی دارند. به این دلیل که لازم است برنامه‌نویسان در زبان جدید خیلی سریع به بازدهی برسند در نتیجه زبان برنامه‌نویسی جدید نمی‌تواند خیلی افراطی باشد.این لیست چیزهایی  است که گولنگ پشتیبانی نمی‌کند:کلاس‌هاسربارگذاری عملگرهاسربارگذاری توابعپارامترهای اختیاریاستثناهااگر چه بعضی وقت ها که با گو کد می‌زنم احساس کمبود بعضی از ویژگی‌ها را می‌کنم ولی من می‌توانم هر کاری می‌خواهم انجام دهم. این فقط نیاز دارد که بعضی وقت‌ها کد بیشتری بنویسم یا بیشتر فکر کنم. مزیت این سادگی این است که کار کردن با کد ما راحت‌تر می‌شود زیرا کمتر انتزاعی است.بعضی وقت‌ها گو من را شگفت‌زده می‌کند وقتی بدون سال‌ها تجربه کد نوشتن خیلی سریع به هدفم می‌رسم، فقط به خاطر اینکه این زیان خوش‌دست و واضح است.همزمانی در گولنگمن صحبت در مورد همزمانی (concurrency) را عمداً برای قسمت آخر مقاله گذاشتم. برای اینکه فکر می‌کنم این موضوع آنقدرها هم مهم نیست.این یک ویژگی جالب از زبان است، اما بعضی وقت‌ها این ویژگی به عنوان ماهیت اصلی گولنگ ذکر می شود، که من با آن موافق نیستم. درنتیجه اجازه دهید که من آن را در یک پاراگراف خلاصه کنم.بله، گولنگ یک سیستم همزمانی عالی دارد. شما با تِرِدها روبرو نمی‌شوید تا اینکه گو-روتین‌ها را بسازید که ساخت و مدیریت‌شان راحت است. گو-روتین‌ها اجازه می‌دهند که بار برنامه را بین هسته‌های پردازنده توزیع کنید بدون اینکه در مورد مدیریت این کار نگران باشید.اگر علاقه مند به خواندن بیشتر در مورد گو-روتین ها هستید این لینک را دنبال کنید.منبع: hackernoon.comاین مطلب همچنین  در این لینک در وبسایت شخصی من انتشار یافته است.</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Fri, 29 Sep 2017 18:43:32 +0330</pubDate>
            </item>
                    <item>
                <title>کارهایی که کاتلین بهتر از جاوا انجام می‌دهد</title>
                <link>https://virgool.io/@saeed__noori/%DA%A9%D8%A7%D8%B1%D9%87%D8%A7%DB%8C%DB%8C-%DA%A9%D9%87-%DA%A9%D8%A7%D8%AA%D9%84%DB%8C%D9%86-%D8%A8%D9%87%D8%AA%D8%B1-%D8%A7%D8%B2-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D9%86%D8%AC%D8%A7%D9%85-%D9%85%DB%8C%E2%80%8C%D8%AF%D9%87%D8%AF-nkopz3hfocne</link>
                <description>با وجود اینکه اخیرا بحث‌های خیلی زیادی در مورد زبان برنامه‌نویسی کاتلین (Kotlin) صورت گرفته است اما شما ممکن است از خودتان بپرسید که چرا شما باید از آن استفاده کنید؟ کاتلین چه کاری انجام می‌دهد که جاوا انجام نمی‌دهد؟ خوب است که آدم همیشه یک احساس شکاکیت سالم نسبت به هر تکنولوژی جدیدی داشته باشد.اما اینجا یک راز در مورد کاتلین وجود دارد: این زبان در کل کار خاصی انجام نمی‌دهد که جاوا نتواند انجام دهد. خیلی از چیزهایی که کاتلین می‌تواند انجام دهد جاوا با دستکاری کافی می‌تواند انجام دهد. این درست است که شما می‌توانید همه کد را از پایه بدون کمک گرفتن از همه‌ی ابزارها و افزونه‌هایی که کاتلین به محیط توسعه اضافه می‌کند بنویسید. خیلی از اَپ‌ها از کاتلین استفاده نمی‌کنند و به خوبی هم کار می‌کنند. اما آنچه که کاتلین می‌تواند بهتر از جاوا انجام دهد این است که با ساده سازی کد و راحتی خوانش آن سرعت برنامه‌نویسی را افزایش می‌دهد. کاتلین این کار را با حذف بعضی از کد‌های پر استفاده و پر حجم انجام می‌دهد.در این پست ما بر دو موضوع ویژه تمرکز می‌کنیم: خصوصیات[کلاس‌ها] و قابلیت نال شدن (nullability) در کاتلین.خصوصیات[کلاس‌ها] اجازه دهید که با یک مدل یوزر شروع کنیم که وقتی که شما یک اَپ جدید را می‌سازید یک مدل رایج است . این مدل یوزر دو تا فیلد دارد: یک آدرس ایمیل (یک String) و سن یوزر (یک Integer). در جاوا ممکن است شما خودتان کد آن را بنویسد یا IDE شما کد آن را به صورت خودکار تولید کند. در مثال زیر این مدل با زبان جاوا نشان داده شده است:public final class User {
@NotNull
private final String email;
private final int age;
public User(@NotNull String email, int age) {
if (email == null) {
throw new RuntimeException(&quot;Email can&#039;t be null&quot;);
}
super();
this.email = email;
this.age = age;
}
@NotNull
public final String getEmail() {
return this.email;
}
public final int getAge() {
return this.age;
}
public String toString() {
return &quot;User(email=&quot; + this.email + &quot;, age=&quot; + this.age + &quot;)&quot;;
}
public int hashCode() {
return (this.email != null ? this.email.hashCode() : 0) * 31 + this.age;
}
@NotNull
public final User copy(@NotNull String email, int age) {
Intrinsics.checkParameterIsNotNull(email, &quot;email&quot;);
return new User(email, age);
}
public boolean equals(Object otherObject) {
if(this != otherObject) {
if(otherObject instanceof User) {
User otherUser = (User)otherObject;
if(this.email.equals(otherUser.email) &amp;&amp; this.age == otherUser.age) {
return true;
}
}
return false;
} else {
return true;
}
}
}این حدود ۵۰ خط کد برای نوشتن getterها ، setterها و تابع برابری برای مدل یوزر است. حالا اجازه دهید این کار را با کاتلین انجام دهیم:data class User(val email: String, val age: Int)در کل کاتلین با سادگی و فقط یک خط کد برنده می‌شود. این یک اشتباه نیست، این یک خط کد دقیقا همان کارایی کد جاوا را دارد.  در واقع از لحاظ تکنیکی جمله قبلی صد در صد درست نیست، زیرا کد کاتلین علاوه بر کاری که جاوا انجام می‌دهد از برنامه‌نویس در زمان کامپایل از اینکه به طور تصادفی مقدار ایمیل را null ارسال کند محافظت می‌کند.قابلیت نال شدن (nullability) اجازه دهید به قابلیت نال شدن بپردازیم. در این مورد کاتلین null را به صورت داخلی در سیستم نوع داده‌اش دارد. این دقیقا به چه معناست؟ در کاتلین وقتی که شما یک آبجکت تعریف می‌کنید شما باید تعیین کنید که آیا به آن اجازه نال شدن می‌دهید یاخیر؟ زیرا در کاتلین آبجکت‌ها به صورت پیش‌فرض قابلیت نال شدن ندارند.به عنوان مثال اجازه دهید در جاوا یک کلاس رویدادنگار ساده بنویسم که به ایمیل کاربر برای ثبت یک رویداد نیاز دارد:public class LoggingClass {
private final User myUser;
public LoggingClass(User myUser) {
this.myUser = myUser;
}
public void logEvent(String eventName) {
String userEmail = myUser.getEmail();
AnalyticsClient.logEvent(eventName, userEmail);
}
}مشکلی که با این کد جاوا وجود دارد این است که اگر myUser نال باشد صدا زدن متد logEvent ممکن است باعث یک NullPointerException شود که این باعث کرش کردن برنامه می‌شود. بنابرین سعی می‌کنیم این مشکل را حل کنیم:public class LoggingClass {
private final User myUser;
public LoggingClass(User myUser) {
this.myUser = myUser;
}
public void logEvent(String eventName) {
if (myUser != null) {
String userEmail = myUser.getEmail();
AnalyticsClient.logEvent(eventName, userEmail);
}
}
} اگربخواهیمصادقباشیمبرایهمه‌یماپیشآمدهاستکهمشکلرااینجوریحلکرده‌ایم.هرچندکهاینیکراهحلکوچکوسریعاستامادرواقعمامشکلراحلنکرده‌ایمبلکهآنراپنهانکرده‌ایم.مشکلکرشکردنبرنامهحلشدهاستامامشکلبرنامههنوزپابرجاستوحالابهصورتبیصداباخطامواجهمی‌شودورویداد‌هابهدرستیثبتنمی‌شوند. اجازه دهید همین کلاس را با کاتلین بنویسیم:class LoggingClass(private val myUser: User) {
fun logEvent(eventName: String) {
val userEmail = myUser.email
AnalyticsClient.logEvent(eventName, userEmail)
}
}در این مثال اگر مدل یوزری که به آن پاس داده می‌شود احتمال نال شدن داشته باشد برنامه اصلا کامپایل نمی‌شود. یک امکان خوب که به کاتلین اضافه شده است این است که کامپایلر در همچین جایی یک خطا تولید می‌کند و از اینکه شما یک NullPointerException تولید کنید جلوگیری می‌کند:همچنان که در شکل بالا مشخص است کامپایلر به شما اجازه نمی‌دهد یوزری که امکان نال شدن دارد را به logger پاس دهید. این بدان معناست که نیاز نیست شما نگران احتمال نال شدن آبجکت یوزر باشید و با حفاظتی که در مقابل مقادیر نال قرار دارد  شما می‌توانید بدون اینکه نگران حالت مدل یوزر باشید کلاس logger خودتان را بنویسید.پس کاتلین اینجا چه کاری انجام می‌دهد تا مقداری که نمی‌تواند نال باشد را تحمیل کند؟ اجازه بدهید کد کاتلین را دکامپایل کنیم تا به جواب برسیم:public LoggingClass(@NotNull User myUser) {
Intrinsics.checkParameterIsNotNull(myUser, “myUser”);
super();
this.myUser = myUser;
}علاوه بر چک کردن در زمان کامپایل، کاتلین همچنین یک چک زمان رانتایم هم به کد اضافه می‌کند.در زبان جاوا هم شما به راحتی می‌توانستید یک کلاس کمکی برای انجام این کار در زمان رانتایم اضافه کنید، و با کمی دستکاری یک linter هم برای کمک در زمان کامپایل بنویسید.یا می‌توانید از کاتلین استفاده کنید که این کارها را به راحتی و رایگان برای شما انجام می‌دهد.نتیجه‌گیریکاتلین به برنامه‌نویسان کمک می‌کند که کد کمتری بنویسند که این باعث ایجاد باگ کمتر، ذخیره زمان بیشتر و استرس کمتر می‌شود. با کاتلین برنامه‌نویس‌ها می‌توانند زمان کمتری را صرف نوشتن کد‌های تکراری و پر حجم کنند یا زمان کمتری به حل کردن NullPointerException‌ها اختصاص دهند و زمان بیشتری را صرف نو‌آوری در تولید و ایجاد تجربیات بهتر برای کاربران کنند.منبع: medium.comپ.ن: اگر در خواندن سورس کدها مشکل دارید می‌توانید این مطلب را در این لینک در وبسایت شخصی من هم بخوانید.</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Thu, 28 Sep 2017 20:34:59 +0330</pubDate>
            </item>
                    <item>
                <title>جدید‌ترین ویژگی‌های جاوا اسکریپت در استاندارد ES8</title>
                <link>https://virgool.io/tehranjs/%D8%AC%D8%AF%DB%8C%D8%AF%E2%80%8C%D8%AA%D8%B1%DB%8C%D9%86-%D9%88%DB%8C%DA%98%DA%AF%DB%8C%E2%80%8C%D9%87%D8%A7%DB%8C-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%AF%D8%B1-%D8%A7%D8%B3%D8%AA%D8%A7%D9%86%D8%AF%D8%A7%D8%B1%D8%AF-es8-fcxkzv6hfhfk</link>
                <description>استاندارد جدید جاوا اسکریپت تحت نام EcmaScript 8 یا EcmaScript 2017 به صورت رسمی در ماه ژوئن به وسیله کمیته TC39 انتشار یافت. به نظر می‌رسد ما به میزان زیادی در مورد EcmaScript در سال گذشته حرف زده‌ایم، این بی‌دلیل نیست. در حال حاضر هر ساله یک نسخه جدید از استاندارد ES انتشار می‌یابد. استاندارد ES6 در سال ۲۰۱۵ انتشار یافت و استاندارد ES7 در سال ۲۰۱۶. اما آیا کسی به خاطر می‌آورد که استاندارد ES5 چه سالی منتشر شد؟ این اتفاق در سال ۲۰۰۹ افتاد، قبل از رشد جادویی جاوا اسکریپت.ما توسعه جاوا اسکریپت را به عنوان یک زبان پایدار دنبال می‌کنیم و الان وقتش رسیده است که ES8 را به دایره واژگان‌مان اضافه کنیم.اگر شما آدم باحوصله‌ای هستید وقت بگذارید و نسخه وب یا PDF ویژگی‌های جدید جاوا اسکریپت را بخوانید. برای بقیه در این مقاله عمده‌ترین ویژگی‌های جدید در ES8 را همراه با مثال پوشش داده‌ایم.دنباله‌گذاری رشته‌ها (String padding)این قسمت دو تابع جدید به آبجکت String اضافه کرده است: padStart و padEnd. همچنان که از نام‌شان پیداست هدف این توابع دنباله‌گذاری رشته‌ها در ابتدا یا انتهای آنهاست، در نتیجه طول رشته به مقدار مورد نظر می‌رسد. شما می‌توانید یک رشته را با یک کاراکتر خاص، یک رشته یا به صورت پیش‌فرض با جای خالی دنباله‌گذاری کنید. اعلان این توابع این شکلی است:str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])همچنان که می‌بینید اولین پارامتر از این توابع targetLength است که طول نهایی رشته حاصله را تعیین می‌کند. پارامتر دوم اختیاری است و رشته‌ای است که به رشته اصلی اضافه می‌شود، مقدار پیش‌فرض این پارامتر جای خالی (space) است.&#039;es8&#039;.padStart(2);          // &#039;es8&#039;
&#039;es8&#039;.padStart(5);          // &#039;  es8&#039;
&#039;es8&#039;.padStart(6, &#039;woof&#039;);  // &#039;wooes8&#039;
&#039;es8&#039;.padStart(14, &#039;wow&#039;);  // &#039;wowwowwowwoes8&#039;
&#039;es8&#039;.padStart(7, &#039;0&#039;);     // &#039;0000es8&#039;
&#039;es8’.padEnd(2);          // &#039;es8&#039;
&#039;es8’.padEnd(5);          // &#039;es8  &#039;
&#039;es8’.padEnd(6, &#039;woof’);  // &#039;es8woo&#039;
&#039;es8’.padEnd(14, &#039;wow’);  // &#039;es8wowwowwowwo&#039;
&#039;es8’.padEnd(7, &#039;6’);     // &#039;es86666&#039;پشتیبانی مرورگرهامتدهای Object.values و Object.entriesمتد Object.values یک آرایه از مقادیر خصوصیات شمارش‌پذیر (enumerable property) یک آبجکت را برمی‌گرداند، به همان ترتیبی که در یک حلقه for in برگردانده می‌شوند. اعلان این متد این شکلی است:Object.values(obj)پارامتر obj همان آبجکت داده شده برای عملیات است. این پارامتر می‌تواند یک آبجکت یا یک آرایه (که یک آبجکت ایندکس‌دار است) باشد.const obj = { x: &#039;xxx&#039;, y: 1 };
Object.values(obj); // [&#039;xxx&#039;, 1]
const obj = [&#039;e&#039;, &#039;s&#039;, &#039;8&#039;]; // same as { 0: &#039;e&#039;, 1: &#039;s&#039;, 2: &#039;8&#039; };
Object.values(obj); // [&#039;e&#039;, &#039;s&#039;, &#039;8&#039;]
// when we use numeric keys, the values returned in a numerical 
// order according to the keys
const obj = { 10: &#039;xxx&#039;, 1: &#039;yyy&#039;, 3: &#039;zzz&#039; };
Object.values(obj); // [&#039;yyy&#039;, &#039;zzz&#039;, &#039;xxx&#039;]
Object.values(&#039;es8&#039;); // [&#039;e&#039;, &#039;s&#039;, &#039;8&#039;]پشتیبانی مرورگرها از Object.valuesمتد Object.entries خصوصیات شمارش‌پذیر یک آبجکت را بصورت جفت‌های کلید و مقدار [key, value] برمی‌گرداند، به همان ترتیبی که متد Object.values خصوصیات را برمی‌گرداند. در مثال زیر نحوه استفاده از این متد را مشاهد می‌کنید:const obj = { x: &#039;xxx’, y: 1 };
Object.entries(obj); // [[’x’, &#039;xxx’], [’y’, 1]]
const obj = [’e’, &#039;s’, &#039;8’];
Object.entries(obj); // [[’0’, &#039;e’], [’1’, &#039;s’], [’2’, &#039;8’]]
const obj = { 10: &#039;xxx’, 1: &#039;yyy’, 3: &#039;zzz&#039; };
Object.entries(obj); // [[’1’, &#039;yyy’], [’3’, &#039;zzz’], [’10’, &#039;xxx’]]
Object.entries(&#039;es8&#039;); // [[&#039;0&#039;, &#039;e&#039;], [&#039;1&#039;, &#039;s&#039;], [&#039;2&#039;, &#039;8&#039;]]پشتیبانی مرورگرها از Object.entries متد Object.getOwnPropertyDescriptorsاین متد همه‌ی توصیف‌گر‌های خصوصیات یک آبجکت را برمی‌گرداند. یک توصیف‌گر متعلق به یک آبجکت، توصیف‌گری است که مستقیما بر روی آبجکت تعریف شده است و از خصوصیت آبجکت به ارث برده نشده است. اعلان این متد مانند زیر است:Object.getOwnPropertyDescriptors(obj)پارامتر obj آبجکت مورد نظر است. کلید‌های ممکن برای آبجکت‌های توصیف‌گر   configurable, enumerable, writable, get, set و value هستند:const obj = { 
get es7() { return 777; },
get es8() { return 888; }
};
Object.getOwnPropertyDescriptors(obj);
// {
//   es7: {
//     configurable: true,
//     enumerable: true,
//     get: function es7(){}, //the getter function
//     set: undefined
//   },
//   es8: {
//     configurable: true,
//     enumerable: true,
//     get: function es8(){}, //the getter function
//     set: undefined
//   }
//}داده‌های توصیف‌گر برای ویژگی‌های پیشرفته‌ای مانند دکوراتورها بسیار مهم هستند.پشتیبانی مرورگرهاکامای انتهایی در لیست پارامترهای توابع و هنگام صدا زدن توابعکامای انتهایی در لیست پارامتر‌های توابع یک توانایی کامپایلر برای باز نگردادن خطای SyntaxError وقتی ما یک کامای غیرضروری به انتهای لیست اضافه می‌کنیم است:function es8(var1, var2, var3,) {
 // ...
}همچنین هنگام صدا زدن توابع نیز ما می‌توانیم یک کامای اضافی بگذاریم:es8(10, 20, 30,);ایده این ویژگی از کامای انتهایی که در آرایه‌ها و آبجکت‌ها گذاشته می‌شود گرفته شده است://Array
[10, 20, 30,]
//Object
{ x: 1, }توابع Asyncاعلان async function یک تابع ناهمگام (asynchronous) را تعریف می کند که یک آبجکت AsyncFunction را برمی‌گرداند. توابع async باطناً  بسیار شبیه جنراتورها عمل می‌کنند، ولی آنها به توابع جنراتور ترجمه نمی‌شوند.function fetchTextByPromise() {
    return new Promise(resolve =&gt; { 
        setTimeout(() =&gt; {   
            resolve(&quot;es8&quot;);   
        }, 2000);
    });
}
async function sayHello() { 
     const externalFetchedText = await fetchTextByPromise();
     console.log(`Hello, ${externalFetchedText}`); // Hello, es8
sayHello();صدا زدن تابع sayHello باعث می‌شود بعد از گذشت ۲ ثانیه عبارت Hello,es8 چاپ شود، به عنوان مثال:console.log(1);
sayHello();
console.log(2); خروجی زیر را تولید می‌کند:1 // immediately
2 // immediately
Hello, es8 // after 2 secondsاین به این دلیل است که صدا زدن تابع، جریان را بلوکه نمی‌کند.توجه کنید که یک تابع async همیشه یک promise را برمی‌گرداند و کلیدواژه await فقط در توابعی به کار می‌رود که با کلیدواژه async مشخص شده باشند.پشتیبانی مرورگرهاحافظه مشترک و اتمیک‌هاوقتی که حافظه مشترک است چندین تِرِد می‌توانند یک داده واحد را در حافظه بخوانند و بنویسند. عملیات اتمیک منجر به اطمینان از خواندن و نوشتن مقادیر قابل پیش بینی می‌شوند. هر کدام از این نوع عملیات قبل از شروع عملیات بعدی پایان می پذیرد، و همچنین این نوع عملیات وقفه‌پذیر نیستند. این قسمت یک سازنده جدید به نام SharedArrayBuffer و همچنین یک آبجکت فضای نام جدید به نام Atomics را معرفی می‌کند.آبجکت Atomics یک آبجکت مانند Math است که تمام متد‌های آن استاتیک هستند، در نتیجه ما نمی‌توانیم از آن به عنوان یک سازنده استفاده کنیم. چند نمونه از متد‌های این آبجکت در زیر آورده شده‌اند:متد‌های add و sub: یه مقدار را به یک مقدار دیگر در یک موقعیت خاص اضافه یا کم می‌کنند.متدهای and و or و xor: عملگرهای بیتی and,or و xor بر روی بیت‌ها هستند.متد load: یک مقدار را در یک موقعیت خاص دریافت می‌کند.پشتیبانی مرورگرهاو یک ویژگی برای سال بعد در استاندارد ES9: رفع محدودیت template literalدر استاندارد ES6 ما می‌توانیم با template literal تگ شده  کارهای جالبی انجام دهیم، مثلا تعریف یک تابع تحلیل‌گر template و بازگرداندن یک مقدار با توجه به منطق مورد نظر ما:const esth = 8;
helper`ES ${esth} is `;
function helper(strs, ...keys) {
    const str1 = strs[0]; // ES
     const str2 = strs[1]; // is
    let additionalPart = &#039;&#039;;
    if (keys[0] == 8) { // 8
        additionalPart = &#039;awesome&#039;;
     }
    else {
        additionalPart = &#039;good&#039;;
    }
    return `${str1} ${keys[0]} ${str2} ${additionalPart}.`;
}مقدار برگشتی ES 8 is awesome خواهد بود. و اگر مقدار esth برابر با ۷ شود مقدار برگشتی ES 7 is good خواهد بود.اما برای template هایی که به عنوان مثال حاوی عبارت u\ یا x\ هستند محدودیت وجود دارد. استاندارد es9 این محدودیت را رفع می‌کند. برای مطالعه بیشتر در این باره به سایت MDN یا مستندات TC39 مراجعه کنید.پشتیبانی مرورگرهانتیجه‌گیریجاوا اسکریپت در حال تولید است اما همیشه در حال نو شدن است. پروسه اضافه کردن ویژگی‌های جدید به آن بسیار منظم و با توازن است. این ویژگی‌های جدید در آخرین نسخه استاندارد آن به وسیله کمیته TC39 تایید شده و توسط توسعه‌دهندگان مرکزی پیاده‌سازی شده است. بسیاری از این ویژگی‌ها هم اکنون قسمتی از زبان تایپ‌اسکریپت، مرورگرها و دیگر پلی‌فیل‌ها هستند، در نتیجه شما همین حالا می‌توانید بروید و آنها را امتحان کنید.منبع: hackernoon.com</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Tue, 29 Aug 2017 06:23:31 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه از اعلان نوع داده در پایتون ۳.۶ استفاده کنیم؟</title>
                <link>https://virgool.io/@saeed__noori/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%A7%D8%B2-%D8%A7%D8%B9%D9%84%D8%A7%D9%86-%D9%86%D9%88%D8%B9-%D8%AF%D8%A7%D8%AF%D9%87-%D8%AF%D8%B1-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%DB%B3-%DB%B6-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85%D8%9F-nqavfy6qgz7e</link>
                <description>یکی از معمول‌ترین مشکلاتی که در پایتون وجود دارد این است که نوع داده‌های آن دینامیک است. این بدین معنی است که شما متغیرها را بدون اینکه نوع داده آنها را مشخص کنید تعریف می‌کنید. نوع متغیرها بر حسب اینکه چه نوع داده‌ای به آنها پاس داده شود به صورت اتوماتیک تعیین می‌شود. به عنوان مثال:president_name = &quot;Franklin Delano Roosevelt&quot;
print(type(president_name)) 
# Result is:
# &lt;class &#039;str&#039;&gt;در مثال بالا متغیر president_name به عنوان یک str ساخته شده است زیرا ما به آن یک رشته نسبت داده‌ایم. اما پایتون تا زمانی که آن خط از کد را اجرا نکند نمی‌داند این متغیر از نوع رشته است.اما در مقام مقایسه زبانی مثل جاوا استاتیک-تایپ است. برای ساخت همین متغیر در جاوا شما باید نوع متغیر را مشخصا با کلمه String مشخص کنید:String president_name = &quot;Franklin Delano Roosevelt&quot;;از آنجا که جاوا از قبل می‌داند که متغیر president_name از نوع String است اگر شما به آن یک مقدار اشتباه مثلا یک عدد را نسبت دهید کامپایلر به شما گزارش خطا نشان خواهد داد.چرا نوع داده مهم است؟ معمولا نوشتن کد به حالت دینامیک-تایپ مانند حالتی که در پایتون نوشته می‌شود سریع‌تر است زیرا شما مجبور نیستید که نوع متغیرها را اعلام کنید، اما هنگامی که کد شما شروع به بزرگ شدن می‌کند با تعداد زیادی خطای زمان اجرا روبرو خواهید شد، خطاهایی که در زبان‌های استاتیک-تایپ به واسطه استاتیک-تایپ بودن از آنها جلوگیری می‌شود.در مثال زیر یکی از رایج‌ترین خطاها در زبان پایتون را می بینید:def get_first_name(full_name):
    return full_name.split(&quot; &quot;)[0]
fallback_name = {
     &quot;first_name&quot;: &quot;UserFirstName&quot;,   
     &quot;last_name&quot;: &quot;UserLastName&quot;
}
raw_name = input(&quot;Please enter your name: &quot;)
first_name = get_first_name(raw_name)
# If the user didn&#039;t type anything in, use the fallback name
if not first_name:
    first_name = get_first_name(fallback_name)
print(f&quot;Hi, {first_name}!&quot;)همه‌ی آنچه که ما در کد بالا انجام داده‌ایم این است که از کاربر اسمش را پرسیده‌ایم و عبارت &quot;Hi, &lt;first name&gt;!&quot; را چاپ کرده‌ایم، و اگر کاربر چیزی را وارد نکند عبارت “Hi, UserFirstName!” را چاپ می‌کنیم.این برنامه تا زمانی که کاربر چیزی را وارد کند به خوبی کار می‌کند. اما اگر کاربر مقدار ورودی را  خالی بگذارد برنامه کرش می‌کند:Traceback (most recent call last):
   File &quot;test.py&quot;, line 14, in &lt;module&gt;   
     first_name = get_first_name(fallback_name) 
 File &quot;test.py&quot;, line 2, in get_first_name 
   return full_name.split(&quot; &quot;)[0]
AttributeError: &#039;dict&#039; object has no attribute &#039;split&#039; مشکل آنجاست که متغیر fallback_name یک رشته نیست بلکه یک دیکشنری است و از آنجا که نوع داده دیکشنری تابعی به نام ()split. ندارد صدا زدن تابع get_first_name بر روی fallback_name با شکست مواجه می‌شود.این یک خطای ساده و آشکار است اما آنچه که این خطا را مشکل‌ساز می‌کند این است که شما هیچوقت از وجود آن آگاه نمی‌شوید تا اینکه کاربر برنامه را اجرا کند و بر حسب تصادف جای نام را خالی بگذارد. شما ممکن است برنامه را صدها بار تست کنید و هیچوقت از وجود همچین باگ ساده‌ای مطلع نشوید زیرا همیشه اسم را وارد می‌کنید.استفاده از مدل استاتیک-تایپ از همچین باگی جلوگیری می‌کند. قبل از آنکه حتی برنامه‌تان را اجرا کنید مدل استاتیک-تایپ به شما می‌گوید که شما نمی‌توانید متغیر fallback_name را به تابع get_first_name() پاس دهید زیرا این تابع یک رشته می‌گیرد ولی شما به آن یک دیکشنری فرستاده‌اید. حتی ممکن است ویرایشگر کد شما هنگامی که در حال نوشتن هستید این خطا را هایلایت کند.هنگامی که این نوع از خطا در پایتون رخ می‌دهد معمولا مانند این مثال در یک تابع ساده نیست، بلکه معمولا چند لایه از ماژول‌ها را رد می کند و نوع داده ارسالی تفاوت کمی با نوع داده مورد قبول دارد. برای دیباگ همچین خطایی شما مجبورید ورودی کاربر را بازسازی کنید و کشف کنید که کجا ممکن است خطا اتفاق افتاده باشد. مقدار بسیار زیادی زمان برای دیباگ کردن همچین خطای قابل‌ پیشگیریی تلف می‌شود.خبر خوب اینکه شما حالا می‌توانید  اگر بخواهید در پایتون از مدل استاتیک-تایپ استفاده کنید، و بالاخره به نسخه ۳.۶ پایتون یک سینتکس معقول برای اعلان نوع داده‌ها اضافه شد.ترمیم برنامه مشکل‌دار بالااجازه دهید برنامه مثال بالا را با اعلان نوع متغیرها و ورودی/خروجی توابع دوباره نویسی کنیم:from typing import Dict
def get_first_name(full_name: str) -&gt; str: 
    return full_name.split(&quot; &quot;)[0]
fallback_name: Dict[str, str] = {
&quot;first_name&quot;: &quot;UserFirstName&quot;,
&quot;last_name&quot;: &quot;UserLastName&quot;
}
raw_name: str = input(&quot;Please enter your name: &quot;)
first_name: str = get_first_name(raw_name)
# If the user didn&#039;t type anything in, use the fallback name
if not first_name:
    first_name = get_first_name(fallback_name)
print(f&quot;Hi, {first_name}!&quot;)    در پایتون ۳.۶ شما نوع یک متغیر را اینجوری اعلام می‌کنید:variable_name: typeو اگر متغیر شما مقدار اولیه بگیرد اعلان آن اینجوری خواهد بود:my_string: str = &quot;My String Value&quot;و همچنین نوع ورودی و خروجی توابع را اینجوری اعلام می‌کنید:def function_name(parameter1: type) -&gt; return_type:این کار بسیار ساده است، فقط یک دستکاری کوچک در سینتکس نرمال پایتون.حالا که نوع داده‌ها را در مثال بالا مشخص کردیم اجازه دهید ببینیم با اجرای برنامه چک کننده نوع چه اتفاقی می‌افتد:$ mypy typing_test.py
test.py:16: error: Argument 1 to &quot;get_first_name&quot; has incompatible type Dict[str, str]; expected 
&quot;str&quot;
برنامه چک کننده نوع بدون اینکه حتی برنامه را اجرا کند می‌فهمد که خط ۱۶ از کد مشکل دارد. شما می‌توانید این مشکل را همین الان رفع کنید بدون اینکه مجبور باشید صبر کنید تا یک کاربر سه ماه بعد آن را کشف کند.و اگر شما از یک IDE مثل  PyCharm استفاده می‌کنید این IDE قبل از اینکه حتی برنامه‌تان را اجرا کنید به صورت خودکار نوع متغیرها را چک می‌کند و به شما نشان می‌دهد کجای کدتان مشکل دارد:مثال‌های بیشتری از سینتکس پایتون ۳.۶ برای اعلان نوع دادهاعلان نوع str یا int راحت است، دردسر واقعی وقتی پیش می‌آید که بخواهیم نوع داده یک متغیر پیچیده‌تر مثل یک لیست تو در تو یا یک دیکشنری تو در تو را اعلام کنیم. خوشبختانه سینتکس پایتون ۳.۶ برای این کار چندان هم بد نیست.الگوی پایه برای این کار این است که نام نوع داده پیچیده را از ماژول typing وارد کنیم و نوع داده‌های داخلی‌تر را داخل براکت بنویسیم. معمول‌ترین نوع داده‌های پیچیده‌ای که شما استفاده می‌کنید List,Dict و Tuple هستند. در زیر یک مثال از استفاده از این نوع داده‌ها را می‌بینید:from typing import Dict, List
# A dictionary where the keys are strings and the values are ints
name_counts: Dict[str, int] = {
    &quot;Adam&quot;: 10,
    &quot;Guido&quot;: 12
}
# A list of integers
numbers: List[int] = [1, 2, 3, 4, 5, 6]
# A list that holds dicts that each hold a string key / int value
list_of_dicts: List[Dict[str, int]] = [ 
    {&quot;key1&quot;: 1},
    {&quot;key2&quot;: 2}
]تاپل‌ها قدری ویژه‌تر هستند زیرا اجازه می‌دهند نوع هر کدام از عناصرشان را به صورت جداگانه اعلان کنید:from typing import Tuple
my_data: Tuple[str, int, float] = (&quot;Adam&quot;, 10, 5.7)شما همچنی می توانید با اختصاص دادن یک نام برای اعلان نوع داده‌های پیچیده‌تر برای آن‌ها نام مستعار (alias) تعیین کنید:from typing import List, Tuple
LatLngVector = List[Tuple[float, float]]
points: LatLngVector = [
    (25.91375, -60.15503),  
    (-11.01983, -166.48477),
    (-11.01983, -166.48477)
]بعضی وقتا تابع شما باید آنقدر انعطاف‌پذیر باشد که بتواند چندین نوع داده مختلف را اداره کند یا با هر نوع داده‌ای کار کند، در این مواقع شما می‌توانید از نوع داده Union به جای چندین نوع داده استفاده کنید یا از نوع داده Any برای پذیرش همه‌ی انواع داده‌ها استفاده کنید.پایتون ۳.۶ همچین از بعضی انواع داده‌های سطح بالاتر که ممکن است در دیگر زبان‌ها دیده باشید پشتیبانی می‌کند، مثل جنریک‌ها و نوع داده‌های تعریف شده توسط کاربر.اجرای برنامه چک کننده نوعهر چند که پایتون ۳.۶ این سینتکس جدید برای اعلان نوع داده‌ها را در اختیار شما می‌گذار اما خودش فعلا هیچ کاری با این اعلان نوع انجام نمی‌دهد. برای چک کردن نوع داده‌ها دو راه دارید:۱. برنامه متن‌باز mypy را دانلود کنید و با استفاده از آن هنگام توسعه یا تست کدتان نوع داده‌ها را چک کنید. ۲. از چک کننده توکار PyCharm استفاده کنید. یا اگر از ویرایشگر دیگری مثل Atom استفاده می‌کنید پلاگین مخصوص این کار را برایش نصب کنید.من توصیه می‌کنم از هر دوی این‌ها با هم استفاده کنید زیرا PyCharm و mypy از دو روش مختلف برای چک کردن نوع داده‌ها استفاده می کنند، در نتیجه هر کدام ممکن است مشکلی را کشف کند که دیگری نتواند ببیند. شما می‌توانید از PyCharm برای کشف خطاها در حین نوشتن کد استفاده کنید و از mypy در هنگام تست کد به عنوان بازبینی نهایی.آیا لازم است از این به بعد کدهای پایتون را با اعلان نوع بنویسیم؟اعلان نوع در پایتون پدیده خیلی تازه‌ای است که فقط در پایتون ۳.۶ به طور کامل کار می‌کند. اگر شما کد دارای اعلان نوع را به یک توسعه‌دهنده پایتون دیگر نشان دهید احتمالا فکر می‌کند دیوانه شده‌اید، همچنین برنامه mypy هنوز در حال توسعه است و به نظر نمی‌رسد به این زودی‌ها به نسخه پایدار برسد. در نتیجه کمی زود است که همه‌ی پروژه‌هایتان را به این سمت سوق دهید. اما اگر بر روی پروژه جدیدی کار می کنید که می‌توانید پایتون ۳.۶ را به عنوان نیازمندی حداقل آن تعیین کنید ممکن است ارزشش را داشته باشد که اعلان نوع داده را در کدتان تجربه کنید، این عمل پتانسیلش را دارد که از تعداد زیادی باگ در برنامه‌تان جلوگیری کند.گزینه خوبی که وجود دارد این است که شما می‌توانید کدی که در آن اعلان نوع وجود دارد را با کدی که اعلان نوع ندارد ترکیب کنید. یعنی اعلان نوع یک چیز «همه یا هیچ» نیست. در نتیجه شما می‌توانید با نوشتن نوع داده‌ها در قسمت‌هایی از کد که مهم‌تر هستند شروع کنید، بدون اینکه همه‌ی کدتان را تغییر دهید. از آنجا که پایتون هنگام اجرا هیچ کاری با این اعلان نوع ندارد در نتیجه اعلان نوع برای کد شما هیچ مشکلی پیش نمی‌آورد.پایان!  منبع: +</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Wed, 16 Aug 2017 08:12:27 +0430</pubDate>
            </item>
                    <item>
                <title>پس شما می‌خواهید یک برنامه‌نویس تابع‌گرا (فانکشنال) شوید؟(قسمت ششم)</title>
                <link>https://virgool.io/@saeed__noori/%D9%BE%D8%B3-%D8%B4%D9%85%D8%A7-%D9%85%DB%8C%E2%80%8C%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%B4%D9%88%DB%8C%D8%AF%D8%9F-%D9%82%D8%B3%D9%85%D8%AA-%D8%B4%D8%B4%D9%85-uunxo3tumk2o</link>
                <description>اولین قدم‌ها برای یادگیری برنامه‌نویسی فانکشنال مهم‌ترین قدم‌ها هستند و در برخی اوقات سخت‌ترین قدم‌ها. البته اگر از راه درست وارد شوید چندان هم سخت نخواهد بود.خب حالا چه؟حالا که شما همه‌ی این چیزهای جالب جدید را آموختید ممکن است بپرسید: خب حالا چه؟ چگونه از این چیزهای جدید در برنامه‌نویسی هر روزه‌ام استفاده کنم؟خوب این بستگی دارد. اگر شما می‌توانید با یک زبان تابع‌گرای خالص مثل Elm یا Haskell کد بزنید شما می توانید همه‌ی این ایده‌ها را به کار بگیرید. این نوع زبان‌ها انجام این کار را تسهیل می‌کنند.اگر شما فقط می‌توانید با یک زبان‌ امری مانند جاوا اسکریپت کد بزنید، همچنان که همه‌ی ما مجبوریم، شما همچنان می‌توانید از خیلی از مفاهیمی که اینجا آموخته‌اید استفاده کنید، هر چند که برای این کار باید انضباط کاری زیادی به خرج دهید.جاوا اسکریپت تابع‌گرا جاوا اسکریپت ویژگی‌های زیادی دارد که به شما اجازه می‌دهد به شکل تابع‌گرا کد بزنید. جاوا اسکریپت یک زبان تابع‌گرای خالص نیست اما شما می‌توانید با آن به مقداری از تغییرناپذیری (Immutability) دست پیدا کنید، و حتی با بعضی از کتابخانه‌ها‌ی آن به مقدار بیشتری برسید.البته این ایده‌آل نیست اما اگر شما مجبور به استفاده از آن هستید چرا از بعضی از ویژگی‌های تابع‌گرای آن استفاده نکنید؟تغییرناپذیری اولین چیزی که باید به آن رسیدگی شود تغییرناپذیری است. در استاندارد ES2015 یا ES6  یک کلمه کلیدی جدید به نام const وجود دارد. هر گاه یک متغیر با این کلمه تعریف شود، آن متغیر بعد از گرفتن مقدار دیگر مقدارش تغییر نخواهد کرد:const a = 1;
a = 2; // this will throw a TypeError in Chrome, Firefox or Node
// but not in Safari (circa 10/2016)در کد بالا a به عنوان یک ثابت تعریف شده است و مقدار ۱ را گرفته است. به همین دلیل وقتی مفسر جاوا اسکریپت به a=2 می‌رسد یک استثنا تولید می‌کند (البته به جز مفسر مرورگر Safari)مشکلی که  const در جاوا اسکریپت دارد این است که چندان هم سختگیر نیست. مثال زیر به روشن شدن موضوع کمک می‌کند:const a = {
x: 1,    
y: 2
};
a.x = 2; // NO EXCEPTION!
a = {}; // this will throw a TypeErrorدقت کنید که چگونه عبارت a.x=2 هیچگونه استثنایی را تولید نکرده است. تنها چیزی که با کلمه کلیدی const تغییرناپذیر شده است متغیر a است. هر چیزی که a به آن اشاره کن می‌تواند تغییر کند.این واقعا ناامید کننده است زیرا جاوا اسکریپت با آن می‌توانست خیلی بهتر شود.پس ما چگونه در جاوا اسکریپت به تغییرناپذیری برسیم؟متاسفانه ما فقط با یک کتابخانه جاوا اسکریپت به نام Immutable.js این کار را انجام دهیم. این کتابخانه هر چند که می‌تواند ما را به تغییرناپذیری بیشتری برساند اما متاسفانه باعث می شود کدمان بیشتر شبیه جاوا شود تا جاوا اسکریپت.کاری کردن و ترکیب (Currying and Composition)قبلا در این سری از آموزش‌ها ما یاد گرفتیم که چگونه توابع را به صورت کاری شده بنویسیم. در زیر یک مثال پیچیده‌تر می‌بینید:const f = a =&gt; b =&gt; c =&gt; d =&gt; a + b + c + dتوجه کنید که در جاوا اسکریپت ما مجبوریم قسمت کاری کردن را خودمان بنویسیم. و صدا زدن تابع f را باید اینجوری انجام دهیم:console.log(f(1)(2)(3)(4)); // prints 10کد بالا آنقدر پرانتز دارد که یک برنامه‌نویس زبان لیسپ را به گریه می‌اندازد! کتابخانه‌های زیادی هستند که این پروسه را راحت‌تر می‌کنند، کتابخانه مورد علاقه من Ramda نام دارد.با استفاده از Ramda حالا ما می‌توانیم بنویسیم:const f = R.curry((a, b, c, d) =&gt; a + b + c + d);
console.log(f(1, 2, 3, 4)); // prints 10
console.log(f(1, 2)(3, 4)); // also prints 10
console.log(f(1)(2)(3, 4)); // also prints 10تعریف تابع چندان بهتر نشده است اما ما نیاز به استفاده از آن همه پرانتز را حذف کرده‌ایم. دقت کنید که ما می توانیم تعداد پرانتزها را هنگام فراخوانی تابع f کم و زیاد کنیم.با استفاده از کتابخانه Ramda ما می‌توانیم تابع mult5AfterAdd10 موجود در قسمت‌های سوم و چهارم از این سری آموزش‌ها را بازنویسی کنیم:const add = R.curry((x, y) =&gt; x + y);
const mult5 = value =&gt; value * 5;
const mult5AfterAdd10 = R.compose(mult5, add(10));کتابخانه Ramda دارای تعداد زیادی تابع کمکی مانند  R.add و  R.multiply است که به ما کمک می‌کنند کد کمتری بنویسیم:const mult5AfterAdd10 = R.compose(R.multiply(5), R.add(10));توابع نگاشت، فیلتر و کاهش (Map, Filter and Reduce)کتابخانه Ramda همچنین دارای توابع map,filter و reduce مخصوص به خود است. هر چند که این توابع در  Array.prototype  در خود جاوا اسکریپت هم وجود دارند ولی نسخه Ramdaی این توابع کاری شده هستند. به مثال زیر توجه کنید:const isOdd = R.flip(R.modulo)(2);
const onlyOdd = R.filter(isOdd);
const isEven = R.complement(isOdd);
const onlyEven = R.filter(isEven);
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(onlyEven(numbers)); // prints [2, 4, 6, 8]
console.log(onlyOdd(numbers)); // prints [1, 3, 5, 7]تابع R.modulo دو تا پارامتر می‌گیرد: پارامتر اول مقسوم (چیزی که قرار است تقسیم شود) و پارامتر دوم مقسوم علیه (چیزی که تقسیم بر آن را انجام می‌دهیم).تابع isOdd باقیمانده تقسیم بر ۲ است، اگر باقیمانده صفر شود عدد فرد نیست و اگر باقیمانده ۱ شود عدد فرد است. ما پارامتر های تابع modulo را برعکس (flip) کرده‌ایم در نتیجه می‌توانیم از عدد ۲ به عنوان پارامتر اول این تابع استفاده کنیم.تابع  isEven مکمل[ریاضی] تابع  isOdd است. تابع onlyOdd یک تابع فیلتر است که تابع تطابق آن(تابعی که مقدار بولین برمی‌گرداند) تابع isOdd است. تابع isOdd قبل از اجرا منتظر گرفتن لیستی از اعداد به عنوان آخرین پارامترش می‌ماند.تابع onlyEven یک تابع فیلتر است که از تابع isEven به عنوان تابع تطابقش استفاده می‌کند. وقتی ما لیست numbers را به توابع  onlyEven و onlyOdd پاس می‌دهیم توابع  isOdd و isEven آخرین پارامترشان را می‌گیرند و اجرا می‌شوند و اعدادی که ما می‌خواهیم را برگشت می‌دهند.نقایص جاوا اسکریپتبا تمام کتابخانه‌ها و بهبود داخلی که جاوا اسکریپت تا حالا داشته باز هم از این حقیقت رنج می‌برد که یک زبان امری است که سعی می‌کند همه چیز را برای همه کس فراهم کند.اغلب برنامه‌نویسان فرانت‌اند سال‌هاست که به جاوا اسکریپت برای توسعه برنامه‌هایشان در مرورگرها چسبیده‌اند زیرا دیر زمانی ست که این تنها انتخاب‌شان بوده. اما امروزه خیلی‌ از توسعه دهندگان نوشتن جاوا اسکریپت را به صورت مستقیم کنار گذاشته‌اند. به جای آن این برنامه‌نویسان از زبان‌هایی استفاده می‌کنند که به جاوا اسکریپت کامپایل می‌شوند، یا به عبارت صحیح‌تر منتقل  (transpiling) می‌شوند.کافی‌اسکریپت یکی از نخستین زبان‌هایی بود که از این مکانیسم استفاده می‌کرد. و امروزه تایپ‌اسکرپت به وسیله انگولار۲ پذیرفته شده است ( زبان پیش‌فرض در توسعه انگولار۲ تایپ‌اسکریپت است). همچنین کتابخانه Babel هم می‌تواند به عنوان یک مبدل جاوا اسکریپت در نظر گرفته شود. هر روز تعدا بیشتری از برنامه‌نویسان در مورد این روش برای توسعه کد صحبت می‌کنند. اما همه‌ی این زبان‌ها با جاوا اسکریپت شروع شده‌اند و آن را قدری بهتر می‌کنند. چرا راه را کامل نرویم و از یک زبان تابع‌گرای خالص برای انتقال به جاوا اسکریپت استفاده نکنیم؟زبان Elmدر این سری از مقالات ما به زبان Elm برای فهم بهتر برنامه‌نویسی تابع‌گرا نگاهی انداختیم. اما زبان Elm چیست؟ و چگونه می‌توانیم از آن استفاده کنیم؟زبان Elm یک زبان تابع‌گرای خالص است که به جاوا اسکریپت کامپایل می‌شود، در نتیجه شما می‌توانید از آن برای توسعه برنامه‌های تحت وب با کمک گرفتن از The Elm Architecture استفاده کنید.برنامه‌هایی که با Elm نوشته شده‌اند هیچگونه خطای زمان اجرایی تولید نمی‌کنند.زبان Elm در شرکت‌هایی مثل  NoRedInk استفاده می شود. این شرکت خالق این زبان جناب Evan Czapliki را استخدام کرده‌ است.برای اطلاعات بیشتر نگاهی به این سخنرانی بیندازید.ممکن است بپرسید: آیا من مجبورم که تمام کد‌های جاوا اسکریپتم را با Elm جایگزین کنم؟نه، شما می‌توانید به صورت افزایشی بعضی از قسمت‌ها را جایگزین کنید، برای اطلاعات بیشتر نگاهی به این مقاله بیندازید.چرا زبان Elm را یادبگیریم؟۱. کد زدن با یک زبان تابع‌گرای خالص هم مزایایی دارد و هم مشکلاتی. آنچه می‌توانید با این زبان‌ انجام دهید محدود است ولی در عین حال شما را از باگ‌ها و طراحی بد خلاص می‌کند زیرا همه‌ی برنامه‌های نوشته شده با این زبان از الگوی Elm Architecture پیروی می‌کنند که یک مدل تابع‌گرای واکنشی است.۲. برنامه‌نویسی تابع‌گرا شما را تبدیل به برنامه‌نویس بهتری می‌کند. ایده‌هایی که در این مجموعه مقالات گفته شد تنها نوک کوه یخ است، شما باید آنها را در عمل ببینید تا بفهمید که چگونه آنها برنامه شما را کم‌حجم‌تر و پایدارتر می‌کنند.۳. جاوا اسکریپت در ۱۰ روز ساخته شد سپس در دو دهه اخیر به آن وصله اضافه شدن تا قدری تابع‌گرا باشد، قدری شی‌گرا و به طور کامل امری.زبان Elm با استفاده از تجربه کاری جامعه کاربری Haskell در ۳۰ سال گذشته طراحی شده است که   تجربه چند دهه کار با ریاضیات و علوم کامپیوتر را دارند.الگوی (The Elm Architecture (TEA به مدت چند سال طراحی و بهبود داده شده است که حاصل نظریه خالق زبان Elm در برنامه‌نویسی تابع‌گرای واکنشی است. برای درک سطح تفکری که پشت فرموله‌سازی این الگو وجود دارد این ویدئو را ببینید.۴. زبان Elm برای توسعه فرانت‌اند وب طراحی شده است. هدف این زبان این است که کار توسعه‌دهندگان فرانت‌اند را راحت‌تر کند. برای درک بهتر این هدف این ویدئو را ببینید.آیندهممکن نیست که بفهمیم که در آینده چه اتفاقی خواهد افتاد، اما می‌توانیم حدس‌هایی بزنیم. در زیر چند مورد از آنها را می‌بینید:۱. در آینده گرایش واضحی به سمت زبان‌هایی که به جاوا اسکریپت کامپایل می‌شوند وجود خواهد داشت.۲. ایده‌هایی از برنامه‌نویسی تابع‌گرا که به مدت ۴۰ سال وجود داشته‌اند به منظور حل پیچیدگی‌های فعلی برنامه‌نویسی دوباره کشف می‌شوند.۳. دوران شکوه سخت‌افزار ( گیگ‌ها بایت‌ از حافظه ارزان قیمت و پردازنده‌های پر سرعت) باعث می شود که تکنیک‌های تابع‌گرا ماندنی شوند.۳. پردازنده‌ها سریع تر نمی‌شوند بلکه تعداد هسته‌های آنها افزایش پیدا می‌کند.۴. حالت تغییرپذیر (Mutable state) به عنوان یکی از بزرگترین مشکلات سیستم‌های پیچیده شناخته خواهد شد. من این سری از مقالات را نوشتم چون باور دارم که برنامه‌نویسی تابع‌گرا آینده‌ی برنامه‌نویسی خواهد بود و همچنین به خاطر اینکه در دو سال گذشته با این مدل برنامه‌نویسی برای یادگیری آن سر و کله زده‌ام (من هنوز در حال یادگیری هستم).هدف من این بود که به دیگران کمک کنم که این مفاهیم را سریع‌تر و آسان‌تر از من یاد بگیرند. و اینکه کمک کنم دیگران تبدیل به برنامه‌نویس بهتری شوند تا بازارکار بهتری در آینده داشته باشند.حتی اگر پیش‌بینی من مبنی بر اینکه زبان Elm یکی از مهم‌ترین زبان‌ها در آیند خواهد بود اشتباه باشد، من با اطمینان می‌توانم بگویم که برنامه نویسی‌ تابع‌گرا و Elm جزو چیز‌هایی هستند که در آینده‌ی برنامه‌نویسی وجود دارند.امیدوارم که بعد خواندن این سری مقالات اعتماد به نفس شما افزایش پیدا کرده باشد و درک شما از این مفاهیم بالاتر رفته باشد.برایتان آرزوی موفقیت می‌کنم.ادامه ندارد!لینک قسمت‌های اول،دوم،سوم،چهارم و پنجم: +و+و+و+و+لینک منبع: + </description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Sun, 13 Aug 2017 08:20:45 +0430</pubDate>
            </item>
                    <item>
                <title>پس شما می‌خواهید یک برنامه‌نویس تابع‌گرا (فانکشنال) شوید؟(قسمت پنجم)</title>
                <link>https://virgool.io/@saeed__noori/%D9%BE%D8%B3-%D8%B4%D9%85%D8%A7-%D9%85%DB%8C%E2%80%8C%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%B4%D9%88%DB%8C%D8%AF%D8%9F-%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-v8yse4ovp7bl</link>
                <description>اولین قدم‌ها برای یادگیری برنامه‌نویسی فانکشنال مهم‌ترین قدم‌ها هستند و در برخی اوقات سخت‌ترین قدم‌ها. البته اگر از راه درست وارد شوید چندان هم سخت نخواهد بود.شفافیت ارجاعی (Referential Transparency)شفافیت ارجاعی یک اصطلاح برای شرح این موضوع است که یک تابع خالص می‌تواند با تعریفش جایگزین شود. یک مثال می‌تواند موضوع را روشن کند.در ریاضیات وقتی شما فرمول زیر را دارید:y=x+10 و گفته می‌شود که:x=3شما می‌توانید مقدار x  را در معادله بالا بگذارید و به نتیجه زیر برسید:y = 3 + 10توجه کنید که این معادله هنوز معتبر است. ما می‌توانیم همچین جایگذاریی را با توابع خالص نیز انجام دهیم.در مثال زیر تابعی در زبان Elm داریم که به رشته ورودی علامت نقل قول اضافه می‌کند:quote str =
&quot;&#039;&quot; ++ str ++ &quot;&#039;&quot;,و در مثال زیر نحوه استفاده از این تابع را می بینید:findError key =
    &quot;Unable to find &quot; ++ (quote key)در بالا تابع findError وقتی جستجو برای Keyموفقیت‌آمیز نباشد یک پیغام خطا تولید می‌کند.از آنجا که تابع quote خالص است ما می‌توانیم در مثال بالا اسم این تابع را با تعریفش جایگزین کنیم: findError key =
 &quot;Unable to find &quot; ++ (&quot;&#039;&quot; ++ str ++ &quot;&#039;&quot;)این چیزی است که من آن را بازتولید معکوس Reverse Refactoring می‌نامم (زیرا این اسم برای من بسیار بامعنی‌تر است). این عمل می‌تواند هم توسط برنامه‌نویسان و هم توسط برنامه‌ها (کامپایلرها یا برنامه‌های تست) در مورد کد برنامه انجام شود.این عمل به طور خاص در مورد توابع بازگشتی کمک کننده است.ترتیب اجرا خیلی از برنامه‌ها تک ترده ( single-threaded) هستند یعنی در آن واحد فقط یک تکه از کد اجرا می‌شود. حتی اگر شما یک برنامه مولتی-ترد داشته باشید خیلی وقت‌ها خیلی از تردها به انتظار تکمیل یک عمل I/O مثل فایل یا شبکه بلوکه شده‌اند.در مثال پایین دلیل اینکه چرا ترتیب مراحل مهم است را شرح می‌دهیم. فرض کنید می‌خواهیم نان تست درست کنیم و روی آن کره بمالیم، مراحل این کار اینجوری می‌شود: ۱. نان را در بیاورید.۲. دو تکه از نان را در توستر قرار دهید.۳. میزان برشتگی را انتخاب کنید.۴. اهرم را رو به پایین فشار دهید.۵. صبر کنید تا تست‌ها بیرون بپرند.۶. تست‌ها را بردارید.۷. کره را بیرون بیاورید.۸. یک چاقوی کره بردارید.۹. بر روی تست‌ها کره بمالید.در مثال بالا دو عمل مستقل وجود دارد: برشته کردن نان، و برداشتن کره. آنها فقط در مرحله شماره ۹ به هم وابسته می‌شوند.ما می‌توانیم مراحل ۷ و ۸ را مستقل از مراحل ۱ تا ۶ انجام دهیم زیرا آنها به هم وابسته نیستند.اما وقتی که ما این کار را انجام دهیم، کارها پیچیده می‌شوند:ترد شماره ۱-------------- ۱. نان را در بیاورید.۲. دو تکه از نان را در توستر قرار دهید.۳. میزان برشتگی را انتخاب کنید.۴. اهرم را رو به پایین فشار دهید.۵. صبر کنید تا تست‌ها بیرون بپرند.۶. تست‌ها را بردارید.ترد شماره ۲------------------۱. کره را بیرون بیاورید.۲. یک چاقوی کره بردارید.۳. صبر کنید تا ترد شماره ۱ تکمیل شود.۴. بر روی تست‌ها کره بمالید.چه اتفاقی برای ترد شماره ۲ می‌افتد اگر ترد شماره ۱ با مشکل مواجه شود؟مکانیسم هماهنگ کردن این دو ترد چگونه است؟ چه کسی مالک نان تست است، ترد شماره ۱ یا ۲ یا هر دو؟آسان‌تر است که برنامه‌مان را تک‌ترده بنویسیم و درگیر این پیچیدگی‌ها نشویم. ولی بعضی وقت‌ها لازم است که راندمان برنامه‌مان را به حداکثر ممکن برسانیم، در همچین موقعیتی لازم است طی یک حرکت قهرمانانه تلاش کنیم که یک برنامه مولتی-ترد بنویسیم.به هر حال ما دو مشکل اساسی با مولتی تردینگ داریم. نخست اینکه نوشتن، خواندن، تست و دیباگ برنامه‌های مولتی-ترد دشوار است. دوم اینکه بعضی از زبان‌های برنامه‌نویسی مثل جاوا اسکریپت مولتی-تردینگ را پشتیبانی نمی‌کنند و آنهایی هم که پشتیبانی می‌کنند پشتیبانی‌شان چندان جالب نیست. اما چه می‌شد اگر ترتیب اجرا مهم نبود و همه چیز به صورت موازی اجرا می‌شد؟ هر چند که این خواسته دیوانگی به نظر می‌رسد ولی آنچنان هم دور از دسترس نیست. اجازه دهید یک مثال با زبان Elm برای نشان دادن این موضوع بزنیم:
buildMessage message value =
    let       
         upperMessage =     
             String.toUpper message
         quotedValue =   
              &quot;&#039;&quot; ++ value ++ &quot;&#039;&quot;
   in
         upperMessage ++ &quot;: &quot; ++ quotedValueدر کد بالا تابع buildMessage مقادیر message و value را می‌گیرد و یک پیام با حروف بزرگ، یک دونقطه و یک value در میان علامت نقل قول تولید می‌کند.دقت کنید که چگونه توابع  upperMessage و quotedValue مستقل از هم هستند. ما چگونه این را می‌دانیم؟برای استقلال توابع دو چیز باید وجود داشته باشد: نخست آنها باید توابع خالص باشند، این مهم است زیرا آنها نباید تحت تاثیر اجرای همدیگر باشند. اگر آنها خالص نباشند ما هرگز نمی‌توانیم بفهمیم که آنها مستقل هستند. در نتیجه ما برای تعیین ترتیب اجرای آنها مجبوریم به ترتیب صدا زده شدن آنها در برنامه تکیه کنیم. این مکانیسمی است که در همه‌ی زبان‌های امری استفاده می شود.دومین چیزی که برای استقلال توابع مهم است این است که خروجی یک تابع به عنوان ورودی تابع دیگر استفاده نشده باشد. اگر این امر در مورد دو تابع اتفاق بیفتد تابع گیرنده مجبور است صبر کند تا تابع فرستنده اجرایش تمام شود. در مثال بالا توابع upperMessage و quotedValue  هم خالص هستند و هم به خروجی همدیگر احتیاجی ندارند درنتیجه می‌توانند به هر ترتیب دلخواه اجرا شوند.کامپایلر می‌تواند در مورد ترتیب اجرای توابع بدون هیچ کمکی از طرف برنامه‌نویس تصمیم بگیرد. این کار فقط در زبان‌های برنامه نویسی تابع‌گرا امکان پذیر است زیرا در دیگر زبان‌ها تعیین زمان انشعاب اثرات جانبی (شبکه، فایل‌ها،...) اگر غیر ممکن نباشد بسیار سخت است.در زبان‌های تابع‌گرا تعیین ترتیب اجرای توابع می‌تواند توسط کامپایلر انجام شود.  این کار با توجه به اینکه پردازنده‌ها دیگر سریع‌تر ساخته نمی‌شوند بلکه به تعداد هسته‌های آنها افزوده می‌شود بی‌نهایت مفید است. این به معنای آن است که کد می‌تواند در سطح سخت‌افزار به صورت موازی اجرا شود.متاسفانه در زبان‌های امری ما فقط در سطوح بالاتر می‌توانیم از این هسته‌‌ها بهره کامل را ببریم و برای این کار مجبوریم در کد برنامه تغییرات زیادی را بدهیم.در زبان‌های تابع‌گرا ما می توانیم که به صورت خودکار از تعداد بالای هسته‌ها در سطح قابل قبولی بهره ببریم بدون اینکه مجبور باشیم حتی یک خط از کد برنامه‌مان را تغییر دهیم.اعلان نوع (Type Annotations)در زبان‌های استاتیک، نوع متغیرها به صورت داخلی اعلام می‌شوند. یک مثال از زبان جاوا را در زیر زیر می بینید:public static String quote(String str) {         return &quot;&#039;&quot; + str + &quot;&#039;&quot;;}توجه کنید که چگونه نوع داده‌ها با تعریف تابع درهم هستند. این شلوغی وقتی که شما با جنریک‌ها سر و کار دارید حتی بدتر می‌شود:private final Map&lt;Integer, String&gt; getPerson(Map&lt;String, String&gt; people, Integer personId) {
 // ...
} من نوع داده‌هایی که باید بیرون باشند ولی هنوز با تعریف تابع قاطی شده‌اند را به صورت توپُر نشان داده‌ام (مترجم: متاسفانه باکس کد این سایت جوریه که حالت بولد کلمات رو از بین می‌بره، پس دنبال کلمات توپُر نگردید!) . شما مجبورید همچین تعریفی را با دقت بخوانید تا نام متغیرها را پیدا کنید.در زبان‌های دینامیک همچین مشکلی وجود ندارد. در جاوا اسکریپت ما می‌توانیم همچین کدی را بنویسیم:var getPerson = function(people, personId) {    
// ...
};بدون آن همه تعریف نوع مزاحم، این کد برای خواندن بسیار راحت‌تر است. تنها مشکل این است که ما از امنیت نوع داده‌هایمان دست کشیده‌ایم، ما خیلی راحت می‌توانیم به این پارامتر‌ها چیز‌های اشتباه بفرستیم، مثلا برای people یک عدد بفرستیم یا برای  personId یک شی بفرستیم.ما تا زمان اجرای برنامه به این مشکل پی‌ نخواهیم برد که این زمان ممکن است ماه‌ها بعد از تولید کد باشد. در جاوا همچین مشکلی پیش نمی‌آید زیرا در جاوا همچین کدی اصلا کامپایل نمی‌شود.اما چه می‌شود اگر ما بهترین‌ها را از هر دو دنیای استاتیک و دینامیک داشته باشیم؟ هم سادگی نحوی جاوا اسکریپت، و هم امنیت نوع داده در جاوا؟معلوم است که ما می‌توانیم، در زیر یک تابع با اعلان نوع در زبان Elm را می‌بینید:add : Int -&gt; Int -&gt; Int
add x y =
      x + yتوجه کنید که چگونه اطلاعات نوع داده در یک خط جداگانه نوشته شده است. همین جدایی یک دنیا تفاوت ایجاد می‌کند.ممکن است شما فکر کنید که در اعلان نوع خطایی وجود درد. من هم وقتی که برای اولین بار این را دیدم همچین فکری کردم. فکر می‌کردم که باید به جای اولین علامت -&gt; کاما وجود داشته باشد. اما این یک خطا نیست.وقتی شما آن را با یک پرانتر ببینید کمی برای‌تان واضح‌تر می‌شود:add : Int -&gt; (Int -&gt; Int)این اعلان می‌گوید که add یک تابع است که یک تک‌پارامتر از نوع  Int می‌گیرد و یک تابع برمی‌گرداند که آن تابع هم یک تک‌پارامتر از نوع Int می‌گیرد و یک Int برمی‌گرداند.در زیر یک مثال دیگر از اعلان نوع با پرانتز‌های ضمنی می‌بینید:doSomething : String -&gt; (Int -&gt; (String -&gt; String))
doSomething prefix value suffix =
     prefix ++ (toString value) ++ suffixاعلان بالا می‌گوید که تابع doSomething یک تک‌پارامتر از نوع String می‌گیرد و یک تابع برمی‌گرداند که این تابع یک تک‌پارامتر از نوع Int می‌گیرد و یک تابع برمی‌گرداند که این تابع یک تک‌پارامتر از نوع String می‌گیرید و یک String برمی‌گرداند.دقت کنید که چگونه تمام توابع فقط یک تک‌پارامتر می‌گیرند، این به این خاطر است که تمام توابع در زبان Elm کاری شده (Curried) هستند.از آنجا که پرانتزها همیشه به سمت راست اشاره می‌کنند نوشتن‌شان ضروری نیست. در نتیجه به سادگی می‌توانیم بنویسیم:doSomething : String -&gt; Int -&gt; String -&gt; Stringپرانتزها وقتی ضروری هستند که ما توابع را به عنوان پارامتر ارسال کنیم. در این حالت اگر پراتنزها را ننویسیم اعلان داده مبهم می‌شود. به عنوان مثال:takes2Params : Int -&gt; Int -&gt; String
takes2Params num1 num2 = 
  -- do somethingبسیار متفاوت است از:takes1Param : (Int -&gt; Int) -&gt; String
takes1Param f =
    -- do somethingتابع takes2Params تابعی است که به دو پارامتر نیاز دارد: یک Int و یک Int دیگر. درحالی که takes1Param یک پارامتر می‌گیرد: یک تابع، که این تابع دو پارامتر از نوع Int می‌گیرد.در زیر اعلان نوع را برای تابع map می‌بینید:map : (a -&gt; b) -&gt; List a -&gt; List b
map f list =   
 // ...اینجا پراتنز‌ها ضروری هستند زیرا f از نوع (a -&gt; b) است یعنی تابعی که یک تک پارامتر از نوع a می‌گیرد و چیزی از نوع b برمی‌گرداند.در اینجا نوع a می‌تواند هر چیزی باشد. هنگامی که نوع داده با حروف بزرگ شروع شود نوعش صریح است مثل String. وقتی که نوع داده با حروف کوچک شروع شود نوعش هر چیزی می‌تواند باشد. a در اینجا هم می‌تواند String باشد و هم Int.اگر جایی دید که (a-&gt;a)  این یعنی اینکه نوع داده ورودی و خروجی باید مشابه باشد، مهم نیست نوعشان چه چیزی باشد مهم این است که حتما مشابه باشند.اما در تابع map ما داریم که (a-&gt;b) این یعنی اینکه نوع داده ورودی و خروجی هم می‌تواند مشابه باشد هم می‌تواند متفاوت باشد.وقتی که نوع داده برای a تعیین شد. a باید در تمام اعلان همان نوع را داشته باشد. به عنوان مثال اگر نوع a را Int و نوع b را String تعیین کنیم اعلان بالا برابر می‌شود با:(Int -&gt; String) -&gt; List Int -&gt; List String در بالا همه‌ی aها با Int جایگزین شده‌اند و همه‌ی bها با String.عبارت  List Int به معنی یک List است که حاوی Intها است و عبارت  List String به معنای یک List است که حاوی String ها است. اگر در جاوا از جنریک‌ها استفاده کرده باشید این عبارت باید برای شما آشنا باشد. ادامه دارد...لینک قسمت‌های اول، دوم،سوم و چهارم: +و+و+و+لینک منبع: + </description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Sat, 12 Aug 2017 11:25:48 +0430</pubDate>
            </item>
                    <item>
                <title>پس شما می‌خواهید یک برنامه‌نویس تابع‌گرا (فانکشنال) شوید؟(قسمت چهارم)</title>
                <link>https://virgool.io/@saeed__noori/%D9%BE%D8%B3-%D8%B4%D9%85%D8%A7-%D9%85%DB%8C%E2%80%8C%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%B4%D9%88%DB%8C%D8%AF%D8%9F-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-rf4txmpy6qbs</link>
                <description>اولین قدم‌ها برای یادگیری برنامه‌نویسی فانکشنال مهم‌ترین قدم‌ها هستند و در برخی اوقات سخت‌ترین قدم‌ها. البته اگر از راه درست وارد شوید چندان هم سخت نخواهد بود.Curryingاگر از قسمت سوم از این مقاله به خاطر داشته باشید مشکل ما در ترکیب دو تابع add و mult5 این بود که mult5 یک پارامتر می‌گرفت در حالی که add دو پارامتر می‌گرفت.ما با مجبور کردن توابع به گرفتن فقط یک پارامتر می‌توانیم این مشکل را به آسانی حل کنیم. ما یک تابع می‌نویسیم که از دو پارامتر استفاده می‌کند ولی در هر لحظه فقط یک پارامتر می‌گیرد. توابع کاری شده به ما اجازه همچین کاری را می‌دهند.یک تابع کاری شده (Curried Function) تابعی است که در هر لحظه فقط یک پارامتر می‌گیرد. مترجم: ترجمه اصطلاح Currying کار ساده‌ای نیست. این اصطلاح اولین بار به افتخار ریاضیدان امریکایی Haskell Curry که ابداع کننده این روش است استفاده شده است. همچنین این کلمه به معنای ادویه زدن هم هست که در برنامه‌نویسی بی‌معناست. به همین دلیل من تصمیم گرفتم به جای Currying از اصطلاح کاری کردن استفاده کنم و به جای Curried از اصطلاح کاری شده استفاده کنم.کاری کردن اجازه می‌دهد که ما به تابع add اولین پارامترش را قبل از ترکیب با تابع mult5 بدهیم، سپس هنگامی که تابع  mult5AfterAdd10 صدا زده شد تابع add دومین پارامترش را می‌گیرد.در جاوا اسکریپت ما می‌توانیم با بازنویسی تابع add این کار را انجام دهیم:var add = x =&gt; y =&gt; x + yاین نسخه از add تابعی است که یکی از پارامتر‌هایش را الان می‌گیرد و دیگری را بعدا. اگر بخواهیم با جزئیات بگوییم: تابع add یک پارامتر می‌گیرد که همان x است و یک تابع برمی‌گرداند، این تابع یک پارامتر می‌گیرد (y) و مقدار x+y را برمی‌گرداند.حالا ما می‌توانیم از این نسخه از تابع add برای ساختن تابع mult5AfterAdd10 استفاده کنیم:var compose = (f, g) =&gt; x =&gt; f(g(x));
var mult5AfterAdd10 = compose(mult5, add(10));تابع compose دو تا پارامتر می‌گیرد: f و g ، و سپس یک تابع برمی‌گرداند که این تابع یک پارامتر می‌گیرد (x) و ترکیب توابع f و g  را بر روی پارامتر x را برمی گرداند.پس ما دقیقا چکار کردیم؟ ما تابع add قدیمی‌مان را به یک تابع کاری شده تبدیل کردیم، این کار باعث می‌شود تابع add بسیار انعطاف‌پذیر شود زیرا اولین پارامتر(عدد ۱۰) می‌تواند جلو‌جلو به این تابع فرستاده شود و پارامتر دوم هنگامی که تابع mult5AfterAdd10  صدا زده شد فرستاده شود.در اینجا شما ممکن است بخواهید بدانید که در زبان Elm چگونه می‌شود که تابع add را بازنویسی کرد. خب شما مجبور به این کار نیستید زیرا در زبان Elm و دیگر زبان‌های تابع گرا همه‌ی توابع به صورت اتوماتیک کاری شده هستند.در نتیجه تابع add مانند قبل نوشته می‌شود:add x y =
    x + yو این هم تابع mult5AfterAdd10 که باید اینجوری نوشته شود:mult5AfterAdd10 =
    (mult5 &lt;&lt; add 10)از لحاظ سینتکس زبان Elm بر زبان‌های امری مثل جاوا اسکریپت برتری دارد زیرا این زبان برای مفاهیم تابع‌گرا مثل ترکیب توابع یا کاری کردن بهینه شده است.کاری کردن و بازتولید (Currying and Refactoring)یک بار دیگر کاری کردن برای بازتولید یک تابع می‌درخشد! هنگامی که شما نسخه عمومی شده از یک تابع را با تعداد زیادی پارامتر می‌نویسید و سپس با استفاده از کاری کردن یک نسخه اختصاصی شده   از آن را با تعداد کمتری پارامتر می‌نویسید.به عنوان مثال توابع زیر را در نظر بگیرید، این توابع به ابتدا و انتهای رشته‌ها براکت یا براکت دوتایی اضافه می‌کنند: bracket str =
    &quot;{&quot; ++ str ++ &quot;}&quot;
doubleBracket str =
    &quot;{{&quot; ++ str ++ &quot;}}&quot;در مثال زیر نحوه استفاده از این توابع را می‌بینید:bracketedJoe =
     bracket &quot;Joe&quot;
doubleBracketedJoe =
     doubleBracket &quot;Joe&quot;ما می‌توانیم نسخه عمومی شده از توابع بالا را بسازیم: generalBracket prefix str suffix =     
    prefix ++ str ++ suffixاما حالا هر بار که بخواهیم از تابع generalBracket استفاده کنیم مجبوریم براکت‌ها را به آن پاس دهیم:bracketedJoe =
    generalBracket &quot;{&quot; &quot;Joe&quot; &quot;}&quot;
doubleBracketedJoe =
    generalBracket &quot;{{&quot; &quot;Joe&quot; &quot;}}&quot;آنچه که ما می‌خواهیم بهترین حالت از هر دو نسخه است.با توجه به این حقیقیت که همه‌ی توابع کاری شده هستند، با چینش دوباره پارامتر‌های تابع generalBracket ما می‌توانیم توابع bracket و doubleBracket را تولید کنیم:generalBracket prefix suffix str =
    prefix ++ str ++ suffix
bracket =
    generalBracket &quot;{&quot; &quot;}&quot;
doubleBracket =
    generalBracket &quot;{{&quot; &quot;}}&quot;توجه کنید که ما با قرار دادن پارامترهایی که به نظر می‌رسد تغییر نمی‌کنند ( prefix ,suffix) در ابتدای لیست پارامترها و با قرار دادن پارامتر‌هایی که تغییر خواهند کرد (str) در انتهای لیست توانسته‌ایم که نسخه اختصاصی شده (specialized) از تابع generalBracket را بسازیم.چینش پارامترها برای به کار گیری کامل currying مهم است.همچنین توجه کنید که توابع bracket و doubleBracket به صورت بدون پارامتر نوشته شده‌اند. هر دوی توابع bracket و doubleBracket توابعی هستند که منتظر دریافت پارامتر نهایی‌شان هستند.حالا ما می‌توانیم از آنها مانند قبل استفاده کنیم:bracketedJoe =
    bracket &quot;Joe&quot;
doubleBracketedJoe =
    doubleBracket &quot;Joe&quot;اما ما این بار از یک تابع عمومی شده‌ی کاری شده استفاده کرده‌ایم (generalBracket ).توابع عمومی در برنامه‌نویسی تابع‌گرابگذارید نگاهی بیندازیم به سه تابع عمومی که در زبان‌های برنامه‌نویسی تابع‌گرا استفاده می‌شوند.اما  ابتدا اجازه دهید نگاهی بیندازیم به کد جاوا اسکریپت زیر:for (var i = 0; i &lt; something.length; ++i) {
     // do stuff
}یک چیز خیلی اشتباه در این کد وجود دارد. البته این یک باگ نیست. مشکل این کد این است که زیادی پر استفاده است یعنی بارها و بارها نوشته می‌شود. اگر شما در زبان‌های امری مثل سی‌شارپ، جاوا یا پایتون کد بزنید می‌توانید خودتان را ببینید که دارید این کد پر استفاده را بیشتر از هر چیز دیگری می‌نویسید.بگذارید این مشکل را برطرف کنیم. اجازه بدهید این تکه کد را در یک تابع (یا یک جفت تابع) بگذاریم و دیگر هرگز یک حلقه for ننویسیم، یا تقریبا هرگز، حداقل تا وقتی که به یک زبان تابع‌گرا مهاجرت کنیم.اجازه بدهید با تغییر دادن یک آرایه به نام things شروع کنیم:var things = [1, 2, 3, 4];
for (var i = 0; i &lt; things.length; ++i) {
    things[i] = things[i] * 10; // MUTATION ALERT !!!!
}
console.log(things); // [10, 20, 30, 40] اَه! تغییرپذیری! (Mutability)بگذارید دوباره سعی کنیم، این بار ما آرایه things را تغییر نمی‌دهیم:var things = [1, 2, 3, 4];
var newThings = [];
for (var i = 0; i &lt; things.length; ++i) {
    newThings[i] = things[i] * 10;
console.log(newThings); // [10, 20, 30, 40]بسیار خوب، ما things را تغییر ندادیم ولی از لحاظ تکنیکی آرایه newThings را تغییر دادیم. فعلا ما از این مسئله چشم‌پوشی می‌کنیم، به هر حال ما در دنیای جاوا اسکریپت هستیم، وقتی که به یک زبان برنامه‌نویسی تابع‌گرا کوچ کنیم ما دیگر قادر نخواهیم بود متغیرها را تغییر دهیم.چیزی که اینجا مهم است این است که ببینیم که توابع عمومی چگونه کار می‌کنند و چگونه به ما در ساده‌سازی کدمان کمک می‌کنند.اجازه بدهید کد بالا را برداریم و در یک تابع بگذاریم. ما این تابع عمومی‌مان را map می‌نامیم زیرا هر مقدار از آرایه قدیمی را به یک مقدار از آرایه جدید نگاشت (map) می‌کند:var map = (f, array) =&gt; {
    var newArray = [];
    for (var i = 0; i &lt; array.length; ++i) {
        newArray[i] = f(array[i]);
    }
    return newArray;
};دقت کنید که تابع f عبور داده شده است در نتیجه تابع map می تواند هر عملی که ما می‌خواهیم با هر یک از اعضای آرایه array انجام دهد.حالا ما می‌توانیم کد قبلی‌مان را برای استفاده از تابع map بازنویسی کنیم:var things = [1, 2, 3, 4];
var newThings = map(v =&gt; v * 10, things);دیگر حلقه for در کار نیست، و  برای خواندن بسیار راحت‌تر است.خب از لحاظ تکنیکی حلقه for هنوز در تابع map وجود دارد اما حداقل ما دیگر مجبور نیستیم آن کد تکراری را بنویسیم.حالا اجازه دهید یک تابع عمومی دیگر برای فیلتر (filter) کردن اعضای یک آرایه بنویسیم:var filter = (pred, array) =&gt; {
    var newArray = [];
    for (var i = 0; i &lt; array.length; ++i) {
        if (pred(array[i]))
        newArray[newArray.length] = array[i];
    }
    return newArray;
};دقت کنید که چگونه با تابع تطابق (pred) اعضای آرایه را فیلتر می‌کنیم. اگر این تابع مقدار true را برگرداند عضو را نگه می‌داریم و اگر مقدار false را برگرداند عضو جاری را دور می‌ریزیم.در مثال زیر نحوه استفاده از تابع filter برای فیلتر کردن اعداد فرد را می‌بینید:var isOdd = x =&gt; x % 2 !== 0;
var numbers = [1, 2, 3, 4, 5];
var oddNumbers = filter(isOdd, numbers);
console.log(oddNumbers); // [1, 3, 5] استفاده از این تابع فیلتر بسیار راحت تر از فیلتر کردن دستی با استفاده از یک حلقه for است.آخرین تابع عمومی تابع کاهش (reduce) نامیده می‌شود. عموما از این تابع برای کاهش دادن اعضای یک لیست به یک تک‌مقدار استفاده می‌شود، اما این تابع می‌تواند کارهای خیلی بیشتری انجام دهد.در زبان‌های برنامه‌نویسی تابع‌گرا این تابع معمولا fold نامیده می‌شود.به مثال زیر توجه کنید:var reduce = (f, start, array) =&gt; {
     var acc = start;    
     for (var i = 0; i &lt; array.length; ++i){       
        acc = f(array[i], acc); // f() takes 2 parameters 
     }  
      return acc;
});تابع reduce سه پارامتر می‌گیرد: یک تابع (f)، یک مقدار برای نقطه شروع (start) و یک آرایه (array).دقت کنید که تابع کاهش دهنده (f)  دو تا پارامتر می‌گیرد:عضو جاری آرایه و یک متغیر انباره acc. این تابع از این پارامترها برای تولید یک انباره جدید در هر تکرار استفاده می‌کند. انباره حاصل از آخرین تکرار برگشت داده می‌شود.مثال زیر کمک می‌کند بفهمیم تابع کاهش چگونه کار می‌کند:var add = (x, y) =&gt; x + y;
var values = [1, 2, 3, 4, 5];
var sumOfValues = reduce(add, 0, values);
console.log(sumOfValues); // 15توجه کنید که تابع add دو پارامتر می‌گیرد و آنها را با هم جمع می‌زند. تابع کاهش هم یک تابع دو پارامتره را به عنوان پارامتر می‌گیرد. یعنی تابع add و تابع کاهش به خوبی با هم کار می‌کنند.ما با مقدار استارت صفر شروع می‌کنیم و آرایه را برای جمع زده شدن مقدار اعضایش پاس می‌دهیم. در داخل تابع کاهش در هر تکرار جمع مقادیر اعضای آرایه در یک متغیر انباشته می‌شود. آخرین مقدار انباشته شده به عنوان متغیر  sumOfValues برگشت داده می‌شود.هر کدام از این توابع عمومی (map,filter,reduce) به ما کمک می‌کنند عملیات دستکاری بر روی آرایه‌ها را انجام دهیم بدون اینکه مجبور باشیم کدهای تکراری حلقه‌های for را بنویسیم. در زبان‌های تابع‌گرا این توابع حتی بیشتر از این موارد مفید هستند زیرا در این زبان‌ها حلقه‌های تکرار وجود ندارد و فقط بازگشت (recursion) وجود دارد. آنجا این توابع تکرار نه تنها بسیار مفید هستند بلکه کاملا ضروری هستند.ادامه دارد...لینک قسمت‌های اول، دوم و سوم: +و+و+منبع: +</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Fri, 11 Aug 2017 07:49:27 +0430</pubDate>
            </item>
                    <item>
                <title>پس شما می‌خواهید یک برنامه‌نویس تابع‌گرا (فانکشنال) شوید؟ (قسمت سوم)</title>
                <link>https://virgool.io/@saeed__noori/%D9%BE%D8%B3-%D8%B4%D9%85%D8%A7-%D9%85%DB%8C%E2%80%8C%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%B4%D9%88%DB%8C%D8%AF%D8%9F-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-spl51eelddkf</link>
                <description>اولین قدم‌ها برای یادگیری برنامه‌نویسی فانکشنال مهم‌ترین قدم‌ها هستند و در برخی اوقات سخت‌ترین قدم‌ها. البته اگر از راه درست وارد شوید چندان هم سخت نخواهد بود.ترکیب توابعبه عنوان برنامه‌نویس ما آدم‌های تنبلی هستیم، ما دوست نداریم بارها و بارها یک کد تکراری بنویسیم. ما همیشه دنبال راهی هستیم که از کدی که قبلا نوشته‌ایم در پروژه‌های آتی استفاده کنیم.استفاده مجدد از کد در نگاه اول چیز فوق‌العاده‌ای به نظر می‌رسد ولی در عمل کار سختی است زیرا اگر کدتان برای یک پروژه زیادی اختصاصی باشد دیگر نمی‌توانید در پروژه‌های بعدی از آن استفاده کنید، و اگر یک کد را زیادی عمومی بنویسید به کار گیری آن در پروژه جاری دشوار است.پس آنچه که ما نیاز داریم یک موازنه بین این دو حالت است، یعنی راهی برای ساختن قطعات کوچک‌تر و با قابلیت استفاده مجدد از کد که بتوان از این قطعات برای ساخت پروژه‌های پیچیده‌تر استفاده کرد.در برنامه‌نویسی تابع‌گرا قطعات ساخت ما توابع هستند. ابتدا توابع را برای انجام عملیات اختصاصی می‌نویسیم، سپس این توابع را مانند قطعات لِگو سر هم می‌کنیم.این عمل ترکیب توابع نامیده می‌شود.به عنوان مثال دو تابع زیر در جاوا اسکریپت را در نظر بگیرید:var add10 = function(value) {
    return value + 10;
};
var mult5 = function(value) {
    return value * 5;
};کد بالا زیادی شلوغ است، اجازه دهید آن را با استاندارد جدید ES6 برای جاوا اسکریپت و با استفاده از fat arrow بازنویسی کنیم:var add10 = value =&gt; value + 10;var mult5 = value =&gt; value * 5;حالا بهتر شد! حالا اجازه دهید تصور کنیم که ما یک تابع می‌خواهیم که یک عدد رابگیرد عدد ۱۰ را به آن اضافه کند و نتیجه را در ۵ ضرب کند، می‌توانیم این تابع را اینجوری بنویسیم:var mult5AfterAdd10 = value =&gt; 5 * (value + 10)حتی با وجودی که این یک مثال ساده است باز ما دل‌مان نمی‌خواهد مجبور باشیم آن را از صفر بنویسم. نخست به این دلیل که ممکن است ما مرتکب اشتباه شویم مثلا گذاشتن پرانتز‌ها را فراموش کنیم، دوم به این دلیل که ما همین الان یک تابع داریم که عدد ۱۰ را به پارامتر ورودی اضافه می‌کند و یک تابع دیگر داریم که پارامتر ورودی را ضرب در ۵ می‌کند، یعنی ما این کد را قبلا نوشته‌ایم.پس به جای نوشتن این تابع بگذارید از توابع  add10 و  mult5 برای ساختن تابع جدیدمان استفاده کنیم:var mult5AfterAdd10 = value =&gt; mult5(add10(value));ما از توابع موجود برای ساخت تابع  mult5AfterAdd10 استفاده کرده‌ایم. اما راه بهتری هم وجود دارد.در ریاضی f ∘ g به معنای ترکیب توابع است وخوانده می‌شود: « f با g ترکیب شده است» یا به عبارت رایج‌تر: « f بعد از g». پس (f ∘ g)(x) برابر است با صدا زدن f بعد از g بر روی متغیر x یا به صورت ساده تر: f(g(x))  در مثال بالا ما داریم mult5 ∘ add10 یا mult5 بعد از add10، به همین دلیل نام تابع را mult5AfterAdd10 گذاشته‌ایم.و این دقیقا چیزی است که انجام داده‌ایم، ما تابع mult5 را بعد از تابع add10 بر روی متغیر value صدا زده‌ایم یا به عبارت ساده‌تر:mult5(add10(value))از آنجا که جاوا اسکریپت به صورت داخلی از ترکیب توابع پشتیبانی نمی‌کند، اجازه دهید مثال‌مان را با زبان Elm بازنویسی کنیم:add10 value =
    value + 10
mult5 value =
    value * 5
mult5AfterAdd10 value =
    (mult5 &lt;&lt; add10) valueعلامت &gt;&gt; عملگر جا دهی است که عملیات ترکیب توابع را در زبان Elm انجام می‌دهد. این علامت کمک می‌کند که از جریان داده‌ها یک درک تصویری داشته باشیم: ابتدا متغیر value به تابع add10 پاس داده می‌شود سپس نتیجه به تابع mult5 فرستاده می‌شود.به پرانتزها در تابع بالا دقت کنید، دلیل وجود آنها این است که مطمئن باشیم که ابتدا توابع ترکیب می‌شوند و سپس مقدار متغیر value اعمال می‌شود.شما از این طریق می‌توانید هر تعداد تابع که دوست داشته باشید ترکیب کنید:f x =
    (g &lt;&lt; h &lt;&lt; s &lt;&lt; r &lt;&lt; t) xدر کد بالا متغیر x به تابع t فرستاده می‌شود، سپس نتیجه به تابع r فرستاده می‌شود، سپس نتیجه به تابع s فرستاده می‌شود، و به همین منوال...اگر شما این کار را در جاوا اسکریپت انجام می‌دادید نتیجه این شکلی می‌شد:g(h(s(r(t(x)))))یک کابوس وحشتناک از پراتنزها!علامت‌گذاری بدون پارامتر (Point-Free Notation)یک روش در نوشتن توابع وجود دارد که در آن پارامتر‌ها را نمی‌نویسم، این روش علامت‌گذاری بدون پارامتر نام دارد. در نگاه اول این روش کمی عجیب و غریب به نظر می‌رسد ولی اگر شما به استفاده از آن ادامه دهید به سودمندی آن پی می‌برید.مترجم: مثل اینکه این غربی‌های کافر! به ورودی‌های یک تابع علاوه بر پارامتر، پوینت (point) هم میگن. یعنی پوینت در اینجا همون پارامتره.در تابع mult5AfterAdd10 می‌توانید ببنید که پارامتر value دو بار عنوان شده است، یک بار در لیست پارامترهای ورودی و یک بار هم در جایی که استفاده شده است:-- This is a function that expects 1 parameter
mult5AfterAdd10 value =
    (mult5 &lt;&lt; add10) valueاما این پارامتر غیر ضروری است زیرا تابع add10 (سمت راست‌ترین تابع از ترکیب توابع بالا) هم همین پارامتر را می‌پذیرد. کد زیر نمونه بدون پارامتر کد بالا است:-- This is also a function that expects 1 parameter
mult5AfterAdd10 =
    (mult5 &lt;&lt; add10)استفاده از نمونه بدون پارامتر سودمندی‌های بسیاری دارد:نخست، مجبور نیستیم پارامترهای زائد را عنوان کنیم، و از آنجا که مجبور نیستیم آنها را عنوان کنیم، مجبور نیستیم برای آنها دنبال اسم مناسب بگردیم.دوم، این مدل نوشتن برای خواندن راحت‌تر است و کدمان کمتر شلوغ می‌شود. مثال بالا یک مثال ساده است، تابعی را تصور کنید که پارامترهای بیشتری می‌گیرد.دردسر در بهشتتا اینجا دیدیم که ترکیب توابع چگونه عمل می‌کند و همچنین روش علامت‌گذاری بدون پارامتر را آموختیم. حالا اجازه دهید از این چیزهایی که آموخته‌ایم در یک مثال متفاوت استفاده کنیم تا ببینیم که این شگردها چگونه عمل می‌کنند. تصور کنید که تابع add10 را با تابع add زیر جایگزین کرده‌ایم:add x y =
    x + y
mult5 value =
    value * 5 حالا تابع mult5After10 را با این دو تابع جدید چگونه می‌نویسیم؟قبل از اینکه به خواندن ادامه دهید کمی در مورد آن فکر کنید. نه جداً! در موردش فکر کنید و سعی کنید حلش کنید.بسیارخوب، اگر شما واقعا وقت گذاشته باشید و در موردش فکر کرده باشید ممکن است به چیزی شبیه به این راه‌حل رسیده باشید:-- This is wrong !!!!
mult5AfterAdd10 =
    (mult5 &lt;&lt; add) 10 اما این راه‌حل غلط است زیرا تابع add دو تا پارامتر می‌گیرد.اگر این مسئله برایتان با زبان Elm واضح نیست سعی کنید آن را با جاوا اسکریپت بنویسید:var mult5AfterAdd10 = mult5(add(10)); // this doesn&#039;t work این کد اشتباه است ولی چرا؟برای اینکه اینجا تابع add فقط یکی از دو پارامتر ورودی‌اش را می‌گیرد در نتیجه حاصلش اشتباه است و همین حاصل اشتباه به تابع mult5 فرستاده می‌شود. و همین باعث می‌شود نتیجه نهایی اشتباه باشد.در واقع در زبان Elm کامپایلر اجازه نمی‌دهد همچین کد اشتباهی بنویسید که این یکی از ویژگی های عالی زبان Elm است.بگذارید دوباره سعی کنیم:var mult5AfterAdd10 = y =&gt; mult5(add(10, y)); // not point-freeکد بالا بدون پارامتر نیست ولی به هر حال می‌توان با آن کنار آمد، اما توجه کنید که ما فقط توابع را ترکیب نکرده‌ایم بلکه یک تابع جدید نیز نوشته‌ایم. و یک مسئله دیگر اینکه اگر این کار پیچیده‌تر شود مثلا بخواهیم تابع  mult5AfterAdd10 را با تابع دیگری ترکیب کنیم کارمان واقعا سخت می‌شود.پس می‌شود نتیجه گرفت که ترکیب توابع سودمندی محدودی دارد زیرا ما نمی‌توانیم این دو تا تابع را ترکیب کنیم. این باعث تاسف است زیرا ترکیب توابع واقعا یک ابزار قدرتمند است.چگونه می‌توانیم این مشکل را حل کنیم؟ چه چیزی نیاز داریم که این مشکل را از سر راه برداریم؟خب خیلی عالی می‌شد اگر ما راهی داشتیم که می‌توانستیم فقط یکی از پارامتر‌های وروردی تابع add را از قبل برایش ارسال کنیم و پارامتر دوم را بعدا یعنی زمانی که تابع  mult5AfterAdd10 صدا زده شد برایش ارسال کنیم.خب یک راه حل پیدا کردیم، این راه‌حل اصطلاحا Currying نامیده می‌شود.ادامه دارد...لینک قسمت‌های اول و دوم: +و+منبع:+</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Wed, 09 Aug 2017 14:00:34 +0430</pubDate>
            </item>
                    <item>
                <title>پس شما می‌خواهید یک برنامه‌نویس تابع‌گرا (فانکشنال) شوید؟(قسمت دوم)</title>
                <link>https://virgool.io/@saeed__noori/%D9%BE%D8%B3-%D8%B4%D9%85%D8%A7-%D9%85%DB%8C%E2%80%8C%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%DB%8C%DA%A9-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%B4%D9%88%DB%8C%D8%AF%D8%9F-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-zip222prt4xy</link>
                <description>اولین قدم‌ها برای یادگیری برنامه‌نویسی فانکشنال مهم‌ترین قدم‌ها هستند و در برخی اوقات سخت‌ترین قدم‌ها. البته اگر از راه درست وارد شوید چندان هم سخت نخواهد بود.یادآوری دوستانهلطفا این مقاله را آهسته بخوانید، قبل از اینکه به سراغ بخش‌های بعدی بروید مطمئن شوید که شما مطلب را فهمیده‌اید. هر بخش پیش‌نیاز بخش بعدی است.اگر شما عجله کنید ممکن است مطلبی را از دست بدهید که برای فهمیدن بخش‌های بعد ضروری است.بازتولید (refactoring)اجازه بدهید یک دقیقه در مورد بازتولید فکر کنیم، در زیر مثالی با جاوا اسکریپت می‌بینید:function validateSsn(ssn) {
if (/^\d{3}-\d{2}-\d{4}$/.exec(ssn))
console.log(&#039;Valid SSN&#039;);
else
console.log(&#039;Invalid SSN&#039;);
}

function validatePhone(phone) {
if (/^\(\d{3}\)\d{3}-\d{4}$/.exec(phone))
console.log(&#039;Valid Phone Number&#039;);
else
console.log(&#039;Invalid Phone Number&#039;);
}ما قبلا بارها و بارها همچین کدی را نوشته‌ایم، با نگاه کردن به کد می‌توانیم تشخیص دهیم که هر دو تابع بسیار مشابه هستند و تفاوت‌های بسیار کمی دارند که با بزرگنمایی مشخص شده است.به جای اینکه تابع validateSsn را کپی پیست و ویرایش کنیم تا تابع validatePhone را بنویسیم، ما باید فقط یک تابع بنویسیم و چیزهایی که را که ویرایش کرده‌ایم به عنوان پارامترهای ورودی‌ش در نظر بگیریم. در این مثال ما می‌توانیم متغیر ورودی (value)، عبارات با قاعده (regular expression) و پیامی (message) که قرار است نشان داده شود (یا حداقل بخش پایانی پیام) را به عنوان پارامتر ورودی در نظر بگیریم. کد بازتولید شده به صورت زیر است:function validateValue(value, regex, type) {
if (regex.exec(value))
console.log(&#039;Invalid &#039; + type);
else
console.log(&#039;Valid &#039; + type);
}پارامترهای ssn و phone در کد قبلی حالابه صورت value درآمده است، عبارات با قاعده به صورت regex نشان داده شده و در نهایت قسمت آخر پیام یعنی &#x27;SSN&#x27; و &#x27;Phone Number&#x27; به صورت type نوشته شده است.داشتن یک تابع خیلی بهتر از داشتن دو تابع یا حتی بدتر، سه، چهار یا ده تابع است. این کار باعث می‌شود کد شما تمیز باشد و قابلیت نگهداریش بالا برود. به عنوان مثال اگر در کد شما باگی وجود داشته باشد خیلی راحت‌تر است که شما فقط یک نقطه از کد را برای رفع آن بگردید تا اینکه مجبور باشید تمام کد را بین توابعی که کپی پیست و ویرایش شده‌اند بگردید.اما اگر کد شما شبیه مثال زیر باشد چه؟:function validateAddress(address) {
if (parseAddress(address)
console.log(&#039;Valid Address&#039;);
else
console.log(&#039;Invalid Address&#039;);
}

function validateName(name) {
if (parseFullName(name))
console.log(&#039;Valid Name&#039;);
else
console.log(&#039;Invalid Name&#039;);
}اینجا parseAddress وparseFullName توابعی هستند که یک رشته را می‌گیرند و اگر مقدارش درست باشد true را برمی‌گردانند.چگونه می‌توانیم این توابع را بازتولید کنیم؟خب ما می‌توانیم از value به جای address و name استفاده کنیم و از type به جای رشته‌های &#x27;Address&#x27; و &#x27;Name&#x27; استفاده کنیم، ولی اینجا یک تابع داریم که عبارات با قاعده را تجزیه وتحلیل می‌کند. اگر می‌توانستیم توابع را به عنوان پارامتر ارسال کنیم...توابع مرتبه بالاتر (Higher-Order Functions)خیلی از زبان‌های برنامه‌نویسی از فرستادن توابع به عنوان پارامتر پشتیبانی نمی‌کنند. بعضی‌ها هم پشتیبانی می‌کنند ولی انجام این کار را تسهیل نمی‌کنند.در برنامه‌نویسی تابع‌گرا هر تابع یک شهروند درجه اول (first-class citizen) از زبان است، به عبارت دیگر هر تابع یک مقدار است.از آنجا که توابع هم مقدار هستند ما می‌توانیم آنها را به عنوان پارامتر به توابع دیگر بفرستیم.اگر چه جاوا اسکریپت یک زبان تابع گرای خالص نیست اما شما می‌توانید بعضی از عملیات تابع‌گرا با آن انجام دهید. از اینرو شما در قطعه کد زیر می‌توانید ببینید که دو تابع مثال قبل تبدیل به یک تابع شده‌اند. در اینجا توابع تحلیل‌گر عبارات با قاعده در مثال قبل با نام parseFunc به عنوان پارامتر ارسال شده است:function validateValueWithFunc(value, parseFunc, type) {
if (parseFunc(value))
console.log(&#039;Invalid &#039; + type);
else
console.log(&#039;Valid &#039; + type);
}  این تابع جدید یعنی validateValueWithFunc تابع مرتبه بالاتر نامید می‌شود.توابع مرتبه بالاتر توابعی هستند که یک تابع دیگر را به عنوان پارامتر ورودی می‌گیرند، یا تابعی را به عنوان مقدار برگشتی برمی‌گردانند، یا هر دوی این کارها را با هم انجام می‌دهند.حالا ما می‌توانیم تابع مرتبه بالاترمان را برای چهار تابع قبلی صدا بزنیم. در مثال زیر به این دلیل که تابع Regex.exec اگر تطابقی با عبارت با قاعده پیدا کند مقدار true را بر‌می‌گرداند همه چیز درست کار می‌کند:validateValueWithFunc(&#039;123-45-6789&#039;, /^\d{3}-\d{2}-\d{4}$/.exec, &#039;SSN&#039;);
validateValueWithFunc(&#039;(123)456-7890&#039;, /^\(\d{3}\)\d{3}-\d{4}$/.exec, &#039;Phone&#039;);
validateValueWithFunc(&#039;123 Main St.&#039;, parseAddress, &#039;Address&#039;);
validateValueWithFunc(&#039;Joe Mama&#039;, parseName, &#039;Name&#039;);این خیلی بهتر از این است که چهار تابع تقریبا مشابه داشته باشیم.اگر به عبارات با قاعده نگاه کنید می‌بینید که آنها زیادی شلوغ و جاگیر هستند، اجازه بدهید با فاکتورگیری از آنها کدمان را تمیزتر کنیم:var parseSsn = /^\d{3}-\d{2}-\d{4}$/.exec;
var parsePhone = /^\(\d{3}\)\d{3}-\d{4}$/.exec;
validateValueWithFunc(&#039;123-45-6789&#039;, parseSsn, &#039;SSN&#039;);
validateValueWithFunc(&#039;(123)456-7890&#039;, parsePhone, &#039;Phone&#039;);
validateValueWithFunc(&#039;123 Main St.&#039;, parseAddress, &#039;Address&#039;);
validateValueWithFunc(&#039;Joe Mama&#039;, parseName, &#039;Name&#039;);حالا بهتر شد! حالا اگر ما بخواهیم یک شماره تلفن را تجزیه تحلیل کنیم لازم نیست که عبارت با قاعده را کپی پیست کنیم.اما تصور کنید که ما عبارات با قاعده بیشتری برای تجزیه تحلیل داشته باشیم، هر بار که ما تحلیلگر یک عبارت با قاعده را می‌نویسم لازم است که به آخر عبارت با قاعده تابع exec را اضافه کنیم، خیلی راحت ممکن است فراموش کنیم که این کار را انجام دهیم. ما می‌توانیم با نوشتن یک تابع مرتبه بالاتر که تابع exec را اجرا می کند از این مشکل جلوگیری کنیم:function makeRegexParser(regex) {
return regex.exec;
}
var parseSsn = makeRegexParser(/^\d{3}-\d{2}-\d{4}$/);
var parsePhone = makeRegexParser(/^\(\d{3}\)\d{3}-\d{4}$/);
validateValueWithFunc(&#039;123-45-6789&#039;, parseSsn, &#039;SSN&#039;);
validateValueWithFunc(&#039;(123)456-7890&#039;, parsePhone, &#039;Phone&#039;);
validateValueWithFunc(&#039;123 Main St.&#039;, parseAddress, &#039;Address&#039;);
validateValueWithFunc(&#039;Joe Mama&#039;, parseName, &#039;Name&#039;);در کد بالا تابع makeRegexParser یک عبارت با قاعده را می‌گیرد و تابع exec را برمی‌گرداند. تابع exec یک رشته می‌گیرد که تابع validateValueWithFunc برایش می‌فرستد. متغیرهای  parsePhone و parseSsn هم دقیقا مانند قبل هستند، یعنی همان تابع exec عبارات با قاعده.در زیر یک مثال دیگر از توابع مرتبه بالا را می‌بینید که یک تابع دیگر را برمی‌گرداند:function makeAdder(constantValue) {
return function adder(value) {
return constantValue + value;
};
}ما اینجا یک تابع به نام makeAdder داریم که مقدار constantValue را می‌گیرد و تابع adder را برمی‌گرداند. تابع adder ثابت constantValue را می‌گیرد و با هر مقداری که بهش پاس داده شود جمع می‌زند و نتیجه را برمی‌گرداند.در زیر مثالی از به کار گیری این تابع نشان داده شده است: var add10 = makeAdder(10);
console.log(add10(20)); // prints 30
console.log(add10(30)); // prints 40
console.log(add10(40)); // prints 50ما با فرستادن یک مقدار ثابت به makeAdder یک تابع به نام  add10 ساخته‌ایم. makeAdder یک تابع برمی‌گرداند که هر چه بهش پاس داده شود با مقدار ثابت ۱۰ جمع می زند.توجه کنید که تابع adder حتی بعد از اینکه تابع makeAdder بازگشت می‌کند به مقدار constantValue دسترسی دارد، این به این دلیل است که وقتی تابع adder ساخته می‌شود ثابت constantValue در محدوده دسترسی‌اش (scope) است.این رفتار بسیار مهم است زیر بدون آن توابعی که یک تابع دیگر را برمی‌گردانند چندان مفید نخواهند بود. در نتیجه مهم است ما بفهمیم که این توابع چگونه عمل می‌کنند و نام این رفتار چیست.این رفتار بستار یا کلوژر (Closure) نامیده می‌شود.کلوژرهادر زیر مثالی می‌بینید که در آن توابع از کلوژرها استفاده می‌کنند:function grandParent(g1, g2) {
var g3 = 3;
return function parent(p1, p2) {
var p3 = 33;
return function child(c1, c2) {
var c3 = 333;
return g1 + g2 + g3 + p1 + p2 + p3 + c1 + c2 + c3;
};
};
} در این مثال تابع child هم به متغیر‌های خودش دسترسی دارد، هم به متغیر‌های parent و هم به متغیر‌های grandParent.تابع parent فقط به متغیرهای خودش و grandParent دسترسی دارد.و تابع grandParent فقط به متغیرهای خودش دسترسی دارد.( برای درک بهتر هرم موجود در تصویر بالا را مشاهده کنید.)در مثال زیر می‌توانید چگونگی استفاده از کلوژر را ببینید:var parentFunc = grandParent(1, 2); // returns parent()
var childFunc = parentFunc(11, 22); // returns child()
console.log(childFunc(111, 222)); // prints 738
// 1 + 2 + 3 + 11 + 22 + 33 + 111 + 222 + 333 == 738در مثال بالا  parentFunc محدوده parent را برقرار نگه می‌دارد زیرا grandParent تابع parent را برمی‌گرداند.به طور مشابه، childFunc محدوده  child را برقرار نگه می‌دارد زیرا که parentFunc که همان  parent است تابع child را برمی‌گرداند.مترجم: خودم هم نفهمیدم چی شد؟ :)وقتی یک تابع ساخته می‌شود همه‌ی متغیرهای در زمان ساخته شدنش که در محدوده‌اش هستند مادامی که زنده است برایش قابل دسترسی هستند. یک تابع تا وقتی که ارجاعی به آن وجود داشته باشد زنده است. به عنوان مثال تابع  child تا هنگامی که متغیر childFunc به آن ارجاع می‌دهد زنده است.یک کلوژر یک محدوده[دسترسی به متغیر] برای یک تابع است که به وسیله یک ارجاع به آن تابع برقرار نگه داشته می‌شود. توجه کنید که در جاوا اسکریپت کلوژرها مشکل‌ساز هستند زیرا متغیرها تغیرپذیر هستند، یعنی آنها می‌توانند مقادیر را از زمانی که بسته شده‌اند تا زمانی که تابع برگشت داده شده صدا زده می‌شود تغییر دهند.خوشبختانه متغیرها در برنامه‌نویسی تابع‌گرا تغییرناپذیر هستند و این ویژگی این منبع باگ و سردرگمی (مشکل بالا) را برطرف می‌کند.ادامه دارد...لینک قسمت اول: +منبع: +</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Wed, 09 Aug 2017 13:53:04 +0430</pubDate>
            </item>
                    <item>
                <title>پس شما می‌خواهید برنامه‌نویس تابع‌گرا (فانکشنال) شوید؟ (قسمت اول)</title>
                <link>https://virgool.io/@saeed__noori/%D9%BE%D8%B3-%D8%B4%D9%85%D8%A7-%D9%85%DB%8C%E2%80%8C%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%B4%D9%88%DB%8C%D8%AF%D8%9F-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-hapfpqn0lbeh</link>
                <description>اولین قدم‌ها برای یادگیری برنامه‌نویسی فانکشنال مهم‌ترین قدم‌ها هستند و در برخی اوقات سخت‌ترین قدم‌ها. البته اگر از راه درست وارد شوید چندان هم سخت نخواهد بود.یادگیری رانندگیوقتی برای اولین بار شروع به یادگیری رانندگی می‌کنیم در نگاه اول وقتی به رانندگی دیگران نگاه می‌کنیم کار ساده‌ای به نظر می‌رسد، اما این کار وقتی خودمان اولین قدم‌ها را برمی‌داریم سخت‌تر می‌شود.ما با ماشین والدین‌مان شروع به تمرین می‌کنیم و تا وقتی که به خیابان‌های اطراف خانه‌مان مسلط نشدیم از ریسک رفتن به بزرگراه‌ها دوری می‌کنیم. اما بعد از تمرین زیاد و پشت سر گذاشتن بعضی از لحظات دلهره‌آور ما بالاخره رانندگی را یاد می‌گیریم و گواهی‌نامه‌مان را می‌گیریم.با در دست داشتن گواهی‌نامه، ما در هر فرصت ممکن ماشین را برمی‌داریم و شروع به رانندگی می‌کنیم، با هر دور، رانندگی ما بهتر و بهتر می‌شود و اعتماد به نفسمان بالا می‌رود. سپس یک روزی می‌رسد که عمر ماشین‌مان تمام می‌شود و ما مجبور می‌شویم یک ماشین دیگر بخریم، یا ماشین فردی دیگر را برانیم.وقتی ما پشت رُل یک ماشین جدید می‌نشینیم چه حسی دارد؟ آیا این حس شبیه حسی است که ما برای اولین بار پشت رُل نشستیم؟ البته که نه، در بار اول‌مان همه چیز ناآشنا بود در حالی که این بار   خیلی چیزها آشنا هستند.وقتی می‌خواهیم ماشین جدیدی را برانیم سوال‌های ساده‌ای را از خودمان می‌پرسیم مثلا: کلید استارت کجاست؟ کلید چراغ‌ها کجا هستند؟ چگونه راهنما بزنیم و چگونه آینه را تنظیم کنیم؟ بعد از این کار به آرامی شروع به حرکت می‌کنیم. اما چرا این بار در مقایسه با بار اول کارمان اینقدر راحت است؟ دلیلش این است که ماشین جدید به میزان بسیار زیادی شبیه ماشین قدیمی است، ماشین جدید هم تمام چیز‌های پایه‌ای که یک ماشین نیاز دارد را دارد و همه‌ی آن چیزها مکان‌ قرارگیری‌شان تقریبا در همان حوالی مکان‌شان در ماشین قبلی است.زبان‌های برنامه‌نویسی را هم تقریبا همینطوری یاد می‌گیریم. یادگیری اولین زبان از همه سخت‌تر است، ولی هنگامی که بر اولی مسلط شدید یادگیری زبان‌های بعدی آسان‌تر می‌شود.هنگامی که شما شروع به یادگیری زبان دوم می‌کنید ممکن است چنین سوالاتی از خود بپرسید: چگونه یک ماژول بسازم؟ چگونه در یک آرایه جستجو کنم؟ پارامتر‌های لازم برای تابع substring چه چیز‌هایی هستند؟ شما مطمئن هستید که می‌توانید زبان جدید را یاد بگیرید چون خیلی از مفاهیمش شبیه زبان قدیمی هستند.راندن اولین سفینه فضایی حالا تصور کنید که شما پشت رُل یک سفینه فضایی نشسته‌اید، اینجا دانستن رانندگی ماشین کمک چندان به شما نخواهد کرد. شما باید دوباره از صفر شروع به یادگیری کنید.یادگیری برنامه‌نویسی تابع‌گرا بعد از یادگیری برنامه‌نویسی رویه‌گرا یا شی‌گرا هم همچین حالتی دارد. شما باید انتظار چیزهای بسیار متفاوتی داشته باشید و خیلی از چیزهایی که در مورد برنامه‌نویسی می‌دانید به کار شما نمی‌آیند.برنامه‌نویسی یعنی فکر کردن و برنامه‌نویسی تابع‌گرا شما را مجبور می‌کند بسیار متفاوت‌تر از قبل فکر کنید، آنقدر متفاوت که احتمالا هرگز به مدل فکر کردن قدیمی باز نمی‌گردید.هر آنچه می‌دانید را فراموش کنیدبرنامه‌نویسی تابع‌گرا مثل شروع کردن از صفر است (البته نه کاملا، ولی به مقدار زیادی). بعضی از مفاهیم مانند قبل هستند ولی بهتر است شما آمادگی داشته باشید که همه چیز را از پایه شروع کنید.با یک دورنمای درست شما انتظارات درستی خواهید داشت و وقتی که انتظارت شما درست باشد وقتی که کار سخت شد دست از تلاش نخواهید کشید. چیزهایی وجود دارند که شما همیشه به عنوان یک برنامه‌نویس معمولی از آنها استفاده کرده‌اید اما این چیزها در برنامه‌نویسی تابع‌گرا دیگر وجود ندارند. دقیقا مثل رانندگی، در رانندگی شما برای حرکت به عقب دنده عقب را دارید ولی در یک سفینه فضایی دنده عقب وجود ندارد. در واقع در یک سفینه فضایی شما به دنده عقب احتیاج ندارید چون سفینه فضایی توانایی حرکت در هر سه راستای فضایی را دارد، هنگامی که شما این حقیقت را بفهمید دیگر هرگز به دنده عقب احساس نیاز نخواهید کرد. در واقع یک روزی به این فکر خواهید کرد که راندن یک ماشین چقدر محدودیت داشت.یادگیری برنامه‌نویسی تابع‌گرا بسیار طول خواهد کشید پس صبور باشید. پس اجازه دهید از دنیای سرد برنامه‌نویسی امری ( Imperative Programming) خارج شویم و یک غوطه نرم در آب‌های گرم برنامه نویسی تابع‌گرا بزنیم.آنچه که در ادامه می‌آید مفاهیمی از برنامه‌نویسی تابع‌گرا هستد که به درک کلی شما از برنامه‌نویسی تابع‌گرا قبل از اینکه یادگیری اولین زبان برنامه‌نویسی تابع‌گرا را شروع کنید کمک می‌کنند.لطفا عجله نکنید، برای یادگیری مطالب و همچنین درک مثال‌ها وقت بگذارید. حتی بهتر است بعد از خواندن هر بخش دست از خواندن بکشید تا مطالب را عمیقا جذب کنید و بعدا دوباره شروع به خواندن کنید. مهم‌ترین چیز این است که شما مطالب را بفهمید. خلوصوقتی برنامه‌نویسان تابع‌گرا در مورد خلوص حرف می‌زنند در واقع منظورشان توابع خالص (Pure Functions) است. توابع خالص توابع بسیار ساده‌ای هستند، آنها فقط بر روی پارامتر‌های ورودی‌شان عمل می‌کنند. در مثال زیر می توانید یک نمونه از یک تابع خالص را در جاوااسکریپت ببیند:var z = 10;function add(x, y) {    return x + y;}دقت کنید که تابع add هیچ کاری با متغیر z ندارد، نه از z می‌خواند و نه در z می‌نویسد. این تابع فقط از پارامترهای ورودی‌ش یعنی x و y می خواند و مجموع آنها را برمی‌گرداند. این تابع یک تابع خالص است، اگر این تابع با z عملیات انجام می‌داد دیگر یک تابع خالص نبود.در زیر یک مثال دیگر داریم:function justTen() {    return 10;}تابع  justTen یک تابع خالص است و فقط یک ثابت بر‌می‌گرداند چون ما به آن هیچ پارامتر ورودی نداده‌ایم و چون خالص است به هیچ متغیر دیگری هم دسترسی ندارد. از آنجا که توابع خالصی که هیچ پارامتر ورودی ندارند کار خاصی انجام نمی‌دهند درنتیجه چندان هم مفید نیستند. در نتیجه بهتر بود که تابع  justTen بصورت یک متغیر ثابت تعریف شود.اکثر توابع خالص مفید باید حداقل یک پارامتر ورودی داشته باشند.حالا این تابع را در نظر بگیرید:function addNoReturn(x, y) {    var z = x + y}توجه کنید که این تابع هیچ چیزی را برنمی‌گرداند. این توابع مقدار متغیرهای x , y را جمع می‌زند و حاصل را در z می‌گذارد ولی آن را برنمی‌گرداند. این یک تابع خالص است چون فقط بر پارامترهای ورودی‌ش تکیه دارد، اما از آنجا که چیزی را برنمی‌گرداند یک تابع بلااستفاده است.همه‌ی توابع خالص مفید باید چیزی را برگردانند.بگذارید دوباره به سراغ تابع add اول‌مان برویم:function add(x, y) {    return x + y;}console.log(add(1, 2)); // prints 3console.log(add(1, 2)); // still prints 3console.log(add(1, 2)); // WILL ALWAYS print 3دقت کنید که همیشه حاصل (1,2)add عدد ۳ است، البته این دور از انتظار هم نیست زیرا تابع add یک تابع خالص است. اگر تابع add به متغیری خارج از محدوده‌اش دسترسی می‌داشت شما هرگز نمی‌توانستید رفتارش را پیش‌بینی کنید.توابع خالص برای هر ورودی مشخص همیشه یک خروجی مشخص تولید می‌کنند.از آنجا که توابع خالص نمی‌توانند هیچ متغیر خارجیی را تغییر دهند همه‌ی توابع زیر غیر خالص هستند:writeFile(fileName);updateDatabaseTable(sqlCmd);sendAjaxRequest(ajaxRequest);openSocket(ipAddress);همه‌ی این توابع چیزی دارند که اثرات جانبی (Side Effects)  نامیده می‌شود. هنگامی که شما این توابع را صدا می‌زنید آنها یک فایل یا یک جدول از پایگاه داده را تغییر می‌دهند، یا به یک سرور داده می‌فرستند و یا از سیستم عامل یک سوکت را درخواست می‌کنند. آنها کارهای بیشتری از فقط خواندن متغیر‌های ورودی و برگرداندن خروجی را انجام می‌دهند، درنتیجه شما هیچوقت نمی‌توانید پیش بینی کنید که این توابع چه چیزی را برمی‌گردانند.توابع خالص دارای اثرات جانبی نیستند.در زبان‌های برنامه‌نویسی امری (imperative) مانند جاوا اسکریپت، سی‌شارپ و جاوا اثرات جانبی همه جا هستند، این پدیده دیباگ برنامه شما را سخت می‌کند چون یک متغیر ممکن است در هر جایی از برنامه شما تغییر کند. درنتیجه وقتی که شما یک باگ در برنامه به این دلیل دارید که مقدار یک متغیر در زمان نامناسب تغییر کرده است، کجا را برای رفع باگ می‌گردید؟ همه‌ جا؟ خب این خوب نیست. در اینجا شما ممکن است بپرسید: چگونه من همه‌ی قسمت‌ها را فقط با توابع خالص بنویسم؟در برنامه‌نویسی تابع‌گرا  شما فقط تابع خالص نمی‌نویسید.زبان‌های برنامه‌نویسی تابع‌گرا نمی‌توانند اثرات جانبی را حذف کنند، این زبان‌ها فقط می‌توانند آنها را محدود کنند. از آنجا که برنامه‌ها به عنوان یک واسطه بین دنیای واقعی و کامپیوتر عمل می‌کنند، بعضی از قسمت‌های هر برنامه باید غیرخالص باشد. هدف این است که مقدار کد غیر خالص را کمینه کنیم و این کد غیر خالص از بقیه قسمت‌های برنامه مجزا شود.تغییرناپذیریآیا وقتی که برای اولین بار همچین قطعه کدی را دید را به خاطر می‌آورید:  var x = 1; x = x+1; و کسی که به شما برنامه‌نویسی یاد می‌داد گفت که هر آنچه که سر کلاس ریاضی یاد گرفته‌اید فراموش کنید؟ در ریاضی x هرگز نمی‌تواند برابر با x+1 شود. اما در برنامه‌نویسی امری این گزاره با معنی است: مقدار x را بگیرید به آن عدد ۱ را اضافه کنید و حاصل را در x بگذارید.در برنامه‌نویسی تابع‌گرا عبارت x=x+1 غیرمجاز است. درنتیجه شما باید هر آنچه که سر کلاس ریاضی یاد گرفتید و در برنامه‌نویسی امری فراموش کردید دوباره به یاد بیاورید!در برنامه‌نویسی تابع‌گرا چیزی بنام متغیر وجود ندارد.مقادیر ذخیره شده به خاطر سازگاری با گذشته همچنان متغیر (variable) نامیده می‌شوند اما آنها در واقع ثابت (constant) هستند، یعنی هنگامی که x مقداری را گرفت برای تمام طول حیاتش مقدارش همان است.نگران نباشید، x معمولا یک متغیر محلی است درنتیجه طول حیاتش کوتاه است، اما تا زمانی که زنده است قابل تغییر نیست.در زیر یک مثال در مورد ثابت‌ها با زبان Elm می‌بینید. Elm یک زبان تابع‌گرای خالص برای توسعه وب است.‍‍‍addOneToSum y z =    let        x = 1    in        x + y + zاگر شما با سینتکس ML-Style آشنا نیستید اجازه بدهید آن برای شما توضیح دهم: addOneToSum  یک تابع است که دو پارامتر می‌گیرد: x و y. داخل بلوک let متغیر x به عدد ۱ مقید می‌شود، یعنی برای تمام طول حیاتش مقدارش برابر با ۱ می‌شود. مدت زمان حیات این متغیر هنگامی که از تابع خارج می‌شویم به پایان می‌رسد، یا به عبارت دقیق‌تر هنگامی که بلوک let ارزیابی می‌شود.در داخل بلوک in حاصل محاسبه می‌تواند شامل مقادیری باشد که در بلوک let تعریف شده‌اند (همان x). نتیجه‌ی محاسبه یعنی x+y+z برگردانده می‌شود، یا به صورت دقیق‌تر  1 + y + z برگردانده می‌شود چون x=1.یک بار دیگر من می‌توانم بشنوم که شما می‌گویید: آخر چگونه می‌توانم همه‌ی کارها را بدون متغیرها انجام دهم؟اجازه دهید در مورد اینکه چه موقع می‌خواهیم مقدار متغیرها را تغییر دهیم کمی فکر کنیم. عموما در دو حالت ما مقدار متغیرها را تغییر می‌دهیم:۱- تغییر دادن یک مقدار از یک متغیر چندمقداره مثل تغییر دادن یک مقدار از یک رکورد یا یک شی، ۲- تغییر دادن یک متغیر یک‌مقداره مثل تغییر دادن مقدار شمارنده حلقه (همان ++i).برنامه‌نویسی تابع‌گرا برای تغییر یک مقدار از یک رکورد یک کپی از رکورد را که در این کپی آن مقدار تغییر کرده را می سازد. این مدل برنامه‌یسی این کار را با استفاده از ساختمان داده‌هایی که در اختیار دارد به صورتی انجام می‌دهد که نیاز نباشد همه‌ی قسمت‌های رکورد کپی شوند.برنامه‌نویسی تابع‌گرا برای تغییر مقدار متغیرهای تک‌مقداره نیز از همین روش استفاده می‌کند و متغیر را کپی می‌کند. و البته بدون استفاده از حلقه‌ها.البته این بدان معنی نیست که در برنامه‌نویسی تابع‌گرا ما نمی‌توانیم حلقه بزنیم بلکه به این معنی است که در این مدل برنامه‌نویسی ساختارهایی مانند for,while,do,repeat نداریم.برنامه‌نویسی تابع‌گرا از بازگشت ( recursion) برای حلقه زدن استفاده می‌کند.در این مثال شما دو روش می‌بینید که می‌توانید در جاوااسکریپت برای حلقه زدن استفاده کنید:// simple loop constructvar acc = 0;for (var i = 1; i &lt;= 10; ++i)    acc += i;console.log(acc); // prints 55// without loop construct or variables (recursion)function sumRange(start, end, acc) {    if (start &gt; end)        return acc;    return sumRange(start + 1, end, acc + start)}console.log(sumRange(1, 10, 0)); // prints 55توجه کنید که چگونه بازگشت (روش تابع‌گرا)  با استفاده از صدا زدن خودش با یک استارت جدید (start + 1) و یک انباره جدید (acc + start) به همان نتیجه‌ای رسیده است که حلقه for رسیده است. بازگشت مقادیر قبلی را تغییر نداده است، به جای آن از مقادیر جدیدی استفاده می‌کند که از روی مقادیر قبلی محاسبه شده‌اند.متاسفانه در جاوااسکریپت دیدن این چیزها سخت است به دو دلیل: ۱- سینتکس جاوااسکریپت شلوغ و درهم برهم است، ۲- شما احتمالا قبلا هیچوقت به صورت بازگشتی فکر نکرده‌اید.در زبان Elm خواندن و در نتیجه فهم بازگشت آسان‌تر است:sumRange start end acc =    if start &gt; end then        acc    else        sumRange (start + 1) end (acc + start)در زیر وقتی که مثال بالا اجرا می‌شود را می‌توانید ببینید:sumRange 1 10 0 =      -- sumRange (1 + 1)  10 (0 + 1)sumRange 2 10 1 =      -- sumRange (2 + 1)  10 (1 + 2)sumRange 3 10 3 =      -- sumRange (3 + 1)  10 (3 + 3)sumRange 4 10 6 =      -- sumRange (4 + 1)  10 (6 + 4)sumRange 5 10 10 =     -- sumRange (5 + 1)  10 (10 + 5)sumRange 6 10 15 =     -- sumRange (6 + 1)  10 (15 + 6)sumRange 7 10 21 =     -- sumRange (7 + 1)  10 (21 + 7)sumRange 8 10 28 =     -- sumRange (8 + 1)  10 (28 + 8)sumRange 9 10 36 =     -- sumRange (9 + 1)  10 (36 + 9)sumRange 10 10 45 =    -- sumRange (10 + 1) 10 (45 + 10)sumRange 11 10 55 =    -- 11 &gt; 10 =&gt; 5555شما ممکن است فکر کنید که حلقه for آسان‌تر درک می‌شود، این مسئله قابل بحث است و به خاطر این است که این حلقه به چشم شما آشناست. حلقه‌های غیربازگشتی به تغییر‌پذیری ( Mutability) احتیاج دارند که چیز خوبی نیست.من نمی‌خواهم اینجا همه‌ی مزایای تغییرناپذیری را شرح دهم. شما می‌توانید برای مطالعه بیشتر به بخش  Global Mutable State از این مقاله مراجعه کنید.یکی از مزایای واضح تغییرناپذیری این است که دسترسی به متغیر‌ها به صورت فقط-خواندنی است که این بدان معنی است که هیچکس نمی‌تواند مقدار آن متغیر را تغییر دهد، حتی شما، در نتیجه تغییرات ناگهانی نداریم.همچنین اگر برنامه شما بصورت مولتی-ترد نوشته شود، تردها عملیات همدیگر را مختل نمی‌کنند، چون اگر یک ترد بخواهد مقدار یک متغیر را تغییر دهد مجبور است یک کپی از روی آن بسازد.تغییرناپذیری کد شما را ساده‌تر و امن‌تر می‌کند. ادامه دارد...منبع: + </description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Mon, 07 Aug 2017 08:28:33 +0430</pubDate>
            </item>
                    <item>
                <title>برنامه‌نویسی تابع‌گرا (فانکشنال) به زبان ساده</title>
                <link>https://virgool.io/@saeed__noori/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AA%D8%A7%D8%A8%D8%B9%E2%80%8C%DA%AF%D8%B1%D8%A7-%D9%81%D8%A7%D9%86%DA%A9%D8%B4%D9%86%D8%A7%D9%84-%D8%A8%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-wjgneix7upi7</link>
                <description>به طور خلاصه برنامه‌نویسی تابع‌گرا یک شیوه از کد نویسی است که ما در آن به جای استفاده از حلقه‌ها و دستورات شرطی فقط از صدا زدن توابع خالص (pure functions) استفاده می‌کنیم، همچنین داده‌ها در این شیوه برنامه‌نویسی تغییر ناپذیر (immutable) هستند.در میان شیوه‌های برنامه‌نویسی، برنامه‌نویسی تابع‌گرا در دسته برنامه‌نویسی اعلانی قرار می‌گیرد. در این شیوه از برنامه‌نویسی ما به سیستم می‌گوییم می‌خواهیم که چه چیزی اتفاق بیفتد به جای اینکه به سیستم بگوییم چگونه کار را انجام دهد. یک مثال از این مدل زبان‌های برنامه‌نویسی زبان SQL است.تابع خالص چیست؟‌تابع خالص تابعی است که فقط بر مقدار آرگومان‌های ورودی‌اش تکیه دارد و برای هر ورودی مشخص ، خروجی‌اش تغییر نمی‌کند. این بدان معنی است که تابع خالص نباید متغیری را خارج از محدوده (socpe) خودش بخواند ( به عنوان مثال متغیرهای سراسری).مسلم است که نمی‌توان همه‌ی تابع‌ها را در یک برنامه به صورت تابع خالص نوشت، مثلا توابعی که چیزی را از فایل‌سیستم می‌خوانند یا یک صفحه وب را از اینترنت واکشی می‌کنند ممکن است که خروجی متغیری داشته باشند. ما به عنوان برنامه‌نویس باید سعی کنیم تا جای ممکن توابع را به صورت توابع خالص بنویسیم، اگر چه نوشتن ٪۱۰۰ توابع به صورت خالص ممکن نیست ولی با سعی و تلاش می‌توان حدود ٪۸۵ از توابع را به صورت توابع خالص نوشت.از آنجا که در برنامه‌نویسی تابع‌گرا داده‌ها تغییرناپذیر هستند ممکن است برای شما این سوال پیش آید که چگونه برنامه را بدون تغییر دادن داده‌ها بنویسیم؟ در عمل ما به جای اینکه ساختمان‌داده مورد نظر را تغییر دهیم یک ساختمان‌داده جدید از روی آن می‌سازیم. به عنوان مثال فرض کنید یک آرایه ۴ خانه داریم که می‌خواهیم آخرین خانه را حذف کنیم، به جای تغییر این آرایه یک کپی از روی آن درست می‌کنیم که خانه آخر حذف شده است. توابع کمکی در برنامه نویسی تابع‌گراتمام زبان‌های برنامه‌نویسی تابع‌گرا دارای تعداد زیادی تابع‌ کمکی (helper functions) هستند که نوشتن کد به صورت تابع‌گرا را برای برنامه‌نویس تسهیل می کند. به عنوان مثال از آنجا که حلقه‌ها (for, while) در برنامه‌نویسی تابع‌گرا وجود ندارند زبان‌های تابع‌گرا تابعی بنام map دارند که یک مجموعه از داده‌ها را می‌گیرد و مقدار هر یک از داده‌ها را به صورت تک به تک به تابع مورد نظر می‌فرستد تا بر روی آن عملیات انجام شود (در بعضی از زبان‌ها از بازگشت به جای حلقه‌ها استفاده می‌شود). یا مثلا به جای دستور شرطی if توابعی به نام find یا from وجود دارند که از میان مجموعه داده‌ها آنهایی که با شرط مورد نظر همخوانی دارند را واکشی می‌کنند.پ.ن: این مقاله یک ترجمه آزاد از بخشی از فصل هفتم کتاب Modern JavaScript Applications  است که مقوله برنامه‌نویسی فانکشنال را خیلی ساده و کاربردی توضیح داده است.</description>
                <category>سعید نوری</category>
                <author>سعید نوری</author>
                <pubDate>Thu, 03 Aug 2017 12:44:55 +0430</pubDate>
            </item>
            </channel>
</rss>