Lua的好和不同 part1

翻译自 http://notebook.kulchenko.com/programming/lua-good-different-bad-and-ugly-parts

我已经用Lua编程了9个月,应该是时候停下来想想这段经历了。过去几年用过不少编程语言, perl, C, Javascript, MATLAB还有其他的,从TurboPascal到F#。Lua和这些语言做个比较是件很有意思的事情。我已经用Lua完成了一些不同类型的项目:一个远程调试器MobDebug https://github.com/pkulchenko/MobDebug ,扩展一个Lua IDE https://github.com/pkulchenko/ZeroBraneStudio ,一个mobile应用https://github.com/pkulchenko/LuaRemote ,还有几个教育性质的脚本https://github.com/pkulchenko/ZeroBraneEduPack ,以及一个在浏览器canvas上使用Lua画图的demo http://notebook.kulchenko.com/programming/drawing-on-browser-canvas-with-lua 。

我已经看到有比较Lua好坏的文章,比如(http://lua-users.org/lists/lua-l/2007-11/msg00248.html http://blog.datamules.com/blog/2012/01/30/why-lua/ http://lua-users.org/lists/lua-l/2012-01/msg00731.html http://stackoverflow.com/questions/564665/advantages-of-lua http://gergely.imreh.net/blog/2011/07/language-of-the-month-lua-part-2/ http://stackoverflow.com/questions/1022560/subtle-differences-between-javascript-and-lua http://www.luafaq.org/gotchas.html ),但是我发现一些影响或者比较关注的特性没有在列表上。所以我写一个自己的列表。这篇文章不够广泛,Lua语言的某些方面也没有覆盖到(比如math和string库),但是它已经包含了我用Lua语言的要点。

Good

小:20000行源代码https://github.com/LuaDist/lua 在Linux下编译后就是182K左右的可执行解释器。

可适性:任何有ANSI C编译器的平台都可以编译。可以看到在http://www.eluaproject.net/ 以及Lego Minstorms NXT上 http://hempeldesigngroup.com/lego/pblua/ ,mobile平台https://github.com/divineprog/mobilelua 游戏主机 http://blog.brokenfunction.com/2011/11/how-to-make-a-massively-cross-platform-game/ 到浏览器中(翻译到Javascript)http://notebook.kulchenko.com/programming/drawing-on-browser-canvas-with-lua

容易嵌入和扩展:http://www.lua.org/pil/24.html 提供了简洁易用的接口与C/C++进行互通。

快:http://shootout.alioth.debian.org/ 相比其他编程语言性能非常不错,还有一个JIT编译器 http://luajit.org/performance.html 对某些任务下的性能有显著提升;如果这还不能满足某些人,可以使用C语言实现性能瓶颈部分,与C的集成很容易,还可以继续从其它有用的部分收益。

文档不错:语言手册 http://www.lua.org/manual/ ,书籍http://lua.org/pil/ 还有wiki http://lua-users.org/wiki/ 另外有http://www.capgo.com/Resources/SoftwareDev/LuaShortRef51.pdf

友好热心的社区 http://lua-users.org/ ,通过文档,wiki还有邮件列表http://www.lua.org/lua-l.html 和SO http://stackoverflow.com/questions/tagged/lua ,任何问题都可以解决。

干净和简单的参数适合初学者,对于非程序员也容易理解。Lua从Pascal的后继Modula http://en.wikipedia.org/wiki/Modula 借鉴了大部分控制语法,我仍然记得Philippe Kahn快速优雅的Turbo Pascal IDE http://en.wikipedia.org/wiki/Turbo_Pascal

集成解释器:只要命令行运行lua就行了

协程http://www.lua.org/pil/9.html 的内在支持,到实现iterators http://www.lua.org/pil/9.3.html 和非抢占性多线程 http://www.lua.org/pil/9.4.html

增量垃圾收集器http://www.lua.org/manual/5.1/manual.html#2.10 有很低的延迟,没有额外的内存开销,很少的实现复杂度,支持弱表http://www.lua.org/pil/17.html

强力的混杂式tables http://www.lua.org/pil/2.5.html 可以存储任意类型(除了nil),可以通过任何值索引(除了nil),比如 [1, 2, 5, foo = “bar”, [func] = “something”, [“some spaces”] = value()]

词法定界(Lexical scoping)

函数式编程http://www.lua.org/pil/6.html 通过一级(first class function)函数http://www.lua.org/pil/5.html 和闭包实现http://www.lua.org/pil/6.1.html

尾调用http://www.lua.org/pil/6.3.html : return functioncall()

递归函数不需要事先声明 local function foo() … foo() … end ,注意这样是不行的local foo = function() … foo() … end

函数可以返回多值。调用者可以要求任意数量的返回值,如果比实际返回数量少,剩余的被抛弃,如果要求的多于实际返回的,用nil填充。

函数允许可变函数参数个数 function foo(…) local args = {…}; bar(param, …) end

Tables可以解开成一个参数列表,通过unpack(或者Lua5.2的table.unpack)实现 print(unpack({1, 2, 3})) prints 1 2 3

可以操作环境变量(Lua5.1中的getfenv和setfenv,Lua5.2中的_ENV),这允许Lua建立沙箱机制 http://lua-users.org/wiki/SandBoxes

变量列表赋值local a, b, c = 1, 2, x, y = y, x, or a, b = foo()

使用[[…]] 做多行字符串,可以用[[…[=[…]=]…]]嵌套,注释如–[[…]]

分号作为语句分隔符是可选的

通过metatables重载 http://www.lua.org/manual/5.1/manual.html#2.8

元编程http://metalua.luaforge.net/ 可以做到获取、修改一个抽象语法树来建立新的DSL

for语句有两种方式,泛型式和数字式,数字型不光支持整数

函数调用(function call)语法糖 f’string’, f”string” f[[string]]和 f{table},以及方法调用(method call) obj:m()

简单但是很有用的调试库 http://www.lua.org/pil/23.html

 

不同之处

表和字符串索引从1开始,而不是0

在table中给一个元素赋值nil,就把这个元素删除了。

没有整型这个数据类型;number表现为浮点数

没有类,面向对象机制通过表和函数实现;继承通过元表机制实现 http://www.lua.org/manual/5.1/manual.html#2.8

方法调用通过object:method(args)实现,这和object.method(object, args)一样,but with object evaluated only once

nil和false是唯二的假值,0,0.0,”0″和其他的都是真。

~=不等符号

not, or, and关键字用做逻辑运算符

赋值是语句http://www.lua.org/pil/4.1.html,这意味着不能a=b=1或者 if (a=1) then … end

没有 a+=1 a++或者近似的方式

没有continue语句,尽管有一个解释 http://www.luafaq.org/#T1.26 和一些变体,像是repeat break until true在循环内部打断,或者Lua5.2中的goto语句

没有switch语句

括号在某些情况下有必要,for example, a = {}; a.field works, but {}.field doesn’t; the latter needs to be specified as ({}).field.

循环中控制变量默认本地化,loop外边就用不了了

数值型for中的限制和步进值是被缓存的http://www.lua.org/pil/4.3.4.html  in for i = init(), limit(), step() do ... end all three functions initlimit, andstep are called once before the loop is executed.

条件语句和其他控制结构不需要括号

字符串和数字自动转换,但是在等于和不等于比较中不能自动转换。 0 == "0" is false{} ~= 1 is true . foo[“0”]和foo[0]在表中指向不同的值; other relational operators generate errors on comparing values of different types.

逗号和分号可以用在table语法中;都可以放在最后的大括号前面作为可选操作符a = {a = 1, b = 2, }。

一些组件额外提供;一些人认为这是“没有电池”。这是紧凑和可适内核的结果,也可以通过Luarocks和Penlight解决 http://luarocks.org/ http://stevedonovan.github.com/Penlight/

萌萌的作文

祖国真美丽

         祖国真美丽啊!看,高高的大山,清清的小河,无边无际的大草原,金黄的田野,一棵棵参天大树,广阔的海洋,茂密的大森林,瞧,花丛中,小蝴蝶在飞舞,小蜜蜂在嗡嗡嗡的唱着美丽的歌。秋天,果子成熟了,农民伯伯看着果实饱满的苹果树,露出了满意的笑容。冬天,下大雪了,大地就盖上了一层厚厚的棉被。好好的睡一觉。。。。。。一觉醒来,大地掀开厚厚的棉被,开始新的生活。农民伯伯开始辛勤劳作等着秋天的好收成。夏天,梨花开了,苹果花也开了,小朋友们快乐的看着美丽的花朵,心里别提有多高兴了。奔腾万里的黄河,源远流长的万里长城。啊,我们的祖国多么美丽!

—————-

这是萌萌打算参加神马作文比赛的文章,虽然有些词语堆砌,而且我们觉得不如她自己平时写的日记有感觉,她还是坚持要写这个题目。

如何称量代码复杂度(C++/C#)

微博上的蛙蛙王子提出三个设想,发送给微博上一些知名程序员,惊悚的是,这三个问题我以前也考虑过还动手做过。这是巧合呢?还是巧合涅?

蛙蛙王子的问题是:是否有个工具可以检测出函数的长度?检测出函数中嵌套的层次?是否可以检测出重复代码?

基于我在罗克韦尔时写的一个Lua脚本经验来看,第一第二个问题非常容易。第三个问题稍有麻烦,有工具或者开源项目能做到,但是效果一般。

回到标题上的问题,称量代码复杂度,可以通过实现某个工具检测长度或者嵌套层次来完成,还有另外更简单的办法。

通常情况下,复杂代码所在文件大小也会比其他文件大出不少,所以不用编写什么工具,只要逐个察看项目中个头比较大的文件,就可以找到代码味道不好的地方了。

另外一个办法是通过版本控制工具,什么样的文件需要重构?基本上修改check in 次数多的文件,你要考虑重构了,即使代码味道不错,也肯定是责任过重,这个办法也很简单,把history导出统计一下就可以了。

如果通过判断函数长度和嵌套层次,建议大家可以这样实现,我考虑过C++的实现,算是比较完整,不需要什么编译原理知识。

函数长度和嵌套层次可以这样判断。前提1,我们可以确定C++中的{}成对出现;前提2,class可以通过关键字定位,而struct可以假定其中没有函数体,不需要判断;前提3,函数中的{}也一定是成对出现。至于其他的复杂问题,我觉得没必要考虑太多,除非你想做一个商用级别的软件,否则一个Python脚本就能搞定。

基于这些前提我们可以这样实现,先清理注释部分,C++注释分成// /*,另外对于/*要考虑单行和多行,基本上就是按行处理就行了。之所以这样,是为了防止注释部分包含{}或者特定关键字。

如果能找到class,判断类名,然后查找{。对于{}匹配,可以定义一个树形结构,函数或者类作为根,发现一个{,加入一层嵌套,发现一个},减去一层嵌套。如果嵌套层次为零(不在class定义体中),或者为一(在class定义体中,假定class的{}级别为0),那就是函数,稍微处理一下(),就能拿到参数,然后前面就是函数名字了。

这样按照文件处理逐个处理完,就能判断出那些函数,函数体多长,嵌套层次如何了。

针对C#,也可以这样处理,但是我猜测如果用Roslyn有更好的办法,可是没找到例子。

————-

另外一个问题是重复代码。有一些链接,比如 http://en.wikipedia.org/wiki/Duplicate_code http://pmd.sourceforge.net/cpd.html http://checkstyle.sourceforge.net/config_duplicates.html http://patterninsight.com/products/clone-detection/ http://stackoverflow.com/questions/546487/tools-to-identify-code-duplications

但是我感觉最好用的办法,是通过peer code review来检查,因为这一块对于算法而言,应该是实现难度挺大的,而且结果也不理想,review的方式基本上可以杜绝类似问题。我们之所以不用review方式解决代码长度和嵌套层次,是因为的确有办法实现。

 

MFC在VisualC++中依然活的好好的

http://blogs.msdn.com/b/vcblog/archive/2012/03/05/10278210.aspx

Pat在这篇文章中介绍了VS11里面的Visual C++部分对MFC的修改,包括bug fix, 静态链接文件大小。

最值得一提的是MFC对Metro Style的支持。

总有人不做研究便大放厥词:MFC老旧了,已经过时了,已经死了,不要学了。结果,拿出来比的QT不醒醒了,设计优秀的Borland葛屁了,只有MFC依然好好的活着,照现在的势头,这笔财富还能用上五年十年的依然没有问题。

所以说,设计好不好,优雅不优雅,这都不是问题,只要能活的比较持久,那就是成功。我一直建议Windows平台的C++程序员学MFC,对于争议,哥是一笑而过啊,不争论用事实说话。

如何成为靠谱的DotNet/C#程序员

1 确定目标

微软系开发涉及面太广,所以你得先确定自己在哪方面有所专长。除了基础知识扎实以外,在asp.net / siliverlight / WPF 必须有一定的侧重。这个侧重点选择可以是自身兴趣,但大多数是项目需要。

2 选择教材

我还是倾向推荐纸质书,这里简单列几本。

C#本质论 http://www.amazon.cn/gp/product/B003ZXBKQC 这本书可以在一开始阅读,保证对C#基础有个全面掌握

CLR via C# http://www.amazon.cn/CLR-via-C-%E7%91%9E%E5%A5%87%E7%89%B9/dp/B00426BTTY/ 这本书建议买,但是高级阅读

深入理解C# 这本书如果看目录觉得感兴趣,可以买,但是不推荐初学者阅读。

另外专门技术方面,可以根据销量和评价买一本,不推荐在开始学习阶段购买。建议可以先通过文档/视频/代码实例学习一阵以后,对技术有一定了解了,然后再选择购买。

3 视频入门

这里推荐微软中国的webcast http://msdnwebcast.net 全中文视频,精品不少,比如老赵就有很多贡献。建议看视频学代码。

如果你英文很好,可以到channal9上看英文视频,也有成系列的。

4 文档中心

对于前面提到的几种技术,微软都有不同的网站专门介绍。

http://www.asp.net/ asp.net和asp.net mvc的老家,下载,文档,视频学习。

http://www.silverlight.net/ 银光的老家,下载,文档,视频学习。

http://windowsclient.net/  wpf的老家,下载,文档,视频学习。

另一个网站必须经常看的是 http://msdn.microsoft.com/en-us/default.aspx 比如这个 http://msdn.microsoft.com/en-us/vstudio/hh388566.aspx 就是Visual C#开发中心

http://msdn.microsoft.com/en-us/library/ff361664%28VS.110%29.aspx 这里是DotNet开发链接页面,可以作为homepage

www.codeplex.com 这是微软开源中心,推荐下载http://1code.codeplex.com/ all-in-one samples学习。

http://www.codeproject.com/ 这里面的文档和代码实例大多数目的单纯,简单扼要,学习起来很方便。

5 提高

http://msdn.microsoft.com/en-US/practices Enterprise Library, prism4.1, MVVM, 这些模式被广泛使用

MSDN要经常翻,里面好东西太多了。

http://msdn.microsoft.com/en-us/magazine/default.aspx MSDN magazine也要经常看。

就这些。

R语言,高估自己的架构师和一些技术链接

part1

先说说创新,对金融类软件开发而言,个人觉得“Big Data”会是一个很大的发展方向,就如同这篇麦肯锡的文字所提到的 http://www.mckinseyquarterly.com/Strategy/Innovation/Are_you_ready_for_the_era_of_big_data_2864  http://blog.nodeable.com/2012/02/21/mckinsey-misses-the-market-on-big-data/

问题是我对统计方面的数学学的很不好,即使有R语言这样的统计数据分析的专门编程语言,仍然感觉到困惑。R语言资源不少 http://ftp.ctex.org/mirrors/CRAN/other-docs.html 也期望自己多学一些,但是精力真的有限,最近要看WPF,C# in depth2, 还想看看Python3, Lua5.2文档,还有Ruby语言和类似lisp的Clojure。这么多好玩的东西,稍微懒一懒就混过去了。回到R语言,国内比较大的讨论组是这个“统计之都“ http://cos.name/cn/forum/15

每年学一门编程语言,到底该选Clojure还是R呢? 

part2

Architect – Overrated! http://www.subbu.org/blog/2012/02/architect-overrated You always talk about the big picture. You think you know how the system ought to be built. You don’t have a working build. You spend a lot of time on documents that are not code. You can prototype – but your code is not production worthy. You spend too much time in meetings. The best code you wrote is a few years old. When asked for opinions you tend to speak in general terms. Your team members secretly joke about you. You start to take analysts and tech blogs too seriously. You are a dinosaur. Code. Don’t wiki. Don’t powerpoint.

顺便问一下,你是这样的架构师么??

part3

http://casbon.me/what-will-pypy-do-for-your-website-benchmarki 一个关于PyPy和CPython的比较测试,PyPy最近很火,就目前发展,很快就能应用到实际生产项目了。

http://msdnwebcast.net/ 面试的时候,很多人抱怨自己项目中只用了这个或者那个,所以不会这个或那个。好吧,只要你懂点DotNet编程,有恒心坚持,天天学一个这里面的webcast,你就能变成高手。另一个选择是 http://learndotnetprogramming.com/free-dot-net-videos-webcasts/

http://blog.phusion.nl/2012/02/21/ruby-enterprise-edition-1-8-7-2012-02-released-end-of-life-imminent/ “We wish to focus our efforts on Phusion Passenger and other products. Instead of doing many things poorly, we want to do a few things, but do them very very well.” 深有同感。

http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c 一个简单的语言编译器,在K&R中也有个简单版本,每个程序员都应该多少了解一下相关的概念。

http://www.bestechvideos.com/2012/02/21/railscasts-265-rails-3-1-overview Railscasts #265: Rails 3.1 Overview

http://www.bestechvideos.com/2012/02/21/railscasts-265-rails-3-1-overview Railscasts #265: Rails 3.1 Overview

http://www.bestechvideos.com/2012/02/21/railscasts-267-coffeescript-basics Railscasts #267: CoffeeScript Basics