如何同时学会两门编程语言?


prtyaa
prtyaa 2023-12-25 13:39:31 67648
分类专栏: 资讯

大概在五年前,我写了一篇文章《学习的艺术——如何学好一门技术、语言》,介绍了如何通过复写现有的系统来学习新的技术。而在最近的两次实践中,我发现了一种更高效(hard way)的方式来学习编程语言。因为高效(hard way),所以这并不是银弹。

当然了,这也是我和我的同事在一次讨论中得到的玩笑结论:你只要用 Go 写一个 C++ 的解析器,那么你就既学会了 Go,又学会了 C++。

只是呢,当我开始去做这样的事情的时候,我发现: It works

故事 A:两门新语言 Go + Antlr

 

我在编写 Coca 的时候,使用的是 Golang 作为开发语言,过程中采用了 Antlr 作为语法解析器生成器,解析 Java 语言生成代码的模型。于是乎,我从 hello, world 开始了我的 Go 学习生涯,将它作为编写应用的语言。与此同时,不断修改使用 Antlr 编写的不同语言的语法,以满足我的开发需要。于是,一来一往之间,我大抵对两个语言有了更深入的研究。

可能你对 Antlr 是否是一门语言有些看法。但是从我的角度来看,由于 Antlr 语言是用来声明语言的语法,所以可以称之为 “元语言” (meta-language)。

高效法则 1:为主语言编写测试

俗话说得好:测试,能反应一名程序员的真正水平:

  1. 短小的函数易于测试
  2. 高耦合的代码难以测试
  3. 测试用例能体现出代码真正做了些什么。

当你面对一个新的语言,你还会学会对应的测试套装。

高效法则 2:修复主语言代码坏味道

对应的方式有多种多样:

  1. 找到身边熟悉语言的大佬,一起 pair。
  2. 查看一些开源项目的代码,学习如何应用
  3. 寻找对应语言的 Design Patterns。如我找到了 Go Patterns
  4. 集成对应语言的 lint 工具,然后有时间就修复。
  5. 集成 Code Climate(开源)/ Sonar 等工具,查看建议。
  6. ……

附赠经验 1:完善元语言语法

大家都懂的,还是得看看使用 Antlr 编写的 AST 代码,这样才能一步步往下走。过程中,还会面对 AST 中的一些问题,查看并修复相关的问题。具体的修复示例可以看看我在 GitHub 上的代码,我就懒得贴代码了。

小结 1

尽管我已经用了多年的 Java,但是这次的解析之旅后,我体会最深的莫过于:

  1. 中英文概念的统一的对齐。
  2. 编程语言中存在一些不常用的语法。
  3. 你永远不知道别人会用怎样的方式组织代码。

除此呢,当你习惯了 A 语言之后,初写 B 语言时,总会呈现出 A 语言的一些编程风格,如 OOP 风格的 C 语言,OOP 风格的 Go 语言。不过,我觉得在我的场景之下,它的益处可能大于坏处,一来,可以让你通过 Google / StackOverflow 快速上手语法,二来,你可以写出统一风格的不同语言代码(手动狗头),方便于你相互翻译 。

正是如此,才让我对成为代码专家有了一点兴致。

故事 B:一门新语言 Kotlin + 其它语言代码

 

我在编写 Chapi (一个通用的编程语言解析器,详见后续的文章,或者 GitHub)的时候,我采用的是 Kotlin 作为开发语言,对于我来说,它可以说是一个新语言。启动这个项目的原因是:为了解决 Coca 实现过程中,发现的 Antlr Go Runtime 下的 TypeScript 性能等各种问题,所以找了个 JVM 系的语言,以调用生成的 Antlr Java Runtime 代码。在这个项目中,我要支持 C#、Pascal 等我没用过的语言,为此便需要寻找对应的语言示例,并编写对应的示例。

因此过程中,你学会了 A 语言,然后能看懂了 B 语言,是不是很棒?

成长:重构主语言代码

Kotlin 比 Go 好重构的一个原因在于,它和 Java 类似,并且是 JetBrains 的新儿子,所以 IDEA 对它的重构支持非常得好。

重构不是这里的主要话题,在那篇《项目初期的最优技术实践》中,我找到了项目的三个周期:

  • 技术准备期
  • 业务回补期
  • 成长优化期

重构是属于成长优化期要做的事件,你不能再放纵过去的烂代码了。

编译测试语言代码

在编写测试用例的过程中,不得不做的一件事情是:编译一下代码。

因为,我遇到过我怀疑这么写,它会编译失败的,然而这是编译成功的。

补齐测试语言用例

对于这样的项目来说,代码即测试数据:

    @Test
    internal fun shouldIdentClassName() {
     val code = """
    class Outer(i : Int) {
     def foo(x : Inner.type) = x.getI
    }
    """

     val container = ScalaAnalyser().analysis(code, "hello.scala")
     assertEquals(container.DataStructures[0].NodeName, "Outer")
     assertEquals(container.DataStructures[0].Type, DataStructType.CLASS)
    }

如上述代码中的 code 变量的值是 Scala 代码,我们要将其转为 Chapi 制作的数据结构。为此,我们需要一步步寻找每一种可能性,并编写对应的测试。

小结 1

故事,还告诉了我们另外一件事:通过应用语言,我们才会掌握一门语言。

所以,方法呢?

没有银弹!

使用一个新语言,编写另外一个语言的解析器。这样一来,你就一下子学会了两种新的语言。

你只需要用 Kotlin 写一个 Go 的解析器,那么你就既学会了 Go,又学会了 Kotlin。

你只需要用 Swift 写一个 Rust 的解析器,那么你就既学会了 Swift,又学会了 Rust。

怎么样,是不是赚到了,是不是很高效(hard way)?

 

嗯,欢迎一起来学习新语言,加入 Chapi (《Chapi —— 一个通用语言元信息转换器》)的开发。

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=30290
赞同 0
评论 0 条
prtyaaL0
粉丝 1 发表 2554 + 关注 私信
上周热门
银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1326
银河麒麟打印带有图像的文档时出错  1239
银河麒麟添加打印机时,出现“server-error-internal-error”  1026
统信桌面专业版【如何查询系统安装时间】  954
统信操作系统各版本介绍  947
统信桌面专业版【全盘安装UOS系统】介绍  906
麒麟系统也能完整体验微信啦!  892
统信【启动盘制作工具】使用介绍  502
统信桌面专业版【一个U盘做多个系统启动盘】的方法  444
信刻全自动档案蓝光光盘检测一体机  389
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

添加我为好友,拉您入交流群!

请使用微信扫一扫!