- 论坛徽章:
- 2
|
回复 7# windyrobin
应该是我记错了, 不是从论坛而是从这篇文章听到的这个词。
这个人我不了解…… 但他的blog我是有订的, 只是他越来越多的文章都是关于js了……
我也只是从语言角度上批评js很烂。
烂不等于不能解决问题, 比如C的声明也很烂……
甚至烂语言对某些问题解决起来还很顺……
比如我有两个wav, 怀疑它们是从同一个wav上截取的, 但时间差了一点, 想找出重叠部分。
最初想法是将每个simple读取出来, 之后就全是熟悉的工具: base64转换为text 然后 diff 比较, 可行!
然后感觉自己研究wav格式麻烦, 就在python里找了找, 结果 wav 读取, base64, diff, 最后计算md5 在标准库里全都有……
于是几行代码就搞定了…… 如果用C/C++ …… 哼哼…… 大家都懂的……
然而一旦脱离定位, 比如python的"胶水", 那就有可能写得让人两眼泪汪汪……
比如js
- function counter(start) {
- return function() { start = start+1; return start; };
- }
复制代码 而python里面想要兼容性好 —— 即,不支持nonlocal的python版本里
- def counter(start) :
- container = [start]
- def inc() :
- container[0] = container[0]+1
- return container[0]
- return inc
复制代码 python丰富的标准库(相比lua一个光杆)让人口水直流, 但上面的代码真的让人欲哭无泪……
再说 lua vs js。 我说js烂就是拿lua作对比的。
比如它们都有同一的数据结构: table。 哦, js称之为 "object" 。
其实叫个什么都无所谓, 关键是一旦叫object, 就容易陷入岐途。
一个岐途就是将某个参数, this, 当作隐式参数, 并十分特殊的处理, 于是js里面有4种函数调用方式, C++都不敢这么复杂啊……
普通调用: f(args...) 给this传入啥? global还是window来着?
方法调用: x.f(args...) 传入x
间接调用: x.f.call(y,args...) 传入y
创建调用: new f(args...) 这个与那个所谓的 prototype(又是一个烂货) 有关了
每次我遇到写js的人都会问一个问题……
Array.prototype.indexOf.call(n.parent.childNodes,n);
语言本身能不能提供一种不那么坑爹的写法?
而且indexOf还不是所有浏览器支持, 即使支持了n.parent.childNodes还是一个hosted object, 还不一定有效, 实际情况就是ff与chrome都没效……
就这水平也好意思说自己functional吗?
lua有且只有一种函数调用。 f(args...)。
如果需要像js那样将一个table塞满一堆函数, 也可以 x.f(args...)。
如果这些函数又恰好以该table为第1个参数, x.f(x,args...) 或者等效的 x:f(args...)。
t["x"] 与 t.x 等效, 这是js于lua另一个很类似的地方。
但将t称为object而不是table, 将x称为property而不是key会陷入的另一个岐途就是这table只能以string作key。。。
a[0] = 12;
a["0"] = 26;
alert(a[0]); // a[0] 被改了……
还有 function scope... scope这种重要但确实是非常基础的东西, 居然是评价一个人js水平的关键(一个stackoverflow的帖子这么说的)……
居然将变量设计为function scope, 这不诚心让程序员写bug代码吗? 设计者以及ECMA那些家伙, 长的是猪脑袋啊?
最后, 那篇文章还提到coroutine …… 好嘛, 又是一个槽点……
那篇文章我没仔细看, 而且他也不是详细介绍coroutine的。 我看的是一个老外的一篇, 以及firefox的什么什么链接。
js, ecmascript 1.7 提供的那个东西是类似python那样的generator; 算不上coroutine, 差远了。
问题出在将含有yield的函数f, 嵌入到另一个函数g中时的行为。
js1.7确切情况我不知道, 曹那篇文章也没有写。 但如果老外那篇文章以及ff非虚, g中对f的调用就会产生一个generator, 然后丢弃。
yield 只能传递仅仅一层, 只能当作geneator 用。
而lua提供的coroutine是真正的协作线程。
t = coroutine.create(f) -- 创建一个协作线程
r = coroutine.resume(t, args...) -- 首次调用为该线程传递启动参数
f的调用会产生一个调用链, 如果这个调用链上存在yield, r 就会得到 yield的值, 而下次 resume就会给yield处提供一个值, 并继续执行。
直到f调用产生的整个调用链都没有 yield, r 就是 f 的返回值, 相当于 r = f(args...)
python设计成这样我表示理解, 因为python的yield本来就是从geneator演化来的:
手动实现一个class, 有next方法, 会抛出 StopIteration异常。。。 就可以用作 for i in g :
然后提供yield语句(之后才改为表达式), 可以更方便的实现这样的class。
然后提供next, 让外部可以给yield传递信息。
但没办法继续改了, 因为创建协作线程与resume是隐式且不可分的, f()。
python是一种自下而上: 我需要for i in g: , 我需要这个 g写起来容易, 我需要给geneator传递信息 。。。
而lua是自上而下的, 我需要coroutine, 然后python那些乱七八糟的全都有了, python没有的也有了。
但有了python与lua作为前车之鉴, js还选择generator就不可理解了……
老外那篇文章提到了这3种语言, 最后表示: js里应该提供geneator而不是coroutine。
而理由大致就类似于: 我们需要计算的数目小, 所以应该使用罗马数字。
综上, 都可以说明我前面提到的, 流行没好货, 越是参与的人多, 越是不能集思广益, 越是会将平均智商扯低……
C++沦为小众语言其实是它脱离流俗的标志 |
|