Version 60 of Salvatore Sanfilippo

Updated 2005-04-04 07:22:07 by antirez

http://www.invece.org/antirez3s.jpg

[L1 ] [L2 ] [L3 ] (no longer access to this second personal site!)

I'm here because I like Tcl! :)

Other languages I like are: C, Scheme, SmallTalk, FORTH, Joy.

I'm the author of The Jim Interpreter. A small footprint implementation of the Tcl programming languages with more support for functional programming and other differences. You can find more information about Jim in the Jim page of this wiki or in the Jim home page at http://jim.berlios.de

Tclwise

I'm writing a book about Tcl programming. Many chapters are online for free, you can find it at http://www.invece.org/tclwise/ .

Random Stuff Genetic Programming

Advantages of Tcl over Lisp

parsing expressions

cfile - object based file I/O for Tcl.

The Tcl IRCd is a little IRC server I wrote in Tcl, the home page and source code are at [L4 ].

Odys Object System

The regmap function may be more secure (against malicious user input) and clean than the usual regsub+subst way, at least some time. Please tell me if something like this is already in some well known library.

Syncronized timer

A different design for Tcl-like languages, with first-class functions: Functions As Values

A let for Tcl: let2 (the let wiki page was already used).

References for Tcl: Tcl References in Tcl (updated version, and C implementation under development)

A Joy stackless/tailrecursive compiler/VM written in Tcl: A Joy implementation in Tcl

lsplit is a useful command ripped from the Joy programming language.

Tcl_Obj types list

Alists for Tcl

TclRef

eDonkey

etprof

Sugar

ptparser

Arity corner cases in math commands (about TIP 174).

Gimp Client

Range

Permutations

bindlife

Tip187 in pure Tcl

hping3

set operations for Tcl lists


Tk code to handle the keyboard in a raw mode. Useful for games or to control real hardware. Uses a trick, don't know if it will work in future or past version of Tcl.

 namespace eval RawKeys {}
 set ::RawKeys::Flag 0
 set ::RawKeys::LastEvent {-1 0 -1}
 set ::RawKeys::Delay 50

 proc ::RawKeys::Init {userPressHandler userReleaseHandler} {
     bind . <KeyPress> [list ::RawKeys::pressHandler %k $userPressHandler]
     bind . <KeyRelease> [list ::RawKeys::releaseHandler %k $userReleaseHandler]
 } 

 proc ::RawKeys::pressHandler {keycode userHandler} {
     variable LastEvent
     variable Delay
     variable Flag
     set Flag 1
     set deliver 1
     if {[lindex $LastEvent 0] == $keycode && \
         ([clock clicks -milliseconds] - [lindex $LastEvent 2]) < $Delay} {
         set deliver 0
     }
     set LastEvent [list $keycode 1 [clock clicks -milliseconds]]
     if {$deliver} {
         $userHandler $keycode
     }
 }   

 proc ::RawKeys::releaseHandler {keycode userHandler} {
     variable LastEvent
     variable Delay
     variable Flag
     set deliver 1
     set Flag 0
     set LastEvent [list $keycode 0 [clock clicks -milliseconds]]
     update
     if {$Flag} {
         set deliver 0
     }
     if {$deliver} {
         $userHandler $keycode
     }
 }    

 #################################### Example ################################### 

 puts "Enter the blank window and press/release random keys" 

 array set ::pressed {}

 proc press keycode {
     set ::pressed($keycode) {}
     puts "=== pressed $keycode! === ([lsort [array names ::pressed]])"
 } 

 proc release keycode {
     catch {unset ::pressed($keycode)}
     puts "=== release $keycode! === ([lsort [array names ::pressed]])"
 }

 ::RawKeys::Init press release

 #include <stdio.h>
 #include <stdlib.h>

 int main(int argc, char **argv)
 {
     int n = atoi(argv[1]), i;
     int *t;
     int chain[30];

     t = malloc(sizeof(int)*n);
     for (i = 0; i < n; i++)
         t[i] = 0;
     for (i = 0; i < n; i++) {
         t[rand()%n]++;
     }
     for (i = 0; i < 30; i++)
         chain[i] = 0;
     for (i = 0; i < n; i++) {
         if (t[i] < 30)
             chain[t[i]]++;
     }
     for (i = 0; i < 30; i++) {
         printf("%d - %d (%.02f)\n", i, chain[i], ((float)chain[i]/n)*100);
     }
     free(t);
     return 0;
 }

Result:

 For N: 1000
 0 - 361 (36.10)
 1 - 370 (37.00)
 2 - 198 (19.80)
 3 - 56 (5.60)
 4 - 9 (0.90)
 5 - 6 (0.60)
 6 - 0 (0.00)
 7 - 0 (0.00)
 8 - 0 (0.00)
 9 - 0 (0.00)
 10 - 0 (0.00)
 11 - 0 (0.00)
 12 - 0 (0.00)
 13 - 0 (0.00)
 14 - 0 (0.00)

 For N: 10000
 0 - 3703 (37.03)
 1 - 3633 (36.33)
 2 - 1860 (18.60)
 3 - 608 (6.08)
 4 - 163 (1.63)
 5 - 28 (0.28)
 6 - 4 (0.04)
 7 - 1 (0.01)
 8 - 0 (0.00)
 9 - 0 (0.00)
 10 - 0 (0.00)
 11 - 0 (0.00)
 12 - 0 (0.00)
 13 - 0 (0.00)
 14 - 0 (0.00)

 For N: 100000
 0 - 36798 (36.80)
 1 - 36736 (36.74)
 2 - 18493 (18.49)
 3 - 6082 (6.08)
 4 - 1492 (1.49)
 5 - 342 (0.34)
 6 - 47 (0.05)
 7 - 8 (0.01)
 8 - 2 (0.00)
 9 - 0 (0.00)
 10 - 0 (0.00)
 11 - 0 (0.00)
 12 - 0 (0.00)
 13 - 0 (0.00)
 14 - 0 (0.00)

 For N: 1000000
 0 - 368080 (36.81)
 1 - 367467 (36.75)
 2 - 184116 (18.41)
 3 - 61303 (6.13)
 4 - 15450 (1.54)
 5 - 3008 (0.30)
 6 - 487 (0.05)
 7 - 82 (0.01)
 8 - 7 (0.00)
 9 - 0 (0.00)
 10 - 0 (0.00)
 11 - 0 (0.00)
 12 - 0 (0.00)
 13 - 0 (0.00)
 14 - 0 (0.00)

 For N: 10000000
 0 - 3677184 (36.77)
 1 - 3680236 (36.80)
 2 - 1840549 (18.41)
 3 - 612607 (6.13)
 4 - 153112 (1.53)
 5 - 30410 (0.30)
 6 - 5090 (0.05)
 7 - 699 (0.01)
 8 - 106 (0.00)
 9 - 4 (0.00)
 10 - 3 (0.00)
 11 - 0 (0.00)
 12 - 0 (0.00)
 13 - 0 (0.00)
 14 - 0 (0.00)

 For N: 100000000
 0 - 36796091 (36.80)
 1 - 36776775 (36.78)
 2 - 18396397 (18.40)
 3 - 6129304 (6.13)
 4 - 1534076 (1.53)
 5 - 307430 (0.31)
 6 - 51574 (0.05)
 7 - 7330 (0.01)
 8 - 910 (0.00)
 9 - 101 (0.00)
 10 - 10 (0.00)
 11 - 2 (0.00)
 12 - 0 (0.00)
 13 - 0 (0.00)
 14 - 0 (0.00)

Category Person