信号是否使源代码更易于阅读?


13

在大多数编程语言中,变量没有像PHP中那样具有识别字符。在PHP中,必须在变量前面加上$字符。

例;

 var $foo = "something";
 echo $foo;

我正在为业务应用程序开发一种新的脚本语言,而我的目标用户没有编程背景。这些字符是否使代码更易于阅读和使用?

PHP使用的原因之一$是因为没有它,PHP无法分辨名称是函数引用还是变量引用。这是因为该语言允许奇怪地引用函数。因此,该$符号可帮助解析器分隔名称空间。

我的解析器中没有这个问题。因此,我的问题仅在于可读性和易用性。我已经用PHP编写了多年代码,以至于我$foo很容易将其识别为变量。我只是给该标识符一个偏见偏好吗?


19
IMO,代码是无印记更具可读性
约翰·德沃夏克

6
@JanDvorak +1给了我新的一天。sigils今天我将尝试使用三遍对话。
Reactgular

6
IMO这取决于您的编辑器是否突出显示语法。
CodeBeard 2013年

5
如果您使用var $x = ...或,type $x = ...那么我认为$是过大的。如果您刚刚拥有,$x = ...那么值得这样做。特别是如果您不想在普通编辑器中支持语法突出显示。但是,我不喜欢sigils
CodeBeard 2013年

5
签名像强制的匈牙利符号
棘轮怪胎

Answers:


13

实际的技术可能性和局限性与本主题中所建议的完全不同。让我们先清除那些。

这是$在PHP中使成为可能的东西:

  • 可变变量
  • 具有关键字名称的变量,例如,$return或者能够为变量和函数/常数使用相同的名称,例如$__FILE__

与$前缀无关的限制或功能:

  • 否则无法分辨函数和变量之间的区别
  • PHP字符串插值或模板语法
  • 必需的变量声明

这意味着您没有技术上的原因

foo = "something";
echo foo;

要么

foo = "something";
echo "foo = $foo";
//would print
//foo = something 

但是您不能拥有(假设return是关键字)

return = "something";

无严重并发症。如果您使用类似的前缀$,则不会有任何问题。

这是一种观点,但我认为对于非程序员来说,这是值得的,因为它使他们能够将关键字用作变量名,否则它们看起来像是任意限制:P


关于return = "something";,C#具有“上下文关键字”,这也是设计语言时值得一试的选项。
luiscubal

1
@luiscubal毫无疑问地用C#编写需要一个符号,因此,如果您希望编译该代码,则需要编写@return = "something;"。有一定数量的上下文关键字,是的,但是将它们全部变为上下文关键字将意味着实现起来要复杂得多。
Esailija

7

实际上,Sigil在Perl中更有意义,因为它们提供了一定数量的类型检查。在php中,它们对模板没有多大帮助。通过浏览不同的语言,您可以了解它们的有用性和可读性。几乎没有人使用它们。

在我正在使用的面向最终用户的语言中,我甚至走得更远,使标识符不区分大小写并允许空格和撇号。这使我可以像Karl's height这样使变量名更接近自然语言。


1
+1为变量中的空格,但我不知道如何实现。不确定我是否会更容易阅读。我只是不习惯。
Reactgular

1
我喜欢这个主意。但是我不喜欢为标识符中的空格编写语言的解析器。:-)At Karl's for the night = true;
马丁·约克

但是,很高兴看到我们将所有这些标准添加到一种语言的顶部以帮助我们阅读它。而不是由外部工具手动检查,而是成为语言定义的一部分。这样,我们就不能在编码标准中有关于标识符名称的毫无意义的论据(就像它们在语言中一样)。
马丁·约克

2
但是,不区分大小写存在国际化的问题。如果允许使用多种语言的字符,则在某些语言环境中可能会遇到“相同”的名称,而在其他语言环境中则不会。
luiscubal

1
原则上,在变量中允许使用空格不是什么大问题-只是表示允许多个单词的标识符的语法规则。但是,这的确意味着在语法上如果不产生歧义,其他事情是不可能的。例如,在Haskell中,map sum是部分应用的函数调用-该函数sum作为参数传递给map。但是这两个都是库名,因此对于多字标识符,编译器无法知道map sum是一个多字标识符还是基于两个单字标识符的函数应用程序。
Steve314

7

