怎麼編程實現if,不使用if關鍵字? Hello!&
true = λ a. λ b. a
false = λ a. λ b. b
if = λ a. λ b. λ c. a(b)(c)
我來個low很多的版本。
[ function_point1, function_point2] [ (num &> 2) as usize ] ()
其實就是強轉bool為索引,然後對長度為2的數組內元素做選擇。
題外話:
這個是我從Rust 標準庫看到的類似用法,目前Rust 的const fn(類似於C++的constexpr)不支持if,於是想寫成const fn,保證編譯時求值,只能用這種扭曲的做法。
before:
if (Fuck fuck = shit; g(fuck))
{
DoSomething(Fuck); // 馬化騰說了,縮進幺三個空格
}
else
{
DoSomethingElse(fuck);
}after:
{
Fuck fuck = shit;
function& branches[2] =
{
[](){DoSomething(Fuck);},
[](){DoSomethingElse(Fuck);}
};
branches[(int)g(fuck)]();
}超容易的
1、如果是C的話可以利用函數指針+數組。有閉包的語言也可以用閉包+數組:
int consq() {/*...*/}
int alt() {/*...*/}int main() {
int (*branch[2])() = {consq, alt};
branch[0]();
/*
&<=&>
if (0) {
consq();
} else {
alt();
}
&<=&> 0?consq():alt();
*/
return 0;
}這個可以做多分支的派分哦。
2、在java里可以用上Visitor Pattern:
interface BoolVisitors& {
R forTrue();
R forFalse();
}abstract class Bool {
public abstract & R accept(BoolVisitors& extends R&> v);public static Bool True() {
return new True();
}
public static Bool False() {
return new False();
}
}final class True extends Bool {
public & R accept(BoolVisitors& extends R&> v) {
return v.forTrue(); //用Visitor訪問私有欄位value,並進行變換
}
}final class False extends Bool {
public & R accept(BoolVisitors& extends R&> v) {
return v.forFalse();
}
}/*
if (true) { f(); } else { g(); }
&<=&>
Bool.True().accept(new BoolVisitors&() {
public R forTrue() { return f(); }
public R forFalse() { return g(); }
});
*/當然這個也可以做類似模式匹配的事情。
3、CPS(Scott encoding)
type BoolCPS r =
r -&> -- forTrue
r -&> -- forFalse
-&> r -- return typetrue :: BoolCPS r -- data constructor
true forTrue forFalse = forTrue
-- = const
false :: BoolCPS r -- data constructor
false forTrue forFalse = forFalse
-- = flip constifThenElse :: BoolCPS (() -&> r) -&> (() -&> r) -&> (() -&> r) -&> r
ifThenElse cond consq alt = cond consq alt ()
-- 假設是嚴格求值的關於後兩個可以看看:
Xyzt Toe:Java筆記:Visitor Pattern與模式匹配與CPS變換(霧)?zhuanlan.zhihu.com當然用和||可以實現單分支的if,已經有其它答主回答了。反過來也可以用if來實現和||,留做作業。
然後,我上面提到的方法都是有運行時開銷的,都基本是模擬了一遍惰性求值。總之就只有原來的if then else是最好的。
方法很多,比如對於用if的這樣的代碼
if (a === 1) {
// do something
}可以用三元運算符:
(a === 1) ? (() =&> {/* do something */ })(): null;
也可以用:
(a === 1) (() =&> {/* do something */ })();
或者:
const handler = {
1: () =&> {/* do something */}
}
handler[a] handler[a]();都是奇技淫巧,如果條件分支里有多條語句,還是老老實實用if吧。
許多人都沒有答在點上,其實彙編就可以不用 test/jmp 實現 if 的邏輯。
大致思路就是:
假設 x 是一個 bool,且取值為 0 或 1,將其乘以一個地址,然後加 1,再加當前 ip,然後 mov 給 ip 即可。
全程只需要數學運算。
擴展閱讀:https://news.ycombinator.com/item?id=9751312
把bool類型作為一個union type然後進行模式匹配執行對應語句。比如Luca Cardelli的總結
Type Systems
給出的一個封裝實現bool類型相應方法cond(其實就是if)