Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

downs wrote:

Andrei Alexandrescu wrote:

downs wrote:

Andrei Alexandrescu wrote:

Hello,


D currently allows defining class allocators and deallocators. They have
a number of problems that make them unsuitable for D 2.0. The most
obvious issue is that D 2.0 will _not_ conflate destruction with
deallocation anymore: invoking delete against an object will call
~this() against it but will not recycle its memory. In contrast, class
deallocators are designed around the idea that invoking delete calls the
destructor and also deallocates memory.

So I'm thinking of removing at least class deallocators from the
language. Class allocators may be marginally and occasionally useful if
the user takes the matter of deallocation in her own hands.

A much better way to handle custom allocation of classes would be in the
standard library.

What do you think?


Andrei

Do you trust the D GC to be good enough to always free everything
you've allocated, without error?

If your answer was 'ye- maaybe ... no actually', please rethink this.

People will always be able to call functions in the garbage collector
manually. The discussion on class allocators and deallocators has
nothing to do with that.

Andrei


So you can still deallocate a class by hand, only it's not called delete 
anymore?


That is correct.

Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread downs
Andrei Alexandrescu wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 Hello,


 D currently allows defining class allocators and deallocators. They
 have
 a number of problems that make them unsuitable for D 2.0. The most
 obvious issue is that D 2.0 will _not_ conflate destruction with
 deallocation anymore: invoking delete against an object will call
 ~this() against it but will not recycle its memory. In contrast, class
 deallocators are designed around the idea that invoking delete
 calls the
 destructor and also deallocates memory.

 So I'm thinking of removing at least class deallocators from the
 language. Class allocators may be marginally and occasionally
 useful if
 the user takes the matter of deallocation in her own hands.

 A much better way to handle custom allocation of classes would be
 in the
 standard library.

 What do you think?


 Andrei
 Do you trust the D GC to be good enough to always free everything
 you've allocated, without error?

 If your answer was 'ye- maaybe ... no actually', please rethink this.
 People will always be able to call functions in the garbage collector
 manually. The discussion on class allocators and deallocators has
 nothing to do with that.

 Andrei

 So you can still deallocate a class by hand, only it's not called
 delete anymore?
 
 That is correct.
 
 Andrei

Isn't that a pretty big violation of Least Surprise?

http://en.wikipedia.org/wiki/Principle_of_least_astonishment :
In user interface design, programming language design, and ergonomics, the 
principle (or rule or law) of least astonishment (or surprise) states that, 
when two elements of an interface conflict, or are ambiguous, the behaviour 
should be that which will *least surprise* the human user or programmer at the 
time the conflict arises.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Kagamin
I don't see any problem with dispose() method (except that it doesn't nullifies 
the pointer, which can be a performance issue for some GC implementations). If 
you plan to go C# way, it's reasonable to adopt its techniques of destruction. 
Moreover C# and C++ approaches are compatible. If the programmer doesn't 
guarantee ownership of the object, it's just unreasonable to call delete, here 
adding the dispose() method to the Object and using it for destruction will 
help.

Your proposal is indeed better than the scheme above and it's not a pain to 
implement and use destruct+free function, but delete and dispose are already 
well-known idioms, as you were already told about.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Don

downs wrote:

Andrei Alexandrescu wrote:

downs wrote:

Andrei Alexandrescu wrote:

downs wrote:

Andrei Alexandrescu wrote:

Hello,


D currently allows defining class allocators and deallocators. They
have
a number of problems that make them unsuitable for D 2.0. The most
obvious issue is that D 2.0 will _not_ conflate destruction with
deallocation anymore: invoking delete against an object will call
~this() against it but will not recycle its memory. In contrast, class
deallocators are designed around the idea that invoking delete
calls the
destructor and also deallocates memory.

So I'm thinking of removing at least class deallocators from the
language. Class allocators may be marginally and occasionally
useful if
the user takes the matter of deallocation in her own hands.

A much better way to handle custom allocation of classes would be
in the
standard library.

What do you think?


Andrei

Do you trust the D GC to be good enough to always free everything
you've allocated, without error?

If your answer was 'ye- maaybe ... no actually', please rethink this.

People will always be able to call functions in the garbage collector
manually. The discussion on class allocators and deallocators has
nothing to do with that.

Andrei

So you can still deallocate a class by hand, only it's not called
delete anymore?

That is correct.

Andrei


Isn't that a pretty big violation of Least Surprise?

http://en.wikipedia.org/wiki/Principle_of_least_astonishment :
In user interface design, programming language design, and ergonomics, the 
principle (or rule or law) of least astonishment (or surprise) states that, when two 
elements of an interface conflict, or are ambiguous, the behaviour should be that which 
will *least surprise* the human user or programmer at the time the conflict arises.


I think the basic rule being introduced is:
that every object can be managed by the gc, or manually managed. But not 
both. That seems reasonable to me. But if delete no longer deletes, it 
needs a name change.


uint is NOT just a positive number

2009-10-07 Thread Kagamin
Some people used to use unsigned integers as 'mere' non-negative numbers, but 
they're actually not numbers from range, they're numbers from entirely 
different algebra. And - yes - this causes subtle bugs. Recent introduction of 
integer range promotions works hard in hiding those bugs, so they manifest only 
in very rare corner cases.

Ever wondered wheter a-=b and a+=-b equivalent? In most cases they are, except 
for one. Do you remember? uint is not propagated to long. I've hit it recently. 
It's exactly because unsigneds are not just non-negative numbers. So it's pain 
to see their wide use as numbers for which sign-sensitive arithmetic operations 
are meaningful.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread downs
Don wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 Hello,


 D currently allows defining class allocators and deallocators. They
 have
 a number of problems that make them unsuitable for D 2.0. The most
 obvious issue is that D 2.0 will _not_ conflate destruction with
 deallocation anymore: invoking delete against an object will call
 ~this() against it but will not recycle its memory. In contrast,
 class
 deallocators are designed around the idea that invoking delete
 calls the
 destructor and also deallocates memory.

 So I'm thinking of removing at least class deallocators from the
 language. Class allocators may be marginally and occasionally
 useful if
 the user takes the matter of deallocation in her own hands.

 A much better way to handle custom allocation of classes would be
 in the
 standard library.

 What do you think?


 Andrei
 Do you trust the D GC to be good enough to always free everything
 you've allocated, without error?

 If your answer was 'ye- maaybe ... no actually', please rethink this.
 People will always be able to call functions in the garbage collector
 manually. The discussion on class allocators and deallocators has
 nothing to do with that.

 Andrei
 So you can still deallocate a class by hand, only it's not called
 delete anymore?
 That is correct.

 Andrei

 Isn't that a pretty big violation of Least Surprise?

 http://en.wikipedia.org/wiki/Principle_of_least_astonishment :
 In user interface design, programming language design, and
 ergonomics, the principle (or rule or law) of least astonishment (or
 surprise) states that, when two elements of an interface conflict, or
 are ambiguous, the behaviour should be that which will *least
 surprise* the human user or programmer at the time the conflict arises.
 
 I think the basic rule being introduced is:
 that every object can be managed by the gc, or manually managed. But not
 both. That seems reasonable to me. But if delete no longer deletes, it
 needs a name change.


Oh, that makes more sense.

Do manually managed objects still count under MarkSweep?


Problem with undefined types with recent DMDs?

2009-10-07 Thread bobef
Hello guys. A little help request. I tried to switch to newer version of DMD 
yesterday (1.048,1.047), but suddenly I get some weird errors.

Error: identifier 'UINT' is not defined
Error: UINT is used as a type
Error: cannot have parameter of type void

and the same thing with other types that are imported already in my module by 
import tango.sys.win32.Types;. It also happens with my own custom types. It 
was working with 1.045. Any idea what could be wrong? Maybe I messed up the DMD 
installation or something?

Thanks,
bobef


Re: Problem with undefined types with recent DMDs?

2009-10-07 Thread Max Samukha
On Wed, 07 Oct 2009 05:24:42 -0400, bobef
blahbalhblahl...@blahblaghblah.blah wrote:

Hello guys. A little help request. I tried to switch to newer version of DMD 
yesterday (1.048,1.047), but suddenly I get some weird errors.

Error: identifier 'UINT' is not defined
Error: UINT is used as a type
Error: cannot have parameter of type void

and the same thing with other types that are imported already in my module by 
import tango.sys.win32.Types;. It also happens with my own custom types. It 
was working with 1.045. Any idea what could be wrong? Maybe I messed up the 
DMD installation or something?

Thanks,
bobef

It is a regression:
http://d.puremagic.com/issues/show_bug.cgi?id=3301


Re: uint is NOT just a positive number

2009-10-07 Thread Don

Kagamin wrote:
Some people used to use unsigned integers as 'mere' non-negative numbers, but they're actually not numbers from range, they're numbers from entirely different algebra. And - yes - this causes subtle bugs. 


Amen!
I actually think it's worse in D, because 'uint' is so easy to type, 
it's far more seductive than 'unsigned int'.


Recent introduction of integer range promotions works hard in hiding 
those bugs, so they manifest only in very rare corner cases.


It's not complete. It doesn't apply to arithmetic operations yet. Once 
that's in place, D could become really harsh about mixing signed and 
unsigned: if there's any chance the highest bit is set in the signed 
type, mixing signed and unsigned should be illegal.



Ever wondered wheter a-=b and a+=-b equivalent? In most cases they are, except 
for one. Do you remember? uint is not propagated to long. I've hit it recently. 
It's exactly because unsigneds are not just non-negative numbers. So it's pain 
to see their wide use as numbers for which sign-sensitive arithmetic operations 
are meaningful.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Christopher Wright

Andrei Alexandrescu wrote:

Christopher Wright wrote:

What exactly is your suggestion?

It seems that you mean that:
delete obj;

should call a destructor but not call delete() or notify the GC that 
the memory is free.


That is correct. In particular, an object remains usable after delete.

You're saying that there is a problem, but you're not telling us 
what's wrong. Why the hell do you want to destroy an object without 
recycling its memory? Why does the inability to do so cause a problem?


The matter has been discussed quite a bit around here and in other 
places. I'm not having as much time as I'd want to explain things. In 
short, destroying without freeing memory avoids dangling references and 
preserves memory safety without impacting on other resources.


Memory safety, sure, but you're deleting the object. It is no longer 
valid. You need to add a flag to the object indicating it's invalid, and 
everything that uses it needs to check that flag. Instead of a probable 
segfault in the current system, you'll get strange errors.


It sounds like a complicated way of supporting a rare use case. Why not 
use a library solution? Make an IDisposable interface with methods void 
dispose() and bool disposed()?


If you don't have enough time to explain the reasoning, could you post a 
link to a more detailed explanation?


Re: D marketplace

2009-10-07 Thread language_fan
Tue, 06 Oct 2009 23:04:04 -0600, Stanley Steel thusly wrote:

 On 10/6/09 11:01 PM, Walter Bright wrote:
 Stanley Steel wrote:
 On 10/6/09 12:58 PM, Walter Bright wrote:
 I'm considering setting up another D newsgroup called D.marketplace.
 In it, you can essentially post advertisements for your D products,
 hang out a shingle offering your D consulting services, post want ads
 for D programmers, anything business oriented that's related to D.

 Is this something needed?
 What about something a little more than a news group? I'd be willing
 to offer up some development time.

 I thought a n.g. would be easy to manage, and we can see how things go
 with it before spending a lot of effort.
 Sounds good.  If you change you mind, let me know.

The nntp system is not that bad actually. What annoys me on the 
announcement group is that there is too much OT discussion and new 
release announcements are added to the same thread with lots of OT posts. 
Some kind of moderation would be more than welcome.

If you have time and energy, you could also fix the web interface and/or 
improve its user interface design - it's annoyingly broken and ugly. I 
guess Walter would be more than glad to accept patches.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Kagamin wrote:

I don't see any problem with dispose() method (except that it doesn't
nullifies the pointer, which can be a performance issue for some GC
implementations). If you plan to go C# way, it's reasonable to adopt
its techniques of destruction. Moreover C# and C++ approaches are
compatible. If the programmer doesn't guarantee ownership of the
object, it's just unreasonable to call delete, here adding the
dispose() method to the Object and using it for destruction will
help.

Your proposal is indeed better than the scheme above and it's not a
pain to implement and use destruct+free function, but delete and
dispose are already well-known idioms, as you were already told
about.


You're right. It would be great to dispose of the delete keyword and 
define a member function and/or a free function that invokes the 
destructor and obliterates the object with its .init bits.


At any rate: deletion + memory reclamation must go. If you want to do 
manual memory management, malloc/free are yours. D's native GC heap is 
not the right place.



Andrei


Re: Problem with undefined types with recent DMDs?

2009-10-07 Thread #ponce
 It is a regression:
 http://d.puremagic.com/issues/show_bug.cgi?id=3301

