编程语言为什么要使用逗号来分隔函数参数?

20

似乎所有编程语言都使用逗号(,)来分隔函数参数。

为什么它们不使用空格呢?


8
我可以建议将“难道你不认为空格会是更好的分隔符吗?”改为更接近于“为什么他们不使用空格呢?”这样的表述,以免被关闭为主观和争论性问题。我认为这是一个有趣的问题,如果被搁置将会很遗憾。 - Richard JP Le Guen
@Richard JP Le Guen:好观点。已解决。 - Emanuil Rusev
1
哦,我不知道,历史?有一种著名的语言(C语言?)有这种语法,然后所有效仿者都跟进了?:) - Yi Jiang
6
@Yi:更像FORTRAN。 - Nordic Mainframe
2
如果我们知道哪种语言应该使用空格而不是逗号,回答您的问题可能会更容易。有些语言确实使用空格,而一些使用逗号的语言(例如C#和Java)使用空格可能会遇到问题。 - ravibhagw
14个回答

57
绝对不行。那这个函数调用呢:
 function(a, b - c);

如果用空格代替逗号,那会是什么样子?

 function(a b - c);

这是否意味着 function(a, b - c); 或者 function(a, b, -c);?逗号的使用可能源自数学,数学中几个世纪以来一直使用逗号来分隔函数参数。


22
在使用空格作为分隔符的语言中(如 lisp、ml、haskell),这个表达式看起来会像是 function a (b - c)(或在 lisp 中是 (function a (- b c)))。 - sepp2k
5
因此,在这些情况下,括号用于消除参数的歧义。我将OP的问题理解为“您不认为在当前使用逗号的语言中,空格会是更好的分隔符吗?”在这种情况下,可以使用括号加空格,但这与使用逗号相比有什么优势呢? - Carl Norum
如果语言像 Haskell 和 ML 一样实现(将 foo x y z = ... 定义为 foo x = \y -> (\z -> ...),其中 \ 开始一个 lambda,从而使部分应用变得非常容易),这可以使一些函数式代码更加优美。考虑 sumOfOddSquares = sum . filter odd . map (^2) $ [1..](摘自 Learn You A Haskell)。 - user395760
4
您的例子之所以存在歧义,是因为“-”既可以是一元运算符也可以是二元运算符。如果消除这种歧义,那么使用空格就变得可行了,就像其他任何二元运算符一样:使用函数时写作 function(a b^c) 或 function(a b 0^c)。请注意,我的翻译旨在使原文更易理解,但并未改变其原本意思,不包含任何额外的解释或信息。 - manixrock
7
提到数学加一点赞,这个符号确实起源于数学。 - Donal Fellows

48

首先,您的前提是错误的。有些语言使用空格作为分隔符(lisp、ML、haskell,可能还有其他语言)。

大多数语言不采用空格作为分隔符的原因可能是a) f(x,y) 是大多数人从数学中习惯的表示法;b) 使用空格会导致很多嵌套的括号(也称为“lisp效应”)。


