您希望语言设计师注意什么?[关闭]


38

这个问题的目的不是要整理一些编程语言功能,这些功能是您不能没有的,或者希望使用您选择的主要语言。这个问题的目的是揭示大多数语言设计师可能没有想到的语言设计的角落。因此,与其思考语言特征X,不如多加思考。

我的偏见之一,也许是有争议的,是工程学的较柔和的一面(为什么和为什么)比更为具体的一面要重要许多倍。例如,Ruby的设计目标是提高开发人员的满意度。尽管您对于是否可以交付发表意见不一,但事实上这是一个目标,这意味着语言设计中的某些选择受该哲学的影响。

请不要发布:

  • 语法火焰大战。面对现实,我们有我们的喜好,语法很重要,因为它与语言设计有关。我只是想避免emacs与VI的本质之间的史诗般的战斗(如今,很多人对此一无所知)。
  • “任何不具有功能X的语言都不应该存在”类型注释。所有编程语言都存在的至少一个原因-好的或坏的。

后:

  • 语言设计师似乎错过的哲学思想。
  • 似乎实施得不好的技术概念经常会出现。请提供一个示例,说明造成疼痛的原因,以及您对如何使其功能有任何想法。
  • 您希望的东西在平台的公共库中,但很少。一个相同的标记,通常在您希望的公共库中没有的东西。
  • 您希望所有编程语言都能正确实现并正确定义的概念性功能(例如内置的测试/声明/合同/错误处理支持)。

我希望这将是一个有趣而有趣的话题。

编辑:澄清了我的意思是语法火焰战争。我并不是想避免对语法的所有讨论,特别是因为语法是程序语言设计的基础部分。


说语法只是实现细节,这完全是错误的。语法设计是设计语言的根本重要组成部分。您确实希望看到的许多要点实际上可能涉及语法。可怜。似乎是一个有趣的问题。
康拉德·鲁道夫

我要避免的是火焰战争。如果您可以在不开始争论的情况下讨论语法,那就去吧。
Berin Loritsch 2011年

Answers:


49

默认情况下支持Unicode

如今,正在开发程序以在国际范围内使用,或者是在可能会在国际范围内使用的前提下进行开发。他们必须为其字符集提供支持,或者使用该语言编写的程序无效。


2
+1实际上,语言本身应允许您使用任何字符作为标识符。我们不是全英文。
Berin Loritsch 2011年

13
@Berin:实际上,即使我是法语,我还是更喜欢英语课程。问题是交流中的一种,如果您使用匈牙利语,西班牙语或葡萄牙语标识符编写程序,不要指望我能参与进来...在国际化的背景下,开发人员之间能够进行交流非常重要,这意味着对标识符,注释和文档使用通用语言。英语是开发人员的通用语言。
Matthieu M.

11
我要补充一点,使用该语言时,unicode支持应该是自然的。如果可能的话,不应该花费额外的精力来“添加”它,而应该“正常工作”(在合理的情况下)。
RHSeeger 2011年

4
相关地,该语言应该在文本(字符序列)和二进制(字节序列)数据之间做出根本的区分。C#通过string和获得正确的权限byte[]。就像Python 3.x和str和一样bytes。C(++)char犯了这个可怕的错误。
2011年

1
@RHSeeger-的确如此!即使在Python中,您也必须输入u'My Unicode Štring'。我希望您忘了您要处理的是哪种类型的字符串,而忘记编写代码。
orokusaki 2011年

25

我有几个:

  • 泛型/模板。例如,Java泛型功能强大,但不一定灵活。另外,由于它们使用类型擦除,因此我看到抽象地实现它们的问题,尤其是在接口中。而且,当使用非特定的泛型时,编译器不应发出警告(例如Hashmap代替Hashmap<String, int>)。我认为可以对其进行重大改进。好的模板非常有用,但是经常被忽略。

  • 标准库中的Good Date支持。我的意思是能够添加和减去日期,小时和分钟,而不必处理自1970年1月1日以来的毫秒数。


2
不过,“良好的约会支持”是一个非常苛刻的要求!那有什么意思?我认为日期和时间是您无法全面解决的问题之一。要么使它变得简单或错误,要么使它变得正确而又不复杂。很难找到一个好的中间地带。
萨拉

@kai关键是日期支持通常非常糟糕。旧java.util.Date有几乎所有可能的陷阱和问题。我只知道新java.time.*软件包的一部分,但是它很干净,易于使用且没有AFAICT错误。更高级的用户可能会发现问题,但这是巨大的改进。+++问题似乎是,这是一个复杂的问题,第一个版本被匆忙破解了。
maaartinus

24

请让计算机安全人员可以分析/审核您的语言。

安全人员需要能够在程序发布之前找到程序中的漏洞。理想情况下,我们会在早期被调用,并且可以在代码库开发时对其进行评论,但通常不会。

当出现新版本的语言或核心库时,以前安全的事情可能不再是:

  1. 库可能会变得更强大:例如,URL库现在支持 javascript:
  2. 可能会有新的方式将字符串或字节转换为代码:例如,eval或反序列化库
  3. 语言反射技术可能会变得更加强大:例如,暴露局部变量

