Code

2011年10月25日星期二

JavaScript Closure

因为新工作的缘故这两天开始学习JavaScript。
一直在看David Flanagan的JavaScript: The Definitive Guide 6th Edition,收获颇丰。

以前在云风的博客上第一次看到closure这个词的时候就很好奇,但那篇介绍是以C作为例子,讲的也不是很清楚,所以一直都没搞懂closure这个东西。
现在读JavaScript,对这个closure算是有一定理解。
Closure 中文叫做闭包,在JavaScript里函数都是有闭包的特性。

理解闭包必须分两步:
1.JS里面函数是first-class function,就是说函数跟class是一个级别的。 函数可以直接赋值到变量上,它的类型为"function",这个变量可以直接用来invoke函数。
function test1() {
    console.log(1);
}
func_var = test1;
console.log(typeof func_var); //"function"
func_var(); // invoked test1 -> '1'

2.JS使用lexical scoping,也就是一个函数的scope在它define的时候就确定了,而不是在invoke的时候才确定。

function test2() {
    var b = 1;
    return function () {console.log(++b);};
} 
b = 10;  //无影响
test2()(); //2
test2()(); //2
func_var = test2();
func_var(); //2
func_var(); //3
func_var(); //4

可以观察到,如果直接从运行从test2那里得到的函数,得到的结果会一直都是2。因为,每次运行test2,一个新的context被建立,一个新的b在这个context里面被建立。每次返回的匿名函数被挂接在一个新的context里面,所以它使用的b的值一直都是1。
然而,将test2返回的函数赋值到func_var上的时候,被返回的匿名函数原本的context被保存,就像把这个context空间封闭住了,只有,这个匿名函数可以访问。所以每次这个func_var被运行的时候都会只用之前旧的b,它相当于这个函数的私有变量了。
这种closure使var b成为test2这个object的私有变量,把data hide起来,不受其他scope的影响。可以猜想,JS使用这种特性可以实现object-oriented programming。

PS: from SICP about first-class procedures
In general, programming languages impose restrictions on the ways in which computational elements can be manipulated. Elements with the fewest restrictions are said to have first-class status. Some of the ``rights and privileges'' of first-class elements are:
  • They may be named by variables.
  • They may be passed as arguments to procedures.
  • They may be returned as the results of procedures.
  • They may be included in data structures.
Lisp, unlike other common programming languages, awards procedures full first-class status. This poses challenges for efficient implementation, but the resulting gain in expressive power is enormous.

Javascript is like Lisp very much in this aspect.

2011年10月24日星期一

15%高税换工作

我今天差点暴怒了。
前雇主发给我邮件,告诉我月底需要到他们那交300新币的个人所得税。
可是我是期望等月底结算这个月7天的工资拿个~800走人的啊。
回复邮件时,所有粗鲁的话都冒出来了。当时觉得,这家小公司真的是cheepo到家了。
当然,我还是冷静的问了下原因。

原来是这样的,在 Inland Revenue Authority of Singapore的网站上有写,像我这种拿外国护照,工作不到182天的人叫做non-resident employee。我离职的时候,公司需要向IRAS申报税务审查( tax clearance) 同时要扣留我这个月的工资。然后审查结果会得到一个税款。从扣留的工资里面扣除这个税款之后,就多退少补。
作为non-resident empolyee,个人所得税的税率是高达15%。一般工作超过183天的resident emplyee只用付2%的税。所以,如果工作不满半年换工作在缴税这个问题上是相当吃亏的。可能新加坡就是用这种政策来防止频繁换工作吧。

IRAS给我的信件里就显示我需要交1100的税,扣除我7天工资,就要倒贴300。
唉,这可是明文规定了,可是前雇主在我辞职的时候也不告诉我这个条款也应该负一定责任。

Anyway, 换工作的事情告一段落了,如果这个礼拜EP下来,在11月之前我就可以到新公司报到上班了。

PS: 上交个人所得税是个人的义务,所以不要总是assume公司有帮你办,可以放心。有时候政策的变化,和一些你不知道的条款的加入会影响到最后的税款。所以定时的检查每月扣除的税款,和公积金是有必要的。这样你可以知道一些政策的变动,并作出相应的决策。

PS: 跟税务局说明我在新加坡读书好多年之后,他们觉得我应该算作是resident employee,然后归还我了1100块钱。这归还的钱显然是没有扣除resident employee的税钱,将近200块。难道我赚了,呵呵。新加坡税务局是相当的廉洁,开明和有同情心啊。

2011年10月14日星期五

Code Complete 2nd Edition

Computer science has some of the most colorful language of any field. In what other field can you walk into a sterile room, carefully controlled at 68°F, and find viruses, Trojan horses, worms, bugs, bombs, crashes, flames, twisted sex changers, and fatal errors?
One of the main differences between programs you develop in school and those you develop as a professional is that the design problems solved by school programs are rarely, if ever, wicked. Programming assignments in school are devised to move you in a beeline from beginning to end. You'd probably want to tar and feather a teacher who gave you a programming assignment, then changed the assignment as soon as you finished the design, and then changed it again just as you were about to turn in the completed program. But that very process is an everyday reality in professional programming.