@
lizon 你的回复有一些比较明显的问题。
1.讲性价比而不顾风险。学茬、低效、一事无成很容易导致性价比一点都发挥不出来。
2.我上面说过不管基本上为了哪种目的学 C ,都有比直接学 C 更有效的策略。
3.你似乎不把 C 当“高级语言”。然而不管 C 的抽象有多不给力,事实上 C 就是彻头彻尾的高级语言。
如果说 C 因为能操作底层实现所以显得低级, C++和 Rust 之流同样也做得到。这和抽象能力的上限没什么关系。
而纯粹的 C ( strictly-conforming ISO C )甚至严格地比 C++更“高级”。比如说, ISO C++引用的 POSIX 的 errno 错误码在 ISO C 里缩水得没剩几个。
可见仅仅要让 C “底层”到堪用到这点程度,就必须学更多 C 以外的东西。更别提二进制互操作了。
注意,你所谓的“俭”——表达相同层次的抽象时对实现细节依赖少——在日常见到的语言中,恰恰就最符合的就是纯粹的 C 。要说其它的,基本上是个日用的语言都不会那么“俭”,而会偷懒假设更多东西。
(当然, C 也不是都不偷懒,比如和 C++一样假定一个字节至少有 8 位,但不管怎么说比 Java 和 POSIX 这样钦定一个字节=8 位总是明显“俭”的。)
C 正是用这点换来了卓越的源码层次的可移植性(尽管实际上由于限制过于严格多数场合并没有什么卵用……)。
所以你说的学 C 只能认为是学 C 和底层的其它知识,这并不比学其它语言+底层知识优越,还更容易引起混乱,同时得到的技能并不实用。
4.混淆抽象性质和实现的层次。
具体来讲,“高级”和“高层”不是一回事,“低级”和“底层”也不是一回事。(有多少人知道有高级汇编语言……?)
底层实现和强调抽象完全不矛盾;相反,为了了解底层实现,一些(和高级语言类似的)抽象是必要的,否则一些情况会导致理解底层这个任务都不具有可行性。
提一下, volatile 本身恰恰就是非常学术的东西,而且算是 designed by committee ( X3J16 )而有正面反馈的典型例子。
工程上实践对 volatile 的大大咧咧反而导致了一大票的误用 bug 的笑话。
比如语言设计领域算是比较著名的 double-checked locking 失败例,最终迫使 Java 更改了 memory model ,而现在 Java 和 C#的 volatile 的意思和 C/C++里的截然不同。
直接根源就是多数用户对 volatile 的想当然。
有多少工程派领会到了这些背景知识?有哪些纯粹的工程需求驱动你去了解这些东西?
我不怎么相信你没有足够的抽象会支持你看得下去,因为具体的东西太细碎了。
另外,像 cache coheretece/memory consistency 这样的东西,我也不信你用反抽象的方式能理解得了。
如果说抽象迟早绕不过去,为什么还要用低效的方法?
5.如果要学院派,请严谨地保持含义的准确。
图灵机与λ演算显然不等价,因为“等价”不等价于“可计算性等价”。
对选择学什么语言入门来讲,恰恰需要在乎其中不等价的部分,比如说抽象能力和性能。
6.注意蕴含逻辑。
即便“ C 的程序更符合初学者的思维方式”,也不自然表示这是初学者需要的思维方式。
何况“ C 的程序更符合初学者的思维方式”其实是很有疑问的。
初学者(乃至有几门其它语言经验的老手)基本上不可能理解 C 的抽象机模型和可观察行为等价的要求,所以没几下子就只能拘泥具体实现了,同时还没搞清楚适用范围。
结果就是一些很重要的基础知识(比如什么是 UB )都缺乏机会掌握,上手做什么就被坑什么,坑了还未必能总结出规律下次避开。
这样还不如直接就来抽象能力强一点的语言呢……好歹能上手把更多的事做对,而不至于找不到方向。