A '''reference''' is a generic term for a value that refers to data that is stored somewhere. Some important examples are: * Pointers (as in e.g. [C]) * Names of Tcl variables (see [upvar]) * ... A feature that is often expected from references in high level languages is that storages should automatically disappear (be freed/deallocated) when there are no more references to them. That kind of reference does not exist in Tcl. Some people coming from other languages are disturbed by this, but one doesn't need that kind of generic references as often as these people think. 下面是关于[url=http://www04.tt33tt.com]六合彩[/url]的公益广告,大家不要相信地下[url=http://www05.99bbcc.com]六合彩[/url]赌博,远离香港[url=http://cai.tt33tt.com]六合彩[/url]公司内幕,[url=http://k.88aabb.com]香港六合彩[/url]相关介绍,请不要沉迷于[url=http://6.88aabb.com]六合彩[/url]赌博, [url=http://d.99bbcc.com]六合彩[/url]奖券是[url=http://liuhecai.99bbcc.com]香港六合彩[/url]奖券管理局委托香港赛马会经办的一种奖券游戏;自1975年推出[url=http://n.tt33tt.com]六合彩[/url]以来,六合彩为香港政府库房及奖券基金带来超过180亿港元的收入,最有趣的是[url=http://g.88aabb.com]六合彩图库[/url]请大家不要参加地下博彩 ,“[url=http://www01.tt33tt.com]六合彩[/url]”与香港政府,[url=http://www02.tt33tt.com]香港六合彩[/url]博彩业非常发达,凡是挨上[url=http://www04.tt33tt.com]六合彩[/url]彩票营销的人都有钱可赚,因此一度卖[url=http://www02.99bbcc.com]香港六合彩[/url]的摊店如麻雀馆、牌九馆等遍地都是。香港 [url=http://www05.tt33tt.com]香港六合彩[/url]的合法化是在 1958 年。当年一次立法会议上,有人提议开办马票摇彩,用以筹集社会福利事业基金。为了推行[url=http://www04.99bbcc.com]六合彩[/url]这项成本低、风险小、获利大的[url=http://www04.88aabb.com]香港六合彩[/url]行业,香港政府在 1975 年成立了[url=http://www02.88aabb.com]香港六合彩[/url]“政府奖券管理局”。 [[Explain garbage collection and the like.]] [[It might also be reasonable to explain the distinctions between '''value''', '''variable''', and '''reference'''. Some languages have ''variables'' whose ''values'' are either '''real''' values if those values are ''primitive'' types or ''references'' if the values are ''structured'' types. Not all languages make the same distinctions. [Java], [Icon], and [Smalltalk] all have slightly different implementations of such things.]] See [TclRef] for an implementation of references for Tcl. ---- References touch upon one of the ways in which Tcl is different from many other languages. What could be called the "standard model" for complex data structures is that: * all values are atomic (scalar), structure (complexity) comes from how they are stored. A basic problem in this model is how to represent a thing that can contain other similar things. The solution is to introduce '''references''': scalar values that lets one access a (usually composite) storage. Some old languages (Algol, old Fortran) couldn't do this in general and as a result had severe restrictions, whereas others ([Pascal]) just barely provide the basic functionality. [C] and [Lisp] were probably the first languages in their respective families to have all the kinks worked out, and owe some of their popularity to that fact. In low-level languages the references are just bare memory addresses (pointers) to a block of memory and the structuring of storage is just a way of labeling offsets within this memory block. In higher level languages there usually exist more flexible ways of structuring storage (variable-length lists, "hashes", etc.) but the role of the references is the same. Every data structure that is not predefined in the language has to be implemented by connecting more basic data structures using references. '''Tcl does not follow this standard model''', because in Tcl everything is a string. Since a [list] can contain arbitrary strings it follows that a list can be a list of other lists, or a list of lists of lists, or whatever, nested to arbitrary depth. The basic problem of a thing containing other similar things can be solved without resorting to references. (Although of course, since Tcl is implemented in C, there are references "under the hood". Keeping them hidden is however often a strength!) [SS] notes that the point is not nesting, but linking. Also note that Tcl already uses (non garbage collected) references: when you pass/return a variable name in place of the content you are using something of similar to references. The same when you use a namespace name (that encapsulates an object) using some kind of OO extension and any other kind of name. Another example is when you pass/return the key inside an array in place of the value contained. All this are references. [Lars H]: The point is that in the standard model even nesting requires references in the language, whereas Tcl can do nesting without resorting to references. Surprisingly much of what people think they need automatically garbage-collected references for is precisely nesting. [SS]: Standard model? well known high level languages: Perl, Python, both have references, but both don't require explicit references to do nesting: they allow lists of lists and arrays of arrays (Tcl seems to be lacking even in this respect thanks to the wonderful arrays we had before [dict]). Of course this languages *actually* are using references to create this structures, so if you pass a list of list to a function that alter it without to use __deepcopy__ or something like it you are going to see the difference, but you can still write: y = [[1, 2, 3, [[5, 6, 7]]]]. Even PHP is able to nest arrays (and in such a case I think they are passwd by value like in Tcl). So you are comparing a low level language like C with Tcl, *if* for standard model you mean C. Also note that in C, FORTH and so on nesting requires user-handled pointers because they use non-automtic memory managment. You can still write a couple of functions in C able to deal with strings representing Tcl Lists that are a single big string, so even without pointers C is able to nest. We should really not get used to Tcl design peculiarities, like broken arrays, unability to build linked data structures, and so on. We have a great language because it's simple, able to do great abstractions with strings, with great introspection capabilties, that allows us to rewrite most of the language itself at the point to create OO systems, new control structures, and many other stuff that are only a privilege of Lisp, SmallTalk, and stack based languages. All this with an ability to deal with real world problems that seems quite superior to other (possibly more powerful) languages that brings the same freedom to the programmer. But there are things that are a limit without doubt. References are in the nature of computation: the ability for two objects to reference a third other object without to have both a copy is something like you can't miss to do some kind of works. I agree that all is a value is still an advantage for Tcl: to change it to have implicit references like lisp/python/... is not a win for Tcl, really, but why we should not have something like [TclRef]? This is disigned so that references are explicit: strings, that identify containers that are automatically empty if no one is still interested in the content. [Lars H]: I do '''not''' think the "standard model" is something which applies only to such low-level languages as C. Lisp is included in the description above. I ''know'' that [Postscript] follows the standard model (and the manual has to be quite explicit about it, since you're not allowed to store a reference to local VM thingie in global VM); even strings are not atomic. I don't have personal experience of Perl, but http://www.garshol.priv.no/download/text/perl.html#id3.3. (the final period is part of the URL, the Wiki gets it wrong for some reason, even when between brackets) claims that references are indeed necessary to work with lists of lists in that language. One language which has both structured values and references is the Maple [http://www.maplesoft.com/] command language, and at least in that case the structured values are straightforward whereas the references are a constant source of trouble. The most striking example comes from comparing lists and vectors. Maple lists are values just like Tcl lists. Maple vectors are a special case of Maple arrays, which are a special case of Maple tables, and these are referenced storages (presumably not unlike Perl hashes). Both look precisely the same when shown in the worksheet, but they behave very different. L:=[1,t,t^2]; f:=unapply(L,t); creates a function f such that f(2) returns [[1,2,4]], but v:=vector([1,t,t^2]); g:=unapply(v,t); creates a function g which returns the vector [[1,t,t^2]] no matter what you give it. In order to get g work in the same way as f, you need to dereference v before handing it to unapply. g:=unapply(eval(v),t); As for [TclRef], does it obey the idiom that everything is a string? What happens if someone goes eval lappend refs [linsert $otherRefs 0 [newRef xxx]] will the things appended to $refs still be references? (Sure, it is silly to do it that way, and in Tcl 8.5 there is {expand}, but for Tcl values it should work! If it doesn't then the ability to embed values in scripts has been severely limited.) ---- [davidw] Everything is not a string in Tcl. Files and namespaces come to mind right away. In my years on this planet, I have developed a healthy skepticism about "every" and "any". Usually (not every time;-) they are wrong. ---- ''Discussion moved here from [Why adding Tcl calls to a C/C++ application is a bad idea]:'' [davidw] - And this is still an area where Python has us beat: * Python has one, reasonably good OO system * Python objects are GC'ed, making them easier to use in scripts. Tcl objects must be destroyed by the programmer. * Python has references, which are also useful for doing data structures. Of course, it's not impossible to do this in Tcl... there are numerous testaments to the intelligence and cleverness of Tcl programmers on this wiki that put paid to that notion. However, what we need to keep in mind is the programmer examining both languages for the first time. It is not obvious how to handle complex data structures in Tcl, as compared with Python, Ruby or other scripting languages. ---- '''?''': Some arguments are not correct * [XOTcl] is better object system than Python. Tcl is flexible to write OO-Systems (see [snit]) * In XOTcl not all object need to be explicit destroyed (without GC). There are subobjects and volatile objects that are destroyed automatic. ---- [Artur Trzewik] In fact XOTcl Objects names are references. Objects are referenced by their names. I do not see big difference amoung C Point *point = Alloc(sizeof(Point)); Free(point); C++ Point *point = new Point(); delete point; C# Point point = new Point(); point = null; Smalltalk | point | point := Point new. point := nil. XOTcl set point [Point new] $point destroy set point [Point new -volatile] # if object sould life only in current block In all cases point is such kind of reference to object (structure) of type Point. '''Memento''' By using of OO in Tcl we not need really any additional references. About GC in OO-Tcl. I programm this language about several years and after big period with Smalltalk programming I would also like GC in Tcl. But till now I do not very miss GC in XOTcl. There are techniques like volatile objects and subobjects that make destroing of many objects very simple. The C++ problems with forgotten objects (dangling objects) do not occurs in XOTcl. On the other side. Releasing objects (destroying) are very important period of object life-time that sould be controlled by programm. I have seen many problems with smalltalk memory handling because the programmer have forgotten to do this magic ( point := nil.) in some global references. Also with GC you have to care about object releasing and you do not have full control about it. It is also interesting to see some C++-programmers arguments agains GC. ---- [davidw] - XOTcl looks ok, but it's not available in ActiveTcl or the default starkit setup and there are no books about it. Even the .deb's have been pulled (I might be convinced to work on fixing at least that...). This is the problem with not having one standard thing. Also, the 'volatile' objects, from what I see on the docs, depend on living in a particular Tcl procedure. I don't want that, I want something that goes away when nothing else references it. The object system may be 'better' than python's or ruby's or something else, but for the new user, the situation looks like a mess. It's something I think we'll have to face up to if we want to program in this "Tcl is the controlling application" style, and promote it to the world at large. ---- [Lars H]: IMO, '''references are evil'''. I cannot recall a single case where using references would have simplified a programming task or would have lead to a better solution. Indeed, I do not know of ''any'' problem where the asymptotic complexity is smaller in a computing model with references than it is in current Tcl (i.e., without references). But feel free to enlighten me if you have an example. [davidw]: The classic example of having references/OO/GC make life easier is the http package. It requires you to do a 'cleanup', because otherwise it will never be GC'ed. [jcw] - Another example is when you want to create Tcl commands and nest them yet clean up automatically. The [Vkit is a vector engine] page goes into an example and tries to find a solution, but it really applies to a lot of problem domains, let's say matrices: set a [$matrix invert] set b [$a transpose] set c [$b invert] $c print I'd like to write: [[[$matrix invert] transpose] invert] print And have everything clean up after use, i.e. the Tcl commands. That's where Python's "matrix.invert().transpose().invert().print()" makes life a lot easier. Even C++'s constructors/destructors with temporaries support such an idiom, with automatic cleanup. [Lars H]: The catch in both examples is that they are of ''idioms'' that require references rather than actual ''problems'' (i.e., something which is solved with an algorithm) that need them. HTTP communication is, as I understand it, completely stateless -- hence there should be no need to create anything that needs to be GC'ed. I find the matrix example almost proposterous. Matrices are data, so why should they ever be make commands? What is wrong with print [invert [transpose [invert $matrix]]] ? [RS]: The former form can be read from left to right to indicate the temporal order of the nested methods, while the latter requires the reader to read from right to left, as usual with nested functions (and APL), but less in Western cultures... [jcw] - Lars, you say "matrices are data" - I see them as objects. Instances of a class, in OO terms (as in Python, C++, Smalltalk). An example which interests me more than matrices btw, is relational algebra [http://www.equi4.com/ratcl.html]. If you brush aside examples where Tcl commands are used as objects, and with it the issue of object cleanup, so be it. Your example uses a namespace to identify operators and apply them to data, the OO model takes objects and makes them respond to methods/messages. Polymorphism, encapsulation - you're free to not care about that, of course. [Lars H]: Well, I suppose I the OO hype must have missed me, because I tend ''not'' to see things as objects, and since this furthermore seems to save me a lot of trouble I'm only glad for it. Polymorphism does not require referenced objects. I can agree that the "object on which a method is acting" view is sometimes appropriate, and I have on some occations suggested using it, but matrix arithmetic does hardly lend itself to that view. When all operations create new things from old then it isn't objects you're working with, but values! The Ratcl you refer to looks like a very striking example of this -- is there ''anything'' (apart from your preferences with respect to syntax) that prevent you from implementing views as Tcl values? (And you can of course have any syntax you like, if you just bite the bullet and create a proper [little language].) ''[jcw] - State.'' ---- The problem with the idea that "references are evil" is that Tcl is full of references. $foo is following a reference to the value of foo. [foo] is following a reference to the procedure called foo. The only difference is that in Tcl there are no exposed "unnamed" references, and all dereferencing operations are symbol table lookups. But Tcl post 8.0 is no longer really an "everything is a string" language, it's an "everything can be made to look like a string" language. So there's no reason not to have unnamed references, they can be efficiently thrown around and shimmered into some unique token (eg ::ref::array_40AB65003) when they're used in a string context. Theis would also make it possible to cut down significantly on the shimmering that happens in lists, you'd just leave them a list of references until the list has to be dealt with as a string. -- Peter da Silva ---- [[ [Category Concept] ]]