Re: [Tcl9-cloverfield] Vector index references
Status: Alpha
Brought to you by:
fbonnet
From: Andy G. <unu...@ai...> - 2009-01-19 16:02:03
|
"Frédéric Bonnet" <fre...@fr...> wrote: > So you're doing away with insert and replace it with set on a > pseudo-index. Interesting, I like the idea. It also unifies > insert/replace/append depending on the index and whether the sublist > is empty or not. [list insert] and [list replace] will still exist for use in functional contexts. For example, they can be used to modify the result of a command substitution before passing it to another command as an argument, without using an intermediate variable. [list index] will likewise exist, the same as single-argument [set], even though both are (hopefully!) the same as certain substitution mechanisms built into the language. But sometimes you simply must have a command name. But yes, my idea is to simplify the common imperative case. "Construct a list by doing X to the value of FOO and store that list into FOO." That's what Tcl has (except for [lset] and [lappend]). "Do X to FOO." That's what I'm shooting for. I do not want to have [lset] and [lappend]. I don't want [dict append], [dict incr], [dict lappend], [dict set], [dict unset], or [dict update] either. [dict with] I will have to think about. If imperative is the opposite of functional, does that mean it's dysfunctional? Tcl supports both. Does that mean it's schizophrenic? ;^) > BTW I suppose that for symmetry unset removes elements. Yup! I want to minimize the number of commands that have side effects. It's like the Sluggy Freelance Harry Potter parody. The question came up: Why is everyone in House Wunnybun (Slytherin) evil? The answer: We like to keep all our bad guys in one place; it makes the paperwork simple. So I'd like to keep all of our "bad guys" (commands that change the state of the interpreter) in one place: [set], [unset]. Also I'd like for as many other imperative commands as possible to be (conceptually) implemented in terms of [set] and [unset]; for example, the way I have lambdas and command invocation defined, [proc &name arglist body] is like [set &name (arglist body)]. Can we make [set &var ${var}suffix] as fast as [append &var suffix]? > However are references to sublists "live"? I think I should put off the sublist (a.k.a. slice) reference question until I can nail down the single-element case! Here, try this: set &var (0 1 2 3) set &ref1 &var{end} set &ref2 &var{3} puts "$ref1 $ref2" -> 3 3 set &var{-1} prepend puts $var -> prepend 0 1 2 3 puts "$ref1 $ref2" -> 2 3 set &var{end+1} append puts $var -> prepend 0 1 2 3 append puts "$ref1 $ref2" -> 2 append &ref1 and &ref2 originally referred to the same element, but after prepending to the list, they wound up referring to different elements. Why? Because &var{end} and &var{3} only refer to the same element when &var is a four-element list. I think this might be an example of what you call "live". I'm pretty sure this quandary is due to my reference behavior being incorrect. Perhaps at time of reference construction, the reference should be bound to a particular element, without regard for the possibility of the "path" changing over time. Example: set &var (0 1) set &index 0 set &ref &var{$index} puts $ref -> 0 set &index 1 puts $ref -> 0 Here, &ref continues to refer to 0 even after changing $index. Using the same semantics, the earlier code and printouts change to: set &var (0 1 2 3) set &ref1 &var{end} set &ref2 &var{3} puts "$ref1 $ref2" -> 3 3 set &var{-1} prepend puts $var -> prepend 0 1 2 3 puts "$ref1 $ref2" -> 3 3 set &var{end+1} append puts $var -> prepend 0 1 2 3 append puts "$ref1 $ref2" -> 3 3 Now the question is: what happens on [unset]? I think that unsetting one of the references should just delete the reference. Unsetting &var or &var{4} will cause the references to lose their string representation. After that, what if these references are used to set a value again? If &var was unset, I imagine this will cause &var to be created and set to a single-element list. If &var{4} was unset, this may cause a new element to be inserted between 2 and append. Another option which may be preferable is to forbid using a reference to a deleted element as the argument to [set]. A third option is to allow it but make no attempt to modify &var; perhaps they lose their referencehood and just become ordinary variables; or perhaps &ref1 and &ref2 continue to be linked, but they are no longer linked to &var. Tricky stuff!! I hope this isn't premature, but let me take a stab at sublist references. If a single-element reference is bound to a particular element at the time the reference is constructed, then a sublist reference should be bound to a pair of "anchor" elements, which serve as indexes. set &var (0 1 2 3) set &ref &var{1:2} puts $ref -> 1 2 set &var{2:} 1.5 puts $var -> 0 1 1.5 2 3 puts $ref -> 1 1.5 2 On [unset] of an anchor element, the sublist reference could become a reference to a deleted object, as described above. I don't think I like this. It could also remain valid but have its anchor element updated, like so: set &var (0 1 2 3) set &ref &var{1:2} unset &var{1} puts $ref -> 0 2 unset &var{2} puts $ref -> 0 3 unset &var{0} puts $ref -> 3 unset &var{0} puts $ref -> {} set &var (a b c d e f g h i j k l m n o p q r s t u v w x y z) puts $ref -> a b c d e f g h i j k l m n o p q r s t u v w x y z The last line is explained by the anchor elements having become the start and the end of the list, so effectively &ref became a reference to &var, not to any particular sublist. I don't think I like this either, since it's otherwise not possible to create a reference to a sublist anchored at end, where the meaning of "end" updates when elements are appended to the list. I sincerely hope it doesn't become idiomatic to add an extra element to a list, create a reference, then delete the extra element. So there's more problems. Everything I said above also applies to pointers. Your thoughts? > On my side I've worked a bit on the whole concept of vector indexing, > and I'm replacing it by the more general concept of "selector" of > which flat indexing is the simplest case. More on that later (I'm > working on a revision of the syntax). I'd be interested to see if this simplifies any of this stuff I've been thinking about. > I don't want to provide features that are too difficult to use (or > implement) from C as I want to keep the dual nature of Tcl. The dual nature of Tcl? Do you mean how it is useful both as a scripting language and a C library? Either can be used without the other, and they can be used together within a single project. > So with the concept of selector I can address the various access > semantics that usual container classes can provide (the C++ STL is > a good start) Much of the STL is made unnecessary by Tcl's built-in strings, lists, and dictionaries. So it is not necessary to emulate all of it. Sure, use it as a source for ideas, but don't set any semblance of compatibility with it as a goal. Take iterators, for example. I suppose they could be similar to pointers, except that they are constructed by means of a command and that they are callable and have subcommands. Like pointers, they can be "followed" with a trailing @. Unlike pointers, they can be updated to point to the "next" element (or whatever), using a subcommand. By callable, I mean that one can type the name of the variable containing the pointer as the first word of the command line. But also consider that C++ iterators over linked lists are important for performance but harder to use than numeric indexes into arrays. Tcl doesn't have this performance problem (*cough* *cough* what I really mean is that it's not something that can or should be dealt with at the script level), so what's the point of iterators over linked lists? C++ iterators can be stored and passed around, but so can my pointers and references. C++ iterators can be compared, incremented, and decremented. Is that worth it? Instead just pass the whole damn list! Or a sublist, or reference thereto. Want reverse iterators? Use -1 stride. > allowing custom object types to introduce their own indexing methods > (e.g XPath for XML elements). Still, the two types of indexing will be vectored and keyed. You're saying that custom objects can provide their own implementations for these. I'd like to see this power exposed at the script level. ;^) -- Andy Goth | http://andy.junkdrome.org/ unununium@{aircanopy.net,openverse.com} |