leonardo
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
View:Website (My Website).
You're looking at the latest 3 entries.

Tags:, , , , ,
Subject:Returning '(()) isn't difficult
Time:04:19 pm
A little amusing post about language syntax:
http://cadrlife.blogspot.com/2008/03/returning-considered-difficult.html

"Suppose you want a function to find all subsequences of a list with a certain length. For instance, the subsequences of (1...5) with length 2 are as follows."
(1 2) (1 3) (1 4) (1 5)
(2 3) (2 4) (2 5)
(3 4) (3 5)
(4 5)
In a lisp dialect:
(def subn (n li)
 (if (is 0 n) '(())
     (no li) '()
       (join (map [cons (car li) _] (subn (- n 1) (cdr li)))
             (subn n (cdr li)))))
Haskell:
subn 0 _      = [[]]
subn _ []     = []
subn n (x:xs) = map (x:) (subn (n-1) xs) ++ subn n xs
Python:
def subn(n, a):
    if not n: return [[]]
    if not a: return []
    return [[a[0]] + sub for sub in subn(n-1, a[1:])] + subn(n, a[1:])
The Scala version too uses pattern matching, showing how much it can be useful (it may be useful for D language too):
def subn[T](n: int, li : List[T]) : List[List[T]] = (n,li) match {
   case (0,_)     => List(Nil)
   case (_,Nil)   => Nil
   case (_,x::xs) => (subn(n-1, xs) map (x :: _)) ::: subn(n, xs)
}
D version using my libs:
import d.func: putr, map, not, range, xrange, select, BaseType, array;

T[][] subn(T)(int n, T[] a) {
    if (!n) return new T[][](1, 0);
    if (not(a)) return new T[][0];
    return map((T[] s){return a[0..1] ~ s;}, subn(n-1, a[1..$])) ~ subn(n, a[1..$]);
}
If you want shorter lines you can use select (reverted from the 'list' name):
T[][] subn2(T)(int n, T[] a) {
    if (!n) return new T[][](1, 0);
    if (not(a)) return new T[][0];
    T[] s;
    return select(a[0..1] ~ s, s, subn2(n-1, a[1..$])) ~ subn2(n, a[1..$]);
}
This version is able to digest any iterable:
BaseType!(TyIter)[][] subn3(TyIter)(int n, TyIter iter) {
    auto a = array(iter);
    alias BaseType!(TyIter) T;
    if (!n) return new T[][](1, 0);
    if (not(a)) return new T[][0];
    return map((T[] s){return a[0..1] ~ s;}, subn3(n-1, a[1..$])) ~ subn3(n, a[1..$]);
}

void main() {
    putr( subn(2, range(5)) );
    // Output: [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4],
    //          [2, 3], [2, 4], [3, 4]]  

    putr( subn2(3, range(5)) );
    // [[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4],
    //  [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

    putr( subn3(2, xrange(5)) );
    // Output: [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4],
    //          [2, 3], [2, 4], [3, 4]]    
}
comments: Leave a comment Add to Memories Tell a Friend

Tags:, ,
Time:09:52 pm
NewLisp e' un linguaggio di scripting abbastanza nuovo, in pratica e' una nuova variante del Lisp e Scheme:

http://newlisp.org/

E' interpretato e la sua velocita' e' paragonabile a quella di Python (ma gli hash e gestione stringhe di Python sono piu' veloci). Elimina un bel po' di difetti di Scheme (che e' una versione ripulita del Lisp) (e hanno aggiunto solo pochi difetti, aggiungendo alcune inefficienze), e in effetti questo NewLisp e' un linguaggio molto gradevole, perche' hanno aggiunto tante cose utili nella pratica, e mi pare lo abbiano semplificato rendendolo perfino piu' semplice dello Scheme.

Ha una IDE, grafica built-in, e' multipiattaforma, ecc. Per cui oggi questa e' la variante del Lisp che preferisco. Comunque non lo usero' perche' per i compiti di scripting Python e' piu' comprensibile, efficiente ed e' molto piu' diffuso. E d'altronde questo NewLisp e' interpretato (e probabilmente e' ben piu' lento di Psyco), per cui non posso usarlo dove serve la massima velocita' (dove ad esempio posso usare D).

Alcuni frammenti di codice che mostrano la notevole eleganza del linguaggio:
http://newlisp.org/index.cgi?page=Code_Snippets

Un esempio, per eseguire un "sort naturale" di stringhe:
(define (natural-sort l) 
   (let (natural-key (lambda (s) (filter true? 
       (flat (transpose (list 
                 (parse s "[0-9]+" 0) 
                 (map int (find-all "[0-9]+" s))))))))
       (sort l (fn (x y) (< (natural-key x) (natural-key y)))) 
))

Che si usa:
(natural-sort '("a10" "a2" "a1" "a14"))
=> ("a1" "a2" "a10" "a14")

Comunque del codice analogamente sintetico puo' essere scritto anche in Python (nota: in Python le RegularExpression dopo essere state compilate vengono messe in una cache, per cui quello che segue non e' molto piu' lento che usare una re.compile):
>>> l = ["a10", "a2", "a1", "a14"]
>>> from re import split
>>> sorted(l, key=lambda s:[int(p) if p.isdigit() else p for p in split("(\d+)",s)])
['a1', 'a2', 'a10', 'a14']

Comunque in Python per scopi reali uso la seguente funzione:
Clicca qui )
comments: Leave a comment Add to Memories Tell a Friend

Tags:,
Subject:MLISP
Time:08:04 pm
Inside the ROM of the the computer Commodore C64 there was a language Basic, because at the time it was very common and it's a light language that works with minimal resources. A better language, that can fit in that space, is probably FORTH, that with few KBs or RAM allowed a compiler too. With a quick search I have found two Lisp interpreters (LIMP and Micro-LISP):
http://www.npsnet.com/danf/cbm/languages.html#LISP

I have tried Micro-LISP V.2.5 by Nicholas Vrtis (non commercial distribution allowed):
http://www.fantascienza.net/leonardo/blog_pics/mlisp_20070404.zip
Inside the zip there is the mlisp program ready to run on C64, a text file of the commands, the original almost-zlh archive, etc.
To run it I have used the WinVICE-1.21 emulator, but probably it works on other emulators too.

It's not a commercial product, so is not much good, and there are few bugs left, but it seem to work well enough. Few screenshoots (under a cut):
Read more... )
comments: Leave a comment Add to Memories Tell a Friend

leonardo
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
View:Website (My Website).
You're looking at the latest 3 entries.