这些更改中的任何一项都可以增加程序具有的可滥用权限,但是由于程序使用的权限(当与非恶意客户端打交道时)没有更改,因此安全人员很难在不进行大量操作的情况下就找出来。重新审核。

因此,在设计和版本化语言时,请考虑我们。以下是一些提示:

定义一些可以分解为程序的原语。

这样HTML5尤其糟糕。他们显然把很多心思的安全,并有一些非常聪明的人,但不是指定新节目元素,如<video>在旧的条款,或创建一个共同的抽象,新<video><img>两可的条款规定,<video>又是另一个一次性程序元素,其自身会带来安全后果。

使您的语言适合静态分析(即使不是静态类型的)。

安全人员经常使用静态分析来查找模式,并尝试排除程序的某些部分,以便他们可以专注于真正棘手的部分。

显而易见,哪些标识符是局部变量,哪些不是。

例如,不要与旧版本的JavaScript犯同样的错误,这使得在下面的代码中无法分辨是否x是局部变量引用(根据规范的旧版本的字面意思):

if (Math.random() > 0.5) {
  Object.prototype.x = 0;
}

function f() {
  var x = 1;
  (function () {
    alert(x);  // Might alert 0, might alert 1.
  })();
}

允许可分解的安全性

许多安全系统是围绕安全内核设计的,该内核保留了安全属性,因此安全人员可以集中精力分析少量代码,并使大多数程序员不必面对烦人,烦躁,偏执,偏执的安全人员。 。

应该可以使用您的语言编写这样的内核。如果您的语言的安全性之一是是否仅会提取URL的特定子集,内核编写者是否可以做一些事情来引导所有URL提取通过他们的代码?或者,静态构建检查(例如查看导入)可以起到相同的作用。

有些语言(例如Newspeak)使用对象功能模型。这是获得可分解安全性的绝佳方法。

但是,如果您不能做到这一点,那么使模块图成为可静态分析的工件可以为您带来很多好处。如果我可以证明某个模块无法到达文件I / O模块(通过在TCB中调用模块中的代码除外),则可以从该模块中排除所有类的问题。

限制嵌入式脚本语言的权限

许多有用的系统被组织为一个静态核心,它启动了许多用动态(甚至功能)语言编写的代码。

嵌入脚本语言可以使系统更具扩展性。

但是脚本语言不应具有VM的全部权限。

如果您选择允许嵌入式脚本语言,请使调用者可以轻松地限制其功能。一个对象能力模型(请参见上面对Newspeak的评论)在这里非常合适;因此,在使用脚本语言评估代码时,调用者应传入要执行的代码以及该代码的所有全局变量。

治疗eval作为一种语言本身嵌入的脚本语言

如果您的语言可以调用自己的编译器将字符串转换为代码,则可以像使用任何嵌入式脚本语言一样,对其进行沙盒处理。

使用简单的并发模型

我们的安全人员在试图弄清楚是否维护安全资产时,不希望担心种族状况。

在建立线程之前,请考虑使用线程替代方法作为几乎无法保护的默认选项。

一个简单的例子就是事件循环并发,就像在E,Verilog和JavaScript中发现的那样。

不要鼓励引述混乱

有些语言是粘合语言,最终它们会处理许多不同语言的字符串。

例如,JavaScript通常包含HTML,CSS,XML,JSON甚至JavaScript的字符串。程序员很难记住在将纯文本字符串组合成其他语言的字符串时正确地编码它们,因此,毫无疑问,JS程序会遇到各种引语混乱的问题:XSS最糟糕。

如果要包括字符串组成功能,请尝试减少程序员的安全负担。DSL,卫生宏和嵌入式模板语言可以通过将负担适当地转移到图书馆或语言开发人员身上,并远离最终开发人员来实现此目的。


美丽的故障。
Qix 2014年

23

一些最好的语言是由想要自己编写语言的人设计的。

因此,我认为语言设计师应较少关注用户。您不能取悦所有人,也不应尝试。


4
在一定程度上可能是正确的。但是,如果您从未听过用户的话,就永远不会知道他们在尝试使用您的大脑孩子时给他们带来的痛苦。如果没有听到/感觉到这种痛苦,您将永远不会想到解决该问题和其他问题的下一个好主意。没有人是与世隔绝的。疼痛可能是创新的重要动力。
Berin Loritsch 2011年

5
@Berin:我不认为重点是您永远不要听用户的话,而不要听那些想要使用该语言的用户不想要的东西。如果您设计了一种语言来解决特定的问题,那么您应该迎合也需要解决这些问题的用户。但是,您确实要解决极端问题,有时一种语言可以在新域中找到合适的位置,因此+1。
Jeremy Heiler 2011年

2
@杰里米,是的,这正是我在说的,但是我认为一种语言在非设计领域中正常工作并不常见。
dan_waterworth 2011年

@dan_waterworth:成功的语言通常可以在非设计领域中正常工作。
David Thornley

