如果您希望立即开始使用Pony,可以使用Pony Playground在浏览器中进行尝试。如果您对Pony的不同之处以及为什么要考虑使用Pony感兴趣,请继续阅读。
如果您对Pony的早期历史及其起源感兴趣,那么您会很幸运:“ Pony的早期历史”。
没有悬空的指针,也没有缓冲区溢出。该语言甚至没有null的概念!
没有运行时例外。所有异常都有定义的语义,并且总是被捕获。
小马没有锁,也没有原子操作或类似的东西。相反,类型系统可确保在编译时并发程序永远不会发生数据争用。因此,您可以编写高度并发的代码,而不会出错。
这很容易,因为Pony根本没有锁!因此,它们绝对不会死锁,因为它们不存在!
小马程序可以本地调用C库。我们的编译器能够为Pony库生成C头文件。因此,C / C ++程序可以本地调用Pony程序!
Pony有很多值得爱的地方,但最重要的是,我们最爱的是Pony使得编写快速,安全,高效,高度并发的程序变得容易。怎么样?小马类型的系统引入了一个新颖的概念:“参考功能”。参考功能使您可以基于如何共享数据来标记数据的不同位。然后,Pony编译器将根据您提供的标签使用数据验证您实际上是否正确。参考功能与Pony的actor并发模型相结合,可以实现强大的配对。让我们深入研究一下:
并发问题是共享的可变数据。如果两个不同的线程可以访问同一数据,则它们可能会尝试同时更新它。充其量可以导致这两个线程具有不同的数据版本。在最坏的情况下,更新之间的交互作用很差,导致数据被垃圾覆盖。避免这些问题的标准方法是使用锁来防止数据更新同时发生。这会导致性能严重下降,并且很难正确解决,因此会导致许多错误。
任何不可变的数据(即无法更改)都可以安全地并发使用。由于它是不可变的,因此它永远不会更新,并且是导致并发问题的更新。
如果一个数据块仅具有一个引用,则称其为孤立的。由于只有一个引用,因此隔离的数据无法由多个线程共享,因此不存在并发问题。隔离的数据可以在多个线程之间传递。只要一次只有一个引用,那么数据就不会出现并发问题。
单个参与者中的代码永远不会同时运行。这意味着在单个参与者中,数据更新不会引起问题。只有当我们想要在参与者之间共享数据时,我们才会遇到问题。
通过仅共享不可变数据并仅交换隔离数据,我们可以拥有安全的并发程序而没有锁。问题在于正确地做到这一点非常困难。如果您不小心参考了移交给您的某些孤立数据或更改了您共享为不变的内容,那么一切都会出错。您需要的是编译器强制您履行诺言。 Pony参考功能使编译器可以做到这一点。
如果您问我们,那真是太酷了,您可以尝试Pony。
小马低于1.0。我们定期发布涉及重大更改的发行版。缺乏稳定性是许多项目避免使用Pony的充分理由。
如果您的项目根据您所使用工具的社区规模而成功或失败,那么Pony并不是您的理想选择。尽管可以使用Pony编写稳定,高性能的应用程序,但您将不得不做大量的工作。可供使用的Pony库的开源库很小。如果它不在标准库中,那么您将不得不自己添加它,方法是从头开始在Pony中编写它,或者使用Pony出色的C-FFI功能包装现有的C库。
有些人已经期望有很多工具,这些工具目前不适用于Pony。我们没有IDE。您可以使用标准的调试器,例如GDB或LLDB,但是经验仍然有些粗糙。如果您习惯使用基本的文本编辑器并使用LLDB,VTune和其他工具,则可能会没事。只是不要期望一个完整,强大的生态系统。我们还没到那儿。
如果您的项目无法从Pony的任何优势中获得很多收益,那么您不应该使用Pony。如果您编写的是单线程应用程序,而没有任何最重要的性能问题,并且需要访问大型社区和丰富的库,那么最好选择另一种语言。但是,我们希望您能在Pony中看到足够的潜力来开始尝试它,即使它不适用于您当前的项目。
按照理查德·加布里埃尔(Richard Gabriel)的精神,小马哲学既不是“正确的事情”,也不是“更糟的事情”。这是“完成工作”。
绝对不允许出现错误。如果您不能保证结果正确,那么尝试完成工作毫无意义。
运行速度比除正确性之外的所有内容都更为重要。如果必须牺牲性能来确保正确性,请尝试提出一种新的处理方式。程序完成工作的速度越快越好。这比除正确结果外的任何内容都重要。
为了性能,可以牺牲简单性。接口要比实现简单,这一点更为重要。程序员完成工作的速度越快越好。可以使程序员更加努力以提高性能是可以的,但是使程序员更容易实现比使语言/运行时变得更轻松更为重要。
为了简单或性能,可以牺牲一致性。不要让过度的一致性妨碍完成工作。
涵盖尽可能多的内容是很不错的,但是其他任何事情都可能牺牲完整性。最好现在就完成一些工作,而不是等到以后一切都完成。
“完成工作”方法与正确和简单的态度与“正确的事情”相同,但对一致性和完整性的态度与“越差越好”。它还将性能作为一项新原则添加,将其视为第二重要的事情(在正确性之后)。
在语言的整个设计和开发过程中,应遵循以下原则。
全类型安全。没有“相信我,我知道我在做什么”的强制。
完全内存安全。没有“老实说,这个随机数实际上是一个指针”。
没有崩溃。编译的程序应永远不会崩溃(尽管它可能会挂起或发生意想不到的事情)。
明智的错误消息。对于特定的错误情况,请尽可能使用简单的错误消息。可以假定程序员知道我们词典中单词的定义,但是要避免使用编译器或其他计算机科学术语。
提供一种单一,干净,清晰的方式来做事情,而不是迎合每个程序员的偏见。
使升级整洁。不要尝试将新功能与它们要替换的功能合并,如果有问题,请将其删除并一次性替换。尽可能提供重写实用程序,以在语言版本之间升级源。
合理的构建时间。减少构建时间很重要,但不如运行时性能和正确性重要。
允许程序员省略代码中的某些内容(默认参数,类型推断等)是可以的,但应始终允许完全指定。
没有歧义。程序员永远不必猜测编译器会做什么,反之亦然。
记录所需的复杂性。 并非所有语言功能都必须精通才能理解,但是复杂的功能必须在文档中具有完整的解释才能使用该语言。 完全定义的语义。 所有语言功能的语义必须在标准语言文档中可用。 行为未定义或“依赖实现”是不可接受的。 必须具有有效的硬件访问权限,但这不必遍及整个语言。 互操作性。 必须与其他语言互操作,但是如果使用非原始类型,则可能需要填充层。 避免图书馆痛苦。 使用第三方Pony库应该尽可能容易,不要感到意外。 这包括编写和分发库以及在单个程序中使用库的多个版本。