سلام دوستان با یکی از تابع های پیش ساخته پایتون جدیدا آشنا شدم
خواستم در میون بگذارم البته سرچ کردم و موضوعی با این عنوان پیدا نکردم
شاید روش های خاضی برای گرفتن لیست از کاربر بلد باشید ولی من روش خودم رو که شاید روش ابتدایی ای باشه به صورت کامنت قرار دادم و توضیح مختصری هم درباره خود تابع map دادم و روش خودم رو باهاش مقایسه کردم
توی این روش فقط کافیه کاربر اعداد رو وارد کنه , به سادگی یک لیست ساخته میشه
امیدوارم مفید باشه براتون و این که تو خیلی جاها میشه ازش استفاده کرد
اگر قبلا استفاده کردید خوشحال میشم من رو هم مطلع کنید درباره اش
سام داره تایپ میکنه و احتمالا چیز مشابهی قراره بگیم
تابع map از ساختار های اصلی برنامه نویسی فانکشنال به حساب میاد
اگر پایه ی ریاضی این تابع را می خواهید متوجه بشید به مبحث functor رجوع کنید
بله زبان الکسیر آشنا شدم باهاش قبلترش اطلاعی نداشتم
ممنونم
در اینکه پایتون آشغالتر از این حرفاست که ادای زبونهای functional رو دربیاره شکی نیست.
ولی از اونجایی که first class function هست، بجز map، دوتا تابع دیگه هم داره که مربوط به برنامه نویسی فانکشنال میشه: filter و reduce
حرفتون رو نمیپذیرم هیچی زبونی اشغال نیست مهم اینه کار کنی باهاش
مثل این میمونه که بگید فارسی خوب نیست یا انگلیسی خوبه
هر کدوم جای خودشون بهترین هستن
ولی بابت این دو تابع خیلی ممنون
زبان برنامه نویسی ربطی به زبان طبیعی نداره.
زبان برنامه نویسی، ابزاره. خوب و بد داره. وقتی توی سال ۲۰۲۰ یه زبانی نتونه یه راهکار معقول واسه concurrency ارائه بده، آشغاله. وقتی یه زبان backward compatible نباشه و ورژن ۲ و ۳ش با هم همخوانی نداشته باشه، آشغاله.
کامیونیتی بزرگ و لایبرریهای زیاد، تنها مزایای پایتون هستن که اونم اگه دقیق نگاه کنیم درصد زیادی از برنامه نویساش حرفه ای نیستن و حتی خیلی بیسوادن.
منم زمانی مثل شما فکر میکردم. تا وقتی با یه ابزار بهتر کار نکنید، نقصهای ابزارهای قدیمیتون رو متوجه نمیشید.
برای بدست آوردن تمام زیرمجموعه های یه مجموعه ازش استفاده کردم. خیلی جاهای دیگه هم میشه استفاده کرد ازش. اونواع و اقسام تابع مپ میشه ساخت برای جاهای مختلف.
مپ یکی از توابع درجه بالائه به اصطلاح. توابعی که تو ورودیا یا خروجیاشون توابع دیگه هستن. اینا به جای حل یه مساله، گروهی از مساله های مشابه رو حل میکنن. ینی کلی تر از توابع معمولی هستن. یکی از مزیتای برنامه نویسی فانکشنال امکان ساختن توابع درجه بالاست.
در ادامه بگم که «تابع درجه بالا» انگلیسیش میشه higher order function (اگه انگلیسی سرچ کنید متریالهای بیشتری برای یادگیری پیدا میکنید)
درکل توی Functional Programming روش کار اینطوریه که توابع ما همیشه یه ورودی میگیرن و همیشه ویرایش شدهی اون ورودی رو به عنوان خروجی خودشون return میکنن. موارد استثنا خیلی کم وجود داره (مثلا تابع print که اصولا چیزی return نمیکنه) این باعث میشه که بتونیم مقادیر خودمون رو از داخل زنجیرهای از توابع رد کنیم و جواب نهایی به دستمون برسه.
(توی برنامه نویسی فانکشنال، اصولا دیتا رو ویرایش نمیکنیم. بلکه ورژن جدیدی از دیتا رو تولید میکنیم. و اصطلاحا مقادیر ما Immutable هستن.)
حالا اینهمه واسه چی توضیح دادم؟
تابع map داستانش اینه که «یک تابع را روی یک مجموعه از مقادیر، اعمال میکند» و نتیجشو بهمون برمیگردونه.
مثلا میخوایم همه چیزو +1 کنیم. یا میخوایم از همش فاکتوریل بگیریم یا مثلا int16 رو تبدیل کنیم به int8.
خیلی راحتتر و سریعتره (هم برای برنامه نویس و هم برای کامپیوتر) که اینکارها رو با map انجام بدیم، نه for loop.
اره واقعا جالبه فانکشنال کردن کد ها مون حالا اگر برنامه هم خودش به خودی خود فانکشنال نبود
حالا اگه سندی یا کتابچه ای برای فانکشنال بودن معرفی کنید خیلی ممنونتون میشم
خودم هم در حال یادگیری الکسیر هستم ولی وقت نمیکنم زیاد برای الکسیر
کار خوبی می کنید اگر کمکی نیاز هست من در خدمتم
ممنونم حتما آموزش های خودتون رو میبینم اگر به مشکلی خوردم حتما سوال میکنم
خب functional programming یه پارادایمه. یه سری از زبونها ساپورتش میکنن یه سریها هم تنها پارادایمشونه.
یه کم سویچ کردن بهش میتونه برای کسانی که همیشه OOP کار کردن سخت باشه. برای من هم یه مقدار سخت بود با اینکه توی imperative programming هم همیشه سعی میکردم به روش functional کار کنم (کلا از OOP خوشم نمیومد. از همون اولش!)
اینکه «فانکشنال پروگرامینگ چیست؟» سوال بیجوابیه. کسی پاسخ دقیقی براش نداره که همه باهاش موافق باشن ولی پاسخ تقریبی اینه که:
- باید قابلیت First Class Function داشته باشیم
- باید دیتاهامون Immutable باشن
- باید توابعمون Pure یا با اصطلاح Pure Function باشن
First class function
توابع ما مثل مقادیرمون باشن و بتونیم اونها رو مثل یه int بفرستیم به یه تابع دیگه یا از یه تابع دیگه اونها رو return کنیم.
اینطوری میتونیم قابلیتهایی مثل map و function composition داشته باشیم. یا تابعی بنویسیم که یه تابع جدید میسازه و بهمون return میکنه!
immutable data structure
از اونجایی که توابع ما هیچ دیتایی رو تغییر نمیدن و فقط ورژن جدیدی از دیتای قدیمی رو بهمون return میکنن، باعث میشه قابلیت زیادی توی concurrency داشته باشیم و مشکلات زیادی که توی زبونهای غیر فانکشنال وجود داره رو نداشته باشیم.
مثلا چون دیتاهامون هیچوقت تغییر نمیکنن، پس میشه مطمئن بود که این دیتا توی thread دیگهای ویرایش نشده و نخواهد شد. پس لازم نیست هر threadی که میخواد با دیتای ما کار کنه، بقیهی threadها رو lock کنه.
یه نگاهی به GIL بندازید تا متوجه بشید چرا میگم پایتون آشغاله! پایتون فقط به درد نوشتن اسکریپتهای نسبتا ساده میخوره. رسما برنامه نویس پایتون باید بگه «من دارم این دیتا رو میخونم یا مینویسم. کسی بهش دست نزنه، کسی از جاش تکون نخوره، کسی نفس نکشه.»
سمیر جان حتی بیشتر از من به GIL آلرژی داره دلم میخواد یه کم اذیتش کنم پس اینجا صداش میزنم @lxsameer
Pure Function
وقتی یه تابعی pure باشه، موقع اجرا شدن، دیتایی از بیرون خودش رو نمیخونه و دیتایی از بیرون خودش رو ویرایش نمیکنه (یا نمیسازه) و خروجی اون تابع همیشه فقط و فقط به ورودیش بستگی داره. امکان نداره یه بار بهش ۵ بدیم ۶ بهمون تحویل بده دفعهی بعد که محیط اطرافش (متغیرهای اطرافش) عوض شده بودن بهمون ۷ برگردونه.
این باعث میشه:
- بتونیم از توابعمون همهجا استفاده کنیم و درگیر این نباشیم که چرا اونجا کار میکرد اینجا کار نمیکنه.
- دیباگ کردن برنامه برامون خیلی راحت باشه چون فقط کافیه این تابع رو اجرا کنیم و جوابشو ببنییم. لازم نباشه چیزی رو خارج از اون تغییر بدیم تا به state مورد نیازمون برسه. حتی لازم نیست کل برنامه اجرا بشه. فقط کافیه همون تابع رو اجرا کنیم. (تا با کلوژر کار نکنید متوجه منظورم نمیشید. بهش میگیم repl development)
- خروجی تابعهایی که کار سنگین انجام میدن رو میشه memoize کرد. اینطوری میشه گفت خروجی تابع cache شده. دفعهی بعد که اجراش کنیم مستقیم به جواب میرسیم دیگه فشاری به سیستم نمیاد. این فقط زمانی ممکنه که تابع pure باشه.
- داستان multi-threading برامون خیلی راحت میشه. در حدی که اصلا لازم نیست کد خاصی بنویسیم. مثلا توی کلوژر وقتی میخوایم تابع map به صورت multi-threading کار کنه فقط کافیه تبدیلش کنیم به pmap. به همین سادگی نرم افزار من سریعتر شد
حالا این وسط یه سری تابع impure هم داریم. به هرحال نرمافزار ما باید یه ورودی از کاربر بگیره یا یه چیزی براش print کنه! باید بتونه به یه سروری ریکوئست بزنه و جواب بگیره یا توی دیتابیس یه چیزی رو بنویسه و بخونه.
اینا باعث میشن نرمافزار ما 100% pure نباشه. (نرمافزاری که صددرصد خالص باشه کار مفیدی انجام نمیده!)
بنابراین مجبوریم بخشهایی از کدمون رو «ناخالص» بنویسیم. توی برنامه نویسی فانکشنال، اینطوری عمل میکنن که این بخشها رو تا حد ممکن کوچیک میکنن و میذارنش یه گوشه. به این صورت که مثلا ۱۰۰تا تابع داریم که کارهامون رو انجام میدن و ۵تا تابع که با بیرون از برنامه ارتباط دارن (ارتبا با کاربر و دیتابیس و…) اینطوری هم خیالمون راحته که side-effectها، قاطی منطق برنامه نیستن و همهچیز تر و تمیزه.
برنامه نویسی فانکشنال، از فانکشنها (توابع) ریاضی میاد. از lambda calculus.
همونطور که توی توابع ریاضی، مقادیرمون تغییر نمیکنن (۵ همیشه ۵ هست، نه چیز دیگهای) و هیچ تابعی با محیط بیرون خودش کار نداره، توی فانکشنال پروگرامینگ هم همین سیستم رو داریم.
چیزهای دیگهای هم هست مثل Atomic data-structure که مسلما بودنشون توی یه زبان برنامه نویسی عالیه ولی فکر میکنم جزء ملزومات زبانهای فانکشنال نباشن.
خیلی توضیح دادم. امیدوارم جایی اشتباه ننوشته باشم و چیزی رو از قلم ننداخته باشم.
این لینک زیاد هم بیربط نیست.
به آرتیکل درمورد higher order function که توش filter, map و reduce رو با مثال توی کلوژر و جاوااسکریپت توضیح داده.
https://blog.ona.io//2020/01/25/clojure-and-js-hof.html
بعد از خوندنش متوجه میشید چرا من کلوژر رو دوست دارم. خوشگل و تر و تمیز چیزی که میخوایو مینویسی جوابو میگیری. کمترین boilerplate توی زبونهایی که میشناسم اول برای کلوژره بعد پایتون.
نمونهکد reduce توی js:
const numbers = [1, 2, 3, 4];
const summedNums = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue }, 100);
console.log(summedNums);
// output
// 110
و همون کد توی کلوژر:
(reduce + 100 [1 2 3 4])
;; output
;; 110
ممنونم از توضیحاتتون خیلی کامل بود
حتما یه نگاهی باید به کلوژر بندازم آشنا بشم باهاش با این اوصاف
واقعا ممنونم
کلوژر یک لیسپه (همین دلیلی بر برتریش نسبت به زبونهای دیگست)
قبلا توی انجمن زیاد درموردش بحث شده و یه مقداری هم براش آموزش نوشتیم که دیگه ادامهدار نبود متاصفانه.
توضیح جالبی بود اما چنتا مورد وجود داره،
اول اینکه FP هم مثل OOP یک پردایم هست و تعریف مشخصی داره، و مورد دوم در رابطه با فانکشن های pure هست، وقتی میگیم side effect منظورمون خواندن دیتا نیست، منظور تغییر دیتاست. و در مورد immutability هم یکی از خصوصیات FP بحساب میاد اما معنیش این نیست که فقط مختص زبان های فانکشنال باشه. فانکشن های pure و Memoization مفهوم های کلی هستند و مختص FP نیست.
الیکسر هم نوع دیگه از زبان های لیسپی هست و با توجه به داشتن اکوسیستم فانکشنال از کلوژر فانکشنال تره اما هر دو برای من جالب هستند.
من یه توضیح کوچیک بدم. البته قبلا بهش اشاره شده. از نظر ریاضی فانکشن pure فانکشنی هست که free variable نداشته باشه. برای مثال:
λx.x
λx.λy.λz.x y
λx.λy.x(xy)
همه pure هستند اما
λx.ax
λx.λy.yxa
λx,y(λy.xy)
pure نستند چون در همه اون متغیری وجود داره که جزئی از ورودی فانکشن نیست
البته پویا جان هم به این مورد جور دیگه ای اشاره کرد اما بنظر من هم از دید ریاضی بهشت نگاه بشه مشکل در پایه ساده میشه