多年前,我学习了Applesoft Basic。字符串始终后缀为$,数组后缀为%。这就是语言的工作方式。您看了一下,知道了那是什么。我从来没有深入研究解释器来理解为什么是这种情况,或者是由于设计决策才如此。


php中的sigil源自其perl影响(受awk和影响sh)。perl中的标记不仅$可以识别许多不同的类型,还远远不够:

  • $ 标量
  • @ 清单
  • % 杂凑
  • & 代码块
  • * 类型球

标记标识您正在查看的符号表结构的哪一部分。在幕后,foo的符号表条目(通过*foo-typeglob 访问)具有可能是foo的所有内容。有$foo@foo%foo,的格式 foo&foo中,文件句柄富,等...

这也可以使一个变量成为另一个变量的别名:

#!/usr/bin/perl

$foo = "foo";
@qux = (1,2);
*bar = \$foo;
*bar = \@qux;

print "$bar @bar\n";

这会打印出来foo 1 2-在perl中,这就是这些签名的真正目的,不是您应该执行此操作,而是在后台执行此操作。

信号的可读性不是很多,而是使一个信号可以在名称空间中发生冲突$foo@foo不会发生冲突(比较其他两种语言不能同时存在的情况int foo; int[] foo;


可读性标记是任何语言的一部分-读取语法。假设您可以强制类型本身(作为匈牙利符号)作为标识符的一部分。

lex中的内容类似于:

typeChar  [is]
capLetter [A-Z]
letter    [a-z]
digit     [0-9]
%%
{typeChar}{capLetter}(letter}|{digit})* { prientif("iddentifier");}
%%

然后你可能会像

iFoo = 42;
sFoo = "a string";
iBar = iFoo * 2;

我并不是说这是个好主意,而是让熟悉该语言的人能够以本机阅读,并认为它可以增强可读性,而对语言不熟悉的人可能会认为它只是增加了语言杂乱无章。

但是,使用这种方式定义的语言后,我可能可以轻松阅读它。

有些人喜欢他们,有些人不喜欢。在各个论坛中都发生了激烈的圣战,辩论的确如此,这归结为您使用了多少圣战。

可以为非程序员设计一种使用信号的新语言,任何从未编程的人都不会抱怨它们。另一方面,您不能将它们作为语言的一部分,然后让ruby或perl程序员抱怨他们缺少一些关键信息。

真的没关系。重要的是,无论是否使用信号,该信号都将适合该信号。您想做"123 $foo 456"还是必须做"123 " + foo + " 456"?这是应该做出决定的地方。


1
字符串插值(例如"123 $foo 456")未通过sigil前缀启用,并且与之完全正交。
Esailija

