来造个php代码生成器吧,实在太难写了

2011-03-12 09:12:20 +08:00
 aligo
我不是一个职业程序猿,觉得php实在太难写了,但同时php的性能还是可以的,而且最主要的是使用广泛
之前帮sai姐姐写了一个算法,最近刨出来用scala和ruby重写了,可是她要我一定用php,坚决不在服务器上装jvm
我看过(包括写过)一些php,它们其实不是代码而是密码,但是大多数情况下php就算不是最好的选择,也是唯一的选择
这里应该有不少人对php是处于爱恨交织态度,所以既然逃不开在生产环境使用php,那么至少开发过程中可以不用写它吧
于是我想了想,不如来做一个php代码生成器吧,以下是我结合使用php经历的构想,欢迎各位提意见:

* 语法简化
* 告别<?php ?>,纯净php代码,反正大家都会用模版,内嵌html是个糟糕的做法。php6也有此改进
* 每一行末的;完全是必要的
* 变量名的$号完全是没有必要,只要全局常量全大写,就不会混淆
* 类名大驼峰,方法名小驼峰,为了一些语法糖不会混淆,这个必须强制

* 类
* 为了纯洁的oop,放弃static,改为类的伴生对象
* 为了纯洁的oop,例如str_replace(...),改为str.replace(...),在字符串对象上调用方法。php6或者7也将如此
* 类的访问控制如public private protected,应该像时髦的语言那样,尽可能少写。即默认public,一个private可以连续修饰好几个方法
* 为了更好的oop,添加mixin功能。php6或者7也将如此
* 基于上两条,同时提供更加细致的访问控制,可以用来专门指定对某个类及其后代的访问权限
* 调用方法中的->改为.或空格,括号不是必须的
* (2012)push->arr,如此实现从右到左调用方法,把2012插入数组arr后端,省略括号后为2012 push->arr

* 方法
* function -> def
* 不变性原则,绝对不能传递引用
* 无上限参数列表用*更直观,而不是在方法中func_get_args()
* 可以有多个返回值


* 静态类型
我目测写php的时候一般至少有20%的单元测试代码不干别的,专门测试类型是否正确
同上,还有更多(有时候是80%了)的phpdoc注释不干别的,专门标示方法参数的类型和返回值的类型
所以静态类型虽然看上去很难用,但是有助于减少体力劳动,所以:
* 语法:str1: String = "hello",用java们的空格方法显然太难看
* 声明时,方法的输入输出一定要显式指定类型,但对于lamdba可选,因为它们大概不需要被单元测试和生成文档
* 字面量和new方法创建对象,除非特例,否则显然不必要专门指定类型
* SQL类型:我用php时,如要长距离传递SQL语句,会定义SQL类,然后执行SQL方法判断输入的类,一定得是SQL类才行。SQL类无法和字符串拼接,然后用bindParam输入参数,防止SQL注入和人为疏忽的SQL注入
* 数组的成员类型要相同,即一个成员的key是数字那么该数组成员所有key都应该是数字,字符串"1"什么的是非法的
* 隐式转换,有静态类型必然还要有它

* 函数式编程
虽然5.3开始支持了lamdba等,但是并不好用
* 语法:{(arg1, arg2) ...},而不是function(arg1,arg2){...}
* {(arg) ...}("foobar")的就地调用,结合前面的调用方法,("foobar"){(arg) ...}也可以,而且更美观
* 结合纯洁的oop,arr.each{}用以代替foreach和变态for等循环语法,同时arr还应该有map和reduce/collect/folding等方法
* 其他一些函数式方法似乎不是很必要

* 其他
* 让定义数组方法更像json些,用:而不是=>,用花括号而不是圆括号,array开头不是必须的

以上基本是我目前的想法,非常不完整,大家有兴趣可以一起做这个东西,当然一切都是可以讨论的,目前我也只是设想阶段
如果各位在哪里见过类似的东西,那就不需要重复发明轮子了XD
11852 次点击
所在节点    PHP
52 条回复
aligo
2011-03-12 12:07:05 +08:00
@CupTools 我不想改变php啊。。。另外也不觉得php恶心,只是写起来有点麻烦,而且缺乏表现力难以理解