8
建议最好用“不要听您没有的用户”来代替“不听用户”。
chrisaycock 2011年

16

实际编写代码仅花费5-10%的时间。语言设计人员应注意使软件真正起作用的困难,这意味着要修复错误和错误。

这意味着从一开始就应该有一个好的调试器。没有一些具有奥术语法和关键命令的工具,仅比大量的打印语句要好。


2
+1。调试是某些语言比其他语言要好的地方之一,而某些IDE则使可用语言与妨碍您使用的语言完全不同。
Berin Loritsch 2011年

2
我将对此加以说明,并在可能的情况下说出有用的堆栈跟踪。如果有错误(或未捕获的异常或其他情况,具体取决于您的语言),我希望能够查看到达该错误的整个调用堆栈,以及所使用的参数值。Tcl的表现特别出色。.但是,公平地说,Tcl中的所有内容都是字符串,因此您可以相对轻松地打印出所有内容的价值。
RHSeeger 2011年

1
不只是调试,而且使编写错误变得困难。当Java引入数组自动边界检查时,我感到非常高兴……但是15年后的今天,我们仍然在用其他语言犯这些错误。
Alex Feinman

3
有一种在编译时找到Bug的语言会更好吗?例如,当我使用Ada时,与在使用C或C ++时相比,在调试器上花费的时间明显减少。
马丁

12

我认为他们应该注意Python,它做的事情比我遇到的任何其他语言都正确(即使您不喜欢某些功能)。这并不意味着他们应该模仿Python,但是即使您根本不想制作像Python这样的语言,了解Python正确的做法也很重要。

至于与之相关的哲学思想,这是Python Zen中最重要的思想:

  • 显式胜于隐式。
  • 可读性很重要。
  • 特殊情况不足以违反规则。
  • 尽管实用性胜过纯度。
  • 应该有一种-最好只有一种-显而易见的方法。
  • 如果实现难以解释,那是个坏主意。
  • 命名空间是一个很棒的主意-让我们做更多这些吧!

我认为遵循这些规则的语言必须一定可以,但是我只知道做到这一点的人,那就是Python。对于与Ruby在实现上的所有相似之处,Ruby错过了诸如可读性之类的东西,并邀请您进行代码高尔夫,这很有趣,但在专业环境中没有用。

我在Python中缺少的唯一技术功能是“直到”语句(例如while,但不是第一次测试该表达式)。然后,Python和其他语言标准库中都有很多可以改进的地方,但这并不是严格意义上的语言,因此这是一个不同的问题。:-)


4
我认为还有两件事更重要,尤其是在语言设计级别上:“特殊情况不足以打破规则。” 因为带有一千个特殊情况或奥秘规则的语言很难使用,并且与“尽管实用胜过纯粹”相结合。因为否则,您会进入巡视沥青的领域。

15
如果显式比隐式好,那么为什么不要求声明变量呢?当简单的错字可能导致难以调试的错误时(与编译时捕获的错误或明显且易于调试的运行时错误相反),这就是对IMO语言的主要打击。
梅森惠勒

4
@Mason Wheeler:必须用其他语言声明变量的唯一原因是必须声明它们是哪种类型。Python是动态的,因此不需要类型声明,因此也不需要声明。我看不出这与隐式/显式有什么关系。Python中的类型是显式的。变量也是如此。十年后,错字从未造成难以调试的错误。实际上,它们很容易调试。
Lennart Regebro 2011年

8
列表+1,狂热者-1。注意所有已获得重大成功的语言,并尝试合并或至少分析这些元素的适用性似乎是更务实的方法。
史蒂文·埃弗斯

3
@Lennart:我想说(但不是必需的,请参见规则4)显式声明函数的类型是一件好事。它类似于按合同设计。这就是我要提出的重点。
Theo Belaire 2011年

11

对我来说,修改语言以适应您的需求的能力是很大的。对于使用宏完成的Lisp,对于具有更高级别的Tcl。在较小的程度上,Ruby使用lambda等。我只希望能够添加适合该问题的新控制结构,而不是围绕可用的控制结构成型问题。举一个简单的例子,在某些语言中存在的“ do ..直到”结构比“ while”结构更干净,是处理某些情况的一种方式,能够添加新的结构来满足其他情况是非常有用的。

从更一般的意义上讲,这是元编程……但是我主要使用它来构建新的控制结构。


有趣。良好的元编程支持可能很难获得正确的支持,但在功能强大的情况下却非常强大。我从喜欢Lisp的人那里听说Lisp的实现是最好的-但是他们对Lisp中的所有内容都这么说。您认为元编程正确的任何示例吗?
Berin Loritsch 2011年

“正确完成元编程”必须在正确的地方做得很简单(嗯,对于合理的简单活动),并且最终结果感觉就像是语言的自然组成部分。
Donal Fellows

1
不仅是可修改的,而且是可解密的修改。如果您重新映射了该语言中的某些内容,那么作为读者,我应该能够迅速找出来。注释或其他外部标记可以帮助解决此问题。
Alex Feinman

