View mode: basic / threaded / horizontal-split · Log in · Help
January 26, 2013
Re: Incorporating D
On Fri, Jan 25, 2013 at 11:32:19PM +0100, Szymon wrote:
> Ah, perfectly clear now. Thanks guys. At one point I though maybe it
> was about move semantics but it indeed about something much more
> fundamental. And indeed surprising coming from C++.
[...]

When moving to D, one thing to keep in mind is that you should not
expect C/C++ struct and D struct to behave the same way, because they do
not.

In D, a struct is a value type, and basically behaves like a glorified
int. This means assignment with = (shallow-)copies the struct, structs
are allocated on the stack by default (unless you explicitly use new),
etc.. Be aware that using struct ctors/dtors is fraught with peril; the
simplest cases do work, but there are some bugs with complicated dtors
and some unexpected behaviour with @disable ctors. If you need a
complicated dtor, chances are you want to be using a class anyway. Same
goes for postblit ctors (the analogue of copy ctors): there are some
bugs related to this, and IMO, if you need to do complicated stuff in a
postblit, you should just use a class.

In D, a class is a reference type, which means they are always passed by
reference, and assignment with = only copies the reference, NOT the
object. By default, they are allocated on the heap (unless you use
emplace), and generally, ctors and dtors work in a much more predictable
and stable way. (But be aware that dtors may not run when you expect,
because the GC may not collect the object immediately after it's out of
use.) Class objects are not deep-copied unless you provide a method to
do that yourself.

