阅读更多
毫无疑问,不同的编程语言间存在着很多差异性。那么对于这种差异性开发者应如何解决?本文就来一探究竟。

以下为译文:

我一直在告诉别人:“编程非常了不起?!痹谀阌腥魏蜗敕ǖ氖焙?,都可以编写软件,然后愿望就实现了。这很真实。与建立物理的东西不同,首先你需要建立整个工厂,而软件的扩张相对非常容易。你可以找到所有已经编译好的组件,而且是免费的,拿来就可以用。建立好一段代码后,就可以重复使用无数次,而无需花钱。听起来很厉害的样子。

但有时候不是这样的。编程带给人的惊喜只是暂时的。在建立了很多代码以后,在写代码的过程中你会不断遇到让人迷惑的错误。一旦你习惯了特定语言和框架的模式后,一旦你需要第二种天性去掌握所选语言中非自然的语法时,编程的伟大之处就不复存在了。

更别提我们有无数种不同的编程语言。每当开发人员面对特殊语言的语法而深感沮丧时,他们都会想“为什么我们不能创建一种新的语言改正这个问题呢?”有些人还真的这么做了,很幸运的是自然选择已经淘汰了很多很差的语言(有时也有意外,比如至今PHP还存在)。一旦一门新的语言开始在一群开发者中流行起来,那么恭喜你 ,现在又出现了一个新的开发者社区,他们互相合作,努力让这门特殊的语言发展壮大。

每一种新语言的诞生所带来的创新,都能造福我们每一个人。但是有时也有不利的一面。有些人可能写了一些非常有用的开源JavaScript库,但是从事Python的开发者却完全没法用。他们不得不自己写一个Python版本的函数库,或者用JavaScript重写所有代码。再想想当前有多少种语言和框架。如果你不觉得这很荒谬的话,那只能说明或许你在软件开发这一行太长时间,已经习以为常了。

语言都包含些什么?

各种编程语言都在以下三个方面上有着很大的不同:语法、语义和标准库。

没错,我知道,我过于简化它们了,但是听我给你解释。

1. 语法

如果不遵循语法,那么你会在编辑器中看到各种弯弯曲曲的红线,而且你的代码也无法通过编译器或解释器。

JavaScript使用大括号,布尔型使用小写的true和false,用//表示行注释。
function doSomething() {
  a = true;
  if (a) {
    ... // Do something.
  }
}

Python用缩进,布尔型用首字母大写的True和False表示,用#表示行注释。
def doSomething():
  a = True
  if a:
    ... # Do something.

Haskell又有完全不同的语法:
doSomething :: IO ()
doSomething = do
  let a = True
  if a
    then ... -- Do something.
    else return ()

2.语义

所有编程语言都有大多数相同的特征:变量赋值、数字相加、字符串操作、调用函数、等等。

然而,每种语言都有特殊的思想,以特定的方式运行??梢越腔殖刹煌哪J剑钍?、面向对象、函数式),但是即便是两个相同模式的编程语言在细节上也是完全不同的。

在“声明类”,“调用函数”,或“定义参数的类型”时,你定义了程序的语义。有些语言遵循这样一套规则,而其他的遵循别的规则。比如:C++中声明的类可以延伸到多个类。当你使用“+”将数字和字符串加到一起的时候,根据语言的语义会得出不同的结果。一些编程语言会因为类型不匹配而导致编译失败,但是有些编程语言会自动将数字转换成十进制的字符串。

语法与语义的关系就相当于用单词(语法)来表达想法(语义)。你可以通过语言的语法来表达语义。

3.标准库

最后,每种语言都有各自的软件包,我们称之为“标准库”。

在Python中,你可以调用如下函数:
  • print():在控制台输出信息
  • len():返回数组的长度
  • 以及各种实用的???,例如:json,threading,等等
在JavaScript中,你可以使用console.log()代替print(),可以访问Object、Array等类。

标准库是一门语言中重要的组成部分。它可以为语言带来活力,没有标准库,你无法简单地做出任何东西。

很讽刺的是,并没有“标准的标准库”。每个标准库基本上都不同于其他库:一些库只提供最低限度的方法,而有些库则提供非常广泛的函数,所以开发人员基本上不需要依赖任何第三方库。

基本的想法

