#instatiate the generic 'concat' procs for these types: if [llength [info commands p7proc]] { set Compiling true } else { set Compiling false source testing.tcl } if $Compiling { foreach T { byt utf uni int } { p7source generic_concat.p7i TYPE $T # define wrappers around those, with specific names using _$T, for calling from Tcl p7proc (int)length_$T " ($T*)a " { length $a } p7proc ($T*)concat_$T " ($T*)a ($T*)b " { concatenate $a $b } p7proc ($T*)to_uppercase_$T " ($T*)a " { to_uppercase $a } p7proc ($T*)to_lowercase_$T " ($T*)a " { to_lowercase $a } } } else { proc dump s { binary scan $s "h*" z set z } foreach T { byt utf uni } { # a quick test first AssertEq abcxyz { concat_$T abc xyz } # now some bigger tests set tcl_big "" set p7_big "" foreach left { "" 0 - Hello {Hello World!} \{ \\ \} } { foreach right { "" 0 - Hello {Hello World!} \{ \\ \} } { AssertEq "$left$right" { concat_$T $left $right } append tcl_big "$left$right" set p7_big [ concat_$T $p7_big [ concat_$T $left $right ] ] AssertEq $tcl_big {set p7_big} AssertEq [ string length $tcl_big ] {length_$T $p7_big} AssertEq [ string toupper $tcl_big ] {to_uppercase_$T $p7_big} AssertEq [ string tolower $tcl_big ] {to_lowercase_$T $p7_big} } } } AssertEq 3 { length_utf "abc" } AssertEq 1 { length_utf "\u0010" } AssertEq 2 { length_utf "\u0100" } AssertEq 3 { length_utf "\u1000" } Okay }