I can't use neither 1.047 or 1.048 for the very same reason. I'm stuck with 
1.046.



Re: Problem with undefined types with recent DMDs?

2009-10-07 Thread Moritz Warning
On Wed, 07 Oct 2009 08:45:28 -0400, #ponce wrote:

 It is a regression:
 http://d.puremagic.com/issues/show_bug.cgi?id=3301
 
 I can't use neither 1.047 or 1.048 for the very same reason. I'm stuck
 with 1.046.

For the record, me too. :


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Michel Fortin
On 2009-10-06 20:26:48 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org said:


The matter has been discussed quite a bit around here and in other 
places. I'm not having as much time as I'd want to explain things. In 
short, destroying without freeing memory avoids dangling references and 
preserves memory safety without impacting on other resources.


It's a safety hack, not a performance hack.


In my opinion, it's mostly an illusion of safety. If you call the 
destructor on an object, the object state after the call doesn't 
necessarily respects the object invariants and doing anything with it 
could result in, well, anything, from returning wrong results to 
falling into an infinite loop (basically undefined behaviour). What you 
gain is that no object will be allocated on top of the old one, and 
thus new objects can't get corrupted. But it's still undefined 
behaviour, only with less side effects and more memory consumption.


I don't think it's a so bad idea on the whole, but it'd be more 
valuable if accessing an invalidated object could be made an error 
instead of undefined behaviour. If this can't be done, then we should 
encourage destructors to put the object in a clean state and not 
leave any dirt behind. But should that still be called a destructor?


Perhaps we could change the paradigm a little and replace deletion 
with recycling. Recycling an object would call the destructor and 
immeditately call the default constructor, so the object is never left 
in an invalid state. Objects with no default constructor cannot be 
recycled. This way you know memory is always left in a clean state, and 
you encourage programmers to safely reuse the memory blocks from 
objects they have already allocated when possible.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Leandro Lucarella
Andrei Alexandrescu, el  6 de octubre a las 21:42 me escribiste:
 should call a destructor but not call delete() or notify the GC
 that the memory is free.
 That is correct. In particular, an object remains usable after delete.
 
 Why would you do that? What is the rationale to not notify the GC?
 
 Because there may be other live references to the object.

But when using delete that's exactly what it should happen. You are hiding
a bug if you let that happen on purpose.

 You're saying that there is a problem, but you're not telling us
 what's wrong. Why the hell do you want to destroy an object
 without recycling its memory? Why does the inability to do so
 cause a problem?
 The matter has been discussed quite a bit around here and in other
 places. I'm not having as much time as I'd want to explain things.
 In short, destroying without freeing memory avoids dangling
 references and preserves memory safety without impacting on other
 resources.
 
 But D is a system programming language.
 
 Well it is but there are quite a few more things at stake. First, it
 is a reality that it is often desirable to distinguish between
 calling the destructor and reclaiming memory. D's current delete
 continues the bad tradition started by C++ of conflating the two.

Why is a bad idea? If you are destroying an object, the object will be in
an inconsistent state. What's the point of keeping it alive. Again, you're
just hiding a bug; letting the bug live longer. The language should try to
expose bugs ASAP, not delay the detection.

I think is a good idea not to force the GC to free the memory immediately
with a delete, but it should if it's easy. Other protection methods as
using mprotect to protect the objects pages it's very desirable too,
because you can spot an access to a inconsistent (destroyed) object as
soon as it first happen.

 If you wrote delete x; the
 language should assume you know what you're doing.
 
 I think delete should be present in SafeD and if you want manual
 memory management you should build on malloc and free.

If you want to introduce a new semantic, I think you should provide a new
method, not change the semantic of an existent one.

And BTW, is there any reason why this can't be implemented in the library
instead of using an operator? Why don't you provide a destroy() function
for that in Phobos?

Really, I can't see any advantages on changing the delete operator
semantics, only problems.

 If you only want to
 deinitialize an object, you can write a .destroy() method for example,
 and call that. I think delete have a strong established semantic to change
 it now, and without any gain.
 
 It has a thoroughly broken and undesired semantics. It would be a step
 forward to divorce it of that.

Why it's broken? Why it's undesired?

 In fact i'd love to simply make delete disappear as a keyword and make
 it a function.

I agree on this one, no need for an operator (AFAIK). But again, I don't
see how letting the user to use a destroyed object is any safer. It's
really bad in fact.

 It seems like a performance hack to me -- you've got an object
 that isn't valid anymore, but you want to hang on to the memory
 for some other purpose. And you could override new() and delete(),
 but you don't want to incur the performance penalty of calling the
 runtime to fetch the deallocator.
 It's a safety hack, not a performance hack.
 
 But you shouldn't provide safety where the programmer is not expecting it.
 delete is for *manual* memory management. It makes no sense to guarantee
 that the memory is *not* freed. It makes sense not guaranteeing that it
 will actually be freed either. I think that's a good idea actually,
 because it gives more flexibility to the GC implementation.
 
 I think we should move away from the idea that delete is for manual
 memory management. We should leave that to the likes of malloc and
 free alone.

Why? Using malloc and free is a lot more trouble, you have to register the
roots yourself for example. It's not like you do malloc() and free() and
everything works magically. You have to have more knowledge of the GC to
use them. Being able to manually manage the *GC* heap (if the GC support
that, if not it can make it a NOP) is good IMHO.

 The only remaining use that I see is a way to reset a shared
 object without explicitly passing around a reference to the new
 version of the object. This seems potentially dangerous, and
 nothing I want for default behavior.
 Well incidentally at least as of now delete obj puts null in obj...
 
 That's nice :)
 
 I think it's a false sense of security.

Why it's bad for D? (I don't care that much about C++ reasons :)

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Debemos creer en los sueños del niño. 

Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Michel Fortin
On 2009-10-07 08:46:06 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org said:


You're right. It would be great to dispose of the delete keyword and 
define a member function and/or a free function that invokes the 
destructor and obliterates the object with its .init bits.


I guess I should have read this before posting mine. :-)

You're suggesting obiterating with the .init bits, but I believe this 
is insufficient: you need to call a constructor if you want to be sure 
object invariants holds. If you can't make the invariants hold, you're 
in undefined behaviour territory.



At any rate: deletion + memory reclamation must go. If you want to do 
manual memory management, malloc/free are yours. D's native GC heap is 
not the right place.


Well, yes you're entirely right saying that. But I fail to see how this 
is linked to class allocators and deallocators. Class allocators and 
deallocators are just a way to tell the runtime (including the GC) how 
to allocate and deallocate a specific class of objects. There is no 
need to manually call delete for the allocator and deallocator to be 
useful.


The way it is currently, if you want objects of a certain class to be 
allocated in one big object pool, you can encapsulate that detail in 
the class so clients don't have to bother about it. I've done that in 
C++ to speed up things without having to touch the rest of the code 
base and it's quite handy.


At other times the client of the class that wants to manage memory, and 
that should be allowed too, bypassing the class's allocator and 
deallocator and calling directly the constructor and destructor.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: uint is NOT just a positive number

2009-10-07 Thread Jeremie Pelletier

Don wrote:

Kagamin wrote:
Some people used to use unsigned integers as 'mere' non-negative 
numbers, but they're actually not numbers from range, they're numbers 
from entirely different algebra. And - yes - this causes subtle bugs. 


Amen!
I actually think it's worse in D, because 'uint' is so easy to type, 
it's far more seductive than 'unsigned int'.


Recent introduction of integer range promotions works hard in hiding 
those bugs, so they manifest only in very rare corner cases.


It's not complete. It doesn't apply to arithmetic operations yet. Once 
that's in place, D could become really harsh about mixing signed and 
unsigned: if there's any chance the highest bit is set in the signed 
type, mixing signed and unsigned should be illegal.


Ever wondered wheter a-=b and a+=-b equivalent? In most cases they 
are, except for one. Do you remember? uint is not propagated to long. 
I've hit it recently. It's exactly because unsigneds are not just 
non-negative numbers. So it's pain to see their wide use as numbers 
for which sign-sensitive arithmetic operations are meaningful.


I think it also depend on the representation of that number, for example 
most numbers I would feel more natural as hex value such bit fields and 
flags, address offsets, and whatnot are all unsigned, almost everything 
else is signed.


I did get annoyed about uint not automatically propagated to long 
however, when I was reading lo/hi uint offset pairs from a file and 
making it a long offset (lo + (hi32)), turns out it can't be done 
without explicit long casts.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Sean Kelly
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 downs wrote:
  Andrei Alexandrescu wrote:
  Hello,
 
 
  D currently allows defining class allocators and deallocators. They have
  a number of problems that make them unsuitable for D 2.0. The most
  obvious issue is that D 2.0 will _not_ conflate destruction with
  deallocation anymore: invoking delete against an object will call
  ~this() against it but will not recycle its memory. In contrast, class
  deallocators are designed around the idea that invoking delete calls the
  destructor and also deallocates memory.
 
  So I'm thinking of removing at least class deallocators from the
  language. Class allocators may be marginally and occasionally useful if
  the user takes the matter of deallocation in her own hands.
 
  A much better way to handle custom allocation of classes would be in the
  standard library.
 
  What do you think?
 
 
  Andrei
 
  Do you trust the D GC to be good enough to always free everything you've 
  allocated, without error?
 
  If your answer was 'ye- maaybe ... no actually', please rethink this.
 People will always be able to call functions in the garbage collector
 manually. The discussion on class allocators and deallocators has
 nothing to do with that.

Right.  There's no plan to eliminate GC.free().


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Jeremie Pelletier

Sean Kelly wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

downs wrote:

Andrei Alexandrescu wrote:

Hello,


D currently allows defining class allocators and deallocators. They have
a number of problems that make them unsuitable for D 2.0. The most
obvious issue is that D 2.0 will _not_ conflate destruction with
deallocation anymore: invoking delete against an object will call
~this() against it but will not recycle its memory. In contrast, class
deallocators are designed around the idea that invoking delete calls the
destructor and also deallocates memory.

So I'm thinking of removing at least class deallocators from the
language. Class allocators may be marginally and occasionally useful if
the user takes the matter of deallocation in her own hands.

A much better way to handle custom allocation of classes would be in the
standard library.

What do you think?


Andrei

Do you trust the D GC to be good enough to always free everything you've 
allocated, without error?

If your answer was 'ye- maaybe ... no actually', please rethink this.

People will always be able to call functions in the garbage collector
manually. The discussion on class allocators and deallocators has
nothing to do with that.


Right.  There's no plan to eliminate GC.free().


But that's runtime dependent, for example on my runtime its 
Memory.Free(). Removing 'delete' would therefore bind the code to a 
certain runtime, that's not a very portable solution, and far from being 
as elegant as delete.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Jeremie Pelletier

downs wrote:

Don wrote:

downs wrote:

Andrei Alexandrescu wrote:

downs wrote:

Andrei Alexandrescu wrote:

downs wrote:

Andrei Alexandrescu wrote:

Hello,


D currently allows defining class allocators and deallocators. They
have
a number of problems that make them unsuitable for D 2.0. The most
obvious issue is that D 2.0 will _not_ conflate destruction with
deallocation anymore: invoking delete against an object will call
~this() against it but will not recycle its memory. In contrast,
class
deallocators are designed around the idea that invoking delete
calls the
destructor and also deallocates memory.

So I'm thinking of removing at least class deallocators from the
language. Class allocators may be marginally and occasionally
useful if
the user takes the matter of deallocation in her own hands.

A much better way to handle custom allocation of classes would be
in the
standard library.

What do you think?


Andrei

Do you trust the D GC to be good enough to always free everything
you've allocated, without error?

If your answer was 'ye- maaybe ... no actually', please rethink this.

People will always be able to call functions in the garbage collector
manually. The discussion on class allocators and deallocators has
nothing to do with that.

Andrei

So you can still deallocate a class by hand, only it's not called
delete anymore?

That is correct.

Andrei

Isn't that a pretty big violation of Least Surprise?

http://en.wikipedia.org/wiki/Principle_of_least_astonishment :
In user interface design, programming language design, and
ergonomics, the principle (or rule or law) of least astonishment (or
surprise) states that, when two elements of an interface conflict, or
are ambiguous, the behaviour should be that which will *least
surprise* the human user or programmer at the time the conflict arises.

I think the basic rule being introduced is:
that every object can be managed by the gc, or manually managed. But not
both. That seems reasonable to me. But if delete no longer deletes, it
needs a name change.



Oh, that makes more sense.

Do manually managed objects still count under MarkSweep?


You have to register the memory range they cover to the GC if they 
contain pointers to GC memory. Otherwise the GC don't know they exist at 
all.


Re: Can D compile for PowerPC Architecture?

2009-10-07 Thread Snake
Jesse Phillips Wrote:

 You will have to look at GDC and LDC.
 
 http://www.dsource.org/projects/ldc/wiki/PlatformSupport
 
 * LDC compiles, but bugs in frontend
 * porting of GDC fixes suggested
 * runtime, inline asm and exception handling need work
 * contact: none 

