Here's a little [Tcl] script which lets you use indentation as optional subsitute for braces, as pioneered by [Python] -[jcw] ---- ''First a sample of the '''new''' syntax (note that this is NOT standard Tcl!):'' ---- # A little package to deal with an alternate Tcl source code syntax, # using optional indentation as a substitute for braces. # # by Jean-Claude Wippler, June 2002 package provide indentcl 0.3 namespace eval indentcl namespace export iconvert ieval isource namespace eval v variable lb \{ variable rb \} proc emit {line} if {[llength $v::last] > 0} lappend v::result [join $v::last " "] foreach x $v::keep lappend v::result $x set v::keep {} set v::last [list $line] proc dedent {i} while {$i < [lindex $v::levels end]} set v::levels [lreplace $v::levels end end] lappend v::last $v::rb proc iconvert {text} set v::last {} set v::levels 0 set v::keep {} set v::result {} foreach x [split $text \n] regexp {^(\s*)(.*)$} $x - a b if {$b == "" || [string index $b 0] == "#"} lappend v::keep $x continue set i 0 foreach y [split $a ""] switch $y " " { incr i } "\t" { incr i [expr {8 - $i%8}] } if {$i < [lindex $v::levels end]} dedent $i if {$i != [lindex $v::levels end] || [regsub {^(\s*)\\:} $x {\1} x]} lappend v::last \\ \:elseif {$i > [lindex $v::levels end]} lappend v::last $v::lb lappend v::levels $i emit $x dedent 0 emit "" set r [join $v::result "\n"] while {[llength $r] == 1 && [lindex $r 0] ne $r} set r [lindex $r 0] ;# strip top level indentation return $r proc ieval {script} uplevel 1 [iconvert $script] proc isource {file} set fd [open $file] set data [read $fd] close $fd set prev [info source] info source $file set result [uplevel 1 [iconvert $data]] info source $prev return $result if {$argv0 == [info script]} if {[llength $argv] != 2} puts "usage: $argv0 infile outfile" exit set fd [open [lindex $argv 0]] set data [read $fd] close $fd set data [indentcl::iconvert $data] set fd [open [lindex $argv 1] w] puts -nonewline $fd $data close $fd ---- ''And here's the Tcl script that can deal with the above input file:'' ---- # A little package to deal with an alternate Tcl source code syntax, # using optional indentation as a substitute for braces. # # by Jean-Claude Wippler, June 2002 package provide indentcl 0.3 namespace eval indentcl { namespace export iconvert ieval isource namespace eval v { variable lb \{ variable rb \} } proc emit {line} { if {[llength $v::last] > 0} { lappend v::result [join $v::last " "] } foreach x $v::keep { lappend v::result $x } set v::keep {} set v::last [list $line] } proc dedent {i} { while {$i < [lindex $v::levels end]} { set v::levels [lreplace $v::levels end end] lappend v::last $v::rb } } proc iconvert {text} { set v::last {} set v::levels 0 set v::keep {} set v::result {} foreach x [split $text \n] { regexp {^(\s*)(.*)$} $x - a b if {$b == "" || [string index $b 0] == "#"} { lappend v::keep $x continue } set i 0 foreach y [split $a ""] { switch $y { " " { incr i } "\t" { incr i [expr {8 - $i%8}] } } } if {$i < [lindex $v::levels end]} { dedent $i if {$i != [lindex $v::levels end] || [regsub {^(\s*)\\:} $x {\1} x]} { lappend v::last \\ } } \ elseif {$i > [lindex $v::levels end]} { lappend v::last $v::lb lappend v::levels $i } emit $x } dedent 0 emit "" set r [join $v::result "\n"] while {[llength $r] == 1 && [lindex $r 0] ne $r} { set r [lindex $r 0] ;# strip top level indentation } return $r } proc ieval {script} { uplevel 1 [iconvert $script] } proc isource {file} { set fd [open $file] set data [read $fd] close $fd set prev [info source] info source $file set result [uplevel 1 [iconvert $data]] info source $prev return $result } } if {$argv0 == [info script]} { if {[llength $argv] != 2} { puts "usage: $argv0 infile outfile" exit } set fd [open [lindex $argv 0]] set data [read $fd] close $fd set data [indentcl::iconvert $data] set fd [open [lindex $argv 1] w] puts -nonewline $fd $data close $fd } ---- If you run that second script with the first as input file... you get the second script again :o) 14apr03 [jcw] - Adjusted to deal with "re-indentation" by starting a line with "\:". There is one example of it in the above. It is needed to support mixed indents/dedents of the form: if {...} { ... } else { ... } This can now be written as: if {...} ... \:else ... In essence, "\:" means: "dedent, but keep on continuing last block". Ugly, but this gets around the issue. Note that "\:" is not just for else's. ---- How's this for a twisted example: package require indentcl indentcl::ieval { package require critcl critcl::ccode fraction {int n} double double f = 1; while (--n >= 0) f /= 2; return f; puts [fraction 6] } 08nov05 [jcw] - Heh, interesting one :) Here's another example I toyed with recently, using htmlgen to generate HTML code: proc do_html {} global info cmds objs this desc sect html head meta http-equiv=Content-type {content=text/html; charset=utf-8} - "" title - $info(name) $info(version) style type=text/css + body do_sect name p - [b $info(name) - $info(title)] do_sect synopsis p ! $info(preamble) foreach {type name} $info(calls) do_call $type $name br - do_sect description do_text $desc(~) dl foreach {type name} $info(calls) dt do_call $type $name dd do_text $desc($name) foreach name $::info(sections) do_sect $name do_text $sect($name) if {$info(examples) ne ""} do_sect examples foreach {x y} $info(examples) set x [string trim $x] if {$x ne ""} do_text $x regsub {^\n} $y {} y set y [string trimright $y] if {$y ne ""} pre width=81n - "  [esc $y]" foreach x {author copyright bugs website see-also keywords} if {$info($x) ne ""} do_sect [string map {- " "} $x] set y $info($x) switch $x author { p - Written by $y. } copyright { p - Copyright {©} $y } keywords { p - [join $y ", "] } website { p - See [a href=$y $y]. } default { p - $y } ---- [IL] Simply amazing. ---- [[[Category Syntax]]]