我的Google Reader分享

Wednesday, December 31, 2008

The World is Black

  2008年的最后一天,我也免不了俗来更新一篇日志,作为年终总结。
  2008年,对世界而言,对中国人而言不得不说是难忘的一年,对我而言,只是感觉到了这种难忘,另外我只是在和以前一样在某种不可救药的个人世界中挣扎而已。“要跳要舞”,还是我在这个世界立足的信条。当然,偶尔还是会有“无论如何都没有意思的”的想法,但很快就能被打消掉,要跳要舞。世界是黑色的,只有变的强大才能得到我要的自由。
  2008年,找到了我的道路,也受到了内心的折磨,终归我还是自私到底的人——大多时候自我感觉良好,但偶尔会想到自己的恶心之处,并对自己厌恶不已。比如现在,我看着自己感觉想吐。
  2008年,在我的道路上前进了很多,但我已经不能再用年作为单位来作为进步程度的分母了,我的青春已经所剩不多。高中,以至于大一,大二时候,我还觉得我什么都没有,唯一拥有的就是有大把的时间,但现在我已经什么都没有,当然也包括“大把的时间”。我觉得我的“大把的时间”没有了有两个原因:一是要学习的东西太多,我对技术还有持续的热情,我对小说还是很大的热情,我对中国传统文化还有很大的兴趣;二是游戏,有人说玩游戏是浪费时间,不过说到底,这是我的人生,我要做我喜欢做的事,当然包括游戏。又要学习,又要玩游戏,又要工作,新的一年会更忙。
  2008年,在技术上,从Linux初学者到达中级阶段,对很多计算机的知识运用的更加自然,熟练。在小说上,大概没有看完一本。其他也没有什么进展。进步太小。
  明天开始,2009年开始,对于不用年作为进步程度的分母的我来说,那只能算是普通的一天。2009要完成的事情:
  1. 图书分享交换网站,(1月内最好,最多到2月底)
  2. 多看书,每天看小说或者史书,保证2个小时,至少每个月看完一本吧,(难度较大,我要玩游戏)
  3. 写一本小说,(难度较大,但不是没有可能)
  4. 找一个女朋友,(这个就是随便写写的,我已经对很多东西绝望了,包括爱情,我这么说指是指我自己,我还是相信别人的爱情的。)
  5. 静下心来,
  6. 在技术上更加进步,Linux C, RoR;
  7. 创业?(看机遇与进步的程度吧)
  1,2,3,5,6还是比较靠谱的东西,至于4,7那就看运气吧。



  

Monday, November 03, 2008

Programming Erlang 笔记(四)

Building Lists in Natural Order

The most efficient way to build a list is to add the elements to the head of an existing list────构建一个列表的最有效率的方法是在一个把元素加到一个已有的列表头上(head)。

常见的代码:

some_function([H|T], ..., Result, ...) ->
H1 = ... H ...,
some_function(T, ..., [H1|Result], ...);
some_function([], ..., Result, ...) ->
{..., Result, ...}.


This code walks down a list extracting the head of the list H and computing some value based on this function (we can call this H1); it then adds H1 to the output list Result.────这段代码不断的取出列表H的头(head),然后根据H1这个函数计算它的值;再把它加到输出列表Result的头上。

The basic idea is fairly simple:
1. Always add elements to a list head.
2. Taking the elements from the head of an InputList and adding them head first to an OutputList results in the OutputList having the reverse order of the InputList.
3. If the order matters, then call lists:reverse/1, which is highly optimized.
4. Avoid going against these recommendations.

最基本的思想相当简单:
1.总是把元素加到列表的头上;
2.从输入列表的头上取元素,把元素加到输出列表的头上,这样输出列表中元素顺序和输入列表正好相反;
3.如果顺序对你有影响,调用list:reverse/1,它是高度优化过的;
4.避免违反这几条。

If you ever see code like this:
List ++ [H]
it should set alarm bells off in your brain—this is very inefficient and acceptable only if List is very short.

如果你看到这样的代码
List ++ [H]
你的脑子应该敲响警钟了────这是非常没有效率的而且只能在列表很短的时候才能接受。


Accumulators (我不明白为什么叫这个名字,蓄电池?)

odds_and_evens(L) ->
Odds = [X || X <- L, (X rem 2) =:= 1],
Evens = [X || X <- L, (X rem 2) =:= 0],
{Odds, Evens}.
5> lib_misc:odds_and_evens([1,2,3,4,5,6]).
{[1,3,5],[2,4,6]}


这个要两次遍历

odds_and_evens_acc(L) ->
odds_and_evens_acc(L, [], []).
odds_and_evens_acc([H|T], Odds, Evens) ->
case (H rem 2) of
1 -> odds_and_evens_acc(T, [H|Odds], Evens);
0 -> odds_and_evens_acc(T, Odds, [H|Evens])
end;
odds_and_evens_acc([], Odds, Evens) ->
{Odds, Evens}.


这个只要一次遍历

Wednesday, October 22, 2008