以上我们介绍了一门语言的构成,接下来我有一个基本的想法:我们是否可以找到一种方法清晰地分割语法、语义和标准库呢?我们又如何实现这一想法呢?

第一步:只有程序员关心语法

我想解决的第一个问题就是语法。编译器和解释器拥有更加有效的方式表现代码,我们称之为抽象语法树。我们用代码描述的内容最终可以用如下抽象语法树表示:

图:欧几里得算法的抽象语法树

如果仔细观察,你会发现上述语法树可能来自多个语言。是Python?是JavaScript?还是C++?这都无所谓:所有这些语言都拥有同一个语法树。

当然,现实的例子会更加复杂。这就是为什么我们用文本写代码的原因:更加紧凑,更加易于书写,还有更加易于阅读(有人可能有不同的看法)。从编程诞生的第一天,我们采用的就是这种方法,很少有人对此质疑。

对于一个更加现实的例子来说,抽象语法树会描述所选语言的语义(例如:类的定义)。但是拥有类似语义的语言之间还是可以共享同一个抽象语法树,并可以扩展到一定范围。这非常实用,因为你可以自动转化部分代码。

所以,我们可以把语法想象成抽象语法树之上的人类思维。代码可能并不会以文本的形式存储在任何地方,仅在文本编辑器内。如果你想在特殊的语言上使用不同的语法,也完全可以。这不会影响到别人。

我其实有点惊讶怎么没有一种工具可以将代码从一种语言转换成另一种语言,这完全可行啊。我猜肯定有人试过,但是放弃了,因为如果不将整个标准库转换过去的话是没有实用性的。很明显,我也在做这方面的尝试。

第二步. 将标准库抽象成API

API是一个非常高明的概念。每个软件都可以通过API与其他软件沟通。移动端的应用可以通过API与服务器交流。服务器可以通过API与数据库交流。每个人都可以通过API与他人对话。这是一件很酷的事情。

为什么我要在这里讨论API?因为这正是我们所需要的。API是语言的媒介。它们是一套语义,可以描述一个特殊代码??槎酝馓峁┑墓δ?。无论是函数库,HTTP服务器,或是别的。

声明API的方式多种多样??梢允荖PM上的JavaScript???,并在README文件内提供API文档。也可以是代码中明确声明的API,比如TypeScript???。也有可能并没有API的声明,也没有清晰的文档。

但是重要的是:API声明了代码??榈摹倍酝饨涌凇?,你可以用其他语言重写??槟诓康拇?,但API不会发生改变。这就是API的魅力所在。虽然编程语言一团糟,但是API很酷。

前面我们提到了标准库,并说了各个语言都拥有完全不同的标准库。如果我们能想个办法将标准库抽象出来,做成干净利落的API,那么我们就可以解决这个问题。虽然在语义上,调用print("Hello")与Java调用System.out.println("Hello")不同,但是其实它们可以是同一个API。

我们有两种方法可以解决这个问题。要么我们让大家都不要再使用标准库了,转而使用我们的“API层”?;蛘呶颐强梢匀眉扑慊远贫夏闶褂玫拇?。我并不看好“说服大家改变他们的方式”,所以我会选择后一种方法。

我们不用为编程语言的标准库中的每个函数都提供API。一般我们只可能用到标准库中的几个函数。我们可以自动将这些代码从一种语言转换到另一种语言。然后,我们只需要每个开发都用这些API替换具体的标准库的调用。不用担心,计算机依然需要你,至少现在需要。

第三步:把所有东西都做成API

现在我们有了干净的代码??槎ㄒ宓拇看獾挠镆?,并将与标准库的交互抽象成了API。

下一步做什么?创建API。

现今的代码库有多个文件构成,彼此之间通过“import语句”互相引用。这对于我们来说很便利,但是这也意味着我们需要在脑海中勾画代码库的结构。任何一个地方发生小的变化,都可能在不经意期间给别的地方带来破坏性的影响,尤其是如果我们没有做好自动测试的话。而且,代码库会不断增长,而编译的时间会逐渐加长。

也许有更好的方法解决这个问题。比如??榛褪歉龊冒旆?。

