From e697a69c4e4d894e77d7b0cbce0e35e6df41b796 Mon Sep 17 00:00:00 2001 From: Alireza Moradi <143579955+moAlireza@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:24:39 +0330 Subject: [PATCH 1/2] Translate article.md --- .../03-currying-partials/article.md | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/1-js/99-js-misc/03-currying-partials/article.md b/1-js/99-js-misc/03-currying-partials/article.md index d71ac23f8..0aa518720 100644 --- a/1-js/99-js-misc/03-currying-partials/article.md +++ b/1-js/99-js-misc/03-currying-partials/article.md @@ -3,21 +3,21 @@ libs: --- -# Currying +# کاری کردن -[Currying](https://en.wikipedia.org/wiki/Currying) is an advanced technique of working with functions. It's used not only in JavaScript, but in other languages as well. +[کاری کردن](https://en.wikipedia.org/wiki/Currying) (Currying) یک شیوه پیشرفته کار با فانکشن ها است. این فقط مختص به جاوااسکریپت نیست و در زبان های دیگر نیز مورد استفاده قرار میگیرد. -Currying is a transformation of functions that translates a function from callable as `f(a, b, c)` into callable as `f(a)(b)(c)`. +کاری کردن به معنای تبدیل فانکشن ها به گونهای است که فانکشنی که در ابتدا به صورت `f(a, b, c)` فراخوانی میشد، به شکل قابل فراخوانی `f(a)(b)(c)` تبدیل میشود. -Currying doesn't call a function. It just transforms it. +به این نکته توجه کنید که کاری کردن فانکشن را صدا نمیزند بلکه فقط آن را تغییر میدهد. -Let's see an example first, to better understand what we're talking about, and then practical applications. +برای درک بهتر این مفهوم، ابتدا یک مثال را مشاهده میکنیم و سپس کاربردهای عملی آن را بررسی میکنیم. -We'll create a helper function `curry(f)` that performs currying for a two-argument `f`. In other words, `curry(f)` for two-argument `f(a, b)` translates it into a function that runs as `f(a)(b)`: +ما یک فانکشن کمکی با نام `curry(f)` ایجاد خواهیم کرد که برای دو آرگومان `f` کاری را اجرا میکند. به عبارتی دیگر، `curry(f)` برای دو آرگومان `f(a, b)` آن را به تابعی ترجمه میکند که به صورت `f(a)(b)` اجرا میشود. ```js run *!* -function curry(f) { // curry(f) does the currying transform +function curry(f) { // تبدیل کاری را انجام میدهد curry(f) return function(a) { return function(b) { return f(a, b); @@ -26,7 +26,7 @@ function curry(f) { // curry(f) does the currying transform } */!* -// usage +// استفاده function sum(a, b) { return a + b; } @@ -36,30 +36,30 @@ let curriedSum = curry(sum); alert( curriedSum(1)(2) ); // 3 ``` -As you can see, the implementation is straightforward: it's just two wrappers. +همانطور که میبینید، پیاده سازی بسیار ساده است: تنها دو بسته بندی صورت میگیرد. -- The result of `curry(func)` is a wrapper `function(a)`. -- When it is called like `curriedSum(1)`, the argument is saved in the Lexical Environment, and a new wrapper is returned `function(b)`. -- Then this wrapper is called with `2` as an argument, and it passes the call to the original `sum`. +- نتیجه `curry(func)` یک بسته بندی به شکل `function(a)` است. +- وقتی به صورت `curriedSum(1)` فراخوانی میشود، آرگومان در محیط واژگانی (the Lexical Environment) ذخیره میشود,و یک بسته بندی جدید به شکل `function(b)` بازگشت داده میشود . +- سپس این بسته با 2 به عنوان آرگومان صدا زده میشود، و فراخوانی را به سمت فانکشن اصلی `sum` ارسال میکند. -More advanced implementations of currying, such as [_.curry](https://lodash.com/docs#curry) from lodash library, return a wrapper that allows a function to be called both normally and partially: +پیاده سازی پیشرفته تری از کاری کردن، مثل [_.curry](https://lodash.com/docs#curry) از کتابخانه lodash، یک بسته بندی بر میگرداند که به کاربر این امکان را میدهد که به صورت عادی و یا جزئی فانکشن را فراخوانی کند. ```js run function sum(a, b) { return a + b; } -let curriedSum = _.curry(sum); // using _.curry from lodash library +let curriedSum = _.curry(sum); // lodash استفاده کاری از کتابخانه -alert( curriedSum(1, 2) ); // 3, still callable normally -alert( curriedSum(1)(2) ); // 3, called partially +alert( curriedSum(1, 2) ); // 3, هنوز به شکل عادی قابل فراخوانی است +alert( curriedSum(1)(2) ); // 3, به شکل جزئی فراخوانده شده است ``` -## Currying? What for? +## کاری کردن؟ چرا استفاده میشود؟ -To understand the benefits we need a worthy real-life example. +برای درک مزایای کاری کردن، به یک مثال واقعی و مفید نیاز داریم. -For instance, we have the logging function `log(date, importance, message)` that formats and outputs the information. In real projects such functions have many useful features like sending logs over the network, here we'll just use `alert`: +برای مثال، ما فانکشن `log(date, importance, message)` را داریم که اطلاعات را قالب بندی کرده و خروجی میدهد. در پروژه های واقعی چنین فانکشن هایی دارای بسیاری از ویژگی های مفید مانند ارسال لاگ ها از طریق شبکه هستند. در اینحا ما فقط از `alert` استفاده خواهیم کرد: ```js function log(date, importance, message) { @@ -67,37 +67,37 @@ function log(date, importance, message) { } ``` -Let's curry it! +بیایید کاری اش کنیم! ```js log = _.curry(log); ``` -After that `log` works normally: +پس از آن `log` به شکل عادی کار میکند: ```js log(new Date(), "DEBUG", "some debug"); // log(a, b, c) ``` -...But also works in the curried form: +... و همینطور در شکل کاری شده کار میکند: ```js log(new Date())("DEBUG")("some debug"); // log(a)(b)(c) ``` -Now we can easily make a convenience function for current logs: +اکنون می توانیم به راحتی یک فانکشن سادهتر برای لاگ های کنونی ایجاد کنیم: ```js -// logNow will be the partial of log with fixed first argument +// جزئی از لاگ با آرگومان اول ثابت خواهد بود let logNow = log(new Date()); -// use it +// استفاده از آن logNow("INFO", "message"); // [HH:mm] INFO message ``` -Now `logNow` is `log` with fixed first argument, in other words "partially applied function" or "partial" for short. +حالا `log` یک نسخه از فانکشن `logNow` است که آرگومان اول آن ثابت شده است. به عبارت دیگر "فانکشن جزئی اعمال شده" یا به اختصار "جزئی" است. -We can go further and make a convenience function for current debug logs: +میتوانیم جلوتر برویم و یک فانکشن برای لاگهای اشکال زدایی کنونی ایجاد کنیم: ```js let debugNow = logNow("DEBUG"); @@ -105,15 +105,15 @@ let debugNow = logNow("DEBUG"); debugNow("message"); // [HH:mm] DEBUG message ``` -So: -1. We didn't lose anything after currying: `log` is still callable normally. -2. We can easily generate partial functions such as for today's logs. +بنابراین: +1. ما چیزی را بعد از کاری کردن از دست ندادیم: `لاگ` هنوز به شکل عادی قابل فراخوانی است. +2. همچنین به راحتی میتوانیم فانکشنهای جزئی مانند لاگهای امروزی را ایجاد کنیم. -## Advanced curry implementation +## پیاده سازی پیشرفته کاری -In case you'd like to get in to the details, here's the "advanced" curry implementation for multi-argument functions that we could use above. +در صورتی که مایلید وارد جزئیات شوید، اینجا پیاده سازی "پیشرفته" کاری برای فانکشن های دارای چند آرگومانه آمده است که میتوانیم در بالا استفاده کنیم. -It's pretty short: +این پیاده سازی بسیار کوتاه است: ```js function curry(func) { @@ -131,7 +131,7 @@ function curry(func) { } ``` -Usage examples: +نمونه های استفاده: ```js function sum(a, b, c) { @@ -140,17 +140,17 @@ function sum(a, b, c) { let curriedSum = curry(sum); -alert( curriedSum(1, 2, 3) ); // 6, still callable normally -alert( curriedSum(1)(2,3) ); // 6, currying of 1st arg -alert( curriedSum(1)(2)(3) ); // 6, full currying +alert( curriedSum(1, 2, 3) ); // هنوز به شکل عادی قابل فراخوانی است، 6 +alert( curriedSum(1)(2,3) ); // کاری کردن آرگومان اول، 6 +alert( curriedSum(1)(2)(3) ); // کاری کردن کامل، 6 ``` -The new `curry` may look complicated, but it's actually easy to understand. - -The result of `curry(func)` call is the wrapper `curried` that looks like this: + `کاری` جدید ممکن است به نظر پیچیده بیاید، اما در واقع درک آن آسان است. + +نتیجه فراخوانی `curry(func)` بسته بندی `curried` است که به این شکل است: ```js -// func is the function to transform +// func فانکشن برای تبدیل است function curried(...args) { if (args.length >= func.length) { // (1) return func.apply(this, args); @@ -161,28 +161,29 @@ function curried(...args) { } }; ``` +