某些编程语言如何区分函数和函数指针?
我主要谈论的是函数式编程语言。例如,map 的维基百科文章在 Haskell 中有这个示例- ish 语言:
map square [1,2,3,4,5]
解析器/编译器如何知道我们要将函数 square
传递给 map
作为高阶函数,而不是尝试调用函数本身?对于具有静态类型的语言,表达式 square [1,2,3,4,5]
显然无法编译,但是编译器真的会使用它来确定这不是我的意思吗?
或者,这只是 Wikipedia 中的一个糟糕示例,更好的示例可能类似于 map &square [1,2,3,4,5]
(使用 C 风格函数引用)?
I'm talking mostly about functional programming languages. For example, the wikipedia article for map has this example in a Haskell-ish language:
map square [1,2,3,4,5]
How does the parser/compiler know that we want to pass the function square
to map
as a higher-order function, and not trying to invoke the function itself? For languages with static typing, the expression square [1,2,3,4,5]
obviously wouldn't compile, but would a compiler really use that to determine that's not what I meant?
Or, is this just a bad example from Wikipedia, and a better example might look like map &square [1,2,3,4,5]
(using C-style function referencing)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,函数应用程序具有最高优先级。因此,当解析器遇到“map”时,它会将右侧的第一个参数作为第一个参数。映射类型需要一个函数作为第一个参数,并且“square”被定义为函数,因此类型是兼容的。您可以将地图方块视为需要数字列表的函数。
关键是按照优先级规则检查类型并验证参数类型。
First of all function application has the highest precedence. so when the parser encounters "map" it will take the first thing to its right as the first argument. map type expects a function as first argument, and "square" is defined as a function, so types are compatible. You can think of map square as a function that is expecting a list of numbers.
The key is to examine types, and verify arguments types, following precedence rules.
这只是一个解析问题:Haskell 中的函数应用程序是左关联的,因此
map square [1, 2, 3, 4, 5]
被解析为((map square) [1 , 2, 3, 4, 5])
而不是(map (square [1, 2, 3, 4, 5]))
。It's just a matter of parsing: function application in Haskell is left-associative, so
map square [1, 2, 3, 4, 5]
is parsed as((map square) [1, 2, 3, 4, 5])
rather than(map (square [1, 2, 3, 4, 5]))
.这取决于语言。
例如,在 Javascript 中,您可以通过在函数
f
后面不加括号来引用该函数。这里,f被视为函数指针。
在这里,它被视为函数调用:
在 Scala 中,规则要复杂得多,并且编译器在“猜测”是否调用或引用该函数方面有一定的余地。请参阅 Scala 方法调用中括号的规则是什么? 以获得更详细的解释。
It depends on the language.
In Javascript, for example, you can reference a function
f
by simply not putting parentheses after it.Here, f is treated as function pointer.
Here, it is treated as a function call:
In Scala, the rules are quite a bit more complex, and the compiler has some leeway in "guessing" whether or not you're invoking or referring to the function. See What is the rule for parenthesis in Scala method invocation? for a more detailed explanation.