استفاده از فانکشن یا شرط در الکسیر؟

درود خدمت دوستان . من هرچی تلاش کردم تیتر مناسب پیدا کنم پیدا نشد .
خوب در الکسیر می شه چندبار یک اسم فانکشن نوشت با حالت های مختلف و با when بهش شرط یا کنترلر یا هرچیزی داد

خوب به نظر شما ( برای موارد عمومی ) آیا یک if بهتر هست در داخل یک فانکشن یا نوشتن چندین حالت از یک فانکشن ؟
کدام منطقی تر و سرعت بیشتری داره

چون برخی موارد همین موضوع نوشتن چندین فانکشن کد های تکراری رو نیز افزاریش می ده

تشکر

1 پسندیده

هر وقت میتونی ازپترن مچینگ بجای if استفاده کن چون فانکشن جدا راحت تر تست و ترکیب میشه

1 پسندیده

تشکر از شما پس اولویت اینکه

اول فانکشن های جدا
و بجای if هم تا هرجا می تونم پترن بزنم درسته ؟ ببخشید زیاد سوال می کنم فقط برای اینکه کامل تایید بگیرم . چون فکر می کردم فانکشن جدا یعنی یک بلاک کد اضافه و باعث سنگین شدن فایل

1 پسندیده

if به مراتب بد تر هست برای سنگینی درک کد. حجم فایل امروزه اصلا مهم نیست من پیشنهاد میکنم همیشه به خوانا تر بودن و تغییر پذیری کد فکرکنید

در مورد if و درک کد یک مطلبی هست به اسم cyclomatic complexity که نشان داده شده هرچه شرط ها بیشتر میشه و لایه ها زیاد میشه درک از کد. کمتر

2 پسندیده

منظور شما از زدن پترن چيه؟

پترن ماچینگ ( حالا انگلیسیش یا فارسیش :smiley: شر شده باید یک نمونه فارسی براش خوب می بود )

در فارسى ميگن تطبیق الگو،
اما منظور من استفاده از واژه نبود، منظور شما رو از پترن زدن متوجه نشدم

2 پسندیده

درود خدمت شما

منظور من یا چیزی که از صحبت دوست خوبمون @samdvr فهمیدم این بود

case Rsvp.EventQueries.create changeset do
		   {:ok , %{id: id}} -> redirect conn, to: event_path(conn, :show, id)
		   {:error, reasons} -> create conn, %{errors: reasons}
end

و از فانکشن هم به صورت زیر بود

defp get_error(comparison) when comparison == :lt do
		[date: "cant be in the past"]
end

و منظورم از if هم به این صورت بود مثلا ( البته داخل یک فانکشن )

if  do
		  
end

الان گفتی کمی شک کردم شاید منظور @samdvr رو بد گرفتم . خوب شد اشاره کردید

تشکر

1 پسندیده

اتفاقا جذابیت الکسیر تو این چیزاست و فکر کنم برای تحمل نقص بالا این چیزا رو داخلش گذاشتن

1 پسندیده

اما اينها تقريبا توى بيشتر زبان ها وجود داره

1 پسندیده

من ندیدم بخصوص when رو و خیلی دوستش دارم.

fn x when is_string x -> “hello”<> x end
این when علت اصلی طراحیش چیه ؟
میتونه همون تحمل نقص بالا باشه دلیلش ؟
با وجود when برای چی if هست ؟
من احساس میکنم برنامه نویسی تابعی یا همون functional سعی میکنه رفتارش دقیقا عین توابع ریاضی باشه مثلا همونطور ک تو تابع فاکتوریل دبیرستان دوتا تابع داشتیم که یکیش برا مقدار صفر بود
https://wikimedia.org/api/rest_v1/media/math/render/svg/7eb17fd64147561f02165c1bec4e388b72bab88d
در فانکشنال هم با when میخواد که همون مدل سازی ریاضی رو برا توابع انجام بدیم و برای حالت های مختلف نتیجه های پیش بینی شده داشته باشیم

when براى اينه كه بر اساس يك سرى از شرايط تست و مقايسه انجام بشه.
هيچ كدوم نبايد بيش از حد استفاده بشوند،
لينك زير خوب توضيح داده
https://www.quora.com/What-is-the-difference-between-switch-and-if-else-statements-Which-is-better-in-different-cases-Why

و

1 پسندیده

ممنون قشنگ بودند لینک ها ، البته اینطوری بهتره بنظرم که فقط یه if نباشه ادم احساس کسلی نمیکنه البته به ذکر شما هرکدوم موارد استفاده خودشون رو دارند که انشالله یه روزی به اون سطحم برسم که هرکدوم رو تو جای مناسب خودش استفاده کنم

1 پسندیده

دوستان من یک پست داخل استک پیدا کردم . دقیقا متوجه نشدم یک جا می گه خوبه یک جا می گه سناریو بدی هست

