Search

1/31/2011

王建民愛吃的日式創意料理 -- 花彘醺 @ 搶著臥軌的世界 :: 痞客邦 PIXNET :

王建民愛吃的日式創意料理 -- 花彘醺 @ 搶著臥軌的世界 :: 痞客邦 PIXNET :
花彘醺
台北市仁愛路4段345巷15弄8號 (之前 “延八”餐廳的原址,普羅咖啡的隔壁)
(02) 2777-1479
5:30pm – 1:00am

水的科學與偽科學

水的科學與偽科學

(1)電解水產生的鹼性水可以中和酸性體質,有益健康?

我們的意見:電解水所產生的鹼性水其程度微不足道,果汁的酸和鎂奶的鹼含量要大得多,但不會影響人體的酸鹼度,人的胃液就是俗稱的鹽酸,所有的鹼性水都不可能通過胃而仍然保持鹼性。人體內的酸鹼度是由緩衝物質(如二氧化碳)和酵素控制的,太酸或太鹼都不好。

人體如何控制酸鹼度?

(2)不要喝純水,因為水中缺乏礦物質?

我們的意見:純水的確不含礦物質,有些賣礦泉水的宣傳據此而勸人不要喝逆滲透水或蒸餾水,其實水在身體裡扮演的是溶劑的角色,喝沒有污染的水對維護人的健康最為重要,人體所需的礦物質來自飲食(如蔬菜水果)。

(3)小分子團水(能量水)比起自來水更能有效地進出細胞,可以讓細胞保持年輕?

我們的意見:沒有任何證據支持以各種結構改變水,或所謂的"水分子團"來推銷"細胞水合"的說法,這些論調毫無根據,也和已知水分子進入細胞壁"一次一分子"的機制不相容,沒有證據顯示任何飲食添加物或療法可以延遲老化。2003年諾貝爾化學獎得主Peter Agre教授告訴我們水分子如何進出細胞。讀者也可以參考臺灣大學化學系蔡蘊明教授的中文版。

(4)磁化水(p水)對人體有益?

我們的意見:水分子有電偶極(分子內局部正負電),但是沒有磁偶極,除非在極端狀況下,水不會受磁場的影響,沒有任何具有公信力的研究證實磁處理水有療效,"抑制腫瘤細胞的產生"的說法更是完全沒有根據。

(5)氧化水讓人活力充沛?

我們的意見:水中只能溶解微乎其微的氧氣,而且喝進腸胃道的氧氣不會被人體吸收;吸一口新鮮空氣,身體得到的氧氣要多得多!

1/26/2011

facebook noscript的作法

if js-disable UA browse to http://www.facebook.com/ will be directed to http://www.facebook.com/?_fb_noscript=1

if js-enable UA browse to http://www.facebook.com/?_fb_noscript=1 will be directed to http://www.facebook.com/

howto:

在http://www.facebook.com/?_fb_noscript=1 的javascript有這行是http://www.facebook.com/ 裡面沒有的
OnloadRegister(function (){window.location.href="http:\/\/www.facebook.com\/"})

同樣的在http://www.facebook.com/ 裡面有這一行是http://www.facebook.com/?_fb_noscript=1 裡面沒有的
<noscript> <meta http-equiv=refresh content="0; URL=/?_fb_noscript=1" /> </noscript>

1/22/2011

JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )

JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )

$=[] is a blank array
$=[$=[]] is [[]]
$ equals to (number) 0, that is, +$ === 0
!$ equals to (bool)false
!$ + $ equals to (string)"false"
__ = !$ + $ equals to "false"
~ operator in JavaScript means -(N+1) so -~ equals +1
if $ = 0, then -~-~-~$ equals 3
thus _/_ equals 3/3 equals 1

(__ = !$ + $)[_ = -~-~-~$]
=> ("false")[_]
=> ("false")(3)
=> "s"

({} + $)[_/_]
=> ("object")[_/_]
=> ("object")[1]
=> "o"

