引用计数为何成为现代语言的隐形选择:从性能开销到优化突围
1960年,John McCarthy在MIT实现第一个LISP解释器时,面临一个看似简单却影响深远的问题:如何在程序运行时自动回收不再使用的内存?他给出的答案是tracing garbage collection——周期性地遍历所有可达对象,标记并清理不可达的内存。这个方案统治了函数式语言数十年。 ...
1960年,John McCarthy在MIT实现第一个LISP解释器时,面临一个看似简单却影响深远的问题:如何在程序运行时自动回收不再使用的内存?他给出的答案是tracing garbage collection——周期性地遍历所有可达对象,标记并清理不可达的内存。这个方案统治了函数式语言数十年。 ...
1960年代,Bertrand Russell为了解决集合论悖论而提出类型理论时,大概没想到这个概念会在六十年后成为程序员日常争论的焦点。今天,每一个新编程语言的诞生都伴随着同样的灵魂拷问:静态类型还是动态类型?结构化还是名义?类型擦除还是单态化? ...
1985年,Bjarne Stroustrup在《The C++ Programming Language》第一版中写道:“C++继承自C的一个关键特性是值语义——对象可以被直接拷贝,而非仅仅通过引用访问。“这一设计决策深刻影响了后来三十年的编程语言演进。然而,同样是面向对象语言,Java在1995年选择了一条截然不同的道路:所有用户定义类型都是引用类型,只有原始类型(primitive types)才是值类型。这两条分道扬镳的路径,至今仍在影响着每一个开发者的日常决策。 ...
1964年,IBM在设计PL/I语言时引入了一个被称为"ON语句"的构造。这个看似简单的语法元素,开创了编程语言中结构化错误处理的先河。六十年后,当Rust的?操作符和Go的显式错误检查成为现代语言的主流选择时,我们不禁要问:为什么错误处理这个问题困扰了语言设计者如此之久? ...
1975年,麻省理工学院的 Gerald Sussman 和 Guy Steele 正在开发一门新的 Lisp 方言。他们遇到了一个看似简单的问题:当一个函数引用外部变量时,它应该找到哪个值?这个问题困扰了编程语言设计者十五年,而他们的解决方案——采用词法作用域——后来成为现代编程语言的标配。 ...
一个概念,三种命运 1975年,Robin Milner在ML语言中首次引入了参数化多态(parametric polymorphism)——这便是我们今天所称"泛型"的理论源头。半个世纪过去,这个概念已经渗透进几乎所有主流编程语言。然而,当你打开C++、Java、Go、Rust、C#的编译器源码,会发现同一个"泛型"概念在这些语言中竟然演化出了截然不同的实现策略。 ...
按下 Ctrl+S,屏幕上的界面几乎瞬间更新——没有重新编译的等待,没有应用重启的闪烁,甚至当前填写的表单数据都还在。这种被称为「热重载」的能力,已经成为现代开发体验的标配。但它究竟是如何工作的?为什么有些语言能轻松实现,而有些却举步维艰? ...