C++ 的一些新感想

因为在工作中C++用的比较多,听说 C++ 17 最近又引入了很多新特性,就买了几本 C++ 的书回来看。看了一阵,感慨颇多,罗列如下:

  • C++ 在 Library 开发人员和普通使用人员之间的鸿沟是越来越大了。新增加的很多特性都是给Library作者提供的,普通用户平时根本用不到。特别的,我以前总是以为所谓 Library 就是在语言之上提供一些包装好的功能模块,现在看到标准库中很多 Type Traits (比如 is_trivially_destructible) 都需要编译器的特殊支持才能实现,远远地超出了我以前的理解范畴。一般的 C++ 用户,如果打开标准库里面的程序想要研究一下某个特性是如何实现的,多半和天书一样看不懂。
  • C++ 现在的救命稻草就是运行时刻的性能了,这集中体现在C++为程序员提供的内存控制上。为此 C++ 几乎牺牲了其他可能的前进方向,并且不惜在语言上增加了巨大的复杂性。C++ 的创始人 Bjarne Stroustrup 前些年还提要在 C++ 中引入自动内存管理,现在是绝口不提了,估计搞出来也没有人用;为了更有效的支持大型对象,C++ 搞出来 Rvalue Reference 和 Move Constructor,让我这样的 C++ 的老鸟程序员也感到太过复杂;更不用提新的 std::string_view,本身大概唯一的作用就是在大字符串上搞一些子串操作比较有效率,结果强行塞进标准库,连 C++ 的资深作者 Nicolai M. Josuttis 都看不下去,在他的书中大声疾呼:string_view is considered harmful! 即便如此追求性能,看着 Programming Language Popularity Trend 上面 C++ 日渐下滑的曲线,我估计日后 C++ 也就只能守着高性能计算这块阵地了。
  • C++ 现在把编译时刻多态搞得很深,这一点其实和 C++ 把性能作为卖点也息息相关。原本是一个编译时刻模板替换的简单玩意,后来发现这个东西因为没有 Virtual table lookup 从而不损失运行时刻的效率,结果在这个方向上一发不可收拾,各种 type traits 如野草般生长,Library 全部都是模板库,里面根据用户提供的类型各种模板特化层出不穷,对于一般的 C++ 程序员来说根本就是天书,唯一的好处就是运行时刻生成的代码都是直接针对用户提供的类型操作的,效率很高。这方面C++阵营一直使用的例子就是 std::sort vs qsort from C。不过在我看来,最初的简单模板替换就已经完成了 90% 的工作,后来加上的一大堆特性,最多不过使得这个编译时刻多态(现在都叫 meta programming了,据称在 Type Domain 还是 Turing Complete)能够在其他 10% 的场合使用一下,实在算是事倍功半的一个好例子吧。

自己呢,还是好好的搞自己的数学,统计,概率,算法等等。这类语言的东西实在不值得深究啊。

戒掉围棋,立此为证(Swear Off Go Game)

下棋劳神费力,导致头疼,这个年纪已经不再合适。

下棋远离家人,却贴近陌生人,本末倒置。

下棋浪费时间,大好光阴本可用于学习与工作。

下棋所争无非输赢,虚荣好胜,引以为耻。

从此把棋盘、棋子、棋书束之高阁;新闻、视频、论坛关禁了事。

立此为证,敬请家人朋友监督。

Playing Go consumes a lot of brain power, causes headache, which is inappropriate for my age.

I spend a lot of time on playing Go with strangers, which could instead be spent with family.  This behavior puts the incidental before the fundamental.

A lot of time is spent on Go playing, which could be used on learning  and studying other interesting things.

The whole point of playing Go on Web is for winning vanity, this should be a shame for any noble men.

Putting the stones, boards and books on attic space, blocking the news, videos and forums on computers.

Family, please help me to keep this promise.

对抗假新闻