I looked into GDC a little bit, and I'm wondering if it can support the cell 
processor? I was looking at this article:

http://www.ibm.com/developerworks/power/library/pa-linuxps3-1/

There are some additional things that are required to be used to fully use the 
cell processor. GCC is mentioned in this article so I think GCC would be the 
most appropriate compiler for C/C++. Since you guys support Linux Based 
PowerPCs, then i simply want to know, based on this article, if it would be 
possible to fully utilize the cell with D.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Michel Fortin wrote:
On 2009-10-06 20:26:48 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org said:


The matter has been discussed quite a bit around here and in other 
places. I'm not having as much time as I'd want to explain things. In 
short, destroying without freeing memory avoids dangling references 
and preserves memory safety without impacting on other resources.


It's a safety hack, not a performance hack.


In my opinion, it's mostly an illusion of safety. If you call the 
destructor on an object, the object state after the call doesn't 
necessarily respects the object invariants and doing anything with it 
could result in, well, anything, from returning wrong results to falling 
into an infinite loop (basically undefined behaviour). What you gain is 
that no object will be allocated on top of the old one, and thus new 
objects can't get corrupted. But it's still undefined behaviour, only 
with less side effects and more memory consumption.


I don't think it's a so bad idea on the whole, but it'd be more valuable 
if accessing an invalidated object could be made an error instead of 
undefined behaviour. If this can't be done, then we should encourage 
destructors to put the object in a clean state and not leave any dirt 
behind. But should that still be called a destructor?


Perhaps we could change the paradigm a little and replace deletion 
with recycling. Recycling an object would call the destructor and 
immeditately call the default constructor, so the object is never left 
in an invalid state. Objects with no default constructor cannot be 
recycled. This way you know memory is always left in a clean state, and 
you encourage programmers to safely reuse the memory blocks from objects 
they have already allocated when possible.


Yes, recycling is best and I'm considering it. I'm only worried about 
the extra cost.


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el  6 de octubre a las 21:42 me escribiste:

should call a destructor but not call delete() or notify the GC
that the memory is free.

That is correct. In particular, an object remains usable after delete.

Why would you do that? What is the rationale to not notify the GC?

Because there may be other live references to the object.


But when using delete that's exactly what it should happen. You are hiding
a bug if you let that happen on purpose.


That is not hiding a bug. That's even worse than Walter's crappy 
argument :o).



You're saying that there is a problem, but you're not telling us
what's wrong. Why the hell do you want to destroy an object
without recycling its memory? Why does the inability to do so
cause a problem?

The matter has been discussed quite a bit around here and in other
places. I'm not having as much time as I'd want to explain things.
In short, destroying without freeing memory avoids dangling
references and preserves memory safety without impacting on other
resources.

But D is a system programming language.

Well it is but there are quite a few more things at stake. First, it
is a reality that it is often desirable to distinguish between
calling the destructor and reclaiming memory. D's current delete
continues the bad tradition started by C++ of conflating the two.


Why is a bad idea? If you are destroying an object, the object will be in
an inconsistent state. What's the point of keeping it alive. Again, you're
just hiding a bug; letting the bug live longer. The language should try to
expose bugs ASAP, not delay the detection.


It is a bad idea because distinguishing between release of (expensive) 
resources from dangerous memory recycling is the correct way to obtain 
deterministic resource management within the confines of safety.



I think is a good idea not to force the GC to free the memory immediately
with a delete, but it should if it's easy. Other protection methods as
using mprotect to protect the objects pages it's very desirable too,
because you can spot an access to a inconsistent (destroyed) object as
soon as it first happen.


(mprotect is much too coarse to be useful.) With the dispose() function 
the state of the object will be restored to default construction:


void dispose(T)(T obj) if (is(T == class) || is(typeof(*T.init))) {
   ... call destructor if any ...
   ... obliterate object with .init ...
   ... invoke default ctor if any ...
}


If you wrote delete x; the
language should assume you know what you're doing.

I think delete should be present in SafeD and if you want manual
memory management you should build on malloc and free.


If you want to introduce a new semantic, I think you should provide a new
method, not change the semantic of an existent one.


Agreed. I hereby vote for deprecating delete with extreme prejudice.


And BTW, is there any reason why this can't be implemented in the library
instead of using an operator? Why don't you provide a destroy() function
for that in Phobos?


That sounds great.


Really, I can't see any advantages on changing the delete operator
semantics, only problems.


I agree.


If you only want to
deinitialize an object, you can write a .destroy() method for example,
and call that. I think delete have a strong established semantic to change
it now, and without any gain.

It has a thoroughly broken and undesired semantics. It would be a step
forward to divorce it of that.


Why it's broken? Why it's undesired?


(See above in this message.)


Why? Using malloc and free is a lot more trouble, you have to register the
roots yourself for example. It's not like you do malloc() and free() and
everything works magically. You have to have more knowledge of the GC to
use them. Being able to manually manage the *GC* heap (if the GC support
that, if not it can make it a NOP) is good IMHO.


We can make things a tad better with library functions, but we do need 
to have a garbage collected heap that guarantees safety.



Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 It is a bad idea because distinguishing between release of (expensive)
 resources from dangerous memory recycling is the correct way to obtain
 deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
worthwhile
tradeoff to add a few manual delete statements to code and sacrifice some safety
for making the GC run less often.)


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Michel Fortin wrote:
On 2009-10-07 08:46:06 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org said:


You're right. It would be great to dispose of the delete keyword and 
define a member function and/or a free function that invokes the 
destructor and obliterates the object with its .init bits.


I guess I should have read this before posting mine. :-)

You're suggesting obiterating with the .init bits, but I believe this is 
insufficient: you need to call a constructor if you want to be sure 
object invariants holds. If you can't make the invariants hold, you're 
in undefined behaviour territory.


That is correct. The default constructor must be called for classes. For 
structs, copying .init over will do.


At any rate: deletion + memory reclamation must go. If you want to do 
manual memory management, malloc/free are yours. D's native GC heap is 
not the right place.


Well, yes you're entirely right saying that. But I fail to see how this 
is linked to class allocators and deallocators.


Discussion took a turn.

Class allocators and 
deallocators are just a way to tell the runtime (including the GC) how 
to allocate and deallocate a specific class of objects. There is no need 
to manually call delete for the allocator and deallocator to be useful.


The way it is currently, if you want objects of a certain class to be 
allocated in one big object pool, you can encapsulate that detail in the 
class so clients don't have to bother about it. I've done that in C++ to 
speed up things without having to touch the rest of the code base and 
it's quite handy.


At other times the client of the class that wants to manage memory, and 
that should be allowed too, bypassing the class's allocator and 
deallocator and calling directly the constructor and destructor.


I agree that some would want to manage their own allocation, and see no 
fault with a pool that exposes factory methods a la create() and 
recycle() or whatever.


The language has become larger and more powerful. Now we're in an odd 
situation: the language has become powerful enough to render obsolete 
some things that previously were in the language because they couldn't 
be expressed. Consider a factory method create(). In the olden days, 
there was no way to properly forward variadic arguments to an object's 
constructor. So repeating C++'s awful hack seemed like a reasonable 
thing to do. Now even the new keyword isn't that justified because a 
simple function could do everything new does, plus custom allocation and 
whatever if we so want.


Walter, Don and myself are looking into ways of making the language 
smaller and moving some of built-in functionality to the standard 
library. Tomasz' post on making an in-situ class instance was a 
watershed point for me. I thought about it some more and realized that 
language size and library size aren't the same thing. (I had a feeling 
before that, but no good argument.)


Language is not modular and doesn't have well-defined boundaries that 
carve subunits. Libraries do. I can always say I will/won't use this 
module/package/library but the language just comes at you in parallel. 
Conversely, if you see something you don't know in some code and it's in 
a library, you can always decide to look at that library's code and/or 
documentation and figure out what's what. In contrast, if I saw a 
highlighted keyword that I had no idea what it does I'd get quite worried.



Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Jeremie Pelletier wrote:

Andrei Alexandrescu wrote:

Hello,


D currently allows defining class allocators and deallocators. They 
have a number of problems that make them unsuitable for D 2.0. The 
most obvious issue is that D 2.0 will _not_ conflate destruction with 
deallocation anymore: invoking delete against an object will call 
~this() against it but will not recycle its memory. In contrast, class 
deallocators are designed around the idea that invoking delete calls 
the destructor and also deallocates memory.


So I'm thinking of removing at least class deallocators from the 
language. Class allocators may be marginally and occasionally useful 
if the user takes the matter of deallocation in her own hands.


A much better way to handle custom allocation of classes would be in 
the standard library.


What do you think?


Andrei


I wouldn't like delete to go away at all, I use it for all my non-gc 
objects like this watered down example:


class ManualObject : Object {
new(size_t size) { return malloc(size); }
delete(void* mem) { free(mem); }
}

And then I can easily subclass it for any objects that doesn't need the 
GC. I've got similar constructs for arrays and structs.


Clearly you use those objects in a very different manner than GC 
objects. So by using new/delete with them you're fooling yourself.


// untested
class ManualObject {
static T create(T : ManualObject)() {
auto p = malloc(__traits(classInstanceSize, T));
memcpy(p, T.classinfo.init.ptr, __traits(classInstanceSize, T));
auto result = cast(T) p;
result.__ctor();
return result;
}
static void yank(ManualObject obj) {
free(cast(void*) obj);
}
}

Looks like a fair amount of work? At some level it actually should, but 
we can put that kind of stuff in the standard library.


malloc/free are nice, but they don't allow for elegant abstractions like 
new/delete does (for example if you want to use a specialized non-gc 
allocator you can just replace a few calls instead of every allocation).


They do if you're willing to write just a bit of scaffolding.

I also use delete when I no longer need large blocks of memory, I don't 
want them to just become uninitialized and sitting on the GC. When I 
want to do that I just nullify my references.


If you're afraid of deleting an object that may still have valid 
references, use smart pointers, or don't delete it at all if it sits on 
the gc and just call a .destroy() method.


Also in my runtime the delete implementations do free the memory, they 
don't just call the finalizer.


In any ways, just don't remove new/delete overrides from the language 
please, just call it a low-level technique or something to scare the 
beginners away and let people who want it have it :)


I strongly believe custom new/delete must go.


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

It is a bad idea because distinguishing between release of (expensive)
resources from dangerous memory recycling is the correct way to obtain
deterministic resource management within the confines of safety.


This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
worthwhile
tradeoff to add a few manual delete statements to code and sacrifice some safety
for making the GC run less often.)


malloc.

Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread downs
Jeremie Pelletier wrote:
 downs wrote:
 Don wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 downs wrote:
 Andrei Alexandrescu wrote:
 Hello,


 D currently allows defining class allocators and deallocators.
 They
 have
 a number of problems that make them unsuitable for D 2.0. The most
 obvious issue is that D 2.0 will _not_ conflate destruction with
 deallocation anymore: invoking delete against an object will call
 ~this() against it but will not recycle its memory. In contrast,
 class
 deallocators are designed around the idea that invoking delete
 calls the
 destructor and also deallocates memory.

 So I'm thinking of removing at least class deallocators from the
 language. Class allocators may be marginally and occasionally
 useful if
 the user takes the matter of deallocation in her own hands.

 A much better way to handle custom allocation of classes would be
 in the
 standard library.

 What do you think?


 Andrei
 Do you trust the D GC to be good enough to always free everything
 you've allocated, without error?

 If your answer was 'ye- maaybe ... no actually', please rethink
 this.
 People will always be able to call functions in the garbage
 collector
 manually. The discussion on class allocators and deallocators has
 nothing to do with that.

 Andrei
 So you can still deallocate a class by hand, only it's not called
 delete anymore?
 That is correct.

 Andrei
 Isn't that a pretty big violation of Least Surprise?

 http://en.wikipedia.org/wiki/Principle_of_least_astonishment :
 In user interface design, programming language design, and
 ergonomics, the principle (or rule or law) of least astonishment (or
 surprise) states that, when two elements of an interface conflict, or
 are ambiguous, the behaviour should be that which will *least
 surprise* the human user or programmer at the time the conflict
 arises.
 I think the basic rule being introduced is:
 that every object can be managed by the gc, or manually managed. But not
 both. That seems reasonable to me. But if delete no longer deletes, it
 needs a name change.


 Oh, that makes more sense.

 Do manually managed objects still count under MarkSweep?
 
 You have to register the memory range they cover to the GC if they
 contain pointers to GC memory. Otherwise the GC don't know they exist at
 all.

Well I certainly wouldn't expect that! :p

This sounds like something that might trip people up. I believe at least 
scanning objects by GC should always be the default for any object, if only 
because the association D heap = GC managed is I think a fairly core part of 
the language.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Manfred_Nowak
Andrei Alexandrescu wrote:

  if I saw a highlighted keyword that I had no idea what it does I'd
  get quite worried 

Why wouldn't you try to look at the documentation of the language---as you 
do with the documentation of a library?

-manfred



Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Sean Kelly wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

It is a bad idea because distinguishing between release of (expensive)
resources from dangerous memory recycling is the correct way to obtain
deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
worthwhile
tradeoff to add a few manual delete statements to code and sacrifice some safety
for making the GC run less often.)

malloc.


So for placement construction of a class, I guess it would look something like:

auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );

Is that right?


Yes, I think so, but I haven't checked all the details. For example I'm 
not sure whether __ctor copies .init over the memory before running the 
user-defined constructor, or expects that to have been done already.


My understanding from Walter is that __ctor(x, y, z) are simply the 
functions this(x, y, z) as written by the user, so you'd need to memcpy 
the .init by hand before calling __ctor.


Aw hell I got curious so let me check.

class MyClass {
int x = 42;
this() {}
}

void main() {
auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor();
writeln(x.x);
writeln(x.toString);
}

That prints 0 and then crashes on my machine. Looks like you need to 
memcpy the .init before calling __ctor.


I'm very glad we're starting to look into this. There are very nice 
opportunities for adding custom allocation support in the stdlib.



Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Manfred_Nowak wrote:

Andrei Alexandrescu wrote:


 if I saw a highlighted keyword that I had no idea what it does I'd
 get quite worried 


Why wouldn't you try to look at the documentation of the language---as you 
do with the documentation of a library?


-manfred



I didn't say I wouldn't. I just said I'd be much more worried.

My point is, languages are never modular. To be even marginally
effective in a language, you must have some understanding of it all.
That definitely isn't the case for libraries.


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Leandro Lucarella
Andrei Alexandrescu, el  7 de octubre a las 13:06 me escribiste:
 I think is a good idea not to force the GC to free the memory immediately
 with a delete, but it should if it's easy. Other protection methods as
 using mprotect to protect the objects pages it's very desirable too,
 because you can spot an access to a inconsistent (destroyed) object as
 soon as it first happen.
 
 (mprotect is much too coarse to be useful.) With the dispose()
 function the state of the object will be restored to default
 construction:
 
 void dispose(T)(T obj) if (is(T == class) || is(typeof(*T.init))) {
... call destructor if any ...
... obliterate object with .init ...
... invoke default ctor if any ...
 }

Ok, if you're going to name that dispose, is fine with me. End of
discussion. With the addition of calling a constructor after destroying
the object, make a little more sense too (I still find it too bug prone,
you can end up with corruption if you dispose an object that other part of
the program think it's not disposed yet, i.e., in a state different than
the recently constructed object).

 If you want to introduce a new semantic, I think you should provide a new
 method, not change the semantic of an existent one.
 
 Agreed. I hereby vote for deprecating delete with extreme prejudice.
 
 And BTW, is there any reason why this can't be implemented in the library
 instead of using an operator? Why don't you provide a destroy() function
 for that in Phobos?
 
 That sounds great.
 
 Really, I can't see any advantages on changing the delete operator
 semantics, only problems.
 
 I agree.

I'm glad to see that.

 Why? Using malloc and free is a lot more trouble, you have to register the
 roots yourself for example. It's not like you do malloc() and free() and
 everything works magically. You have to have more knowledge of the GC to
 use them. Being able to manually manage the *GC* heap (if the GC support
 that, if not it can make it a NOP) is good IMHO.
 
 We can make things a tad better with library functions, but we do
 need to have a garbage collected heap that guarantees safety.

I don't think I understand this very well. What kind of safety? If the
user disposed/freed an object before it should, it's an user bug, with
unavoidable bad side effects. The best you can do is make the program
blow in the user face ASAP.

I don't understand what all this have to do with GC safety.

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
It's not a lie, if you believe it.
-- George Constanza


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Leandro Lucarella
Andrei Alexandrescu, el  7 de octubre a las 14:16 me escribiste:
 Sean Kelly wrote:
 == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
 == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 It is a bad idea because distinguishing between release of (expensive)
 resources from dangerous memory recycling is the correct way to obtain
 deterministic resource management within the confines of safety.
 This is based on two faulty assumptions:
 
 1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
 2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
 worthwhile
 tradeoff to add a few manual delete statements to code and sacrifice some 
 safety
 for making the GC run less often.)
 malloc.
 
 So for placement construction of a class, I guess it would look something 
 like:
 
 auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
 x.__ctor( a, b, c ); // construct
 ...
 x.__dtor();
 free( cast(void*) x );
 
 Is that right?
 
 Yes, I think so, but I haven't checked all the details. For example
 I'm not sure whether __ctor copies .init over the memory before
 running the user-defined constructor, or expects that to have been
 done already.
 
 My understanding from Walter is that __ctor(x, y, z) are simply the
 functions this(x, y, z) as written by the user, so you'd need to
 memcpy the .init by hand before calling __ctor.

What I don't understand is why you're willing to make that hard to do
manual memory management in D. Do you see that you're making the
programmer's job deliberately for no reason? D needs conservative GC,
which means slow GC; by definition. D is a system programming language, so
it's expected to be fast, but because of the GC there will be often
situations where you have to do manual MM. Why are you making that much
harder?

You know that in the search for safety you'll be making much more unsafe
(or bug-prone) to do manual MM?

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Ya ni el cielo me quiere, ya ni la muerte me visita
Ya ni el sol me calienta, ya ni el viento me acaricia


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Leandro Lucarella
Andrei Alexandrescu, el  7 de octubre a las 14:18 me escribiste:
 Manfred_Nowak wrote:
 Andrei Alexandrescu wrote:
 
  if I saw a highlighted keyword that I had no idea what it does I'd
  get quite worried
 
 Why wouldn't you try to look at the documentation of the
 language---as you do with the documentation of a library?
 
 -manfred
 
 
 I didn't say I wouldn't. I just said I'd be much more worried.
 
 My point is, languages are never modular. To be even marginally
 effective in a language, you must have some understanding of it all.
 That definitely isn't the case for libraries.

Languages are modular when they let you define new syntax, but that's
another topic ;)

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
You look so tired-unhappy,
bring down the government,
they don't, they don't speak for us.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el  7 de octubre a las 14:18 me escribiste:

Manfred_Nowak wrote:

Andrei Alexandrescu wrote:


if I saw a highlighted keyword that I had no idea what it does I'd
get quite worried

Why wouldn't you try to look at the documentation of the
language---as you do with the documentation of a library?

-manfred


I didn't say I wouldn't. I just said I'd be much more worried.

My point is, languages are never modular. To be even marginally
effective in a language, you must have some understanding of it all.
That definitely isn't the case for libraries.


Languages are modular when they let you define new syntax, but that's
another topic ;)


A topic at which no language succeeded.

Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el  7 de octubre a las 14:16 me escribiste:

Sean Kelly wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

It is a bad idea because distinguishing between release of (expensive)
resources from dangerous memory recycling is the correct way to obtain
deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
worthwhile
tradeoff to add a few manual delete statements to code and sacrifice some safety
for making the GC run less often.)

malloc.

So for placement construction of a class, I guess it would look something like:

auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );

Is that right?

Yes, I think so, but I haven't checked all the details. For example
I'm not sure whether __ctor copies .init over the memory before
running the user-defined constructor, or expects that to have been
done already.

My understanding from Walter is that __ctor(x, y, z) are simply the
functions this(x, y, z) as written by the user, so you'd need to
memcpy the .init by hand before calling __ctor.


What I don't understand is why you're willing to make that hard to do
manual memory management in D. Do you see that you're making the
programmer's job deliberately for no reason? D needs conservative GC,
which means slow GC; by definition. D is a system programming language, so
it's expected to be fast, but because of the GC there will be often
situations where you have to do manual MM. Why are you making that much
harder?

You know that in the search for safety you'll be making much more unsafe
(or bug-prone) to do manual MM?


You seem to be asserting that without additional built-in language 
support, manual memory management is unduly difficult. Why so?


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
  It is a bad idea because distinguishing between release of (expensive)
  resources from dangerous memory recycling is the correct way to obtain
  deterministic resource management within the confines of safety.
 
  This is based on two faulty assumptions:
 
  1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
  2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
  worthwhile
  tradeoff to add a few manual delete statements to code and sacrifice some 
  safety
  for making the GC run less often.)
 malloc.
 Andrei

Kludge.  Requires using two separate heaps (inefficient) and worrying about
whether your stuff is manually freed on all code paths, not just the ones that 
are
executed often enough for performance to matter.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Leandro Lucarella
Andrei Alexandrescu, el  7 de octubre a las 15:23 me escribiste:
 Leandro Lucarella wrote:
 Andrei Alexandrescu, el  7 de octubre a las 14:16 me escribiste:
 Sean Kelly wrote:
 == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
 == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
 article
 It is a bad idea because distinguishing between release of (expensive)
 resources from dangerous memory recycling is the correct way to obtain
 deterministic resource management within the confines of safety.
 This is based on two faulty assumptions:
 
 1.  Memory is cheap.  (Not if you are working with absurd amounts of 
 data).
 2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
 worthwhile
 tradeoff to add a few manual delete statements to code and sacrifice 
 some safety
 for making the GC run less often.)
 malloc.
 So for placement construction of a class, I guess it would look something 
 like:
 
 auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
 x.__ctor( a, b, c ); // construct
 ...
 x.__dtor();
 free( cast(void*) x );
 
 Is that right?
 Yes, I think so, but I haven't checked all the details. For example
 I'm not sure whether __ctor copies .init over the memory before
 running the user-defined constructor, or expects that to have been
 done already.
 
 My understanding from Walter is that __ctor(x, y, z) are simply the
 functions this(x, y, z) as written by the user, so you'd need to
 memcpy the .init by hand before calling __ctor.
 
 What I don't understand is why you're willing to make that hard to do
 manual memory management in D. Do you see that you're making the
 programmer's job deliberately for no reason? D needs conservative GC,
 which means slow GC; by definition. D is a system programming language, so
 it's expected to be fast, but because of the GC there will be often
 situations where you have to do manual MM. Why are you making that much
 harder?
 
 You know that in the search for safety you'll be making much more unsafe
 (or bug-prone) to do manual MM?
 
 You seem to be asserting that without additional built-in language
 support, manual memory management is unduly difficult. Why so?

Because of this:

 auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
 x.__ctor( a, b, c ); // construct
 ...
 x.__dtor();
 free( cast(void*) x );

:)

You even forgot to register your object as a root in the GC, so if your
MyClass has any pointers to the GC your program will blow in your face.

If you plan to library support to ease this and avoid repetitive and
bug-prone work, you can ignore my complains...

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Y tuve amores, que fue uno sólo
El que me dejó de a pie y me enseñó todo...


Re: D marketplace

2009-10-07 Thread Stanley Steel
language_fan Wrote:

 
 The nntp system is not that bad actually. What annoys me on the 
 announcement group is that there is too much OT discussion and new 
 release announcements are added to the same thread with lots of OT posts. 
 Some kind of moderation would be more than welcome.
 
 If you have time and energy, you could also fix the web interface and/or 
 improve its user interface design - it's annoyingly broken and ugly. I 
 guess Walter would be more than glad to accept patches.

I am looking for a project to complete to help enhance my nonexistent 
portfolio.  So, I was hoping to do something along the lines of web development 
and design as that is where my interest and experience lies.  Hence, the 
suggestion to do something other than a newsgroup topic.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el  7 de octubre a las 15:23 me escribiste:

You seem to be asserting that without additional built-in language
support, manual memory management is unduly difficult. Why so?


Because of this:


auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );


:)

You even forgot to register your object as a root in the GC, so if your
MyClass has any pointers to the GC your program will blow in your face.

If you plan to library support to ease this and avoid repetitive and
bug-prone work, you can ignore my complains...


I too think it would be great to add the necessary support to the
stdlib. In fact, since you have a great deal of expertise in the matter,
feel free to suggest API functions! They'd need to be approved by Sean
too because probably they belong to druntime.

Andrei



Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

It is a bad idea because distinguishing between release of (expensive)
resources from dangerous memory recycling is the correct way to obtain
deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes it's a 
worthwhile
tradeoff to add a few manual delete statements to code and sacrifice some safety
for making the GC run less often.)

malloc.
Andrei


Kludge.  Requires using two separate heaps (inefficient) and worrying about
whether your stuff is manually freed on all code paths, not just the ones that 
are
executed often enough for performance to matter.


Au contraire, once the GC heap becomes safe, I have less to worry about.

Andrei


Re: D marketplace

2009-10-07 Thread Walter Bright

Stanley Steel wrote:

I am looking for a project to complete to help enhance my nonexistent
portfolio.  So, I was hoping to do something along the lines of web
development and design as that is where my interest and experience
lies.  Hence, the suggestion to do something other than a newsgroup
topic.


