SG Dev Corner

SG Dev Corner

On programming, erlang, science, web design, business and politics.

 
 

31 May 2006 - Narrative JavaScript

From lambda-the-ultimate:

Narrative JavaScript is a small extension to the JavaScript language that enables blocking capabilities for asynchronous operations. This makes writing asynchronous code sequences easier and increases code readability.

It provides on the client side what continuation based web frameworksdo on the server side. Instead of manually splitting up your code intocallbacks and handlers for events, setTimeout, XMLHttpRequestcallbacks, etc you write your code in a sequential manner.

The code is CPS transformed and the continuations at the point of useof the new operator are used for the callbacks - allowing continuationof the function when done.

Comments (0) - Leave a Comment


23 May 2006 - Sahi Web automation and testing tool tutorial [flash]

Sahi is an automation and testing tool for web applications, with the facility to record and playback scripts.
Developed in java and javascript, this tool uses simple javascript to execute events on the browser.
View the Flash tutorial.


Comments (0) - Leave a Comment


22 May 2006 - On Continuations

Gilad Bracha recently posted an article on continuations and why they won't be implemented in the JVM yet.
Among other things he says that continuations are difficult to implement in Java and that they are mainly useful for a particular type of web development.
Avi Bryant the creator of the continuations based web framework Seaside replies with considerations on the various architectures for web based applications (REST, continuations/closures based and Ajax based) and why a developer should know each one and learn which is the best approach to use.
A more interesting reply is this: Sapir-Whorf is not a Klingon where Curtis Poe uses the Sapir-Whorf hypotesis to answer Gilad Bracha.
The Saphir-Whorf hypotesis is taken from linguistic. Simplifying it states that language shapes thougth, so some concepts can't be understood if the language hasn't the words to express them. The hypotesis is quite controversial, though recently a study introduced new elements in support of the hypotesis.
My humble opinion, based on my experience on different programming languages with different paradigms is that the language used shapes thoughts and so the way we code in different languages.

Comments (0) - Leave a Comment


21 May 2006 - Erlang 5.5/OTP R11B released

Erlang 5.5/OTP R11B has been released.
The major improvement is support for SMP (Symmetric MultiProcessing). The SMP support is totally trasparent, so Erlang processes are scheduled trasparently across multiple CPUs.
SMP is recently becoming more and more important now when dual processors, hyper-threading and multi-core systems are reality.

The latest release can be downloaded in source or windows binary format.

Comments (0) - Leave a Comment


10 May 2006 - Scheme Implementation in Javascript

A scheme implementation written in javascript.
Read the article in the Bluish Coder blog.
Comments (0) - Leave a Comment


8 May 2006 - Memoize utility

Here is a small utility I use to memoize expensive function calls in python. This utility too (like compose seen some days ago) is a traslation from lisp to python of a utility found in the book On Lisp by Paul Graham:
def memoize(fun):
cache = {}
def inner(*args, **kwargs):
cached = cache.get((args, repr(kwargs)), None)
if cached is None:
val = fun(*args, **kwargs)
cache[(args, repr(kwargs))] = val
return val
return cached
return inner

The memoize function uses an internal dict (cache) to store the values already calculated and returns a function containing a binding to the cache, hence a closures.
The closure when called first tries to search in the cache for a previously stored value corresponding to the arguments passed. If found the cached value is returned, otherwise the value is calculated and stored in the cache using the arguments and the repr() of the keyword arguments as the cache key. The repr is used because a dictionary, in python, is not hashable and so it can't be used as a key.

To test the utility we define a function that calculates the fibonacci sequence:

def fib(n):
if n < 2:
return 1
return fib(n-1) + fib(n-2)

To use the memoize utility first we get the closure that memoizes the fib function:

import memoize
memo = memoize.memoize(fib)

Now we call the memo closure two times with the same argument and we time its execution:

def test_memoize_fib():
memo = memoize.memoize(fib)
start = time.time()
print memo(30)
end = time.time()
print "First call: %f" % (end - start)
start = time.time()
print memo(30)
end = time.time()
print "Second call: %f" % (end - start)

Calling the test function we get an output like this:

1346269
First call: 1.976743
1346269
Second call: 0.000072



Comments (0) - Leave a Comment


4 May 2006 - Sito Ascione Associati

Pubblicato il sito Ascione Associati. Sito di consulenza di direzione, strategica, commerciale e marketing.

Comments (0) - Leave a Comment


3 May 2006 - The Lonely Planet guide to My apartment

Funny reading
Comments (0) - Leave a Comment


1 May 2006 - Compose functions

Recently I'm reading the book "on Lisp" by Paul Garham. One the best books of programming I've ever read.
Here is an utility I translated from lisp to python to learn more on the use of closures. I wrote the function as part of a module functional (file functional.py)

def compose(*fns):
if fns:
f1 = fns[-1]
fns = list(fns[:-1])
fns.reverse()
def inner(*args, **kwargs):
curr_arg = f1(*args, **kwargs)
for f in fns:
curr_arg = f(curr_arg)
return curr_arg
return inner
return None

The utility let you compose an arbitrary number of functions and apply each function to the result of the previous call. The first function can take any number of arguments or keyword arguments. All the others must take a single argument which is the result of the previous function call. Calling compose returns a closure that can be called with the number of arguments required by the first composed function:
>>> import functional
>>> import operator
>>> myop1 = functional.compose(operator.neg, operator.add)
>>> myop2 = functional.compose(operator.neg, operator.mul)

Now we can call the new operators like this:

>>> myop1(3, 2)
>>> myop1(3, 4)
>>> myop2(3, 2)
>>> myop2(3, 4)

and we get respectively:

-5, -7, -6 and -12

First operator.add (or operator.mul) is called with the two arguments passed. Then operator.neg is called with the result of the previous call as an argument.


Comments (0) - Leave a Comment