چرا باید اف‌شارپ رو یاد بگیریم و چه مزایا و کاربرد هایی داره؟

پیش گفتارتو این نوشته سعی شده افراد با سطح دانش برنامه نویسی متوسط هدف قرار داده بشن، بنابراین اگه بیشتر میدونید خیلی راحت میتونید بخش هایی که بلدید رو رد کنید، و اگه جایی براتون مبهم بود، خجالت نکشید و تو کامنتا سوال بپرسید، سعی میکنم جوابتون رو هر چه سریع تر بدم، و یا اگه گسستگی مطلب در جایی دیدید بگید که اطلاعات بیشتری اضافه کنم.اف‌شارپ چیه؟اگه برنامه نویس باشید و توی Stack Overflow و آمار های سالیانش چرخ زده باشین احتمال زیاد هر سال اف‌شارپ رو جز زبان هایی که بیشتر میزان حقوق رو دارن دیدید، ولی تا حالا براتون سوال پیش اومده که این زبان چیه؟Top Paying Technologies - Stack Overflow Annual Survey (2019)اف‌شارپ (به انگلیسی: #F یا FSharp) یه زبان برنامه نویسی متن باز و کراس‌پلتفرم (قابل اجرا روی لینوکس و مک و ویندوز) هست که توسط موسسه تحقیقاتی مایکروسافت (Microsoft Research) ایجاد شد. این زبان، یه زبان تابعی (یا همون Functional) روی پلتفرم دات‌نت مایکروسافته که از پارادایم شی گرایی هم پشتیبانی میکنه. (این که زبان Functional و یا شی گرایی چیه رو جلوتر توضیح میدم).من با اف‌شارپ چیکار میتونم انجام بدم؟به طور خلاصه، هر کاری! این زبان، یک زبان کاملا عام منظورست و برای هر کاری میتونید ازش استفاده کنید، همچنین برای هر کیس خاص هم کتاب خونه ها و موتور های خاصی توسعه داده شده که احساس کمبود نمیکنید.نمونه هایی از کاربرد های اف‌شارپ:بازی سازی: این زبان کاملا سازگار با موتور بازی سازی معروف Unity هست. موتور های دیگه ای مثل Godot و یا کتاب خونه های بازی سازی مثل مونوگیم (Mono Game) هم با اف‌شارپ تمیز کار میکنن. اف‌شارپ موتور بازی سازی اختصاصی خودش به اسم Nu رو هم داره که با خود اف‌شارپ نوشته شده. اشاره به موتور های دیگه ای مثل Xenko یا Wave هم خالی از لطف نیست.برنامه نویسی وب: اف‌شارپ برای وب فوق العادست. این زبان خیلی راحت میتونه از طریق پروژه Fable با اکوسیستم جاوا اسکریپت ارتباط برقرار کنه و خیلی راحت میتونید توابع جاوا اسکریپت رو صدا بزنید. با پروژه Elmish میتونید فرانت اند خودتون رو به اف‌شارپ (که خیلی خلاصه تر از HTML هست) بنویسید و یا یه برنامه React رو با اف‌شارپ درست کنید. همچنین در کنار همه این موارد اف‌شارپ به WebAssembly هم اومده و میتونید برنامه اف‌شارپ خودتون رو بدون نیاز به کامپایل به جاوا اسکریپت روی مرورگر اجرا کنید. این پروژه Bolero نام داره و برای همه این موارد هم نمونه و مستندات آموزشی به اندازه کافی پیدا میشه. در انتها، اگه فکر میکنید که ممکنه این موارد سردرگم تون کنه، پروژه ای هست به نام SAFE-Stack که براتون یه قالب آماده از یه پروژه اف‌شارپ رو میسازه که از برنامه نویسی سمت سرور و API تا کلاینت و طراحی رابط کاربری رو داخل خودش داره که باهاش شروع کنید به ساخت ایده هاتون. برای ساخت یه وب‌سایت، به چیزی جز اف‌شارپ و دانش معمولی از وب نیاز پیدا نمیکنید.توسعه برنامه های موبایل: با اف‌شارپ و زامارین (Xamarin) میتونید خیلی راحت برای گوشی های اندرویدی یا آیفون‌تون بازی یا برنامه درست کنید و بفروشیدشون. همچنین با استفاده از Xamarin Forms میتونید یه برنامه واحد بنویسید و خروجیش رو هم برای اندروید و هم iOS بگیرید.برنامه نویسی دسکتاپ: با اف‌شارپ میتونید برنامه های دسکتاپ بسازید. این زبان از WinForms و WPF و همچنین Avalonia که برای ساخت برنامه های کراس‌پلتفرم استفاده میشه به طور رایگان و بدون محدودیت استفاده کنید.هوش مصنوعی، یادگیری ماشین و علوم داده: اگر به کارکردن تو این حوزه ها علاقه دارید، اف‌شارپ میتونه خیلی تجربه خوبی براتون به ارمغان بیاره، چرا که خوراک اف‌شارپ داده‌ست، مخصوصا با قابلیت Type Provider که مخصوص اف‌شارپ هست (این رو هم جلوتر توضیح میدم). میتونید از ML.NET و Tensorflow توی اف‌شارپ استفاده کنید؛ فرقی نمیکنه که تخمین‌گر قیمت میسازید، میخواید کلاه برداری رو شناسایی کنید، چهره رو توی عکس تشخیص بدید، احساسات نویسنده رو توی کامنت ها و نوشته ها تشخیص بدید و خیلی چیزای دیگه... اف‌شارپ برای همه این موارد قابل استفادست. همچنین Apache Spark و FsLab که یه پکیج کامل برای کار با پروژه های علوم دادست مخصوص برنامه نویس های اف‌شارپ وجود داره.اینترنت اشیا: اف‌شارپ برای توسعه اینترنت اشیا هم در کنار شماست. خیلی راحت میتونید اف‌شارپ رو روی رزبری پای خودتون راه بندازید و روی دستگاه های مختلفی ازش استفاده کنید.محاسبات ابری: از اف‌شارپ به شکل بومی و رسمی توی Azure که یک ارائه دهنده خدمات ابری هست پشتیبانی میشه و برای بقیه هم ازونجایی که اف‌شارپ روی دات‌نت کار میکنه میتونید استفاده کنید مثل GCP و AWS و ...و ...: همون طور که میبینید، اف‌شارپ برای هر کاری میتونه مورد استفاده قرار بگیره، و همچنین خیلی از موارد دیگه که میتونید تو صفحه پروژه های اف‌شارپ پیدا کنید.گفتی اف‌شارپ یه زبان Functional ئه. این یعنی چی؟پارادایم های برنامه نویسی روش هایی هستن که باهاشون میتونیم زبان های مختلف رو بر اساس ویژگی هایی که دارن دسته بندی کنیم.پارادایم Object Oriented، پارادایمی از نوع زبان های برنامه نویسی دستوریه (Imperative)، یعنی اینکه برنامه شما در هر لحظه به ماشین میگه که حالت برنامه (بخوانید متغیر ها و همه المان های برنامه) رو چطور تغییر بده و برای لحظه به لحظه اتفاقی که میفته یه دستور کار داره. در حالی که پارادایم Functional از گروه زبان های توصیفی (Declarative) هست، یعنی شما فقط به ماشین میگید که اون حالت نهایی که مد نظرتون هست چه ویژگی هایی داره، بدون اینکه خودتون محاسبش کنید.زبان های Functional از اونجایی که به منطق و ریاضیات نزدیک تر هستن، اعتبار سنجی برنامه راحت تره، یعنی شما زمان کامپایل میتونید باگ های بیشتری رو بگیرید. در واقع میشه گفت در این زبان ها به جای اجرای برنامه (Execute)، از واژه ارزیابی برنامه (Evaluate) استفاده میشه، چون که توابع مثل توابع ریاضی فقط قراره محاسبه بشن، بدون اینکه در حین این محاسبه اتفاق بی ربطی مثل تغییر یه داده در یه گوشه از برنامه صورت بگیره. مثلا شما حین محاسبه مجموع صورت حساب یک مشتری در رستوران موشک هوا نمیکنید! و صدا زدن یک تابع با پارامتر های یکسان، همواره مقدار یکسانی رو برمیگردونه و هیچ چیزی در بیرون تغییر پیدا نمیکنه. به بیان دیگه شما عوارض-جانبی (Side-effect) ندارید. برای همین در اف‌شارپ همه چیز به طور پیشفرض غیر قابل تغییر (Immutable) هست، و شما نمیتونید بگید یه چیزی مساوی با 2 هست و پایین تر برابر با 3 کنیدش. (مگراینکه از کلید واژه mutable استفاده کنید)اگه این موارد براتون گنگ و یا نامفهومه، شاید با خوندن ادامه متن و یا دیدن نمونه هایی از کد های تابعی برطرف بشه، در هر حالت سوالی بود میتونید بپرسید.زبان هایی که میشناسید مثل پایتون، سی، جاوا، سی‌شارپ، سی‌پلاس‌پلاس، پی‌اچ‌پی، جاوا اسکریپت، روبی و ... همه زبان های دستوری هستند که به مرور زمان بهشون ممکنه قابلیت های تابعی هم اضافه شده باشه.بخش برنامه نویسی تابعی خیلی مفصله و داستان زیاد داره و من ازونجایی که نمیخوام این پست رو آکادمیک کنم و وارد مفاهیمی مثل Monad ها و محاسبات لامبدا و ... بشم به همین موارد بسنده میکنم، همین قدر هم برای شروع با این زبان ها و کلی کارای خلاقانه کردن کافیه پس از چیزی نترسید.نمونه از از یک برنامه دستوری (Imperative) به زبان سی‌شارپ:var list = new List<int> { 1, 2, 3 , 4}; int result = 0; for(int i = 0; i < list.Count; i++){ result += list[i]; } Console.WriteLine($&quotSum: {result}&quot);همین برنامه با زبان اف‌شارپ:let result = List.sum [1; 2; 3; 4] printfn &quotSum: %A&quot resultاف‌شارپ چه ویژگی هایی داره؟اف‎شارپ ویژگی های مختلفی داره که ممکنه برات جالب باشه.۱- سمی کالناف‎شارپ برای اتمام دستوراتش به سمی‌کالن (;) نیاز نداره۲- فاصله گذاریاف شارپ مثل پایتون برای بلوک بندی کد از Indentation و فاصله‌ها استفاده میکنه، ولی نگرانش نباشید چون تو اف‌شارپ این فاصله گذاری‌ها ارورخیز نیست!let x = &quotHello&quot let number = if x.Length > 10 then 20 else 30۳- توابع مانند متغیر ها شهروند درجه یک زبان هستنتوی اف شارپ تعریف توابع هیچ فرقی با تعریف مقادیر نداره و همشون با کلید واژه let ایجاد میشن و هرجایی هم میتونید مقدار و تابع تعریف کنید.let myName = &quotAryan&quot let myAge = 21 let addGreetingsToName name (age:int) = $&quotHello {name}! You are {age} years old!&quot addGreetingsToName myName myAgeدر کد بالا addGreetingsToName یک تابع هست. همون طور که احتمالا متوجه شدید توی اف‌شارپ برای نوشتن پارامتر ها و یا دادن پارامتر تابع نیازی به نوشتن پرانتز و یا کاما ندارید و فقط با یک فاصله گذاشتن میتونید به پارامتر ها مقدار بدید (اگرچه میتونید به فرم سنتی پرانتز و کاما هم بنویسید). این نوع نحوه نوشتار یه مزیت خیلی بزرگ داره که تو بخش بعدی یعنی اعمال جزئی میبینیم.۴- اعمال جزئی یا Partial Applicationتو اف‌شارپ میتونید توابع رو Partially Apply کنید، یعنی به تابعی کم تر از مقداری که نیاز داره پارامتر بدید. نتیجه تولید شده تابع جدیدیه که فقط پارامتر های پاس داده نشده رو نیاز داره.let someFunction param1 param2 param3 = param1 + (2 * param2) - param3 let anotherFunction = someFunction 10 20 let result = anotherFunction 30 // calculates 10 + (2 * 20) - 30در این مثال تابعی تعریف شده به اسم someFunction و سه پارامتر میگیره به اسم param1 تا param3. توی خط بعد من یه تابع جدید ساختم که با دادن پارامتر های اول و دوم، فقط یه پارامتر باقی مونده رو میگیره و مقدار زیر رو حساب میکنه:10 + (2 * 20) + param3۵- تعریف نوع های جدید و رکورد ها تو اف‌شارپ کوتاه و آسونهtype Gender = | Male | Female | Other of string type Person = { name : string age : int father : Person option mother : Person option gender : Gender }در نمونه کد بالا ما دو نوع تعریف کردیم یکی برای جنسیت، و یکی دیگه برای شخص. شخص با پارامتر های نام، سن و جنس تعریف شده، و همچنین دو ویژگی اختیاری (option) به نام پدر و مادر۶- پایپ همه جا! (|>)پایپ یا خط لوله ویژگی ای از اف‌شارپه که همه جا تو اف‌شارپ میبینیدش. پایپ هم یک اپراتور هست، مثل اپراتور های ریاضیات مثل جمع و ضرب با این تفاوت که پایپ یه مقدار رو به تابع جلوییش پاس میده و در واقع مثل یک خط تولید در کارخونه عمل میکنه:let car = Car(name = &quotMy Car&quot) car |> paintBody green |> paintRoofs red |> testStrength |> driveدر این مثال ابتدا یک ماشین جدید ساختیم، و بعد با خط لوله پاسش دادیم به تابعی که بدنش رو سبز رنگ کنه، در مرحله بعد این ماشین با بدنه سبز رو به تابعی دادیم که سقفش رو قرمز میکنه، در مرحله بعدی سپردیمش به تیم تست قدرت ماشین، و در نهایت باهاش رانندگی کردیم.۷- استاتیک تایپ همراه با استنتاج نوع (Type Inference)زبان اف‌شارپ یه زبان Static Type هست، یعنی اینکه زمان کامپایل نوع و تایپ همه چیز معلومه. به همین خاطر خیلی از خطا های برنامتون از جهات منطقی هنگام مرحله کامپایل گرفته میشه. از طرفی کامپایلر اف‌شارپ باهوش هم هست و میتونه نوع پارامتر یا متغیر ها و تابع ها و غیره رو از روی کاربردش استنتاج کنه. به عنوان مثال اگه من در ادامه مثال بالا نمونه ای با دادن نام و جنسیت و ... تعریف کنم، خود کامپایلر میفهمه که من یک انسان رو تعریف کردم. در واقع شما مثل پایتون تایپ ها رو نمینویسید، ولی از اون طرف مزیت های استاتیک تایپینگ رو هم دارین.// infers as Person let someGuy = { name = &quotMohsen Mehdinia&quot age = 31 gender = Male father = None mother = None }someGuy binding infered as Person typeدر این مثال دوم فرض کنید من میخوام تابعی بنویسم که لیستی از اسامی رو بگیره و به همه این اسامی خوش‌آمد بگه:let greet names = names |> List.iter (fun name -> printfn &quotHello %s!&quot name)در کد بالا اول از همه تابع greet با پارامتر names رو تعریف کردیم و در بدنه تابع مقدار names رو پایپ کردیم داخل تابع iter که مخصوص پیمایش روی لیست و انجام کار روی هر آیتم از لیسته. این تابع باید بدونه که به ازای هر آیتم از لیست باید چه کاری انجام بده پس به یک تابع دیگه نیاز داره.میتونیم این تابع رو یک جای دیگه تعریف کنیم، و یا همونجا جلوی iter با کلید واژه fun یک تابع جدید تعریف کنیم که پارامتر name رو میگیره و یه کاری باهاش انجام میده.حالا بازی اصلی شروع میشه! کامپایلر اینجا خودش استنتاج میکنه که پارامتر names از نوع لیستی از string هاست و همچنین تابع greet از نوع:string list -> unitهست. این یعنی که این تابع لیستی رشته ها رو میگیره و یک unit برمیگردونه. unit یا واحد به این معنیه که تابع فقط یه کاری انجام داده و مقداری برنگردونده (در واقع میتونید به unit به همون شکل void در سایر زبان ها نگاه کنید). این فقط یه نمونه ساده بود و میتونید نمونه های خیلی پیچیده تری هم که کامپایلر قادر به تشخیص نوع هست رو هم در مثال ها ببینید.۸- ترکیب توابع یا Compositionترکیب توابع هم از مواردی هست که زیاد تو اف‌شارپ میبینید. به مثال زیر نگاه کنید:let countCharacter char (str:string) = str.ToCharArray() |> Array.filter (fun c -> c = char) |> Array.length let isMoreThanTen len = len > 10اینجا دو تابع تعریف کردیم یکی به نام countChar که یک رشته و یک کاراکتر رو به عنوان پارامتر میگیره و میشمره که توی اون رشته چند بار کاراکتر مورد نظر ما دیده شده. همچنین تابعی وجود داره به اسم isMoreThanTen که یک عدد رو میگیره و میگه که اون عدد بیشتر از 10 هست یا نه. همون طور که حدس زدید هم تایپ این دو تابع به این شکله:countChar : char → string→ intisMoreThanTen : int → boolحالا فرض کنید ما میخوایم تابعی بنویسیم که به ما بگه آیا تعداد کاراکتر های حرف b داخل یک متن بیشتر از 10 هست یا نه. خیلی راحت میتونیم این دو تابع رو به این شکل و با استفاده از اپراتور (>>) ترکیب کنیم:let hasMoreThanTenB = countCharacter 'b' >> isMoreThanTenو من حالا میتونم به این شکل فراخوانیش کنم:hasMoreThanTenB &quotOh baba, what a boooablabo&quotتایپ این تابع نهایی هم به این شکل هست:hasMoreThanTenB : string → bool۹- تطبیق الگو یا Pattern Matchingبا استفاده از این ویژگی زبان شما میتونید روی انواع و اقسام متغیر ها و توابع و زیر مجموعه هاشون الگویابی کنید و در صورت تطبیق الگو کار مورد نظرتون رو انجام بدید. (تطبیق الگو در زبان های برنامه نویسی یه جورایی مثل نوشتن RegEx روی رشته های زبان های طبیعی میمونه)type Suit = | Diamond | Spades | Hearts | Clubs type Rank = | Ace | King | Queen | Jack | NumberRank of int type Card = Rank * Suit let getScore card = match card with | (Ace, Spades) -> 20 | (King, Hearts) | (Queen, Hearts) -> 15 | (NumberRank x, Spades) -> (x % 5) * 2 | _ -> 0در نمونه کد بالا ما اول سه تایپ یکی برای شکل کارت، یکی دیگه برای مقدار روی کارت، و یکی هم برای خود کارت که ترکیبی از شکل و مقدار کارت هست تعریف کردیم. (علامت * برای ترکیب شکل و مقدار کارت که تایپ جدیدی تولید کرده، همون ضرب دکارتی ریاضیات روی مجموعه مقادیر هست که مجموعه مقادیر جدید ایجاد میکنه و از فضا نیومده)حالا ما تابعی نیاز داریم که به ازای یک سری کارت خاص به کاربر امتیاز بدن، همون طور که میبینید این تابع به ازای آس پیک 20 امتیاز برمیگردونه، به ازای شاه یا بی‌بی دل 15 امتیاز، به ازای هر عددی از پیک ها، ابتدا اون عدد در پیمانه پنج حساب میشه و سپس ضرب در 2 شده و برگشت داده میشه، و در غیر این حالات امتیازی تعلق نمیگیره. میبینید که بدون نیاز به if های متوالی به شکل خیلی ساده همچین تابعی ممکن شد. زبان اف‌شارپ از الگو های خیلی زیاد و متنوعی پشتیبانی میکنه که میتونید از مستنداتش مطالعه کنید.۱۰- تهیه کننده نوع یا Type Providerتایپ پروایدر ها، قابلیت هایی از زبان اف‌شارپ هستن که براتون از یه فایل یا هر منبع دیگه ای تایپ تولید میکنن. به عنوان مثال شما بهش فایل csv یا json و ... به عنوان ورودی میدید و تایپ پروایدر براتون تجزیش میکنه و علاوه بر اینکه توی محیط توسعه تون براتون Auto Complete یا Intellisense میاره، تایپ چک هم میشه و اگه برنامه در رابطه با اون داده ها باگ داشته باشه، کامپایلر بهتون اطلاع میده.A JSON Type Provider sample in F#۱۱- پشتیبانی کامل از دات‌نت و همکاری بدون مشکل با سایر زبان های دات‌نت مثل سی‌شارپاف‌شارپ یکی از زبان های رسمی دات‌نته و میتونه از پروژه های سایر زبان های دات‌نت مثل پروژه هایی که با سی شارپ نوشته شدن استفاده کنه، و یا داخل یک Solution میتونید هم پروژه سی‌شارپ و هم اف‌شارپ داشته باشید و این پروژه ها بدون مشکل هم رو صدا بزنن.عملا هر مزیتی برای دات‌نت وجود داره، اف شارپ هم میتونه ازش استفاده کنه و گسترشش بده.۱۲- سایر...اف‌شارپ کلی قابلیت خفن دیگه داره مثل واحد های اندازه گیری ( Units of Messure) که میتونید به هر متغیر عددی واحد بدید (مثل کیلوگرم، کیلو وات، گیگا بایت و ... حتی واحد های سفارشی خودتون) و این واحد ها توسط کامپایلر تایپ چک میشن، همچنین تایپ های ناشناس، ماژول سیستم خوب، ارتباط بومی با سیستم، Computational Expressions یا عبارات محاسباتی که یکی از قدرت مند ترین ساختار های زبانی اف‌شارپه، بهینه سازی TailCall و خیلی چیز های دیگه... که توضیحشون خارج از این پست هست.مقایسه اف‌شارپ با سایر زبان هاپایتون: همون طور که دیدیم، اف‌شارپ مثل پایتون از Indentation استفاده میکنه و خیلی جاها نیازی به نوشتن تایپ ها نیست، لایبرری های خیلی خوبی برای هوش مصنوعی داره که میتونید مدل تون رو باهاش train کنید، در کنار اون استاتیک تایپ هست و اعتبار منطقی برنامه رو بالا میبره و در برنامه های بزرگ به باگ خیلی کمتری میخورید. جاوا اسکریپت: اف‌شارپ برای برنامه نویس های جاوا اسکریپت هم دوست خوبیه. چرا که با Fable عملا به لایبرری های گذشته تون دسترسی دارید و میتونید خیلی راحت برنامه نویسی Front-end انجام بدید.سی‌شارپ: اگه برنامه نویس دات‌نت هستید، قطعا اف‌شارپ رو یاد بگیرید. اولش ممکنه گیج کننده باشه، ولی بعدا دیگه حتی دوست ندارین به سی‌شارپ برگردین. دیفالت های اف‌شارپ خیلی کدتون رو کمتر میکنه و در عین حال چون با دات نت آشنایی دارین، خیلی خیلی کارتون برای یادگیری آسون تر میشه.هسکل (Haskell): هسکل به نوعی بابابزرگ زبان های تابعی شناخته میشه و اونقدر از نظر ساخت زبانی قوی و منطقی هست که نه تنها رو زبان های تابعی مثل اف‌شارپ، بلکه روی زبان های mainstream هم تاثیر زیادی داشته. اگرچه بعضی از ویژگی های هسکل توی اف‌شارپ نیست (قراره اضافه بشه)، ولی شما به کل اکوسیستم دات‌نت دسترسی پیدا میکنین. کم نبودن هسکلر هایی که بعد از کار با اف شارپ بهشون حس اینکه تو خونه خودشون هسکل هستن دست داده.وضعیت ابزارهای توسعه برای اف‌شارپ چجوریه؟اف‌شارپ برای توسعه رسما توسط مایکروسافت پشتیبانی میشه، و این یعنی اینکه شما میتونید خیلی راحت داخل ویژوال استودیو اف‌شارپ بنویسید. همچنین اگه طرفدار محصولات JetBrains هستید و قبلا با PyCharm یا IntelliJIdea یا PhpStorm و ... تجربه داشتید، میتونید از JetBrains Rider استفاده کنید که از اف‌شارپ پشتیبانی میکنه.ولی جدای همه اینا اگه نظر منو بخواید، من افزونه Ionide برای VSCode رو بهتون توصیه میکنم. این افزودن قابلیت های خارق العاده ای داره که حتی برای زبان های پر استفاده تر هم پیدا نمیشن مثل ابزار های یکپارچه شده با بلید سیستم و یا قابلیت Info Panel. سایتش هم اینجاست:http://ionide.ioاوف! میخوام اف‌شارپ یاد بگیرم.خیلی هم عالی! منابع خیلی زیادی برای شروع وجود داره.سایت «بنیاد اف‌شارپ»https://fsharp.orgسایت «اف‌شارپ برای سرگرمی و سود»https://fsharpforfunandprofit.comسایت اف‌شارپ در دات‌نتhttps://dotnet.microsoft.com/languages/fsharpبیشتر بخوانیدمروری کوتاه و تاریخی بر زبان‌های برنامه‌نویسی Functionalسوالی داشتم که تو متن جواب ندادی!این پایین بپرس ↓