Friday, February 27, 2009

Subroutine Pointer in C

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, plus_one has the same referencing environment whether the referencing environment is created when it is passed as a parameter to caller or when it is called in caller.

#include
int plus_one(int n) {
return n + 1;
}
void caller(int (*f) (int)) {
int result = f(3);
printf("3 plus 1 is %d\n", result);
}
int main() {
caller(plus_one);
return 0;
}

For a language which supports nested scope, the situation is different. In the following Common Lisp code, a closure must be created for plus_2 to make it a function which addes 2 to its sole parameter.

(let ((one 1))
(defun plus_1 (x)
(+ x one)))

(let ((one 5))
(plus_1 3))

Thursday, February 26, 2009

Dynamic Scope in LISP

The following program will print (3 5) in newlisp which is dynamic scoped. But it will print (3 7) in CLISP which is static scoped.

(let ((y 7)) (define (scope-test x) (list x y)))
(let ((y 5)) (scope-test 3))

Sunday, February 22, 2009

Java's file.encoding property on Windows platfor

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. System.getProperty("file.encoding") can be used to access this property. Code such as System.setProperty("file.encoding", "UTF-8") 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. java -dfile.encoding=UTF-8 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.

Tuesday, February 17, 2009

Produce the "TeX: The Program" from tex.web

This is how I have produced the TeX: The Program from tex.web

The result is a PDF file program.pdf and CONTENTS.tex. These files are the book.

Monday, February 9, 2009

A Quick Start of SWI-Prolog for Windows

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.

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 C:\Program Files\pl\bin.

SWI-Prolog has a plwin.exe which is GUI environment for SWI-Prolog. I prefer to use the SWI-Prolog console environment which is plcon.

  • Open a command line

  • change to directory containing my prolog source code. In my case, it is D:\documents\Prolog.

  • type plcon to launch prolog


Now the command console looks as follows.

D:\Documents\Prolog>plcon
Welcome to SWI-Prolog (Multi-threaded, 32 bits, Version 5.6.64)
Copyright (c) 1990-2008 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

1 ?- consult(woman).
% woman compiled 0.00 sec, 1,060 bytes
true.

2 ?-

Type consult(women) to load D:\documents\Prolog\women.pro. It contains the following clauses.

:-dynamic pregnant/.
human(susan).
human(jane).
pregnant(susan).
woman(X) :- pregnant(X), human(X).

Assert can only be used to add facts to dynamic predicates in the prolog interpreter. I want to add facts for predicate pregnant. So I add the dynamic directive in the prolog source code. pregnant/1 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.

2 ?- assert(pregnant(jane)).
true.

Issue a query. Type ; to ask for more answers.

3 ?- woman(X).
X = susan ;
X = jane.

Type halt. to exit SWI-Prolog

4 ?- halt.

Sunday, February 8, 2009

Iterator in Icon

In Icon programming language, iterator is very powerful. As a result, Programming Language Pragmatics dedicates a sub section to explain it. The following shows the complete running code corresponding to the code snippets in the book.

procedure main()
write("=================================================")
every i := 1 to 10 by 2 do {
write(i)
}
write("=================================================")
every i := 1 + upto(' ', "a ss ss") do {
write(i)
}
write("=================================================")
i := 1
every write(i + upto(' ', "a ss ss"))
write("=================================================")
if 2 < 3 then {
write("2 < 3")
}
write("=================================================")
if (i := find("abc", "abcabcabc")) > 6 then {
write(i)
}
write("=================================================")
if (i := find("x", "xaax")) = find("x", "bxxx") then {
write(i)
}
end

The following code explains the description at the end of the sub section. It is If the expression following suspend contains an invocation of a generator, then the subroutine will suspend repeatedly, once for each generated value.

# suspend is followed by a value
procedure FollowedByValue()
i := 1
while i <= 3 do {
suspend i
i +:= 1
}
end

# suspend is followed by a generator expression
procedure FollowedByGenExpr()
suspend(1|2|3)
end

# suspend is followed by a generator function invocation
procedure FollowedByGenFuncInvocation()
suspend FollowedByValue()
end

procedure main()
write("=================================================")
every write(FollowedByValue())
write("=================================================")
every write(FollowedByGenExpr())
write("=================================================")
every write(FollowedByGenFuncInvocation())
end

Iterator in Ruby and Python

Unlike Java, both languages support real iterator not just iterator object. The following code shows how to create and use iterator in Python.

def from_1_to_5():
for i in [1, 2, 3, 4, 5]:
yield i

for num in from_1_to_5():
print num

The following code shows how to make it in Ruby. Desides a style similar to Python, Ruby can use iterator with block.

def iterator
for i in [1, 2, 3, 4, 5]
yield(i)
end
end

# invoke iterator in a way similar to Python
call_block do |num|
puts "#{num}"
end

# invoke iterator with the use of block
call_block { |num| puts "#{num}" }