@vayn 没事,这事我也没干过,首先需要解析器和生成器,hiphop用的是Flex/Bison,不过我觉得用php写成的LIME更合适(http://sourceforge.net/projects/lime-php/),或者也可以用http://pear.php.net/package/PHP_ParserGenerator和http://pear.php.net/package/PHP_LexerGenerator
然后再写一个标准库是必须的,没必要把所有特性,一股脑的交给生成器
最后就是一些外围的工具,如make工具,和文档/单元测试工具的集成,编辑器的语法高亮等

不过最重要的还是搞一个让大家满意而且愿意用的语法,当然这个可以慢慢改进

有兴趣吗?
darasion
2011-03-12 12:17:03 +08:00
看来大家都这么想过啊!!!!!

我从学php一开始,就想到这么做了。只是苦于没有时间精力更重要的是没有毅力!!!!!!

许许多多的想法做法以及更重要的灵感都已经随着时间空间不经意间的逝去了!!!!!!

后来一想好像似乎八成大概没准不一定这个东西应该没啥太大作用!!

人们为啥总是想出很多很多很多生成某种语言的语言的语言的语言......

始祖好像最先是01011010111吧啊!!!!!!!????????
后来出了个什么汇编,它是不是生成01011010111语言的语言????
再后来出什么A啊B啊C啊的语言,它好像大概是先生成汇编,然后再由汇编生成01011010111。是不是所谓搞基语言!????????

后来后来是不是又有人在A啊B啊C啊的语言里边又创造出什么java、 c#、php等等乱七八糟的更搞基的语言!!!!!!!??????

终于有一天!!!!我们来了,我们要做的是比更搞基语言更搞基的更更搞基语言!!!!

未来的某一天,是不是有人觉得我们的更更搞基语言不够搞基,发明一个更更更搞基语言呢?????

............
bcxx
2011-03-12 12:28:49 +08:00
@darasion 咆哮体了= =||

其实每种语言都每种语言特点嘛,只不过php的语法实在是让人失望
levn
2011-03-12 12:38:17 +08:00
原来机器语言是搞基语言…… — —
rechtar
2011-03-12 12:53:57 +08:00
@aligo 解析器和生成器、外围工具、语法高亮,这些都不是大问题。只要肯把时间精力往里砸,几个月就能出来个样子了
但是,「让大家满意而且愿意用的语法」——直说,这不可能的 = =

@darasion 亮了!XD
huangz
2011-03-12 13:37:24 +08:00
见过一些有类似想法的人,不过都是做着做着就没有然后了。。。

因为他们都转写python、ruby之类去了。
harryxu
2011-03-12 13:44:41 +08:00
我感觉php虽然不是特别优雅,但也没有到神马丑陋的地步,配置好vim写起来也挺爽的。

如果lz要找一个生成php代码的语言可以试试看看 haxe http://haxe.org/
e6nian
2011-03-12 13:47:39 +08:00
囧。你想重复发明轮子么?
写ruby或者node.js吧。
reorx
2011-03-12 14:47:30 +08:00
@huangz +1
aligo
2011-03-12 15:25:01 +08:00
@huangz python、ruby、groovy、scala、node.js、fantom、erlang、reia什么的时髦的语言,不敢说精通,我大概都折腾过一点吧(我不知道我这种折腾的态度对不对),然后又被迫回头
现在php仍然是主流,我也没觉得php有多么糟糕,只是觉得写php应该更容易更轻松一些才是
做着做着就没有然后了,这也是我担心的事情的XD
@harryxu 恩,我了解haxe,准确的说我那些关于静态类型的想法就是来自于它,去掉$的想法就是来自于neko
aligo
2011-03-12 16:00:43 +08:00
天啊,我找到这个:
http://code.google.com/p/php-snow/
语法非常简洁,静态类型,内牛满面,至少和我的想法有80%的相似
重新考虑是否要自己造一个。。。
levn
2011-03-12 16:26:14 +08:00
为什么不考虑加入他们……
aligo
2011-03-13 18:18:43 +08:00
今天把php-snow看了一下,它用Python Lex-Yacc的解释器,还可以把现有的php转换回去
虽然很多想法和我相似,但是感觉它精简过头了,例如用fn而不是def,用pri而不是print,不太符合日常期望,而且oop和fp也没有针对性改进
est
2011-03-13 18:30:12 +08:00
还不如基于zend什么的字节码搞个target compiling
aligo
2011-03-13 18:34:42 +08:00
@est 部署问题啊。。。
如果那么搞的话,和直接编译成jvm或者bean或者neko或者像hiphop那样没区别了

动机只是因为php太难写,而要代码生成器,生成的还是php
aligo
2011-03-13 21:14:22 +08:00
晚上把我对基本语法的想法写下来,欢迎吐槽

一切都是对象和方法调用(类似Smalltalk),并且完全基于lambda(类似Lisp),实现各种语言的基本功能
最简单例子1+1其实是1.+(1)
包括代码块也是方法调用,所有代码其实都是一个顶层对象Source的内部调用
如果创建一个类
class A
def a
print "helloworld"
其实是
Source.class(A,{
this.def(a,{
print "helloworld"
})
})

if(x == 0)
...
else
...
其实是
this.if((x == 0),{...},{...})

因此三目运算符
(x == 0) ? 1 : 2
其实是
this.if((x == 0),1,2)

调用方法的点是可选的,传递参数过程中圆括号可以省略,逗号可以用空格替代,花括号可以用换行缩进替代,end闭合代码块是可选的
arr.each({...})
str.replace("a","b")
可以为
arr each
...
str replace "a" "b"

lambda部分,具名输入为
{(arg1,arg2,args*)
...
}
如果
{
print "helloworld"
}
print方法的调用对象,是上下文对象列表中的由最后一个到第一个中的一个,按顺序,第一个永远是Source
所以对一个lambda对象执行call/apply方法
lambda.apply(this) #定义上下文不调用方法
lambda.call(...) #传入参数调用方法
或者
lambda(...)
的输入参数永远是被加入到当前上下文对象列表中的最后一个
基本上就是一个lambda会继承包裹自己的lambda的上下文对象列表,并且加入新的对象,再传递给自己内部的lambda
用俗话说,就是类似闭包感觉,另外当然闭包也是存在的,唯一的区别就是不会在闭包能访问的对象上调用前面说到的print方法等

简单说就是糅合各种语言,集大成的山寨语法
另外我没把上面这些为什么这么做的好处写出来,要写估计又是一大堆了,有可能,我打算尽快着手实现
aligo
2011-03-13 21:18:56 +08:00
。。。贴出来之后缩进都被干掉了。。。
大家自行脑补好了。。。

现在实现上我最大难题就是eval,我只能想到提供一个php写的标准库然后把全部代码生成器的代码的都灌进去一遍的方法

这就基本意味者这个php代码生成器必须用php写成(或者至少有php实现),而这东西诞生的目的是php很难写。。。

另外php-snow用的PLY看上去是不错的,关键是一直被更新着
aligo
2011-03-19 09:34:31 +08:00
这两天稍微找了找能用的资源,并没有什么用来生成纯php解析器的生成器的好方案
现在有的选择要么就是自己用php从头造一个,以后再慢慢改成用代码生成器生成(有点绕,就是用代码生成器生成自己的解析器生成器和代码生成器自己)
要么像php-snow那样用例如PLY之类的
各位有什么好主意吗。。。
bigbrother
2011-03-19 09:48:26 +08:00
我笑了,
整天什么面向对象面向对象的,

有几个是能按面向对象的编程标准写程序的,大多数时候,你们写个类跟写个方法没啥不同!
ray58750034
2011-03-19 10:57:39 +08:00
php-snow的语法有点看不懂了,用了太多自定义的东西。
现在不是很时髦Polyglot Programming(多语言编程)么,相信慢慢地会有更多自定义的语言出现,计算机行业的进步啊~
虽然我挺喜欢现在的php的,但还是很期待你的尝试。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/9646

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX