On 05/30/12 10:17, Thiez wrote:
> On Wednesday, 30 May 2012 at 06:31:32 UTC, Dmitry Olshansky wrote:
>> I'll intervene. Following famous nerd motto "talk is cheap, show me the 
>> code" I strongly suggest discussing concrete scenarios. All "prone to 
>> deadlock sentiment" is trivia as in buyer beware.
>>
>> That being said:
>>
>> class iMutexed
>> {//implicit intent, explicit details
>>     Mutex mutex;
>> }
>>
>> vs
>>
>> class iMutexed
>> {//implicit intent, implicit details
>>
>> //implicit mutex
>> }
>>
>> Makes little to no difference. EXCEPT that designer of the class has no 
>> control what so ever over hidden mutex! Thus I believe the best way to fix 
>> it is to (say) require obj be a subclass of Mutex in order to use 
>> synchronized(obj). i.e.
>>
>> class iMutexed: Mutex
>> {//explicit intent, implicit details
>>
>> }
> 
> Forcing synchronized classes to extend Mutex would make it impossible to 
> create a synchronized subclass of a pre-existing unsynchronized class, would 
> it not? Unless you want to introduce multiple inheritence. If you want to go 
> this way at least make it an interface that has special meaning to the 
> compiler, instead of a class that must be inherited from.
> 

Yeah, that leads to multiple inheritance, or cheap imitations thereof.

Just create lock+unlock (or acquire+release, whatever) operators that
can be overloaded, ie

void opUnary!("lock")() {}
void opUnary!("unlock")() {}

and make 'synchronize (struct|class){...}' use them, ditto for implicitly
synchronized public methods (note: by lowering directly. You can already
do something like this right now, but it would have a large runtime
overhead.) Full backward compatibility retained, and the user can actually
implement the locking in a sane manner - something that is not likely to
happen any time soon as a built-in language feature. And yes, removing the
monitors from classes is desirable and would have back-compat issues, but
it is then just an optimization, and does not need to happen immediately.


On 05/30/12 11:34, deadalnix wrote:
> Le 29/05/2012 23:33, Andrei Alexandrescu a écrit :
>> On 5/29/12 1:37 AM, deadalnix wrote:
>>> I would say that breaking things here, with the right deprecation
>>> process, is the way to go.
>>
>> So what should we use for mutex-based synchronization if we deprecate
>> synchronized classes?
>>
>> Andrei
> 
> I think something similar to range design here is the way to go.
> 
> It is easy to define something like
> 
> template isLockable(T) {
>     enum isLockable = isShared!T && is(typeof(T.init.lock())) && 
> is(typeof(T.init.release()));
> }
> 
> And allow locking only if(isLockable!Type) .
> 
> Now we can create SyncObject or any structure we want. The point is that we 
> lock explicit stuff.

Yep, a way to mark objects usable for locking would also help. I'd drop the
'isShared' check - it's redundant and doesn't play well with D 'shared' concept
in its current form; it can always be introduced back, when 'shared' evolves to
something more sane.


On 05/30/12 11:14, Jacob Carlborg wrote:
> On 2012-05-29 23:48, Andrei Alexandrescu wrote:
> 
>> Don't be hatin'. You'd appreciate the matter considerably more after you
>> defined your own language and had its users yell at you for changing
>> even a small detail.
>>
>> The situation is at it is, and there's no need to get agitated. We're
>> all on the same boat, trying to make things work out best.
> 
> It seems more and more that D2 is not a designed language. Instead new 
> features are just slapped on without considering how it would impact the rest 
> of the language.

Yes. But it is not so much the adhoc features that are the problem, as long
as they don't significantly break the rest of the language. Not fixing known
deficiencies in the name of backward compatibility is. The gain from having
a new, useful and working feature more than makes up for the cost of changes
to app code. Having features that work for trivial hello-world programs, but
fail for most real code, does much more harm than good.


artur

Reply via email to