I've been interested in a long time in writing a D cgi application that 
runs on the server and enables a reddit-like view of the n.g. postings, 
as well as the usual n.g. nntp interface.


The current archiving stuff 
http://www.digitalmars.com/d/archives/digitalmars/D/announce/index.html
is a step in that direction, but it is not interactive and doesn't allow 
posting.


People would have two possible ways to interact with the n.g. - through 
the standard NNTP interface using a normal newsreader, or the 
reddit-style interactive web view. The latter would also allow logged in 
users to vote + or -, have avatars, etc.


Re: D marketplace

2009-10-07 Thread Nick Sabalausky
Walter Bright newshou...@digitalmars.com wrote in message 
news:haj1ek$20s...@digitalmars.com...
 Stanley Steel wrote:
 I am looking for a project to complete to help enhance my nonexistent
 portfolio.  So, I was hoping to do something along the lines of web
 development and design as that is where my interest and experience
 lies.  Hence, the suggestion to do something other than a newsgroup
 topic.

 I've been interested in a long time in writing a D cgi application that 
 runs on the server and enables a reddit-like view of the n.g. postings, as 
 well as the usual n.g. nntp interface.


Oooh, yea. In fact, speaking of D abnd CGI, an up-to-date D 
equivilent-of/port/bindings-for/etc of FastCGI (sorry no link handy atm, but 
should be easy to google) would be a great thing for D to have.




Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Craig Black
Andrei Alexandrescu Wrote:

 Michel Fortin wrote:
  On 2009-10-06 20:26:48 -0400, Andrei Alexandrescu 
  seewebsiteforem...@erdani.org said:
  
  The matter has been discussed quite a bit around here and in other 
  places. I'm not having as much time as I'd want to explain things. In 
  short, destroying without freeing memory avoids dangling references 
  and preserves memory safety without impacting on other resources.
 
  It's a safety hack, not a performance hack.
  
  In my opinion, it's mostly an illusion of safety. If you call the 
  destructor on an object, the object state after the call doesn't 
  necessarily respects the object invariants and doing anything with it 
  could result in, well, anything, from returning wrong results to falling 
  into an infinite loop (basically undefined behaviour). What you gain is 
  that no object will be allocated on top of the old one, and thus new 
  objects can't get corrupted. But it's still undefined behaviour, only 
  with less side effects and more memory consumption.
  
  I don't think it's a so bad idea on the whole, but it'd be more valuable 
  if accessing an invalidated object could be made an error instead of 
  undefined behaviour. If this can't be done, then we should encourage 
  destructors to put the object in a clean state and not leave any dirt 
  behind. But should that still be called a destructor?
  
  Perhaps we could change the paradigm a little and replace deletion 
  with recycling. Recycling an object would call the destructor and 
  immeditately call the default constructor, so the object is never left 
  in an invalid state. Objects with no default constructor cannot be 
  recycled. This way you know memory is always left in a clean state, and 
  you encourage programmers to safely reuse the memory blocks from objects 
  they have already allocated when possible.
 
 Yes, recycling is best and I'm considering it. I'm only worried about 
 the extra cost.
 
 Andrei

No this is a bad idea.  Removing the possibility to delete data will cause 
serious problems with heap fragmentation in some programs.

-Craig



Re: Eliminate class allocators and deallocators?

2009-10-07 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
  dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
  article
  It is a bad idea because distinguishing between release of (expensive)
  resources from dangerous memory recycling is the correct way to obtain
  deterministic resource management within the confines of safety.
  This is based on two faulty assumptions:
 
  1.  Memory is cheap.  (Not if you are working with absurd amounts of 
  data).
  2.  Garbage collection is never a major bottleneck.  (Sometimes it's a
worthwhile
  tradeoff to add a few manual delete statements to code and sacrifice some 
  safety
  for making the GC run less often.)
  malloc.
  Andrei
 
  Kludge.  Requires using two separate heaps (inefficient) and worrying about
  whether your stuff is manually freed on all code paths, not just the ones 
  that are
  executed often enough for performance to matter.
 Au contraire, once the GC heap becomes safe, I have less to worry about.
 Andrei

If you're that concerned about making the GC heap safe, here's a less 
destructive
(to other people's programming styles) way to do it:

1.  Make delete only call the d'tor and not release memory.  (I'm fine with this
provided the stuff below is done.)

2.  Add a std. lib convenience function to core.memory that does what delete 
does
now (calls d'tor AND frees memory).  For the purposes of this discussion, we'll
call it deleteFree().  There's already a std. lib. function that just frees
memory, GC.free().  Keep it.

3.  If you really insist on absolute heap safety even at the expense of
performance, grep your code and get rid of all deleteFree() and GC.free() calls.

Frankly, I consider the ability to manually free GC allocated memory to be a 
HUGE
asset for the following reasons, which I've mentioned before but would like to
distill:

1.  GC is usually the best way to program, but can be a huge bottleneck in some
corner cases.

2.  Maintaining two separate heaps (the manually memory managed C heap and the
GC'd D heap) is a massive and completely unacceptable kludge because:

1.  If you just want to delete a few objects to make the GC run less often, you
can just add delete statements for the common code paths, or paths where the end
of an object's lifetime is obvious.  You then just let the GC handle the less
common code paths or cases where object lifetimes are non-trivial and gain tons 
of
simplicity for only a small performance loss.  If you have to handle all the odd
code paths manually too, this is when bugs really start to seep in.

2.  Heaps have overhead.  Two heaps have twice the overhead.

3.  addroot(), etc. is a PITA *and* adds yet another place where you have to 
lock
on the GC mutex.  Half the need for manual memory management in D is because the
GC sometimes scales poorly to large numbers of threads.  This would definitely 
not
help the situation.

4.  Using the C heap whenever you want the ability to manually free something
doesn't play nicely w/ builtin language features such as classes, arrays,
associative arrays, etc., or objects returned from library functions.

Because of these 4 issues, I feel that only being allowed to do manual memory
management if you use the C heap is such an unacceptably bad kludge that it is 
for
many practical purposes akin to not being allowed to do manual memory management
at all.  This is unacceptable in a systems/performance language.

Remember, performance/systems languages can't place excessive emphasis on safety
and absolutely MUST assume the programmer knows what he/she is doing.  If you 
want
Java, you know where to find it.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread grauzone

Andrei Alexandrescu wrote:

Sean Kelly wrote:
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
article

dsimcha wrote:
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
article

It is a bad idea because distinguishing between release of (expensive)
resources from dangerous memory recycling is the correct way to obtain
deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts of 
data).
2.  Garbage collection is never a major bottleneck.  (Sometimes it's 
a worthwhile
tradeoff to add a few manual delete statements to code and sacrifice 
some safety

for making the GC run less often.)

malloc.


So for placement construction of a class, I guess it would look 
something like:


auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );

Is that right?


Yes, I think so, but I haven't checked all the details. For example I'm 
not sure whether __ctor copies .init over the memory before running the 
user-defined constructor, or expects that to have been done already.


Apparently it doesn't: 
http://www.digitalmars.com/techtips/class_objects.html


See, it's even documented.

Anyway, does your statement mean that _ctor is officially supported (by 
all conform D compilers)?


Because, quoting from the page above:
This technique goes under the hood of how D works, and as such it is 
not guaranteed to work with every D compiler. In particular, how the 
constructors and destructors are called is not necessarilly portable.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Michel Fortin

On 2009-10-07 17:53:21 -0400, Craig Black cbl...@ara.com said:


Yes, recycling is best and I'm considering it. I'm only worried about
the extra cost.

Andrei


No this is a bad idea.  Removing the possibility to delete data will 
cause serious problems with heap fragmentation in some programs.


Hum, perhaps we need to review more thoroughly how memory allocation 
works. As Andrei said himself, we now have all the necessary parts in 
the language to reimplement 'new' as a library function.


So let's say we ditch 'new' and 'delete' as keywords. Let's first 
replace the keyword 'new' with a static function of the same name in a 
class or a struct. It could be implemented this way:


static T new(A...)(A a) {
T t = GC.alloc!T(); // GC.alloc sets the T.init bits.
t.__ctor(a);
return t;
}

Usage:

Foo foo = Foo.new();

That's a static function template that needs to be reimplemented for 
every subclass (Andrei already proposed such kind of mixins) and that 
returns a garbage-collected object reference. Now, if you want manual 
allocation:


static T new(A...)(A a) {
T t = GC.allocNoCollect!T(); // GC won't collect this bit.
t.__ctor(a);
return t;
}

void dispose() {
this.__dtor();
GC.free(this);
}

Usage:

Foo foo = Foo.new();
...
foo.dispose();

But then you could do much better: 'new' could return a different type: 
a smart reference-counted pointer struct for instance. The 
possibilities are endless.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: D marketplace

2009-10-07 Thread Stanley Steel
Walter Bright Wrote:

 Stanley Steel wrote:
  I am looking for a project to complete to help enhance my nonexistent
  portfolio.  So, I was hoping to do something along the lines of web
  development and design as that is where my interest and experience
  lies.  Hence, the suggestion to do something other than a newsgroup
  topic.
 
 I've been interested in a long time in writing a D cgi application that 
 runs on the server and enables a reddit-like view of the n.g. postings, 
 as well as the usual n.g. nntp interface.
 
 The current archiving stuff 
 http://www.digitalmars.com/d/archives/digitalmars/D/announce/index.html
 is a step in that direction, but it is not interactive and doesn't allow 
 posting.
 
 People would have two possible ways to interact with the n.g. - through 
 the standard NNTP interface using a normal newsreader, or the 
 reddit-style interactive web view. The latter would also allow logged in 
 users to vote + or -, have avatars, etc.

Just out of curiosity, do you or could you have a database running or would you 
want to use flat files for data storage?


Re: D marketplace

2009-10-07 Thread Walter Bright

Stanley Steel wrote:

Walter Bright Wrote:

I've been interested in a long time in writing a D cgi application
that runs on the server and enables a reddit-like view of the n.g.
postings, as well as the usual n.g. nntp interface.

The current archiving stuff 
http://www.digitalmars.com/d/archives/digitalmars/D/announce/index.html

 is a step in that direction, but it is not interactive and doesn't
allow posting.

People would have two possible ways to interact with the n.g. -
through the standard NNTP interface using a normal newsreader, or
the reddit-style interactive web view. The latter would also allow
logged in users to vote + or -, have avatars, etc.


Just out of curiosity, do you or could you have a database running or
would you want to use flat files for data storage?


I see the 'database' as the NNTP message files, unmodified, so the NNTP 
news server runs unmodified and unmolested. The cgi app should create an 
additional database with the votes  avatars, etc., that is separate. 
The cgi app should 'post' to NNTP any new messages, and monitor the NNTP 
message files for new ones.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

grauzone wrote:

Andrei Alexandrescu wrote:

Sean Kelly wrote:
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
article

dsimcha wrote:
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
article
It is a bad idea because distinguishing between release of 
(expensive)
resources from dangerous memory recycling is the correct way to 
obtain

deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts 
of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes 
it's a worthwhile
tradeoff to add a few manual delete statements to code and 
sacrifice some safety

for making the GC run less often.)

malloc.


So for placement construction of a class, I guess it would look 
something like:


auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );

Is that right?


Yes, I think so, but I haven't checked all the details. For example 
I'm not sure whether __ctor copies .init over the memory before 
running the user-defined constructor, or expects that to have been 
done already.


Apparently it doesn't: 
http://www.digitalmars.com/techtips/class_objects.html


See, it's even documented.

Anyway, does your statement mean that _ctor is officially supported (by 
all conform D compilers)?


Because, quoting from the page above:
This technique goes under the hood of how D works, and as such it is 
not guaranteed to work with every D compiler. In particular, how the 
constructors and destructors are called is not necessarilly portable.


That technique will be used by a library function.

Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Denis Koroskin wrote:
I'm not sure you will convince people to use foo.recycle() instead of 
foo.delete(). Not only it's slower, I believe recycling an object works 
for hiding bugs: accessing a recycled object - obviously a bug - will no 
longer be detected.


Is anyone under the illusion that today there's any detection going on?

Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Denis Koroskin
On Thu, 08 Oct 2009 04:13:12 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
I'm not sure you will convince people to use foo.recycle() instead of  
foo.delete(). Not only it's slower, I believe recycling an object works  
for hiding bugs: accessing a recycled object - obviously a bug - will  
no longer be detected.


Is anyone under the illusion that today there's any detection going on?

Andrei


There is none, but it's possible. It's just not implemented.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Michel Fortin wrote:

On 2009-10-07 17:53:21 -0400, Craig Black cbl...@ara.com said:


Yes, recycling is best and I'm considering it. I'm only worried about
the extra cost.

Andrei


No this is a bad idea.  Removing the possibility to delete data will 
cause serious problems with heap fragmentation in some programs.


