'''[http://www.schemers.org/%|%Scheme]''' is derivate of [Lisp]. A programming language with even less syntax than Tcl itself. (but special forms and the like...? [RS]) ''Scheme is a lexically-scoped, block structured, dynamically typed, mostly functional language. It is a variant of Lisp. It has first-class procedures with block structure and indefinite extent. Parameter passing is by value, but all values are references. It has first-class continuations to allow the construction of new control abstractions. It has lexically-scoped ("hygienic") macros to allow definition of of new syntactic forms, or redefinition of old ones.'': [ftp://ftp.cs.utexas.edu/pub/garbage/cs345/schintro-v14/schintro_toc.html%|%An Introduction to Scheme and its Implementation] ** See Also ** [Biglook]: [Muddy Scheme]: a Scheme implementation in [Tcl] [Playing Scheme]: [Tcl and LISP]: [Playing LISP]: [Serial summing]: [Cameron Laird%|%Cameron Laird's] [http://phaseit.net/claird/comp.lang.scheme/scheme.html%|%personal notes on Scheme]: [tcl-scheme], by Ian Bicking : a translation of Tcl into [Guile]/[Scheme] ** Reference ** [BOOK Structure and Interpretation of Computer Programs%|%Structure and Interpretation of Computer programs], by Harold Abelson, Gerald Jay Sussman, Julie Sussman: [http://okmij.org/ftp/Scheme/monad-in-Scheme.html%|%Monadic Programming in Scheme]: ** Tools ** [PS/Tk]: Portable Scheme interface to [Tk] [Chicken/Tk], by [wdb%|%Wolf-Dieter Busch]: An interface to Tk, based on [scheme_wish] [scheme_wish], by Sven Hartrumpf: a portable interface between Scheme and Tcl/Tk [Scheme Tk]: a free R4RS Scheme interpreter that can access Tk. Concretely, it can be seen as the standard Tk package where Tcl has been replaced by a Scheme interpreter [Scheme Widget Library]: a graphics package for [http://www.scheme.com/%|%Chez Scheme], based on [Tk] ** Description ** [wdb]: I strongly disagree that Scheme has less syntax than Tcl! Reason: the symbols have a value ''per se''. Tcl has no symbols as $varname is just a shortcut for [[set varname]] where ''varname'' is just a constant, and the procedure addressed by ''set'' carries all the semantics. In Tcl, the command ''list unknown'' returns ''unknown'' because it is a constant. In Scheme, ''(list unknown)'' throws an error unless a symbol ''unknown'' is defined. If you want to list an unknown symbol, indeed, you need the special form ''(quote unknown)'' resp. its shortcut '' 'unknown''. * In Lisp, the special form ''quote'' is essential. * In Tcl, it is not necessary as it can be defined as a regular procedure as follows: ====== proc quote x { set x } ====== (Thank you, [RS], for the hint with the combinator ''[identity function%|%Identity]''!) ---- One interesting difference is that setting of (only global?) variables and function definition both are done with ''define'', which creates a lambda if its first element is a list. Just for experimenting, here's how to have that in Tcl: ====== proc define {what how} { if {[llength $what] == 1} { uplevel 1 set $what [list $how] } else { proc [lindex $what 0] [lrange $what 1 end] $how } } ====== ======none % define x 42 42 % define {+ x y} {expr {$x+$y}} % + $x $x 84 ====== This prevents us from having spaces in variable names (not a big problem), but presents the function name and arguments in one list, similar to how it will later be called - people sometimes wonder why we define `proc foo {x y} {..}` but call it `foo $x $y`... ---- [silas] 2018-11-14: LISP has the quote operator ('), as described above, but also has the backquote operator (`) that does what (in Scheme parlance) is called quasi-quotation. It will not eval anything unless lists followed by commas. Take the following Scheme code as an example: ======none (define (nl) (display "\n")) (define x 10) (define v '(display x)) (display v) (nl) (eval v) (nl) (define a 20) (define y `(display ,(+ a 10))) (display y) (nl) (eval y) (nl) ; Output is: ; (display x) ; 10 ; (display 30) ; 30 ====== In Tcl I've stumbled upon situations where I needed something similar. Usually people use `eval "..."` and escape `\$` and `\[` when don't want it to be evaluated, but it can lead to more or less unreadable code. I wrote a small method called xset that works just like [set], but replaces variables that start with `@`: ====== proc xset {var body} { # Look for own @ identifiers in $body set my_identifiers [regexp -inline -all {@[[:alpha:]]+} $body] set my_identifiers [lsort -unique $my_identifiers] set map_list [list] # Builds the map_list variable foreach my_ident $my_identifiers { set ident [string map [list "@" ""] $my_ident] upvar 1 $ident x # If upvar'ed variable does not exist, raise an error. if {[catch {lappend map_list $my_ident $x}]} { set raw_name [string map [list "@" ""] $my_ident] return -code error \ -errorinfo "can't read $raw_name: no such variable" } } # Make substitutions, set and return $body. upvar 1 $var x set body [string map $map_list $body] set x $body return $body } ====== And example to that would be: ====== set one 1 xset test { set one "test" set a $one set b @one } puts $test # outputs: # set one "test" # set a $one # set b 1 ====== How would you implement quasi-quotation in Tcl? <<categories>> Language | Functional Programming