支付宝的霸王面以及之后

  16号去杭电参加支付宝的宣讲会并参加笔试。笔试很郁闷,我本来是要应聘系统工程师的,谁想到系统工程师和Java工程师,UED竟然考的是同一张试卷。考的全是Java和前端的东西,一点都没有考关于操作系统,Linux的东西,很是郁闷。考完后自己感觉还行,觉得自己是应聘系统工程师,前面必答题做的可以考官应该会给机会。
  支付宝是笔试完了以后马上改卷,然后当晚24点以后通知是否有面试机会。因此那天晚上我到1点才睡,然后中途又醒了几次,一直把手机放在脑袋边。不过,遗憾的是,到第二天早上醒来的时候还是没有看到短信的通知。说实话,挺郁闷的。郁闷的继续睡觉。
  大概10点多起来看到Twitter上的Fenng(支付宝大牛,负责系统工程师的面试)讲他那边还没有人去面(这个Tweet发布于1个小时前),我就不要脸的问了他:面试太差。。。连面试通知都没收到。。。话说为什么系统工程师考的全是Java和前端的东西?Fenng大概因为没人去他那边无聊了,回复我:如果觉得自己对操作系统有信心,下午就带简历来一下吧。
  虽然我没什么信心,我还是去了。。。
  我进去面的时候,Fenng貌似就已经知道我就是Twitter上那个人了,看来面系统工程师的人还真是够少。我问:我这也算是霸王面了吧。。。Fenng答:其实也不算,你不是说考的全是Java的么。问:找出/foo下大于1m的文件。答:du -s /foo/* | sort -nr,几天后才醒悟应该用find来找。大概问了一些基础知识,看了下简历,觉得我学习能力还行,其他的就都马马虎虎了。中途问我应该不应该给我二面的机会,我说应该。。。(脸皮厚的。。)。还真给了我二面。。。
  二面是个胖胖的蛮面善的大叔。问了一些奇怪的问题:做过的最冒险的事情是什么啦,杭州市有多少个应井盖啊什么的。还和我聊了英雄无敌V。。。大概他学生时代玩过那游戏,不过想必他也没玩过V。。然后最后说:等会还有几个问题要问,叫我外面等会。。。
  等了快一个小时,见到一个HRMM,聊的还蛮开心的,最后叫我2周内手机24小时开机等消息。然后四天已经过去。
  真的是很想进支付宝,觉得有机会在一个成长中的公司工作肯定能学到很多东西,另外就是懒人心理了────找到了就不用再找了。。。总之,等吧。。。说2个星期,我就等2个星期吧。
  等的有点郁闷,特发此文,以资鼓励!

Sunday, October 12, 2008

Shell编程笔记(二)

if/else

退出状态和返回

0通常为无错退出状态,而其他(1-255)通常表示错误(diff例外,此命令对“没有差别”返回0,“找到差别“返回1,或是对无效文件名参数错误返回2)

if command运行成功
then
正常处理
else
错误处理
fi

返回:return

组合退出状态:(注意得到操作结果后,有的命令就不会执行了)
if command1 && command2
then
....
fi

if command1 || command2
then
....
fi


条件测试([...],"["符号后,"]"符号前的空格是必须的。

字符串比较:
str1 = str2 str1匹配str2 (不同于C等高级语言,是一个”=“,而不是两个)
str2 != str2 str1不匹配str2
str1 <> str2 str1大于str2
-n str1 str1为非null(长度大于0)
-z str1 str1为null(长度为0)

Saturday, October 11, 2008

Shell编程笔记

字符串操作符语法:

替换操作符(:)
${varname:-word}, if count is not defined, ${count:-0} is 0
${varname:=word}, if count is not defined, ${count:=0} define count 0
${varname:?message}, if varnaem is defined, return varname, else print message
${varname:+word}, if varname is defined, return word, else return null

模式与模式匹配:

模式匹配操作符(#,##,%,%%)
${variable#pattern}, 取值的开头,删除最短匹配
${variable##pattern}, 取值的开头,删除最长匹配
${variable%pattern}, 取值的结尾,删除最短匹配
${variable%%pattern}, 取值的结尾,删除最长匹配

命令替换:

$(Unix command)

Friday, September 26, 2008

网易笔试后

  上午去参加网易笔试,老早起来跑去浙大玉泉校区。今天还刚好冷空气来了,我穿个短袖差点没冻死我。到了那里刚好9点,看到考场门口堆着一群人还以为没开始,但又看到里面有人坐着了。我死不拉鸡的又在外面逛了一会,然后挤进去看了看,马上工作人员就问我座位号了。原来外面那一群是没有收到通知但还是来了的,我晕倒。。。
  我一开始还以为考的不是全是关于技术的东西,昨天P都没复习。第一部分必答题,考的数据结构和算法,我这方面一向垃圾。其余都是选做题,C++的部分没做,JAVA部分,关于线程的全空,Linux部分,命令参数我实在记不住。。GDB调试不会。数据库没做,SQL写不来。。理论也不懂,数据库原理等于白学了。Web开发,开始扯蛋,扯了一点,JS不会,CSS不会,Flash更不用说了。最后是测试,我就没写过测试代码。
  总而言之,就是没戏了。下次去应聘支付宝的系统工程师,得把Linux命令参数记一下,然后Shell再复习下。就嘎。

Friday, August 29, 2008

ipod充电图标Tip和关于Bash的以前一知半解的东西


  这段时间ipod nano听的很少,主要是歌都没换,听的都腻了。今天用来拷Arch的盘的时候拿出来用了一下,然后突然发现以前充电时的绿色的充电图标不见了,怎么弄也出不来。然后开始Google,人家说弹出ipod然后睡眠后就会显示这个图标。我这么干就直接睡过去了,ipod就关了。我一开始还以为是上次ipod从高空坠落给摔坏了,后来关掉Linux,进XP,开起ITunes发现睡眠状态下可以显示这个鸟图标。Apple对Linux一直不友好啊。

  最近不是新装了Arch嘛,然后发现自己Linux知识的不扎实开始显现了。设置Fcitx输入法的时候总是不能激活.具体设置参照的是Arch的Wiki(http://wiki.archlinux.org/index.php/Fcitx中文输入法)。最后检查locale也OK,.bashrc也写对了,但Fcitx就是不能激活。郁闷了半天,后来发现我的.bashrc里有一个alias: alias ls='ls --color=auto'。但是这个也没有起作用,才开始怀疑是.bashrc没有被source,然后发现用户目录下面没有.bash_profile,我在/etc/skel/中拷贝了一份过来,顺便cat了一下内容:[winfield@myhost ~]$ cat .bash_profile
. $HOME/.bashrc
原来在这里source了~/.bashrc了,reboot后搞定。知道问题所在之后觉得有必要了解下Bash是怎么加载这几个配置文件了。man bash吧。然后看manpage的INVOCATION。
  • A login shell is one whose first character of argument zero is a -, or one started with the --login option.
    所谓的login shell我一开始没有明白,后来这么干了一下:
    [winfield@myhost ~]$ bash
    [winfield@myhost ~]$ ps aux | grep bash
    winfield 2966 0.0 0.1 6324 1820 tty2 S+ 14:56 0:00 -bash
    winfield 4281 0.0 0.1 6324 1824 tty1 S 16:57 0:00 -bash
    winfield 4492 0.0 0.1 6324 1836 pts/0 Ss 19:14 0:00 -bash
    winfield 4516 0.7 0.1 6324 1796 pts/0 S 20:53 0:00 bash
    winfield 4518 0.0 0.0 4072 816 pts/0 R+ 20:53 0:00 grep bash
    前面有“-”的就是指Login shell了。像tty这些。另外关于Login Shell的可以参考这个,http://learnlinux.tsf.org.za/courses/build/shell-scripting/ch02s02.html(IP是南非,大概是南非的某个大学?感叹一下)
  • When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile
    如果是Login Shell,读取文件的顺序是/etc/profile,~/.bash_profile,~/.bash_login,然后是~/.profile,注意没有~/.bashrc,这也是为什么我出现问题的原因。
  • When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc.
    如果不是Login Shell,bash会读~/.bashrc。

  

Wednesday, August 20, 2008

硬盘安装Arch Linux(2008.06)


  玩Linux也有很久了,一开始用的就是Ubuntu,它的确适合新手。不过时间长了,倒觉得用Ubuntu进步越来越小,或许换个风格不一样的发行版能学到些新的东西。最近在看《LPI Linux认证》这本书,倒不是想去考这个,只是想再巩固下自己的Linux基本功。于是决定装个Arch看看。
  因为我总是懒的刻录盘来装(其实我手边也没有盘),所以一般都是硬盘安装。虽然我这个台式机上已经装了Ubuntu,但我还是在XP里设置Grub4Dos来引导的。
  • 下载个Grub4Dos,把grldr复制到C盘,修改boot.ini,在此文件末尾加一行C:\grldr="arch";复制2008.03光盘中的initrd.img和vmlinuz到C盘(我在网上搜索听说2008.06的这两个镜像文件硬盘安装时不成功所以用了2008.03的)
  • 新建个menu.lst,
    • title Fuck Install Arch Linux
    • root (hd0,0) #假设你的C盘是在第一个分区
    • kernel /vmlinuz ro
    • initrd /initrd.img
  • 重启,进入临时文件系统
    • mount /dev/sda1 /mnt
      挂载C盘到/mnt(当然也可以是其他地方。。)
    • mount -t iso9660 -o loop /mnt/archlinux-2008.06-core-i686.iso /media/dvd/
      挂载ISO到/media/dvd
    • mkdir /src/core
      Arch安装程序貌似会在这个目录下找包,因为是硬盘安装,所以要手动先挂载ISO,然后建立一个目录,再在这个目录中建一个链接到ISO中的包
    • ln -s /media/dvd/core/pkg /src/core/pkg
  • 开始安装,cd arch & ./setup

Wednesday, August 06, 2008

Programming Erlang 笔记(三)

Sequential Programming---Again..

Guards
  • A guard is a series of guard expressions, separated by commas (,).──── 一个Guard是一系列由(,)分隔的Guard表达式
  • A guard sequence is either a single guard or a series of guards, separated by semicolons (;).──── 一个Guard序列可是是一个单一的Guard,也可以是一系列用(;)分隔的的Guard
  • Guard Examples
    1. f(X,Y) when is_integer(X), X > Y, Y <> ...──── The comma, which separates the test in the guard, means “and.”
    2. is_tuple(T), size(T) =:= 6, abs(element(3, T)) > 5
      element(4, X) =:= hd(L)
    3. X =:= dog; X =:= cat
      is_integer(X), X > Y ; abs(Y) <>Y或者Y的绝对值小于23。Guard Sequence用于表示“或”,而(,)来表示“且”
    4. The guard sequence G1; G2; ...; Gn is true if at least The guard sequence G1; G2; ...; Gn is true if at least one of the guards—G1, G2, ...—evaluates to true. one of the guards—G1, G2, ...—evaluates to true.


Records
  • record is not a shell command.record definitions can be included in Erlang source code files or put in files with the extension .hrl──── record不是一个Shell命令;record定义可以被包含在Erlang源代码中或者放在一个扩展名为“.hrl”的文件中
  • Records are declared with the following syntax:
    -record(Name, {
    %% the next two keys have default values
    key1 = Default1,
    key2 = Default2,
    ...
    %% The next line is equivalent to
    %% key3 = undefined
    key3,
    ...
    }).
    Name is the name of the record. key1, key2, and so on, are the names of the fields in the record; these must always be atoms.────上面的定义中,Name是record的名字,key1, key2....是记录中条目的名字,他们必须是atom
  • -record(todo, {status=reminder,who=joe,text}).
    Once a record has been defined, instances of the record can be created.──── 一旦一个record被定义了,就可以创建这个record的实例
    1> rr("records.hrl").
    [todo]
    2> X=#todo{}.
    #todo{status = reminder,who = joe,text = undefined}
    3> X1 = #todo{status=urgent, text="Fix errata in book"}.
    #todo{status = urgent,who = joe,text = "Fix errata in book"}
    4> X2 = X1#todo{status=done}.
    #todo{status = done,who = joe,text = "Fix errata in book"}
  • Extracting the Fields of a Record────从Record中提取元素
    5> #todo{who=W, text=Txt} = X2.
    #todo{status = done,who = joe,text = "Fix errata in book"}
    6> W.
    joe
    7> Txt.
    "Fix errata in book"
    8> X2#todo.text.
    "Fix errata in book"
  • Records Are Tuples in Disguise────record其实是伪装了的Tuple
    9> X2.
    #todo{status = done,who = joe,text = "Fix errata in book"}
    10> rf(todo).
    ok
    11> X2.
    {todo,done,joe,"Fix errata in book"}
    Records are just tuples.Internally there are only tuples.────Record就是Tuple;从内部来讲,Erlang中只能Tuple




case and if Expressions
  • case Expressions
    case has the following syntax:
    case Expression of
    Pattern1 [when Guard1] -> Expr_seq1;
    Pattern2 [when Guard2] -> Expr_seq2;
    ...
    end
  • if Expressions
    if
    Guard1 ->
    Expr_seq1;
    Guard2 ->
    Expr_seq2;
    ...
    end
    Often the final guard in an if expression is the atom true, which guarantees that the last form in the expression will be evaluated if all other guards have failed.────
    "if"表达式的最后一个guard常常是atom "true",它保证了如果前面的guard全部没有匹配的,最后一个肯定会被计算


Building Lists in Natural Order
  • The most efficient way to build a list is to add the elements to the head of an existing list
    The basic idea is fairly simple:
    1. Always add elements to a list head.
    2. Taking the elements from the head of an InputList and adding
    them head first to an OutputList results in the OutputList having
    the reverse order of the InputList.
    3. If the order matters, then call lists:reverse/1, which is highly opti-
    mized.
    4. Avoid going against these recommendations.
    If you ever see code like this:
    List ++ [H]
    it should set alarm bells off in your brain—this is very inefficient and acceptable only if List is very short.

Wednesday, July 30, 2008

KDE4.1初体验


  今天KDE4.1终于如期发布,我也迫不及待的下来用了,惊喜之处还是蛮多的,当然问题也存在不少。不过很多不是KDE4.1本身的问题,而是原先应用程序兼容性还有显卡驱动的问题。相信随着时间的推移,这些问题都会被解决的。先来看个截图吧:)
  这个是我现在的桌面,很爽,啊哈哈。不过KWin的效果还是比不上Compiz,另外N卡对于KWin的支持我感觉也不是太好,所以我索性把特效给关了(我就是不喜欢在KDE中用Compiz)。
  用上KDE4.1后的一个感觉就是屏幕还是不够大,不够宽。真是越大越好,能放更多的Widget。另外正好想学QT4,以后就能自己写Widget了,真TMD爽呐。
  当然我还有很多小问题没有解决,比如Phonon还不大清楚,现在声音都有点问题,要找点文档来看下。我是喜新厌旧啦,暂时和我的Mac-like Gnome Say Goodbye了。

Tuesday, July 29, 2008

Erlang中的快排,近段时间的总结

  最近两个星期在看Erlang,蛮有新鲜感的一种语言。由于看的英文版,看的比较慢,也看的比较仔细的,简直可以算是一字不漏的看了。前几天刚看到List Comprehensions,由它实现的一个qsort,我觉得在某种程序上也算是能体现Erlang的特点了。


qsort([]) -> [];
qsort([Pivot|T]) ->
qsort([X || X <- T, X < Pivot])
++ [Pivot] ++
qsort([X || X <- T, X >= Pivot]).



  Erlang似乎常常用到类似于这种的递归。说实话,我数据结构和算法学的是不怎么样,对于快排,我其实也是一知半解。不过Erlang这种形式,我倒是一看就明白了。现在要我用C来实现下快排应该没什么问题了。

  今天忽然想到,3月到现在,我到底学了点什么。想了半天,我是越想越心虚,感觉自己好像什么都没有学到。所以我决定写一个日志来仔细的想想自己有哪些进步,来填补下我的心虚。
  3月到4月,我看来只能心虚了,我完全不记得我到底是在干嘛了。看了一点操作系统和Linux Kernel的东西,无心的看了下Android的NotePad的代码,Ruby Quiz没有进行下去。其他时间我甚至不知道用在哪了。
  4月到5月,我记得我的笔记本上双系统的时候应该是在这段时间,Ubuntu8.04记得好像是4月底正式发布的,而我是从Beta3开始用的,想来应该是在4月初或者3月底吧。这个月大概(只能说大概)接触了REST,听说REST是在一年前Robbin在“侠客行”上的演讲,虽然我最后没有去听,但是印在入场券上我看到了。然后一年后我不知怎么的,开始找REST的资料了。而这时候Rails已经是2.0了,其默认创建的项目就是基于REST的,这对我上手倒是帮了很大的忙。然后这个月干的事情应该就是再次熟悉Linux的各个方面吧。
  5月到6月,开始了一个自己的项目。有感于学校教材的昂贵和大四那帮人走人时对没用的书的处理方式(竟然按斤卖了。。。。),决定做一个系统,利用学校内部网络,让大家把没用的书分享出来。然后大概做了20多天吧,具体时间我无聊时上Github看看就知道,因为我每天都有Push上去。这个系统应该是5月下旬开始的,那上,中旬我在干嘛呢。。。想不出来。。。
  6月到7月,6月上,中旬我是在做我的那个项目,因为时间离的近,所以我段时间的存在感还比较实在,没有很大心虚的感觉。。。然后下旬开始应付考试了,换句话说,开始放荡了。一考试,我就特想玩游戏。。。。记不清了,好像又玩的三国志11和英雄无敌吧。三国志11我就是流氓,用流言流死人。。。英雄无敌我就是卡死人了,我的电脑啊。。。。。
  7月到现在(其实也就是到8月了,还剩两天,我还能干出舍惊天到地的?),前面半个月还是考试+课程设计。课程设计用我的那个Alpha都算不上的项目就过关了,而且我自信比其他人做的应该要好,因为我可是花了时间的了,不比他们好也太没面子了。。。然后到现在,在做一个基于ArcGIS的项目。晚上在看Programming Erlang和RESTful Web Service这两本书,玩DS上的口袋妖怪和EVE ONLINE。
  对了,提一提EVE ONLINE,从去年暑假开始玩的一个网游。其实两年前就玩过,后来因为觉得卡贵没玩,去年8月1号决心玩了。然后半年时间浪费了,今年以来,改过自新变成蹲站党。最近每天玩上4个小时左右,但因为昨天网卡(学校的上网包月卡,70RMB/月)到期,将会再次成为蹲站党。。。。这应该算是个好消息。。。。。
  虽然进步很慢,但是进步还是有的,正所谓欲速则不达,就这样吧。在就这样的基础上再提高下自己利用时间的效率就好了。

Monday, July 28, 2008

Programming Erlang 笔记(二)

Sequential Programming

Modules(模块)
  • Modules are the basic unit of code in Erlang.────模块是Erlang中基本的代码单元。
  • -module(geometry).
    -export([area/1]).
    area({rectangle, Width, Ht}) -> Width * Ht;
    area({circle, R}) -> 3.14159 * R * R.
    (这就是一个模块,geometry.erl)
  • 上面的例子中,函数area由两个子句组成,子句用分号隔开,最后用点号结束。
  • Each clause has a head and a body; the head consists of a function name followed by a pattern (in parentheses), and the body consists of a sequence of expressions, which are evaluated if the pattern in the head is successfully matched against the calling arguments. The patterns are matched in the order they appear in the function definition.────每个子句有一个头和身体;头由函数名跟着一个模式(在括号中)组成,身段由一序列的表达式组成,当头中的模式和调用的参数相匹配时,表达式就会被计算。模式按在函数中被定义的顺序进行匹配。
  • compile and run it:
    1> c(geometry).
    {ok,geometry}
    2> geometry:area({rectangle, 10, 5}).
    50
    3> geometry:area({circle, 1.4}).
    6.15752
  • the order of the clauses doesn’t matter, if the patterns in the clause are mutually exclusive.In general, though, clause order does matter.────如果子句中的模式是互斥的,那么子句就顺序就无所谓了。但是一般情况下,子句的顺序很有关系。


Functions with the Same Name and Different Arity
  • The arity of a function is the number of arguments that the function has. In Erlang, two functions with the same name and different arity in the same module represent entirely different functions. They have nothing to do with each other apart from a coincidental use of the same name.────一个函数的arity是指这个函数拥有的参数的个数。在Erlang中,同一个模块中名字相同但arity不同的两个函数是完全不同的两个函数。它们仅仅是巧合的有了相同的名字而已。
  • Here’s an example:
    sum(L) -> sum(L, 0).
    sum([], N) -> N;
    sum([H|T], N) -> sum(T, H+N).

Funs
  • funs are “anonymous” functions.────"funs"是匿名的函数。
  • 1> Z = fun(X) -> 2*X end.
    #Fun
    2> Z(2).
    4
    3> Double = Z.
    #Fun
    4> Double(2).
    4
    5> Hypot = fun(X, Y) -> math:sqrt(X*X + Y*Y) end.
    #Fun
    6> Hypot(3,4).
    5.00000
    7> Hypot(3).

    =ERROR REPORT==== 28-Jul-2008::20:14:30 ===
    Error in process <0.31.0> with exit value: {{badarity,{#Fun,[3]}},[{erl_eval,expr,3}]}

    ** exited: {{badarity,{#Fun,[3]}},[{erl_eval,expr,3}]} **
    8> TempConvert = fun({c, C}) -> {f, 32 + C*9/5};
    8> ({f, F}) -> {c, (F-32)*5/9}
    8> end.
    #Fun
    9> TempConvert({c,100}).
    {f,212.000}
    10> TempConvert({f, 212}).
    {c,100.000}
    11> TempConvert({c, 0}).
    {f,32.0000}
    12>
  • Functions that return funs, or functions that can accept funs as their arguments, are called higher-order functions.────那些返回funs,或者可以接受funs作为参数的函数叫作"higher-order"函数。
  • Functions That Have Funs As Their Arguments
    1. 12> L = [1,2,3,4].
      [1,2,3,4]
      13> lists:map(Double, L).
      [2,4,6,8]
      14> Even = fun(X) -> (X rem 2) =:= 0 end.
      #Fun
      15> Even(8).
      true
      16> Even(7).
      false
      17> lists:map(Even, [1,2,3,4,5,6,8]).
      [false,true,false,true,false,true,true]
      18> lists:filter(Even, [1,2,3,4,5,6,8]).
      [2,4,6,8]
      (接上例)
  • Functions That Return Funs
    1. 1> Fruit = [apple,pear,orange].
      [apple,pear,orange]
      2> MakeTest = fun(L) -> (fun(X) -> lists:member(X, L) end) end.
      #Fun
      3> IsFruit = MakeTest(Fruit).
      #Fun
      4> IsFruit(pear).
      true
      5> IsFruit(apple).
      true
      6> IsFruit(dog).
      false
      7> lists:filter(IsFruit, [dog,orange,cat,apple,bear]).
      [orange,apple]

the use of the -import and -export declarations in the module
  • The declaration -import(lists, [map/2, sum/1]). means the function map/2 is imported from the module lists, and so on. This means we can write map(Fun, ...) instead of lists:map(Fun, ...). cost/1 was not declared in an import declaration, so we had to use the “fully qualified” name shop:cost.────定义"-import(lists,[map/2,sum/1])"的意思是函数"map/2"是从模块"lists"中导入的。所谓导入的意思是指你可以用"map(Fun,...)这样的写法代替"lists:map(Fun, ...)"。而比如"cost/1"在导入声明中没有被声明,则我们必须使用"fully qualified"名称"shop:cost".
  • The declaration -export([total/1]) means the function total/1 can be called from outside the module shop2. Only functions that are exported from a module can be called from outside the module.────定义"-export([total/1])的意思是指函数"total/1"可以从模式外面被调用。只有那些从模块中导出的函数才可以在模块外被调用。


List Comprehensions
  • List comprehensions are expressions that create lists without having to use funs, maps, or filters. This makes our programs even shorter and easier to understand.────List comprehensions是一种可以不使用funs,maps,filters就可以创建lists(列表)的表达式。这让我们的程序更加短小,而且更加容易理解。
  • 1> L = [1,2,3,4,5].
    [1,2,3,4,5]
    2> lists:map(fun(X) -> 2*X end, L).
    [2,4,6,8,10]
    3> [2*X || X <- L]. [2,4,6,8,10]
  • The notation [ F(X) || X <- L] means “the list of F(X) where X is taken from the list L.” Thus, [2*X || X <- L ] means “the list of 2*X where X is taken from the list L.”────"[F(X) || X <- L]"的意思是指"经过F(X)处理的列表,X来自于列表L"。因而,"[2*X || X <- L]的意思是“经过2*X处理的的列表,X来自于列表L”。
  • 4> Buy=[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}].
    [{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
    5> [{Name, 2*Number} || {Name, Number} <- Buy].
    [{oranges,8},{newspaper,2},{apples,20},{pears,12},{milk,6}]

Wednesday, July 16, 2008

Programming Erlang 笔记(一)

Variables(变量)

  • All variable names must start with an uppercase letter.────所有的变量必须用大写字母开头
  • 例子: Eshell V5.5.5 (abort with ^G)
    1> X = 123456789.
    123456789
    2> X.
    123456789
    3> X*X*X*X*X*X*X
    3> .
    437124189620885610010004822109262358637075660656881926429

  • Single Assignment Is Like Algebra,Variables That Don’t Vary────赋值就像代数里一样,不变的变量。(回想一下,在没有接触C等其他高级语言之前,代数中的变量是怎么样的。没错,它们的值是不变的)。 例子(接上例):4> X = 1234.

    =ERROR REPORT==== 16-Jul-2008::22:34:38 ===
    Error in process <0.31.0> with exit value: {{badmatch,1234},[{erl_eval,expr,3}]}

    ** exited: {{badmatch,1234},[{erl_eval,expr,3}]} **


  • Pattern Matching────模式匹配。在其他语言(C,JAVA,RUBY and so on)中,“=”都是赋值用,而在Erlang中它是作为模式匹配用的。比如:Lhs = Rhs,它的意思是,计算右边的值(Rhs),然后和左边的(Lhs)匹配。 例子:Eshell V5.5.5 (abort with ^G)
    1> X = (2+4).
    6
    2> Y = 10.
    10
    3> X = 6.
    6
    4> X = Y.

    =ERROR REPORT==== 16-Jul-2008::22:41:58 ===
    Error in process <0.31.0> with exit value: {{badmatch,10},[{erl_eval,expr,3}]}

    ** exited: {{badmatch,10},[{erl_eval,expr,3}]} **


Floating-Point Numbers(浮点数)
  • “/” always returns a float; thus, 4/2 evaluates to 2.0000 (in the shell). ────“/”操作符总是返回一个浮点数;所以,4/2计算得2.0000(in the shell)。
  • N div M and N rem M are used for integer division and remainder; thus, 5 div 3 is 1, and 5 rem 3 is 2.────N div M 和 N rem M 用于整除和计算余数,因而,5 div 3 等于1,而5 rem 3 等于2.
  • 例子:Eshell V5.5.5 (abort with ^G)
    1> 5/3.
    1.66667
    2> 4/2.
    2.00000
    3> 5 div 3.
    1
    4> 5 rem 3.
    2
    5> 4 div 2.
    2
    6> Pi = 3.14159.
    3.14159
    7> R = 5.
    5
    8> Pi * R * R.
    78.5397


Atoms
  • In Erlang, atoms are used to represent different non-numerical constant values.────在Erlang中,atoms被用来代表不同的非数字常量。
  • In Erlang, atoms are global, and this is achieved without the use of macro definitions or include files.────在Erlang中,atoms是全局的,而且这不是通过宏定义或者包含头文件来实现的。
  • Atoms start with lowercase letters, followed by a sequence of alphanumeric characters or the underscore (_) or at (@) sign.7 For example: red, december, cat, meters, yards, joe@somehost, and a_long_name.────Atoms以小写字母开头,跟一串字母数字或者下划线(_)或者at(@)标志。比如:red, december, cat, meters, yards, joe@somehost, a_long_name。
  • The value of an atom is just the atom.────一个atom的值就是atom本身。例子: 1> hello.
    hello



Tuples(元组)
  • You can create a tuple by enclosing the values you want to represent in curly brackets and separating them with commas. for example:{joe, 1.82}────你可能用大括号括起用逗号分隔的值来创建一个元组。比如{joe, 1.82}

  • Tuples are similar to structs in C────元组和C语言中的结构类似。
  • To make it easier to remember what a tuple is being used for, it’s common to use an atom as the first element of the tuple, which describes what the tuple represents.────为了能更加容易的记住一个元组是做什么用的,通常用一个atom来做元组的第一个元素,用来描述这个元组代表什么。
  • Tuples can be nested.────元组可以嵌套。例子:Eshell V5.5.5 (abort with ^G)
    1> Person = {person,
    1> {name, joe},
    1> {height, 1.82},
    1> {footsize, 42},
    1> {eyecolor, brown}}.
    {person,{name,joe},{height,1.82000},{footsize,42},{eyecolor,brown}}
  • 2> F = {firstName, joe}.
    {firstName,joe}
    3> L = {lastName, armstrong}.
    {lastName,armstrong}
    4> P = {person, F, L}.
    {person,{firstName,joe},{lastName,armstrong}}
  • Extracting Values from Tuples────从元组中抽取数据
    1. pattern matching is fundamental to Erlang and that it’s used for lots of different tasks.────模式匹配是Erlang的基础而且它被用于许多不同的任务。
    2. If we want to extract some values from a tuple, we use the pattern
      matching operator =.────如果我们想要从一个元组中抽取数据,我们用匹配操作符“=”。
    3. 例子:Eshell V5.5.5 (abort with ^G)
      1> Point = {point, 10, 45}.
      {point,10,45}
      2> {point, X, Y} = Point
      2> .
      {point,10,45}
      3> X.
      10
      4> Y.
      45
    4. 一个更为复杂的例子:Eshell V5.5.5 (abort with ^G)
      1> Person={person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
      {person,{name,{first,joe},{last,armstrong}},{footsize,42}}
      2> {_,{_,{_,Who},_},_} = Person.
      {person,{name,{first,joe},{last,armstrong}},{footsize,42}}
      3> Who.
      joe
    5. _ as a placeholder for variables that we’re not interested in. The symbol _ is called an anonymous variable.────"_"作为占位符。符号"_"叫作匿名变量。


Lists(列表)
  • create a list:Eshell V5.5.5 (abort with ^G)
    1> ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
    [{apples,10},{pears,6},{milk,3}]
    2> [1+7, hello, 2-2, {cost, apple, 30-20}, 3].
    [8,hello,0,{cost,apple,10},3]

  • We call the first element of a list the head of the list.what’s left is called the tail of the list.────我们把列表的第一个元素叫做“头”,剩下的叫做“尾”。比如[1,2,3,4,5]这个列表中,头是整数1,尾是列表[2,3,4,5]。
  • Note that the head of a list can be anything, but the tail of a list is usually also a list.────注意,一个列表的头可以是任何类型,但是尾通常也是一个列表。
  • (*)If T is a list, then [H|T] is also a list, with head H and tail T.Whenever we construct a list using a [...|T] constructor, we should make sure that T is a list.────如果T是一个列表,那么[H|T]也是一个列表,头是H,尾是T。不管我们如何用[...|T]来构造一个列表,必须要保证T一定是一个列表。
  • 3> ThingsToBuy1 = [{oranges, 4}, {newspaper, 1}|ThingsToBuy].
    [{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]

    (接上面的例子)
  • Extracting Elements from a List────从列表中提取元素


    4> [Buy1|ThingsToBuy2] = ThingsToBuy1.
    [{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
    5> Buy1.
    {oranges,4}
    6> [Buy2, Buy3|ThingsToBuy3] = ThingsToBuy2.
    [{newspaper,1},{apples,10},{pears,6},{milk,3}]
    7> Buy2.
    {newspaper,1}
    8> Buy3.
    {apples,10}
    9> ThingsToBuy3.
    [{pears,6},{milk,3}]
    (接上面例子)




Strings(字符串)
  • Strictly speaking, there are no strings in Erlang. Strings are really just lists of integers. Strings are enclosed in double quotation marks (")────严格的讲,Erlang中并没有字符串。所谓字符串实际上只是整数的列表。字符串是用双引号括起来的。
  • Eshell V5.5.5 (abort with ^G)
    1> Name = "Hello".
    "Hello"

  • When the shell prints the value of a list it prints the list as a string, but only if all the integers in the list represent printable characters.────当shell打印一列表的值的时候,如果这个列表中的整数都能代表一个可打印的字符,它就会把这个列表当作一个字符串来打印。
  • 2> [1,2,3].
    [1,2,3]
    3> [83,117,114,112,114,105,115,101].
    "Surprise"
    4> [1,83,117,114,112,114,105,115,101].
    [1,83,117,114,112,114,105,115,101]

  • We don’t need to know which integer represents a particular character.We can use the “dollar syntax” for this purpose.────我们没有必要去知道哪个整数代表哪个字符,我们可以用美元符号"$"来做这件事情。(见下例)
  • 5> I = $s.
    115
    6> [I-32, $u, $r, $p, $r, $i, $s, $e].
    "Surprise"



Pattern Matching Again(再谈模式匹配)
  • Note: The command f() tells the shell to forget any bindings it has. After this command, all variables become unbound────注意:f()命令会告诉shell忘记掉所以的绑定。在这个命令之后,所以的变量都是未绑定的。

Monday, March 31, 2008

倾向

又把《The Wall》(迷墙)看了一遍,上一次看已经是几年前的事了。当时想看这部电影是因为其特殊性,整个电影其实就是Pink Floyd《The Wall》整张专辑的MV。我已经不记得第一次是从哪了解到有这么个电影了,是先听的歌还是先看的电影也忘的一干二净,看这个电影时,我奶奶还在不在也不记得了。总觉得不可思议,我的记性现在怎么会差到这种程度。对事物的时间感也变得极其模糊,三年和十年在我的记忆中感觉一样遥远。当然三年前的记忆要比十年前的记忆多得多,但是如果上帝下来对我说:其实你上先读的高中,再读的小学;我觉得就我的记忆时间感而言,他(她?它?)还是说的有道理的。所以,离的越近的记忆,越发不能分辩其时间上的先后。虽然有时这样也会造成某些麻烦,但就日常生活而言,还是没有太大的影响,幸事。

  又扯了,回来说这电影。电影的主人公Pink的父亲死于二战,在母亲的呵护下Pink长大,但没有父亲的Pink一直感到孤独。整部电影光怪陆离,回忆,现实,磕药后的迷幻不停交错,Pink的童年回忆,妻子的背叛,心中不断筑起的Wall,二战,纳粹,教育,制度。从批评的角度而言,电影主题未免过于不明,但是将其看成是Pink的人生自然一切合情合理。

  大二的时候上了周易的选修课,老师说:命运这东西或多或少应该是存在的。以前我不信,现在我有点相信了。不过在我看来,与其说是命运,更不如说是一种倾向,一种潜意识的影响。拿Pink做例子就是他父亲死于二战在他潜意识留下很深的印象,使他有了某种倾向。拿我做例子。。。这还是算了吧,有空再细谈。。。有了倾向,某些看似是巧合的事件就会发现其必然性。如果我的人生从三岁重来,我想我还是会走到今天的处境。所以,老话说:三岁看老,的确是有道理。

Friday, February 29, 2008

迟钝

  听着The Album Leaf的歌不知怎么的眼泪就流了下来,不是伤心,不是难过,我找了好久用一个词来形容这种感觉,“孤独”这个词大概是最贴切的。
  听着歌,思绪也开始飞散,想到高中时候认识的杂志《音乐天堂》,想到好久没有在杂志摊上见到她了,就用Google查了下。当了解到那本是终刊的时候,我有一点惊讶,但转瞬就没了——我其实早就知道她已经不在了吧?当我看着那本终刊的那个时候我就已经知道了吧?当我几个月没有见到卖的时候我就已经确信了吧?
  现在我只是将这一事实完全的接受了,大概仅此而已。很多事我都是到将其做为事实完全接受时才意识到“哦,其实老早我就已经知道是这样子的啊,怎么回事?晕”。这也可以算是一种迟钝吧,也或许我又将梦境与现实混淆了。
  不管是什么,还是那句话:这对我的生活的影响微乎其微。
  The Album Leaf——Story Board.

Monday, February 04, 2008

瑞雪兆丰年

  印象中只有很小的时候看到这么大的雪。不过问了个老妈,她说记不起来生我以后有过这么大的雪。但我的确是有这么个印象:小时候,我在雪地里艰难的走着,因为雪已经到了我的膝盖。不是老妈真的老了,就是我又把梦境与现实搞混了。我的记忆有多少是真实的,这个我已经不想关心了,即使全当成是现实,对我的生活也造成不了太大的影响。
  这几天看了几个高中同学的QQ空间,似乎人人都有着各式各样的自己的问题,相比之下,甚至觉得自己活的真是不错。高中有段时间我很悲观,原因很多;现在觉得自己很乐观,原因很简单,我差不多完全掌握了自利的原则。记得哪本小说有句话说:我很自利,但我不自私。
  好吧,其实我想说的是,大家都应该自利点,来年必将是丰收的一年。雪已经停了,股灾也要结束了,没老婆的就要有老婆了,没老公的老公就快来了。记得小学语文有一课就是讲过年的,里面老人们说:瑞雪兆丰年!顺带提下,这是我仅能马上想起的两篇小学语文课文,还有一篇是那个傻X赖宁。。。

Wednesday, January 30, 2008

我们一直没变

28号,同学会,开心。
几个小时的聚会还不够尽兴,真希望有一天我们能在找个地方开个一星期的同学会,那就爽了。老同学们都没有变,在走进萧中大门的那瞬间,我觉得岁月根本没有在我们身上留下任何东西,我们还是和三年前一样,年轻单纯。事实是,我们的确还是很单纯很年轻,只有当我们想到自己的时候才发现,三年时间已经过去了。我忘记了很多人的名字,我的记性越来越差,这几年忘记的东西越来越多。我需要你们来提醒我的。我不想忘记你们以及和你们在一起的日子,就像忘记我和我的小学同学的许多事那样,我想我一定忘记掉了很多了。
我知道我们这三年其实过的可能都不容易,人总是有很多烦恼。我知道我们都能找到解决办法。明年这时候,大家谈的应该是工作了,不过我相信我们都是人才。我一直这么相信的说。大家都要为了梦想而奋斗啊。我也是。
夜猫子,准备睡觉。有你们我很满足。

Sunday, January 06, 2008

一个烧水壶引发的思考

  很久没有更新了,正如我以前说的一样,如果我很长一段时间没有更新博客,那我肯定沉迷于游戏了。这次也不例外。自从8月1号开始我就一直将大量的时间用在玩EVE上了,到现在为止,差不多5个月。其间,我挂掉了软件设计师的考试。
  前天,本来想烧点水洗头,然后回学校,不知怎么的,我竟然将没水的烧水壶直接插上了电源,直到水壶爆了我才对此后知后觉。我被这一爆震醒了。后来我在回学校的路上想了很多。我带回家本来想看的书一页未翻;我在家的每天都玩游戏玩到凌晨3点多;我爸也曾跟我一样傻B地摔坏电视机;我的寒假计划;我这5个月做的事(当然第一印入脑海的是游戏);女人;钱;技术;对自己的怀疑。
  其实如果不谈游戏,还有软件设计师考试,我在这5个月里做的还不错。学到了很多东西,也有所进步,觉得生活也变得很有意思。我老是在想,如果我以前在高中里能怎么怎么做,或许我就能怎么怎么样;近几天当我在这么想后,我马上醒悟:我要做的是现在我应该怎么怎么样。我的大学还有一年时间,这一年我能做到什么程度呢,做到让我以后不会遗撼呢?
  我总是陷入自我迷失与找回的循环中,对此,我不以为然,甚至还很开心,因为我有受虐的倾向可能,我能享受某些痛苦。不管怎么样,我现在知道我是什么,我要做什么,我缺的是什么,我下一步是什么,我明天要做什么。然后最重要的,我要能精确到下一秒要做什么。
  让我看看这次我能有什么变化。