Hum, perhaps we need to review more thoroughly how memory allocation 
works. As Andrei said himself, we now have all the necessary parts in 
the language to reimplement 'new' as a library function.


So let's say we ditch 'new' and 'delete' as keywords. Let's first 
replace the keyword 'new' with a static function of the same name in a 
class or a struct. It could be implemented this way:


static T new(A...)(A a) {
T t = GC.alloc!T(); // GC.alloc sets the T.init bits.
t.__ctor(a);
return t;
}

Usage:

Foo foo = Foo.new();

That's a static function template that needs to be reimplemented for 
every subclass (Andrei already proposed such kind of mixins) and that 
returns a garbage-collected object reference. Now, if you want manual 
allocation:


static T new(A...)(A a) {
T t = GC.allocNoCollect!T(); // GC won't collect this bit.
t.__ctor(a);
return t;
}

void dispose() {
this.__dtor();
GC.free(this);
}

Usage:

Foo foo = Foo.new();
...
foo.dispose();

But then you could do much better: 'new' could return a different type: 
a smart reference-counted pointer struct for instance. The possibilities 
are endless.




That's just awesome. Incidentally it would dovetail nicely with the code 
injection feature that I recently discussed here. But then that 
increases the size of the language...


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Denis Koroskin wrote:
On Thu, 08 Oct 2009 04:13:12 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
I'm not sure you will convince people to use foo.recycle() instead of 
foo.delete(). Not only it's slower, I believe recycling an object 
works for hiding bugs: accessing a recycled object - obviously a bug 
- will no longer be detected.


Is anyone under the illusion that today there's any detection going on?

Andrei


There is none, but it's possible. It's just not implemented.


It's not possible if you allow actual memory reuse! Now I'm not sure I 
understand what you want.


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Denis Koroskin
On Thu, 08 Oct 2009 04:39:20 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
On Thu, 08 Oct 2009 04:13:12 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
I'm not sure you will convince people to use foo.recycle() instead of  
foo.delete(). Not only it's slower, I believe recycling an object  
works for hiding bugs: accessing a recycled object - obviously a bug  
- will no longer be detected.


Is anyone under the illusion that today there's any detection going on?

Andrei

 There is none, but it's possible. It's just not implemented.


It's not possible if you allow actual memory reuse! Now I'm not sure I  
understand what you want.


Andrei


In our custom memory management system, deallocated memory gets filled  
with a debug data, which is checked for consistency when memory gets  
allocated again. Any write to that memory we be noticed. Not immediately,  
but still, it's better than nothing. Microsoft C++ debug runtime does the  
same.


Under Windows (2000 and later) you can also mark a range of memory as not  
accessible (by calling VirtualProtect on that memory with a PAGE_NOACCESS  
flag). Any read/write attempt with cause an immediate access violation  
exception. This is not widely used, probably because it's slow, but when  
you have a memory damage (caused by modifying some memory via a dangling  
pointer) performance is of lesser importance.


I believe similar mechanisms exist for nixes, too.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Michel Fortin
On 2009-10-07 20:11:31 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org said:


That's just awesome. Incidentally it would dovetail nicely with the 
code injection feature that I recently discussed here.


Indeed. That's what gave me the idea. :-)



But then that increases the size of the language...


Really? Remove new and delete; add code injection. Seems like a tie to 
me, except the later is much less limited and will solve problems well 
beyond memory allocation.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Denis Koroskin wrote:
On Thu, 08 Oct 2009 04:39:20 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
On Thu, 08 Oct 2009 04:13:12 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
I'm not sure you will convince people to use foo.recycle() instead 
of foo.delete(). Not only it's slower, I believe recycling an 
object works for hiding bugs: accessing a recycled object - 
obviously a bug - will no longer be detected.


Is anyone under the illusion that today there's any detection going on?

Andrei

 There is none, but it's possible. It's just not implemented.


It's not possible if you allow actual memory reuse! Now I'm not sure I 
understand what you want.


Andrei


In our custom memory management system, deallocated memory gets filled 
with a debug data, which is checked for consistency when memory gets 
allocated again. Any write to that memory we be noticed. Not 
immediately, but still, it's better than nothing. Microsoft C++ debug 
runtime does the same.


Under Windows (2000 and later) you can also mark a range of memory as 
not accessible (by calling VirtualProtect on that memory with a 
PAGE_NOACCESS flag). Any read/write attempt with cause an immediate 
access violation exception. This is not widely used, probably because 
it's slow, but when you have a memory damage (caused by modifying some 
memory via a dangling pointer) performance is of lesser importance.


I believe similar mechanisms exist for nixes, too.


There are (anyway, page-level marking is not the right level of 
granularity).


My overall point is twofold:

1. new and delete were symmetric in C++. In D they aren't and aren't 
supposed to be symmetric. The delete keyword should be deprecated and 
the functionality of delete should be relegated to a function.


2. Mostly as a consequence of (1), class-level operators new and delete 
are misdesigned and should be eliminated. Object 
factories/pools/regions/etc. should be the way to go for custom class 
allocation.


