JavaScript 的分號,以及 ASI (Automatic Semicolon Insertion)

目前 community 的主流跟我理出來的期望不一樣... 所以記錄一下。

先提一下背景,在 JavaScript 程式語言裡面,在大多數的情境下是可以省略掉分號 (;) 的,也就是說這兩種寫法都是合法的 JavaScript 語法:

console.log('Hello, world.')
console.log('Hello, world.');

這是因為在 ECMA-262 裡面有 ASI (Automatic Semicolon Insertion) 的設計:「Automatic Semicolon Insertion」。

ASI 設計本身是好的,可以讓開發者少處理 ;,但偏偏 EMCA-262 又允許千變萬化的換行,於是就造成了各種奇怪的現象。

因此早期在 community 上都是推薦無條件加上分號,這可以避免各種奇怪的 bug 與 error,像是「Do you recommend using semicolons after every statement in JavaScript?」以及「Should I use semicolons in JavaScript?」這些問答。

大家會推薦加上分號主要的原因是因為,不加上分號遇到的 error 與 bug 不是那種你知道很雷,所以會主動查詢 & 避開的問題:

而是各種平常寫就會遇到的情況,最容易中獎的是第二組敘述是 ([ 開頭的,像是 ECMA-262 文件裡面提到的 case 就算常見了:

a = b + c
(d + e).print()

// 等價於:
a = b + c(d + e).print();

而且不因為註解受到影響:

// blahblah
a = b + c

// blahblah
(d + e).print()

// 還是等價於:
a = b + c(d + e).print();

另外一個常見的情況是我們會利用 anonymous function 包出一個 block,避免變數污染到外面:

// I want to do blahblahblah...
(() => {
  const a = '';
  // ...
})()

// I want to do another blahblahblah...
(() => {
  const a = '';
  // ...
})()

大多數的情況應該會 error,除非第一個 anonymous function 傳回一個 callable,而這種情況跑出來的結果就更慘了...

另外這種 case 也是常見的情況:

// ...
[1, 2, 3].forEach(...)

// ...
[4, 5, 6].forEach(...)

// 等價於:
[1, 2, 3].forEach(...)[4, 5, 6].forEach(...)

這邊省略分號最大的問題是你無法知道「自己這行需不需要加上分號」,因為註解可能很長有個 30 行,所以依照這些現況,比較好的方法應該是全部加上分號,保持一致性。

但這幾年所有的 frontend framework 都是推動拿掉分號,這可以從各家的文件看到,就搞不懂 community 是怎麼推導出來的... 在全部都拿掉分號的情況下,遇到上面的情況就得寫成不一致的 style:

// ...
[1, 2, 3].forEach(...);

// ...
[4, 5, 6].forEach(...)

查了目前可行的 workaround,大多都是透過 ESLint 類的工具來擋可能會出現 bug 的地方,也只能先這樣做了...

搞爆 Python 的各種姿勢

Hacker News 首頁上看到「no-op statements syntactically valid only since Python X.Y」這個專案,搞爆各個版本 Python 的各種方式,從 Python 2.4+ 一路到 3.11+ (不過中間有少了 3.2 與 3.4)。

專案要求的條件是 no-op,所以像是 import 這種行為都會產生 side effect,所以就不能用 sys.version_info 這個變數了:

This is a collection of no-op statements that are syntactically valid only since Python X.Y, for most X.Y ≥ 2.4.

看了一下裡面的例子,反而看到一些有趣的東西,像是原來這種語法在 Python 2.3 是不能跑的:

(0 for x in [])  # Python >= 2.4 is required

然後 0_0 這種方便表示數字的寫法在 Python 3.6+ 才能動:

0_0  # Python >= 3.6 is required

有些東西真的是用習慣就忘記了,遇到一些古董環境可能會中獎然後在那邊疑惑半天 XD

看起來這個專案應該比較偏娛樂性質?實際應用上有很多其他比較常見的方式檢查環境才對 XD 但馬上想到,在打黑箱的時候可以用這個方法判斷 Python 的環境版本?

換到 vim-polyglot 上...

在「A guide to setting up Vim for JavaScript development」這邊看到可以用 sheerun/vim-polyglot 吃多種語言:

Vim supports basic syntax highlighting for JavaScript but I found it suboptimal especially when it comes to modern ES2015+ syntax, and it doesn’t support JSX when working with React. I found that vim-javascript and vim-jsx solved my problems in both instances.

However, I later replaced those two with vim-polyglot which is a plugin that bundles several other syntax plugins for over 100 languages, and loads them on demand so that performance is not affected.

先前遇到新的語言就得去找新的 plugin 加,現在看起來可以用一套吃遍天下 (只要一直更新),換過去後先短暫的測了一下,沒什麼大問題...

YAML 的痛點

Changelog 上看到「In defense of YAML」這篇講 YAML 的問題,裡面是引用「In Defense of YAML」這篇文章。

未必全盤接受文章裡面的說法,但裡面提到的兩個點的確是痛點,第一個是空白 (或者說 indent),第二格式特殊語法。這兩個是用 YAML 時都很頭痛的問題:

Whitespace is a minefield. Its syntax is surprisingly complex.

就像 JavaScript 的 == 一樣 (我指的是之前寫的「JavaScript 的 == 條列式比較」這篇),你可以把定義背下來,但你會覺得沒什麼道理可言而有種無奈的感覺...

文章裡也有提到 JSON 內沒有 comment 的設計的確是用起來比較無奈的地方...

SQLite 的 CLI 操作工具 litecli

之前應該都是用 SQLite 提供的 cli 操作,現在有人提供支援 auto completion 與顏色的 cli 軟體了:「CLI for SQLite Databases with auto-completion and syntax highlighting」。

工具是用 Python 寫的,可以直接用 pip 安裝。

對投影片的程式碼加上色彩

在「Syntax highlighting in presentations」這邊用了一些迂迴一點的方法來加上色彩:

pygmentize -O style=xcode -o output.rtf input.js

這邊介紹的方式是用 Pygments 把程式碼轉成 rtf,然後再 copy & paste 貼到投影片上,有點硬但還算 okay 的方案吧...

Go 上面的白箱安全性檢查

HP 的 open source 專案「Go AST Scanner」,分析 Go 的原始程式碼拉出 AST 進行分析 (Static program analysis),再找出可能的安全性問題。

雖然是 alpha 階段,但看起來是個好東西啊... 至少寫的太誇張的 SQL injection 可以掃出來。

CPAN 官方支援 Syntax Highlighter...

剛剛看到 CPAN 網站上直接由官方支援 Syntax Highlighter:Syntax highlighting for search.cpan.org,雖然目前的 UI 做的並不太好 (選擇 theme 的選擇條應該是上下都要有,目前只有最下方),但仍然是進步不少...

之前的 Greasemonkey script 在 Firefox 4.0 上爛掉 (因為 async loading 的關係),本來還在想要怎麼處理,現在看起來就用官方提供的就好了...

將 search.cpan.org 的 source 部份加上 SyntaxHighlighter

在「CPAN 的 Greasemonkey 工具…」這邊提到打算寫一個 Greasemonkey script,將 CPAN 上面的 source code 部份加上 syntax highlight,因為有不少現成的 Highlighter 是 javascript-based,所以程式只要套一套就可以了...

Greasemonkey 的程式在這:「CPAN Syntax Highlight」。

使用前:

使用後: