很多人不喜欢用某种编程语言,并不是因为其不好用或者设计上的问题,只是单纯的讨厌其代码风格,比如我很喜欢let这个关键字,想把lua中的local,c++中的auto都替换成let。很讨厌python中的强制缩进,喜欢c风格的花括号。
比如我心目中理想的python风格就是这样的
fn func(a: number, b: number, kwargs: {a:b,c:d}) number {
a+b
}
if @NAME == "main" {
print("...")
}
但是,如果要改动这些东西,必须改编译器/解释器的前端,而且一改全改,lsp什么都得改,于是我就有个设想就是在编辑器里的时候用一个中间层自动将其转译成原来类型的代码,这样也不用改lsp之类的,又没有编译的烦恼。。
这不是重点,重点是如何实现按照每个人的口味将一门编程语言的语法转换成另一门的
我个人觉得转换的话不如重新写一遍, 但你完全可以根据 ts-mode 划分的抽象语法树, 在函数定义和条件语句后加上 overlay ,达到你说的效果而不改变代码本身, 以方便阅读.
我倒是觉得语法不是编程语言圣战的原因。scheme跟common lisp以及一大堆其他的都是纯括号,可以说根本没有(具体)语法,也不见得争吵就少了。或者rust也会因为语法繁琐遭到诟病,但仍然是现在最火(?)的新兴语言,主要争论还是在语言设计上。不过这个有点离题了
不太可能,这样的话你需要搞一套语法的超集出来,那会挺复杂的。
wsug
9
python这样全是缩进的很难,非缩进的语言实现起来就好多了,lua中的local替换成let
, 这个用字符串查找替换就可以。
比如我org-mode中有好多代码是 #+BEGIN_SRC php … #+END_SRC
包裹的。
我做了字符串替换#+BEGIN_SRC php
替换成"<?php" ,`#+END_SRC`替换成`?>`,生成的php文件就可以直接执行。
然后调试问题,我遇到的主要是行号处理,解释器给出错误在执行文件中的行号,要把那个行号对应到你实际源文件中的行号。
巴克斯范式不行么?
实在不行看看能不能搞到原ast,一对一替换。
如果只是修改语法糖,你可以看看vala这个语言的设计。
但是我想说的是,事情没有你想的那么简单,即使最简单的语法替换也会有很多工作。
世间难有完美的语言,关键是语言的生态库。光有优美语法的语言很多,但是长期活下去的很少。
1 个赞
这个我同意,但是有些别的语言的语法糖写的确实很方便,我这个设想估计只牵扯到编译器前端,应该不会特别复杂。
你有空看看vala吧,vala就是一个纯粹c#语法糖的c语言。
c的速度,python简洁,默认大括号,语法很舒服,就是已经弃坑了。
LdBeth
14
见识得太少了
http://www.txl.ca/
其他的比如 invisible xml + xslt, ANTLR 这种稍微会绕弯路的解决方案就更多了。
TXL 也能处理 Python/Haskell 这种 offside rule,无非就是先跑一遍预处理把缩进转换成 token 就可以了,实际上 GHC 也是这样 parse Haskell 的
1 个赞
yfzhe
15
3 个赞
楼主想要的不仅仅是加了糖的 Python,而且要现成的 lsp 能够支持。
通过转换器把代码实时去糖,交给 lsp 分析。分析结果再通过转换器反馈到编辑界面:
+- Emacs -------------------------+
| |
| Sugared Code | <---> User
| ↑ |
| Adapter |
| ↓ |
LangServer <---> | LSP Client <---> Desugared Code |
| |
+---------------------------------+
估计 Emacs 性能抗不住。
1 个赞
o2o
18
racket的理念好像就是构建不同的DSL语法在不同的场景使用,我个人还是挺认同这种理念的。其实现在绝大部分开发者使用的框架,从另一个角度看也是一种领域专用的语言。
如果你想要的是 利用旧有的语法用新的语法糖重新包装
的功能,这一点在 Racket 语言通过 define-syntax
可以轻松做到。以下是一个例子 :
my-if 通过 define-syntax 添加了 then else 关键字,形成新的语法糖,与原生 if 表达式等价。