Lazy Evaluation And Short Circuiting

Wai Lin Kyaw
2 min readJan 20, 2021

Lazy evaluation ပေးတဲ့ language တွေမှာ short circuiting ကို ဘာကြောင့် free ရလဲ။ နောက် အခုသုံးနေတဲ့ Traditional Languages တွေ ဆိုလိုတာက strict evaluation လုပ်တဲ့ languages တွေမှာ expression တွေကို ဘယ်လိုရှင်းလဲဆိုတာရယ်၊ ဘာဖြစ်လို့ short circuit ကို language level မှာ support လုပ်ရသလဲဆိုတာ ပြောမှာပါ။

Short circuiting ကိုမပြောခင် expression evaluation ကိုအရင်ကြည့်ကြည့်မယ်။ evaluation အရကြည့်ရင် language တွေမှာ strict evaluation ရယ် non-strict evaluation ရယ်ဆိုပြီးတော့ နှစ်မျိုး ခွဲလို့ရတယ်။

isOdd ( 1 + 2 )

ဒီ code မျိုးဆိုရင် ဥပမာ Java တို့၊ JavaScript တို့၊ နောက်တစ်ခြား C-like language အများစုမှာ function ( or method ) ကို applied မလုပ်ခင် argument တွေကိုအရင်ရှင်းတယ်။ ဒီမှာဆို 1 + 2 ကိုအရင်ရှင်းမယ်။ ရလာတဲ့ 3 ကို isOdd ကိုပေးပြီး isOdd ရဲ့ function body ကိုရှင်းမယ်။ ဒါက strict evaluation လုပ်တဲ့ language တွေမှာပြောတာ။ eager evaluation လို့လည်းခေါ်တယ်။ တိုက်ရိုက်တော့ မတူဘူး။ တစ်ချို့ eager languages တွေမှာ laziness ရအောင် ထိန်းလို့ရတာရှိတယ်။ JavaScript မှာဆိုရင် laziness ‌ရ‌အောင် thunk တစ်ခုနဲ့ wrap လုပ်ပြီး သုံးတာမျိုး လုပ်လို့ရတယ်။ တခြား language တွေမှာလည်း ပုံစံအမျိုးမျိုးနဲ့ ရှိတယ်။

နောက် non-strict evaluation languages တွေရှိတယ်။ အဲ့ဒီ languages တွေမှာကျတော့ value ကို တကယ်လိုတဲ့ အချိန်ကျမှ expression ကို evaluate လုပ်မှာ။ ဥပမာ Haskell နဲ့ပေါ့

isOdd n = mod n 2 == 1

isOdd ( 1 + 2 )

Haskell လိုမျိုး non-strict evaluation နဲ့သွားတဲ့ language တွေမှာကျတော့ isOdd ကို argument ( 1 + 2 ) ပေးလိုက်ပေမဲ့ ချက်ချင်း evaluate လုပ်ပြီး 3 ဖြစ်သွားတာမျိုး မဟုတ်ဘူး။ 1 + 2 ကိုတကယ် မသုံးသ၍ မရှင်းသေးဘူးဆိုတဲ့သဘော။ ဒီကနေမှ mod (1+2) 2 ဆိုပြီးဖြစ်သွားမယ်။ ပြောရရင် parameter ကိုသုံးထားတဲ့ နေရာတွေမှာ ဝင်လာတဲ့ argument ( expression ဖြစ်မယ်ဆိုရင် ) ကို evaluate မလုပ်ပဲနဲ့ expression အတိုင်း အစားထိုး လိုက်တာလို့ မြင်ကြည့်လို့ရတယ်။ ခုနက evaluate မလုပ်ရသေးတဲ့ expressions တွေကို thunk လို့ခေါ်တယ်။ non-strict evaluation ကို lazy evaluation လို့လည်းခေါ်ကြတယ်။ အပေါ်မှာပြောခဲ့ သလိုပဲ တိုက်ရိုက်တော့ ထပ်တူမကျဘူးပေါ့။ lazy evaluation နဲ့ non-strict evaluation မှာ ကွဲတာတွေရှိတယ်။ ဒီမှာတော့ အသေးစိတ် ရှင်းမပြတော့ပါဘူး။

Short Circuiting

&& || ? အစရှိတဲ့ Operators ( မြင်သာအောင် ပြောတာ language နဲ့လည်း ဆိုင်ပါသေးတယ် ) တွေမှာ && ဆိုရင် operand နှစ်ခုလုံး true ဖြစ်မှ အဖြေက true ရမှာ။ တစ်ခုက false ဖြစ်တာနဲ့ false ပဲရမယ်။ || မှာလည်း အလားတူပဲ။ ဒီတော့ ပထမ operand တစ်ခုနဲ့တင်အဖြေရနိုင်ရင် ဒုတိယ operand ကို ဆက်မရှင်းဘူး evaluate မလုပ်ဘူးပေါ့။ ဒီတော့ ခုနက eager evaluation language တွေမှာကျတော့ language level မှာတည်းက special implementation တွေနဲ့ short circuit evaluation ကို support လုပ်ရတယ်။ ဒီနေရာမှာ eager evaluation နဲ့သွားလို့မရဘူး။

နောက် သက်ဆိုင်ရာ languages တွေမှာ operators တွေကို ဘယ်လို ထပ်ခွဲလို့ရလဲဆိုတော့ ခုနက short circuit operators တွေရယ်၊ နောက်ထပ် eager operators တွေရယ်ဆိုပြီး ခွဲလို့ရတယ်။ ဥပမာ Kotlin မှာဆိုရင် && || ဒီနှစ်ခုက short circuit operators တွေ၊ ‌နောက် and နဲ့ or ကျတော့ eager operators တွေလို့ပြောလို့ရတယ်။ short circuiting မဖြစ်ဘူးပေါ့။

Haskell လို lazy evaluation ရတဲ့ language တွေမှာကျတော့ short circuiting ကိုတကူးတက special implementation တွေနဲ့ support လုပ်စရာမလိုဘူး။ lazy evaluation ရဲ့အားသာချက် အရ short circuiting ကို free ရသွားတယ်ပေါ့။ ဥပမာ အနေနဲ့ short circuiting လုပ်တဲ့ function တစ်ခုကို ဒီလိုကိုယ်တိုင် ရေးလိုက်လို့ရတယ်။

myAnd a b = if not a then a else b

lazy evaluation တွေမှာက ဘယ် operations ကအရင် ဘယ်ဟာကနောက်မှ ဖြစ်မယ်ဆိုတဲ့ order ကိုကြိုသိဖို့ခက်တယ်။ အဲ့တာကြောင့်ပဲ imperative language တွေနဲ့ သိပ်မကိုက်တာပါ။

--

--