gpt4 book ai didi

functional-programming - "Mathematical state"函数式语言?

转载 作者:行者123 更新时间:2023-12-02 00:08:54 24 4
gpt4 key购买 nike

我已经阅读了这里的一些讨论,以及其他解释的后续链接,但我仍然无法理解“改变状态”和“不改变状态”之间的数学联系,因为它属于我们的函数式编程与非 FP 辩论。据我所知,基本论点可以追溯到函数的纯数学定义,即函数将域成员映射到一个范围成员。然后将其与计算机代码函数被赋予特定输入时进行比较,它总是会产生相同的输出,即不会因使用而异,即函数的状态,如在其域到范围映射行为中一样,不会改变.

然后它在我脑海里变得模糊。这是一个例子。假设我想在 x-y 字段上显示封闭的 block 状多边形。在 GIS 软件中,我知道一切都存储为有向的、封闭的图形,即一个正方形是四个向量,它们的头和尾相连。原始数据表示只是每个向量的各个笛卡尔起点和终点。当然,软件中可能有一个功能可以“处理”所有这些坐标集。好的。但是如何以数学方式表示每个多边形,例如,正 x、负 y 象限中的矩形可能是:

Z = {(x,y) | 3 <= x <= 5, -2 <= y <= -1}

所以我们会有很多类似 Z 的函数,每个函数都表示一个单独的多边形——如果不是我的矩阵数学高手,也许这些“函数”可以表示为矩阵。 . .但我离题了。

因此,使用通常的原始矢量数据方法,我的代码中有一个函数在处理每组坐标时“改变状态”,然后绘制每个多边形(然后处理多边形的变化),而每个多边形只有一个类似 Z 的函数方法似乎完全符合“不改变状态”的规则。正确的?还是我离开这里了?似乎老式的单函数处理原始坐标数据也没有改变域范围纯度法则。我很困惑....

我的部分灵感来自阅读有关图像处理的新想法,其中每个“帧”将由一个能够“gnu-plot”整个图像、边缘、颜色的大函数来表示,而不是猛击像素架,渐变等。这有关系吗?我想我想弄明白为什么我想以一种或另一种方式表示多边形(例如城市街区)的街道 map 。我一直听到函数式语言的拥护者围绕这样的想法跳舞:数学函数是纯粹的、安全的、好的,最终是乌托邦的,而非 FP 软件函数是某种马虎的拼凑,使我们无法获得 Borg 般的幸福。

但更令人困惑的是 FP 与非 FP 的内存管理。我一直听到的(例如并行编程)是 FP 并没有像 C/C++ 程序那样改变“内存状态”。这是否像谷歌文件系统,所有东西都只是放在虚拟内存池中,而不是数据移入和移出数据库和内存位置?不知何故,所有这些事情都是相关的。因此,完美的 FP 程序似乎只是一个函数(可能由许多子函数组成)执行一个任务——尽管快速浏览任何 elisp 代码似乎是在这方面对编程精神 split 症的研究。

最佳答案

Referential transparency在编程(以及数学、逻辑等)中,原则是表达式的含义或值可以在不需要任何非本地上下文的情况下确定,并且表达式的值不会改变。代码如下

int x = 0;

int nextX() {
return x++;
}

违反引用透明性,因为 nextX() 将在某一时刻返回 32,并在下一次调用时返回 33,并且有没办法,仅根据本地分析,what nextX() 将在任何给定位置返回。在许多情况下,通过向过程 添加参数,很容易将非引用透明过程 转变为引用透明函数。例如,在刚刚给出的示例中,添加参数 currentX 使 nextX 引用透明:

int nextX( int currentX ) {
return currentX+1;
}

当然,这确实需要每次调用 nextX 时,以前的值都可用。

对于其全部目的是修改状态(例如,屏幕状态)的过程,这没有多大意义。例如,虽然我们可以编写一个方法 print,它在某种意义上是引用透明的:

int print( int x ) {
printf( "%d", x );
return x;
}

还有一个问题是系统的状态被修改了。例如,询问屏幕状态的方法在调用 print 前后会有不同的结果。为了使这些类型的过程具有引用透明性,可以使用表示系统状态的参数来扩充它们。例如:

// print x to screen, and return the new screen that results
Screen print( int x, Screen screen ) {
...
}

// return the contents of screen
ScreenContents returnContentsOfScreen( Screen screen ) {
...
}

现在我们有了引用透明性,但代价是必须传递 Screen 对象。例如:

Screen screen0 = getInitialScreen();
Screen screen1 = print( 2, screen0 );
Screen screen2 = print( 3, screen1 );
...

这对于使用 IO 来说可能感觉有点矫枉过正,因为毕竟目的是修改某些状态(即屏幕、文件系统或……)。因此,大多数编程语言不会使 IO 方法引用透明。然而,有些人,比如 Haskell,会这样做。由于按照刚才的方式进行操作相当麻烦,因此这些语言通常会使用一些语法来使事情变得更简洁。在 Haskell 中,这是通过 Monaddo 符号来完成的(这确实超出了这个答案的范围)。如果您对如何使用 Monad 概念来实现这一点感兴趣,您可能会对这篇文章感兴趣,You Could Have Invented Monads! (And Maybe You Already Have.)

关于functional-programming - "Mathematical state"函数式语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16677142/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com