$$ = ($_=!" + $)[_/_]
=> $$ = ("true)[1]
=> "r"

1/19/2011

Parrot - The Parrot Primer

Parrot - The Parrot Primer

Virtual Machines

Parrot is a virtual machine. To understand what a virtual machine is, consider what happens when you write a program in a language such as Perl, then run it with the applicable interpreter (in the case of Perl, the perl executable). First, the program you have written in a high level language is turned into simple instructions, for example fetch the value of the variable named x, add 2 to this value, store this value in the variable named y, etc. A single line of code in a high level language may be converted into tens of these simple instructions. This stage is called compilation.

The second stage involves executing these simple instructions. Some languages (for example, C) are often compiled to instructions that are understood by the CPU and as such can be executed by the hardware. Other languages, such as Perl, Python and Java, are usually compiled to CPU-independent instructions. A virtual machine (sometimes known as an interpreter) is required to execute those instructions.

While the central role of a virtual machine is to efficiently execute instructions, it also performs a number of other functions. One of these is to abstract away the details of the hardware and operating system that a program is running on. Once a program has been compiled to run on a virtual machine, it will run on any platform that the VM has been implemented on. VMs may also provide security by allowing more fine-grained limitations to be placed on a program, memory management functionality and support for high level language features (such as objects, data structures, types, subroutines, etc).

Design goals
Parrot is designed with the needs of dynamically typed languages (such as Perl and Python) in mind, and should be able to run programs written in these languages more efficiently than VMs developed with static languages in mind (JVM, .NET). Parrot is also designed to provide interoperability between languages that compile to it. In theory, you will be able to write a class in Perl, subclass it in Python and then instantiate and use that subclass in a Tcl program.

Historically, Parrot started out as the runtime for Perl 6. Unlike Perl 5, the Perl 6 compiler and runtime (VM) are to be much more clearly separated. The name Parrot was chosen after the 2001 April Fool's Joke which had Perl and Python collaborating on the next version of their languages. The name reflects the intention to build a VM to run not just Perl 6, but also many other languages.

Instruction formats
Parrot can currently accept instructions to execute in four forms. PIR (Parrot Intermediate Representation) is designed to be written by people and generated by compilers. It hides away some low-level details, such as the way parameters are passed to functions. PASM (Parrot Assembly) is a level below PIR - it is still human readable/writable and can be generated by a compiler, but the author has to take care of details such as calling conventions and register allocation. PAST (Parrot Abstract Syntax Tree) enables Parrot to accept an abstract syntax tree style input - useful for those writing compilers.

All of the above forms of input are automatically converted inside Parrot to PBC (Parrot Bytecode). This is much like machine code, but understood by the Parrot interpreter. It is not intended to be human-readable or human-writable, but unlike the other forms execution can start immediately, without the need for an assembly phase. Parrot bytecode is platform independent.

http://www.programmersheaven.com/2/Parrot-a-Virtual-Machine-For-Everyone

The 'Parrot' Software-CPU instruction set includes arithmetic and logical operators, compare and ranch/jump (for implementing loops, if...then constructs, etc), finding and storing global and lexical variables, working with classes and objects, calling subroutines and methods along with their parameters, I/O, threads and more. As we mentioned earlier that the 'Parrot' VM is register based. So we should expect number of fast-access storing units called registers in the 'Parrot' Software-CPU. Our guess is very correct, there are 4 types of register, 32 each in numbers, in 'Parrot': integers (I), numbers (N), strings (S) and PMCs (P). These registers are named I0, N0, S0, P0 ....... I31, N31, S31, P31 etc. Integer registers are the same size as a word ( 32 bit on 32 bit CPUs and 64 bit on 64 bit CPUs) on the machine 'Parrot' is running on and number registers also map to a native floating point type.

Portable Programming Languages Using "Parrot"
As we have learnt that 'Virtual Machines' provide portability across the different machine architectures. So if someone wants to design a portable programming language that provides "Write Once, Run Anywhere" model then 'Parrot' fulfills this purpose very intelligently. In fact you can study about many concept languages written for 'Parrot' runtime in the 'languages' subdirectory.

Let's now discuss more about using 'Parrot' as a run time engine for custom designed portable languages. First we have to define a language with all its constructs and grammar, then we design a parser that takes source code of the language and creates a syntax tree of that source. As described above, we can convert the output of the parser in PAST format and then use 'Parrot' as runtime engine for our custom portable language. Although it's very simple layout of the total plan because we have to implement the optimization at the various stages also. This total scheme is shown in Fig-3.

Easing into SICP

Easing into SICP

"The Structure and Interpretation of Computer Programs" by Abelson and Sussman (http://mitpress.mit.edu/sicp/full-text/book/book.html) is often recommended reading on HN and elsewhere. However, you may find it to be much denser than the breezy computer books that are typically published. To help you acclimate to the concepts in SICP, I recommend the following steps:

First, read "Concrete Abstractions" by Max Heilparin (http://gustavus.edu/+max/concrete-abstractions-pdfs/index.html) and "Simply Scheme" by Brian Harvey (http://www.cs.berkeley.edu/~bh/ss-toc2.html). Neither of these books assume much programming knowledge, and should be accessible to anyone.

Next, listen to or watch Brian Harvey's lectures for "The Structure and Interpretation of Computer Programs" (http://webcast.berkeley.edu/course_details.php?seriesid=1906978502). This course uses SICP as a text book, but takes a less mathematical approach. The lecture notes are also available (http://www-inst.eecs.berkeley.edu/~cs61a/reader/vol2.html). This is a full semester course, so it will take you a while to get through it, but Harvey's lectures are easy to listen to.

Third, watch the lectures by Holly Yanko (http://www.aduni.org/courses/sicp/index.php?view=cw) for a SICP course. These follow the book very closely, but Yanko covers the material at relaxed pace. Unfortunately, these videos are Real Player, so you may have difficulty playing them. There are notes for the first few lectures.

Finally, watch the videos of Abelson and Sussman (http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/). At this point, you will certainly be able to understand the more subtle and/or complex points that they make.

Overall, this is a big commitment of time, but it will certainly shake you out of any rut that your current languages have put you in regarding how to solve problems with computers.

1/17/2011

Countdown to Knockout: Post 9 - WebSockets everywhere with Socket.io

17 Jan 08:25:28 - Initializing client with transport "xhr-multipart" (firefox 3.6.13)
17 Jan 08:25:28 - Client 39879375603049994 connected
17 Jan 08:25:33 - Initializing client with transport "websocket" (chrome 8.0.552.237)
17 Jan 08:25:33 - Client 9136935125570744 connected
17 Jan 08:25:46 - Answering flash policy request inline
17 Jan 08:28:01 - Initializing client with transport "htmlfile" (ie 6.0)
17 Jan 08:28:01 - Client 09895511576905847 connected


Countdown to Knockout: Post 9 - WebSockets everywhere with Socket.io

This is possible with at least two fairly well known techniques:

* XMLHttpRequest and the multipart/x-mixed-replace MIME type (which is enabled by setting multipart = true in the XMLHTTPRequest instance)

Although it was introduced by Netscape in 1995 (yes, when some of us were still unable to read properly), the only commonplace user agent to support it is Firefox.
* An <iframe> populated with a response with the headers Transfer-encoding: chunked and Connection: keep-alive.

The technique consists of writing <script> tags that call a function on the parent page as information becomes available to push to the client.

The disadvantage of this method is that it'll trigger a never-ending spinner or progress bar in most user agents, severely hurting the user experience. In Internet Explorer, this can be worked around by inserting the <iframe> in a hidden document (via the obscure ActiveX object htmlfile). This technique was exposed to me for the first time thanks to the Gmail Chat team. This gem was analyzed/discovered back in the day by Alex Russell.

By now, it's obvious that some lower-latency techniques are available to certain user agents, under certain conditions. The fundamental problem is that now the server has to treat HTTP requests differently, altering

* The headers sent with the response (Content-Type, Connection, etc).
* The duration (a timeout is required for long-polling, but not all the others)
* The "framing" of the messages. For multipart, each message has to be accompanied by a delimiter (boundary).
* Random quirks (IE requires a certain number of dummy bytes at the beginning of the document streamed through the iframe).


What else is burried down in the depth’s of Google’s amazing JavaScript?

// we were served from child.example.com but
// have already set document.domain to example.com
var currentDomain = "http://exmaple.com/";
var dataStreamUrl = currentDomain+"path/to/server.cgi";
var transferDoc = new ActiveXObject("htmlfile"); // !?!
// make sure it's really scriptable
transferDoc.open();
transferDoc.write("<html>");
transferDoc.write("<script>document.domain='"+currentDomain+"';</script>");
transferDoc.write("</html>");
transferDoc.close();
// set the iframe up to call the server for data
var ifrDiv = transferDoc.createElement("div");
transferDoc.appendChild(ifrDiv);
// start communicating
ifrDiv.innerHTML = "<iframe src='"+dataStreamUrl+"'></iframe>";

计算机程序的构造和解释 Structure and Interpretation of Computer Programs, SICP

计算机程序的构造和解释

本書被广泛地认为是计算机科学的经典教材,在计算机科学的教学领域产生了深刻的影响。諸多的經典教材都是由本書間接催化,諸如:

* Structure and Interpretation of Classical Mechanics (SICM), 由 SICP 啟發,Gerald Jay Sussman 參與的古典力學教材。(激發的創作中,唯一非電腦科學領域的。)
* How to Design Programs (HtDP),由 SICP 出發的改良品。有簡體中文版《程序設計方法》。DrScheme 是作者群搭配本書推出的 Scheme 教學用實作品。
* t (EoPL) ,以特定語言 Scheme 推演全書,這種寫法在程式語言結構的主題十分罕見。
* Lisp in Small Pieces (LiSP),專談 Scheme 的編譯器與直譯器原理與製作。[12]
* Simply Scheme,為了讓 SICP 更容易上手的先備書籍。SICP 的部份作者也參與了本書先期的製作過程。[13]
* Concrete Abstractions,比 SICP 擁有更多例子並且不那麼要求讀者的數學能力。[14]

值得一提的是,幾乎所有的衍生作都直接或間接地抱怨 SICP “太難”;甚至連 SICP 自身於第二版也試圖補充了一些讓學習曲線更平滑的材料。第一屆的圖靈獎得主 Alan J. Perlis 甚至在序文為此辯白:
Do not labor under the illusion that this is a text digestible at MIT only, peculiar to the breed found there. It is precisely what a serious book on programming Lisp must be, no matter who the student is or where it is used.[15]

此外本書的讀者群 - 包含教師學生與各界社會人士 - 給了本書十分兩極化的評價,但不論好壞都非常有道理。所有改進或取代本書的動機都來自對本書的愛與恨。其中 Peter Norvig 的讀後感:〈Its the Best! Its the Worst! Why the split?〉[16] 總結了造成雙峰現象的各種原因並給了讓人信服的統合性結論。


Its the Best! Its the Worst! Why the split? by Peter Norvig
To use an analogy, if SICP were about automobiles, it would be for the person who wants to know how cars work, how they are built, and how one might design fuel-efficient, safe, reliable vehicles for the 21st century. The people who hate SICP are the ones who just want to know how to drive their car on the highway, just like everyone else.

Donald Knuth says he wrote his books for "the one person in 50 who has this strange way of thinking that makes a programmer". I think the most amazing thing about SICP is that there are so FEW people who hate it: if Knuth were right, then only 1 out of 50 people would be giving this 5 stars, instead of about 25 out of 50. Now, a big part of the explanation is that the audience is self-selected, and is not a representative sample. But I think part of it is because Sussman and Abelson have succeeded grandly in communicating "this strange way of thinking" to (some but not all) people who otherwise would never get there.

1/14/2011

Visualization of Quick sort

How to write a simple operating system

How to write a simple operating system


PC primer
If you're writing an OS for x86 PCs (the best choice, due to the huge amount of documentation available), you'll need to understand the basics of how a PC starts up. Fortunately, you don't need to dwell on complicated subjects such as graphics drivers and network protocols, as you'll be focusing on the essential parts first.

When a PC is powered-up, it starts executing the BIOS (Basic Input/Output System), which is essentially a mini-OS built into the system. It performs a few hardware tests (eg memory checks) and typically spurts out a graphic (eg Dell logo) or diagnostic text to the screen. Then, when it's done, it starts to load your operating system from any media it can find. Many PCs jump to the hard drive and start executing code they find in the Master Boot Record (MBR), a 512-byte section at the start of the hard drive; some try to find executable code on a floppy disk (boot sector) or CD-ROM.

This all depends on the boot order - you can normally specify it in the BIOS options screen. The BIOS loads 512 bytes from the chosen media into its memory, and begins executing it. This is the bootloader, the small program that then loads the main OS kernel or a larger boot program (eg GRUB/LILO for Linux systems). This 512 byte bootloader has two special numbers at the end to tell the OS that it's a boot sector - we'll cover that later.

Note that PCs have an interesting feature for booting. Historically, most PCs had a floppy drive, so the BIOS was configured to boot from that device. Today, however, many PCs don't have a floppy drive - only a CD-ROM - so a hack was developed to cater for this. When you're booting from a CD-ROM, it can emulate a floppy disk; the BIOS reads the CD-ROM drive, loads in a chunk of data, and executes it as if it was a floppy disk. This is incredibly useful for us OS developers, as we can make floppy disk versions of our OS, but still boot it on CD-only machines. (Floppy disks are really easy to work with, whereas CD-ROM filesystems are much more complicated.)

Assembly language primer
Like most programming languages, assembly is a list of instructions followed in order. You can jump around between various places and set up subroutines/functions, but it's much more minimal than C# and friends. You can't just print "Hello world" to the screen - the CPU has no concept of what a screen is! Instead, you work with memory, manipulating chunks of RAM, performing arithmetic on them and putting the results in the right place. Sounds scary? It's a bit alien at first, but it's not hard to grasp.

At the assembly language level, there is no such thing as variables in the high-level language sense. What you do have, however, is a set of registers, which are on-CPU memory stores. You can put numbers into these registers and perform calculations on them. In 16-bit mode, these registers can hold numbers between 0 and 65535. Here's a list of the fundamental registers on a typical x86 CPU:
AX, BX, CX, DX General-purpose registers for storing numbers that you're using. For instance, you may use AX to store the character that has been pressed on the keyboard, while using CX to act as a counter in a loop. (Note: these 16-bit registers can be split into 8-bit registers such as AH/AL, BH/BL etc.)
SI, DI Source and destination data index registers. These point to places in memory for retrieving and storing data.
SP The Stack Pointer (explained in a moment).
IP (sometimes CP) The Instruction/Code Pointer. This contains the location in memory of the instruction being executed. When an instruction has finished, it is incremented and moves on to the next instruction. You can change the contents of this register to move around in your code.

So you can use these registers to store numbers as you work - a bit like variables, but they're much more fixed in size and purpose. There are a few others, notably segment registers. Due to limitations in old PCs, memory was handled in 64K chunks called segments. This is a really messy subject, but thankfully you don't have to worry about it - for the time being, your OS will be less than a kilobyte anyway! In MikeOS, we limit ourselves to a single 64K segment so that we don't have to mess around with segment registers.

The stack is an area of your main RAM used for storing temporary information. It's called a stack because numbers are stacked one-on-top of another. Imagine a Pringles tube: if you put in a playing card, an iPod Shuffle and a beermat, you'll pull them out in the reverse order (beermat, then iPod, and finally playing card). It's the same with numbers: if you push the numbers 5, 7 and 15 onto the stack, you will pop them out as 15 first, then 7, and lastly 5. In assembly, you can push registers onto the stack and pop them out later - it's useful when you want to store temporarily the value of a register while you use that register for something else.

PC memory can be viewed as a linear line of pigeon-holes ranging from byte 0 to whatever you have installed (millions of bytes on modern machines). At byte number 53,634,246 in your RAM, for instance, you may have your web browser code to view this document. But whereas we humans count in powers of 10 (10, 100, 1000 etc. - decimal), computers are better off with powers of two (because they're based on binary). So we use hexadecimal, which is base 16, as a way of representing numbers. See this chart to understand:
Decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14

As you can see, whereas our normal decimal system uses 0 - 9, hexadecimal uses 0 - F in counting. It's a bit weird at first, but you'll get the hang of it. In assembly programming, we identify hexadecimal (hex) numbers by tagging a 'h' onto the end - so 0Ah is hex for the number 10. (You can also denote hexadecimal in assembly by prefixing the number with 0x - for instance, 0x0A.)

Let's finish off with a few common assembly instructions. These move memory around, compare them and perform calculations. They're the building blocks of your OS - there are hundreds of instructions, but you don't have to memorise them all, because the most important handful are used 90% of the time.
mov Copies memory from one location or register to another. For instance, mov ax, 30 places the number 30 into the AX register. Using square brackets, you can get the number at the memory location pointed to by the register. For instance, if BX contains 80, then mov ax, [bx] means "get the number in memory location 80, and put it into AX". You can move numbers between registers too: mov bx, cx.
add / sub Adds a number to a register. add ax, FFh adds FF in hexadecimal (255 in our normal decimal) to the AX register. You can use sub in the same way: sub dx, 50.
cmp Compares a register with a number. cmp cx, 12 compares the CX register with the number 12. It then updates a special register on the CPU called FLAGS - a special register that contains information about the last operation. In this case, if the number 12 is bigger than the value in CX, it generates a negative result, and notes that negative in the FLAGS register. We can use this in the following instructions...
jmp / jg / jl... Jump to a different part of the code. jmp label jumps (GOTOs) to the part of our source code where we have label: written. But there's more - you can jump conditionally, based on the CPU flags set in the previous command. For instance, if a cmp instruction determined that a register held a smaller value than the one with which it was compared, you can act on that with jl label (jump if less-than to label). Similarly, jge label jumps to 'label' in the code if the value in the cmp was greater-than or equal to its compared number.
int Interrupt the program and jump to a specified place in memory. Operating systems set up interrupts which are analogous to subroutines in high-level languages. For instance, in MS-DOS, the 21h interrupt provides DOS services (eg as opening a file). Typically, you put a value in the AX register, then call an interrupt and wait for a result (passed back in a register too). When you're writing an OS from scratch, you can call the BIOS with int 10h, int 13h, int 14h or int 16h to perform tasks like printing strings, reading sectors from a floppy disk etc.

1/13/2011

An Experiment in Rounded Corners

An Experiment in Rounded Corners

demo; http://snook.ca/technical/rounded_corners/
DD_roundies: Code-only rounded HTML boxes

tag: vml

F# 程式設計入門 (1)

F# 程式設計入門 (1)

LISP 是第一個函數式語言,越來越多函數式語言隨之出現。真實世界的函數式語言無法像 Lambda Calculus 那樣,畢竟 Lambda Calculus 是讓虛幻不存在的機器執行的,沒有受到真實世界的限制。所以函數式語言雖然都是源自於 Lambda Calculus,但是卻都和 Lambda Calculus 之間存在差異。由於 FP 只是一些構想,各種語言實踐這些構想的作法,彼此之間也可能有不小的差異。

儘管各種語言有差異,但是大致上來說,FP 的特點在於:

* 「沒有副作用」(Side Effect)。在表示式(expression)內不可以造成值的改變。
* 「第一級函數」(First-Class Function)。函數被當作一般值對待,而不是次級公民,也就是說,函數可當作「傳入參數」或「傳出結果」。

基本上,遵守上述兩點進行程式編寫,差不多就可以稱為 FP。FP 和我們慣用的編寫程式風格,有相當大的差異。Imperative Programming 認為程式的執行,就是一連串狀態的改變;但 FP 將程式的運作,視為數學函數的計算,且避免「狀態」和「可變資料」。

為了提昇效率,許多函數式語言會納入 imperative 的某些作法(例如允許副作用),這類的 FPL 被稱為不純(Impure)的函數式編程語言,例如 Ocaml、F#、LISP、REBOL。當然也有一些語言堅持 Pure Functional 的作法,例如 Erlang、Haskell、Occam、Oz。

以往純的函數式語言會被某些人認為不實際,而不純的函數式語言,則被認為比較實際,但是最近大家的看法似乎有了改變。主要是以 Erlang 為首的純函數式語言,似乎更能充分展現出 FP 的優勢。FP 的優勢是容易進行單元測試、容易除錯、適合編寫(Concurrency)的程式。適合進行程式碼「熱抽換」或「熱部署」(Hot Code Deployment)。

除了上述的優點,我們可以透過 FP 作了些什麼,來瞭解 FP 是什麼。FP 語言常常能做下面的事:Higher-Order Function、Currying、Lazy Evaluation、Continuations、Pattern Matching、Closure、List Processing、Meta-Programming。如果你對這些觀念不太瞭解,可以查詢 Wikipedia 的說明。

微軟也注意到了 FP 的潮流。F# 的 F 是 Functional Language(函數式語言)的意思,# 是 .NET 的意思,所以顧名思義,F# 是 .NET 平台上函數式語言,由微軟官方所設計。F# 的血緣關係是 ML -> Caml -> OCaml(Objective-Caml)-> F#。同時 F# 也混入了一些 Haskell 和 C# 的語言特色。

1/09/2011

BATTLE OF THE LISPS: Common Lisp vs. Scheme

BATTLE OF THE LISPS: Common Lisp vs. Scheme

Scheme’s Idea

The way Scheme unified compared to the way CL differs vastly. Scheme’s idea of unification is exemplified by one of the first statements in the Scheme standard itself:
Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.

Essentially, Scheme was an attempt to take the core idea of Lisp, and derive a bare but practical “minimum” which could be reasonably extended as needed. This was highly successful, and the Scheme standard ended up being just over 50 or so pages (and anyone who has seen a language standard before would be staggered by such a low number). Due to the succinctness of the definition of the language, it is an incredible medium for studying programming languages and computer science in general (it is the language used in the famous book Structure and Interpretation of Computer Programs, or SICP).

The use of Scheme extends beyond simple educational or theoretical value. It is a practical language. The standard includes many examples of practical use. Since Scheme is a lisp, it can be extended to the users’ needs via macros and such. So, while being incredibly simple and small, it does not preclude it from being useful or practical.

CL’s Idea

CL took an entirely different approach. Instead of making a language as a result of picking out fundamentals of earlier languages and ideas, it, in a sense, took many of the previous popular lisps (notably MacLisp, not related to Apple’s Macintosh), and took the good, tested, and popular features from them. A central goal in the design of CL was to make a language that was highly compatible (in terms of features and how things worked) with other lisps. If four out of five lisps had a certain way of doing hash tables, then CL would likely have this feature as well.

As a result, CL ended up being a very large language with the genes of previous lisps highly woven in. The language standard is 1153 pages of printed text (though just about every function described has examples and whatnot). Some people see CL as having an incredible amount of cruft and baggage, others see the extra features (that could otherwise be there with libraries) as means of keeping code consistent and portable.

As one might guess, CL is not a great language for using as a model for studying. But if one is programming to get things done, then it of course is great and practical.

Names



SchemeCommon LispMeaning
mapmapcarApply a function to every element of a list.
definedefun, defparameter, defvarDefine a function (or value).
beginprognExecute a block of “statements” (à la Pascal).
newlineterpriPrint a newline.
set-car!rplacaDestructively set the car of a pair.
pair?conspDetermine if a value is a pair.
string->numberparse-integerConvert a string literal like "123" to a number (integer).

The “informality” and brevity of CL’s choice of many names seems to be a turn-off to many. As it turns out, however, the names of many CL functions are the way they are for a reason. If something is a definitional form, it will almost always begin with def (defun, defmacro, defparameter, defconstant, …). If something is destructive or non-consing, it will likely begin with the letter n (nconc, nreverse, nsubst, …). In contrast, Scheme uses ! to denote destructive operations (set!, reverse!, concatenate!, …).

On a similar note, CL tends to end a function with p if it is a predicate of some sort (characterp, evenp, …) whereas Scheme uses a ? to denote such (char?, even?, …).

Functions and Values
Both languages allow for first class functions. However, in Scheme, functions are “truly” first class in that they have no special treatment. A parameter to a function may also be a function, may be listed, may be called, etc. In CL however, things are different. While function parameters may themselves be functions, they must be used in a different way.

In CL, every symbol may have a function definition, and “value” definition. So one symbol may actually represent several different data.

CL is often called a “Lisp-2″ because it has two primary namespaces for values to exist. Scheme is called a “Lisp-1″ because all values co-exist in a single namespace. In reality, we might actually say CL is a “Lisp-n”, because we actually can have more namespaces, such as for dynamic variables.

Implementations
Everyone and their dog has their own Scheme implementation.


I highly recommend two Schemes: Chicken Scheme for your compiling and interpreting needs (also has a great library system and code repository system), and Chibi Scheme, a standards-strict tiny Scheme suitable for embedding in C applications. There are other good Schemes, but those are what I like most.

The CL implementations are generally known to be standards conforming and usually produce good code. My two favorites are SBCL for general work and very efficient compilation, and CLISP as a very portable system (as it uses its own bytecodes and VM). A nice thing about extensions to the CL language is that they can be delimited in their own namespace (using CL’s packages). In SBCL for example, extensions are in the SB-EXT package.

1/07/2011

Peter Norvig - Teach Yourself Programming in Ten Years

Peter Norvig - Teach Yourself Programming in Ten Years

Learn at least a half dozen programming languages. Include one language that supports class abstractions (like Java or C++), one that supports functional abstraction (like Lisp or ML), one that supports syntactic abstraction (like Lisp), one that supports declarative specifications (like Prolog or C++ templates), one that supports coroutines (like Icon or Scheme), and one that supports parallelism (like Sisal).

* Scheme: Structure and Interpretation of Computer Programs (Abelson & Sussman) is probably the best introduction to computer science, and it does teach programming as a way of understanding the computer science. You can see online videos of lectures on this book, as well as the complete text online. The book is challenging and will weed out some people who perhaps could be successful with another approach.
* Scheme: How to Design Programs (Felleisen et al.) is one of the best books on how to actually design programs in an elegant and functional way.
* Python: Python Programming: An Intro to CS (Zelle) is a good introduction using Python.
* Python: Several online tutorials are available at Python.org.
* Oz: Concepts, Techniques, and Models of Computer Programming (Van Roy & Haridi) is seen by some as the modern-day successor to Abelson & Sussman. It is a tour through the big ideas of programming, covering a wider range than Abelson & Sussman while being perhaps easier to read and follow. It uses a language, Oz, that is not widely known but serves as a basis for learning other languages.

1/03/2011

Performance Calendar » Coding Better Object-Oriented JavaScript with Closure Compiler

Performance Calendar » Coding Better Object-Oriented JavaScript with Closure Compiler


/**
* Helper function that implements (pseudo)Classical inheritance inheritance.
* @see http://www.yuiblog.com/blog/2010/01/06/inheritance-patterns-in-yui-3/
* @param {Function} childClass
* @param {Function} parentClass
*/
function inherits(childClass, parentClass) {
/** @constructor */
var tempClass = function() {
};
tempClass.prototype = parentClass.prototype;
childClass.prototype = new tempClass();
childClass.prototype.constructor = childClass;
}

//////////////////////////////////////////////////////////////////////////////

/**
* The shape
* @constructor
*/
function Shape() {
// No implementation.
}

/**
* Get the size
* @return {number} The size.
*/
Shape.prototype.getSize = function() {
// No implementation.
};

//////////////////////////////////////////////////////////////////////////////

/**
* The Box.
* @param {number} width The width.
* @param {number} height The height.
* @constructor
* @extends {Shape}
*/
function Box(width, height) {
Shape.call(this);

/**
* @private
* @type {number}
*/
this.width_ = width;

/**
* @private
* @type {number}
*/
this.height_ = height;
}
inherits(Box, Shape);

/**
* @return {number} The width.
*/
Box.prototype.getWidth = function() {
return this.width_;
};

/**
* @return {number} The height.
*/
Box.prototype.getHeight = function() {
return this.height_;
};

/** @inheritDoc */
Box.prototype.getSize = function() {
return this.height_ * this.width_;
};

////////////////////////////////////////////////////////////////////////////

/**
* The Box.
* @param {number} width The width.
* @param {number} height The height.
* @param {number} depth The depth.
* @constructor
* @extends {Box}
*/
function Cube(width, height, depth) {
Box.call(this, width, height);

/**
* @private
* @type {number}
*/
this.depth_ = depth;
}
inherits(Cube, Box);

/**
* @return {number} The width.
*/
Cube.prototype.getDepth = function() {
return this.depth_;
};

/** @inheritDoc */
Cube.prototype.getSize = function() {
return this.depth_ * this.getHeight() * this.getWidth();
};

////////////////////////////////////////////////////////////////////////////

var cube = new Cube(3, 6, 9);
document.write(cube.getSize().toString());



// skip example code.

////////////////////////////////////////////////////////////////////////////

/**
* The shape
* @interface
*/
function Shape() {
}

/**
* Get the size
* @return {number} The size.
*/
Shape.prototype.getSize = function() {};

////////////////////////////////////////////////////////////////////////////

/**
* The Box.
* @param {number} width The width.
* @param {number} height The height.
* @constructor
* @implements {Shape}
*/
function Box(width, height) {
Shape.call(this);

/**
* @private
* @type {number}
*/
this.width_ = width;

/**
* @private
* @type {number}
*/
this.height_ = height;
}

/**
* @return {number} The width.
*/
Box.prototype.getWidth = function() {
return this.width_;
};

// skip example code