我认为Mata-Lua或Template Haskell在提供此功能方面做得很好。(不如Scheme宏那么好,但这就是您为在语言中使用更多然后是parens付出的代价)
Theo Belaire 2011年

10

最重要的是,您的语言需要具有“风格”。例如,我将C称为基于指针的系统编程语言。我将Erlang称为高度并发的函数式编程语言。艾伦·凯(Allan Kay)称其他一些语言(例如C ++和Java)为“凝集”语言:科学怪人的语言由许多特性组成。

接下来最重要的是,更改语言本身应该是不得已的方法。当与该语言的其他功能结合使用时,即使是最温和的声音也可能变得复杂。我要说的是,要以一种语言添加新功能,您需要:

  1. 证明这是真正必要的。
  2. 证明它不能在库中完成。
  3. 证明它属于该语言。

2
换句话说,该语言应具有一个总体设计原则,并且该语言应与该原则一致。关于语言进化的评论是有必要的(我已经看过几次了)。
Berin Loritsch 2011年

1
让我想起了我最喜欢的C ++报价... 将多余的腿钉在狗上制成的章鱼。
ocodo 2011年

4
证明不能在库中完成。+1
Qix 2014年

2
我喜欢图书馆的花絮。像haskell这样的语言没有内置的控制流之类的东西(例如循环,异常或延续),这很酷。它们在语言中定义起来非常简单,可以保持语法真正整洁,并通过提供许多巧妙的语言功能来提高可扩展性和可组合性。
2016年

10

谢谢你问一个很好的问题。您会得到一些很好的答案。

不要让您眼前一亮,但我将程序员视为一个信息渠道。想法/概念/需求进入了另一端,而代码则出炉了。

如果您将一组需求(无论如何陈述)和一组代码放在一个巨大的白板上,然后画线将每个需求映射到实现该需求的代码,那么该图的复杂度将取决于代码的性能表达要求。理想情况下,它应该非常直接并且一对一,但这在实践中很难实现。

我衡量一种语言的领域特定性,以此来简化该图。这是一个非常理想的属性,可以通过多种方式来实现,从定义正确的类/例程(名词/动词)到宏,再到编写自己的解析器和解释器/编译器,都可以通过任何方式来实现。

让我举一个例子说明我的意思。对于创建灵活的对话框用户界面的问题,该技术消除了编写事件处理程序,数据移动以及大多数通常在UI中完成的工作的麻烦。它还导致源代码减少大约一个数量级。元语言实际上只是C / C ++ / Lisp中的一些例程和宏,而我也已经在没有宏的语言中做到了。

如果可以通过对代码进行5个点编辑或对10个代码进行编辑来实现需求,那么用5个代码进行编辑不仅可以减少代码编写量,而且可以减少错失一个步骤并引入错误的机会。因此,一种特定于语言的语言越多,代码越小,更易于维护且更没有错误。我认为我们需要知道如何实现这一目标。它不是指的是代码的可读性,除非读者已经投入的学习曲线,了解技术。


9

有界和独特的整数类型,例如Pascal和Ada。老实说:您多久需要一次整数的全部范围?我认为在原始类型方面有很多地方需要改进,以更好地表示现实世界。


2
有界整数类型ala C,C ++,D,Java,C#等肯定有它们的位置。某些类型的编程无关紧要,只需要区分整数和浮点数即可。即使那样,也许我们只需要一个数字类型,而后再担心数字的整数部分?简而言之,与数字是整数这一事实相比,业务编程对特定的整数类型不那么敏感。在较低级别实施协议时,规则会发生巨大变化。
Berin Loritsch 2011年

2
我认为,Ada的类型在哪里,您可以说,type Date_Of_Month is 1 .. 31;然后将诸如16或32位的决策留给优化器。但更重要的是,将32或0或-5分配给该类型的变量会给您一个RANGE_ERROR
马丁

范围对于Date_Of_Month(或Month_Of_Year)有明显范围可使用的东西很有效,但是很多(可能多数)情况是模糊的。 type Persons_Age is 0..120?如果有人打破寿命记录怎么办? type Year is 0..9999?如果您是埃及学家怎么办?
dan04 2011年

如果您是一位埃及学家,那么您根本就不需要type Egyptian_Year is -9999 .. 300;。以我的经验,大多数时候都可以找到有用的整数边界。在这方面,您应该考虑type Scrolls_Found is array Egyptian_Year of Natural;您不能/不应该将无限制的类型作为数组索引。这只是黑客的攻击手段。顺便说一句:Ada允许在运行时计算范围边界。
马丁,

1
@kai没有人说类型系统的这一特殊功能必须无处不在的使用。我确定Ada也允许使用“常规”数字类型。有界数字类型对于某些(相当常见的)问题肯定很有用。
Sarge Borsch

8

一旦学习了某些功能,它们就使编程语言易于使用,并且有些特性使它们易于学习和使用。由于理想情况下,一种语言的用户与它具有长期的关系,因此优化易用性要比优化易学性更好。不要让事情变得不必要的困难,但不要为了不熟悉该语言的人而牺牲表达力(能够编写一些能做很多事情的代码)以提高可读性。另一方面,对于已经使用该语言多年的人来说,该语言不应像行杂音那样读;使用起来或学习起来都不容易。


8

命名约定(我在看您的PHP)


但是,语言设计问题较少。当然,您始终必须注意进入标准库的内容,但是语言设计人员无法强制执行命名约定;)

3
您可以为标准库。
Malfist 2011年

3
甚至不提PHP。最糟糕的常用语言。不是由计算机科学家设计的,只是一个想要模板的人,并且添加了类固醇。
Keyo

@delnan:某些语言(例如Mercury或Eiffel)强加命名约定(所有大写的类名,以大写字母开头的变量等),它们由编译器强制执行。Fortran表示,以i,j,k开头的变量是整数(因此,在大多数语言中,传统用法都是循环变量...)。等等。如果您不喜欢该约定,则至少会有点恼人,但是至少有利于源代码的一致性。
PhiLho

@PhiLho:但是那是非常有限的。它不能(仅举一个例子)强制(对人类读者)对大写字母或下划线使用一致,有意义的方法(可以尝试,但会冒风险让程序员保持理智)。

7

与开发环境的一流集成。

如今,编码是在丰富的环境中完成的。对于HTML / CSS / JS,我们有Firebug和其他交互式工具。对于Java,Eclipse和IDEA以及其他真正的IDE。依此类推。有一种工具的生态,从编辑器开始,但不止于此:

  • 文件内和文件间的代码组织
  • 智能突出显示
  • 智能完成/预测性键入
  • 静态调试(标记语法,语义和样式错误)
  • 创建和使用模板和宏
  • 版本控制(版本控制,合并,分支等)
  • 具有多位作者的分布式开发(注释,内联文档,注释等)
  • 运行时调试(堆栈跟踪,步进,监视等)
  • 交互式“实时”调试(例如Firebug-实时系统的编辑行为)
  • ...我什至不知道接下来会发生什么。

应该建立语言来为这些活动提供支持。已经取得了一些进展-例如,Java中的注释可以帮助其他开发人员理解代码的意图。

但是大多数情况下,它都是被黑客入侵的东西,例如在注释中使用$ Id $,以便CVS控制的源可以包含版本号。为什么我不能从语言本身做类似的事情?


您是说像ASIS(ISO / IEC 15291:1999“ Ada语义接口规范”)之类的东西吗?ASIS不能满足您的所有需求,但可以满足很多要求。我经常希望为其他编程语言提供类似ASIS的功能。有关详细信息,请参见sigada.org/wg/asiswg
马丁

其中一些操作相对便宜,或者可以从IDE中免费获得:代码组织,语法突出显示,代码折叠,版本控制,模板/宏。其他方面则需​​要付出更多的努力:运行时调试,静态调试,智能完成/预测性键入,重构等。尽管经常被忽略,但是当您还需要担心IDE插件时,设计一致的语言要困难得多。
Berin Loritsch 2011年

6

分布式计算

免费午餐结束了。如今,人们需要在多个内核/多个处理器(以及特殊情况下的多台计算机)上运行的程序。

不幸的是,从概念上讲,编写多线程代码很困难,因此实际上不需要添加语言作为障碍。

C ++ 0xfuture的使用当然很有趣,因为它作为一个库提供,并且不能使您摆脱实际的同步问题(您知道,那些问题很容易解决...)

我真的很喜欢Go的方法:多线程是内置的,采用的方法(通道和goroutines)比传统的信号量/互斥锁/锁定方法更容易设定心态。虽然(Go有指针)或同时发生死锁(通道等待周期...),但同时访问非同步结构仍然很容易。

我认为,支持数据不变性的语言(例如功能语言)可能拥有它的权利(不过我确实喜欢那里的经验)。

此外,Actor模型可能是我们的下一个目标。它也用于分布式计算。


另一个示例是Erlang。这种语言之间的一个共同主题是无共享方法,即状态与消息一起传递。该方法可以很好地扩展。
Berin Loritsch 2011年

@Berin:您是对的,即使我在邮件中没有引用Erlang是因为我对此知之甚少,但我记得它正确地实现了Actor模型。
Matthieu M.

6

叫我疯了,但对我来说,最重要的语言功能之一就是可以获得良好的在线参考资料以及示例。我知道我可以为任何语言找到良好的搜索结果,但是我真的很喜欢MSDN和Java API网站。对于没有特定语言经验的人,它们使编程变得容易得多。


JavaDoc,CppDoc,RubyDoc等在理解标准库以及您创建的库方面具有很大的优势。它们并非一律平等,有些比其他的更容易导航。
Berin Loritsch 2011年

同意,Java API网站是一个极好的资产。具有创建API文档的标准格式也很棒。使用内置了对JavaDoc(netbeans)的支持的IDE所带来的生产率提高是惊人的。尽管我的记忆力很差,所以它可能比其他人受益更多。
toc777

6

帮助编译器检查代码的更多功能。

作为嵌入式系统程序员,我始终使用C。但是,我始终希望我有更多/更好的方法告诉编译器我对代码的期望,以便可以对其进行验证。

