拥抱开源的微软近日又为开发者带来好消息:在受 TypeScript 语法类型与 ML 和 Node/JavaScript 语义启发下,微软推出了全新的开源编程语言 Bosque。

Bosque 创作者是微软研究院的计算机科学家 Mark Marron,他设计通过拥抱代数运算和避开导致复杂性的技术,试图创造出一种简单易懂的语言,走出 1970 年代兴起的结构化编程模型。如今,Bosque 似乎已经实现了这一点,它不再需要“for”、“while”、“do while”等循环,可让开发者开发效率更高。

与此同时,本文的作者 Erik Pragt 也发现 Bosque 和 Kotlin 有着诸多的相似之处。

作者 | Erik Pragt

译者 | 弯月

责编 | 屠敏

出品 | CSDN(ID:CSDNnews)

以下为译文:

昨天,我的一个同事Sahil发给我一个链接,链接的文章介绍了微软研究院发布的新语言Bosque。在读了这篇文章,看了里面的代码示例后,我不禁想看看它和Kotlin有多少相似之处。我想通过这篇文章,分享我使用Bosque语言的短暂经验,以及它和Kotlin的比较。我不会深入讨论Kotlin和Bosque的生态系统,这篇文章的重点是语言结构和语法本身。

什么是Bosque编程语言?

