Poll: a nonstate keyword
Fawzi Mohamed
fmohamed at mac.com
Sun Jun 1 10:08:26 PDT 2008
On 2008-06-01 15:31:12 +0200, "Janice Caron" <caron800 at googlemail.com> said:
> On 01/06/2008, Fawzi Mohamed <fmohamed at mac.com> wrote:
>> but needs at least a mixin in the destructor, or there is some magic that I
>> don't know yet?
>
> There's some magic that you don't know about yet - specifically, that
> classes are allowed to have multiple destructors. When the object goes
> out of scope, all of its destructors are called. That means that the
> Cache! mixin I mentioned earlier only needs to define an additional
> destructor of its own.
nice!
>> I think for example that in the case of lazy linked list the external
>> hastable solution is probably too expensive, at leas twice as slow to
>> traverse, and with at least twice the overhead in memory.
>
> Absolutely. However, if the standard library were to provide List!(T),
> then I think this need would go away.
The need of a mutable part in const comes form the lazyness of the
construction of the list, not from the use of the list, any lazily
constructed structure might need it.
let's look at a simple (and thus artificial) example (fully explicit,
most of it can then be part of a mixin template) of what I want to be
able to do: a lazy list of odd numbers from 1 to 1_000_000 (or even
infinity)
This example as written is illegal and correctly so, but I want to be
able to do something like this with a similar efficiency.
class ByTwo{
int nAtt;
private ByTwo *_next;
this(int nAtt, ByTwo next){
this.nAtt=nAtt;
this._next=next;
}
ByTwo next() pure{
if (_next==undefined){
if (nAtt<1_000_000){
_next=new ByTwo(nAtt+2,undefined);
else
_next=null;
}
return _next;
}
}
Here undefined is just an invalid memory location 0x01, or if no such
memory exist then just the address of an object that will stay around
forever.
Now I might have a pure function like
int listLengthAcc(T)(T t,int length)pure{
if (t is null) return length;
return listLengthAcc(t.next,length+1);
}
and I want to call
listLengthAcc(cast(const) new ByTwo(1,undefined))
if everything would work this will use few memory, the stack will not
grow and will return 499_999.
Note that the list is effectively constant from outside, and it is as
if it would be there from the beginning, but it is potentially much
more efficient from the memory point of view (and from the
computational point of view in not all elements are needed).
This use is the (static) Lazy Caching (in the wiki).
To use it one could also use unsafe casts instead of some keyword, if
it is guaranteed that no readonly memory (or something like it) are
used.
>> Also for statistical information about calling pattern to a pure function
>> one probably doesn't want to spend much time/space.
>
> It might not be possible to collect "statistical information about
> calling pattern to a pure function" anyway, since if the compiler does
> any decent optimization, then the number of times that a pure function
> is executed may have no bearing whatosever on the number of times that
> it's called. I think, the question, "How often would it have been
> executed if it wasn't pure?" can only be answered by not making it
> pure!
If I want to optimize the function I want the answer to the calling
pattern of a pure function with all optimization.
Not a common use case, and it can be hacked around ad hoc, but still
not unresonable.
More information about the Digitalmars-d
mailing list