On 19 August 2010 18:50, Abigail <abigail@abigail.be> wrote: > On Fri, Aug 06, 2010 at 12:24:36PM +0000, Ęvar Arnfjörš Bjarmason wrote: >> >> I don't think the point is that we should *guarantee* that FETCH will >> only be called once per "logical access". But that we shouldn't make >> any guarantees *at all*. >> >> I.e. explicitly document that if you write a tie class you shouldn't >> depend on how many times FETCH and friends are called, since they may >> be called by the core at unexpected times, and those times may change >> without warning in future releases. > > > Well, that may be the easy way out, but does that improve the usefulness > of the language? I'm sure it makes it easier for a language implementation > if > > f () OP g () > > does not make any promises how often f() and g() are called when evaluating > the expression. But one has to question whether that's useful for an imperative > language. > > IMO, if $x and $y are tied, > > $x OP $y > > should just be a shortcut for > > (tied ($x) -> FETCH) OP (tied ($y) -> FETCH) > > > I don't think many people will argue you should write f() and g() in such a > way that Perl is free to call f() and g() as many times as it pleases > when writing > > f () OP g (); > > > And I fail to see why tied variables should be except. This debate has drifted as far as I can see and you seem to be arguing against a straw man. So let me recap. The question as I understand it was originally what should happen when we have an expression of the form: $x OP $x and what should happen if the fetch method of the tie CHANGES the package the variable is tied to. Should we guarantee that BOTH methods are called? In other words do we have to recheck the magic associated to a variable EVERY access? It was then observed that outside of certain logical operators we actually do not make any guarantees of the /order/ in which the fetch methods are called, which in turn implies that any such statement is undefined. Consider a variable $x that is tied to a package with a fetch method that encapsulates a counter which increments each fetch. For the expression: $y= $x / $x + $x; we could end up with any of the following: $y= 1 / 2 + 3; $y= 2 / 3 + 1; $y= 3 / 1 + 2; $y= 3 / 2 + 1; etc.... Note that switching to sub calls DOES NOT change this situation: $y= x() / x() + x(); is similarly undefined for x()'es which are not true mathematical functions. This then lead some to propose that we simply state that we evaluate variables only once per expression. Others object, and think that we should guarantee that the fetch method should be called as many times as the variable is used, but that we should determine this method only once per expression as opposed to rechecking which fetch method to call each time. The reason this is important is that depending on which choices we make we end up making *EVERY* variable access expensive, when only very very very very few variable access actually involve a tie. (Ties are so slow that most people avoid them in true production code in my experience - they are nice toys but barely fit for purpose for real enterprise work.) You ask why it should be the case that Perl should treat $y= $x + $x; differently from $y= x() + x(); My view is that a variable fetch method SHOULD behave as a true function whereas a subroutine that returns a value is not expected to do so at all. I personally think that generally people are unwilling to pay for something which does not benefit them, and which benefits only a very small group. Taxing every program so that one can play silly tricks with ties is not a good cost/benefit trade off, and I personally would shed no tears if we changed the rules. I do NOT think that this debate is about how many times x() and y() are called in the expression: $y= x() + y(); I believe that there is general consensus that x() and y() in this case would be called exactly once (although I believe there is a general consensus that there is no guarantee which is called first). The debate is rather about how many times tied($x) is called AND how many times FETCH is called on the resulting object when considering an expression of the form $y= $x + $x; where $x is tied. Considering the options of [tied($x) twice, FETCH twice], [tied($x) once, and FETCH twice], and [tied($x) once, and FETCH once]. I personally would prefer the once/once solution, but am resigned to the necessity of calling the FETCH twice, thus leaving me in the once/twice camp. I personally think that making EVERY script pay a price for the current approach of twice/twice is not the right balance when you consider how rarely variables are tied in proportion to how often untied variables are accessed. Perls hyper dynamic nature requires one to consider these things carefully. The wrong choice can mean that perl has to do a LOT of extra work for what is really minimal benefit to anybody. Think of pseudo hashes and the cost associated to them. Basically I think we have to decide what ties are really for. Are they there to provide a fancy way to make a subroutine call? Or are they a way to extend the behavior of variables? For me the answer is clearly the latter. A tie which makes a variable return a random variable on fetch IS NOT in the spirit of such a variable. A tie which ensures that the keys of a hash are order is. I don't think we need any more ways to spell x() and that if you want that just write that. Don't forget the tie interface was originally coded to allow hashes to be bound to file based storage, the more creative uses to which they have been put since have been essentially implementation byproducts that were and are subject to change. Apologies if this mail rambles a bit, ive been reading on my holiday a book* of the correspondence of a man born in 1880 and I suspect the writing style of the period has rubbed off on me a bit. cheers, Yves * "Letters of Agar Adamson" - edited by N.M. Christie and published by CEF Books - A terrific and horrifying account of the Great War and especially the role of Canada during it. For those interested it is well worth reading. -- perl -Mre=debug -e "/just|another|perl|hacker/"Thread Previous | Thread Next