Friday, April 17, 2009

Install PHP 5.2.9-2 (Windows)

I have already had Apache 2.2 installed.

  • Download php-5.2.9-2-Win32.zip. Extract it to C:/free/php

  • Make a copy of php.ini-dist and rename it to php.ini

  • Add the following text to C:/free/Apache2.2/conf/httpd.conf


    • #load the php main library to avoid dll hell
      Loadfile "C:/free/php/php5ts.dll"

      #load the sapi so that apache can use php
      LoadModule php5_module "C:/free/php/php5apache2_2.dll"

      #set the php.ini location so that you don't have to waste time guessing where it is
      PHPIniDir "C:/free/php"

      #Hook the php file extensions, notice that Addtype is NOT USED, since that's just stupid
      AddHandler application/x-httpd-php .php
      AddHandler application/x-httpd-php-source .phps

Thursday, April 16, 2009

Opening PDF files within Firefox

I can't open pdf files side Firefox recently. I am using Firefox 3 on Windows XP.

After done some googling, I found
Opening PDF files within Firefox which provides a complete solution of this problem. The following method works for me.


1. Close Firefox.
2. Navigate to my Firefox profile folder.
3. Delete the mimetypes.rdf file.
4. Restart Firefox.


For how to find profile folder, refer to to How to find your profile.

Monday, April 13, 2009

Handle Multi-key to One-value Property File

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.

# [v1]
K11=v1
K12=v1
K13=v1

# [v2]
K21=v2
K22=v2
K23=v2

# [v2]
K31=v3
K32=v3
K33=v3

It contains a lot of duplications. v1, v2 and v3 appears many times in the property file. DIY (Don't Repeat Yourself) principle is violated. One improvement is to write the following property file:

# [v1]
K11,K12,K13 = v1

# [v2]
K21, K22, K23 = v2

# [v2]
K31, K32, K33 = v3

For this property file, I need to write additional code. The following steps are one option:

  • get the entry set from the property file

  • create a hash map

  • iterate over the entry set. k is the map entry key, v is the map entry value


    • split the iterated k with , into key[]

    • add (key[0], v), (key[1], v), ... to the hash map



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.

#lang scheme
(define (find-value k)
(let* ([ks2v '(

; multi-key to one-value mappings
((K11 K12 K13) V1)
((K21 K22 K23 K24) V2)
((K31 K32 K33 K34) V3)

)]
[contain? (lambda (k keys)
(let ([equal2k? (lambda (a) (equal? k a))])
(ormap equal2k? keys)))]
[k2v (lambda (pair)
(if (contain? k (car pair))
(cadr pair)
#f))])
(ormap k2v ks2v)))

This solution is elegant. Code as data characteristic of Scheme makes such kind of solutions possible. And when I was coding this solution, I had the same feeling as the quote SQL, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing.

Wednesday, April 8, 2009

Disable Translating Chinese Character into Character Entities in Tidy and Xmllint

For Tidy, set char-encoding to raw. The following text is my setting.

tidy -q --char-encoding raw -indent --show-warnings n --tidy-mark n -w 80

For xmllint, set encode to UTF-8 (The encoding of my XML files is UTF-8). Here is my xmllint setting.
xmllint --encode UTF-8 --format

Monday, April 6, 2009

Building DSL with Scheme

I have listened a talk made by Shriram Krishnamurthi. It is called The Swine Before Perl . 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.

The following source code is tested in DrScheme, version 4.1.4.
The first version of automaton.

#lang slideshow
(define b-machine-states
'((init (c more))
(more (a more)
(d more)
(r end))
(end (r end))))

(define (b-machine stream)
(letrec ([walker (lambda (state stream)
(or (empty? stream)
(let ([transitions
(cdr (assv state b-machine-states))])
(let ([1st (first stream)])
(let ([new-state (assv 1st transitions)])
(if new-state
(walker (cadr new-state) (rest stream))
false))))))])
(walker 'init stream)))

(b-machine '(c a r))
(b-machine '(c a d r))
(b-machine '(c a x))

The goto version of automaton.

#lang scheme
(define b-machine
(letrec ([init
(lambda (stream)
(or (empty? stream)
(case (first stream)
[(c) (more (rest stream))]
[else false])))]
[more
(lambda (stream)
(or (empty? stream)
(case (first stream)
[(a) (more (rest stream))]
[(d) (more (rest stream))]
[(r) (end (rest stream))]
[else false])))]
[end
(lambda (stream)
(or (empty? stream)
(case (first stream)
[(r) (end (rest stream))]
[else false])))])
init))

(b-machine '(c a r))
(b-machine '(c a d r))
(b-machine '(c a x))

The second version of automaton.

#lang scheme
(define-syntax automaton
(syntax-rules (-> :)
[(_ init-state
(state : (cndn -> new-state) ...)
...)
(letrec ([state
(lambda (stream)
(or (empty? stream)
(case (first stream)
[cndn (new-state (rest stream))]
...
[else false])))]
...)
init-state)]))

(define b-machine
(automaton init
(init : ((c) -> more))
(more : ((a) -> more)
((d) -> more)
((r) -> end))
(end : ((r) -> end))))



(b-machine '(c a r))
(b-machine '(c a d r))
(b-machine '(c a x))

The following code is really an elegant DSL for automaon.

(automaton init
(init : ((c) -> more))
(more : ((a) -> more)
((d) -> more)
((r) -> end))
(end : ((r) -> end)))


I have also implemented the first and goto version of automaton in Ruby.
The first version of automaton in Ruby

$b_machine_states = {
"init" => {"c" => "more"},
"more" => {"a" => "more",
"d" => "more",
"r" => "end"},
"end" => {"r" => "end"}}

def walker(state, stream)
if stream.empty?
return true
end
first = stream[0]
transitions = $b_machine_states[state]
new_state = transitions[first]
if new_state == nil
return false
else
rest = stream[1, stream.length()]
return walker(new_state, rest)
end
end

def b_machine(stream)
walker("init", stream)
end

print b_machine("car") , "\n"
print b_machine("cadr") , "\n"
print b_machine("cax") , "\n"

The goto version of automaton in Ruby

class Automaton

def accept(stream)
return init(stream)
end

private
def init(stream)
if stream.empty?
return true
end
first = stream[0]
case first
when "c"
return more(rest(stream))
else
false
end
end

def more(stream)
if stream.empty?
return true
end
first = stream[0]
case first
when "a"
return more(rest(stream))
when "d"
return more(rest(stream))
when "r"
return terminate(rest(stream))
else
return false
end
end

def terminate(stream)
if stream.empty?
return true
end
first = stream[0]
case first
when "r"
return terminate(rest(stream))
else
return false
end
end

def rest(stream)
return stream[1, stream.length()]
end
end

auto = Automaton.new()
print auto.accept("car") , "\n"
print auto.accept("cadr") , "\n"
print auto.accept("cax"), "\n"

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.