阅读视图

发现新文章,点击刷新页面。
🔲 ⭐

开始读《异见时刻》

打算开始读《异见时刻:“声名狼藉” 的金斯伯格大法官》。这是一本前美国最高法院大法官 Ruth Bader Ginsburg (RBG) 的传记。RBG 是美国最高法院第二位女性大法官。最开始听说 RBG 是在詹青云做客鲁豫的一集播客中(岩中花述 S5E1,03/12/2024)。当时好像正好是在 DC 市里面逛,听到 RBG 的墓就在 arlington national cemetary,本来打算去看看的,结果当时比较晚了就没去。当然后来有时间就去瞻仰了一下 RBG 和她丈夫的墓。

Grave of RBG and her husband

当时听播客的时候有一个点我印象很深,就是阿詹说 RBG 是一个相信慢慢努力的人。因为法律的改变是非常缓慢的,她不会去想着一定要做那些有着划时代意义的大案子,而是一点点地搭建人们对男女不应该区别对待的认知。当 RBG 处在一个保守派占多数的最高法院的时候,她会努力去和保守派法官妥协,就算放弃自己意见中的一些激进的部分,也要去争取保守派的票从而赢得这个 case。在她发现无法胜利的时候,她仍然会站出来并更加努力地表达自己 “I dissent” 的态度,尽管当时的判决并不会改变。这种精神虽然不会在现实中有立即的作用,但也是非常有价值的。比如她在 Ledbetter v. Goodyear Tire & Rubber Co. 案的反对意见1中建议国会立法推翻最高法院的决定,结果在奥巴马当选总统之后就实现了。

正好我最近突然意识到我自己其实就是处在一个 “无法接受微小的进步” 的状态里。很多时候需要去做一些细枝末节的事情,但是我在做的时候会没有意义感,从而无法专心做事。说来我意识到我处在这个状态也是从金刚经中的 “应无所住而生其心” 来的。当时听王德峰讲六祖惠能和神秀的偈句的不2,一时间突然意识到我和神秀犯的错误其实是一样的:就是沉浸在小乘佛教的自了汉的境界中了。而要达到大乘菩萨的境界,是需要在现实世界中产生影响,去帮助具体的人,做具体的事的。如果 RBG 只在小乘佛教的境界中,她大可以在一些 5 比 4 的判决中拒绝和保守派的法官妥协,就说我自己坚持了自己的原则,但是以案子的失败作为代价。虽然这样做自己的 “心” 没有 “惹尘埃”,但是除了显得自己境界高没有任何现实的作用。我们意识到万物皆性空之后不能执着于空。

这两周看阿詹和阿庞的直播的时候又重新听到了她们对《异见时刻》的推荐。希望能从书中得到一些来自 RBG 的智慧和 inspiration。


  1. https://supreme.justia.com/cases/federal/us/550/618/ 

  2. https://www.bilibili.com/video/BV1Mu411Z7eN/ 

☑️ ⭐

关于基于表达式的编程语言的一些思考

最近学 Go 语言又想起之前看过的一个 talk,presenter 说他几乎不用 else 关键字。因为一般情况下,if 语句的其中一个 branch 会比较短(比如处理特殊情况),这样可以在这个 branch 结束后直接从函数返回,后续的代码就不需要进行缩进了,如

func fact(n int) int {
    if n <= 1 {
        return 1
    }
    // no extra indent here!
    return fact(n - 1) * n
}

可以减少缩进当然是件好事。如果后续代码很长可以采用这种风格。但我觉得并不是所有的情况都适用于这种写法。相比之下我更喜欢这样的写法

int fact(int n) {
    return n <= 1 ? 1 : fact(n - 1) * n;
}

或者使用 else

fn fact(n: i32) -> i32 {
    if n <= 1 {
        1
    } else {
        fact(n - 1) * n
    }
}

Go 语言里没有三目运算符,因为语言设计者认为滥用三目运算符可能会降低可读性 1。三目运算符的可读性确实没有 if 语句高,但是问题的核心其实不在三目运算符。三目运算符的鼻祖 C 需要它是因为 C 的 if 语句不是一个表达式,所以需要一个新的语法来表示 if 表达式。相比很多语言就不需要三目运算符,因为它们的 if 本身就是一个表达式。同时 if 语句的可读性也比三目运算符高不少,用 else if 再添加几个 branch 也不会降低可读性。

对我来说基于表达式可以让代码更容易理解。在理解一个基于表达式的程序时,我们可以自底向上地学习程序,从小的表达式开始理解,再理解上级的表达式。如果表达式没有副作用,在学习了这个表达式之后就可以把它看作一个黑盒了。一般来说函数式的语言都会支持更多类型的表达式(如 if 表达式),函数式语言的宗旨之一也是通过组合无副作用的函数而实现更复杂的功能。

  1. go.dev 上的观点应该可以算是语言设计者的吧 https://go.dev/doc/faq#Does_Go_have_a_ternary_form 

☑️ ⭐

使用 bwrap 隔离 WPS Office

看到依云在 博客 中提到了非特权沙盒工具 bwrap。博客的结尾提到可以用它来跑一些不太干净的软件,便来配置一下 WPS Office。