1
它是变量插值的一部分,取决于解析字符串的方式。印记可以简化这个过程(也可以做其他的方式如通过做变量替换在javascript中的最佳方式?但这并不是核心语言印记,可以说,使它更容易编写和理解这一部分。

1
@MichaelT不,变量具有前缀这一事实并不会使实现字符串内插变得容易或困难。它们只是2个完全不相关的事物。对于人类读者来说,$asd如果$已经将其用于变量前缀,则可能是在字符串插值语法中使用的不错选择,但与最初实现字符串插值的实际可能性无关。
Esailija

2
@Esailija您能描述它们之间的关系吗?另外,来自en.wikipedia.org/wiki/Variable_interpolation- “支持变量插值的语言包括Perl,PHP,Ruby,Tcl,Groovy和大多数Unix Shell。在这些语言中,变量插值仅在字符串文字为用双引号引起来,但不能用单引号引起来。因为这些变量在这些语言中以符号(通常为“ $”)开头,所以可以识别变量。

@MichaelT在变量前缀和字符串插值中使用的美元符号完全是肤浅的选择(它仅具有可读性参数,与实现#无关,例如,它可能也用在coffeescript中。而coffeescript没有前缀带有#-实际上没有任何变量的前缀)
Esailija

3

我不同意PHP使用$来使func与var不同。至少因为PHP具有类似C的语法,而funcs()在名称后有括号。

阅读有关堆栈溢出的这篇文章,了解为什么$在PHP中。

许多流行的语言,例如C,C ++,C#,Java都不使用$,我们可以将easy var与function区别开。

例如,在PHP中,$会帮助您编写:echo“ var = $ var”

没有$,这种技巧将是不可能的。


+1 ah确实更有意义。谢谢。
Reactgular 2013年

3
具有信号的语言与具有字符串插值的语言无关,如您的示例echo "var = $var"

4
-1。PHP语法的怪异并不是由于某些实际限制,而是因为语法规则设计得很差,即使根本没有设计。这就是为什么他们需要黑客来启用fn()[]明智的语法,而这些语法本来就不需要思考就可以使用。
Esailija

@svidgen是的。您无法安全地进行字符串插值,而无需采取任何方法来指明应该将字符串的哪一部分映射到变量。其他语言以认为烦人/不必要的冗长结尾,例如Python的字符串格式。但是,PHP也有其他优点:RuslanZasukhin不正确地说函数将始终用括号表示,因为它们也可以作为引用传递。
Izkata

@Izkata在语言中使用变量的方式与字符串插值语法无关。但这暗含了这个答案,因此为-1 ...
Esailija

3

在所有这些答案之后,我想对马修·福斯卡里尼(Mathew Foscarini)提出更多意见。

  • 您现在将问题视为“语言构造函数”。您尝试了解为什么另一种语言具有此功能或该功能来选择是否使用自己的语言。我多年担任同一职位,因为为我们的Valentina数据库开发SQL解析器。
  • 我建议您浏览antlr.org,甚至阅读Terence的书。对于语言开发人员来说,它有很多好处。
  • 我仍然不同意其他答案揭示的“理由”。他们认为PHP的主要作者决定使用$来使用保留关键字,并且更好地将变量与非变量区分开。我不这么认为……尽管证明只能是他/他们自己的故事。
  • 很可能他们只是遵循perl和更多早期语言。着重于Terrence的是,大多数语言都是相似的,尤其是在LEXER部分。通常,一种新语言的构造者只需选择他将要开发的语言,然后采用该语言语法的词法分析器即可。这就是您现在应该做的。无需从头开始发明。我敢打赌,PHP作者也是如此。
  • 人们提到的所有其他内容:
    • 区分变量和非变量
    • 将单词存储为变量名
    • 将变量放在字符串内的能力
    • 可能是其他(我不是PHP方面的大专家)

此LEXER的副作用,因为它能够识别令牌。

举个例子:在SQL中,我们使用“”来使用带有保留字的标识符,甚至使用带有空格的标识符“ First Name”,“ Group Name”。GROUP是一个关键字。有问题-有特殊的解决方案。

PS:MichaelT的很好​​评论。


+1感谢您的大力链接。我最终使用了这个,但是您的链接看起来好多了。goldparser.org
Reactgular

也感谢您的链接。我以前没有看到这个黄金解析器。看起来也很有趣。
Ruslan Zasukhin

@RuslanZasukhin如果您引用我的答案,我从未说过开发人员启用关键字的意图。我只说过,当变量以开头时,使用关键字作为变量名在技术上成为可能$。同样,“能够在字符串中放置变量的能力”并不是因为变量以开头,例如$。也就是说,"123 $foo 456"即使变量语法为foo = 3或,也可以使用@foo = 3。它们彼此不相关。
Esailija

3

...印记允许:

  • 更好地区分变量和非变量。仍在学习基本概念的人可能难以确定哪些单词是变量,哪些不是变量。他们通常是从没有足够背景的示例或其他人的代码开始阅读。

  • 使用保留的关键字函数名称作为变量名称。有时,我发现其中一些名称是变量的正确名称(即$count,在count()定义函数的同时),并感谢sigils允许我使用它们。

另外,我碰巧经常重复使用函数名称,以将函数的结果保存在一次性变量中,例如:

$isdir=isdir($dir);

if(/* complex condition implying $isdir */) {
/* etc */
}


1
ZHR,什么更好?在C ++中,我们编写所有不带$的变量,并且可以完美,轻松地区分它们。范例:{int z = 0; z = 55;Z Z); 在C ++中,如果需要分配函数名,例如函数指针,也可以使用函数名。
Ruslan Zasukhin 2013年

@RuslanZasukhin,计算机文盲,你知道吗?尝试教他们C ++,您会感到惊讶。
ZJR

另外:我认为$标记不一定总是标志。我记得当我还是个孩子的时候,美元符号使我感到困惑,因为它固有的货币关联。%可能是一个可行的选择。
ZJR
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.