Logical const
Fawzi Mohamed
fawzi at gmx.ch
Thu Dec 2 03:26:48 PST 2010
On 1-dic-10, at 04:52, Jesse Phillips wrote:
> Fawzi Mohamed Wrote:
>
>> The thing is that a lazy structure is very useful in functional
>> programming.
>> A lazy evaluation is something that should be possible using pure and
>> immutable.
>> I find it jarring that to do that one has to avoid D pure and
>> immutable.
>
> Don't know what you mean by this.
a lazy list (for example one that list all natural numbers) cannot be
immutable, without the possibility of a backdoor because all the
"next" elements will have to be set at creation time.
(Lazy structures can be seen as memoizing a value produced by a pure
function forever (i.e. never forgetting it).
>> To be able to safely use pure and immutable as I said one would need
>> some idioms that are guaranteed to be non optimized by the compiler.
>> for example casting a heap allocated type should be guaranteed to
>> remain modifiable behind the back:
>> auto t=new T;
>> auto t2=cast(immutable(typeof(t)))t;
>>
>> auto tModif=cast(typeof(t))t2; // the compiler has not moved or
>> flagged the memory of t, so one can modify tModif.
>
> This code is valid, the requirements placed on cast will not allow
> it to move the data. Even types declared to be immutable my be
> modifiable when cast to Unqual!(T), but the compiler can not
> guarantee these.
>
> If I am wrong, please let me know why.
The code works now, I would like some assurance that
cast(immutable(T)) doesn't do fancy stuff (or some equivalent way to
ensure that *some* idiom will remain allowed.
If you think about it already now with opCast you cannot really know
what opCast does, so a compiler would be allowed to return an
immutable copy, or (if it uses whole pages) make the whole memory as
read only.
>> clearly this is unsafe and it is up to the implementer to make sure
>> that the object is really logically const
>> and no function will see the internal changes.
>
> Yes, and I don't think compiler support adds any more guarantee than
> casting those you want to modify in a const function. This Mutable
> struct is supposed to help verify only modifiable data is cast:
>
> https://gist.github.com/721066
you example has an error in parallel, this is a good example of why
the casting away should not be made convenient, and a user should just
use well tested library code (for example dong thunk evaluation), that
might be in a special type or mixed in.
You cannot have separate flag, and value without any synchronization,
as other threads could see their value in a different order, so they
could see dirty=false, but still no determinant.
This is somehow related to dataflow variables that can be set several
times, but only to the same value (and indeed with a lazy list one can
allow two threads to calculate the next element, but then only one
should set it (using atomic ops to avoid collistions).
I have implemented DataFlow variables (but using the blip
paralelization, that delays a task that waits, and resumes it when the
value is ready, not with a thread lock) in
https://github.com/fawzi/blip/blob/master/blip/parallel/smp/DataFlowVar.d
using D1
> I've taken many example use-cases for logical const and added them
> as unittests. I think it is fairly reasonable if I could just get an
> answer to my question about concurrency and declaring immutable types.
>
>> This is something that should be done sparingly, probably just in
>> library code implementing lazy evaluation or memoization (but code
>> that might be mixed in).
>
> Could you give an example of how lazy evaluation is achieved by
> modifying state?
lazy structures need to modify the state (as I showed with the linked
list example), lazy evaluation alone does not need to modify the state
(and is indeed possible in D), but the storing/memoizing of the result
needs it. To say the truth in D memoizing can be done with a static
variable, but think about making the singly linked list like that, and
you should immediately see that if gets *very* inefficient.
More information about the Digitalmars-d
mailing list