表达式问题的优雅解决:多重派发与开放方法
本文探讨了困扰面向对象和函数式编程的“表达式问题”:如何在不修改现有代码的情况下,添加新的数据类型和操作。作者通过C++和Haskell的例子,展示了这个问题的本质。传统的OOP方法难以同时扩展类型和操作,而函数式编程也存在类似的局限性。文章深入分析了访问者模式及其扩展,并最终以Clojure的多方法和协议为例,展示了如何通过多重派发和开放方法优雅地解决表达式问题,实现代码的灵活性和可扩展性。
阅读更多
本文探讨了困扰面向对象和函数式编程的“表达式问题”:如何在不修改现有代码的情况下,添加新的数据类型和操作。作者通过C++和Haskell的例子,展示了这个问题的本质。传统的OOP方法难以同时扩展类型和操作,而函数式编程也存在类似的局限性。文章深入分析了访问者模式及其扩展,并最终以Clojure的多方法和协议为例,展示了如何通过多重派发和开放方法优雅地解决表达式问题,实现代码的灵活性和可扩展性。
阅读更多
本文探讨了软件设计中的“表达问题”:在既要添加新数据类型又要添加新操作的场景下,如何避免修改已有代码。作者通过C++和Haskell的例子展示了面向对象和函数式编程在解决这个问题上的局限性,并深入分析了访问者模式和Clojure的多方法及协议的优雅解法。Clojure的解法巧妙地利用了开放方法的特性,将方法定义与类型定义分离,从而实现了灵活的扩展,避免了修改已有代码的困境。
阅读更多
作者在二十年前初识Forth语言,最近又重新拾起,并花了两个月时间完成了两个Forth解释器的实现:goforth(Go语言实现)和ctil(C语言实现)。goforth是一个纯粹的解释器,简单易用,但缺乏对高级功能的支持;ctil则更接近传统的Forth实现,允许用户用Forth本身扩展语言功能,展现了Forth语言的强大之处。作者认为Forth在早期硬件环境下具有独特的优势,但其基于堆栈的编程模型使其可读性较差,在现代编程环境下实用性有限,更适合作为学习项目来提升对编译原理和虚拟机的理解。
阅读更多
本文深入浅出地讲解了统一化算法,一种用于自动求解符号项之间方程式的过程。它在逻辑编程和类型推断中有着广泛应用。文章从模式匹配开始,逐步引出统一化概念,并给出了基于Norvig改进算法的Python实现,包括数据结构定义、核心函数`unify`、辅助函数`unify_variable`和`occurs_check`,以及详细的代码示例和运行结果。
阅读更多
这篇文章探讨了多项式乘法、卷积和它们之间的联系。文章首先用表格和图形化的方式解释了多项式乘法,指出其本质是卷积运算。随后,文章介绍了离散信号和系统,以及线性时不变系统。文中指出,任何信号都可以分解成一系列缩放和平移的单位脉冲,而线性时不变系统的响应可以通过卷积计算得到。文章最后简要介绍了卷积的性质和傅里叶变换的关系,指出卷积的傅里叶变换等于其操作数的傅里叶变换的乘积,这使得卷积运算可以高效地实现。
阅读更多
布隆过滤器是一种概率数据结构,它以极小的空间代价高效地判断一个元素是否在一个集合中。通过多个哈希函数将元素映射到位数组,布隆过滤器能够快速地判断元素是否存在,虽然存在少量误判的可能性(误报),但对于大多数查询结果为负的场景,它能显著提高效率。文章详细解释了布隆过滤器的原理、实现以及数学推导,并通过Go语言示例展示了其应用,最终计算出针对十亿级数据,误判率为1%时的最佳参数配置,证明了其在海量数据处理中的实用性。
阅读更多
Transformer模型中的前馈网络层通常参数量巨大,成为效率瓶颈。稀疏门控专家混合模型(MoE)提供了一种优雅的解决方案。MoE将大型前馈层分解成多个小型“专家”网络,并使用路由器选择每个token最合适的专家子集进行计算,从而显著降低计算成本,提升效率。这篇文章详细解释了MoE的原理,并提供了基于NumPy的实现代码,同时也探讨了专家负载均衡等关键问题。
阅读更多
本文深入浅出地讲解了交叉熵在机器学习分类任务中作为损失函数的数学原理。从信息论角度出发,文章首先介绍了信息量、熵的概念,然后引出交叉熵,并将其与KL散度进行比较。最后,文章阐述了交叉熵与最大似然估计之间的联系,并用具体的数值例子进行了说明,帮助读者理解交叉熵在机器学习中的应用。
阅读更多
一个看似简单的数学谜题:仅用四个数字2和任何数学运算,生成任何自然数。从小学算术到大学高等数学,都能参与其中。最初看似简单的挑战,随着引入指数、阶乘等,难度陡增。最终,物理学家狄拉克利用嵌套平方根和对数,找到了一个通解,优雅地解决了这个世纪难题,即使只使用四个2。
阅读更多
本文深入探讨了 Python 中流行的 JIT 装饰器模式,特别是 JAX 和 Triton 库中的应用。作者通过一个简化的示例,从零开始实现了三种 JIT 装饰器:基于 AST 的、基于字节码的和基于追踪的。基于 AST 的方法直接处理抽象语法树;基于字节码的方法利用 Python 的字节码解释器;基于追踪的方法则通过运行时追踪函数执行来构建表达式 IR。文章详细比较了这三种方法的优缺点,并以 JAX 和 Numba 为例,阐述了它们在实际应用中的策略。
阅读更多
本文是关于Raft分布式一致性算法的系列文章的第一篇,介绍了Raft算法的基本概念和架构。Raft算法用于解决在多个服务器上复制确定性状态机的问题,确保即使部分服务器崩溃,服务也能保持可用性。文章解释了Raft的核心组件,包括状态机、日志、一致性模块,以及领导者和跟随者角色,并阐述了客户端与Raft集群的交互方式。此外,文章还讨论了Raft的容错能力和CAP定理,以及选择Go语言作为实现语言的原因。后续文章将深入探讨Raft算法的实现细节。
阅读更多
本文探讨了如何在 Go 应用程序中利用机器学习模型,特别是大型语言模型(LLM)。文章首先介绍了使用现成的互联网 LLM 服务(如 ChatGPT 和 Gemini)以及本地运行的开源模型(如 Llama 和 Mistral)的简便方法,并推荐使用 Ollama 或 Llamafile 等工具简化本地模型部署和 API 调用。接着,文章深入讲解了如何使用 Python 作为辅助程序,通过自定义模型实现更高级的定制化。文章以 Gemma 和 JAX 为例,演示了如何构建一个 Python 服务器,通过 REST API 为 Go 应用程序提供本地 LLM 推理服务。此外,文章还展示了如何使用 TensorFlow 和 Keras 训练一个简单的图像分类模型,并通过 Unix 域套接字实现 Go 客户端与 Python 服务器之间的低延迟通信。
阅读更多
文章介绍了如何在 Linux 系统上使用 Go 语言构建静态链接的二进制文件。作者首先解释了 Go 语言默认情况下并不总是生成静态链接的二进制文件,特别是在使用 cgo 的情况下,需要额外的设置才能实现。文章详细介绍了如何使用 musl libc 和 Zig 工具链来构建静态链接的 Go 二进制文件,并提供了一些示例代码来说明这些方法。
阅读更多
本文介绍了泰勒级数和麦克劳林级数,它们是用于逼近函数的多项式。麦克劳林级数是泰勒级数的一种特殊形式,用于在0附近逼近函数。文章首先通过逼近余弦函数的例子直观地解释了麦克劳林级数的工作原理,然后推导了麦克劳林级数的公式。接着,文章介绍了泰勒级数,它可以用于在任意点附近逼近函数。文章以逼近自然对数函数为例说明了泰勒级数的应用。最后,文章讨论了幂级数的收敛性,并使用比值检验来确定麦克劳林级数和泰勒级数的收敛区间。
阅读更多
本文介绍了如何使用 Go 程序读取谷歌表格数据。文章提供了两种方法:使用服务账户和 OAuth 2.0。使用服务账户时,需要创建服务账户并下载私钥,然后在程序中使用私钥进行身份验证。使用 OAuth 2.0 时,需要在 GCP 控制台中设置 OAuth 2.0 客户端 ID,并在程序中使用客户端 ID 和密钥进行身份验证。文章还提供了一个完整的示例程序,演示了如何使用这两种方法读取谷歌表格数据。
阅读更多
该网站提供了有关在Go中进行快速XML流式处理的信息,重点介绍了使用高速和轻量级的streadfast XML解析器。它涵盖了StreamFast的安装、使用和优点,并讨论了基于事件的流式处理模型。
阅读更多