<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6419924689110079275</id><updated>2011-11-27T16:15:03.934-08:00</updated><category term='ruby'/><category term='State'/><category term='rmi'/><category term='WTP'/><category term='syntax-rules'/><category term='C'/><category term='classpath'/><category term='blank'/><category term='Windows'/><category term='Lisp'/><category term='prolog'/><category term='C++'/><category term='type checking'/><category term='console'/><category term='values'/><category term='overriding'/><category term='locate'/><category term='python'/><category term='shell'/><category term='DSL'/><category term='hiding'/><category term='function'/><category term='class'/><category term='define-syntax'/><category term='effective java'/><category term='file.encoding'/><category term='macro'/><category term='Scheme'/><category term='generator'/><category term='assert'/><category term='enum'/><category term='variable'/><category term='consult'/><category term='java'/><category term='taocp'/><category term='cygwin'/><category term='process'/><category term='scope'/><category term='bash'/><category term='font'/><category term='Tomcat'/><category term='access control'/><category term='TeX: The Program'/><category term='Head First Design Patterns'/><category term='updatedb'/><category term='subroutine pointer'/><category term='iterator'/><category term='Icon'/><category term='linking'/><category term='closure'/><category term='Eclipse'/><category term='Design Pattern'/><category term='SWI-Prolog'/><category term='working directory'/><category term='equals'/><category term='rmiregistry'/><category term='valueOf'/><title type='text'>Programming with Passsion</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-7003763753496380086</id><published>2009-05-04T07:52:00.000-07:00</published><updated>2009-05-04T07:59:00.494-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='taocp'/><title type='text'>Begin to Read The Art of Computer Programming</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0mOaQyA-BaM/Sf8Byqp1kqI/AAAAAAAAAE8/JxUlXflR9yo/s1600-h/taocp_1-3.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 396px; height: 400px;" src="http://1.bp.blogspot.com/_0mOaQyA-BaM/Sf8Byqp1kqI/AAAAAAAAAE8/JxUlXflR9yo/s400/taocp_1-3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5331982453784810146" /&gt;&lt;/a&gt;&lt;br /&gt;I baugh the book more than one year ago. Due to busy development work and other stuff to learn, I have not read it. Now it is time for me to read this great book. I will write notes when reading it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-7003763753496380086?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/7003763753496380086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=7003763753496380086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7003763753496380086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7003763753496380086'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/05/begin-to-read-art-of-computer.html' title='Begin to Read The Art of Computer Programming'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0mOaQyA-BaM/Sf8Byqp1kqI/AAAAAAAAAE8/JxUlXflR9yo/s72-c/taocp_1-3.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8967334710293554536</id><published>2009-05-04T03:01:00.000-07:00</published><updated>2009-05-04T03:02:09.132-07:00</updated><title type='text'>Reading of Programming Language Pragmatics</title><content type='html'>After more than a year, I have finally finished reading PLP 2e. It is a wonderful book. Every programmer who want a complete and deep of programming language theory should read it. It teaches you compiler techniques. But unlike the dragon book which is for writing compilers, it teaches you the compiler concepts.&lt;br /&gt;&lt;br /&gt;The book is written by Miachael Scott who is academic. I like his writing style, succint and precise. For one sentence of his writing, I often need a page to describe it. After his writing has a academic flavor, it is easy for non-academics to understand.&lt;br /&gt;&lt;br /&gt;But there are two problems with this book. Only an instructor using this book can obtain the solutions to the exercises in the book. As a software professional outside of schools, I am not entitled to get these solutions. It is really frustrated if I can't solve one exercise and can't get the solution provided by the author. As a result, I did not do the exercises in the book.&lt;br /&gt;&lt;br /&gt;The other problem is that the author often mention some technique in a short sentence. I often need some considerable time to understand the sentence because I am teaching myself.&lt;br /&gt;&lt;br /&gt;During the reading of this book, I find some bugs of the book. I have emailed to the author. The author has listed these bugs in the errdata page.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8967334710293554536?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8967334710293554536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8967334710293554536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8967334710293554536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8967334710293554536'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/05/reading-of-programming-language.html' title='Reading of Programming Language Pragmatics'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-575684944003477956</id><published>2009-05-03T05:18:00.001-07:00</published><updated>2009-05-03T05:22:04.264-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Seeking in PrintStream</title><content type='html'>I played with maven today. I found the following output message when maven is downloading something. The &lt;tt&gt;xxx&lt;/tt&gt; changes to indicate the download progress.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;xxx/yyyK&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I am curious about how this is done. As far as I know, &lt;tt&gt;System.out&lt;/tt&gt; is &lt;tt&gt;PrintStream&lt;/tt&gt;. In &lt;tt&gt;PrintStream&lt;/tt&gt;, there is no method to seek. I searched for the answer on the web. Unfortunately, I can't find the answer. I downloaded the maven source code. After some browsing, I found that printing &lt;tt&gt;\r&lt;/tt&gt; will position the following printings at the beginning of a line. The following Java code shows how it is done.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;import java.io.PrintStream;&lt;br /&gt;&lt;br /&gt;public class Print {&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        PrintStream ps = System.out;        &lt;br /&gt;        ps.print("100");&lt;br /&gt;        sleep2s();&lt;br /&gt;        ps.print("\r200");&lt;br /&gt;        sleep2s();&lt;br /&gt;        ps.print("\r300");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void sleep2s() {&lt;br /&gt;        try {&lt;br /&gt;            Thread.sleep(2 * 2000);&lt;br /&gt;        } catch (InterruptedException ie) {&lt;br /&gt;            throw new RuntimeException(ie);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I think that Javadoc should have documented this kind of usage, which can save developers a lot of time to scratch their heads.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-575684944003477956?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/575684944003477956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=575684944003477956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/575684944003477956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/575684944003477956'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/05/seeking-in-printstream.html' title='Seeking in PrintStream'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-844056058884289157</id><published>2009-04-17T22:32:00.000-07:00</published><updated>2009-04-17T22:34:27.976-07:00</updated><title type='text'>Install PHP 5.2.9-2 (Windows)</title><content type='html'>I have already had Apache 2.2 installed.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Download php-5.2.9-2-Win32.zip. Extract it to &lt;i&gt;C:/free/php&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make a copy of &lt;i&gt;php.ini-dist&lt;/i&gt; and rename it to &lt;i&gt;php.ini&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Add the following text to &lt;i&gt;C:/free/Apache2.2/conf/httpd.conf&lt;/i&gt; &lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;#load the php main library to avoid dll hell&lt;br /&gt;Loadfile "C:/free/php/php5ts.dll"&lt;br /&gt;&lt;br /&gt;#load the sapi so that apache can use php&lt;br /&gt;LoadModule php5_module "C:/free/php/php5apache2_2.dll"&lt;br /&gt;&lt;br /&gt;#set the php.ini location so that you don't have to waste time guessing where it is&lt;br /&gt;PHPIniDir "C:/free/php"&lt;br /&gt;&lt;br /&gt;#Hook the php file extensions, notice that Addtype is NOT USED, since that's just stupid&lt;br /&gt;AddHandler application/x-httpd-php .php&lt;br /&gt;AddHandler application/x-httpd-php-source .phps&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-844056058884289157?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/844056058884289157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=844056058884289157' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/844056058884289157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/844056058884289157'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/04/install-php-529-2-windows.html' title='Install PHP 5.2.9-2 (Windows)'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-5434590496906952064</id><published>2009-04-16T00:42:00.000-07:00</published><updated>2009-04-16T00:43:36.702-07:00</updated><title type='text'>Opening PDF files within Firefox</title><content type='html'>I can't open pdf files side Firefox recently. I am using Firefox 3 on Windows XP.&lt;br /&gt;&lt;br /&gt;After done some googling, I found &lt;br /&gt;&lt;a href="http://support.mozilla.com/en-US/kb/opening+PDF+files+within+Firefox"&gt;Opening PDF files within Firefox&lt;/a&gt; which provides a complete solution of this problem. The following method works for me.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   1. Close Firefox.&lt;br /&gt;   2. Navigate to my Firefox profile folder.&lt;br /&gt;   3. Delete the mimetypes.rdf file.&lt;br /&gt;   4. Restart Firefox.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For how to find profile folder, refer to to &lt;a href="http://support.mozilla.com/en-US/kb/Profiles#How_to_find_your_profile"&gt;How to find your profile&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-5434590496906952064?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/5434590496906952064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=5434590496906952064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5434590496906952064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5434590496906952064'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/04/opening-pdf-files-within-firefox.html' title='Opening PDF files within Firefox'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-1677665129788396080</id><published>2009-04-13T08:35:00.000-07:00</published><updated>2009-04-13T08:47:54.110-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp'/><title type='text'>Handle Multi-key to One-value Property File</title><content type='html'>One of my friend asked how to implement a configuration file which contains key to value mappings. One special thing is that multiple keys are mapped to one value. If Java property is used, the following text shows the property file.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# [v1]&lt;br /&gt;K11=v1&lt;br /&gt;K12=v1&lt;br /&gt;K13=v1&lt;br /&gt;&lt;br /&gt;# [v2]&lt;br /&gt;K21=v2&lt;br /&gt;K22=v2&lt;br /&gt;K23=v2&lt;br /&gt;&lt;br /&gt;# [v2]&lt;br /&gt;K31=v3&lt;br /&gt;K32=v3&lt;br /&gt;K33=v3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It contains a lot of duplications. &lt;tt&gt;v1&lt;/tt&gt;, &lt;tt&gt;v2&lt;/tt&gt; and &lt;tt&gt;v3&lt;/tt&gt; appears many times in the property file. DIY (Don't Repeat Yourself) principle is violated. One improvement is to write the following property file:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# [v1]&lt;br /&gt;K11,K12,K13 = v1&lt;br /&gt;&lt;br /&gt;# [v2]&lt;br /&gt;K21, K22, K23 = v2&lt;br /&gt;&lt;br /&gt;# [v2]&lt;br /&gt;K31, K32, K33 = v3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For this property file, I need to write additional code. The following steps are one option:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;   &lt;li&gt;get the entry set from the property file&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;create a hash map&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;iterate over the entry set. &lt;tt&gt;k&lt;/tt&gt; is the map entry key, &lt;tt&gt;v&lt;/tt&gt; is the map entry value&lt;/li&gt;&lt;br /&gt;   &lt;ul&gt;&lt;br /&gt;       &lt;li&gt;split the iterated &lt;tt&gt;k&lt;/tt&gt; with &lt;i&gt;,&lt;/i&gt; into key[]&lt;/li&gt;&lt;br /&gt;       &lt;li&gt;add (key[0], v), (key[1], v), ... to the hash map&lt;/li&gt;&lt;br /&gt;   &lt;/ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;After the above steps done, the hash map can be used to get a value for a given key. There still one problem. The property file and the Java code are separated. Then I thought about Scheme. Here is the solution in Scheme. It is tested on DrScheme, version 4.1.4.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#lang scheme&lt;br /&gt;(define (find-value k)&lt;br /&gt;   (let* ([ks2v '(&lt;br /&gt;&lt;br /&gt;; multi-key to one-value mappings&lt;br /&gt;((K11 K12 K13) V1)&lt;br /&gt;((K21 K22 K23 K24) V2)&lt;br /&gt;((K31 K32 K33 K34) V3)&lt;br /&gt;&lt;br /&gt;                 )]&lt;br /&gt;         [contain? (lambda (k keys)&lt;br /&gt;                (let ([equal2k? (lambda (a) (equal? k a))])&lt;br /&gt;                  (ormap equal2k? keys)))]&lt;br /&gt;         [k2v (lambda (pair)&lt;br /&gt;                 (if (contain? k (car pair))&lt;br /&gt;                     (cadr pair)&lt;br /&gt;                     #f))])&lt;br /&gt;     (ormap k2v ks2v)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This solution is elegant. &lt;i&gt;Code as data&lt;/i&gt; characteristic of Scheme makes such kind of solutions possible. And when I was coding this solution, I had the same feeling as the quote &lt;i&gt;SQL, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-1677665129788396080?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/1677665129788396080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=1677665129788396080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/1677665129788396080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/1677665129788396080'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/04/handle-multi-key-to-one-value-property.html' title='Handle Multi-key to One-value Property File'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4422963235447692861</id><published>2009-04-08T07:46:00.000-07:00</published><updated>2009-04-08T08:18:24.634-07:00</updated><title type='text'>Disable Translating Chinese Character into Character Entities in Tidy and Xmllint</title><content type='html'>For Tidy, set &lt;tt&gt;char-encoding&lt;/tt&gt; to &lt;tt&gt;raw&lt;/tt&gt;. The following text is my setting.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;tidy -q --char-encoding raw -indent --show-warnings n --tidy-mark n -w 80&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For xmllint, set &lt;tt&gt;encode&lt;/tt&gt; to UTF-8 (The encoding of my XML files is UTF-8). Here is my xmllint setting.&lt;br /&gt;&lt;pre&gt;xmllint --encode UTF-8 --format&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4422963235447692861?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4422963235447692861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4422963235447692861' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4422963235447692861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4422963235447692861'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/04/disable-translating-chinese-character.html' title='Disable Translating Chinese Character into Character Entities in Tidy and Xmllint'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-5283045837154688650</id><published>2009-04-06T05:38:00.000-07:00</published><updated>2009-04-06T05:45:56.153-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><title type='text'>Building DSL with Scheme</title><content type='html'>I have listened a talk made by &lt;a href="http://www.cs.brown.edu/~sk/"&gt;Shriram Krishnamurthi&lt;/a&gt;. It is called &lt;a href="http://www.cs.brown.edu/~sk/Publications/Talks/SwineBeforePerl/"&gt;The Swine Before Perl &lt;/a&gt;. The talk is about using scheme to do heavy lifting which other languages can't handle. It is a great talk. It shows me the real amazing strength of Scheme programming language. Shriram centers his talk around an example of automaton. The Scheme source code is based on the old version of PLT Scheme. As a result, the source code can't run against the current implementation. I have made a little change to the source code. I post it here for reference.&lt;br /&gt;&lt;br /&gt;The following source code is tested in DrScheme, version 4.1.4. &lt;br /&gt;The first version of automaton.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#lang slideshow&lt;br /&gt;(define b-machine-states&lt;br /&gt;  '((init (c more))&lt;br /&gt;    (more (a more)&lt;br /&gt;          (d more)&lt;br /&gt;          (r end))&lt;br /&gt;    (end (r end))))&lt;br /&gt;&lt;br /&gt;(define (b-machine stream)&lt;br /&gt;  (letrec ([walker (lambda (state stream)&lt;br /&gt;                     (or (empty? stream)&lt;br /&gt;                         (let ([transitions&lt;br /&gt;                                 (cdr (assv state b-machine-states))])&lt;br /&gt;                           (let ([1st (first stream)])&lt;br /&gt;                             (let ([new-state (assv 1st transitions)])&lt;br /&gt;                               (if new-state&lt;br /&gt;                                 (walker (cadr new-state) (rest stream))&lt;br /&gt;                                 false))))))])&lt;br /&gt;    (walker 'init stream)))&lt;br /&gt;&lt;br /&gt;(b-machine '(c a r))&lt;br /&gt;(b-machine '(c a d r))&lt;br /&gt;(b-machine '(c a x))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The goto version of automaton.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#lang scheme&lt;br /&gt;(define b-machine&lt;br /&gt;  (letrec ([init&lt;br /&gt;             (lambda (stream)&lt;br /&gt;               (or (empty? stream)&lt;br /&gt;                   (case (first stream)&lt;br /&gt;                     [(c) (more (rest stream))]&lt;br /&gt;                     [else false])))]&lt;br /&gt;           [more&lt;br /&gt;             (lambda (stream)&lt;br /&gt;               (or (empty? stream)&lt;br /&gt;                   (case (first stream)&lt;br /&gt;                     [(a) (more (rest stream))]&lt;br /&gt;                     [(d) (more (rest stream))]&lt;br /&gt;                     [(r) (end (rest stream))]&lt;br /&gt;                     [else false])))]&lt;br /&gt;           [end&lt;br /&gt;             (lambda (stream)&lt;br /&gt;               (or (empty? stream)&lt;br /&gt;                   (case (first stream)&lt;br /&gt;                     [(r) (end (rest stream))]&lt;br /&gt;                     [else false])))])&lt;br /&gt;    init))&lt;br /&gt;&lt;br /&gt;(b-machine '(c a r))&lt;br /&gt;(b-machine '(c a d r))&lt;br /&gt;(b-machine '(c a x))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The second version of automaton.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#lang scheme&lt;br /&gt;(define-syntax automaton&lt;br /&gt;  (syntax-rules (-&gt; :)&lt;br /&gt;                [(_ init-state&lt;br /&gt;                    (state : (cndn -&gt; new-state) ...)&lt;br /&gt;                    ...)&lt;br /&gt;                 (letrec ([state&lt;br /&gt;                            (lambda (stream)&lt;br /&gt;                              (or (empty? stream)&lt;br /&gt;                                  (case (first stream)&lt;br /&gt;                                    [cndn (new-state (rest stream))]&lt;br /&gt;                                    ...&lt;br /&gt;                                    [else false])))]&lt;br /&gt;                          ...)&lt;br /&gt;                   init-state)]))&lt;br /&gt;&lt;br /&gt;(define b-machine &lt;br /&gt;  (automaton init&lt;br /&gt;             (init : ((c) -&gt; more))&lt;br /&gt;             (more : ((a) -&gt; more)&lt;br /&gt;                     ((d) -&gt; more)&lt;br /&gt;                     ((r) -&gt; end))&lt;br /&gt;             (end  : ((r) -&gt; end))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(b-machine '(c a r))&lt;br /&gt;(b-machine '(c a d r))&lt;br /&gt;(b-machine '(c a x))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following code is really an elegant DSL for automaon.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(automaton init&lt;br /&gt;     (init : ((c) -&gt; more))&lt;br /&gt;     (more : ((a) -&gt; more)&lt;br /&gt;             ((d) -&gt; more)&lt;br /&gt;             ((r) -&gt; end))&lt;br /&gt;     (end  : ((r) -&gt; end)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I have also implemented the first and goto version of automaton in Ruby.&lt;br /&gt;The first version of automaton in Ruby&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;$b_machine_states = {&lt;br /&gt;  "init" =&gt; {"c" =&gt; "more"},&lt;br /&gt;  "more" =&gt; {"a" =&gt; "more",&lt;br /&gt;             "d" =&gt; "more",&lt;br /&gt;             "r" =&gt; "end"},&lt;br /&gt;  "end" =&gt; {"r" =&gt; "end"}}&lt;br /&gt;&lt;br /&gt;def walker(state, stream)&lt;br /&gt;  if stream.empty?&lt;br /&gt;    return true&lt;br /&gt;  end&lt;br /&gt;  first = stream[0]&lt;br /&gt;  transitions = $b_machine_states[state]&lt;br /&gt;  new_state = transitions[first]&lt;br /&gt;  if new_state == nil&lt;br /&gt;    return false&lt;br /&gt;  else&lt;br /&gt;    rest = stream[1, stream.length()]&lt;br /&gt;    return walker(new_state, rest)&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def b_machine(stream)&lt;br /&gt;  walker("init", stream)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;print b_machine("car") , "\n"&lt;br /&gt;print b_machine("cadr") , "\n"&lt;br /&gt;print b_machine("cax") , "\n"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The goto version of automaton in Ruby&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class Automaton&lt;br /&gt;  &lt;br /&gt;  def accept(stream)&lt;br /&gt;    return init(stream)&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  private&lt;br /&gt;  def init(stream)&lt;br /&gt;    if stream.empty?&lt;br /&gt;      return true&lt;br /&gt;    end&lt;br /&gt;    first = stream[0]&lt;br /&gt;    case first&lt;br /&gt;    when "c"&lt;br /&gt;      return more(rest(stream))&lt;br /&gt;    else&lt;br /&gt;      false&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def more(stream)&lt;br /&gt;    if stream.empty?&lt;br /&gt;      return true&lt;br /&gt;    end&lt;br /&gt;    first = stream[0]&lt;br /&gt;    case first&lt;br /&gt;    when "a"&lt;br /&gt;      return more(rest(stream))&lt;br /&gt;    when "d"&lt;br /&gt;      return more(rest(stream))&lt;br /&gt;    when "r"&lt;br /&gt;      return terminate(rest(stream))&lt;br /&gt;    else&lt;br /&gt;      return false&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def terminate(stream)&lt;br /&gt;    if stream.empty?&lt;br /&gt;      return true&lt;br /&gt;    end&lt;br /&gt;    first = stream[0]&lt;br /&gt;    case first&lt;br /&gt;    when "r"&lt;br /&gt;      return terminate(rest(stream))&lt;br /&gt;    else&lt;br /&gt;      return false&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def rest(stream)&lt;br /&gt;    return stream[1, stream.length()]&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;auto = Automaton.new()&lt;br /&gt;print auto.accept("car") , "\n"&lt;br /&gt;print auto.accept("cadr") , "\n"&lt;br /&gt;print auto.accept("cax"), "\n"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the second version of automaton, I can't find a way to implement it in Ruby because Ruby does not have a macro system similar to Scheme. I am happy to know if anyone has a solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-5283045837154688650?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/5283045837154688650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=5283045837154688650' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5283045837154688650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5283045837154688650'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/04/building-dsl-with-scheme.html' title='Building DSL with Scheme'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-2781407027340521083</id><published>2009-03-16T06:34:00.000-07:00</published><updated>2009-03-16T06:54:07.619-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='font'/><category scheme='http://www.blogger.com/atom/ns#' term='console'/><title type='text'>Add Fonts to Windows Command Line Console</title><content type='html'>By default, the command line console only has two fonts for Windows XP Simple Chinese version. They are &lt;tt&gt;Roster Font&lt;/tt&gt; and &lt;tt&gt;Lucida Console&lt;/tt&gt;. I am unhappy with them. I like &lt;tt&gt;Consolas&lt;/tt&gt; and &lt;tt&gt;Bitstream Vera Sans Mono&lt;/tt&gt; for command line. So I decided to add these fonts to the command line console. I have done it following &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q247815"&gt;Necessary criteria for fonts to be available in a command window&lt;/a&gt;. I have added two registry values as shown in the following registry file.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Windows Registry Editor Version 5.00&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont]&lt;br /&gt;"00"="Consolas"&lt;br /&gt;"000"="Bitstream Vera Sans Mono"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The machine needs to be restarted after adding these stuff to registry. And I need to set the current code page to 437 in &lt;tt&gt;Option&lt;/tt&gt; tab of the command line console shortcut if I want to select &lt;tt&gt;Consolas&lt;/tt&gt; and &lt;tt&gt;Bitstream Vesa Sans Mono&lt;/tt&gt;. The code page 936 does not work for these 2 fonts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-2781407027340521083?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/2781407027340521083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=2781407027340521083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2781407027340521083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2781407027340521083'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/03/add-fonts-to-windows-command-line.html' title='Add Fonts to Windows Command Line Console'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-7476115211881535118</id><published>2009-02-27T05:11:00.000-08:00</published><updated>2009-02-27T17:06:48.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='closure'/><category scheme='http://www.blogger.com/atom/ns#' term='subroutine pointer'/><title type='text'>Subroutine Pointer in C</title><content type='html'>C has subroutine pointers. It does not require closures because it does not have nested scopes and it is static scoped. Every subroutine is at global scope. As a result, the referencing environment for a subroutine is the same whether it is created when the subroutine is first passed a parameter or when the subroutine is finally called. In the following code, &lt;tt&gt;plus_one&lt;/tt&gt; has the same referencing environment whether the referencing environment is created when it is passed as a parameter to &lt;tt&gt;caller&lt;/tt&gt; or when it is called in &lt;tt&gt;caller&lt;/tt&gt;.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;int plus_one(int n) {&lt;br /&gt;    return n + 1;&lt;br /&gt;}&lt;br /&gt;void caller(int (*f) (int)) {&lt;br /&gt;    int result = f(3);&lt;br /&gt;    printf("3 plus 1 is %d\n", result);&lt;br /&gt;}&lt;br /&gt;int main() {&lt;br /&gt;    caller(plus_one);&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For a language which supports nested scope, the situation is different. In the following Common Lisp code, a closure must be created for &lt;tt&gt;plus_2&lt;/tt&gt; to make it a function which addes 2 to its sole parameter.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;(let ((one 1))&lt;br /&gt;  (defun plus_1 (x)&lt;br /&gt;     (+ x one)))&lt;br /&gt;&lt;br /&gt;(let ((one 5))&lt;br /&gt;  (plus_1 3))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-7476115211881535118?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/7476115211881535118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=7476115211881535118' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7476115211881535118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7476115211881535118'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/subroutine-pointer-in-c.html' title='Subroutine Pointer in C'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8070341298030527748</id><published>2009-02-26T06:50:00.000-08:00</published><updated>2009-02-26T06:51:15.569-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scope'/><category scheme='http://www.blogger.com/atom/ns#' term='Lisp'/><title type='text'>Dynamic Scope in LISP</title><content type='html'>The following program will print &lt;tt&gt;(3 5)&lt;/tt&gt; in newlisp which is dynamic scoped. But it will print &lt;tt&gt;(3 7)&lt;/tt&gt; in CLISP which is static scoped.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(let ((y 7)) (define (scope-test x) (list x y)))&lt;br /&gt;(let ((y 5)) (scope-test 3))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8070341298030527748?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8070341298030527748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8070341298030527748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8070341298030527748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8070341298030527748'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/dynamic-scope-in-lisp.html' title='Dynamic Scope in LISP'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8030834329834239878</id><published>2009-02-22T05:17:00.000-08:00</published><updated>2009-02-22T05:55:03.993-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='file.encoding'/><title type='text'>Java's file.encoding property on Windows platfor</title><content type='html'>This property is used for the default encoding in Java, all readers and writers would default to using this property. file.encoding is set to the default locale of Windows operationg system since Java 1.4.2. &lt;tt&gt;System.getProperty("file.encoding")&lt;/tt&gt; can be used to access this property. Code such as &lt;tt&gt;System.setProperty("file.encoding", "UTF-8")&lt;/tt&gt; can be used to change this property. However, the default encoding can be not changed dynamically even this property can be changed. So the conclusion is that the default encoding can't change after JVM starts. &lt;tt&gt;java -dfile.encoding=UTF-8&lt;/tt&gt; can be used to set the default encoding when starting a JVM. I have searched for this option Java official documentation. But I can't find it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8030834329834239878?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8030834329834239878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8030834329834239878' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8030834329834239878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8030834329834239878'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/javas-fileencoding-property-on-windows.html' title='Java&apos;s file.encoding property on Windows platfor'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4380216305353776480</id><published>2009-02-17T06:11:00.000-08:00</published><updated>2009-02-17T06:38:17.561-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TeX: The Program'/><title type='text'>Produce the "TeX: The Program" from tex.web</title><content type='html'>This is how I have produced the &lt;i&gt;TeX: The Program&lt;/i&gt; from tex.web&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Install the full package of MikTex 2.7&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Get tex.web from &lt;a href="http://www.tug.org/svn/texlive/trunk/Build/source/texk/web2c/tex.web"&gt;http://www.tug.org/svn/texlive/trunk/Build/source/texk/web2c/tex.web&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Place tex.web in &lt;i&gt;D:/book&lt;/i&gt;. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Open a command console. Change directory to &lt;i&gt;D:/book&lt;/i&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make a empty file &lt;i&gt;change-file&lt;/i&gt; in the current directory.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Run "weave tex.web change-file program.tex".&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Run "pdfTex program"&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;The result is a PDF file &lt;i&gt;program.pdf&lt;/i&gt; and CONTENTS.tex. These files are the book.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4380216305353776480?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4380216305353776480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4380216305353776480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4380216305353776480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4380216305353776480'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/produce-tex-program-from-texweb.html' title='Produce the &quot;TeX: The Program&quot; from tex.web'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4875577172525598988</id><published>2009-02-09T02:00:00.000-08:00</published><updated>2009-02-11T04:34:12.146-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SWI-Prolog'/><category scheme='http://www.blogger.com/atom/ns#' term='consult'/><category scheme='http://www.blogger.com/atom/ns#' term='assert'/><category scheme='http://www.blogger.com/atom/ns#' term='prolog'/><title type='text'>A Quick Start of SWI-Prolog for Windows</title><content type='html'>Recently, I have been reading chapter 12 of Programming Language Pragmatics. This chapter is about logic programming. So I need a prolog implementation to try the code in the book. I choose SWI-Prolog. SWI-Prolog has a thorough reference manual. But what I want is only some quick start. After searching on Google, I don't find a decent SWI-Prolog quick start. So I have to do my work by scanning the reference book. It is kind of painful. Here, I write down what I think it is enough to do some simple things with SWI-Prolog, hoping that it will help you if you only do some simple things with SWI-Prolog.&lt;br /&gt;&lt;br /&gt;My platform is Windows. After the installation of SWI-Prolog, add the SWI-Prolog bin directory to PATH environment varialbe. In my case, the bin directory is &lt;i&gt;C:\Program Files\pl\bin&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;SWI-Prolog has a &lt;i&gt;plwin.exe&lt;/i&gt; which is GUI environment for SWI-Prolog. I prefer to use the SWI-Prolog console environment which is plcon. &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;Open a command line&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;change to directory containing my prolog source code. In my case, it is &lt;i&gt;D:\documents\Prolog&lt;/i&gt;.&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;type &lt;i&gt;plcon&lt;/i&gt; to launch prolog&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Now the command console looks as follows.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;D:\Documents\Prolog&gt;plcon&lt;br /&gt;Welcome to SWI-Prolog (Multi-threaded, 32 bits, Version 5.6.64)&lt;br /&gt;Copyright (c) 1990-2008 University of Amsterdam.&lt;br /&gt;SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,&lt;br /&gt;and you are welcome to redistribute it under certain conditions.&lt;br /&gt;Please visit http://www.swi-prolog.org for details.&lt;br /&gt;&lt;br /&gt;For help, use ?- help(Topic). or ?- apropos(Word).&lt;br /&gt;&lt;br /&gt;1 ?- consult(woman).&lt;br /&gt;% woman compiled 0.00 sec, 1,060 bytes&lt;br /&gt;true.&lt;br /&gt;&lt;br /&gt;2 ?-&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Type &lt;tt&gt;consult(women)&lt;/tt&gt; to load &lt;i&gt;D:\documents\Prolog\women.pro&lt;/i&gt;. It contains the following clauses. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;:-dynamic pregnant/.&lt;br /&gt;human(susan).&lt;br /&gt;human(jane).&lt;br /&gt;pregnant(susan).&lt;br /&gt;woman(X) :- pregnant(X), human(X).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Assert can only be used to add facts to dynamic predicates in the prolog interpreter. I want to add facts for predicate &lt;tt&gt;pregnant&lt;/tt&gt;. So I add the dynamic directive in the prolog source code. &lt;tt&gt;pregnant/1&lt;/tt&gt; is a predicator indicator. A predicate indicator is used to denote predicates. It's form is Name/Arity where Name is an atom denoting the name of a predicate and Arity is a integer denoting the number of its arguments.  Add one fact to the prolog clause databse. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;2 ?- assert(pregnant(jane)).&lt;br /&gt;true.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Issue a query. Type &lt;tt&gt;;&lt;/tt&gt; to ask for more answers.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;3 ?- woman(X).&lt;br /&gt;X = susan ;&lt;br /&gt;X = jane.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Type &lt;tt&gt;halt.&lt;/tt&gt; to exit SWI-Prolog&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;4 ?- halt.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4875577172525598988?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4875577172525598988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4875577172525598988' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4875577172525598988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4875577172525598988'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/quick-start-of-swi-prolog.html' title='A Quick Start of SWI-Prolog for Windows'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8791995685714816087</id><published>2009-02-08T06:36:00.000-08:00</published><updated>2009-02-08T07:24:03.540-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iterator'/><category scheme='http://www.blogger.com/atom/ns#' term='Icon'/><title type='text'>Iterator in Icon</title><content type='html'>In Icon programming language, iterator is very powerful. As a result, &lt;a href="http://www.cs.rochester.edu/~scott/pragmatics/"&gt;Programming Language Pragmatics&lt;/a&gt; dedicates a sub section to explain it. The following shows the complete running code corresponding to the code snippets in the book.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;procedure main()&lt;br /&gt; write("=================================================")&lt;br /&gt; every i := 1 to 10 by 2 do {&lt;br /&gt;  write(i)&lt;br /&gt; }&lt;br /&gt; write("=================================================")&lt;br /&gt; every i := 1 + upto(' ', "a ss ss") do {&lt;br /&gt;  write(i)&lt;br /&gt; }&lt;br /&gt; write("=================================================")&lt;br /&gt; i := 1&lt;br /&gt; every write(i + upto(' ', "a ss ss"))&lt;br /&gt; write("=================================================")&lt;br /&gt; if 2 &lt; 3 then {&lt;br /&gt;  write("2 &lt; 3")&lt;br /&gt; }&lt;br /&gt; write("=================================================")&lt;br /&gt; if (i := find("abc", "abcabcabc")) &gt; 6 then {&lt;br /&gt;  write(i)&lt;br /&gt; }&lt;br /&gt; write("=================================================")&lt;br /&gt; if (i := find("x", "xaax")) = find("x", "bxxx") then {&lt;br /&gt;  write(i)&lt;br /&gt; } &lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following code explains the description at the end of the sub section. It is &lt;tt&gt;If the expression following suspend contains an invocation of a generator, then the subroutine will suspend repeatedly, once for each generated value.&lt;/tt&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# suspend is followed by a value&lt;br /&gt;procedure FollowedByValue()&lt;br /&gt; i := 1&lt;br /&gt; while i &lt;= 3 do {&lt;br /&gt;  suspend i&lt;br /&gt;        i +:= 1&lt;br /&gt; }&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# suspend is followed by a generator expression&lt;br /&gt;procedure FollowedByGenExpr()&lt;br /&gt; suspend(1|2|3)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# suspend is followed by a generator function invocation&lt;br /&gt;procedure FollowedByGenFuncInvocation()&lt;br /&gt; suspend FollowedByValue() &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;procedure main()&lt;br /&gt; write("=================================================")&lt;br /&gt; every write(FollowedByValue())&lt;br /&gt; write("=================================================")&lt;br /&gt; every write(FollowedByGenExpr())&lt;br /&gt; write("=================================================")&lt;br /&gt; every write(FollowedByGenFuncInvocation())&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8791995685714816087?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8791995685714816087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8791995685714816087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8791995685714816087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8791995685714816087'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/iterator-in-icon.html' title='Iterator in Icon'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4197862013449038560</id><published>2009-02-08T02:41:00.000-08:00</published><updated>2009-02-08T06:36:12.348-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='iterator'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='generator'/><title type='text'>Iterator in Ruby and Python</title><content type='html'>Unlike Java, both languages support real iterator not just iterator object. The following code shows how to create and use iterator in Python.&lt;br /&gt;&lt;pre class="prettyprint lang-py"&gt;&lt;br /&gt;def from_1_to_5():&lt;br /&gt;  for i in [1, 2, 3, 4, 5]:&lt;br /&gt;    yield i&lt;br /&gt;&lt;br /&gt;for num in from_1_to_5():&lt;br /&gt;  print num&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The following code shows how to make it in Ruby. Desides a style similar to Python, Ruby can use iterator with block.&lt;br /&gt;&lt;pre class="prettyprint lang-rb"&gt;&lt;br /&gt;def iterator&lt;br /&gt;  for i in [1, 2, 3, 4, 5]&lt;br /&gt;    yield(i)&lt;br /&gt;  end &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# invoke iterator in a way similar to Python&lt;br /&gt;call_block do |num|&lt;br /&gt;  puts "#{num}"&lt;br /&gt;end&lt;br /&gt;  &lt;br /&gt;# invoke iterator with the use of block &lt;br /&gt;call_block { |num| puts "#{num}" }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4197862013449038560?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4197862013449038560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4197862013449038560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4197862013449038560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4197862013449038560'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/02/iterator-in-ruby-and-python.html' title='Iterator in Ruby and Python'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-3952460639480275558</id><published>2009-01-22T18:42:00.000-08:00</published><updated>2009-01-22T18:50:38.560-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp'/><title type='text'>Accumulator Generator in Common Lisp</title><content type='html'>The following code  helps me understand Accumulator Generator in Common Lisp. I am still not used to lisp's true meaning. I often need to struggle to understand a little piece of lisp code. So I write down the code.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun foo (n) (lambda (i) (incf n i)))&lt;br /&gt;(setq starting 10)&lt;br /&gt;(setq acc (foo starting))&lt;br /&gt;(funcall acc 1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For a complete description of Accumulator Generator, refer to &lt;a href="http://www.paulgraham.com/accgen.html"&gt;Accumulator Generator&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-3952460639480275558?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/3952460639480275558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=3952460639480275558' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/3952460639480275558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/3952460639480275558'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/01/accumulator-generator-in-common-lisp.html' title='Accumulator Generator in Common Lisp'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-2148941281773768393</id><published>2009-01-21T01:09:00.000-08:00</published><updated>2009-01-21T01:33:57.944-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='define-syntax'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax-rules'/><title type='text'>"define-syntax" and "syntax-rules" in Scheme</title><content type='html'>Scheme has a macro mechanism which allow us to extend the Scheme language syntax. The description in &lt;i&gt;Revised5 Report on the Algorithmic Language Scheme&lt;/i&gt; is precise. But the description has a mathematical flavor.&lt;br /&gt;&lt;br /&gt;I refer to the book &lt;tt&gt;The Scheme Programming Language&lt;/tt&gt;. It uses the following example to explain "define-syntax" and "syntax-rules". The following code is to define &lt;tt&gt;let&lt;/tt&gt;. &lt;tt&gt;let&lt;/tt&gt; is defined as &lt;tt&gt;(let &amp;lt;bindings&amp;gt; &amp;lt;body&amp;gt;)&lt;/tt&gt; in &lt;i&gt;Revised5 Report on the Algorithmic Language Scheme&lt;/i&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(define-syntax let&lt;br /&gt;  (syntax-rules ()&lt;br /&gt;    ((_ ((x v) ...) e1 e2 ...)&lt;br /&gt;     ((lambda (x ...) e1 e2 ...) v ...))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I still find the description hard for me to understand because I am very new to Scheme. After some time of struggling, I find the following way to understand it. &lt;tt&gt;(let &amp;lt;bindings&amp;gt; &amp;lt;body&amp;gt;)&lt;/tt&gt; is just like a function invocation. &lt;tt&gt;bindings&lt;/tt&gt; create a local binding scope. In some sense, it binds formal parameters to actual parameters. Take &lt;tt&gt;(let ((x 1) (y 2)) (+ x y))&lt;/tt&gt; as an example, &lt;tt&gt;x&lt;/tt&gt; is bound to &lt;tt&gt;1&lt;/tt&gt; and &lt;tt&gt;&lt;/tt&gt; is bound to &lt;tt&gt;2&lt;/tt&gt;. &lt;tt&gt;body&lt;/tt&gt; is just like the body of an function. &lt;tt&gt;(+ x y)&lt;/tt&gt; will produce 3.  &lt;br /&gt;&lt;br /&gt;Back to the "define-syntax" example, we see that &lt;tt&gt;((lambda (x ...) e1 e2 ...) v ...)&lt;/tt&gt; define what we have described as function invocation. For &lt;tt&gt;(_ ((x v) ...) e1 e2 ...)&lt;/tt&gt;, we can see that &lt;tt&gt;(x v)&lt;/tt&gt; indicate a binding. &lt;tt&gt;((x v) ...)&lt;/tt&gt; indicates any number of bindings. &lt;tt&gt;e1&lt;/tt&gt; indicates a expression in the &lt;tt&gt;body&lt;/tt&gt;. &lt;tt&gt;e1 e2 ...&lt;/tt&gt; indicates all the expressions in the &lt;tt&gt;body&lt;/tt&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-2148941281773768393?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/2148941281773768393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=2148941281773768393' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2148941281773768393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2148941281773768393'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/01/define-syntax-and-syntax-rules-in.html' title='&quot;define-syntax&quot; and &quot;syntax-rules&quot; in Scheme'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4606004054341145736</id><published>2009-01-18T23:12:00.000-08:00</published><updated>2009-01-18T23:18:16.813-08:00</updated><title type='text'>Great Programming Book</title><content type='html'>This book (Programming Language Pragmatics) by Scott is really great. Everyone who want to have a complete and deep understanding of programming languages should read this book. I bought this book from US. It costs me more than $60 which is a big amount for a Chinese citizen. Although I have not finished it yet, this book has taught me much.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0mOaQyA-BaM/SXQoI4bcJ3I/AAAAAAAAAEA/v1oALMGeGUg/s1600-h/PLP-2e.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 329px; height: 400px;" src="http://2.bp.blogspot.com/_0mOaQyA-BaM/SXQoI4bcJ3I/AAAAAAAAAEA/v1oALMGeGUg/s400/PLP-2e.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5292899595118716786" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4606004054341145736?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4606004054341145736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4606004054341145736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4606004054341145736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4606004054341145736'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2009/01/great-programming-book.html' title='Great Programming Book'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0mOaQyA-BaM/SXQoI4bcJ3I/AAAAAAAAAEA/v1oALMGeGUg/s72-c/PLP-2e.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8070839309158279080</id><published>2008-11-22T17:11:00.000-08:00</published><updated>2008-11-22T18:30:58.976-08:00</updated><title type='text'>Use GREP or ACK to Search for Chinese Characters</title><content type='html'>I have been developing a solution for a Chinese customer. As a result, I need to search for Chinese characters in text files. I use GREP and &lt;a href="http://petdance.com/ack/"&gt;ACK&lt;/a&gt;. There is some subtlety when searching for Chinese characters. &lt;br /&gt;&lt;br /&gt;In order to input Chinese characters, the windows command line's code page needs to be set to 936. Issuing &lt;tt&gt;chcp 936&lt;/tt&gt; can do this. 936 is for GBK encoding. &lt;br /&gt;&lt;br /&gt;There are two files a.txt and b.txt in d:/text. Both of these 2 files contain the following text:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;中国&lt;br /&gt;中国abc&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The encoding for a.txt is GBK. The encoding for b.txt is UTF-8. The &lt;tt&gt;grep 中国 d:/test/*.txt&lt;/tt&gt; only finds &lt;tt&gt;中国&lt;/tt&gt; in a.txt.&lt;br /&gt;&lt;br /&gt;The conclusion is that GREP can only find Double Byte characters such as Chinese only if the command line console and the file to be searched has the same encoding. This conclusion also applies to ACK.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8070839309158279080?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8070839309158279080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8070839309158279080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8070839309158279080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8070839309158279080'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/11/use-grep.html' title='Use GREP or ACK to Search for Chinese Characters'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-3189422786874095188</id><published>2008-11-22T16:50:00.000-08:00</published><updated>2009-02-08T07:24:55.740-08:00</updated><title type='text'>Use PAR to format XML comment</title><content type='html'>PAR is fantastic for formatting text files. It can be used to give XML comment a pretty layout. For the following XML comment:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;!-- You can recognize truth by its beauty and --&amp;gt;&lt;br /&gt;&amp;lt;!-- simplicity. When you get it right, it is obvious that it is right. --&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;tt&gt;par 50&lt;/tt&gt; produces&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;!-- You can recognize truth by its beauty    --&amp;gt;&lt;br /&gt;&amp;lt;!-- and simplicity. When you get it right,   --&amp;gt;&lt;br /&gt;&amp;lt;!-- it is obvious that it is right.          --&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But for the following text&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;!-- You can recognize truth by its beauty and simplicity. When you get it right, it is obvious that it is right. --&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;tt&gt;par 50&lt;/tt&gt; produces&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;!-- You can recognize truth by its beauty and&lt;br /&gt;simplicity. When you get it right, it is obvious&lt;br /&gt;that it is right. --&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is not what we want. Instead, &lt;tt&gt;par 50 -p5 -s5&lt;/tt&gt; can be used to produce&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;!-- You can recognize truth by its beauty    --&amp;gt; &lt;br /&gt;&amp;lt;!-- and simplicity. When you get it right,   --&amp;gt; &lt;br /&gt;&amp;lt;!-- it is obvious that it is right.          --&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For the details of using PAR, you can refer to &lt;a href="http://www.nicemice.net/par/par-doc.var."&gt;Par&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-3189422786874095188?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/3189422786874095188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=3189422786874095188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/3189422786874095188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/3189422786874095188'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/11/use-par-to-format-xml-comment.html' title='Use PAR to format XML comment'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-2455017313416312503</id><published>2008-11-17T22:07:00.000-08:00</published><updated>2008-11-17T22:16:06.496-08:00</updated><title type='text'>Paste Multiple Lines of Code into Clisp Console</title><content type='html'>There is a little problem when pasting multiple lines of code into clisp console. If TAB is used for code indentation, there will be the following error when pasting the code into CLISP console.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;You are in the top-level Read-Eval-Print loop.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using spaces for code indentation will fix this problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-2455017313416312503?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/2455017313416312503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=2455017313416312503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2455017313416312503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2455017313416312503'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/11/paste-multiple-lines-of-code-into-clisp.html' title='Paste Multiple Lines of Code into Clisp Console'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4270437136825799294</id><published>2008-10-15T00:36:00.000-07:00</published><updated>2008-10-15T00:50:15.094-07:00</updated><title type='text'>Display Chinese characters in Eclipse console</title><content type='html'>Recently, I have been working on a project for a Chinese company. As a result, I want to display Chinese characters in Eclipse console. I am using Eclipse 3.3. I don't want to change Regional and language settings for Windows XP since it will influence other programs. After searching with google, I find the following solution work for me. First, we need to configure the JRE we are using in Eclipse.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;In &lt;tt&gt;Preferences-&gt;Java-&gt;Installed JREs&lt;/tt&gt;, choose the JRE you are using.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Click &lt;tt&gt;Edit&lt;/tt&gt; to show &lt;tt&gt;Edit JRE&lt;/tt&gt; dialog&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Input &lt;tt&gt;-Dfile.encoding=UTF-8&lt;/tt&gt; in &lt;tt&gt;Default VM Arguments&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Second, we need to configure all the Run (Debug) configurations.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;In &lt;tt&gt;Common&lt;/tt&gt; tab, select &lt;tt&gt;UTF-8&lt;/tt&gt; as &lt;tt&gt;Console Encoding&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Eclipse 3.4 does not have this prolem. It can display Chinese correctly by default.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4270437136825799294?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4270437136825799294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4270437136825799294' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4270437136825799294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4270437136825799294'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/10/display-chinese-characters-in-eclipse.html' title='Display Chinese characters in Eclipse console'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8279828479980759097</id><published>2008-09-22T07:52:00.000-07:00</published><updated>2008-09-22T07:57:19.709-07:00</updated><title type='text'>Notebook and Ballpoint Pen</title><content type='html'>My favorite note book and ballpoint pen&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0mOaQyA-BaM/SNexwhNgWJI/AAAAAAAAAC0/3Fsel6LUnHg/s1600-h/notebook-pen.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0mOaQyA-BaM/SNexwhNgWJI/AAAAAAAAAC0/3Fsel6LUnHg/s400/notebook-pen.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5248859337830455442" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8279828479980759097?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8279828479980759097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8279828479980759097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8279828479980759097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8279828479980759097'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/09/notebook-and-ballpoint-pen.html' title='Notebook and Ballpoint Pen'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_0mOaQyA-BaM/SNexwhNgWJI/AAAAAAAAAC0/3Fsel6LUnHg/s72-c/notebook-pen.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-103979544773449142</id><published>2008-08-27T07:10:00.000-07:00</published><updated>2008-08-27T07:13:40.427-07:00</updated><title type='text'>Swap CAPSLOCK and ESC key in Windows</title><content type='html'>I decide to do the swap because I use VIM a lot. Save the following text into a file such as swap.reg. Double click the file import the registry values.&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;REGEDIT4&lt;br /&gt;[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]&lt;br /&gt;"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,3a,00,01,00,01,00,3a,00,00,00,00,00&lt;br /&gt;&lt;/tt&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-103979544773449142?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/103979544773449142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=103979544773449142' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/103979544773449142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/103979544773449142'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/08/swap-capslock-and-esc-key-in-windows.html' title='Swap CAPSLOCK and ESC key in Windows'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-7468330523730267712</id><published>2008-08-16T02:27:00.000-07:00</published><updated>2008-08-16T02:39:34.507-07:00</updated><title type='text'>Build Ruby on Windows</title><content type='html'>Get the Ruby 1.8.7  source code from &lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p71.tar.gz"&gt;ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p71.tar.gz&lt;/a&gt;. Extract the source code to a directory such as D:/Ruby 1.8.7-p71 . Open  a &lt;tt&gt;Visual Studio .NET 2003 Command Prompt&lt;/tt&gt;.  Run the following commands to compile ruby.&lt;br /&gt;&lt;ul&gt;&lt;tt&gt;&lt;/tt&gt;&lt;li&gt;&lt;tt&gt;cd /d D:/Ruby 1.8.7-p71 &lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;tt&gt;win32\configure.bat&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;tt&gt;nmake&lt;/tt&gt;&lt;/li&gt;&lt;tt&gt;&lt;/tt&gt;&lt;/ul&gt;If the following error occurs, its means that Cygwin &lt;tt&gt;find&lt;/tt&gt; is invoked from the make file. Make sure that windows &lt;tt&gt;find&lt;/tt&gt; precedes Cygwin find in PATH environment variable.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;Creating Makefile&lt;br /&gt;find: `=': No such file or directory&lt;br /&gt;NMAKE : fatal error U1077: 'cl' : return code '0x1'&lt;br /&gt;Stop.&lt;br /&gt;&lt;/tt&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-7468330523730267712?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/7468330523730267712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=7468330523730267712' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7468330523730267712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7468330523730267712'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/08/build-ruby-on-windows.html' title='Build Ruby on Windows'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4004066219192747087</id><published>2008-08-02T06:32:00.000-07:00</published><updated>2008-08-02T06:39:30.412-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='WTP'/><title type='text'>HTTP Status 404 when running tomcat inside Eclipse</title><content type='html'>&lt;tt&gt;HTTP Status 404&lt;/tt&gt; will show up when I running tomcat inside Eclipse. And my resource exists. The error will disappear when I restart tomcat for some times. How many times I need to restart tomcat to remove the error is random. And the dialogs of &lt;tt&gt;Run on server&lt;/tt&gt; wizard is random.&lt;br /&gt;&lt;br /&gt;Sometimes, I get this error when using &lt;tt&gt;welcome-file-list&lt;/tt&gt;. For some reasons, the welcome-file can be found. &lt;br /&gt;&lt;br /&gt;I have used tomcat in Eclipse for some. My overall experience is bad. Maybe some improvements should be made on WTP. For now, I use ANT to deal with Tomcat. And it works well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4004066219192747087?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4004066219192747087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4004066219192747087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4004066219192747087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4004066219192747087'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/08/http-status-404-when-running-tomcat.html' title='HTTP Status 404 when running tomcat inside Eclipse'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8380848629513610105</id><published>2008-08-02T06:17:00.000-07:00</published><updated>2008-08-02T06:31:50.872-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='classpath'/><category scheme='http://www.blogger.com/atom/ns#' term='class'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Classpath subtlety when using tomcat inside Eclipse</title><content type='html'>First, an eclipse dynamic web project only recognized classes produced by source folders configured in &lt;tt&gt;Java Build Path-&gt;Source&lt;/tt&gt; and classes in the libraries under &lt;tt&gt;WebContent/WEB-INF/lib&lt;/tt&gt; folder. The locations of source folders and class output folders do not matter if they are inside this project. The count of   source folders and output folders also does not matter. By default, the output class folder is &lt;tt&gt;build/classes&lt;/tt&gt;. It does not recognize the jar libraries which are not under &lt;tt&gt;WebContent/WEB-INF/lib&lt;/tt&gt; and class folder configured in &lt;tt&gt;Java Build Path-&gt;Libraries&lt;/tt&gt;. For class compilation, it is Ok. ClassNotFound exception will be thrown if you begin to use &lt;tt&gt;Run on server&lt;/tt&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8380848629513610105?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8380848629513610105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8380848629513610105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8380848629513610105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8380848629513610105'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/08/classpath-subtlety-when-using-tomcat.html' title='Classpath subtlety when using tomcat inside Eclipse'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-7328005475221033372</id><published>2008-07-02T06:41:00.000-07:00</published><updated>2008-07-02T06:44:00.204-07:00</updated><title type='text'>Running the Eclipse 3.4 formatter application</title><content type='html'>D:\gnu\eclipse\eclipse.exe -application org.eclipse.jdt.core.JavaCodeFormatter -config D:\gnu\jee\workspace\Concurrency\.settings\org.elipse.jdt.core.prefs d:\Foo.java&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-7328005475221033372?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/7328005475221033372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=7328005475221033372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7328005475221033372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7328005475221033372'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/07/running-eclipse-34-formatter.html' title='Running the Eclipse 3.4 formatter application'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-5659982585690215168</id><published>2008-06-12T07:28:00.001-07:00</published><updated>2008-06-12T08:43:55.647-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='variable'/><category scheme='http://www.blogger.com/atom/ns#' term='type checking'/><title type='text'>variable type checking in C</title><content type='html'>Put all the files in a directory. Run &lt;tt&gt;gcc *.c -o main.exe&lt;/tt&gt;. The compilation will succeed. The reason is that C does not check type consistency of external variable declaration and reference. &lt;br /&gt;1 one.c&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int abc = 1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2 main.c&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;extern float abc;&lt;br /&gt;int main(void) {&lt;br /&gt;    printf( "%f", abc );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-5659982585690215168?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/5659982585690215168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=5659982585690215168' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5659982585690215168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5659982585690215168'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/06/variable-type-checking-in-c.html' title='variable type checking in C'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-3520184099060391456</id><published>2008-06-12T07:01:00.000-07:00</published><updated>2008-06-12T07:10:33.554-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='function'/><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='linking'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='type checking'/><title type='text'>Function type checking in C</title><content type='html'>Put all the following 3 files in a directory. Run &lt;tt&gt;gcc *.c&lt;/tt&gt;. The compilation will succeed. And running the resulted excecutable file will print &lt;i&gt;I am here, man!&lt;/i&gt;. Run &lt;tt&gt;g++ *.c&lt;/tt&gt; The compilation will fail. The reason is that during linking, C only check function names. But C++ check function type.&lt;br /&gt;1. caller.c&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include "callee.h"&lt;br /&gt;int main(void) {&lt;br /&gt;    foo();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. callee.h&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int foo(void);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3. callee.c&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;void foo(int v) {&lt;br /&gt;    printf( "I am here, man!" );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-3520184099060391456?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/3520184099060391456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=3520184099060391456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/3520184099060391456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/3520184099060391456'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/06/function-type-checking-in-c.html' title='Function type checking in C'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-1150865884021209470</id><published>2008-05-14T06:36:00.000-07:00</published><updated>2008-05-14T06:45:48.456-07:00</updated><title type='text'>Index overflow in Java for loop</title><content type='html'>The following little code snippet shows the overflow of for loop index in Java.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Out {&lt;br /&gt;    public static void main(String[] ars) {&lt;br /&gt;        for(int i = 0; i &lt;= 2147483647 ; i+=100000000 )&lt;br /&gt;        {&lt;br /&gt;            System.out.println( i + "\n" );&lt;br /&gt;        }        &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You may expect that the iteration count is 22. But it is not true. &lt;tt&gt;i&lt;/tt&gt; is 2100000000&lt;/tt&gt; after the 22nd iteration. Then 100000000 is added to &lt;tt&gt;i&lt;/tt&gt;(2100000000) again. 2200000000 is bigger than 2147483647. So int overflow will happen. &lt;tt&gt;i&lt;/tt&gt; will become a negative integer. So the loop will continue.&lt;br /&gt;&lt;br /&gt;For details of loop index overflow, you can refer to Programming Language Pragmatics.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-1150865884021209470?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/1150865884021209470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=1150865884021209470' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/1150865884021209470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/1150865884021209470'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/05/index-overflow-in-java-for-loop.html' title='Index overflow in Java for loop'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-11374052073495567</id><published>2008-05-02T08:06:00.000-07:00</published><updated>2008-05-02T08:23:14.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='enum'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='valueOf'/><category scheme='http://www.blogger.com/atom/ns#' term='values'/><title type='text'>Genenared methods values and valueOf for Enum</title><content type='html'>I have recently tried Java Enum when doing software development. The following code is an example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public Enum FooType {&lt;br /&gt;    ABC, DEF;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I found two methods &lt;tt&gt;valueOf&lt;/tt&gt; and &lt;tt&gt;values&lt;/tt&gt; in the Javadoc for my enum code. I did not write these 2 methods. And it's superclass &lt;tt&gt;java.lang.Enum&amp;lt;FooType&amp;gt;&lt;/tt&gt; also does not have these 2 methods. Then I checked &lt;i&gt;JLS 3.0&lt;/i&gt;. &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9"&gt;8.9 Enums&lt;/a&gt; says these 2 methods are automatically generated. It is a little magic. One Java class can has methods which do not exist as source code. Too many magic which do not have a consistent rationale can make a language hard to learn and use.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-11374052073495567?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/11374052073495567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=11374052073495567' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/11374052073495567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/11374052073495567'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/05/genenared-methods-values-and-valueof.html' title='Genenared methods values and valueOf for Enum'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-1982904262002151769</id><published>2008-04-26T23:51:00.000-07:00</published><updated>2008-04-27T01:04:46.518-07:00</updated><title type='text'>Modula-2</title><content type='html'>I tried a little Modula-2 programming today. I used XDS 2.5. I built the following little program successfully in XDS IDE.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MODULE hello;&lt;br /&gt;FROM InOut IMPORT WriteString, WriteLn;&lt;br /&gt;BEGIN&lt;br /&gt;    WriteString("Hello, world!");&lt;br /&gt;    WriteLn;&lt;br /&gt;END hello.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And I could use xc to compile it.  The following error showed up when I used xlink to link it.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;XDS Link  Version 2.6 Copyright (c) 1995-2001 Excelsior&lt;br /&gt;Fatal error (13): No program entry point&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I have googled answers for it and read XDS documentation. Unfornately, I can't find an answer. Again, it shows a quick start guide with some simple examples is extremely important for a beginner to use some new tools.&lt;br /&gt;&lt;br /&gt;After wresting with xlink for some time , I worked out the following solution.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;xlink hello.obj C:\free\XDS\LIB\x86\libxds.lib C:\free\XDS\LIB\x86\import32.lib C:\free\XDS\LIB\x86\xstart.lib&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-1982904262002151769?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/1982904262002151769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=1982904262002151769' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/1982904262002151769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/1982904262002151769'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/modula-2.html' title='Modula-2'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-426668200005973804</id><published>2008-04-15T01:12:00.000-07:00</published><updated>2008-04-15T01:24:17.577-07:00</updated><title type='text'>Reading of Programming Language Pragmatics</title><content type='html'>&lt;h4&gt;Programming Language Syntax&lt;/h4&gt;&lt;br /&gt;The following syntax shows dangling else problem of Pascal. &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;&lt;font color="red"&gt;stmt&lt;/font&gt;&lt;/i&gt; -&amp;gt; if &lt;i&gt;&lt;font color="red"&gt;condition&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="red"&gt;then_clause&lt;/font&gt;&lt;/i&gt; &lt;i&gt;&lt;font color="red"&gt;else_clause&lt;/font&gt;&lt;/i&gt; | &lt;i&gt;&lt;font color="red"&gt;other_stmt&lt;/font&gt;&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;&lt;font color="red"&gt;then_clause&lt;/font&gt;&lt;/i&gt; -&amp;gt; then &lt;i&gt;&lt;font color="red"&gt;stmt&lt;/font&gt;&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;&lt;font color="red"&gt;else_clause&lt;/font&gt;&lt;/i&gt; -&amp;gt; else &lt;i&gt;&lt;font color="red"&gt;stmt&lt;/font&gt;&lt;/i&gt; | &amp;epsilon; &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Sometimes, we have a hard time to use some language. Sometimes it is not because we are not smart enough. It is because of the flaws of the programming language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-426668200005973804?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/426668200005973804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=426668200005973804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/426668200005973804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/426668200005973804'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/reading-of-programming-language.html' title='Reading of Programming Language Pragmatics'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-248192971061107068</id><published>2008-04-12T06:34:00.000-07:00</published><updated>2008-04-12T07:01:15.669-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hiding'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='access control'/><category scheme='http://www.blogger.com/atom/ns#' term='overriding'/><title type='text'>Hiding and overriding in Java</title><content type='html'>For some technical terms in this post, please refer to JLS 3.0. And the discussion is not very precise. I have looked for some explicit rules governing this topic in JLS. But I failed. So I am just trying to summarize my personal understanding. Any feedbacks are welcomed.&lt;br /&gt;&lt;br /&gt;In the following discussion, &lt;tt&gt;A&lt;/tt&gt; and &lt;tt&gt;B&lt;/tt&gt; are used. Type &lt;tt&gt;A&lt;/tt&gt; extends type &lt;tt&gt;B&lt;/tt&gt; (type means class or interface).&lt;br /&gt;&lt;h3&gt;Field&lt;/h3&gt;&lt;br /&gt;Only hiding applies tojava fields. Hiding happens in the following situation.Both &lt;tt&gt;A&lt;/tt&gt; and &lt;tt&gt;B&lt;/tt&gt; have a variable named as &lt;tt&gt;var&lt;/tt&gt;. And &lt;tt&gt;var&lt;/tt&gt; is of the same kind of variables ( static fields or instance fields).&lt;br /&gt;Java allows a variable belonging to different variable kinds appears in both A and B. But hiding does not happen in such situations.&lt;br /&gt;&lt;h3&gt;Method&lt;/h3&gt;&lt;br /&gt;Method &lt;tt&gt;m1&lt;/tt&gt; in &lt;tt&gt;A&lt;/tt&gt; . Method &lt;tt&gt;m2&lt;/tt&gt; in &lt;tt&gt;B&lt;/tt&gt;.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;m1&lt;/tt&gt; is subsignature of &lt;tt&gt;m2&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;m1&lt;/tt&gt;'s visibility is no less than &lt;tt&gt;m2&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Both &lt;tt&gt;m1&lt;/tt&gt; and &lt;tt&gt;m2&lt;/tt&gt; are instance methods. Or both &lt;tt&gt;m1&lt;/tt&gt; and &lt;tt&gt;m2&lt;/tt&gt; are static methods. Otherwise, there will some compile errors.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h4&gt;Overriding&lt;/h4&gt;&lt;br /&gt;Overriding applies to instance methods.&lt;br /&gt;&lt;h4&gt;Hiding&lt;/h4&gt;&lt;br /&gt;Overriding applies to static methods.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-248192971061107068?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/248192971061107068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=248192971061107068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/248192971061107068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/248192971061107068'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/hiding-and-overriding-in-java.html' title='Hiding and overriding in Java'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-7183247776026543998</id><published>2008-04-09T06:17:00.000-07:00</published><updated>2008-04-09T06:38:07.285-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><category scheme='http://www.blogger.com/atom/ns#' term='blank'/><title type='text'>blank in shell script</title><content type='html'>Try to avoid the use of blank in pathnames. It will drive you crazy under some circumstances. Take the following script as an example.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;opt="-path \"*/a bc\" -prune"&lt;br /&gt;find $opt -o -print0&lt;br /&gt;bash -c "find $opt -o -print0"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;tt&gt;find $opt -o -print0&lt;/tt&gt; does not work. But &lt;tt&gt;bash -c "find $opt -o -print0"&lt;/tt&gt; works. I have tried very hard to find a way to make the former work. But I failed. I will be happy to hear if anybody has a solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-7183247776026543998?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/7183247776026543998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=7183247776026543998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7183247776026543998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/7183247776026543998'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/blank-in-shell-command.html' title='blank in shell script'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-8203344170374616932</id><published>2008-04-09T05:20:00.000-07:00</published><updated>2008-04-09T05:53:01.497-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='updatedb'/><category scheme='http://www.blogger.com/atom/ns#' term='locate'/><category scheme='http://www.blogger.com/atom/ns#' term='cygwin'/><title type='text'>Little hacking with bash shell</title><content type='html'>I have recently tried &lt;tt&gt;locate&lt;/tt&gt; from findutils in cygwin. I wanted to use &lt;tt&gt;updatedb&lt;/tt&gt; to create a file name database. And I wanted to exclude all the files and directories under &lt;i&gt;.svn&lt;/i&gt; directories . So I tried &lt;tt&gt;updatedb --localpaths='D:/gnu/ws/ctre/space' --findoptions='-path "*/.svn" -prune -o'&lt;/tt&gt;. But I could't exclude the files in &lt;tt&gt;.svn&lt;/tt&gt; directories with this command. I am not very experienced with bash. But I wanted to solve this problem. So I checked &lt;tt&gt;update&lt;/tt&gt; script and did some debugging to it. The problem is that bash shell will do pathname expansion to &lt;tt&gt;"*/.svn"&lt;/tt&gt;. My first fix is to add &lt;tt&gt;set -f&lt;/tt&gt; in &lt;tt&gt;updatedb&lt;/tt&gt; script. It works.&lt;br /&gt;&lt;br /&gt;Then I wanted to open a bug for this script. For opening a bug, I need to do further investigation. So I learned more about bash and try more scripts.  Finally, I found that I can use &lt;tt&gt;updatedb --localpaths='D:/gnu/ws/ctre/space' --findoptions='-path */.svn -prune -o'&lt;/tt&gt; or &lt;tt&gt;updatedb --localpaths='D:/gnu/ws/ctre/space' --findoptions='-path '*/.svn' -prune -o'&lt;/tt&gt;. Bash shell will preserve the literal value of every chacter within the qoutes. But bash shell will do expansion to characters enclosed by double quotes.&lt;br /&gt;&lt;br /&gt;As a result, I did not open an invalid bug. I have learned more. It tells me that contributing to community will let me learn more.&lt;br /&gt;&lt;br /&gt;Sometimes I was frustrated during this hacking. But the overall experience is good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-8203344170374616932?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/8203344170374616932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=8203344170374616932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8203344170374616932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/8203344170374616932'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/little-hacking-with-bash-shell.html' title='Little hacking with bash shell'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-4072281577520662844</id><published>2008-04-05T08:08:00.000-07:00</published><updated>2008-12-09T00:46:54.286-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='Head First Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='State'/><title type='text'>Solution to one Design Puzzle in Head First Design Pattern</title><content type='html'>I am reading Head First Design Pattern. It is a great book.&lt;br /&gt;&lt;img  src="http://2.bp.blogspot.com/_0mOaQyA-BaM/R_eaUWKjkZI/AAAAAAAAACU/kHi6lMTMzks/s320/hfdp_cover.gif" id="BLOGGER_PHOTO_ID_5185783170278330770" border="0" /&gt;&lt;br /&gt;Generally, I don't like exercises in a book which don't have answers provided. I have run into the design puzzle on page 468. At first sight, I knew that I should use state pattern. I have never applied state pattern in real software work before. So I took this exercise as an opportunity to practice state pattern. Here is my solution.&lt;br /&gt;&lt;br /&gt;State.java&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package headfirst.proxy.virtualproxy;&lt;br /&gt;import java.net.*;&lt;br /&gt;import java.awt.*;&lt;br /&gt;import java.awt.event.*;&lt;br /&gt;import javax.swing.*;&lt;br /&gt;&lt;br /&gt;public interface State {&lt;br /&gt; public int getIconWidth();&lt;br /&gt; public int getIconHeight();&lt;br /&gt; public void paintIcon( Component c, Graphics g, int x, int y );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;NullState.java&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package headfirst.proxy.virtualproxy;&lt;br /&gt;import java.net.*;&lt;br /&gt;import java.awt.*;&lt;br /&gt;import java.awt.event.*;&lt;br /&gt;import javax.swing.*;&lt;br /&gt;&lt;br /&gt;public class NullState implements State {&lt;br /&gt;&lt;br /&gt;    private ImageProxy proxy;&lt;br /&gt;    private Thread retrievalThread;&lt;br /&gt;    private URL imageURL;&lt;br /&gt; boolean retrieving = false;&lt;br /&gt;&lt;br /&gt;    public NullState( ImageProxy p, URL url) {&lt;br /&gt;        proxy = p;&lt;br /&gt;        imageURL = url;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getIconWidth() {&lt;br /&gt;        return 800;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getIconHeight() {&lt;br /&gt;        return 600;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void paintIcon( final Component c, Graphics g, int x, int y ) {&lt;br /&gt;        g.drawString("Loading CD cover, please wait...", x+300, y+190);&lt;br /&gt;        if (!retrieving) {&lt;br /&gt;            retrieving = true;&lt;br /&gt;            retrievalThread = new Thread(new Runnable() {&lt;br /&gt;                public void run() {&lt;br /&gt;                    try {&lt;br /&gt;                        ImageIcon imageIcon = new ImageIcon(imageURL, "CD Cover");&lt;br /&gt;                        proxy.setState( new ImageState( imageIcon )  );&lt;br /&gt;                        c.repaint();&lt;br /&gt;                    } catch (Exception e) {&lt;br /&gt;                        e.printStackTrace();&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            });&lt;br /&gt;            retrievalThread.start();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ImageState.java&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package headfirst.proxy.virtualproxy;&lt;br /&gt;import java.net.*;&lt;br /&gt;import java.awt.*;&lt;br /&gt;import java.awt.event.*;&lt;br /&gt;import javax.swing.*;&lt;br /&gt;&lt;br /&gt;public class ImageState implements State {&lt;br /&gt;    &lt;br /&gt;    private ImageIcon imageIcon;&lt;br /&gt;    &lt;br /&gt;    public ImageState( ImageIcon i ) {&lt;br /&gt;        imageIcon = i;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getIconWidth() {&lt;br /&gt;        return imageIcon.getIconWidth();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getIconHeight() {&lt;br /&gt;        return imageIcon.getIconHeight();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void paintIcon( final Component c, Graphics g, int x, int y ) {&lt;br /&gt;        imageIcon.paintIcon(c, g, x, y);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ImageProxy.java&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package headfirst.proxy.virtualproxy;&lt;br /&gt;&lt;br /&gt;import java.net.*;&lt;br /&gt;import java.awt.*;&lt;br /&gt;import java.awt.event.*;&lt;br /&gt;import javax.swing.*;&lt;br /&gt;&lt;br /&gt;public class ImageProxy implements Icon {&lt;br /&gt;&lt;br /&gt;    private NullState ns;&lt;br /&gt;    private State state;&lt;br /&gt;     &lt;br /&gt; public ImageProxy(URL url) {&lt;br /&gt;        ns = new NullState( this, url );&lt;br /&gt;        state = ns;&lt;br /&gt;    }&lt;br /&gt;     &lt;br /&gt; public int getIconWidth() {&lt;br /&gt;        return state.getIconWidth();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public int getIconHeight() {&lt;br /&gt;        return state.getIconWidth();&lt;br /&gt; }&lt;br /&gt;     &lt;br /&gt; public void paintIcon(final Component c, Graphics  g, int x,  int y) {&lt;br /&gt;        state.paintIcon( c, g, x, y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;    public void setState( State s ) &lt;br /&gt;    {&lt;br /&gt;        state = s;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-4072281577520662844?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/4072281577520662844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=4072281577520662844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4072281577520662844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/4072281577520662844'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/solution-to-one-design-puzzle-in-head.html' title='Solution to one Design Puzzle in Head First Design Pattern'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0mOaQyA-BaM/R_eaUWKjkZI/AAAAAAAAACU/kHi6lMTMzks/s72-c/hfdp_cover.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-2573435503303450591</id><published>2008-04-05T02:34:00.000-07:00</published><updated>2008-04-05T02:55:17.016-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rmiregistry'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='rmi'/><title type='text'>ClassNotFoundException problem with rmiregistry</title><content type='html'>It is very possible that you will get &lt;span style="font-style: italic; color: rgb(255, 102, 102);"&gt;ClassNotFoundException &lt;/span&gt;when you try &lt;span style="font-style: italic;"&gt;Getting Started &lt;/span&gt;tutorial for RMI in JDK documentation. There is a easy way to fix it. Start &lt;span style="font-style: italic;"&gt;rmiregistry &lt;/span&gt;and the server implementation in the same command line console on Windows (assuming that the current directory is the root directory of the class file tree for the example).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;start rmiregistry&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;java example.hello.Server&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The CLASSPATHs for both &lt;span style="font-style: italic;"&gt;rmiregistry&lt;/span&gt; and j&lt;span style="font-style: italic;"&gt;ava example.hello.Server&lt;/span&gt; must contains the path for the class file tree for the example if you want to run them from different command line console.&lt;br /&gt;&lt;br /&gt;I have run into this problem twice. And JDK documentation does not explicitly specified. I searched the web. &lt;a href="http://forum.java.sun.com/thread.jspa?threadID=589511&amp;amp;messageID=3059742"&gt;Remote Method Invocation (RMI) - RMI server ClassNotFoundException&lt;/a&gt;solves my problem.&lt;br /&gt;&lt;br /&gt;So documentation is vital to software quality. Good documentation can save developers a lot of precious time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-2573435503303450591?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/2573435503303450591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=2573435503303450591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2573435503303450591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/2573435503303450591'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/04/classnotfoundexception-problem-with.html' title='ClassNotFoundException problem with rmiregistry'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-5174702243329302374</id><published>2008-03-24T02:23:00.000-07:00</published><updated>2008-03-24T02:29:18.844-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='working directory'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='process'/><title type='text'>Working Directory</title><content type='html'>To decide the working directory for a process is difficult. I have found a entry in wikipedia for working directory. And I have added some rules for deciding working directory in the wikipedia entry &lt;a href="http://en.wikipedia.org/wiki/Working_directory"&gt;Working directory&lt;/a&gt;. You can refer to it for details.&lt;br /&gt;&lt;br /&gt;For this reason, we should always try to use pathname relative to classpath instead of working directory in Java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-5174702243329302374?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/5174702243329302374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=5174702243329302374' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5174702243329302374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5174702243329302374'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/03/working-directory.html' title='Working Directory'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-9067910639566084401</id><published>2008-03-19T09:22:00.000-07:00</published><updated>2008-04-11T20:37:16.844-07:00</updated><title type='text'>Unicode &amp; Java</title><content type='html'>&lt;h3&gt;Endianess&lt;/h3&gt;&lt;br /&gt;In computing, endianness is the byte (and sometimes bit) ordering used to represent&lt;br /&gt;some kind of data.&lt;br /&gt;Most modern computer processors agree on bit ordering "inside" individual bytes (this was not always the case). This means that any single-byte value will be read the same on almost any computer one may send it to.&lt;br /&gt;Integers are usually stored as sequences of bytes, so that the encoded value can be obtained by simple concatenation. The two most common of them are:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;increasing numeric significance with increasing memory addresses, known as little-endian&lt;/li&gt;&lt;br /&gt;&lt;li&gt;its opposite, most-significant byte first, called big-endian.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Inter x86 use little-endian. JVM use big-endian.(The above content is from &lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;Wikipedia Endianess Entry&lt;/a&gt;)&lt;br /&gt;&lt;h3&gt;Unicode&lt;/h3&gt;&lt;br /&gt;Code Point. Any value in the Unicode codespace; that is, the range of integers from 0 to 10FFFF16.&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Basic_Multilingual_Plane"&gt;Mapping of Unicode character planes&lt;/a&gt; is a good explanation of Unicode planes and code points.&lt;br /&gt;&lt;h4&gt;UTF-16&lt;/h4&gt;&lt;br /&gt;To represent the complete range of characters using only 16-bit units, the Unicode standard defines an encoding called UTF-16. In this encoding, supplementary characters are represented as pairs of 16-bit code units, the first from the high-surrogates range, (U+D800 to U+DBFF), the second from the low-surrogates range (U+DC00 to U+DFFF). For characters in the range U+0000 to U+FFFF, the values of code points and UTF-16 code units are the same.&lt;br /&gt;&lt;h3&gt;Java&lt;/h3&gt;&lt;br /&gt;In the Java SE API documentation, &lt;em&gt;Unicode code point&lt;/em&gt; is  used for character values in the range between U+0000 and U+10FFFF,  and &lt;em&gt;Unicode code unit&lt;/em&gt; is used for 16-bit  &lt;code&gt;char&lt;/code&gt; values that are code units of the &lt;em&gt;UTF-16&lt;/em&gt;  encoding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-9067910639566084401?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/9067910639566084401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=9067910639566084401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/9067910639566084401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/9067910639566084401'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/03/unicode-java.html' title='Unicode &amp; Java'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6419924689110079275.post-5658544788813674338</id><published>2008-02-24T06:54:00.000-08:00</published><updated>2008-02-25T19:16:24.849-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='effective java'/><category scheme='http://www.blogger.com/atom/ns#' term='equals'/><title type='text'>It is not true that there is simply no way to extend an instantiable class and add an aspect while preserving the equals contract.</title><content type='html'>In Effective Java, Item 7 is "Obey the general contract when overriding &lt;code&gt;equals&lt;/code&gt;". There is one sentence "There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract." Josh uses the following classes to illustrate &lt;b&gt;Transitivity&lt;/b&gt;. The following text is excerpted from the book.&lt;br /&gt;The &lt;tt&gt;Point&lt;/tt&gt; class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Point {&lt;br /&gt;private final int x;&lt;br /&gt;private final int y;&lt;br /&gt;public Point(int x, int y) {&lt;br /&gt;    this.x = x;&lt;br /&gt;    this.y = y;&lt;br /&gt;}&lt;br /&gt;public boolean equals(Object o) {&lt;br /&gt;    if (!(o instanceof Point))&lt;br /&gt;        return false;&lt;br /&gt;    Point p = (Point)o;&lt;br /&gt;    return p.x == x &amp;amp;&amp;amp; p.y == y;&lt;br /&gt;}&lt;br /&gt;... // Remainder omitted&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;tt&gt;ColorPoint&lt;/tt&gt; class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class ColorPoint extends Point {&lt;br /&gt;private Color color;&lt;br /&gt;public ColorPoint(int x, int y, Color color) {&lt;br /&gt;    super(x, y);&lt;br /&gt;    this.color = color;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Broken - violates transitivity.&lt;br /&gt;public boolean equals(Object o) {&lt;br /&gt;    if (!(o instanceof Point))&lt;br /&gt;        return false;&lt;br /&gt;    // If o is a normal Point, do a color-blind&lt;br /&gt;    // comparison&lt;br /&gt;    if (!(o instanceof ColorPoint))&lt;br /&gt;        return o.equals(this);&lt;br /&gt;    // o is a ColorPoint; do a full comparison&lt;br /&gt;    ColorPoint cp = (ColorPoint)o;&lt;br /&gt;    return super.equals(o) &amp;amp;&amp;amp; cp.color == color;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;... // Remainder omitted&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This approach does provide symmetry, but at the expense of transitivity:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ColorPoint p1 = new ColorPoint(1, 2, Color.RED);&lt;br /&gt;Point p2 = new Point(1, 2);&lt;br /&gt;ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;At this point, &lt;tt&gt;p1.equals(p2)&lt;/tt&gt; and &lt;tt&gt;p2.equals(p3)&lt;/tt&gt; return &lt;tt&gt;true&lt;/tt&gt;, while &lt;tt&gt;p1.equals(p3)&lt;/tt&gt; returns &lt;tt&gt;false&lt;/tt&gt;, a clear violation of transitivity. The first two comparisons are “color-blind,” while the third takes color into account.&lt;br /&gt;&lt;br /&gt;So what's the solution? It turns out that this is a fundamental problem of equivalence relations in object-oriented languages. &lt;b&gt;There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Then Josh gives a a workaround where &lt;tt&gt;ColorPoint&lt;/tt&gt; does not extend &lt;tt&gt;Point&lt;/tt&gt;. I thinks that we can allow ColorPoint to extend Point  and preserve the equals contract. Here is my solution.&lt;br /&gt;The &lt;tt&gt;Point&lt;/tt&gt; class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Point {&lt;br /&gt;    private final int x;&lt;br /&gt;    private final int y;&lt;br /&gt;&lt;br /&gt;    public Point( int x, int y ) {&lt;br /&gt;        this.x = x;&lt;br /&gt;        this.y = y;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean equals( Object o ) {&lt;br /&gt;        if( this == o )&lt;br /&gt;            return true;&lt;br /&gt;        if( !(this.getClass() == o.getClass()) )&lt;br /&gt;            return false;&lt;br /&gt;        Point p = (Point) o;&lt;br /&gt;        return p.x == x &amp;&amp; p.y == y;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;... // Remainder omitted&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;tt&gt;ColorPont&lt;/tt&gt; class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class ColorPoint extends Point {&lt;br /&gt;private Color color;&lt;br /&gt;public ColorPoint(int x, int y, Color color) {&lt;br /&gt;    super(x, y);&lt;br /&gt;    this.color = color;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public boolean equals( Object o ) {&lt;br /&gt;    if( this == o )&lt;br /&gt;        return true;&lt;br /&gt;    if( o == null )&lt;br /&gt;        return false;&lt;br /&gt;    if( !(this.getClass() == o.getClass()) )&lt;br /&gt;        return false;&lt;br /&gt;    ColorPoint cp = (ColorPoint) o;&lt;br /&gt;    return super.equals( o ) &amp;amp;&amp;amp; cp.color == color;&lt;br /&gt;}&lt;br /&gt;... // Remainder omitted&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;First, &lt;tt&gt;equals&lt;/tt&gt; method use the == operator to check if the argument is a reference to this object. Secondly, it check whether the argument and this object are of the same type. I have tested this piece of code. It works. But I think that there may be some situations I have not taken into account.&lt;br /&gt;&lt;br /&gt;Any comments are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6419924689110079275-5658544788813674338?l=yaojingguo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yaojingguo.blogspot.com/feeds/5658544788813674338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6419924689110079275&amp;postID=5658544788813674338' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5658544788813674338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6419924689110079275/posts/default/5658544788813674338'/><link rel='alternate' type='text/html' href='http://yaojingguo.blogspot.com/2008/02/reading-of-item-7-of-effective-java.html' title='It is not true that there is simply no way to extend an instantiable class and add an aspect while preserving the equals contract.'/><author><name>Jing Guo Yao</name><uri>http://www.blogger.com/profile/15845167097443821430</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry></feed>