Heck, others are shunning new and we're clinging on to it?


Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
  2.  Maintaining two separate heaps (the manually memory managed C heap and 
  the
  GC'd D heap) is a massive and completely unacceptable kludge because:
 Coding in a way that requires the GC to offer manual deletion is a
 completely unacceptable kludge. Most GCs could NOT offer a primitive to
 manually release memory. Designing D around a requirement that manual
 deletions work on the GC is crippling pressure on GC designers.

Ok, fine, you got me on one point:  Manual freeing of objects only makes sense 
in
certain GC implementations.  So what?  GC.free() can be defined by the runtime
implementation.  If you're using something like pointer bump allocation with
generational, moving GC, the implementation is free to do nothing.  If you're
using conservative mark/sweep, it should actually free memory.


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
2.  Maintaining two separate heaps (the manually memory managed C heap and the
GC'd D heap) is a massive and completely unacceptable kludge because:

Coding in a way that requires the GC to offer manual deletion is a
completely unacceptable kludge. Most GCs could NOT offer a primitive to
manually release memory. Designing D around a requirement that manual
deletions work on the GC is crippling pressure on GC designers.


Ok, fine, you got me on one point:  Manual freeing of objects only makes sense 
in
certain GC implementations.  So what?  GC.free() can be defined by the runtime
implementation.  If you're using something like pointer bump allocation with
generational, moving GC, the implementation is free to do nothing.  If you're
using conservative mark/sweep, it should actually free memory.


I think there is convergence! My larger point is that we can leave 
GC.free() with loose semantics (e.g. may or may not act on it), and that 
we need to remove class-level allocators and probably the delete keyword 
too.



Andrei


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
  dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
  article
  2.  Maintaining two separate heaps (the manually memory managed C heap 
  and the
  GC'd D heap) is a massive and completely unacceptable kludge because:
  Coding in a way that requires the GC to offer manual deletion is a
  completely unacceptable kludge. Most GCs could NOT offer a primitive to
  manually release memory. Designing D around a requirement that manual
  deletions work on the GC is crippling pressure on GC designers.
 
  Ok, fine, you got me on one point:  Manual freeing of objects only makes 
  sense in
  certain GC implementations.  So what?  GC.free() can be defined by the 
  runtime
  implementation.  If you're using something like pointer bump allocation with
  generational, moving GC, the implementation is free to do nothing.  If 
  you're
  using conservative mark/sweep, it should actually free memory.
 I think there is convergence! My larger point is that we can leave
 GC.free() with loose semantics (e.g. may or may not act on it), and that
 we need to remove class-level allocators and probably the delete keyword
 too.
 Andrei

Perfect.  I'd be happy with this proposal as long as noone makes it harder to
manually free GC-allocated memory while the GC implementation is still
conservative mark-sweep or something similar.  I had been under the impression
that you wanted to flat-out get rid of GC.free().  Making it implementation
defined but requiring that it at least exist even if it does nothing makes 
perfect
sense.  If the implementation changes to some better algorithm (not likely in 
the
short term, but fairly likely in the long run), then my whole rationale for
wanting to free stuff manually in the first place may change.


Use of first person in a book

2009-10-07 Thread Andrei Alexandrescu
I'd decided to not use the first person at all in TDPL, but now I find 
myself a bit constrained by that decision. I personally think a small 
amount of meta-references and asides prevents boredom and brings a more 
personal note to the communication, but such devices should be used very 
sparingly and with care.


So I thought I'd ask a candid question in here. How do you feel about 
moderate use of the first person in a technical book? Do you find it 
comfortable, neutral, or cringeworthy?



Andrei


Re: Use of first person in a book

2009-10-07 Thread Jeremie Pelletier

Andrei Alexandrescu wrote:
I'd decided to not use the first person at all in TDPL, but now I find 
myself a bit constrained by that decision. I personally think a small 
amount of meta-references and asides prevents boredom and brings a more 
personal note to the communication, but such devices should be used very 
sparingly and with care.


So I thought I'd ask a candid question in here. How do you feel about 
moderate use of the first person in a technical book? Do you find it 
comfortable, neutral, or cringeworthy?



Andrei


I wouldn't cringe on the first person, so long as its not overused. Not 
using it definitely helps to set a neutral tone to the book, but a few 
uses of the first person here and there never hurt either.


For example, when describing something its best to avoid first person, 
but when you give a real world example its perfectly fine to use it 
since it shows you have personal experience with the example.


Just go with what you feel comfortable using, it usually shows when 
people go out of their way to try and please their audience instead of 
being themselves :)


Re: Use of first person in a book

2009-10-07 Thread Nick Sabalausky
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message 
news:hajod7$fm...@digitalmars.com...
 I'd decided to not use the first person at all in TDPL, but now I find 
 myself a bit constrained by that decision. I personally think a small 
 amount of meta-references and asides prevents boredom and brings a more 
 personal note to the communication, but such devices should be used very 
 sparingly and with care.

 So I thought I'd ask a candid question in here. How do you feel about 
 moderate use of the first person in a technical book? Do you find it 
 comfortable, neutral, or cringeworthy?


I don't write as much as I should, but I've always found the strict no 
first-person rule to be highly arbitrary. Worse, as a reader, I find that 
it often results in a quite awkward (and even pretentious) style. And FWIW, 
I find the always use plural first-person instead of singular first-person 
style to be even worse because it leads to statements that are just plain 
factually incorrect or misleading. 




Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Sean Kelly
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
  dsimcha wrote:
  == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
  article
  2.  Maintaining two separate heaps (the manually memory managed C heap 
  and the
  GC'd D heap) is a massive and completely unacceptable kludge because:
  Coding in a way that requires the GC to offer manual deletion is a
  completely unacceptable kludge. Most GCs could NOT offer a primitive to
  manually release memory. Designing D around a requirement that manual
  deletions work on the GC is crippling pressure on GC designers.
 
  Ok, fine, you got me on one point:  Manual freeing of objects only makes 
  sense in
  certain GC implementations.  So what?  GC.free() can be defined by the 
  runtime
  implementation.  If you're using something like pointer bump allocation with
  generational, moving GC, the implementation is free to do nothing.  If 
  you're
  using conservative mark/sweep, it should actually free memory.
 I think there is convergence! My larger point is that we can leave
 GC.free() with loose semantics (e.g. may or may not act on it), and that
 we need to remove class-level allocators and probably the delete keyword
 too.

The docs for GC.free() should already state that what actually happens is
implementation-defined.  If they don't it's an oversight on my part.  I do
agree that the presence of delete in D is a bit weird, and would be happy
to see it replaced by a library routine.  new as well.


Re: Use of first person in a book

2009-10-07 Thread Jarrett Billingsley
On Thu, Oct 8, 2009 at 12:04 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 I'd decided to not use the first person at all in TDPL, but now I find
 myself a bit constrained by that decision. I personally think a small amount
 of meta-references and asides prevents boredom and brings a more personal
 note to the communication, but such devices should be used very sparingly
 and with care.

 So I thought I'd ask a candid question in here. How do you feel about
 moderate use of the first person in a technical book? Do you find it
 comfortable, neutral, or cringeworthy?

I totally prefer reading something where I feel like the author is
having a conversation with me, so go ahead - use it!


Re: Use of first person in a book

2009-10-07 Thread Rainer Deyke
Andrei Alexandrescu wrote:
 So I thought I'd ask a candid question in here. How do you feel about
 moderate use of the first person in a technical book? Do you find it
 comfortable, neutral, or cringeworthy?

Occasionally a technical author finds that a personal anecdote or
opinion is useful for illustrating a concept.  The author then has these
choices:
  1. Leave it out.
  2. Treat it as a universal fact.
  3. Anonymize it.
  4. Talk about himself in the third person.
  5. Use first person.

The first three options are clearly bad because information is lost.  I
prefer option 5 over option 4, but both are acceptable to me.


-- 
Rainer Deyke - rain...@eldwood.com


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Ary Borenszweig

Andrei Alexandrescu wrote:

grauzone wrote:

Andrei Alexandrescu wrote:

Sean Kelly wrote:
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
article

dsimcha wrote:
== Quote from Andrei Alexandrescu 
(seewebsiteforem...@erdani.org)'s article
It is a bad idea because distinguishing between release of 
(expensive)
resources from dangerous memory recycling is the correct way to 
obtain

deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts 
of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes 
it's a worthwhile
tradeoff to add a few manual delete statements to code and 
sacrifice some safety

for making the GC run less often.)

malloc.


So for placement construction of a class, I guess it would look 
something like:


auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );

Is that right?


Yes, I think so, but I haven't checked all the details. For example 
I'm not sure whether __ctor copies .init over the memory before 
running the user-defined constructor, or expects that to have been 
done already.


Apparently it doesn't: 
http://www.digitalmars.com/techtips/class_objects.html


See, it's even documented.

Anyway, does your statement mean that _ctor is officially supported 
(by all conform D compilers)?


Because, quoting from the page above:
This technique goes under the hood of how D works, and as such it 
is not guaranteed to work with every D compiler. In particular, how 
the constructors and destructors are called is not necessarilly 
portable.


That technique will be used by a library function.


So... the library will be related somehow to the implementing compiler?


Re: Eliminate class allocators and deallocators?

2009-10-07 Thread Andrei Alexandrescu

Ary Borenszweig wrote:

Andrei Alexandrescu wrote:

grauzone wrote:

Andrei Alexandrescu wrote:

Sean Kelly wrote:
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s 
article

dsimcha wrote:
== Quote from Andrei Alexandrescu 
(seewebsiteforem...@erdani.org)'s article
It is a bad idea because distinguishing between release of 
(expensive)
resources from dangerous memory recycling is the correct way to 
obtain

deterministic resource management within the confines of safety.

This is based on two faulty assumptions:

1.  Memory is cheap.  (Not if you are working with absurd amounts 
of data).
2.  Garbage collection is never a major bottleneck.  (Sometimes 
it's a worthwhile
tradeoff to add a few manual delete statements to code and 
sacrifice some safety

for making the GC run less often.)

malloc.


So for placement construction of a class, I guess it would look 
something like:


auto x = cast(MyClass) malloc(MyClass.classinfo.init.length);
x.__ctor( a, b, c ); // construct
...
x.__dtor();
free( cast(void*) x );

Is that right?


Yes, I think so, but I haven't checked all the details. For example 
I'm not sure whether __ctor copies .init over the memory before 
running the user-defined constructor, or expects that to have been 
done already.


Apparently it doesn't: 
http://www.digitalmars.com/techtips/class_objects.html


See, it's even documented.

Anyway, does your statement mean that _ctor is officially supported 
(by all conform D compilers)?


Because, quoting from the page above:
This technique goes under the hood of how D works, and as such it 
is not guaranteed to work with every D compiler. In particular, how 
the constructors and destructors are called is not necessarilly 
portable.


That technique will be used by a library function.


So... the library will be related somehow to the implementing compiler?


I'd believe so!

Andrei


Member functions C to D

2009-10-07 Thread Craig Kuhnert
Hi
I am trying to convert some code I wrote in C++ to D to give it a try and I 
have come across some code that I dont know how to convert.
I have simplified the code to illustrate the problem I have.
How do I do this in D?

class IFieldSetter
{
public:
virtual void SetValue(void * object, const void * value) = 0;
};

template class C, class T
class FieldSetter : public IFieldSetter
{
private:
typedef T (C::* MemberField);
 MemberField field;

public:
FieldSetter(MemberField afield)
: field(afield)
{}

void SetTypedValue(C * object, const T value)
{
object-*field = value;
}

void SetValue(void * object, const void * value)
{
SetTypedValue((C*) object, (const T) value);
}
};

class MySampleClass
{
public:
int Status;
std::string Name;
};

void main(void)
{
IFieldSetter * StatusSetter = new 
FieldSetterMySampleClass,int(MySampleClass::Status);
IFieldSetter * NameSetter   = new 
FieldSetterMySampleClass,std::string(MySampleClass::Name);

MySampleClass * a = new MySampleClass();
MySampleClass * b = new MySampleClass();

StatusSetter-SetValue(a, (void*)20);
StatusSetter-SetValue(b, (void*)40);

NameSetter-SetValue(a, 2002);
NameSetter-SetValue(b, 2002);
}

Thanks
Craig


Re: Getting started - D meta-program question

2009-10-07 Thread downs
Justin Johansson wrote:
 Your code as below, using auto to declare a temporary var in an if statement, 
 ahh, nice,
 didn't know that.
 
  if (auto res = dg(current.data))
 return res;
 
 What other statement types can you generalized use of auto like this to?
 

Sadly, it's an if-specific syntax.

 Thank you for taking the time downs,
 
 -- Justin

Anytime.


Re: Member functions C to D

2009-10-07 Thread Craig Kuhnert
downs Wrote:

 Craig Kuhnert wrote:
  Hi
  I am trying to convert some code I wrote in C++ to D to give it a try and I 
  have come across some code that I dont know how to convert.
  I have simplified the code to illustrate the problem I have.
  How do I do this in D?
  
  class IFieldSetter
  {
  public:
  virtual void SetValue(void * object, const void * value) = 0;
  };
  
  template class C, class T
  class FieldSetter : public IFieldSetter
  {
  private:
  typedef T (C::* MemberField);
   MemberField field;
  
  public:
  FieldSetter(MemberField afield)
  : field(afield)
  {}
  
  void SetTypedValue(C * object, const T value)
  {
  object-*field = value;
  }
  
  void SetValue(void * object, const void * value)
  {
  SetTypedValue((C*) object, (const T) value);
  }
  };
  
  class MySampleClass
  {
  public:
  int Status;
  std::string Name;
  };
  
  void main(void)
  {
  IFieldSetter * StatusSetter = new 
  FieldSetterMySampleClass,int(MySampleClass::Status);
  IFieldSetter * NameSetter   = new 
  FieldSetterMySampleClass,std::string(MySampleClass::Name);
  
  MySampleClass * a = new MySampleClass();
  MySampleClass * b = new MySampleClass();
  
  StatusSetter-SetValue(a, (void*)20);
  StatusSetter-SetValue(b, (void*)40);
  
  NameSetter-SetValue(a, 2002);
  NameSetter-SetValue(b, 2002);
  }
  
  Thanks
  Craig
 
 If I'm getting this correctly, here's one way to do it ..
 
 module test;
 
 import std.stdio, tools.ctfe: ctReplace; // easy to write your own ctReplace 
 function
 
 template Init(T) { T Init; }
 
 interface IFieldSetter {
   void setValue(Object obj, void* value);
 }
 
 class FieldSetter(T: Object, string Name) : IFieldSetter {
   override void setValue(Object obj, void* value) {
 auto tee = cast(T) obj;
 mixin(tee.%NAME = *cast(typeof(tee.%NAME)*) value; .ctReplace(%NAME, 
 Name));
   }
   void setValue(T obj, typeof(mixin(Init!(T).~Name)) value) {
 mixin(obj.%NAME = value; .ctReplace(%NAME, Name));
   }
 }
 
 class Sample {
   int status;
   string name;
 }
 
 void main() {
   auto statSetter = new FieldSetter!(Sample, status);
   auto nameSetter = new FieldSetter!(Sample, name);
   auto sample = new Sample;
   int i = 20;
   statSetter.setValue(sample, i);
   statSetter.setValue(sample, 40);
   nameSetter.setValue(sample, Fooblr);
 }

Thanks
Thats brilliant! D rocks!
I never though of using mixin for that purpose.



Re: Member functions C to D

2009-10-07 Thread Jarrett Billingsley
On Wed, Oct 7, 2009 at 8:07 AM, Don nos...@nospam.com wrote:
 Craig Kuhnert wrote:

 downs Wrote:

 Craig Kuhnert wrote:

 Hi
 I am trying to convert some code I wrote in C++ to D to give it a try
 and I have come across some code that I dont know how to convert.
 I have simplified the code to illustrate the problem I have.
 How do I do this in D?

 class IFieldSetter
 {
 public:
        virtual void SetValue(void * object, const void * value) = 0;
 };

 template class C, class T
 class FieldSetter : public IFieldSetter
 {
 private:
        typedef T (C::* MemberField);
         MemberField field;

 public:
        FieldSetter(MemberField afield)
                : field(afield)
        {}

        void SetTypedValue(C * object, const T value)
        {
                object-*field = value;
        }

        void SetValue(void * object, const void * value)
        {
                SetTypedValue((C*) object, (const T) value);
        }
 };

 class MySampleClass
 {
 public:
        int Status;
        std::string Name;
 };

 void main(void)
 {
        IFieldSetter * StatusSetter = new
 FieldSetterMySampleClass,int(MySampleClass::Status);
        IFieldSetter * NameSetter   = new
 FieldSetterMySampleClass,std::string(MySampleClass::Name);

        MySampleClass * a = new MySampleClass();
        MySampleClass * b = new MySampleClass();

        StatusSetter-SetValue(a, (void*)20);
        StatusSetter-SetValue(b, (void*)40);

        NameSetter-SetValue(a, 2002);
        NameSetter-SetValue(b, 2002);
 }

 Thanks
 Craig

 If I'm getting this correctly, here's one way to do it ..

 module test;

 import std.stdio, tools.ctfe: ctReplace; // easy to write your own
 ctReplace function

 template Init(T) { T Init; }

 interface IFieldSetter {
  void setValue(Object obj, void* value);
 }

 class FieldSetter(T: Object, string Name) : IFieldSetter {
  override void setValue(Object obj, void* value) {
    auto tee = cast(T) obj;
    mixin(tee.%NAME = *cast(typeof(tee.%NAME)*) value;
 .ctReplace(%NAME, Name));
  }
  void setValue(T obj, typeof(mixin(Init!(T).~Name)) value) {
    mixin(obj.%NAME = value; .ctReplace(%NAME, Name));
  }
 }

 class Sample {
  int status;
  string name;
 }

 void main() {
  auto statSetter = new FieldSetter!(Sample, status);
  auto nameSetter = new FieldSetter!(Sample, name);
  auto sample = new Sample;
  int i = 20;
  statSetter.setValue(sample, i);
  statSetter.setValue(sample, 40);
  nameSetter.setValue(sample, Fooblr);
 }

 Thanks
 Thats brilliant! D rocks!
 I never though of using mixin for that purpose.

 There's almost NOTHING which is impossible with string mixins. With just
 recursive string mixins, coupled with .stringof and is(typeof()), you can
 get access to most of the compiler's semantic analysis, and its symbol
 table.
 Deep in the final semantic pass, just before code generation, when you have
 access to all the type information, you can generate new source code for the
 compiler to start again at the beginning with parsing.
 It's insanely powerful.

It's also insanely kludgy and ugly. Bleh.


How about macro == symbol for mixin statement? [was Re: Member functions C to D]

2009-10-07 Thread Steven Schveighoffer
On Wed, 07 Oct 2009 09:17:59 -0400, Jarrett Billingsley  
jarrett.billings...@gmail.com wrote:



It's also insanely kludgy and ugly. Bleh.


If all a macro did was translate a scoped normal symbol to a mixin (or  
other macro) statement, would this take care of the ugliness? (would also  
be an insanely simple solution)


i.e.

macro doit(x, y, z) mixin(x ~ y ~ z); // allow easy syntax for  
quoting parameters, since mixins are all about stringification.


doit(a, b, c) = mixin(abc);

Another example, logging:

class Logger
{
  ...
  macro logError(msg) mixin({if(this.level = ERROR)  
logMessage(this.level.Error, msg);});

}

usage:

log.logError(bad error occurred with object:  ~  
expensiveObjectStringification(obj));


No more lazy parameters, no more stupid delegates :)

-Steve


Get template and its instantiation parameters

2009-10-07 Thread Michal Minich
If one has a template instance, is it possible to get template name and parameter 
type that was used for instantiating, at compile time?


consider:

class List (T) {}

List!(int) lst;
Foo (lst);

I want to create such template Foo which prints:
List!(int)
List
int

Something simiar for Arrays can be created:
int[char] x;
Foo (x);

template Foo (X : T[U], T, U)
{
   void Foo (X arr)
   {
   writeln(typeof(arr).stringof);
   writeln(T.stringof);
   writeln(U.stringof);
   }
}

but similar template for template instances does not work:
template Foo (X : T!(U), T, U) // does not matches List!(int)

when is changed to something more specific, it starts working:
template Foo (X : List!(U), U) // matches List!(int)




Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]

2009-10-07 Thread Don

Steven Schveighoffer wrote:
On Wed, 07 Oct 2009 09:17:59 -0400, Jarrett Billingsley 
jarrett.billings...@gmail.com wrote:



It's also insanely kludgy and ugly. Bleh.