EG我可以有一个功能

f(int x)

但我更喜欢

f(int range[-5..25] x)

EG我希望能够使用某种高级功能语言(例如Lisp或Haskell)编写有关函数的断言。它们不会被编译成代码,但可以用于静态或动态分析。


本质上是进行边界检查的有效方法吗?那实在是太酷了。虽然,我至少希望将其包括在运行时检查以及编译时间检查中。从数据库或用户界面提取信息时,始终保证该值将是有效的。如果这是一种语言功能,我也想将其用于这些目的。
Berin Loritsch 2011年

3
您应该使用Pascal。您可以定义一个覆盖任意范围的数字的类型,例如-5..25,编译器可以在编译时进行验证。(当然,只要您只分配常量。)
Mason Wheeler

1
@Kugel:除了声明编译器功能外,还有什么?并且单元测试不会检查生产中的代码。而且,不进行生产检查就像在首次航行后将救生船取下。为了节省燃料并使船舶更快。
马丁

1
我将使用Ada,但要使用的平台没有Ada编译器。它只有一个C编译器,因此无论如何都是学术性的。
Rocketmagnet

1
我已经使用了很多断言,但是最好将此内容和其他内容作为语言功能。
Rocketmagnet

5

小语法,关键字越少越好,因为冗长的语法难以学习且不利于可读性。

最糟糕的例子是Ada:

procedure Hello is
begin
  Put_Line("Hello World!");
end Hello;

像is,as ...这样的填充词对编程语言没有意义。


4
我认为最糟糕的例子是您所说的语言public static void
乔伊·亚当斯

1
这个想法不是什么新东西,已经以SmallTalk的形式实现了,它根本没有关键字。因此,您应该使用SmallTalk作为索赔的积极示例。顺便说一句:如果您IS不了解Ada的用途,那么您就不了解Ada(您曾经编写过Ada吗?):IS将过程声明与局部变量声明分开,并从实现中区分规范。当然,只有在比较函数的规范和实现时,您会注意到,这样IS做很有意义并且根本不是填充物。
马丁

1
忘了提及:SmallTalk语法也适合明信片的背面。因此,它也将满足您对“小”的渴望。当然,这里的大多数想法已经在某处以某种语言实现,并且这里的大多数张贴者都使用该语言作为正面示例,而不是做出错误的负面示例。如果我有足够的声誉,我会否决你。不是因为您的想法不好,而是因为使用了负面示例。
马丁

7
如果填充词有助于消除语法歧义,则实际上可以达到目的。举例来说,我更喜欢if x then …if (x) …。我们已经将一对括号换成上下文关键字。这是有道理的,因为条件x可能是带有自己括号的复杂表达式。消除最外面的一对可以大大提高可读性。当然,替代方法是在此处使用冒号,例如在Python中。实际上,我相信大多数此类歧义性填充词都可以用冒号代替。不知道我喜欢哪种方法。
Konrad Rudolph

3
@Konrad:如果它消除了语法含义,则不是填充符。之所以is 填充词,因为Ada 可以procedure Hello begin ... end毫不含糊地允许这样做。
dan04 2011年

4

我希望看到更多学习语言。不仅对于绝对初学者来说,语言的使用要严格得多,例如每个标记之间都需要一个空格,而且对于已经了解编程并且想要学习新概念或在总体上更好地编程的人来说,这些语言也适用。

对我而言,Haskell是我所说的“学习语言”的一个很好的例子(尽管多年来,它也越来越流行和通用)。通过放弃熟悉的C语法并使用向后的函数组合运算符(例如(+2) . (*3),一个乘以3,然后加 2 的函数),Haskell教我编写较短的函数。它无情的类型检查器帮助我更快地学习语言,并提高了我对代码进行逻辑思考的能力。这两个好处都蔓延到其他语言,甚至是汇编语言。

学习语言的目标和通用语言的目标经常会冲突。学习语言应该具有挑战性和学习奖励,并应强制执行一种特定的样式,即使该样式对于许多应用程序而言并非最佳。通用语言应能很好地完成工作,对抽象的使用应进行仔细的衡量并“合理”。例如,在修复网站时,了解monad将是程序员的最后一件事。另一方面,当某人正在学习编程时,如果他们甚至还没有学习过功能,那么他们就不必白费力气。

如果您是语言设计师,请确定您的语言是学习语言还是应用语言。这将确定您要在设计中采用纯度的程度。


2
Haskell的功能如何向后倾斜?这是的直接翻译(f ∘ g)(x) = f(g(x))
乔恩·普迪

@Jon Purdy:这意味着您必须按照其应用程序的相反顺序编写函数。两种形式g都首先应用于参数,然后是f。如果要对列表进行排序,将其分组并获取这些列表的第一项,则可以编写(map head . group . sort) listmap head $ group $ sort listmap head (group (sort list))。在所有情况下,最终都会向后写入操作。顺便Control.Arrow说一句,导入让您说(sort >>> group >>> map head) list,但是>>>操作员对我来说显得很尴尬和冗长。
乔伊·亚当斯