Bosque是微软研究院发明的一门新的编程语言。在我撰写本文的时候,Bosque语言才刚满11天!根据Bosque的GitHub页面(https://github.com/Microsoft/BosqueLanguage),Bosque的设计目标是“编写简单、明确且人和机器都容易理解的代码”。因此,Bosque吸取了许多概念,例如不可更改性、原子构造器、工厂等,还有丰富的类型系统。

Bosque是一门非常新的的语言,它的语法受到了TypeScript的启发。从我的另一篇文章《Kotlin vs TypeScript》(https://www.jworks.io/dart-vs-typescript-vs-kotlin-js/)中,你就可以看出两者之间有许多相似之处,因此不难想象,Kotlin和Bosque之间也会有许多共同点。

Bosque vs Kotlin:语法

Bosque的GitHub页面上给出了一小段Bosque代码示例,这段代码很好地展示了它与Kotlin之间的相似性:

  1. // Bosque 

  2. function add2(x: Int, y: Int): Int {

  3.     return x + y;

  4. }

  5. add2(2, 3) //5

  1. // Kotlin

  2. fun add2(x: Int, y: Int): Int {

  3.     return x + y;

  4. }

  5. add2(2, 3) //5

尽管这段代码非常简单,但应当注意到,Bosque的语法与非常规版本的Kotlin非常相似。唯一的区别就是关键字function与fun的不同,其他代码完全一样。我们来看看更多的示例。

Bosque网站上给出了一个简单的井字棋游戏(https://github.com/Microsoft/BosqueLanguage/blob/master/docs/tictactoe.md)。虽然我完全没有编写Bosque代码的经验,但这段代码非常直观,除了一些像'x'#PlayerMark;(有类型的字符串)、@[ 2, 2 ](元组/结构)和this<~(cells=this.cells..(原子批量数据操作)等语法糖之外。

下表总结了Bosque的井字棋游戏游戏示例中用到的一些语言概念,以及对应的Kotlin概念。这个列表并不完整,但可以让你方便地理解两种语言的代码示例:

语言特性

Bosque

Kotlin

不可更改的值(Immutable Values)

全部

部分(基本类型,集合)

有类型的字符串(Typed Strings)

支持

内嵌类或类型别名

灵活调用(Flexible invocations)

命名实参

命名实参

批量代数数据操作(Bulk Algebraic Data Operations)

x<~(f=-1, g=-2)

copy()方法

短路运算符(o?.m)

使用问号

使用问号

原子构造器(Atomic Constructors)

支持

伴生对象(Companion Objects)

元组(Tuples)

支持

不支持(仅支持Pair/Triple)

函数类型(Function types)

支持

支持

现在我们对两门语言有了一点理解,接下来我们再来深入看一看井字棋游戏的代码,看看两者具体的比较情况。如果你想直接看结果可以点这里(https://gist.github.com/bodiam/749b5174d26522cdaeba43c1401cbc8d)。如果你有耐心看下去,我可以带你阅读一些代码,并给出相应的Kotlin代码。

Bosque井字棋

井字棋的示例是一个小游戏,玩家可以明确指定走哪一步,也可以随机走一步。游戏不需要修改状态,因为一切都是不可修改的。

Bosque有类型字符串

在井字棋示例中我们看到的第一个语言概念就是有类型字符串(Typed Strings):

  1. const playerX: String[PlayerMark] = 'x'#PlayerMark;

  2. const playerO: String[PlayerMark] = 'o'#PlayerMark;

上面这段代码创建了两个常量:playerX和playerO,都是有类型的字符串。也就是说,PlayerMark类型的字符串不能与包含邮政编码的字符串兼容。

Kotlin不支持有类型字符串,但提供了内嵌类(Inline Class)或类型别名(Type Aliases),可以用在类似的场合。内嵌类可能更好(我们稍后会讲到),但现在先来看看类型别名。类型别名促使Kotlin代码更接近Bosque代码:

  1. const val playerX: PlayerMark = "x" as PlayerMark

  2. const val playerO: PlayerMark = "o" as PlayerMark

Bosque类型

接下来看看这段代码:List[[Int, Int]]。可以想象这是一个列表,但列表的元素类型为结构类型[Int, Int]。因此,该列表只能包含整数对。

在Kotlin中,如果类型能够推断出来,我们就不需要明确定义,但如果要定义的话可以写成List<Pair<Int, Int>>,写法非常相似。

Bosque结构类型

如果需要保存数据,但不希望定义类,则可以使用结构(Struct)。在Bosque中,结构类似于:@[ 0, 0 ]。它定义了一个结构,包含两个值:0和0。

虽然Scala等语言都有结构,但Kotlin从早期的某个版本开始就不再支持结构了。听起来似乎有点奇怪,因为尽管有时候结构的存在是合理的,但是结构并不会提高代码的可读性,而且创建数据类也非常容易。同时,Kotlin原生支持Pair和Triple,因此在Kotlin中可以利用to方法创建上述结构:0 to 0,得到的结果是一个Pair对象。

Bosque前置条件

另一个有趣的概念是前置条件(preconditions),该功能可以通过requires关键字检查函数的输入。

requires 0 <= x && x < 3 && 0 <= y && y < 3;

Kotlin也有同样的概念:

require( 0 <= x && x < 3 && 0 <= y && y < 3)

但是,除了支持前置条件外,Bosque还支持后置条件(postconditions)。后置条件可以检查函数是否返回了正确的值,例如ensures _result_ % 2 == 0; 可以检查返回值是否为偶数。

Kotlin也支持范围检查,因此我们可以通过重构用更加常规的形式编写上述代码成。

Bosque的原位更新

有一个很不错的功能,但Kotlin中却没有:通过拷贝的方式更新一个不可修改的列表。在Bosque中可以用下面的代码实现:

return this<~(cells=this.cells->set(x + y * 3, mark));

上面这段代码创建了cells列表的拷贝,并将x + y * 3位置上的值更新成了mark。在Scala中,该操作可以通过updated方法实现,但Kotlin不支持这个方法。该方法已经有了一个YouTrack问题票,所以如果你想要这个功能,可以去为该功能投票。同时,你还可以通过创建扩展函数的方式来创建自己的updated方法:

  1. private fun <E> List<E>.updated(index: Int, value: E): List<E> {

  2.     return this.toMutableList().apply { set(index, value) }

  3. }

如果你希望编写一段效率更高、但可读性较差的代码,则可以参考重构后的Kotlin版本,或参考上述YouTrack问题票。

Bosque的扩散操作符

Bosque代码中还有一行非常有意思:

  1. var tup = opts->uniform(rnd);

  2. nboard = this.board->markCellWith(...tup, mark);

这段代码创建了新的棋盘(nboard),该棋盘是当前棋盘的拷贝,是根据一个从列表中的数据项半随机(uniform,表示根据种子来选取)地创建的。由于tup变量是元组,因此可以利用...操作符来扩散(spread)其内容。

尽管Kotlin也有扩散运算符,但没这么灵活。它只能在调用vararg方法的时候使用。但是,Kotlin中只能做到使用Pair的第一个或第二个值,或者更Kotlin的方式是,像下面这样先将Pair解构:

  1. val (x, y) = opts.random(Random(rnd))

  2. nboard = this.board.markCellWith(x, y, mark)

但是,由于我们希望尽可能地与原始代码相似,所以暂时线直接使用第一个和第二个值:

nboard = this.board.markCellWith(tup.first, tup.second, mark)

结果

上面的比较给出了一些Kotlin和Bosque之间的异同。作为本文的结果,我们现在有了三个不同版本的井字棋代码:

  • 原始的Bosque代码:https://github.com/Microsoft/BosqueLanguage/blob/master/docs/tictactoe.md

  • 原始的Kotlin代码,尽可能与上述代码相似:https://gist.github.com/bodiam/749b5174d26522cdaeba43c1401cbc8d

  • 重构后的Kotlin代码,功能与上面的代码相同,但使用了更多的Kotlin最佳实践:https://gist.github.com/bodiam/c98cef9da8660a06c76883326b21a2cb

Kotlin最佳实践

最后一个版本(即重构后的Kotlin代码)使用了一些Kotlin的最佳实践。我不知道Bosque中是否有这些结构,也许Bosque的代码也可以改进。我们可以通过下列变更编写更符合惯例的代码:

使用内嵌类代替类型别名

inline class PlayerMark(val value: String)

这种写法可以给出更好的类型信息,避免在应该使用String的地方使用PlayerMark。

在require中使用范围检查

不要使用单独的比较,我们应该使用范围比较:

  1. require( 0 <= x && x < 3 && 0 <= y && y < 3) // both statements

  2. require(x in 0..2 && y in 0..2)              // do the same

去除类型信息

Bosque中的类型用法似乎很冗余。尽管Kotlin中也完全可以这样做,但并不是必须的。所以,下面两条语句是相同的:

  1. // this

  2. val allCellPositions : List<Pair<Int, Int>> = listOf(

  3.     0 to 0, 1 to 0, 2 to 0,

  4. )

  5. // vs

  6. val allCellPositions = listOf(

  7.     0 to 0, 1 to 0, 2 to 0,

  8. )

去掉`this`

Bosque代码似乎用了许多this,但在Kotlin中不需要这样做,所以重构后的版本中去掉了this。

总结

总之,我希望在上文中我们很好地比较了两种语言,我们也很期待Bosque语言将来的发展,而其他语言如C#、TypeScript或Kotlin能否采纳这些概念呢,让我们拭目以待吧。

微软推出新逆天开源语言Bosque,告别 for 循环,提高开发效率!相关推荐

  1. 微软推出新逆天开源语言,告别 for 循环,提高开发效率!

    拥抱开源的微软近日又为开发者带来好消息:在受 TypeScript 语法类型与 ML 和 Node/JavaScript 语义启发下,微软推出了全新的开源编程语言 Bosque. Bosque 创作者 ...

  2. vscode自动补全插件c语言,一些提高开发效率的VSCode必备插件(分享),vscode代码补全插件...

    一些提高开发效率的VSCode必备插件(分享)提高开发效率的虚拟代码的一些重要插件(分享),本文推荐一些VSCode插件来提高效率.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有帮助.Vis ...

  3. Webkit推出新的着色语言whlsl

    本文将介绍一门叫作Web High Level Shading Language(WHLSL,发音为"whistle")的新Web图形着色语言.它对HLSL进行了扩展,变得更安全. ...

  4. 推荐一款结构化数据处理开源库,极大提高开发效率

    现代Java应用架构越来越强调数据存储和处理分离,以获得更好的可维护性.可扩展性以及可移植性,比如火热的微服务就是一种典型.这种架构通常要求业务逻辑要在Java程序中实现,而不是像传统应用架构中放在数 ...

  5. 微软推出新语言Bosque,超越结构化程序设计

    微软近期推出了一款全新的编程语言 Bosque,该语言参考了 TypeScript 的语法与类型,还有 ML 和 Node/JavaScript 的语义. 作者微软计算机科学家 Mark Marron ...

  6. 微软推出新编程语言 Bosque,超越结构化程序设计

    微软近期推出了一款全新的编程语言 Bosque,该语言参考了 TypeScript 的语法与类型,还有 ML 和 Node/JavaScript 的语义.作者微软计算机科学家 Mark Marron  ...

  7. 洞察疫情,微软推出新冠数据分析网站COVID Insights

    来源 | 微软研究院AI头条 COVID Insights 网站功能亮点 持续数月的新冠疫情一路肆虐.席卷全球,世界各地的科研人员都在为此奋战,希望通过最先进的技术逐步揭开新冠病毒的神秘面纱. 近日, ...

  8. 洞察疫情,微软推出新冠数据分析网站 COVID Insights

    来源 | 微软研究院AI头条 COVID Insights 网站功能亮点 持续数月的新冠疫情一路肆虐.席卷全球,世界各地的科研人员都在为此奋战,希望通过最先进的技术逐步揭开新冠病毒的神秘面纱. 近日, ...

  9. edge 此项内容已下载并添加到 Chrome 中。_微软推出的逆天神器,让我抛弃用了5年的 Chrome...

    微软在今年年初正式上线了新版的 Edge 浏览器,不少人对它寄予厚望,因为它也采用了和 Chrome 浏览器一样的内核,可以安装 Chrome 上的各种插件,增强自身的能力. 而在一些产品功能或细节上 ...

最新文章

  1. LightGBM用法速查表
  2. linux c语言 readline,Linux C代码实现读取配置文件示例
  3. 微软应用商店_微软自家的软件也放弃Windows 10
  4. Asp.Net Core 已支持 gRPC-Web !!
  5. 安卓开发之android使用webview时按后退会退出而不是回退的问题
  6. 误删除了mysql库的user表解决办法
  7. IOS磁力下载软件,老司机必备品
  8. 雅诗兰黛公司宣布晋升Stéphane de La Faverie为集团总裁
  9. adb shell dumpsys activity activities调用信息简析
  10. 我们到底该转行Web全栈工程师吗?
  11. 华为快应用支持广告变现,加速商业化进程
  12. 罗杨老师带你了解谷歌编程之夏(GSoC)活动全流程
  13. 做淘宝店铺为什么一定要定位?
  14. 手撕promise.all以及promise.race
  15. python函数调用时所提供的参数可以是常量_元组的元素不能修改,一般作为参数传递给函数调用,或是从函数调用除获得参数时,保护其内容不被外部接口修改和破坏。( )_学小易找答案...
  16. javascript开源电子表格
  17. Kusion Watch:实时监控资源状态变更
  18. php里 没temp文档 如何创建temp文档 win7,Win7更改Temp文件夹存储位置的操作方法
  19. 演讲比赛流程管理---C++
  20. 华为路由交换精讲系列⑦:super密码配置 密码重置与破解 权限级别 [肖哥]视频课程-肖宗鹏-专题视频课程...

热门文章

  1. Leetcode: Populating Next Right Pointers in Each Node II
  2. CDOJ1633 Video Game Combos [AC自动机+dp]
  3. Node Mysql事务处理封装
  4. 极路由+NETGEAR 传输无线网络
  5. Docker 常见问题 (FAQ)-2015
  6. 模拟STL链表类的实现
  7. 《3D数学基础》系列视频:这次,真的是广告!
  8. spfa 判断负环 (转载)
  9. TX Text Control X10新特性之图像占位符合并
  10. PHP中$_SERVER的详细参数与说明