电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

Loop:紧凑的JVM多核语言


发布日期:2022/11/5
 

作为一种紧凑简洁的JVM编程语言Loop很明显地受到了HaskellSchemeRuby和Erlang的影响而且它也同时尝试着将函数式语言和面向对象语言的优秀特性实用且一致地整合在一起

程序会在传输到JVM中进行编译而且会尽可能地优化这样在解释执行的时候就不会产生性能损失所有的这一切优化都是为了产生高效的可执行代码

Loop的源码文件结构一般如下

moduledeclaration

importdeclarations

functions&typedefinitions

freeexpressions

下面是一个Loop程序的例子

modulemymodule

requireothermod

requireyetanother

classPair>

left:

right:

main>

newPair()#注释可以放在任何地方

#自由表达式必须放在最后

print(mymoduleisgo!)

InfoQ和Loop的创建者Dhanji R Prasanna进行了一次小型的问答互动在这之前有必要对Dhanji做一下介绍他是前Google工程师JAXRS规范的作者之一依赖注入设计模式的作者Manning出版社已经将这本书付梓

InfoQLoop相比其他的JVM语言来说有何不同?

Dhanji我不想做一个面面俱到的特性比较不过我觉得若是阐述Loop的设计理念这将能更好地回答你的这个问题Loop是为了让开发者有一个一致简单而且快乐的编程经历所有的特性都是经过精心设计并且设计过程中我非常仔细地考虑了特性之间的交互不仅仅是句法上而且还包括了语义在其他的语言中你可能有很多方法来完成一件事情这已经几乎成为一种语言的特性但是我觉得多数其他实现都是不需要的在Loop中我尝试着对如何完成一件事情做出种种限制这样便能够保持语言的简洁和简单从而得到一个富有魅力的感觉舒适的语法要知道阅读和编写代码应该是一个简单愉快的过程

另外一个区别就是Loop源代码直接编译成为JVM字节码但是这个编译过程是在传送到JVM的过程中完成也就是说它看起来非常像是一门脚本语言(而且像Lisp一样是REPL(读取求值打印循环)式)但是它的性能实际上要比真正的解释型语言要好我可以让其他人做基准测试来验证不过现在看来在我做的简单测试中Loop的速度非常快我也在启动优化上花费了很多时间和精力因此它的启动速度能够完全达到JVM的极限我可以毫不夸张的说启动速度这个特性通常被大多数JVM语言给忽略了

Loop也是紧密地和Java结合在一起在Loop程序中可以很方便地调用Java方法或者使用Java对象ListsSets和Maps都只是javautil的成员但是做了一些扩展(也简单地扩展了String)这和其他的语言有区别它们是维护了了两个不同的库来对Java库进行扩展

最后Loop从一开始就内建了对并发的支持而且将不可变和状态的共享作为不可或缺的特性

InfoQ你提到了许多Loop的特性都受到了例如HaskellScheme和Ruby这样的语言的影响你可以简单介绍一些例子吗?

Dhanji当然不过要知道当你说受到影响的时候人们总是趋向于认为直接抄袭并且会仔细地检查你是不是有什么地方抄错了应付这种想法是非常艰难的从我看来直接受到影响的部分是语法尤其是Haskell的模式匹配以及wheredo语句块Scheme的类型系统模块TCO(尾调用优化)以及词法结构(闭包)当然还有Ruby的符号以及自由形式的脚本

这里有一个句法结构的典型例子你可以看到Loop是如何受到这些影响的看看函数调用可以以一种后缀的形式来使用

print()

#可以写为

print()

这看起来的确很像是Ruby的函数调用但是事实上这是多态(重载)的函数的简单使用我发现这种形式能够增强某些代码的可读性尤其是扩展已经存在的Java对象时候当然我们也要权衡这种调用的利弊不过我相信当Loop成熟之时这个特性将会得到大量应用

更进一步地说Loop也还在函数设计的过程中受到了来自于Haskell和Scheme(尤其是后者)的语义影响一个典型的例子便是从状态性面向封装的设计转为一个无状态声明式的设计像SchemeLoop在IO的设计上也并不是非常优秀但是另一方面来看这也加强了并发程序的不可变性这个加强之处很明显地受到了Haskell哲学的影响

不仅如此Haskell还影响了如何将声明式的代码更易编写和阅读上我非常喜欢这个哲学理念代码应该读起来像是一个解而不是像一个如何在洗衣房洗衣的说明列表或者说我们应该强调程序做什么而不是怎么样Loop毫无疑问地受到了这种理念的影响

InfoQ看起来Loop也花费了非常多的精力在并发支持和内建的消息传递接口上你可以跟我们解释一下和其他流行的并发技术Loop的并发支持有什么不同吗?

Dhanji这是一个非常好的问题Erlang有许多非常优秀的地方值得借鑒在Loop中实现并发有两个主要的方法它们都是Loop原生支持而且如果能够相互结合使用将会非常强大

消息驱动通道(对消息传递队列和线程池的面向事件的抽象)

软件事务内存(一个用于共享可变状态的无锁的原子性的一致性的模式)

前者将会管理好所有的细节你所面临的只是一个抽象的概念设置好可以并发执行的轻量级的通道数目然后简单地放入一堆任务即可当然也可以考虑将这些任务分片然后在各个片内然后串行执行这其实提供了一个非常简单的方法来创建真正地分片事件队列因为通道是非常的轻量级你可以很简单很容易地创建成千上万的通道然后用来分片执行例如按照用户名分片每个串行通道各自拥有一小块永久的内存这将会使得增量式任务处理更加容易

Loop同样保证每个线程都是平均分布在这些通道中这个所谓的公平参数是可以配置的所有我现在介绍的特性你现在可以马上在Loop中找到而且以后每个串行通道将会有一个可以配置的线程池

我提到了串行通道拥有少量的永久私有内存 另一方面事务内存则是一个更强大的选择如果你熟悉数据库的话Loop如何使用这个技术是和数据库中的并发优化类似我们再也不需要锁这个概念即便是在写入的时候这类内存的优化目标便是超高吞吐量的读操作和无阻塞的写操作这个已经成为语法的一部分

update(person)in@person>

thisname:personname

thisage:personage

注意in @personLoop将会在@person片中执行这个事务

在这个方法中我将会更新@person事务片中的数据this指针指向当前的事务片当函数完成的时候当前事务片将会对其他线程原子可见或者失败之后当做完全没有执行过(类似于回滚)其他的线程(即使不在这个事务中)都可以看到一个一致的@person片然后这个片在事务执行的时候会短暂不可见所有的线程在事务完成之后将会马上看到一个新的对象无锁无需等待这最激动人心的事情便是读和写线程完全无阻塞

这个特性仍然还是处于Alpha阶段我尝试着搞定这个语义问题但是我真的觉得通道API使得Loop中并行编程变得优美强大而且容易理解

你也可以在Github上提交你的代码为Loop做贡献

上一篇:专家指导 如何进行JVM参数配置

下一篇:static内部类