develooper Front page | perl.perl5.porters | Postings from August 2010

Re: Order of evaluation of terms (was peephole optimiser could prunemore dead code)

Thread Previous | Thread Next
August 20, 2010 07:33
Re: Order of evaluation of terms (was peephole optimiser could prunemore dead code)
Message ID:
On 19 August 2010 18:50, Abigail <> 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;

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.

* "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 Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About