【问题标题】:What strategy to turn non-pure functions into a pure functions in JavaScript在 JavaScript 中将非纯函数转换为纯函数的策略是什么
【发布时间】:2020-01-06 20:18:38
【问题描述】:

我开始学习 javascript 中的函数式编程。这可能是一个愚蠢的问题,但我试图解决以函数方式编写的非纯函数。

我的问题是在函数式编程范式中应该使用什么策略来实现这一点。

const crypto = require('crypto');

const encrypt = (data, publicKey) => {
    if (publicKey === undefined ) throw 'Missing public key.';

    const bufferToEncrypt = Buffer.from(data);
    const encrypted = crypto.publicEncrypt({
        key: publicKey
    }, bufferToEncrypt);

    return encrypted;

};

【问题讨论】:

  • @cdhowie 我对纯函数的理解是,对于相同的参数,它的返回值是相同的。我上面的例子是为相同的参数返回不同的输出。
  • @cdhowie haha​​ha 是的,我想你应该写一个答案。当我开始对纯函数感到困惑时。大声笑
  • 我已将我的 cmets 转换为正确的答案。

标签: javascript functional-programming pure-function


【解决方案1】:

成为纯函数有两个标准。

纯函数准则 1:调用具有相同值的函数必须始终产生相同的返回值

在进行非对称加密时这是不可能的,因为每次操作都会生成一个随机会话密钥。会话密钥用公钥加密,然后会话密钥用于加密负载。返回的值通常只是两个值的编码版本:(1) 公钥加密的会话密钥,以及 (2) 会话密钥加密的有效负载。

每次调用函数时,这两个值都会不同,因为会话密钥每次都会不同。

然而,尽管返回值不相等,但我认为它们在语义上相等 -- 也就是说,如果您使用匹配的私钥解密每个值,解密后的值将比较平等。

加密有效地混淆了值相等,对于加密来说这是一件好事。我们不希望比较在不同时间生成的两条加密消息没有 em> 拥有解密密钥。这将是一个安全风险。

因此,我认为这个函数在语义上符合这个标准,但是 如果没有公钥,我们就无法判断。

纯函数准则 2:函数没有可观察到的副作用

这一点应该是相当明显的:写入磁盘是副作用,写入全局变量是副作用等等。我们应该无法区分调用函数前后的任何状态差异.

从技术上讲,会话密钥的生成需要使用系统的安全随机数生成器。这将消耗一些熵。运行函数后,可用的熵会减少,可以测量。

但是,我认为这种副作用可以忽略,因为任何需要安全随机数的都会有同样的问题,这更像是一个实现细节 的安全随机数生成器。

这就像声称需要大量 CPU 时间的函数具有副作用,因为运行它会增加进程的 CPU 时间计数器。是副作用吗?技术上……也许吧?但是没有理智的人会认为这是副作用。

结论

我会称这个函数为“语义纯”。如果你问我这是否是一个纯函数并且只接受是/否的答案而没有限定,我会告诉你“是”。

【讨论】:

  • @cdhowie 这很有意义。谢谢你说清楚,谢谢!
  • 1 & 2 很容易通过让函数将状态作为第二个参数并返回一个状态来修复。因此,即使对于需要多次调用的运行,副作用也消失了。
  • @Sylwester 我不确定这与这个特定功能有何关系。能举个例子吗?
  • @cdhowie 所有函数都可以重写以符合您的 2 个标准。例如。 cryptoWrite(payLoad) 完成将值放入其中后,您将在其中获取有效负载。我同意 OPs 功能有一个功能契约,从用户的角度来看,它是否 100% 纯是不可能的。
  • @Sylwester 如果您的意思是将延续传递给函数,则可以将其视为非纯函数(调用提供的函数是一种副作用)。如果我们规定这不算作副作用,它仍然不会改变函数的任何内容,因为传递给延续的值可以被视为“返回值”。如果传递延续不是你的建议,那么我仍然不知道你想说什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
相关资源
最近更新 更多