اگر شما متوجه شدید لطفا راهنمایی فرمایید که واقعا when با چندتا فانکشن بهتره یا از شرط هایی مثل ifelse ?
البته دوست خوبمون @samdvr عزیز مثل همیشه توضیحاتی دادند ولی باز من تو کار شکم زیاد شده

کدوم مورد باید در کجا انتخاب بشه و استفاده بشه ؟

همون طور که Jose توضیح داده اکثرا pattern matching سریع تره با BigO log2N چون pattern ها در درخت binary ذخیره میشن به غیر از گارد ها که BigO N دارند

تمام if else ها BigO N دارند در نتیجه pattern matching اکثرا سریع تر و دربدترین صورت هم سرعت با ifelse هستند

1 پسندیده

درود خدمت شما . گارد منظور مثل when هست درسته ؟
پترن ماچین ها هم مثل case داخلش استفاده می کنیم درسته ؟

خیلی تو آموزش ها از when استفاده می کنند و چندین تابع

و یک سوال دارم خدمتتون . اینکه چطور یک برنامه رو می تونیم از نظر سرعت و همینطور اینکه کجا باعث می گردد سرعت و کارایی کم شود تست و آنالیز بکنیم ؟
مثلا بنده یک بار برنامه رو با ifelse بنویسم یک بار یک چیز دیگه . آیا کدی یا برنامه ای برای این مورد وجود دارد ؟
چون ممکن هست مثلا این برنامه ها کاربران مجازی ای ایجاد کنند و به برنامه فشار بیارند نمی دونم هرچیزی که در همین رابطه هست ؟

ببخشید سوالام زیاد شد
تشکر ویژه از شما دوست محترم و همیشه کمک حال تازه واردین به برنامه نویسی

گارد منظور مثل when هست درسته ؟ بله
پترن ماچین با گارد

defmodule User do
  defstruct age: 0
end

defmodule Greeting do
  def greet(%{age: age}) when 6 < age and age < 12, do: "Hiya"
  def greet(%{age: age}) when 12 < age and age < 18, do: "Whatever"
  def greet(%{age: age}) when 60 < age, do: "You kids get off my lawn"
  def greet(_), do: "Hello"
end

پترن ماچین معمولی

{:ok, result} = {:ok, 13}

شما برای آنالیز و تست میتونید از ابزار benchmarking استفاده کنید

1 پسندیده

سلام خدمت اساتید گرامی
من با توجه به لینک هایی که دوستان دادن و مطالبی که توی داکیومنت الکسیر نوشته بود . تقریبا به این نتیجه رسیدم که اگر جایی یک شرط داشتیم استفاده از if بهتر هست البته طبق چیزی که خودش گفته
Elixir also provides the macros if/2 and unless/2 which are useful when you need to check for only one condition
با این حال هر جا بشه پتر ماچین استفاده میکنم تا بهترین performance رو داشته باشم توی برنامه
این benchfella رو هم تست کردم البته با کدهایی که خودش داشت ولی موفق نشدم به درستی برای کد های زیر تست بکنم

defmodule Test    Bench do
            use Benchfella 
            import IO, only: [puts: 1]

    def mytest(msg, n) when n <= 1 do
        puts msg
    end
    
    def mytest(msg ,n) do
        puts msg
        mytest(msg, n-1)
    end

    bench "Test" do
        mytest("aa",3)
    end
end

خروجی تست میده ولی توی حلقه بی نهایت میمونه . حتی از شرط هم استفاده کردم به غیر از پترن ماچین به صورت زیر

def test2(msg , n) do
        if(n == 1) do
            puts msg
        else
            puts msg
            test2(msg, n-1)
        end
    end

bench "Test" do
        test2("aa",3)
    end

ولی نتیجه تست همون میشه . در صورتیکه با توجه به توابع نباید توی حلقه گیر بکنه . نمیدونم کجا کار مشکل داره . منتظر نظرات دوستان هستم .

Finished in 2.99 seconds

## Bench
benchmark name iterations   average time
Pattern Match      100000   12.30 µs/op
Conditional        100000   14.86 µs/op

اینم کدش

 defmodule Bench do
  use Benchfella 
  import IO, only: [puts: 1]
  
  def pattern_match(msg, 1) do
    puts msg
  end
  
  def pattern_match(msg ,n) do
    puts msg
    pattern_match(msg, n-1)
  end

  bench "Pattern Match" do
    pattern_match("aa",3)
  end

  def conditional(msg , n) do
    if(n == 1) do
      puts msg
    else
      puts msg
      conditional(msg, n-1)
    end
  end

  bench "Conditional" do
    conditional("aa",3)
  end
end

در دوحالت انقدر این تست ها بهم نزدیک هستند که گاهی conditional سریع تره گاهی pattern matching برای تست بهتر به هرکدوم تعداد زیادی شرط اضافه کن که فرقشون واضح بشه مثلا ۱۰ شرط در هردوحالت

2 پسندیده