WPS 目前(AUR 版本 11.1.0.10702-1)还有使用反斜杠作为文件路径分隔符的问题,不过没有影响到外部的观感,只是在 ~/.local/share/Kingsoft 内部。但是它每次运行都会在后台启动 wpscloudsvr 进程,可能和云同步有关吧,每次还要 kill 一下,有点麻烦。另外作为那种不得不使用的商业软件,还是感觉隔离一下舒服一些。

使用的 bwrap 命令修改自依云的博客。wrap-wps 脚本如下:

#!/bin/bash

# 根据扩展名选择对应的 WPS 程序
file=$1
case $file in
    *.doc | *.docx) exe=/usr/bin/wps ;;
    *.xls | *.xlsx) exe=/usr/bin/et ;;
    *.ppt | *.pptx) exe=/usr/bin/wpp ;;
    *) exe=/usr/bin/wps ;;
esac

binds=()
for dir in fontconfig gtk-2.0 gtk-3.0 mimeapps.list Kingsoft; do
    binds+=(--ro-bind ~/.config/"$dir" ~/.config/"$dir")
done

# bind mount 需要操作的文件
if [[ -f "$file" ]]; then
    path="$(realpath "$file")"
    binds+=(--bind "$path" "$path")
fi

exec bwrap --unshare-all --die-with-parent \
    --ro-bind / / \
    --tmpfs /sys --tmpfs /home --tmpfs /tmp --tmpfs /run --proc /proc --dev /dev \
    --ro-bind "$XDG_RUNTIME_DIR" "$XDG_RUNTIME_DIR" \
    --ro-bind /tmp/.X11-unix /tmp/.X11-unix \
    "${binds[@]}" \
    --ro-bind ~/Documents ~/Documents \
    --bind ~/tmp ~/tmp \
    "$exe" "$@"

可以在使用此脚本之前运行一下 wps,让它生成 ~/.config/Kingsoft,避免每次启动还要同意一下许可证。

再写一个 application 文件并配置上文件类型关联。把 /usr/share/applications/wps-office-prometheus.desktop 复制到 ~/.local/share/applications/wps-office-wrap.desktop,并把 Exec 的命令改成上面的 wrap-wpsInitialPreference 调成 99,把各个 WPS 程序的 MimeType 合并。如下

diff --git a/usr/share/applications/wps-office-prometheus.desktop b/home/wang/.local/share/applications/wps-office-wrap.desktop
index 820214f..87ab130 100644
--- a/usr/share/applications/wps-office-prometheus.desktop
+++ b/home/wang/.local/share/applications/wps-office-wrap.desktop
@@ -2,7 +2,8 @@
 Comment=Use WPS Writer to office work.
 Comment[zh_CN]=使用 WPS 2019进行办公
-Exec=/usr/bin/wps %F
+Exec=/home/wang/scripts/wrap-wps %U
 GenericName=WPS
 GenericName[zh_CN]=WPS 2019
+MimeType=application/wps-office.et;application/wps-office.ett;application/wps-office.ets;application/wps-office.eto;application/wps-office.xls;application/wps-office.xlt;application/vnd.ms-excel;application/msexcel;application/x-msexcel;application/wps-office.xlsx;application/wps-office.xltx;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/wps-office.uos;application/wps-office.dps;application/wps-office.dpt;application/wps-office.dpss;application/wps-office.dpso;application/wps-office.ppt;application/wps-office.pot;application/vnd.ms-powerpoint;application/vnd.mspowerpoint;application/mspowerpoint;application/powerpoint;application/x-mspowerpoint;application/wps-office.pptx;application/wps-office.potx;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.openxmlformats-officedocument.presentationml.slideshow;application/wps-office.uop;application/wps-office.wps;application/wps-office.wpt;application/wps-office.wpso;application/wps-office.wpss;application/wps-office.doc;application/wps-office.dot;application/vnd.ms-word;application/msword;application/x-msword;application/msword-template;application/wps-office.docx;application/wps-office.dotx;application/rtf;application/vnd.ms-word.document.macroEnabled.12;application/vnd.openxmlformats-officedocument.wordprocessingml.document;x-scheme-handler/ksoqing;x-scheme-handler/ksowps;x-scheme-handler/ksowpp;x-scheme-handler/ksoet;x-scheme-handler/ksowpscloudsvr;x-scheme-handler/ksowebstartupwps;x-scheme-handler/ksowebstartupet;x-scheme-handler/ksowebstartupwpp;application/wps-office.uot;
 Name=WPS 2019
 Name[zh_CN]=WPS 2019
@@ -16,4 +17,4 @@ X-KDE-SubstituteUID=false
 X-KDE-Username=
 Icon=wps-office2019-kprometheus
-InitialPreference=3
+InitialPreference=99
 StartupWMClass=wpsoffice

然后在 ~/.config/mimeapps.list 中配置默认程序

[Default Applications]
application/vnd.openxmlformats-officedocument.wordprocessingml.document=wps-office-wrap.desktop
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet=wps-office-wrap.desktop
application/vnd.openxmlformats-officedocument.presentationml.presentation=wps-office-wrap.desktop
application/vnd.ms-word=wps-office-wrap.desktop
application/vnd.ms-excel=wps-office-wrap.desktop
application/vnd.ms-powerpoint=wps-office-wrap.desktop

PS. 合并 WPS 的 MimeType 可用以下的 zsh 命令(需要 extendedglob 选项)

grep MimeType /usr/share/applications/wps-office-^pdf* | cut -d'=' -f2 | paste -sd ''
❌