In summary, if you want something that behaves like an int, but just
happens to have a couple of extra fields, use a struct. If you want
complex behaviours like ctors, dtors, copy/cloning semantics,
polymorphism, etc., spare yourself the pain and just use a class. (It
*is* possible to pull some tricks along these lines with structs, but
like I said, there is a risk of running into some bugs in that area, so
it's best to steer clear until these issues have been fixed.)


T

-- 
"I suspect the best way to deal with procrastination is to put off the procrastination itself until later. I've been meaning to try this, but haven't gotten around to it yet. " -- swr
January 26, 2013
Re: Incorporating D
On Fri, Jan 25, 2013 at 02:53:31PM -0800, Walter Bright wrote:
[...]
> If you stick to bread and butter code, you shouldn't have problems.
> If you use advanced features out to the edge, you're more likely to
> run into issues.

And I have to add that so far, I haven't found any problems that are
showstoppers (in the sense that there's no way to work around it).
Almost all of the bugs I've found have workarounds that aren't too
painful. (They may look a bit ugly at times, but they work, and let you
get the job done.)

Even with advanced features, when you run into bugs it's almost always
possible to recast your code in a way that *doesn't* use that specific
combination of advanced features that exhibit the bug. You may not be
able to write idealistic, perfect code in that case, but things will
still work.


[...]
> >Is it true that D has GC problems?
> 
> All GC's have problems. GC isn't a "fire and forget" way to deal
> with memory management. However, the GC is reliable and works well
> if you use it with awareness of how it works.
[...]

I have to say that while the current GC certainly could do with some
significant improvements, *I've* certainly never run into any major
problems with it yet.

There have been reports of performance loss in some cases, but there are
ways to disable/re-enable the GC which you can use to minimize the
problem around critical pieces of code.

In any case, the GC *is* being worked on, and hopefully we'll see a much
better incarnation of it in the near future.

(Not to mention that having a GC makes it much easier to write certain
kinds of code. Complex string manipulations, for example, are an utter
pain in the neck in C/C++. The simplest operations require meticulous
care and copious tricky pointer arithmetics to prevent buffer overflows
and memory leaks. In D, you just write string operations with impunity
and they Just Work(tm). And the resulting code is much more readable.)


T

-- 
Your inconsistency is the only consistent thing about you! -- KD
January 26, 2013
Re: Incorporating D
> We better get this right and not hurry about this.

I will open a new, separate thread about this tomorrow. Seems to 
me more appropriate. Then we can discuss about this important but 
missing feature in detail.

> What languages have that feature, and what makes it important? 
> To me it seems rather niche and is easily worked around within 
> the language.
>
>
> Andrei

Sorry I was tired and had misunderstood the relation to D 
problems which keep you back from using it in production. I will 
write a few sentences about this tomorrow.
January 26, 2013
Re: Incorporating D
On Friday, 25 January 2013 at 21:33:15 UTC, q66 wrote:
>> D's GC does not have serious problems. The only issue is 
>> controversial status of GC.
>>
>
> D's GC has inherent issues with false positives, sometimes 
> freeing memory that you don't really want freed, causing 
> (sometimes hidden) bugs that are pretty much impossible to 
> debug.

That is very wrong. False positive are the exact opposite : 
memory that isn't freed.

And it statistically never occurs on 64 bits systems.
January 26, 2013
Re: Incorporating D
On Friday, 25 January 2013 at 23:02:10 UTC, Walter Bright wrote:
> On 1/25/2013 1:33 PM, q66 wrote:
>> D's GC has inherent issues with false positives, sometimes 
>> freeing memory that
>> you don't really want freed, causing (sometimes hidden) bugs 
>> that are pretty
>> much impossible to debug.
>
> There are zero reported examples of this happening.
>

I had an issue like like in D < 2.061 .
January 26, 2013
Re: Incorporating D
Walter Bright wrote:

> Yes, and it is in use for production code.

What do you mean by this statement?

Do those companies publish their reliance on D?

How many people make there living on "production code" written in 
D with a time perspective of at least five years? 

-manfred
January 26, 2013
Re: Incorporating D
26-Jan-2013 04:42, H. S. Teoh пишет:
> On Fri, Jan 25, 2013 at 11:32:19PM +0100, Szymon wrote:
>> Ah, perfectly clear now. Thanks guys. At one point I though maybe it
>> was about move semantics but it indeed about something much more
>> fundamental. And indeed surprising coming from C++.
> [...]
>
> When moving to D, one thing to keep in mind is that you should not
> expect C/C++ struct and D struct to behave the same way, because they do
> not.
>
> In D, a struct is a value type, and basically behaves like a glorified
> int. This means assignment with = (shallow-)copies the struct, structs
> are allocated on the stack by default (unless you explicitly use new),
> etc.. Be aware that using struct ctors/dtors is fraught with peril; the
> simplest cases do work, but there are some bugs with complicated dtors
> and some unexpected behaviour with @disable ctors. If you need a
> complicated dtor, chances are you want to be using a class anyway. Same
> goes for postblit ctors (the analogue of copy ctors): there are some
> bugs related to this, and IMO, if you need to do complicated stuff in a
> postblit, you should just use a class.

In general postblit/dtor are working but I wouldn't recommend using them 
in complex code (least you want to file a bug report) like with 
statements, or array-literals [ Struct(...), Struct(...), Struct(...)], 
and of course built-in associative arrays(!).

Another thing of importance is that pass-by-value is automated to move 
(simple bitwise-copy) where applicable as D structs can't have internal 
references. And you don't have to define move constructor or rely on 
sombody to define it.

>
> In D, a class is a reference type, which means they are always passed by
> reference, and assignment with = only copies the reference, NOT the
> object. By default, they are allocated on the heap (unless you use
> emplace), and generally, ctors and dtors work in a much more predictable
> and stable way. (But be aware that dtors may not run when you expect,
> because the GC may not collect the object immediately after it's out of
> use.) Class objects are not deep-copied unless you provide a method to
> do that yourself.
>
> In summary, if you want something that behaves like an int, but just
> happens to have a couple of extra fields, use a struct. If you want
> complex behaviours like ctors, dtors, copy/cloning semantics,
> polymorphism, etc., spare yourself the pain and just use a class. (It
> *is* possible to pull some tricks along these lines with structs, but
> like I said, there is a risk of running into some bugs in that area, so
> it's best to steer clear until these issues have been fixed.)
>
>
> T
>


-- 
Dmitry Olshansky
January 26, 2013
Re: Incorporating D
26-Jan-2013 03:48, Rob T пишет:
> On Friday, 25 January 2013 at 22:29:44 UTC, Adam D. Ruppe wrote:
>> On Friday, 25 January 2013 at 22:22:44 UTC, Szymon wrote:
>>> So structs in D are always passed by-value? That is unfortunate...
>>
>> It has both pointers and ref but they both only work with lvalues,
>> regardless of const:
>>
>> struct S {}
>>
>> void test(const ref S s) {}
>> void test2(const S* s) {}
>>
>> S getS() { return S(); }
>>
>> void main() {
>>         S s;
>>         test(s); // ok
>>         test2(&s); // ok
>>         test(getS()); // not ok (line 12)
>>         test2(&getS()); // not ok (line 13)
>> }
>>
>> test.d(12): Error: function test.test (ref const(S) s) is not callable
>> using argument types (S)
>> test.d(12): Error: getS() is not an lvalue
>> test.d(13): Error: getS() is not an lvalue
>
> It should be mentioned that there's a solution of sorts, but it is a
> pain to have to do and does not scale up when you have multiple ref
> arguments.
>
> void test(const ref S s)
> {
>     // implementation
>     ...
>     return;
> }
> void test(const S s)
> {
>      test( s ); // calls test(const ref S s)
>      return;
> }

void test(const S s){ return test(s); }

D is not Java and allows returning void functions directly ;)


-- 
Dmitry Olshansky
January 26, 2013
Re: Incorporating D
On Friday, 25 January 2013 at 23:24:54 UTC, Andrei Alexandrescu 
wrote:

> Thank you for asking. We have been strongly focused on quality 
> improvement since last year but judging from this thread we 
> need to work more on it (and the derived community sentiment).
>
> Andrei

And that is true, during 2012 and by now 1495 bug fixed and 
closed:

http://d.puremagic.com/issues/buglist.cgi?chfieldto=Now&query_format=advanced&chfield=bug_status&chfieldfrom=2012-01-01&bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&component=DMD&product=D

That is just so Awesome! Great thanks to everybody involved!

The bad news is there are still some TDPL bugs:

http://d.puremagic.com/issues/buglist.cgi?keywords=tdpl&query_format=advanced&keywords_type=allwords&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=DMD&product=D

These probably would require more attention because TDPL is the 
_only_ printed
source of the language.
Not so big amount although, so using D per TDPL looks pretty safe.

Oleg.
January 26, 2013
Re: Incorporating D
Am Fri, 25 Jan 2013 22:38:51 +0100
schrieb "Jonathan M Davis" <jmdavisProg@gmx.com>:

> On Friday, January 25, 2013 22:33:14 q66 wrote:
> > > D's GC does not have serious problems. The only issue is
> > > controversial status of GC.
> > 
> > D's GC has inherent issues with false positives, sometimes
> > freeing memory that you don't really want freed, causing
> > (sometimes hidden) bugs that are pretty much impossible to debug.
> 
> I've _never_ heard of it freeing something when it shouldn't.

I've seen that when porting GDC. Usually happens if the GC fails to
scan the stack or more often it misses some TLS ranges. Never saw that
with dmd though.

IIRC toStringz is also dangerous. You have to make sure that the C
library does not store the pointer or also store it manually so the GC
can find it. (This is not different from passing other C/D pointers, but
with toStringz it's easy to miss).
1 2 3 4 5 6 7 8 9
Top | Discussion index | About this forum | D home