Prev: Is there a IPTC and/or XMP tcl package (scripted or binary) out in the wild?
Next: How to profile a Tcl/Tk extension?
From: MartinLemburg on 15 Jan 2010 07:26 Hi Andreas, your "lappend" example made curious, so I did: % set d [expr {1.0}] 1.0 % rep $d value is a double with a refcount of 4, object pointer at 00D2AE60, internal representation 00000000:3FF00000, string representation "1.0". % lappend d x; rep $d value is a list with a refcount of 4, object pointer at 00DCC2D8, internal representation 00DC8070:00000000, no string representation. % rep [lindex $d 0] value is a pure string with a refcount of 4, object pointer at 00DCC428, string representation "1.0". % rep [lindex $d 1] value is a pure string with a refcount of 8, object pointer at 00D2B550, string representation "x". Why the hell the first element of the new list "d" is not a double anymore? Yes ... if a value given to a list command is not a list it is converted into a list - currently: 1. d contains a double 2. the contents of d are converted to list (with one atom) 3. the one and only atom of the list in d is converted to a string I expected: 1. d contains a double 2. the contents of d are converted to list (with one atom) 3. the previous content of d (double) is used as the one and only atom of the new list in d There is NO need for shimmering! If "d" would have no string representation, than it can be created from the internal object representation! Some days ago, we thought for our simulation application to create "complex" object types, hiding complex structures in C++ via a simple string. I'm glad, we didn't go this way, because not everybody is writing clean (non-shimmering) code and I'm afraid, that nearly nobody is able to write non-shimmering code! One example: % set d [expr {1.0}] 1.0 % rep $d value is a double with a refcount of 4, object pointer at 00D2AE60, internal representation 00000000:3FF00000, string representation "1.0". % llength $d 1 % rep $d value is a list with a refcount of 4, object pointer at 00D2AE60, internal representation 00D59720:00000000, string representation "1.0". % rep [lindex $d 0] value is a pure string with a refcount of 4, object pointer at 00D2B130, string representation "1.0". % set d [expr {1.0}] 1.0 % string is list $d 1 % rep $d value is a list with a refcount of 4, object pointer at 00DCC4A0, internal representation 00D63D98:00000000, string representation "1.0". % rep [lindex $d 0] value is a pure string with a refcount of 4, object pointer at 00DCC428, string representation "1.0". Even trying to detect a value being usable as list (string is list $d) causes the value in d to shimmer to a list with one pure string atom. I always thought, that all the "string is ..." usages won't alter any data pushed into this command, but even the following converts the internal object type: % set d [expr {1.0}] 1.0 % string is list $d 1 % rep $d value is a list with a refcount of 4, object pointer at 00DCC4A0, internal representation 00D63D98:00000000, string representation "1.0". % string is double $d 1 % rep $d value is a double with a refcount of 4, object pointer at 00DCC4A0, internal representation 00000000:3FF00000, string representation "1.0". Not that nice, isn't it? Using variables containing values of "complex" application specific tcl object types (e.g. 3D geometric facetted representations based on numerically exact 3D geometry, with a string representation describing the tesselation parameters) is so a bit risky, because this shimmering chaos (IMO) would cause a lot of actions of building up internal C++ structures and tearing them down again. And the more I dive into, the more I don't expect to be able to prevent shimmering! So a last question: may it be useful to have a "string is dict" capability to allow a quick conversion from a list to a dict? Best regards, Martin On 15 Jan., 12:14, Andreas Leitgeb <a...(a)gamma.logic.tuwien.ac.at> wrote: > Alexandre Ferrieux <alexandre.ferri...(a)gmail.com> wrote: > > See my other post: when rep says "string" it means > > typePtr==&tclStringType > > Yes, sorry, I saw that only after writing mine. > > Most of my comments were kind of voided then, but the one about > append is still strange to my understanding. > > >> % set d [expr double(1)]; append d "x"; rep $d > >> value is a string with a refcount of 3, object pointer at 0x9c24870, > >> internal representation 0x9c11cc8:0x3ff00000, string representation "1..0x". > > >> I'd really want to know, what the old internal rep turned to here...; > >> why doesn't rep name it a "pure string" now, and (nil)ify the secend rep? > > > Apparently [append] suffers from the same suboptimaliy. Will track it > > in the same bug report, thanks. > > But it's still all different from the format-case. > I'd have expected "append" to destroy all but any of the two string-reps, > So, in any case, I'd have expected the ":0x3ff00000" to disappear. > That this ":0x3ff00000" was still there was the reason why I even made > that goofy expr-test on it. Why is it *not* replaced by ":(nil)", as it > happens with other operations that eventually thwart the previous type, > like "lappend" ? > > % set d [expr {atan(1)*4}]; lappend d x; rep $d > value is a list with a refcount of 3, object pointer at 0x86528f8, > internal representation 0x8651848:(nil), no string representation. > > >> PS: Don't mind the refcounts. I've got Alex's original lastresult patch > >> compiled in (which accounts for the "4" in my first example) and I don't > >> know why it's 3 rather than 2 in the other cases. > > Flattered :) > > And I didn't even see that you were participating in this thread > when I wrote it :) > > > If you want to see a "1" as a refcount, I'd suggest: > > - ... > > - avoiding aliases > > Wasn't aware that aliases kept another ref, so now it's clear to me. > > Thanks! (also for the bugreport)
From: Kevin Kenny on 15 Jan 2010 08:24 MartinLemburg(a)Siemens-PLM wrote: > % set d [expr {1.0}] > 1.0 > % rep $d > value is a double with a refcount of 4, object pointer at > 00D2AE60, internal representation 00000000:3FF00000, string > representation "1.0". > % lappend d x; rep $d > value is a list with a refcount of 4, object pointer at 00DCC2D8, > internal representation 00DC8070:00000000, no string representation. > % rep [lindex $d 0] > value is a pure string with a refcount of 4, object pointer at > 00DCC428, string representation "1.0". > % rep [lindex $d 1] > value is a pure string with a refcount of 8, object pointer at > 00D2B550, string representation "x". > > Why the hell the first element of the new list "d" is not a double > anymore? > > Yes ... if a value given to a list command is not a list it is > converted into a list - currently: > > 1. d contains a double > 2. the contents of d are converted to list (with one atom) > 3. the one and only atom of the list in d is converted to a string > > I expected: > > 1. d contains a double > 2. the contents of d are converted to list (with one atom) > 3. the previous content of d (double) is used as the one and only > atom of the new list in d > That might be all right, but it's horribly complicated. The code in [lappend] tries to be fairly general; if it's confronted with a pure object, it has to stringify it in case it's not a single list element. (This can happen with the "pure String" internal rep that comes back from some of the operations, for instance.) To avoid the string conversion, we'd have to have special cases, "a double converts to a one-element list", "an integer converts to a one-element list", and so on. These would bloat the code and invite coding errors, to very little benefit. Observe that in any case, this code is really requesting shimmering (it constructs a double, and then treats it as a list!); avoiding it is as simple as: set d [list [expr {1.0}]]; # don't treat the double as a list, # but instead make a list containing it. lappend d x Here you construct the list explicitly from the double, and append a second element to it. The only shimmering occurs in the construction of the pure '1.0' result, and of course with that being a constant, you could save it off. -- 73 de ke9tv/2, Kevin
From: MartinLemburg on 15 Jan 2010 09:00 Hi Kenny, you are right - right coding can avoid shimmering, but taking a look at all the developers I know writing tcl code ... everyone is trying to be "on the line" of good coding, but everyone has its habits and style and even if everyone tries to full fill a style or development guide, it never really happens. And if some rapid developed code is introduced to be replaced later on, than this RaD code is often not that good either! Greet's, Martin On 15 Jan., 14:24, Kevin Kenny <kenn...(a)acm.org> wrote: > MartinLemburg(a)Siemens-PLM wrote: > > % set d [expr {1.0}] > > 1.0 > > % rep $d > > value is a double with a refcount of 4, object pointer at > > 00D2AE60, internal representation 00000000:3FF00000, string > > representation "1.0". > > % lappend d x; rep $d > > value is a list with a refcount of 4, object pointer at 00DCC2D8, > > internal representation 00DC8070:00000000, no string representation. > > % rep [lindex $d 0] > > value is a pure string with a refcount of 4, object pointer at > > 00DCC428, string representation "1.0". > > % rep [lindex $d 1] > > value is a pure string with a refcount of 8, object pointer at > > 00D2B550, string representation "x". > > > Why the hell the first element of the new list "d" is not a double > > anymore? > > > Yes ... if a value given to a list command is not a list it is > > converted into a list - currently: > > > 1. d contains a double > > 2. the contents of d are converted to list (with one atom) > > 3. the one and only atom of the list in d is converted to a string > > > I expected: > > > 1. d contains a double > > 2. the contents of d are converted to list (with one atom) > > 3. the previous content of d (double) is used as the one and only > > atom of the new list in d > > That might be all right, but it's horribly complicated. The code in > [lappend] tries to be fairly general; if it's confronted with a pure > object, it has to stringify it in case it's not a single list element. > (This can happen with the "pure String" internal rep that comes back > from some of the operations, for instance.) To avoid the string > conversion, we'd have to have special cases, "a double converts to > a one-element list", "an integer converts to a one-element list", > and so on. These would bloat the code and invite coding errors, > to very little benefit. Observe that in any case, this code > is really requesting shimmering (it constructs a double, and then > treats it as a list!); avoiding it is as simple as: > > set d [list [expr {1.0}]]; # don't treat the double as a list, > # but instead make a list containing it. > lappend d x > > Here you construct the list explicitly from the double, and append a > second element to it. The only shimmering occurs in the construction > of the pure '1.0' result, and of course with that being a constant, > you could save it off. > > -- > 73 de ke9tv/2, Kevin- Zitierten Text ausblenden - > > - Zitierten Text anzeigen -
From: Andreas Leitgeb on 15 Jan 2010 09:18 MartinLemburg(a)Siemens-PLM <martin.lemburg.siemens-plm(a)gmx.net> wrote: > your "lappend" example made curious, so I did: > % set d [expr {1.0}]; lappend d x; rep [lindex $d 0] > value is a pure string with a refcount of 4, object pointer at > 00DCC428, string representation "1.0". (somewhat contracted quote) I had this example in mind, too, but removed it from my post before sending it off, for two reasons: It distracted from the actual question: (why was that second (out-of-date) representation still visible in the result of [rep $d] *after* [append] had "destroyed" the old value?) And, converting a double (or int) directly into a list is not the common case, but rather a sign that one forgot to initially create a singleton list of that number. It's rather a coincidence that numbers can be "safely" reinterpreted as list of that number, and this coincidence does not extend to e.g. dicts. It's better to get used to distinguishing numbers and lists, than have tcl actively support that mixup which fails almost every- where except with numbers.
From: Alexandre Ferrieux on 15 Jan 2010 10:34
On Jan 15, 3:00 pm, "MartinLemburg(a)Siemens-PLM" <martin.lemburg.siemens-...(a)gmx.net> wrote: > Hi Kenny, > > you are right - right coding can avoid shimmering, but taking a look > at all the developers I know writing tcl code ... everyone is trying > to be "on the line" of good coding, but everyone has its habits and > style and even if everyone tries to full fill a style or development > guide, it never really happens. > > And if some rapid developed code is introduced to be replaced later > on, than this RaD code is often not that good either! Not sure exactly what you're arguing about here (please avoid top posting when the quoted message is rich), but note this: [append]'s shimmering to a string object or to a pure string is perfectly justified. (you'll also note I did't mention [append] in the bugreport's title for this reason) Why ? Because for all other types (Dicts, Lists, varied Numbers, Channels, etc), the result of appending is almost certainly not convertible to that type. And when it is, [appending] is just the most stupid way of doing it... So, it's not at all a matter of style or educated optimization, it's one of logic. If you want to be both fast and maintainable, stay in the definition domain of the type. To extend a dict use dict (or even list [*]) operations. To extend a list use [lappend]. But [append] is a string tool, period. Don't mix oil and water. -Alex [*] it turns out Lists and Dicts are friends, and have conversion shortcuts. |