Ugly, yes. Kludgy, I don't think so. It's only a syntax issue. The basic 
concept of passing meta-code to the compiler in the form of raw text is 
simple:


mixin() if you want to insert something into the parse step.
 is(typeof()) if you want to catch it again after the syntax pass.
 stringof if you want to catch it again after the semantic pass.

And that's all. The syntax is ugly, but the semantics are beautifully 
elegant.


By contrast, something like Nemerle macros are a kludge. The idea of 
providing a 'hook' into the compiler is a horrible hack. It exposes all 
kinds of compiler internals. Yes, it has nicer syntax.


If all a macro did was translate a scoped normal symbol to a mixin (or 
other macro) statement, would this take care of the ugliness? (would 
also be an insanely simple solution)


I think that's where the majority of the ugliness comes from.


Re: Get template and its instantiation parameters

2009-10-07 Thread Jarrett Billingsley
On Wed, Oct 7, 2009 at 12:54 PM, BCS n...@anon.com wrote:
 Hello Michal,

 If one has a template instance, is it possible to get template name
 and parameter type that was used for instantiating, at compile time?

 consider:

 class List (T) {}

 List!(int) lst;
 Foo (lst);
 I want to create such template Foo which prints:
 List!(int)
 List
 int

 You could try parsing T.stringof at compiletime to extract the parts you
 need.

This is *exactly* the kind of bullshit that I hate about string
mixins. The thought process just ends up going oh, why bother having
any terse, elegant mechanisms to get at program information when you
can *parse arbitrary code at compile time*? And why do you need macros
when a string substitution will do? Is it powerful? Sure. But it's
lame, ugly, slow, easy to mess up, lacks hygiene, and is unidiomatic.
String mixins are basically just a text preprocessor with user-defined
functionality. Neat, but it can only get you so far before you're in
tarpit territory.


Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]

2009-10-07 Thread Jarrett Billingsley
On Wed, Oct 7, 2009 at 11:21 AM, Don nos...@nospam.com wrote:
 Steven Schveighoffer wrote:

 On Wed, 07 Oct 2009 09:17:59 -0400, Jarrett Billingsley
 jarrett.billings...@gmail.com wrote:

 It's also insanely kludgy and ugly. Bleh.

 Ugly, yes. Kludgy, I don't think so. It's only a syntax issue. The basic
 concept of passing meta-code to the compiler in the form of raw text is
 simple:

 mixin() if you want to insert something into the parse step.
  is(typeof()) if you want to catch it again after the syntax pass.
  stringof if you want to catch it again after the semantic pass.

 And that's all. The syntax is ugly, but the semantics are beautifully
 elegant.

It'd be nice if they actually worked. is(typeof()) fails for *any*
error, and it eats those errors too, so if your code fails to compile
for some reason other than the one you're testing for, welp, good luck
figuring that out. And don't even get me started on .stringof.

Also, see my post on the get template and its instantiation
parameters thread for my detailed opinion on them.

 By contrast, something like Nemerle macros are a kludge. The idea of
 providing a 'hook' into the compiler is a horrible hack. It exposes all
 kinds of compiler internals. Yes, it has nicer syntax.

I.. don't even know how to begin to respond to that.


Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]

2009-10-07 Thread Bill Baxter
 On Wed, Oct 7, 2009 at 11:21 AM, Don nos...@nospam.com wrote:

 By contrast, something like Nemerle macros are a kludge. The idea of
 providing a 'hook' into the compiler is a horrible hack. It exposes all
 kinds of compiler internals. Yes, it has nicer syntax.

Are you talking specifically about the ability to define new syntax?
Because it looks to me that one can use nemerle macros just fine
without defining new syntax.
I'm getting that from here: http://nemerle.org/Macros_tutorial

Here's just a simple macro that adds no new syntax from that page:

macro m () {
  Nemerle.IO.printf (compile-time\n);
  [ Nemerle.IO.printf (run-time\n) ];
}

module M {
  public Main () : void {
m ();
  }
}


That seems significantly more elegant to me than

string m() {
   pragma(msg, compile-time);
   return q{writefln(run-time);}
}
void main() {
   mixin(m());
}

So it looks to me like the mechanics of it are basically identical.
Just Nemerle's syntax is nicer.

If you want to condem Nemerle's ability to define new syntax, I think
that should be taken up as a separate matter.

--bb


Re: Get template and its instantiation parameters

2009-10-07 Thread Michal Minich
On Wed, 07 Oct 2009 13:15:46 -0400, Jarrett Billingsley wrote:

 On Wed, Oct 7, 2009 at 12:54 PM, BCS n...@anon.com wrote:
 Hello Michal,

 If one has a template instance, is it possible to get template name
 and parameter type that was used for instantiating, at compile time?

 consider:

 class List (T) {}

 List!(int) lst;
 Foo (lst);
 I want to create such template Foo which prints: List!(int)
 List
 int

 You could try parsing T.stringof at compiletime to extract the parts
 you need.
 
 This is *exactly* the kind of bullshit that I hate about string mixins.
 The thought process just ends up going oh, why bother having any terse,
 elegant mechanisms to get at program information when you can *parse
 arbitrary code at compile time*? And why do you need macros when a
 string substitution will do? Is it powerful? Sure. But it's lame, ugly,
 slow, easy to mess up, lacks hygiene, and is unidiomatic. String mixins
 are basically just a text preprocessor with user-defined functionality.
 Neat, but it can only get you so far before you're in tarpit territory.

Jarrett,

I agree with you except the lame and preprocessor part. But I 
wouldn't be so harsh on D. The prospect of parsing D code really does not 
appeal to me. Also the usage of advanced templates is not very intuitive. 
But please don't forget that features that are made possible by D 
templates and/or the .stringof + CTFE are not available in many 
languages. Languages that have such or better type level expressivity as 
D are few, mostly functional ones: Haskell, ML, OCaml, F# (I don't know 
of Scala). Also these features in D are more general, and even if kludgy, 
they are *available*.


The answer to my question is:

The problem was that parameter T needs to be alias because it should 
match List which is not complete type, until is applied to some 
argument (int); it is just template name. The result for T.stringof is 
surprising for me, but anyway, I get what I needed.

class List (T) {}

void main ()
{
List!(int) lst;
Foo (lst);
}


template Foo (C : T!(U), alias T, U)
{
void Foo (C container)
{
writeln(C.stringof); // List
writeln(T.stringof); // List(T)
writeln(U.stringof); // int
}
}

(tested on DMD 2.033)


Re: Get template and its instantiation parameters

2009-10-07 Thread Christopher Wright

BCS wrote:

Hello Michal,


If one has a template instance, is it possible to get template name
and parameter type that was used for instantiating, at compile time?

consider:

class List (T) {}

List!(int) lst;
Foo (lst);
I want to create such template Foo which prints:
List!(int)
List
int


You could try parsing T.stringof at compiletime to extract the parts you 
need.


No, you can't. You can try parsing demangle!(T.mangleof) at compiletime 
to extract the parts you need. stringof is a morass of inconsistency and 
partial information. Whenever a template gets within a mile of a type, 
all bets are off.


Re: Get template and its instantiation parameters

2009-10-07 Thread BCS

Hello Jarrett,


On Wed, Oct 7, 2009 at 12:54 PM, BCS n...@anon.com wrote:


You could try parsing T.stringof at compiletime to extract the parts
you need.


This is *exactly* the kind of bullshit that I hate about string
mixins.



The question was how to do somthing now. If the best solution isn't that 
good, it says a few things, but what it does /not/ say is that you shouldn't 
do the best solution.





std.socket again

2009-10-07 Thread Sam Hu
Greetings!

Is there anybody kindly write several pieces of code to demonstrate how to use 
socket in D2.Say ,just download the D main page and print the content in the 
console should be enough.

 I tried several days but still got lost.The sample accompany with DMD 2032/3 
does not work .

Thank you so much in advance.

Regards,
Sam


std.socket again

2009-10-07 Thread Sam Hu
Greetings!

Is there anybody kindly write several pieces of code to demonstrate how to use 
socket in D2.Say ,just download the D main page and print the content in the 
console should be enough.

 I tried several days but still got lost.The sample accompany with DMD 2032/3 
does not work .

Thank you so much in advance.

Regards,
Sam


[Issue 3366] Segfault(declaration.c) variadic template with unmatched constraint

2009-10-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=3366


Don clugd...@yahoo.com.au changed:

   What|Removed |Added

   Keywords||patch
 CC||clugd...@yahoo.com.au
Summary|Crash by variadic member|Segfault(declaration.c)
   |function templates  |variadic template with
   ||unmatched constraint


--- Comment #1 from Don clugd...@yahoo.com.au 2009-10-07 00:22:00 PDT ---
Reduced test case:

void f(T...)() if (T.length  20){}
void main(){
f!(int, int)();
}

If the tuple length isn't used in the constraint, there's no ICE, but you get
the same silly error message about T is already defined. It only happens if
the function has no parameters, and when there is no match.

It thinks T is already defined, because in the code which is patched below,
it's trying to pass an empty tuple for T. But it's already worked out what T
must be (in this case (int, int)). So it gets horribly confused.

Root cause: deduceFunctionTemplateMatch() missed this case.

PATCH:
template.c, deduceFunctionTemplateMatch(), line 885.

/* Check for match of function arguments with variadic template
 * parameter, such as:
 *
 * template Foo(T, A...) { void Foo(T t, A a); }
 * void main() { Foo(1,2,3); }
 */
if (tp)// if variadic
{
-if (nfparams == 0)// if no function parameters
+if (nfparams == 0  nfargs!=0)// if no function parameters
{
Tuple *t = new Tuple();
//printf(t = %p\n, t);
dedargs-data[parameters-dim - 1] = (void *)t;
declareParameter(paramscope, tp, t);
goto L2;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 3041] Array slices can be compared to their element type: bad codegen or ICE

2009-10-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=3041



--- Comment #2 from Walter Bright bugzi...@digitalmars.com 2009-10-07 
01:20:22 PDT ---
The error detection really needs to go in the front end, in
EqualExp::semantic(), etc. I'll fix.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 3371] New: regexp behavior in console and win32 are different

2009-10-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=3371

   Summary: regexp behavior in console and win32 are different
   Product: D
   Version: 2.032
  Platform: x86
OS/Version: Windows
Status: NEW
  Severity: normal
  Priority: P2
 Component: Phobos
AssignedTo: nob...@puremagic.com
ReportedBy: l...@yahoo.com


--- Comment #0 from bcosca l...@yahoo.com 2009-10-07 05:06:50 PDT ---
my win32 program has been driving me nuts until I realized that the following
code:

/* --- console code --- */
import std.regexp;
import std.stdio;

void main() {
auto r=search(abcdef,c);
writefln(r[0]);
}
/* --- end of console code --- */

outputs c on the console. but the following win32 equivalent:

/* --- windows code --- */
import core.runtime;
import std.regexp;
import std.c.windows.windows;

extern(Windows) void WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nCmdShow) {
void exceptionHandler(Throwable e) {
throw e;
}
try {
Runtime.initialize(exceptionHandler);
auto r=search(abcdef,c);
MessageBoxA(cast(HANDLE)0,cast(char*)r[0],Alert,0);
Runtime.terminate(exceptionHandler);
}
catch(Object o) {
MessageBoxA(cast(HANDLE)0,cast(LPSTR)o.toString(),Alert,0);
}
}
/* --- end of windows code --- */

results in cdef! also, the compiled win32 program - without the exception
handling code - causes windows to crash.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 3371] regexp behavior in console and win32 are different

2009-10-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=3371


Jarrett Billingsley jarrett.billings...@gmail.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||jarrett.billings...@gmail.c
   ||om
 Resolution||INVALID


--- Comment #1 from Jarrett Billingsley jarrett.billings...@gmail.com 
2009-10-07 06:16:54 PDT ---
Uh, no. Windows uses 0-terminated strings, D does not. All you're seeing when
you output the result of the search with the message box is Windows stupidly
reading until it hits a nul character (which, thankfully, D inserts at the end
of string literals, or else you'd probably be getting a segfault here). You
should be using toStringz to convert any D strings to C strings.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1140] ICE(cod1.c) casting last function parameter to 8 byte value

2009-10-07 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1140


Don clugd...@yahoo.com.au changed:

   What|Removed |Added

Summary|ICE(cod1.c) casting last|ICE(cod1.c) casting last
   |function parameter to   |function parameter to 8
   |struct. |byte value


--- Comment #4 from Don clugd...@yahoo.com.au 2009-10-07 06:31:19 PDT ---
Even simpler test case shows it's nothing to do with structs! It just happens
when casting the last parameter, **which is passed in EAX, not on the stack**,
to an 8-byte value -- either an 8-byte struct or a long/ulong.
Although this code is legal, it's surely a bug. It would be OK for the compiler
to generate an error message.

long foo(int y) {
return *cast(long*)(y);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---