现在互联网上的假新闻越来越多,有一些是无心的以讹传讹,但是也有很多是别有用心的杜撰,专门用来混淆视听的。传统的大媒体比如BBC、卫报还好一些,论坛、自媒体以及社交网络都是重灾区。关于新型冠状病毒的假新闻,过去的这六个月来就遇到了很多,比如有假新闻说英国首相鲍里斯在感染新冠之后,虽然勉强活命,但是身体严重受损,无法坚持工作,不得不辞去首相职位。最新的一则是前一天有报道说俄罗斯的疫苗研制成功,普京总统亲自下令全民接种,自己的大女儿以身作则,率先尝试。这消息已经相当使人震惊,毕竟疫苗是人命关天的大事,俄罗斯在疫苗研制方面的火箭速度实在是不同寻常。可是隔天就又有新的消息,说俄罗斯疫苗研制失败,普京的大女儿已经因为接种疫苗的不良反应挂了!!!  这消息也太过耸人听闻了吧,实在让人难以相信。联想起前一阵子一个中文自媒体播报说末任香港总督彭定康已经向海牙国际法庭提交诉讼,要把香港的主权重新交还给英国,我当时也是大吃一惊,最后也悄无声息,又是一个假新闻。

互联网上的假新闻实在是太多了,干脆眼不见心不烦,专注于自己的家人、学习、工作吧。

Vim Window Management (Vim 多窗口管理)

我一直使用Vim作为编辑器。现在大屏幕显示器越来越流行,使用Vim的时候也越来越多地同时用到多个窗口。为了能够更有效地利用多个窗口,我琢磨着写了一些脚本来更好地在多个窗口之间切换,下面把我学到的知识说一说。

首先我不会写 Vim Script,所以我的脚本都是用 Python写的,不过 Vim的 Python Interface 也很方便,就把脚本写在一个单独的 window.py 文件中,然后在 vimrc 里面加上:

py3file window.py

就可以了。

要想有效的管理窗口,首先需要能够了解当前的窗口分布情况。Vim 的 Python Interface 提供了一个 vim.windows 对象,不过更好的办法是调用 winlayout 这个函数。因为 Vim 中所有的窗口都是从一个主窗口水平或者垂直切分得到的,所以所有的窗口可以表示为一棵递归二叉树。遍历这棵树就可以得到所有窗口的信息,包括其编号、大小,当前位置,父窗口以及其中显示的数据。具体的调用方法如下:

winlayout = vim.eval('winlayout()')

第二个非常有用的命令是 wincmd。Vim提供的绝大部分窗口管理命令都从快捷键 CTRL+W 开始,但是这个快捷键在脚本中使用起来并不方便,这个时候就可以使用wincmd。比如我们要把输入焦点切换到左面的窗口,可以使用:

vim.command('wincmd l')

最后就是创建新窗口和关闭当前窗口的命令,这方面Vim提供了非常繁多的命令,但是对于脚本作者来讲最实用的也就是下面几个:

  • 关闭当前窗口:vim.command(‘close’)
  • 关闭所有其他窗口,只留下当前窗口:vim.command(‘only’)
  • 垂直切分在右面打开新窗口:vim.command(‘rightbelow vnew’)
  • 垂直切分在左面打开新窗口:vim.command(‘leftabove vnew’)
  • 水平切分在下面打开新窗口:vim.command(‘rightbelow new’)
  • 水平切分在上面打开新窗口:vim.command(‘leftabove new’)

有了这些命令以后,我们就可以编写脚本来控制Vim的多个窗口了。我自己写了一个脚本用于管理两个Side by Side 放置的窗口,再加上一些水平切分的支持,结果挺方便的,以后有机会放到 Github 上吧。

等位基因的组合数目

假定某种形状(比如豌豆花的颜色)由一对等位基因控制,其中显性基因用字母A表示,隐性基因用字母a表示。显而易见,我们一共有三种可能的基因型:AA, Aa, aa,分别对应红色、粉色和白色。如果某个等位基因一共有n种可能的变异,即:

(1)   \begin{equation*} A_1, A_2, A_3, ..., A_n \end{equation*}

那么一共有多少种可能的基因型呢(注意基因型A_nA_mA_mA_n 是一样的)?

这个问题看上去很简单,但是我自己却迷惑了很长一段时间。最后我终于认识到:在阅读 William Feller 老爷爷的概率书的这段时间里,自己在经过了相当多的训练之后,已经习惯性的去考虑样本空间内每一个样本的概率是相等的情形了,从这一点讲,那么很明显我们一共有 n \times n 种基因组合的结果。但是问题是这些组合虽然每一个出现的概率相等,但是其中却有一些重复;等到我们把重复的合并以后,剩下的样本出现的概率却不相等了。具体来讲,纯合的基因型:

(2)   \begin{equation*} (A_1, A_1),  (A_2, A_2), (A_3, A_3), ...,  (A_n, A_n) \end{equation*}

要比杂合的基因型

(3)   \begin{equation*} (A_1, A_2),  (A_1, A_3), (A_1, A_4), ...,  (A_{n-1}, A_n) \end{equation*}

出现的概率要低。具体到豌豆花的例子,也就是白色和红色出现的概率分别是 25%,而粉色出现的概率是50%。在领悟到这一点之后,前面给出的题目就很容易计算了:当某个等位基因一共有n种可能的变异的时候,我们可以把所有的可能的组合排成一个 n \times n的表格,其中对角线上的基因型是纯合的,一共有n个,而非对角线上的基因型是杂合的,一共有 n^2 - n 种。考虑到杂合的基因型每种都会出现两次,那么所有不同的基因型一共有:

(4)   \begin{equation*} \frac{n^2 - n}{2} + n = \frac{n(n+1)}{2} \end{equation*}

这和William Feller 老爷爷书中给出的答案完全一致。

音乐欣赏的两个对比

以前自己都是只会打开音响听音乐,自从自己开始弹琴以后,才慢慢悟出来音乐欣赏这里面还有两个有趣的对比:第一,同样一首歌曲,听别人弹和听自己亲手弹出来的感觉,后者带来的愉悦要大得多,听着旋律与和声跟随着自己手指的动作流淌出来,即使是很简单的曲目,也很享受,要是别人弹,可能就会觉得这旋律很简单,没什么特别的。第二,钢琴想要弹到别人觉得好听要比自己觉得好听难得多,常常一段旋律自己弹得摇头晃脑,乐在其中,可是家人已经听过无数遍了,早已听得滚瓜烂熟,耳朵起茧了。

看来要想领会音乐的妙处,自己动手实践是一个好办法呀。

打开 Do Not Disturb

过去半年多以来,手机上收到的诈骗电话多到了无以复加的地步。让我只能感慨世风日下,人心不古。无奈之下,我只有抓起电话研究一下如何过滤这些电话。最后的结论是Android 有一个选项是 “Do Not Disturb”,打开以后就只有你的通讯录上的人给你打电话才能响铃,其他的电话就全部过滤掉了。看来这是目前最为有效的方法了。

The Art of Piano Fingering: Traditional, Advanced, and Innovative is very useful book

During the Covid 19, I have to give up my ping pong play since it is impossible to find partners any more.  It did not take me long to decide to pick up piano as the next activity, since I have a piano right at home. After some basic scales practice and childish songs, I decided to start to try some more adult-style songs since it is really hard to keep motivated if I keep playing those naive songs. Anyway, first I picked a well-known song The Moon Represents My Heart, and it took me a few weeks to be able to play it by heart without making any mistakes (but not always be able to do so), then I picked a new song The main theme from XuanYuan Sword:The Scar of the Sky, although this one looks only a little bit harder than the previous one, but it proves beyond me: I practiced for a few weeks, but only finished the  one third, and never be able to play even this one third part without any mistakes: some part are just too hard to play, let along the fact many part are played in a quite hasty way, and music produced by me also sounds poor.

Only at this occasion, it occurred to me that I need some help instead of just keep trying by myself, not just some music theory, but some more practical guide about playing piano. Very fortunately, I found the book The Art of Piano Fingering: Traditional, Advanced, and Innovative, which focuses on fingers arrangement in piano play. It has a lot of simple but very effective advice for how to arrange fingers for various music pieces, from simple scales, triads, to arpeggios which spans more than 1 octave. By applying these advice to my piano, I can play the  The Moon Represents My Heart with more confidence and easier hand moves, and got some new ideas about how to play The main theme from XuanYuan Sword:The Scar of the Sky. Hopefully in the next a few weeks, I can really master this song and I am looking forward to that day. 🙂

Text from Yeti:

BTW I am thinking about getting a digital piano cuz I seem to be driving Yeti crazy soooooo yea abut dat anyways i should rlly start to apply the pedal more cus life would just be so much easier ok thats it yeti out baiiiii :))) :PP