The BLT Toolkit is an extension to Tcl and Tk. It adds new commands and widgets to the Tcl interpreter. Included widgets are 2D graph, barchart, stripchart, tab notebook, and tree viewer.
Since I am lucky enough to be the first Wiki contributor, I must begin by expressing a universal, I am sure, love and admiration for this amazing, outstanding bit of code craftsmanship.
Thanks, George A. Howlett! You have created an indispensable tool.
BLT 2.4z has been the mainstay of most Linux distributions for a while and, unfortunately, the recent changes to the code here have not yet made it through to the distribution channels. I wanted to make my code run under either the 2.x series or under the current 3.0 (4.0? in Readme) versions if you downloaded/compiled/installed that from this sourceforge location.
These are some of the tricks I had to use:
if{[catch{setBLTversion[packagerequireBLT]}]}{putsstderr"BLT package is missing, maybe `sudo apt-get install blt`\n";exit1}else{if{![packagevsatisfies$BLTversion3]}{setBLT30}else{setBLT31}}if{[infoexistsBLTversion]}{if{[catchnamespaceimport::blt::*]}{;# in BLT3 blt::scale conflicts with tcl/tk scalenamespaceimport::blt::graphnamespaceimport::blt::vectornamespaceimport::blt::markernamespaceimport::blt::element}}
Then, later on I can use the BLT3 flag to identify the incompatible bits of code:
if {$BLT3} {
if { [infoexistsx] } { vectordestroyx } ; vector create x -length $sizeif { [infoexistsy] } { vectordestroyy } ; vector create y -length $size
} else {;# BLT 2.x allowed to re-create existing vectorsvectorcreatex($size)y($size)
}
BLT v.3 significantly changed the syntax of the vector command. Since a lot of places are still running v.2.47z, trying to write universal code requires accommodations like these:
procnewVector{namelen}{#BLT2.xallowedtore-createexistingvectors,#thisisnecessaryinBLT3butwillalsoworkinBLT2.xglobalBLT3$nameif{[infoexists${name}]}{vectordestroy${name}}if{$len!=""&&$len>0}{if{$BLT3}{vectorcreate${name}-length$len#BLT3initializestoNaN,restoreBLT2.xbehaviourofinitializingto0.0set${name}(:)0.0}\
else{vectorcreate${name}($len)}}\
else{vectorcreate${name}}}#takecareoftheBLTv.2.xsyntax:"vector create x y(5) z..."procvectorsCreate{lv}{foreachv$lv{setv_name[lindex[split$v()]0]setv_len[lindex[split$v()]1]newVector$v_name$v_len}}
With the above, both newVector x 5 and vectorsCreate {y(3) z t(0)} (which is a slight modification of what in v.2.47z would have been vector create y(3) z t(0)) work fine under all versions of BLT.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Since the create operation has switches in 3.x, the old syntax of
blt::vector create /arrayName/(/len/) ...
*
*
could not be cleanly maintained. [The idea in 2.x was to have the
vector look like a data type instead of a command.]
**
You would still have to set the values to 0.0 to replicate the 2.x behavior.
--gah
On 7/6/22 18:27, Edward Sternin wrote:
BLT v.3 significantly changed the syntax of the |vector| command.
Since a lot of places are still running v.2.47z, trying to write
universal code requires accommodations like these:
|procnewVector{namelen}{#BLT2.xallowedtore-createexistingvectors,#thisisnecessaryinBLT3butwillalsoworkinBLT2.xglobalBLT3$nameif{[infoexists${name}]}{vectordestroy${name}}if{$len!=""&&$len>0}{if{$BLT3}{vectorcreate${name}-length$len#BLT3initializestoNaN,restoreBLT2.xbehaviourofinitializingto0.0set${name}(:)0.0}\else{vectorcreate${name}($len)}}\else{vectorcreate${name}}}#takecareoftheBLTv.2.xsyntax:"vector
create x y(5)
z..."procvectorsCreate{lv}{foreachv$lv{setv_name[lindex[split$v()]0]setv_len[lindex[split$v()]1]newVector$v_name$v_len}}|
With the above, both |newVector x 5| and |vectorsCreate {y(3) z t(0)}|
(which is a slight modification of what in v.2.47z would have been
|vector create y(3) z t(0)|) work fine under all versions of BLT.
Sorry, @ghowlett, I may have been unclear. It's the loss of ability to declare multiple vectors on one line that represents a discontinuity in syntax:
$ bltsh30
% blt::vector create x(5) t w
unknown switch "t"
The following switches are available:
-variable varName
-command command
-watchunset bool
-flush bool
-length length
although I just noticed that there is in v.2.5.3 from blt-dev an option: vector configure -oldcreate bool which may be doing what I had in mind:
The configure operation sets the default options used in creating vectors: ... The -oldcreate enable the creation shortcut: vector vec1 vec2 ...
However, this seems to not have been included in 3.0, so it's probably one of the non-canonical changes made in a fork of the BLT. It does seem like a reasonable approach, though I still think that simply preserving the old flexible syntax would be my first choice.
Even in the new syntax, I think the multiple-vector option could be maintained: all switches begin with a -, so in
vector create x -length 5 t w
it's pretty clear that vectors t and w would have a zero length. Or one could use
vector create x -length 5 -- t w
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you don't use the "create" keyword, then you can still create
multiple vectors with the same command. This works in both 2.x and 3.x.
bltsh30
% blt::vector x(30) y(30) z(30)
I'm not 100% clear as to why syntactical compatibility between 2.x and
3.x is needed. Nor why the vectors need to created in a single command.
Is this because the TCL code making the call can't be changed?
[It wasn't my goal in 3.x to be 100% backward compatible with 2.x
syntax. The addition of switches to the create operation superseded
maintaining the old syntax.]
I don't know anything about 2.5.3.
--gah
On 7/11/22 19:20, Edward Sternin wrote:
Sorry, @ghowletthttps://sourceforge.net/u/ghowlett/, I may have
been unclear. It's the loss of ability to declare multiple vectors
on one line that represents a discontinuity in syntax:
|$ bltsh30 % blt::vector create x(5) t w unknown switch "t" The
following switches are available: -variable varName -command command
-watchunset bool -flush bool -length length |
The configure operation sets the default options used in creating
vectors: ... The -oldcreate enable the creation shortcut: vector
vec1 vec2 ...
However, this seems to not have been included in 3.0, so it's probably
one of the non-canonical changes made in a fork of the BLT. It does
seem like a reasonable approach, though I still think that simply
preserving the old flexible syntax would be my first choice.
Even in the new syntax, I think the multiple-vector option could be
maintained: all switches begin with a |-|, so in
|vector create x -length 5 t w |
it's pretty clear that vectors |t| and |w| would have a zero length.
Or one could use
Oh, I see! Vectors get created even without create! This might be good enough.
I'm not 100% clear as to why syntactical compatibility between 2.x and
3.x is needed. Nor why the vectors need to created in a single command.
Is this because the TCL code making the call can't be changed?
The reason for my initiating this compatibility discussion is this: if I want to write a code that I can distribute (to students, for example) I need to anticipate the environment in which they will be using it. The vast majority of Linux distributions out there use a fork of BLT which calls itself "v 2.5.3" - just because there is a convenient Debian/Ubuntu package of it that is installed by default by apt install blt. ActiveTCL which dominates the Windows world has dropped support for BLT altogether, although one can still find a v.2.4.7z that will install and run there. We tend to recommend to Windows users undroidwish/vanillawish which has BLT 2.4.7z built in, and this also works under Android and MacOS (androwish.org).
And I keep hoping to return all the "strays" back to this mother project. Maybe when the official version 3.0 is released , it will be picked up by the Debian/Ubuntu maintainers. Not everyone will be willing to install from source.
That is why I found myself needing to focus on robust code that runs under all flavours of BLT. As to the preference for making multiple vectors in a single command: that's just a desire for compactness and similarity with variable declarations in any other language, and a mild irritation at having to modify perfectly good code that's been running for years.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Very simple but useful things that are missing in v.2.x : [x min] and [x max]. This is difficult to overcome (my shortest version is x dup xx; xx sort; puts "$xx(0)" for min), and the best workaround I found is to use critcl:
packagerequireBLTnamespaceimport::blt::*packagerequirecritclcritcl::clibraries-lBLTcritcl::ccode{#include <tcl.h>#include <blt.h>}critcl::cprocminValue{Tcl_Interp*ipTcl_Obj*v}double{Blt_Vector*vp;Blt_GetVector(ip,Tcl_GetString(v),&vp);returnvp->min;}critcl::cprocmaxValue{Tcl_Interp*ipTcl_Obj*v}double{Blt_Vector*vp;Blt_GetVector(ip,Tcl_GetString(v),&vp);returnvp->max;}vectorcreatex;xseq50-1puts"$x(:) is from [minValue x] to [maxValue x]"
the Blt_Vector structure in C simply has the min/max within it, but in v.2.x access to them is not provided. The above will work under all versions, fast and with no memory overhead.
Unless I missed something and @gah can correct me.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Since I am lucky enough to be the first Wiki contributor, I must begin by expressing a universal, I am sure, love and admiration for this amazing, outstanding bit of code craftsmanship.
Thanks, George A. Howlett! You have created an indispensable tool.
BLT 2.4z has been the mainstay of most Linux distributions for a while and, unfortunately, the recent changes to the code here have not yet made it through to the distribution channels. I wanted to make my code run under either the 2.x series or under the current 3.0 (4.0? in Readme) versions if you downloaded/compiled/installed that from this sourceforge location.
These are some of the tricks I had to use:
Then, later on I can use the BLT3 flag to identify the incompatible bits of code:
Last edit: Edward Sternin 2020-02-11
BLT v.3 significantly changed the syntax of the
vector
command. Since a lot of places are still running v.2.47z, trying to write universal code requires accommodations like these:With the above, both
newVector x 5
andvectorsCreate {y(3) z t(0)}
(which is a slight modification of what in v.2.47z would have beenvector create y(3) z t(0)
) work fine under all versions of BLT.I believe the syntax
blt::vector /arrayName/(/len/)
works the same in both versions.
Since the create operation has switches in 3.x, the old syntax of
blt::vector create /arrayName/(/len/) ... * * could not be cleanly maintained. [The idea in 2.x was to have the
vector look like a data type instead of a command.]
**
You would still have to set the values to 0.0 to replicate the 2.x behavior.
--gah
On 7/6/22 18:27, Edward Sternin wrote:
Sorry, @ghowlett, I may have been unclear. It's the loss of ability to declare multiple vectors on one line that represents a discontinuity in syntax:
although I just noticed that there is in v.2.5.3 from
blt-dev
an option:vector configure -oldcreate bool
which may be doing what I had in mind:However, this seems to not have been included in 3.0, so it's probably one of the non-canonical changes made in a fork of the BLT. It does seem like a reasonable approach, though I still think that simply preserving the old flexible syntax would be my first choice.
Even in the new syntax, I think the multiple-vector option could be maintained: all switches begin with a
-
, so init's pretty clear that vectors
t
andw
would have a zero length. Or one could useI think it was me that was probably unclear.
If you don't use the "create" keyword, then you can still create
multiple vectors with the same command. This works in both 2.x and 3.x.
bltsh30
% blt::vector x(30) y(30) z(30)
I'm not 100% clear as to why syntactical compatibility between 2.x and
3.x is needed. Nor why the vectors need to created in a single command.
Is this because the TCL code making the call can't be changed?
[It wasn't my goal in 3.x to be 100% backward compatible with 2.x
syntax. The addition of switches to the create operation superseded
maintaining the old syntax.]
I don't know anything about 2.5.3.
--gah
On 7/11/22 19:20, Edward Sternin wrote:
Oh, I see! Vectors get created even without
create
! This might be good enough.The reason for my initiating this compatibility discussion is this: if I want to write a code that I can distribute (to students, for example) I need to anticipate the environment in which they will be using it. The vast majority of Linux distributions out there use a fork of BLT which calls itself "v 2.5.3" - just because there is a convenient Debian/Ubuntu package of it that is installed by default by
apt install blt
. ActiveTCL which dominates the Windows world has dropped support for BLT altogether, although one can still find a v.2.4.7z that will install and run there. We tend to recommend to Windows users undroidwish/vanillawish which has BLT 2.4.7z built in, and this also works under Android and MacOS (androwish.org).And I keep hoping to return all the "strays" back to this mother project. Maybe when the official version 3.0 is released , it will be picked up by the Debian/Ubuntu maintainers. Not everyone will be willing to install from source.
That is why I found myself needing to focus on robust code that runs under all flavours of BLT. As to the preference for making multiple vectors in a single command: that's just a desire for compactness and similarity with variable declarations in any other language, and a mild irritation at having to modify perfectly good code that's been running for years.
Very simple but useful things that are missing in v.2.x :
[x min]
and[x max]
. This is difficult to overcome (my shortest version isx dup xx; xx sort; puts "$xx(0)"
for min), and the best workaround I found is to use critcl:the
Blt_Vector
structure in C simply has the min/max within it, but in v.2.x access to them is not provided. The above will work under all versions, fast and with no memory overhead.Unless I missed something and @gah can correct me.