2
我不知道,我仍然认为从右到左是有道理的。(map head . group . sort) list读为“某种分类中每组的第一项list”,这是很自然的,而且在我看来(sort >>> group >>> map head) list,它比的功能更强大,后者必不可少且向后读为“分类然后分组,然后取每组的第一项。 .. list”。
乔恩·普迪

@JoeyAdams - >>>操作看起来相当笨拙而冗长 -一些较新的函数式编程语言已经开始使用|>作为一个左到右链接运营商,这也许是对眼睛更容易一些...
朱尔斯

4

既然我们在2011年,

  • 绝对完整的规格。没有像C中的依赖架构的漏洞
  • 多线程支持;不只是同步功能(锁),还有使多线程就像编写循环一样容易的语言功能:

    全部(在myCollection中为o){o.someMethod()}

  • 多范式 让我(作为程序员)根据具体情况决定我是否需要静态语言的编译时安全性或动态语言的简洁性;给我面向对象的功能,功能的功能等。

  • 一致性(我知道一致性和多范式都要求很多...)


我100%同意您的要求。多范式和一致性绝对是一个平衡的举动。您可以为动态范式指定一组行为,作为静态检查行为的子集-但我认为这两种方法可以使它们采用非常不同的编程样式。那时他们真的很想成为单独的语言。您可能正在寻找一对具有100%兼容性的一致语言?
Berin Loritsch 2011年

得益于类型推断和隐式,像Scala这样的语言(也许还有Haskell?我还不够了解)具有强大的静态类型系统和简洁性。
PhiLho

2
当语言允许程序员指定重要或不重要时,与体系结构相关的功能就很好。使C可怕的是,没有办法声明“包装65536模的数字类型”。即使平台实现了uint16_t,该标准也要求某些实现将两个uint16_t值之间的差异视为带符号,而另一些实现则将差异视为无符号。它无法为程序员提供任何方法来指定所需的行为。
2014年

我不同意多范式。这给编码风格的战斗留下了太多的摆动空间。库A是用一堆动态范例编写的。库B用一堆静态范例编写。好吧,现在图书馆A需要与图书馆B对话;中间地带在哪里?如果必须用相同的语言在两段代码之间编写胶水,则该语言固有地存在缺陷。
Qix 2014年

3

轻量级工艺

我希望像Erlang一样具有轻量级进程。这主要是运行时的问题。JVM和.NET CLR中缺少此功能。LWP帮助创建大型并发软件。理想情况下,创建流程应该不会花费太多,因为用语言创建对象是很昂贵的。我想在我的应用程序中创建数百万个进程。

它被实现为具有预先调度功能的线程池,因此单个任务不会阻止其他任务,并且可以在任何可用的CPU内核上调度这些任务。

支持尾递归

我想支持尾递归。这对于运行时环境也可能是个问题。例如,JVM不支持尾递归。

简单的分布式编程

我想支持发送()和接收原语,以便在与Erlang相同的netword上在其他计算机上运行的应用程序的某些部分。这使得构建可扩展应用程序(例如分布式数据存储)变得容易。与erlang一样,使用该语言内置的序列化功能也非常有用。而不是像Java中那样,我必须手动进行操作。



Scala具有尾递归功能,并已编译为JVM。IBM Java编译器有时也可以执行尾递归。
马丁

3

促进元编程。

限制特殊形式

在Python中,没有充分的理由说明为什么不将其打印为内置函数。除了不希望与parens有任何关系之外,它的外观和作用类似于一个函数。

我们真的需要forforeachwhile等的每一个作为自己的特殊形式。如何提供一个循环构造和一些默认宏以提供变体循环形式的语法糖。

特殊形式的元编程

form['if'](test-fn, body-fn)


Ruby至少在某种意义上说,可迭代对象通常具有类似的方法each,该方法将一个代码块作为参数,从而使循环具有“特殊形式” 。(Ruby也有forand while循环,但没有自重的Ruby程序员实际使用它们。)
mipadi

@mipadi:我是Ruby块和相关习语的忠实拥护者。
Dietbuddha 2011年

也许他们认为-您会把视线移开。:)我猜这是你们所有强大的“ Python”和“没有充分的理由”的联系。但是,元编程是一个经常被忽略的有效语言设计问题。出于这个原因,我会投票支持。
Berin Loritsch 2011年

@Berin:我实际上使用过,并且是Python的粉丝,这使其更有趣。
Dietbuddha 2011年

一种循环类型会使代码流变得晦涩难懂。例如,do..while如果有一种类型的循环的评估值位于顶部,那么循环的外观如何?它看起来根本不像do..while循环。
Qix 2014年

2

网络功能

在当今世界上,一种不带网络支持的语言是相当la脚的。

大多数现实世界的应用程序都需要通过某种网络进行通信:

  • 自动更新
  • 数据库访问
  • 网页服务

当然,它也是分布式/云计算支持的基石。


8
但这可以是标准库功能就可以了。
Donal Fellows

