纯函数可以返回一个符号吗? [英] Can a pure function return a Symbol?

查看:110
本文介绍了纯函数可以返回一个符号吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能与哲学有关,但我认为这是正确的提问地点。

This may border on philosophical, but I thought it would be the right place to ask.

假设我有一个创建ID列表的函数。这些标识符仅在内部用于应用程序,因此可以在此处使用ES2015 Symbol()

Suppose I have a function that creates a list of IDs. These identifiers are only used internally to the application, so it is acceptable to use ES2015 Symbol() here.

我的问题是,技术上,当你要求一个符号时,我想象JS运行时会创建一个唯一的标识符(随机数?内存地址?不确定),为了防止冲突,需要访问全球国家。我不确定的原因是因为这个词,技术上。我不确定(再次,从哲学的角度来看)这是否足以打破API所呈现的数学抽象。

My problem is that, technically, when you ask for a Symbol, I'd imagine the JS runtime creates a unique identifier (random number? memory address? unsure) which, to prevent collisions, would require accessing global state. The reason I'm unsure is because of that word, "technically". I'm not sure (again, from a philosophical standpoint) if this ought to be enough to break the mathematical abstraction that the API presents.

tl; dr :这是一个例子 -

tl;dr: here's an example--

function sentinelToSymbol(x) {
  if (x === -1) return Symbol();
  return x;
}

这个函数是纯粹的吗?

推荐答案

不是,不,但实际上可能并不重要。

Not really, no, but it might not actually matter.

关于surface,(foo)=>符号(foo)看起来很纯粹。虽然运行时可以执行一些带副作用的操作,但即使你同时调用 Symbol(),你也永远不会看到它们。相同的参数。但是,使用相同的参数调用 Symbol 将永远不会返回相同的值,这是主要条件之一(下面的#2)。

On the surface, (foo) => Symbol(foo) appears pure. While the runtime may do some operations with side effects, you will never see them, even if you call Symbol() at the same time with the same parameters. However, calling Symbol with the same arguments will never return the same value, which is one of the main criteria (#2, below).

来自 MDN页面


请注意,Symbol(foo)不会将字符串foo强制转换为符号。它每次都会创建一个新符号:

Note that Symbol("foo") does not coerce the string "foo" into a symbol. It creates a new symbol each time:

Symbol("foo") === Symbol("foo"); // false


仅考虑副作用,(foo)=>符号(foo)是纯的(在运行时之上)。

Looking solely at side effects, (foo) => Symbol(foo) is pure (above the runtime).

但是,纯函数必须符合更多条件。 来自维基百科

However, a pure function must meet more criteria. From Wikipedia:


纯功能函数(或表达式)没有副作用(内存或I / O)。这意味着纯函数有几个有用的属性,其中许多可用于优化代码:

Purely functional functions (or expressions) have no side effects (memory or I/O). This means that pure functions have several useful properties, many of which can be used to optimize the code:


  • 如果纯表达式的结果如果没有影响其他表达式,则可以删除它。

  • 如果使用不带副作用的参数调用纯函数,则结果对于该参数列表是常量(有时称为引用透明度),即如果再次使用相同的参数调用pure函数,将返回相同的结果(这可以启用缓存优化,例如memoization)。

  • 如果有两个纯表达式之间没有数据依赖关系,那么它们的顺序可以颠倒,或者它们可以并行执行,它们不会相互干扰(换句话说,任何纯表达式的评估都是线程安全的)。

  • 如果整个语言不允许副作用,那么可以使用任何评估策略;这使编译器可以自由地重新排序或组合程序中表达式的评估(例如,使用砍伐森林)。

  • If the result of a pure expression is not used, it can be removed without affecting other expressions.
  • If a pure function is called with arguments that cause no side-effects, the result is constant with respect to that argument list (sometimes called referential transparency), i.e. if the pure function is again called with the same arguments, the same result will be returned (this can enable caching optimizations such as memoization).
  • If there is no data dependency between two pure expressions, then their order can be reversed, or they can be performed in parallel and they cannot interfere with one another (in other terms, the evaluation of any pure expression is thread-safe).
  • If the entire language does not allow side-effects, then any evaluation strategy can be used; this gives the compiler freedom to reorder or combine the evaluation of expressions in a program (for example, using deforestation).

您可以认为该列表的前言排除了JavaScript中的所有,因为任何操作都可能导致内存分配,内部结构更新等。在最严格的解释中,JS是从不纯洁。这不是很有趣或有用,所以...

You could argue the preface to that list rules out everything in JavaScript, since any operation could result in memory being allocated, internal structures updated, etc. In the strictest possible interpretation, JS is never pure. That's not very interesting or useful, so...

此功能符合标准#1。忽略结果,(foo)=>符号(foo)(foo)=> ()与任何外部观察者相同。

This function meets criteria #1. Disregarding the result, (foo) => Symbol(foo) and (foo) => () are identical to any outside observer.

标准#2给我们带来了更多麻烦。给定 bar =(foo)=>符号(foo) bar('xyz')!== bar('xyz'),所以符号根本不符合该要求。每次调用符号时,您都可以获得一个唯一的实例。

Criteria #2 gives us more trouble. Given bar = (foo) => Symbol(foo), bar('xyz') !== bar('xyz'), so Symbol does not meet that requirement at all. You are guaranteed to get a unique instance back every time you call Symbol.

继续,标准#3会导致没问题。您可以从不同的线程调用 Symbol ,而不会发生冲突(并行),并且它们的调用顺序无关紧要。

Moving on, criteria #3 causes no problems. You can call Symbol from different threads without them conflicting (parallel) and it doesn't matter what order they are called in.

最后,标准#4更像是一个音符,而不是直接要求,并且很容易满足(JS运行时随着时间的推移将所有内容随机播放)。

Finally, criteria #4 is more of a note than direct requirement, and is easily met (the JS runtimes shuffle everything around as they go).

因此:


  • 严格来说,JS中的任何内容都不是纯粹的。

  • 符号()绝对不是纯粹的,因此示例也不是。

  • 如果你关心的只是副作用而不是记忆,那么这个例子确实符合这些标准。

  • strictly speaking, nothing in JS can be pure.
  • Symbol() is definitely not pure, thus the example is not either.
  • If all you care about is side effects rather than memoization, the example does meet those criteria.

这篇关于纯函数可以返回一个符号吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