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 type

true :: BoolCPS r -- data constructor
true forTrue forFalse = forTrue
-- = const
false :: BoolCPS r -- data constructor
false forTrue forFalse = forFalse
-- = flip const

ifThenElse :: 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)

不用過多關注bool類型的構造,現在假設已經有了bool,true和false相關定義,直接模式匹配

newif :: Bool -&> a -&> a -&> a
newif True consequence _ = consequence
newif False _ alternative = alternative

反正Haskell也是惰性求值的,不存在consequence和alternative同時求值問題(絕望)


ifThenElse : Bool -&> A -&> A -&> A
ifThenElse = case
True -&> const
False -&> flip const


IF =
-&> b {
-&> x {
-&> y {
b[x][y]
}
}
}

Programming with Nothing?

codon.com

對應的中文翻譯書

計算的本質 (豆瓣)?

book.douban.com圖標

編程啥的只要函數就夠了

或者微軟的channel9上有個關於js的,只是沒上面的學術化,有些用了js的技巧

Funky Functions by Spencer Jobe?

channel9.msdn.com圖標

Python

用 list 的 index,True 和 False 被轉化為1和0

exec([do_if_false(), do_if_true()][statement])

還有用try:

try:
1 / (if_statement)
except ZeroDivisionError:
do_if_false()
else:
do_if_true()

實現if太low了,還有更高級的:

只用整數(布爾),浮點數,字元串,exec和eval函數實現一切功能

比如實現 for 循環:

var = i # for變數名稱
from_ = 0 # 變數初始值
to = 10 # 變數最終值
# for循環內部
do_what =
"""
print(i)
"""

empty__ =
is_condition = f"""
x = {var} == {to}
exec(eval(do_whatempty__[x * 7: (x+1)*7]))"""
do_what = do_what + f"""
{var} += 1
exec(is_condition)"""
exec(f"{var} = {from_}")
exec(is_condition)


會React的同學,條件渲染知道吧?

Inline If with Logical Operator

function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
&
&

Hello!&

{unreadMessages.length &> 0
&

You have {unreadMessages.length} unread messages.
&

}
&

相关文章