Version 27 of First impressions with tcl/tk 8.5.0

Updated 2007-12-28 18:32:34 by JH

2007-12-26 HE This days I tried tcl/tk 8.5 the first time. Here my experiences with 8.5.0 on Windows XP with eTcl.

:-) nice, good, I like it; :-| neutral; :-( not so good, I don't like it, makes additional work:

  • :-) Checkbuttons are tristate.
  • :-| But why are the new ttk::checkbutton not tristate? (JH: it is, from the docs: The widget sets the alternate state whenever the linked -variable is unset. (The alternate state may be used to indicate a tri-state or indeterminate selection.))
HE Sorry! The ttk::checkbutton docu says: to indicate a tri-state or indeterminate selection.
This means. The programmer can find out if the ttk::checkbox is in tristate.
But there is no simple way to set the ttk::checkbutton in a state, to show the user the tristate.
The normal checkbutton have a -tristatevalue. If the variable named by -variable is set to the
-tristatevalue, the user see a checked box with gray background (default on w32).
: Perhaps this behavior can be simulate with ttk::checkbutton. But it's not in the docu. And I don't know how? So from my point of view
ttk::checkbutton are not tristate (or better ttk::checkbutton don't show tristate)
       checkbutton .c1 -variable c1 -onvalue a -offvalue b -tristatevalue c
       checkbutton .c2 -variable c2 -onvalue a -offvalue b

       pack .c1 .ce -side left

       set c1 a ;# .c1 checked (on)
       set c1 b ;# .c1 unchecked (off)
       set c1 c ;# .c1 checked with grey background (tristate)

       set c2 a ;# .c2 checked (on)
       set c2 b ;# .c2 unchecked (off)
       unset c2 ;# .c2 checked with fill-dot check (tristate) [JH] - as noted above
  • :-) {*} the reason why I tried 8.5.0
  • :-) lassign: I like the foreach-term but lassign looks faster:
       time {foreach {a b c} [list de da lus] {break}} 1000
       2.396 microseconds per iteration
       time {lassign [list de da lus] a b c} 1000
       1.632 microseconds per iteration
DKF: note that that's not a fair test of foreach; put each in a procedure or lambda term to test properly
HE I don't think the test is unfair. Both are one command, three variables, one list to generate with the same values, must be interpreted.
But for your reassurance:
       proc a {} {
              foreach {a b c} [list de da lus] {break}
              return
       }

       proc b {} {
              lassign [list de da lus] a b c
              return
       }

       time {a} 1000
       1.643 microseconds per iteration
       time {b} 1000
       1.234 microseconds per iteration
a. 1.643 / 2.396 => 68,6% time saved after bytecoded
b. 1.234 / 1.632 => 75,6% time saved after bytecoded
=> bytecoding saves ~70% time
=> lassign still looks faster
Is this what you mean?
DKF: Yes. Wow; while I wrote that code, I didn't expect a speedup in this situation as lassign is implemented as a whole load of bytecodes and foreach has specialist ones. Might be worth rethinking the foreach compiler...
  • :-( text widget: What's that. Font has changed to a fixfont. And from a normal font to a named font (returnvalue from [.t configure -font] changed). First breaks the look and feel in some of my scripts and last breaks compatibility. I had to change my scripts. JH: [option add *Text.font TkDefaultFont] may be the easiest "revert", but there is also ::tk::classic::restore.
  • :-) New ttk::notebook and peer widgets for text. A small editor in 8.5.0 for tests. The peer widgets works fine.
  • :-( ttk::notebook: tabs changes their size and becomes unreadable when windows size shrink. I expected arrowbuttons like the BWidgets notebook. Or, as an alternative, breaking tabs in additional rows. The bwidget way works better on small displays like pocketPC.
  • :-) ttk::combobox: Works fine. Easy to replace the BWidget ComboBox.
  • :-( ttk::treeview: A small try:
       ttk::treeview -show tree
       pack .t -fill both -expand 1
       .t insert {} end -id 1 -text de
       .t insert 1  end -id 3 -text da
       .t insert 1  end -id 4 -text lus
       .t insert 4  end -id 5 -text ika
       .t insert 4  end -id 6 -text rus
       .t insert {} end -id 2 -text foo
I'm missing the lines like in BWidgets Tree. In little more complex trees without the lines the tree becomes unclear.
  • :-( Ok. At this point the new widgets in 8.5.0 are not ready to replace BWidget in my scripts.

This are my personal first impression. And it covers only a small part of the new features.


AM This seems a good place to add a link to Mark Roseman's overview of Tcl/Tk 8.5: [L1 ]


2007-12-26 HE Some new impression:

  • :-) expression operators in and ni: Looks like a faster way:
       time {if {[lsearch -exact [list de da lus] {da}]!=-1} {}} 1000
       1.134 microseconds per iteration
       time {if {{da} in [list de da lus]} {}} 1000
       0.701 microseconds per iteration

       proc c {} {
	      if {[lsearch -exact [list de da lus] {da}]!=-1} {}
	      return
       }
       proc d {} {
	      if {{da} in [list de da lus]} {}
	      return
       }

       time {c} 1000
       1.417 microseconds per iteration
       time {d} 1000
       1.05 microseconds per iteration



       time {if {[lsearch -exact [list de da lus] {da}]==-1} {}} 1000
       1.132 microseconds per iteration
       time {if {{da} ni [list de da lus]} {}} 1000
       0.695 microseconds per iteration

       proc c {} {
      	      if {[lsearch -exact [list de da lus] {da}]==-1} {}
	      return
       }
       proc d {} {
	      if {{da} ni [list de da lus]} {}
	      return
       }

       time {c} 1000
       1.487 microseconds per iteration
       time {d} 1000
       1.05 microseconds per iteration
  • :-| Incr auto-initialization: The 'old' looks faster. The 'new' way looks better.
        unset n
        time {if {![info exists n]} {set n 0};incr n} 1000
        0.678 microseconds per iteration

        unset n
        time {if {![info exists n]} {set n 1} else {incr n}} 1000
        0.655 microseconds per iteration

        unset n
        time {incr n}
        8 microseconds per iteration
        unset n

        proc e {} {
	        if {![info exists n]} {set n 0};incr n
        	return
        }

        proc f {} {
        	if {![info exists n]} {set n 1} else {incr n}
        	return
        }

        proc g {} {
        	incr n
        	return
        }

        time {e} 1000
        0.921 microseconds per iteration
        time {f} 1000
        0.803 microseconds per iteration
        time {g} 1000
        1.864 microseconds per iteration