function hashing/fingerprinting 作为内置功能?

function hashing/fingerprinting as a built-in feature?

如何在运行时获得函数的稳定散列?

这意味着hash随着实现的改变而改变,这是递归的,所以如果有嵌套函数调用,嵌套函数hash会影响外层函数hash。

不确定哪种语言具有此功能。我正在寻找一种实用的编程语言,它既简单又高效。

我想函数式语言,也许 lisp 或 haskell 是通常的嫌疑人,但不确定它看起来像什么。

function myFunction() {
    ... // Some code, possibly using names from other files/modules/libraries
}

 // Prints the hash which changes if anything in the implementation of `myFunction` changes, stable across runs.
print(hash(myFunction))

有这种语言吗?如果是的话,需要一个例子来说明它是如何编写的以及它为什么起作用。

非示例为 js、python、java...

我已经在使用 CCL (Clozure Common Lisp) 部署的 Common Lisp 编写的商业应用程序中实现了这一点。

您可以通过使用 disassemble 获取函数编译图像的表示,然后使用合适的摘要器对其进行哈希处理,例如 Ironclad 中的摘要器。

我在 CCL 解决方案中实际使用的是函数 ccl::%function-code-words 来获取函数中有多少个单词和访问器 ccl::%function-code-byte 来获取字节(有四次与字数一样多)。

显然,基于代码字节的散列不会反映在不同时间在程序中同一点创建的函数实例之间捕获的词法环境的差异。

实现不是递归的。相反,整个解决方案迭代了已知的函数列表。

如果您想要一种 general-purpose 编程语言,Unison 可以做到这一点:

Each Unison definition is some syntax tree, and by hashing this tree in a way that incorporates the hashes of all that definition's dependencies, we obtain the Unison hash which uniquely identifies that definition.

https://www.unisonweb.org/docs/tour

每个 Unison 定义都由 512-bit SHA3 hash 标识,并且是不可变的 — 您不能修改定义,只能创建一个新定义。此外,names 与定义分开存储,因此重命名是一个微不足道的操作,如果两个人 structurally 编写相同的代码,只是变量 &函数名称,它们的代码将共享相同的哈希值,因此被识别为相同的代码。

至于配置语言,Dhall 也是如此:

Use Dhall's support for semantic hashes to guarantee that many types of refactors are behavior-preserving

https://dhall-lang.org/

由于Dhall是非图灵完备的,所以每个表达式都有一个范式,而这个范式的hash可以用来识别它,所以当你重构你的Dhall时代码,您可以确信它会产生相同的结果。