我之前写过关于??榛奈恼拢ǖ慊髡饫锊榭矗篽ttps://medium.com/@fwouts/the-zenc-master-plan-c693bf3b265e),基本上来说:每段独立的代码都应该抽象成API。我称之为???。你无需在意一个具体的??槭褂檬裁从镅员嘈吹?。在写??榈氖焙?,你不用导入这些文件。实际上,这时文件已不复存在。你可以直接使用API,它们会自动加载这些功能。

??橛惺裁春么??
  • 可以鼓励大家考虑设计:首先你需要设计API
  • 可以降低认知的开销:你仅需要“填空”
  • 简化测试:你只需测试API,并可以模拟所有的依赖性
  • 世界会变得更加美好:没有了语言之间的壁垒,没有了巨大的代码库;程序员更加快乐,客户更加快乐
第四步:尽情享受

我不确定第三步之后会发生什么,但是我觉得所有人都会很满意。
  • 大小: 341.7 KB
  • 大小: 91.3 KB
来自: CSDN资讯
4
0
评论 共 5 条 请登录后发表评论
5 楼 xingqi1058 2019-08-22 15:27
xingqi1058 写道
xingqi1058 写道
ss

说的很好
4 楼 xingqi1058 2019-08-22 15:27
xingqi1058 写道
ss
3 楼 xingqi1058 2019-08-22 15:27
2 楼 xingqi1058 2019-08-22 15:22
[img] [/img]
1 楼 aa87963014 2018-07-24 09:42
非常赞同,现在的语言太多了语法又差异太大增加无谓的学习成本很恶心

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • https://blog.csdn.net/weixin_38744694/article/details/99825769

  • 怎样解决编程语言之间差异性问题?(转载)

  • 30种编程语言的比较选择问题

    本文涉及到的编程语言:C、C++、Java、C#、Prolog、VB、Scala、Clojure、Haskell、Ada、Python、Ruby、Pascal(Delphi)、Fortran、Lisp、matlab、Perl、Erlang、Boo、Tcl、Bash、C shell、Objective-C、PHP、PL-SQL、Transact-SQL、ASP、JSP、Lua、smalltalk、R、golang,rust

  • 如何解决不同浏览器之间的兼容性问题

    常见的浏览器兼容性问题解决方案大致有以下九种形式:?   一、不同浏览器的标签默认的外边界和内填充不同   问题表现:不加样式控制下,margin和padding差异较大   解决方案:css里 *{margin:0; padding:0;}   备注:这是最常见也是最易解决的一个兼容问题,几乎所有的css文件开头都会用通配符*来设置各个标签外边界和内填充为0

  • WinPcap编程错误:error C2079: 'IPAddress' uses undefined struct 'sockaddr_storage的解决办法

    出现这个问题的原因一般是由于Winsock的版本和IPv4和IPv6的版本兼容性问题。由于新版的 Winpcap 完全使用了新的 Winsock(支持IPv6),因此这个问题可能影响到每一个已有程序。?以下是新旧两版的 packet32.h 之间的差异:【新版本】typedef struct npf_if_addr {??? struct sockaddr_storage

  • https://blog.csdn.net/cui_yonghua/article/details/90674650

    1. Java语言概述 java语言的特性:①面向对象性 ②健壮性 ③跨平台性(write once ,run anywhere)—JVM 河床好比操作底层,jdk好比是河水,java应用程序好比是船。 JVM (Java Virtual Machine) : 解决了不同操作系统之间的差异; JRE (Java Runtime Environment) : 包括java虚拟机 + 解释器; JDK...

  • https://blog.csdn.net/zhangliangzi/article/details/51221477

    一、什么是面向过程 面向过程是一种思维方式。当试图通过面向过程解决问题时,我们的关注点在于问题解决的流程,重在这个过程的控制,需要用大量的??椋?榛乃枷朐醋杂谟布?,在C语言中是函数)将大问题拆解,程序员通过控制??榈闹葱兴承蛞?em class='related_suggestion_highlight'>解决问题。举个例子,当我们解决一个“如何将大象装入冰箱?”的问题时,最简单的解决思路是面向过程解决: 1、关注过程,将大问题拆解为小问题,实现每个小问题解决方法

  • https://blog.csdn.net/weixin_40819954/article/details/79679600

    最近因为毕业设计,需要用到C语言写一部分的代码。之前学习C语言的时候只是会写罢了,没有关心很多其他的问题。这次写代码就直接踩坑了。简单地写下一个笔记,提醒自己。关于C语言标准C语言标准有K&RC,C89,C99,C11几个标准,不同的标准有不同的书写规则。具体内容可以参考:https://blog.csdn.net/qq_31029351/article/details/53290990谢...

  • 移动端开发 安卓和ios兼容性的那些坑以及解决方案

    问题1:移动端项目要求是全屏滚动,用的是 fullpage,上下滚动时安卓正常,苹果手机浏览器上下滚动时会出现底色问题 解决方案: document.body.addEventListener('touchmove', function (e) { e.preventDefault(); //阻止默认的处理方式(阻止下拉滑动的效果) }, {passive: false...

  • https://blog.csdn.net/hzr0523/article/details/80978343

    一、概述       计算机中的任何数据都是二进制,而编程语言是人与计算机之间的桥梁,编译语言利用算法,解决人类使用十进制与二进制之间的鸿沟。(官方一点)  

  • https://blog.csdn.net/weixin_40803490/article/details/79871895

    一、实验目的1、 熟练掌握线性表的结构特点,掌握顺序表的基本操作。2、 巩固?C++相关的程序设计方法与技术。3、 学会使用顺序表解决实际问题。二、实验内容1、顺序表的建立与操作实现建立 n?个元素的顺序表(n?的大小和表里数据自己确定),实现相关的操作:输出,插入,删除,查找等功能。编写完整程序实现,程序语言不限定,使用技术形式不定。2、实际问题解决(*)使用顺序表来实现约瑟夫环问题。三、设计...

  • https://blog.csdn.net/haboop/article/details/89848590

     BI(Business Intelligence),中文翻译是商务智能,是一套完整的解决方案,用来将组织中现有的数据进行有效的整合,快速准确的提供报表并提出决策依据,帮助组织做出明智的业务经营决策。   大数据(Big Data)是从收集的海量数据中,通过算法将这些来自不同渠道、格式的数据进行直接分析,从中寻找到数据之间的相关性。简单而言,大数据更偏重于发现,以及猜测并印证的循环逼近过程...

  • https://blog.csdn.net/github_36757348/article/details/53493343

  • https://blog.csdn.net/jonahzheng/article/details/8070134

    Delphi7转移到Delphi XE, 从代码上看,一个变化就是对Unicode(从此用Delphi编写乱码的问题,国际化问题算是彻底解决了)。 特别是代码中喜欢用PChar的同学要注意了,在XE中PChar默认都是PWideChar,而Delphi7中指向PAnsiChar的。 关于Delphi XE的Unicode说明可以下面的一篇资料,讲的很详细了 //www.china

  • https://blog.csdn.net/u011526599/article/details/51337364

  • https://blog.csdn.net/quanjiao4514/article/details/78568150

    首先来简单说下什么是DockerDocker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 点击进入Docker官网 用我自己的理解,Docker就是一个USB鲸鱼吧,鲸鱼它也是官网的形象描述。为何称为USB呢,因为它有很好的移植性,类似usb一样,

  • https://blog.csdn.net/weixin_33787529/article/details/88826429

    Vue中实现组件之间的通信方式有很多种,eventBus,props,vuex,v-on,ref...等等。自己在很多时候用的没有章法,简单的想着实现功能就可以了,以至于逻辑混论,后期很难维护。所以给自己做个总结,方法并不是唯一,只是我现在认为的解决方案。 组件通信包括:子组件与父组件之间,兄弟组件之间,???em class='related_suggestion_highlight'>之间 父子组件通信 props...

  • https://blog.csdn.net/u013490280/article/details/82085130

    异构性:分布式系统由于基于不同的网路、操作系统、计算机硬件和编程语言来构造,必须要考虑一种通用的网络通讯协议来屏蔽异构系统之间的禅意。一般交由中间件来处理这些差异。 缺乏全球时钟:在程序需要协作时,它们通过交换消息来协调它们的动作。紧密的协调经常依赖于对程序动作发生时间的共识,但是,实际上网络上计算机同步时钟的准确性受到极大的限制,即没有一个正确时间的全局概念。这是通过网络发送消息作为唯一的通信...

  • https://blog.csdn.net/m0_38106923/article/details/100130354

  • https://blog.csdn.net/qq_40693171/article/details/100716766

Global site tag (gtag.js) - Google Analytics