賦值算符的方向

作者:   發佈於:   #coding #rakulang

先參考這影片: https://youtu.be/g8xXrhjqOZM

在這 2017 年 The Perl Conference Amsterdam 的演講中,於 19:04 處,Damian Conway 開始描述這個重複出現的 code pattern (Raku 語。當時仍名為 Perl 6):

@tape[$head] = .<write> if defined .<write>;
$state       = .<state> if defined .<state>;

這個 .<write> 語法是從名爲 $_ 的 HashMap 把對應到 "write" 的值取出來的意思。

這兩行則是在意圖要描述「在某個值為不為未定義時,才將某個值存到某變數中」。這個代表「某個值」的算式必須在同一行陳述裡面出現兩次。是重複出現的。

接着他以定義新算符 ?= 的手法,將其重構為:

sub infix:< ?= > ($lval is rw, $rval) { $lval = $rval if defined $rval; }

@tape[$head] ?= .<write>;
$state       ?= .<state>;

關於這個 ?= 算符,雖然這符號的外觀有點像是 js / kotlin 中的 safe-navigation ?.,但兩相比較起來,?. 的測試對象在其左方,而 ?= 的測試對象是在其右方,也就是算式的閱讀方向正好相反。有點像是主語位置變到句尾去的感覺。但對於已經習慣 ?. 語意的人而言可能要稍微花時間適應一下。

一般來說賦值算符算式的方向都是從右到左。計算右邊的算式所得到的值,會被存到左邊的變數內。但例如 TI-BASIC 這程式語言,其賦值算式是從要左至右讀的:

42 → A
A + 1 → B

在 Raku 語,可自行定義新算符來實做出這種方向是自左至右的算算符。例如以下的 assign-to

sub infix:< assign-to > ($lval, $rval is rw ){ $rval = $lval }

42 assign-to $a;

say $a; #=> 42

那麼基於類似概念而定義出來的 ?assign-to 算符,在閱讀方向上就與 safe-navigation 相同了

sub infix:< ?assign-to > ($lval, $rval is rw ) { $rval = $lval if defined $lval }

$a ?assign-to $b;

如果要去把「$a ?assign-to $b」這一句給唸出來的話,就類似:

$a 的內容如果不是未定義的話,就存到 $b 裡面

或許對於已經讀慣 safe-navigation 的人而言,是一種比較親切的 code pattern。