@Donal:我从没有说过(或至少没有这样想),这个问题对语言和库功能都开放。我的意思是,如果您收到语言包,并且其中没有网络功能,那么您将尽早解决这个问题:)
Matthieu M.

3
标准库确实是语言经验的一部分,应该同样谨慎地对待它。我也同意标准库的这一要求。
Berin Loritsch 2011年

1

我喜欢易于学习且易于组合以创建新事物的编程语言。

例如,虽然有很多方法可以写东西很吸引人,但我认为最好只有一种或两种方法来写东西。这样,程序更易于维护。

一种可以将概念应用于所有元素的语言非常有帮助(我认为这称为正交性),因此,下次您面对新的语言功能时,可以推断出如何使用它。

我知道有时候语言语法必须妨碍在编译/解释阶段中更好地执行,但是有时候我觉得语言设计师会将这项工作推迟给开发人员。例如,Java或Javascript中的多行字符串。

最后,语言语法是其用户界面,因此,它应该清晰,简洁,直观,易于使用,并应遵守您的习惯。


正交意味着每个功能都有所不同。看一下grep或awk之类的工具。他们做一件事,很好。然后,您可以按不同的顺序将它们挂起,以执行所需的任何操作。
Theo Belaire 2011年

1
  • 可读性:语法中使用的符号越少/越小,越干净越好。
  • 面向对象的类型:方法,而不是函数。
  • 可理解性:内置流利的接口,库类/接口和各种综合和简称。

1
抱歉,我得给你-1,因为这完全是错误的。简洁有助于更快地编写代码,但绝对不能使代码更具可读性(超过一定的最低要求)。一定程度的冗长性使代码更易于阅读,因为这些多余的单词和符号意味着某些东西,并向程序员提供了有意义的信息,尤其是如果它最初是由其他人编写的,而您却没有头脑的优势它在您脑海中的模型。
梅森惠勒

对我来说,干净的代码是可读的代码。我还说了最小的:在PHP数组中使用“:”而不是“ =>”,或者使用“。”。而不是“->”,肯定会有所改进(并且我已经很喜欢PHP)。
dukeofgaming 2011年

4
@梅森:我和许多优秀的技术作家(例如威廉·津塞尔(William Zinsser))不同意。言过其实是可读性的敌人,而不是简洁。
康拉德·鲁道夫

2
我追求一种简洁的形式,用符号来定义。但是,我对多字符符号感到非常满意,只要它们是读者自然将其视为单个符号的事物(例如,单词就是一个符号)。
Donal Fellows

1
您的第一点与您的后两者直接冲突。
Qix 2014年

1

向现有的编程语言添加功能。因此,新语言B是旧语言A加特征X。

现有示例:

  1. C添加类=> C ++
  2. Java添加一些东西=> C#

2
这是一个过分的简化。一个更好的例子是C和Objective-C之间的区别。
乔恩·普迪

0

当涉及到技术/平台/语言/数据库等时,多数情况下都取决于性能。由于我们拥有更强大的计算功能,将来可能会使用图形语言来设计当今的许多软件。

我希望有一天我们拥有计算能力和一种语言,您可以在其中设计应用程序,而不必担心语言细节

更新: 我发送了指向此类语言LabView的链接

更新: 我应该更多地解释“计算功能强大”的含义。编译软件的性能可能不如基于语法语言的编译软件强大。我认为图形编程是更高级别的编程,可能会有更多开销。当今的计算机可以并且很容易地运行图形化编程语言。


3
计算机已经足够强大,可以执行此操作。这只是不切实际,因为您出于某种原因需要进入代码。
Jeremy Heiler 2011年

2
它仍然是一种语言。为了实现这一目标,已经进行了不止一种尝试。UML工具将生成一定数量的代码,但是当模型足够详细以生成有效的产品时,就无法再理解代码了。我相信Unix环境中存在一些用于应用程序图形连接的东西,但是需要很多配置才能使其正确。工作流引擎使用此隐喻来允许非程序员设计工作流。
Berin Loritsch 2011年

1
简而言之,尽管我严重怀疑此方法的实用性,但目前在某些特定的应用程序中使用该方法并对该方法很好地起作用。回复:您的观点... 1.计算机具有计算能力,技术方面不是问题。2.问题在于提供一种视觉语言,该视觉语言要足以在一般意义上完成工作而又不会迷失细节。在利基应用程序之外,文本似乎是程序的紧凑表示形式。我赞成,因为它适用于提出的问题。
Berin Loritsch 2011年

1
@Amir:然后请解释为什么计算机需要更强大的功能才能进行“图形编程”来驱动软件开发?
Jeremy Heiler 2011年

7
@Amir:您将技术限制与更基本的限制混为一谈。我们没有许多图形化计算机语言的原因是我们不知道如何做好它们(也不知道它们是否可以做得很好)。我知道LabView,并且听说过有关在其中做复杂的事情或更改简单的事情的烦恼。我们也不需要功能更强大的计算机来设计这种语言,因此,继续尝试以这种假设的语言来绘制一些示例程序。
David Thornley
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.