其实关注中文编程领域很久了,一直在思考为什么一个14亿人使用的语言没有出现一个被广泛使用的编程语言。

夭折的中文编程

其实关注中文编程领域很久了,一直在思考为什么一个14亿人使用的语言没有出现一个被广泛使用的编程语言。本文是对知乎和推特上各路大佬对中文编程看法的总结和延伸。

中文编程现状

为什么很多人想要中文编程

因为编程和他们已经熟练运用的技能之间存在巨大的鸿沟,他们觉得中文能够帮助他们缩窄这个鸿沟。我觉得这个思路既不全对也不全错:中文确实能够缩小一点学习编程的距离,但也就一点点,难以改变学习编程的门槛。能学会编程的人,最后都会发现中文不中文其实不重要。

重要的是那一堆符号后面所隐藏的算法和逻辑。甚至,完全可以用emoji表情来写代码。

中文编程是个伪概念

就像很多人说的,他们也没有用英文去编程,而是用Python、C++、Java编程。

其实中文编程就是一个伪概念,C++是丹麦人写的,Linux 是芬兰人写的,Python是荷兰人写的,Ruby 是日本人写,但程序员不用丹麦语写 C++,也不用荷兰语写Python,编程语言是一套符号系统,没有英文编程,也没有所谓的中文编程,用中文写代码并不会降低算法和逻辑的复杂度。

汉语第三方库的优点

在我的思考中,中文编程并不是彻底用汉字写代码,并不是只针对关键字做语法分析和正则替换。

而是有一个中文编程的生态,有很多用基础库和第三方库能有一套完整的汉字API,这对以中文母语者来说,尤其是对初学者来说,能降低很大的心智负担。

其实 python 的基本语法很简单了,只有几十个关键字,很多人真的能轻松上手。很多人都是被卡在第三方库上。

如果中国人能直接用汉字导入类似“支持向量机”、“异步服务器”、“XXX运行时”的 python库,中国人上手任何库都能像今天英语母语者们一样简单轻松,5 分钟从入门到精通。

中文编程的痛点 - 生态

之前有易语言,可以把它理解成中文编程,但是没多久就销声匿迹了。

事实上现有的社会中完全没有中文编程的生存环境,如果读不懂英文的代码,写不出英文代码,看不懂英文文档,基本上没有公司会招你做程序员。大量的历史代码你不能维护,同事写的代码你不能调用,框架文档不能读懂,招你来做什么呢?

中文编程真正需要的,不是着眼于那几十个关键字的汉化,而是一个宏观的,社会性的纯中文软件开发环境。框架,库,文档是中文的,公司招聘的也是中文的,中文成为程序开发的默认语言。这样,只会编程,不会英文,也可以找到好工作。

这才是其根本需求。

在今后的十年二十年内,如果你只会“中文编程”,大概率是找不到编程工作的。

所以很多程序员为什么不提倡“中文编程”,因为是在浪费初学者的时间。

Zpy - Lab

在有了对以上中文编程现状的思考后,我做了zpy-lab。

GitHub - zpy lab, chinese programming lab

zpy lab 的技术选型

Q1: 为什么选用 Python 语法,而不选择其他编程语言如C/C++,Java,JS,PHP,Go
  • Python 语法最简单,最易上手。

  • Zpy 的目标用户是对中文编程感兴趣的初学者和开发者,毫无疑问 Python 单的语法会帮助他们更快上手

  • Zpy 语法只是 Python 语法的翻译,初学者熟练之后,可以无难度地转向 Python 开发

Q2: 为什么没有从 Python 解释器入手修改源代码中的关键字,而是选择做一个翻译器。
  • 安装简单,快捷

  • 兼容 Python 生态,可以使用社区很多现成且优秀的包

  • 开发起来很简单,可拓展性强

Q3: 如何解决中文编程生态差的问题
  • 借用Python丰富的标准库与第三方库
  • 可通过插入一个替换表插件来实现对库的汉化

zpy lab 基本示例

值得一提的是,为了降低入门的门槛,zpy-lab做成了开箱即用的web页面。

在线体验 - Zpy Lab

并且zpy语法完全兼容python,可以在任意代码段引用python库。

几个例子
打印("你好, 世界!")

你好, 世界!

打印星号三角形
星星数 = 12
如果 星星数 % 2 != 1:
    星星数 += 1
对于 层数 在 范围(舍入((星星数-1)/2)+1):
    星星 = '*'*(层数*2+1)
    打印(星星.center(星星数, " "))
      *      
     ***     
    *****    
   *******   
  *********  
 *********** 
*************
圆周率蒙特卡洛方法
从 随机 导入 随机
从 时间 导入 性能计数器
基准 = 1000*1000
击中 = 0.0
开始时间 = 性能计数器()
对于 i 在 范围(1, 基准+1):
    x, y = 随机(), 随机()
    计算值 = 乘方(x ** 2 + y ** 2, 0.5)
    如果 计算值 <= 1.0:
        击中 = 击中 + 1
圆周率 = 4 * (击中/基准)
打印("圆周率值是: {}".格式化(圆周率))
打印("运行时间是: {:.5f}s".格式化(性能计数器() - 开始时间))

圆周率值是: 3.141464 运行时间是: 0.66439s

排序算法
# 排序算法
函数 冒泡排序(目标数组):
    对于 索引一 在 范围(长(目标数组), 0, -1):
        标记 = 错
        对于 索引二 在 范围(0, 索引一 - 1):
            如果 目标数组[索引二] > 目标数组[索引二+1]:
                目标数组[索引二], 目标数组[索引二+1] = 目标数组[索引二+1], 目标数组[索引二]
        如果 标记:
            终止
    返回 目标数组


函数 希尔排序(目标数组):
    步长 = 长(目标数组)
    当 步长 > 0:
        步长 //= 2
        对于 甲 在 范围(步长, 长(目标数组)):
            替换 = 目标数组[甲]
            乙 = 甲
            当 乙 >= 步长 与 替换 < 目标数组[乙-步长]:
                目标数组[乙] = 目标数组[乙-步长]
                乙 -= 步长
            目标数组[乙] = 替换
    返回 目标数组


函数 冒泡排序(目标数组):
    对于 甲 在 范围(长(目标数组), 0, -1):
        标记 = 错
        对于 乙 在 范围(0, 甲 - 1):
            如果 目标数组[乙] > 目标数组[乙+1]:
                目标数组[乙], 目标数组[乙+1] = 目标数组[乙+1], 目标数组[乙]
        如果 标记:
            终止
    返回 目标数组


函数 快速排序(目标数组):

    函数 _快速排序(目标数组, 左指针, 右指针):
        枢轴 = 目标数组[左指针]
        原左指针 = 左指针
        原右指针 = 右指针
        左指针空标记 = 0  # 左指针 po整数er null
        当 左指针 != 右指针:
            如果 左指针空标记:
                如果 (目标数组[左指针] >= 枢轴):
                    目标数组[右指针] = 目标数组[左指针]
                    左指针空标记 = 0
                否则:
                    左指针 += 1
            否则:
                如果 (目标数组[右指针] < 枢轴):
                    目标数组[左指针] = 目标数组[右指针]
                    左指针空标记 = 1
                否则:
                    右指针 -= 1
        中指针 = 左指针
        目标数组[中指针] = 枢轴
        如果 原左指针 < 中指针 - 1:
            _快速排序(目标数组, 原左指针, 中指针 - 1)
        如果 中指针+1 < 原右指针:
            _快速排序(目标数组, 中指针+1, 原右指针)

    左指针 = 0
    右指针 = 长(目标数组) - 1
    _快速排序(目标数组, 左指针, 右指针)
    返回 目标数组


函数 选择排序(目标数组):
    对于 甲 在 范围(长(目标数组)):
        最小数值 = 甲
        对于 乙 在 范围(甲, 长(目标数组)):
            如果 目标数组[乙] < 目标数组[最小数值]:
                最小数值 = 乙
        目标数组[甲], 目标数组[最小数值] = 目标数组[最小数值], 目标数组[甲]
    返回 目标数组


导入 随机
从 拷贝 导入 深拷贝
数据集 = [随机.随机数(0, 100) 对于 _ 在 范围(20)]
打印("     原数据:", 数据集)
打印("   希尔排序:", 希尔排序(深拷贝(数据集)))
打印("   冒泡排序:", 冒泡排序(深拷贝(数据集)))
打印("   快速排序:", 快速排序(深拷贝(数据集)))
打印("   选择排序:", 选择排序(深拷贝(数据集)))

​ 原数据: [33, 60, 92, 37, 34, 7, 33, 18, 82, 73, 14, 79, 35, 70, 52, 15, 68, 65, 46, 10]

希尔排序: [7, 10, 14, 15, 18, 33, 33, 34, 35, 37, 46, 52, 60, 65, 68, 70, 73, 79, 82, 92]

冒泡排序: [7, 10, 14, 15, 18, 33, 33, 34, 35, 37, 46, 52, 60, 65, 68, 70, 73, 79, 82, 92]

快速排序: [7, 10, 14, 15, 18, 33, 33, 34, 35, 37, 46, 52, 60, 65, 68, 70, 73, 79, 82, 92]

选择排序: [7, 10, 14, 15, 18, 33, 33, 34, 35, 37, 46, 52, 60, 65, 68, 70, 73, 79, 82, 92]