<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xingzhi&#039;s Temporary Tech Blog</title>
	<atom:link href="http://pro.panxingzhi.net/wp/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://pro.panxingzhi.net/wp</link>
	<description>Just another TEMP WordPress weblog</description>
	<lastBuildDate>Mon, 26 Jul 2010 04:30:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Sage &#8220;LaTeX error&#8221; on Mac OS X</title>
		<link>http://pro.panxingzhi.net/wp/?p=1453</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1453#comments</comments>
		<pubDate>Mon, 26 Jul 2010 01:52:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://pro.panxingzhi.net/wp/?p=1453</guid>
		<description><![CDATA[Sage is my new toy of the time.  I have it run on my Snow Leopard and play with it every which way.  Soon enough I found the LaTeX part broken &#8211; executing something as simple as &#8220;latex.eval(&#8216;$x^2$&#8217;, {})&#8221; gave only elliptical error message (&#8220;An error occurred.&#8221;) in either command line or browser [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.sagemath.org">Sage</a> is my new toy of the time.  I have it run on my Snow Leopard and play with it every which way.  Soon enough I found the LaTeX part broken &#8211; executing something as simple as &#8220;latex.eval(&#8216;$x^2$&#8217;, {})&#8221; gave only elliptical error message (&#8220;An error occurred.&#8221;) in either command line or browser interface.</p>
<p>I Googled around and found some hints using &#8220;latex.eval(&#8216;$x^2$&#8217;, {}, debug=True)&#8221;.  This gives details on what Sage does underhood.  In my case, the absence of &#8220;gs&#8221;, i.e. GhostScript, fails ImageMagick&#8217;s &#8220;convert&#8221; utility, which is invoked by Sage to convert a .ps file to a .png.  So I just</p>
<pre>sudo brew install gs</pre>
<p>then everything is good!  However, please note that beforehand I already had TeX Live, ImageMagick and libpng installed.  I&#8217;m not sure but you might want to secure these boys, too.</p>
<pre>sudo brew install imagemagick
sudo brew install libpng
sudo brew link libpng</pre>
<p>And just Google for TeX Live!</p>
<p>Btw, with the command line interface, &#8220;latex.eval&#8221; would save your .png files under where you started Sage.  It&#8217;s an excellent way to generate snippet images for math formulas &#8211; you don&#8217;t have to write the whole \begin{document} thing at all!</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1453</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Exit shell without quitting running jobs</title>
		<link>http://pro.panxingzhi.net/wp/?p=1448</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1448#comments</comments>
		<pubDate>Mon, 28 Jun 2010 02:56:57 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://pro.panxingzhi.net/wp/?p=1448</guid>
		<description><![CDATA[This is the issue I always sought to solve.  If the process doesn&#8217;t run itself as a daemon (detaching itself from the terminal or something, I can&#8217;t remember exactly, check APUE* if not sure), and you exit the shell, in many cases if not all, the process is killed.  Adding &#8216;&#38;‘ doesn&#8217;t work &#8211; it [...]]]></description>
			<content:encoded><![CDATA[<p>This is the issue I always sought to solve.  If the process doesn&#8217;t run itself as a daemon (detaching itself from the terminal or something, I can&#8217;t remember exactly, check APUE* if not sure), and you exit the shell, in many cases if not all, the process is killed.  Adding &#8216;&amp;‘ doesn&#8217;t work &#8211; it just means the job will be put in background (i.e., standard io unavailable, or I&#8217;m wrong, again, APUE).</p>
<p>Finally I encountered nohup and disown!  If you&#8217;re interested, read <a href="http://www.cyberciti.biz/tips/nohup-execute-commands-after-you-exit-from-a-shell-prompt.html" target="_blank">this</a> and <a href="http://en.wikipedia.org/wiki/Nohup" target="_blank">that</a>.</p>
<p>Note that wikipedia mentions start-stop-daemon.  This is what I used to overcome the problem!!!  The &#8216;at&#8217; command is also good.  However on Mac &#8216;at&#8217; is implemented by launchd and by default disabled.  Talk about learning new stuff everyday pal!</p>
<p>* APUE is the famous &#8220;Advanced Programming in the UNIX Environment&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1448</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim returning 1 (exit code) on Mac</title>
		<link>http://pro.panxingzhi.net/wp/?p=1445</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1445#comments</comments>
		<pubDate>Thu, 27 May 2010 17:36:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://pro.panxingzhi.net/wp/?p=1445</guid>
		<description><![CDATA[Using Mac OS 10.6, I don&#8217;t why this happens but if you compare what you get from
vim
echo $?

and
/usr/bin/vim
echo $?

you can see the difference.  A &#8216;which vim&#8217; shows /usr/bin/vim so I have no clue.
I noticed this because Mutt reported &#8220;Error on running &#8216;vi /var/tmp/some-random-tmp-file&#8217;&#8221;.  It doesn&#8217;t really break anything but it&#8217;s annoying.  Obviously Mutt depends on [...]]]></description>
			<content:encoded><![CDATA[<p>Using Mac OS 10.6, I don&#8217;t why this happens but if you compare what you get from</p>
<pre>vim
echo $?
</pre>
<p>and</p>
<pre>/usr/bin/vim
echo $?
</pre>
<p>you can see the difference.  A &#8216;which vim&#8217; shows /usr/bin/vim so I have no clue.</p>
<p>I noticed this because Mutt reported &#8220;Error on running &#8216;vi /var/tmp/some-random-tmp-file&#8217;&#8221;.  It doesn&#8217;t really break anything but it&#8217;s annoying.  Obviously Mutt depends on Vim&#8217;s exit code to decide this.  Specifying &#8220;set editor=/usr/bin/vim&#8221; in muttrc eliminates the problem.<a href="http://groups.google.com/group/vim_mac/browse_thread/thread/0d33e2f2130867b0?pli=1"></a></p>
<p>And &#8230; <a href="http://groups.google.com/group/vim_mac/browse_thread/thread/0d33e2f2130867b0?pli=1" target="_blank">no I&#8217;m not alone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1445</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding user-defined language support to Exuberant Ctags</title>
		<link>http://pro.panxingzhi.net/wp/?p=1382</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1382#comments</comments>
		<pubDate>Thu, 01 Apr 2010 09:26:39 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://personal.panxingzhi.net/?p=1382</guid>
		<description><![CDATA[I&#8217;ve been dealing with a lot LZX (OpenLaszlo/Webtop) code since joining Laszlo Systems.  LZX is a very dynamic language &#8211; akin to JavaScript.  IDE support for such languages is innately weak, because there isn&#8217;t as much information one can get by static code analysis (that is, without actually running the code).
Luckily it is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been dealing with a lot LZX (OpenLaszlo/Webtop) code since joining Laszlo Systems.  LZX is a very dynamic language &#8211; akin to JavaScript.  IDE support for such languages is innately weak, because there isn&#8217;t as much information one can get by static code analysis (that is, without actually running the code).</p>
<p>Luckily it is not very hard to add custom language support to ctags, so not only can we jump around in source files, but we can also make use of other Vim plugins like FuzzyFinder to release the full potential of tags.  Here&#8217;s how.</p>
<p>To add our language, LZX, the simplest way is to use ctags&#8217; command line options.  Since the options are many, we write a file containing them all:</p>
<pre>
--langdef=lzx
--langmap=lzx:.lzx
--regex-lzx=/^[ \t]*&lt;class[ \t]*name=["']([A-Za-z0-9_]+)["']/\1/c,Class/
--regex-lzx=/^[ \t]*&lt;method[ \t]*name=["']([A-Za-z0-9_]+)["']/\1/m,Method/
--regex-lzx=/^[ \t]*&lt;handler[ \t]*name=["']([A-Za-z0-9_]+)["']/\1/h,Handler/
--regex-lzx=/^[ \t]*&lt;attribute[ \t]*name=["']([A-Za-z0-9_]+)["']/\1/a,Attribute/
--exclude=*.as
--exclude=*.bat
--exclude=*.cc
--exclude=*.h
--exclude=*.htm
--exclude=*.html
--exclude=*.java
--exclude=*.js
--exclude=makefile
--exclude=*.mk
--exclude=*.php
--exclude=*.pl
--exclude=*.pm
--exclude=*.py
--exclude=*.rb
--exclude=*.sql
--exclude=*.tex
--exclude=*.vim
--links=no
</pre>
<p>&#8211;langdef indicates the name of the user-defined language, while &#8211;langmap defines the suffix of its source files. &#8211;regex-&lt;LANG&gt; defines the patterns ctags uses to extract tags.  The use of &#8211;exclude is obvious &#8211; I don&#8217;t want to collect information (tags) from these files for a LZX project.  &#8211;links just tells ctags to ignore symbolic links.</p>
<p>Then this is how we tell ctags to use above options and generate tags:</p>
<pre>
ctags --options=ctags-lzx -f &lt;PATH-AND-NAME-OF-THE-TAGS-FILE&gt; -R &lt;BASEDIR-OF-SOURCE-CODE&gt;
</pre>
<p>Naturally, -R means recursive, and -f specifies our tags file.  Normally Vim will pick up the tags file if we follow good habit, but if it doesn&#8217;t, we can tell it by:</p>
<pre>
:set tags+=&lt;PATH-AND-NAME-OF-THE-TAGS-FILE&gt;,&lt;EVEN-MORE-TAGS-FILE&gt;
</pre>
<p>Then we are ready to jump to most definitions and back by ctrl-], g] (for multiple matches) and ctrl-T!  With FuzzyFinder, try &#8220;:FufTag&lt;CR&gt;&#8221;.  I&#8217;ve already mapped it to “&lt;LEADER&gt;t” since it&#8217;s so brilliant!  (Try also &#8220;:FufFile&lt;CR&gt;&#8221; to “&lt;LEADER&gt;f”, &#8220;:FufBuffer&lt;CR&gt;&#8221; to “&lt;LEADER&gt;b”, etc.)</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1382</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mac OS及fink使用感触</title>
		<link>http://pro.panxingzhi.net/wp/?p=1355</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1355#comments</comments>
		<pubDate>Thu, 11 Feb 2010 01:48:45 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://personal.panxingzhi.net/?p=1355</guid>
		<description><![CDATA[Mac OS是目前我用过的操作系统里，用户体验最好的，这主要归功于多点触摸，精心设计的界面和字体，华丽的dock（dock设计的非常用心，细心如我能看出有些icon下面有光点，意为正在运行的程序）；但要论软件管理，还是比Ubuntu差一些。
实际上我用fink装的第一个软件就失败了 － mutt（fink -b install mutt，因为没有binary包所以不能用apt-get）。错误信息是令人挠头的“Failed: Fink::SysState: Could not resolve inconsistent dependencies”。官方给的解释是他们计算dependency的引擎不够强大，当dependency很复杂的时候就会错。这在Ubuntu的aptitude上是不可想象的：不够强大还好意思出来混么？！当然fink是免费软件靠志愿者的，没人逼我非得用这个。只是看起来，对于我这种程序员，用Mac OS当一个开发环境，也许还是奢望。
最后问题倒是解决了，用的是这里最下面给出的方法。也就是说如果错误信息给出提示需要你手动装什么，你就装，然后再fink install；如果没给出，那你只能碰运气去执行fink update-all，然后再重新执行fink install。确实比aptitude差远了，而且包也比较旧。
但我真的很喜欢那些华丽的玩意儿啊！！！
]]></description>
			<content:encoded><![CDATA[<p>Mac OS是目前我用过的操作系统里，用户体验最好的，这主要归功于多点触摸，精心设计的界面和字体，华丽的dock（dock设计的非常用心，细心如我能看出有些icon下面有光点，意为正在运行的程序）；但要论软件管理，还是比Ubuntu差一些。</p>
<p>实际上我用fink装的第一个软件就失败了 － mutt（fink -b install mutt，因为没有binary包所以不能用apt-get）。错误信息是令人挠头的“Failed: Fink::SysState: Could not resolve inconsistent dependencies”。官方给的解释是他们计算dependency的引擎不够强大，当dependency很复杂的时候就会错。这在Ubuntu的aptitude上是不可想象的：不够强大还好意思出来混么？！当然fink是免费软件靠志愿者的，没人逼我非得用这个。只是看起来，对于我这种程序员，用Mac OS当一个开发环境，也许还是奢望。</p>
<p>最后问题倒是解决了，用的是<a href="http://www.opensubscriber.com/message/fink-beginners@lists.sourceforge.net/9632744.html" target="_blank">这里</a>最下面给出的方法。也就是说如果错误信息给出提示需要你手动装什么，你就装，然后再fink install；如果没给出，那你只能碰运气去执行fink update-all，然后再重新执行fink install。确实比aptitude差远了，而且包也比较旧。</p>
<p>但我真的很喜欢那些华丽的玩意儿啊！！！</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1355</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A joke for geeks</title>
		<link>http://pro.panxingzhi.net/wp/?p=1282</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1282#comments</comments>
		<pubDate>Fri, 04 Dec 2009 14:43:07 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Trivia]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://www.panxingzhi.net/?p=1282</guid>
		<description><![CDATA[我想我大概成了一个血统纯正的Unix geek。这周我开始用mutt &#8211; 一个命令行电子邮件客户端，并且当前正式版本不支持收发邮件。这是一个笑话吗？呃，不，这意味着你得装fetchmail, sendmail, procmail等等等等。也许我应该把它称为是电子邮件浏览器才对，毕竟它连收发都不管。也许我疯了，我不知道，但是它真的很酷，嗯，我讨厌用鼠标点来点去的，更何况mutt会贴心的让你用vi编辑邮件，甚合我意。额外的好处是速度快，内存占用小，搜索极为方便（可以像vi里那样按“/”之后输入正则表达式），还有非常费脑子。
UW开发过一个叫pine的类似的东西，于是我google了一下它和mutt的比较，结果意外的发现了一个非常好笑但大概只有geek们才能看懂的笑话。我向你保证，这真的是个笑话，看到cat那句我就开始抽搐了。。。
&#8220;I use pico.&#8221;
&#8220;Hah! Pico. You are lame. Get a real editor, like emacs.&#8221;
&#8220;Emacs isn&#8217;t pre-installed on Unix systems. Real geeks use vi.&#8221;
&#8220;Oh yeah? I do everything with ed!&#8221;
&#8220;Well, **** that, I just use cat.&#8221;
&#8220;That&#8217;s nothing. I edit my system&#8217;s raw partition directly.&#8221;
&#8220;You&#8217;re not a real hacker until you&#8217;ve manually sent [...]]]></description>
			<content:encoded><![CDATA[<p>我想我大概成了一个血统纯正的Unix geek。这周我开始用mutt &#8211; 一个<strong>命令行</strong>电子邮件客户端，并且当前正式版本<strong>不支持收发邮件</strong>。<strong>这是一个笑话吗？</strong>呃，不，这意味着你得装fetchmail, sendmail, procmail等等等等。也许我应该把它称为是电子邮件浏览器才对，毕竟它连收发都不管。也许我疯了，我不知道，但是它真的很酷，嗯，我讨厌用鼠标点来点去的，更何况mutt会贴心的让你用vi编辑邮件，甚合我意。额外的好处是速度快，内存占用小，搜索极为方便（可以像vi里那样按“/”之后输入正则表达式），还有非常费脑子。</p>
<p>UW开发过一个叫pine的类似的东西，于是我google了一下它和mutt的比较，结果意外的发现了一个非常好笑但大概只有geek们才能看懂的笑话。我向你保证，<strong>这真的是个笑话</strong>，看到cat那句我就开始抽搐了。。。</p>
<p>&#8220;I use pico.&#8221;<br />
&#8220;Hah! Pico. You are lame. Get a real editor, like emacs.&#8221;<br />
&#8220;Emacs isn&#8217;t pre-installed on Unix systems. Real geeks use vi.&#8221;<br />
&#8220;Oh yeah? I do everything with ed!&#8221;<br />
&#8220;Well, **** that, I just use cat.&#8221;<br />
&#8220;That&#8217;s nothing. I edit my system&#8217;s raw partition directly.&#8221;<br />
&#8220;You&#8217;re not a real hacker until you&#8217;ve manually sent electronic signals with a couple of batteries over your keyboard&#8217;s wires by hand.&#8221;<br />
&#8220;But you have to use a pre-fabricated power source. I shuffle along the floor and discharge my information through static electricity directly onto the wiretraces of my motherboard. And you have to be very skilled to not to cause ESD damage.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1282</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Denoting method of proof by contradiction</title>
		<link>http://pro.panxingzhi.net/wp/?p=1275</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1275#comments</comments>
		<pubDate>Mon, 16 Nov 2009 10:52:37 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://www.panxingzhi.net/?p=1275</guid>
		<description><![CDATA[Just another simple reminder&#8230;but it&#8217;s about math and logic: I want to show the logical process when people are using proof by contradiction.
Say if we want to prove A is true, we can suppose ~A is true, and try to find a contradiction.
Then according to some rules like ~A → B (≡ A∨B; the rule [...]]]></description>
			<content:encoded><![CDATA[<p>Just another simple reminder&#8230;but it&#8217;s about math and logic: I want to show the logical process when people are using proof by contradiction.</p>
<p>Say if we want to prove A is true, we can suppose ~A is true, and try to find a contradiction.</p>
<p>Then according to some rules like ~A → B (≡ A∨B; the rule itself is true regardless of the truth value of ~A), we deduct that B is true by <em>modus ponens</em>.</p>
<p>However we then find B to be wrong (contradictory).  Then what makes us determine our assumption of &#8220;~A is true&#8221; to be false out of our instinct?  It turns out that the underlying logic is just another <em>modus ponens</em>:</p>
<pre>   ~A → B ≡ ~B → A
   ~B
∴ A</pre>
<p>I know I&#8217;m pulling hair but things can get really confusing when you delve into logic&#8230;</p>
<p>凡事就怕较真儿。。。连反证法都如此。</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1275</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up SSH tunnels</title>
		<link>http://pro.panxingzhi.net/wp/?p=1250</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1250#comments</comments>
		<pubDate>Fri, 30 Oct 2009 14:22:50 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.panxingzhi.net/?p=1250</guid>
		<description><![CDATA[Describing how to setup an SSH tunnel in minimal words. Essentially the -D, -L and -R options.
-D&#60;localport&#62;
Open &#60;localport&#62; on the client side. TCP traffic made to this port is forwarded through the secured tunnel between the SSH client and server.
-L&#60;localport&#62;:&#60;host&#62;:&#60;port&#62;
Open &#60;localport&#62; on the client side. &#60;port&#62; on &#60;host&#62;, which can be reached from the SSH [...]]]></description>
			<content:encoded><![CDATA[<p>Describing how to setup an SSH tunnel in minimal words. Essentially the -D, -L and -R options.</p>
<pre>-D&lt;localport&gt;</pre>
<p>Open &lt;localport&gt; on the client side. TCP traffic made to this port is forwarded through the secured tunnel between the SSH client and server.</p>
<pre>-L&lt;localport&gt;:&lt;host&gt;:&lt;port&gt;</pre>
<p>Open &lt;localport&gt; on the client side. &lt;port&gt; on &lt;host&gt;, which can be reached from the SSH server, is mapped to &lt;localport&gt;.</p>
<pre>-R&lt;serverport&gt;:&lt;host&gt;:&lt;port&gt;</pre>
<p>Open &lt;serverport&gt; on the server side. &lt;port&gt; on &lt;host&gt;, which can be reached from the SSH client, is mapped to &lt;serverport&gt;.<br />
Draw some pics when you&#8217;re in doubt. And, use your imagination.</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1250</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>In respect to &#039;Lifting in Flapjax&#039;</title>
		<link>http://pro.panxingzhi.net/wp/?p=1240</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1240#comments</comments>
		<pubDate>Wed, 28 Oct 2009 17:02:42 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Object-Oriented and Design Patterns]]></category>

		<guid isPermaLink="false">http://www.panxingzhi.net/?p=1240</guid>
		<description><![CDATA[After reading Lifting in Flapjax, I did a little mind bending and came up with my version of lift_e, supporting arity larger than one and function-valued stream as the first parameter.
So basically the enhancements are:

Since f may accept more than one arguments, we can support it by

lift_e returning stream of curried f, which can be [...]]]></description>
			<content:encoded><![CDATA[<p>After reading <a href="http://www.weaselhat.com/2007/08/11/lifting-in-flapjax/" target="_blank">Lifting in Flapjax</a>, I did a little mind bending and came up with my version of lift_e, supporting arity larger than one and function-valued stream as the first parameter.</p>
<p>So basically the enhancements are:</p>
<ol>
<li>Since f may accept more than one arguments, we can support it by
<ol>
<li>lift_e returning stream of curried f, which can be fed to lift_e again repeatedly</li>
<li>lift_e accepting multiple streams as arguments of f: e1, e2 &#8230;</li>
</ol>
<p>I have picked the former just because it was the first one came to my mind, and it sounds more reasonable. The latter implies a lot (probably meaningless) updates in the lifted stream.</li>
<li> When f is a function-valued stream, each time it updates, the lifted is also renewed.</li>
</ol>
<pre lang="JavaScript">/* f is a function or a function-valued event stream.
   e is an event stream.

   Returns a "lifted" function-valued event stream which consists of curried
   functions from f with values in e as the first argument.
   A new value in e (or f if it's a stream) triggers the new value in "lifted".

   Special work-arounds for empty values:
   1. If f is a function-valued event stream, every value in e before the
   appearance of the first value in f is ignored (since there is no function
   to "lift" them). In the future if f provides an initial value this can be
   patched.

   2. In the same vein, if f is a stream but its first value comes before the
   first value of e, no new value appears in lifted. Again, this can be patched
   of e provides an initial value.
*/
function lift_e(f, e) {

    /* Accepts a function of arbitrary arity and its first argument.
       Returns a curried version taking one less arguments. */
    function curry1(func, v) {
        return function () {
            var args = new Array();
            for(var i=0; i &lt; arguments.length; i++) {
                args[i] = arguments[i];
            }
            // insert the new value in e at the beginning
            args.unshift(v);
            return func.apply(this, args);
        };
    }

    /* Uses func to "lift" e and stores the latest value in e to lifted.curValue */
    function liftAndStore(func) {
        e.listeners.push(
            function (v) {
                lifted.newValue(curry1(func, v));
                lifted.curValue = v;
            }
        );
    }

    var lifted = new Event();
    // TODO initial value of e should be put here
    lifted.curValue = undefined;

    if (f instanceof Event) {
        // f is a function-valued event stream
        f.listeners.push(
            function (fv) {
                // fv is a function.
                // A new function value in f triggers in lifted a new value
                // which is a curried function taking one less argument
                if (lifted.curValue !== undefined)
                    lifted.newValue(curry1(fv, lifted.curValue));
                // TODO need a better way to remove exactly
                // the previous function in f from e.listeners
                e.listeners.pop();
                liftAndStore(fv);
            }
        );
        // TODO if f has an initial value, liftAndStore it here
    } else {
        // f is just a function
        liftAndStore(f);
    }
    return lifted;
}</pre>
<p>This has a flavor of mergeE since the resulting stream is triggered whenever f or e updates. Also, it can be seen as an operation satisfying the closure property (closure as in abstract algebra, not in programming langauges), or an OO decorator pattern.</p>
<p>In practice we can of course use the lifted stream in many different ways. Here for simplicity we provide arguments of curried f in a modified version of showStream called showStreamApplied, which delegates the presentation part to the former:</p>
<pre lang="JavaScript">function showStreamApplied(e, args) {
    var appliedStream = new Event();
    e.listeners.push(
            function(fv) {
                appliedStream.newValue(fv.apply(this, args));
            }
    );
    showStream(appliedStream);
}</pre>
<p>To show its usage I have made 3 showcases. Feel free to comment out some of them to observe individual output.</p>
<pre lang="JavaScript">function loader() {
    // 1. curried functions in lifted do not need extra arguments
    showStreamApplied(lift_e(function (v) { return 10000 * v; }, timer_e(500)));

    // curried functions in func_e take (4-1)=3 extra arguemnts
    var func_e = lift_e(function(a, t, prefix, suffix) {
                            return prefix + t + suffix;
                        },
                        // every sec
                        timer_e(1000));
    // 2. feeding 3 arguments directly
    showStreamApplied(func_e, ['unknown', 'system time ', '.']);
    // 3. providing one argument by lifting again
    showStreamApplied(lift_e(func_e,
                             // every 5 sec
                             timer_e(5000)),
                      ['system time is ', '.']);
}</pre>
<p>Note how first-class streams/behaviors objects in Flapjax hide callbacks away and make client code more lucid.<br />
At last, you can <a href="http://pro.panxingzhi.net/wp/wp-content/uploads/2009/10/flapjax_lifting.html" target="_blank">see it run here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1240</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Integrating Vim with Perforce</title>
		<link>http://pro.panxingzhi.net/wp/?p=1205</link>
		<comments>http://pro.panxingzhi.net/wp/?p=1205#comments</comments>
		<pubDate>Fri, 16 Oct 2009 02:21:36 +0000</pubDate>
		<dc:creator>Pan Xingzhi</dc:creator>
				<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://www.panxingzhi.net/integrating-vim-with-perforce/</guid>
		<description><![CDATA[Well, this is the first time I use VimScript and it&#8217;s not a decent language. Although Python or Ruby can be employed, the interfaces to Vim smell bad. I didn&#8217;t do much research but seems they do some string processing and pass the result to the VimScript interpreter.
Anyway, put this in your .vimrc and replace [...]]]></description>
			<content:encoded><![CDATA[<p>Well, this is the first time I use VimScript and it&#8217;s not a decent language. Although Python or Ruby can be employed, the interfaces to Vim smell bad. I didn&#8217;t do much research but seems they do some string processing and pass the result to the VimScript interpreter.</p>
<p>Anyway, put this in your .vimrc and replace P4 and USERNAME with yours.</p>
<pre lang="vim">nmap <leader>e :call P4CurrentFile("edit")<cr>
nmap <leader>r :call P4CurrentFile("revert")<cr>
nmap <leader>d :call P4CurrentFile("diff")<cr>

function P4CurrentFile(operation)
    if !exists("g:P4WS")
        echo "Please set up P4WS first"
    else
        let l:p4cmd="!P4 -u USERNAME -c " . g:P4WS . ' ' . a:operation . ' //' . g:P4WS . '/' . bufname("%")
        execute l:p4cmd
    endif
endfunction</pre>
<p>Now after setting your workspace and directory by</p>
<pre lang="vim">
:let P4WS="YOURWS"
:cd YOURWSDIR
</pre>
<p>you can check out, revert or diff the file in current buffer with (without the double quotes) &#8220;\e&#8221;, &#8220;\r&#8221; and &#8220;\d&#8221; in normal mode. On my machine these are &#8220;,e&#8221;, &#8220;,r&#8221; and &#8220;,d&#8221; since I redefined the mapleader.</p>
]]></content:encoded>
			<wfw:commentRss>http://pro.panxingzhi.net/wp/?feed=rss2&amp;p=1205</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