6
减少函数调用中的括号并不会导致更多的括号。导致大量括号的原因是将许多需要分组的部分组成大表达式(在任何语言中都是如此)。在Lisp中,括号基本上是唯一的结构符号,而其他语言也使用“,;.{}`”等符号... 因此,由于括号履行了所有这些符号的功能,当然会得到更多的括号(但较少的大括号等)。 - sth
2
还有Haskell $运算符,它非常有用,可以消除最后一项周围的一组括号,例如sum(foo 3 (bar 23 5))等价于sum $ foo 3 $ bar 23 5。 - Chris Smith
如果我没记错的话,有一个反例。Forth使用空格作为分隔符,并且最小化使用括号。 - ypercubeᵀᴹ
@ypercube:Forth使用空格作为“语句”分隔符。它实际上没有函数参数的语法。函数将只使用当前堆栈上的内容。 - sepp2k

12
类似Lisp的编程语言使用:(f arg1 arg2 arg3),这基本上就是你所要求的。ML-类似的编程语言使用连接将柯里化参数应用于函数中,因此您可以编写f arg1 arg2 arg3

我喜欢它。有没有流行的服务器端语言具有类似的语法? - Emanuil Rusev
1
@Emanuil 很少有语言使用S表达式,而且它们都不是很流行。其他函数式语言也是如此,虽然它们在概念上通常相似,但语法更加传统。 - user395760
1
@Emanuil 受欢迎吗?这取决于你的定义。有一些针对“受欢迎”的Lisp编程语言的Web框架,尤其是Common Lisp和Scheme。 - jdd
1
@Emanuil:我相信你在看Clojure;它有一个健康的Java库生态系统,以及你非常喜欢的Lisp风格的语法;-) - sasuke

6

Tcl 使用空格作为传递给命令的单词之间的分隔符。如果有复合参数,那么必须用括号或其他方式加以引用。请注意,即使在此处,您也会发现逗号作为分隔符的使用 - 仅在表达式语法中 - 但这是因为该表示法在编程以外的常见用途中被广泛使用。数学已经使用这种方式书写了n元函数应用很长时间了;计算机(尤其是Fortran)只是借鉴了这种表示法。


5

有许多历史原因,已经指出。

此外,在大多数语言中,逗号,用作分隔符,空格序列大多被忽略,或者更准确地说,虽然它们可以分隔标记,但它们本身不起作为标记的作用。这对于所有从C语法派生其语法的语言来说都是正确的。一系列空格就像空单词一样,让空单词限定任何东西可能不是最好的想法。

此外,我认为这样更清晰、更易读。为什么要有看不见的字符——空格,本质上除了格式化之外没有任何作用,作为真正有意义的分隔符呢?这只会引入歧义。其中一个例子是卡尔提供的。

第二个例子是f(a (b + c))。现在是f(a(b+c))还是f(a, b+c)

JavaScript的创建者有一个非常有用的想法,与您的类似,但也存在同样的问题。这个想法是,如果语句完整,回车也可以作为;。请注意:

function a() {
    return "some really long string or expression or whatsoever";
}

function b() {
    return 
          "some really long string or expression or whatsoever";
}
alert(a());//"some really long string or expression or whatsoever"
alert(b());//"undefined" or "null" or whatever, because 'return;' is a valid statement

事实上,有时候我会在那些没有这种“特性”的语言中使用后一种符号表示法。JavaScript强制我按照一种方式格式化代码,因为有人想到了使用回车键而不是分号;
我认为,有很多好的理由解释为什么某些编程语言会以它们当前的形式存在。尤其在动态语言(如PHP)中,没有编译时检查的情况下,编译器无法提醒你,如果解析二义性的方式与你要调用的函数签名不匹配,你将会遇到很多奇怪的运行时错误和非常困难的生活。
虽然有一些编程语言允许这样做,但背后也有很多原因。首先,一个很聪明的团队花费了相当长的时间设计语言,然后发现它的语法使得,大多数情况下都是不必要的,于是就决定将其删除。

大多数语言不使用不可见的空格。空格会明显地移动非空格字符,无论是用于标记分隔、缩进还是显示新行。括号很方便,可以避免歧义或错误。在 carl 示例中,您可能也将空格作为标记分隔符,因此答案将是第二个。在上面的 JavaScript 示例中,您只需要在第一行打开一个括号,然后就可以自由格式化了。您只需要在使用时付费,而不是每行都加上“;”。 - ReneSac

5

我们不必去看自然语言中的大部分语言,就可以看到逗号用于分隔列表中的项目。因此,对于第一次学习编程语言的人来说,使用除逗号以外的任何东西来列举参数都会出乎意料。


3

Haskell 不使用逗号。

示例

multList :: [Int] -> Int -> [Int]
multList (x : xs) y = (x * y) : (multList xs y) 
multList [] _ = []

在C/C++中使用逗号的原因是,如果没有逗号作为分隔符,读取一个长参数列表可能会很困难。请试着阅读以下内容。
void foo(void * ptr point & * big list<pointers<point> > * t)

逗号就像空格一样有用。在拉丁语中,没有使用空格、句号或小写字母。

试着读一下这个:

IAMTHEVERYMODELOFAWHATDOYOUWANTNOTHATSMYBUCKET

主要是为了帮助你阅读东西。


在你的 Haskell 示例中,我认为你想说的是 Int -- 字面类型名称总是以大写字母开头。此外,在 multList 的第一个 case 的表达式侧面,multList 的调用没有应用足够的参数。如果听起来有点迂腐,那很抱歉,但是代码示例无误会更有帮助。 - Chris Smith
@Chris Smith - 没错,你说得对。我只是在两分钟内凭记忆编写了它,没有仔细检查。现在正在修复它。 - BT.
你的意思是第一行不使用逗号而是使用空格。 - amd

3

这可能听起来有点“明智”,但我认为大多数地球语言使用它的原因相同(英语、法语和其他几种语言;-)此外,对于大多数人来说,这也是直观的。


口语并不使用它...只是我个人的意见:它只是用于书面语言以便更容易阅读。 - hurikhan77
8
@hurikhan77 - 我不太同意。尝试听一个擅长朗读的人(大多数人都不行)。稍微集中注意力,你就能轻松地判断出句子中逗号的位置。 - Rook

2

似乎所有编程语言都使用逗号(,)来分隔函数参数。

在包含逗号的自然语言中,该字符用于分隔事物。例如,如果您要枚举水果,您会写:"柠檬,橙子,草莓,葡萄",即使用逗号。

因此,在函数中使用逗号分隔参数比使用其他字符(例如 | )更自然。

考虑:

someFunction( name, age, location ) 

vs.

一些函数( 名称|年龄|位置 )

为什么他们不只使用空格呢?

这是可能的。 Lisp就是这样做的。

主要原因是,空格已经被用来分隔标记,不需要再分配额外的功能。


2

这不是真的。有些语言不使用逗号。在编程构造之前,函数已经是数学概念,因此一些语言保留了旧的符号表示法。而大多数新语言都受到C语言的启发(例如Javascript、Java、C#和PHP),它们共享一些形式规则,如逗号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接