March 04, 2006
"Kevin Bealer" <Kevin_member@pathlink.com> wrote in message news:dub5c4$2lo2$1@digitaldaemon.com...
> Constructors and destructors in C++ have become something much larger than
> memory cleanup.  They provide a syntactic tool that plays almost the same
> role
> as (and complements well with) assertions and contract programming.
>
> For instance, in C++ I can write a mutex class like this (I'll use D notation):
>
> class Mutex {
> ,  void Lock();
> ,  void Unlock();
> ,  bool is_Locked();
> };
>
> ,class MutexHolder {
> ,   this(Mutex x);
> ,
> ,   void Lock()   { assert(! am_locked); x.Lock();   am_locked = true; }
> ,   void Unlock() { assert(am_locked);   x.Unlock(); am_locked = false; }
> ,
> ,   ~this()
> ,   {
> ,       if (am_locked) {
> ,         assert(my_x.isLocked());
> ,         my_x.Unlock();
> ,       }
> ,   }
> ,}
>
> If you insert enough assert() tests, you can virtually guarantee that you
> either
> have perfect locking, or die (or hang) at the point of the first usage
> error.
>
> But the ability to check for correct state, or unlock things, in the
> destructor
> is CRUCIAL to this kind of testing.  I worked for a few years in C
> language file
> system code that did not have these guarantees.  We were constantly
> hunting down
> mysterious hangs.  Doing locking via object lifetime is an excellent way
> to
> enforce a kind of whole-system behavior -- that is what's powerful.
>
> But D can't do this kind of thing, AFAIK.  The RIIA works for a class, but
> I
> can't nest classes this way.  I can't tell class Foo that it owns Bar in
> "auto"
> mode.  I suspect that this would interact badly with "dup" if it was
> implemented.  I'm not sure what to do about that, unless there is an
> "opDup()"
> method (I like this idea, but its another been-discussed idea.).

Is it really necessary to tell the compiler you own a class member, rather than doing it by convention?


> If you write a class in C++ to wrap an integer for some reason, its only 4 bytes.

So it is with a D struct.

> You can replace a set of integers (this is usually done if you have at
> least a
> pair of ints) with "managed" ints or int-pairs, that guarantee some
> property.
> If the guarantee is done via debug-mode-only testing, the class really
> does turn
> into primitive types in release mode.

debug
{    struct myint
    {
        ... management code ...
    }
}
else
{
    alias int myint;
}

> Unfortunately, if I have a container of D structs, getting one out and
> calling a
> method, copies the value out - I can't set fields via "container[i].x =
> 5;" the
> last time I checked.

Can you post an example of this?

> I'm also thinking there is one restriction that may make this easier - if
> the
> auto class could only be owned by a function scope (as currently) OR
> another
> auto class - this would fix the unknown-delete-order issue for auto
> classes,
> because it would mean that every auto class knew it was not garbage (and
> inductively, its children arent garbage) at destruct time.

I'll have to think about that.


March 04, 2006
"Miles" <_______@_______.____> wrote in message news:dub8id$2rn3$1@digitaldaemon.com...
> I hardly post anything to the NG, most of the time I just read to see
> how D is maturing... but I would like to leave my opinion on this subject:

It's good to hear the opinions now and then of the lurkers, too, as they are just as important as the prolific posters.

> 1. const parameters and member functions
>
> Countless times this saved me. I just can't imagine references being passed in and out of functions without something explicitly saying that the function is expected or not to modify it.
>
> 2. implicit function template instantiation
>
> D templates are great, but I miss just this one feature. Perhaps because that I'm too used to C++...

They're coming.

> 3. array literals and initialization
>
> Don't know how D still don't support this, while we see things like regexes and scope guard comming in... (not that I didn't like those features, but I think that array literals should have came first).

C++ doesn't have array literals either <g>.

> 4. library
>
> This is a really weak point in D. STL is not that great, and I can't imagine someone programming in C++ without using some additional library like boost, CC++, Qt, MFC or (that Borland one that I just forgot the name)... But Phobos is simply out-of-question, it was created without project (I'm not a Software Engeneering fan, but at least I understand the importance to design and document before coding).

I don't find the STL compelling, either, and that's the only library thing standard C++ has over libc. Furthermore, large chunks of STL are simply irrelevant in D because D has core arrays, strings, and associative arrays.

> Also, the standard library should rely on the operating system, not on libc.

D is meant to be compatible with the C ABI, and that means supporting libc. Beyond that, it doesn't make a whole lot of sense to, for example, duplicate printf's ability to format floating point numbers. That code is complicated but well tested, why not take advantage of it? The libc stuff that isn't good is ignored.

> Now a bit off-topic, I'm also one of the guys that would like to see true, pure booleans in the language. I don't know why D should inherit such stupid behavior from C/C++, and the excuse that "D should be a sucessor to C" does not get at all... I believe that, before being a sucessor to C, D is a completely *new* language, no one will code in D with just C knowledge. So, if we are going to make things again, lets make them right.
>
> Best regards,
> Miles.


March 04, 2006
"Walter Bright" <newshound@digitalmars.com> wrote in message news:dub64a$2n07$1@digitaldaemon.com...
>
> "Andrew Fedoniouk" <news@terrainformatica.com> wrote in message news:dub0rk$2eje$1@digitaldaemon.com...
>> There is no way currently in D to implement "guarded variable":
>>
>> something s = ....;
>>
>> I cannot write code which will allow to catch
>> assignment to the variable (concrete memory region if you wish).
>> Just nothing for that in D at all - variables are naked.
>
> There are assign-at-compile-time and assign-once variables. What major niche does a guarded variable serve?

I am not exactly sure what this means: assign-at-compile-time, assign-once. Could you provide some examples?

I mean something like

struct cow_string {
   ref_counted_buffer data;
   void opAssign(cow_string s)
   {
       release(data);
       data = s.data;
       addref(data);
   }
}

GC as a memory managment is only one from others
possible management technics. refcounting has it own
pluses (as minuses).

To be able to combine both is just good thing -
key to effective technically correct solutions.

C++ gives ref counting and stack allocations (with ctors/dtors),
D gives only GC and stack allocations are not currently implemented there.

Ideal system should have all three. In this case requirement to effectiveness of GC could be lowered.

>
>>> I don't really understand this, as many languages have serious libraries without const - such as Java, Python, C#, etc.
>> 1) All these have builtin immutability. For example strings there
>> are immutable objects. D has no strings so it must have
>> some features in the language allowing to implement such
>> objects as a library.
>
> You can do so by only allowing private functions access to the underlying data. There is no notion of "const-correctness" or const as a type modifier in any of those languages.

True. This is why they are so uneffective.
String s = somestring.substring(1,4);
will allocate new String object.

You can implement the same approach in D of course
but you will give up ranges ( s[2..$] ) in almost all cases.
To return substring from immutable string you will
always allocate new object. So what is a big reason in D then?
Go for C# - it has faster GC so this joy-of-GC will not be so critical.

>
>
>> If you can do something in C/C++ you must
>> be able to do it in D. This is it.
>>
>> Postulate: D must include all features C++ has now.
>
> Are you suggesting D must have a preprocessor, too?

Don't understand this. Strictly speaking preprocessor
is not a part of C++.  This way D has also preprocessor - build.exe

>
>
>>> Try doing nested functions elegantly in C++ <g>.
>> Agree, they are useful. But if used with care.
>> As soon as you can get address of such inner function
>> then you are in trouble - result of later call of such function
>> is non-deterministic.
>
> True, one can get into trouble doing that wrong, but it isn't conceptually any different from the following C++ code:
>
>    int *p;
>    void foo()
>    {    int i;
>        p = &i;
>    }
>
>    void test()
>    {
>        ... = *p;
>    }
>
> So I would not argue that it is a defect *in comparison to C++*.

I am not speaking about defects or something like this here.
I just want to mention that D is a low level language and cannot
be compared with Java or the like.
D - fast but flammable.
Java - fireproof but slow.

Completely different roles and use cases.

>
>
>> D inner classes for example - strange halfly implemented Java feature.
>
> How so?

This is again about problems

And last time I've checked: I couldn't reference explicitly members of outer class like in java:

Outer.this.member = ...;

and there is no restriction on final's in outer function (Java is not
allocating
function frames, D does the same but not safe)


>
>> Scope guards are generally good
>> but without clear and strict definition of execution model - almost
>> useless - syntactic noise.
>
> I strongly disagree there. I thought I had answered your questions about that in the scope guard thread.

Key-point is "without clear and strict definition of execution model".

1) Again, what will happen if on_scope_success will throw?

If it is not safe in principle and there is complex handling required then you will end up with following:

on_scope_success try { ... } catch(object er) {...}

2) As I said before, implementation of on_scope_success seems like artificial  to D. In syntax and in implementation.

IMO, it makes real sense to provide facilities to
do things like on_scope_*** by others.

D as a language shall just provide generic mechanisms to do this: There are mixins already. So why not to extend them?

mixin can mix code in at point of definition. Add another
optional "parameter" to denote where to mix it and
allow anonymous mixins.

mixin atexit { .... }
mixin atfailure { .... }

But I would think more in this direction.


>
>> "auto zoo" there too.  Over-qualified 'static' All that private/protected
>> stuff
>> is just not finished yet - I was fighting with it in Harmonia - never
>> win.
>
> The private/protected stuff works like it does in C++.

Negative. D has concept of packages and there are problems there.

As far as I recall classes sitting in inner folders of some package have
very strange rules of accessibility to package objects. Classes and their
members
in particular.

>
>> OT: I was proposing readonly ranges and pointers as a simple alternative
>> / palliative
>> of problem #1. At least they allow to have lightweight and fast strings
>> as in Java/C#/Python.
>
> Java/C#/Python do not have lightweight and fast strings. There are some layers of complexity there that are hidden, but are there.

Sorry  not "fast as" but "faster than".

Andrew.



March 04, 2006
Here is the real life example:

This is C++ wrapper of  DOM element
from my HTMLayout SDK:

It wraps HELEMENT which is in fact reference counted handler of HTML DOM object.

namespace dom
{
    class element
    {
    protected:
      HELEMENT he;

      void use(HELEMENT h) { he = (HTMLayout_UseElement(h) == HLDOM_OK)? h:
0; }
      void unuse() { if(he) HTMLayout_UnuseElement(he); he = 0; }
      void set(HELEMENT h) { unuse(); use(h); }

    public:

      element(): he(0) { }
      element(HELEMENT h)    { use(h); }
      element(const element& e) { use(e.he); }
      operator HELEMENT() const { return he; }
      ~element()                { unuse(); }

      element& operator = (HELEMENT h) { set(h); return *this; }
      element& operator = (const element& e) { set(e.he); return *this; }

     ....
  }
}

Usage of this in C++ (code of DOM element event handler, aka "behavior"):

virtual BOOL on_mouse(HELEMENT he, HELEMENT target,
     UINT event_type, POINT pt, UINT mouseButtons, UINT keyboardStates )
    {
        dom::element el = he;
            // 'use' handler - add_ref it to prevent from deletion
        if(!el.is_valid())
             return false;

       dom::element root = el.root(); // get root element (<html>)
       dom::element editbox = root.find_first("input[type='text']");
           // get first edit box using CSS selector
       editbox.text("Hello world!"); // set text to it
       .....
    }

As you may see it is mission critical here to have ctor/dtors/assignment in
structs.
It is simply not feasible (realisticly) to call manually each time use/unuse
methods for all objects
in the function. Dead corner.

I really don't know how to design lightweight wrapper for HTMLayout for D. <g>

Any real advices?

Andrew.



March 04, 2006
Walter Bright wrote:
> "Miles" <_______@_______.____> wrote in message news:dub8id$2rn3$1@digitaldaemon.com...
>> I hardly post anything to the NG, most of the time I just read to see
>> how D is maturing... but I would like to leave my opinion on this subject:
> 
> It's good to hear the opinions now and then of the lurkers, too, as they are just as important as the prolific posters.

In that case here is another lurker opinion.

>> 1. const parameters and member functions
>>
>> Countless times this saved me. I just can't imagine references being
>> passed in and out of functions without something explicitly saying that
>> the function is expected or not to modify it.

You did not answer the above statement and i have seen this repeated all over this thread along with destructors in structs. I will not repeat all the arguments but to me this is important issues.
If i should rank the most showstoping things in D (from my perspective) it would be
1. bugs
2. as far as I know no way of inporting somthing in a parent directory (as C++ #include "../myheader.hpp")
3. read only sematics that work as a strong reminder that one is not suposed to modify somthing (but can bee subverted by a cast)
4. overlodable assignment and copy constructors.
5. library and other minor issues

>> 4. library
>> ...
> I don't find the STL compelling, either, and that's the only library thing standard C++ has over libc. Furthermore, large chunks of STL are simply irrelevant in D because D has core arrays, strings, and associative arrays.

I agree on this one. So wath is your plan for the D standard library?
March 04, 2006
In article <dubckj$1e4$1@digitaldaemon.com>, Walter Bright says...
>
>
>"Kevin Bealer" <Kevin_member@pathlink.com> wrote in message news:dub5c4$2lo2$1@digitaldaemon.com...
>> Constructors and destructors in C++ have become something much larger than
>> memory cleanup.  They provide a syntactic tool that plays almost the same
>> role
>> as (and complements well with) assertions and contract programming.
>>
>> For instance, in C++ I can write a mutex class like this (I'll use D notation):
>>
>> class Mutex {
>> ,  void Lock();
>> ,  void Unlock();
>> ,  bool is_Locked();
>> };
>>
>> ,class MutexHolder {
>> ,   this(Mutex x);
>> ,
>> ,   void Lock()   { assert(! am_locked); x.Lock();   am_locked = true; }
>> ,   void Unlock() { assert(am_locked);   x.Unlock(); am_locked = false; }
>> ,
>> ,   ~this()
>> ,   {
>> ,       if (am_locked) {
>> ,         assert(my_x.isLocked());
>> ,         my_x.Unlock();
>> ,       }
>> ,   }
>> ,}
>>
>> If you insert enough assert() tests, you can virtually guarantee that you
>> either
>> have perfect locking, or die (or hang) at the point of the first usage
>> error.
>>
>> But the ability to check for correct state, or unlock things, in the
>> destructor
>> is CRUCIAL to this kind of testing.  I worked for a few years in C
>> language file
>> system code that did not have these guarantees.  We were constantly
>> hunting down
>> mysterious hangs.  Doing locking via object lifetime is an excellent way
>> to
>> enforce a kind of whole-system behavior -- that is what's powerful.
>>
>> But D can't do this kind of thing, AFAIK.  The RIIA works for a class, but
>> I
>> can't nest classes this way.  I can't tell class Foo that it owns Bar in
>> "auto"
>> mode.  I suspect that this would interact badly with "dup" if it was
>> implemented.  I'm not sure what to do about that, unless there is an
>> "opDup()"
>> method (I like this idea, but its another been-discussed idea.).
>
>Is it really necessary to tell the compiler you own a class member, rather than doing it by convention?

Maybe not necessary... particularly with on_scope_exit() etc.  It's so useful in C++ relative to C.  That said, it maybe partly just due to my expectations.

I think it boils down to this - in C++ the lifetime of objects can be influenced by other objects, and as part of algorithms.  And algorithms and code can be influenced by the lifetime of objects.  In D the lifetime of objects is influenced by code, but not the other way around.

Maybe this is just the cost of GC.  It seems like both methods could coexist, but if enough features are added to D it will weigh as much as C++.  I'll have to think about whether there are other cases that auto/on_scope can't do.

>> If you write a class in C++ to wrap an integer for some reason, its only 4 bytes.
>
>So it is with a D struct.
>
>> You can replace a set of integers (this is usually done if you have at
>> least a
>> pair of ints) with "managed" ints or int-pairs, that guarantee some
>> property.
>> If the guarantee is done via debug-mode-only testing, the class really
>> does turn
>> into primitive types in release mode.
>
>debug
>{    struct myint
>    {
>        ... management code ...
>    }
>}
>else
>{
>    alias int myint;
>}

I guess what I'm saying is that in C++ you have incremental power over the functionality.  If you want a virtual table but no operators, you can have it. Operators but no virtual table, okay.  Each feature is turned on seperately.  In D there is struct, which has some stuff, and class, which has everything and a very different personality.

This is starting to sound like a complaint, but actually I like D's way.  All that syntax is why C++ is so treacherous for anyone who doesn't have a law degree in it.  The first ten times you write operator=(), you need to look at the book.  But C++'s a-la carte is powerful, if you want to spend time crafting the classes.  It's a tradeoff.  D makes a lot of common sense tradeoffs.  In C++ you can build uncopyable classes, inherit from classes that have no code (i.e. traits programming) etc.  D tosses a lot of semi-obscure flexibility and lets some of it in through other doors.  Again, good decision, but there are small ramifications here and there.

I'll just force myself to stop typing now. ;)

>> Unfortunately, if I have a container of D structs, getting one out and
>> calling a
>> method, copies the value out - I can't set fields via "container[i].x =
>> 5;" the
>> last time I checked.
>
>Can you post an example of this?

Yes.  As I mentioned elsewhere, "foo * opIndex(int i)" fixes this.

struct foo {
|    int x = 0;
|    int y = 0;
|
|    int set_x(int q)
|    {
|        x = q;
|        return x;
|    }
};

struct holds_foo {
|    foo[] foos;
|
|    // this one fails.
|    foo opIndex(int i)
|    {
|        return foos[i];
|    }
|
|    /+ This one works here.
|    foo * opIndex(int i)
|    {
|        return & foos[i];
|    }+/
};

int floo()
{
|    holds_foo hoho;
|    hoho.foos.length = 10;
|
|    hoho[0].set_x(11);
|
|    printf("ho ho %d.\n", hoho[0].x);
|
|    return 0;
}

int main(char[][] args)
{
|    printf("okay then\n");
|
|    floo();
|
|    printf("okay now\n");
|
|    return 0;
}


>> I'm also thinking there is one restriction that may make this easier - if
>> the
>> auto class could only be owned by a function scope (as currently) OR
>> another
>> auto class - this would fix the unknown-delete-order issue for auto
>> classes,
>> because it would mean that every auto class knew it was not garbage (and
>> inductively, its children arent garbage) at destruct time.
>
>I'll have to think about that.
>
>


March 04, 2006
Kyle Furlong wrote:
> 
> Walter, how technologically complex is implicit template instantiation? I think the consensus
>  here is that that is the next feature that everyone wants. I guess my question is, why did you go through the regex debacle, instead of working on ITI.

I doubt it's the next feature /everyone/ wants, and I pretty sure it's not the next *task done* that everyone wants.


-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
March 04, 2006
Bruno Medeiros wrote:

> Kyle Furlong wrote:
>> 
>> Walter, how technologically complex is implicit template instantiation?
>> I think the consensus
>>  here is that that is the next feature that everyone wants. I guess my
>> question is, why did you go through the regex debacle, instead of
>> working on ITI.
> 
> I doubt it's the next feature /everyone/ wants, and I pretty sure it's not the next *task done* that everyone wants.

ITI is important because its absence blocks library development.

/Oskar
March 04, 2006
On Fri, 03 Mar 2006 13:03:34 -0800, Walter Bright wrote:

> I started a new thread for this:
> 
> "Mike Capp" <mike.capp@gmail.com> wrote in message news:dua67i$12cr$1@digitaldaemon.com...
>> 7. D has all (well, most of) the power of C++
> 
> I see this often and am a bit perplexed by it. What power do you feel is missing?
> 
> And what about the missing power in C++ - inline assembler, nested functions, contract programming, unit testing, automatic documentation generation, static if, delegates, dynamic closures, inner classes, modules, garbage collection, scope guard?
> 
> What does D have to do to have more power than C++?

Well I think that D already have more programing power than C++.

What D need is more street respect ;-)

I think that most programmers won't switch to D before it have a magnitude more power than C++.

To get there I think you should just look at the top
of the wish list at
http://all-technology.com/eigenpolls/dwishlist/story.php

it says

84  array initialization/literals
  This feature witch everybody miss in C++ and D.
56  Reflection API
  Many are missing this from Java
53  vectorization
  This will give D more calculating power than C++ and FORTRAN
50  Stack tracing
  There is a unofficial patch make it official
46  Faster GC
  The judgement by the people ;-)
43  Short syntax for new
  The typing length to create a new object is one of the very ignoring
  things when coming from C++.





March 04, 2006
Johan Granberg wrote:
> 
> You did not answer the above statement and i have seen this repeated all
> over this thread along with destructors in structs. I will not repeat
> all the arguments but to me this is important issues.
> If i should rank the most showstoping things in D (from my perspective)
> it would be
> 1. bugs
> 2. as far as I know no way of inporting somthing in a parent directory
> (as C++ #include "../myheader.hpp")

If you have a package hierarchy:

foo/
foo/bar/

and the files
foo/a.d
foo/bar/b.d

you can in your foo/bar/b.d do

import foo.a;

For good measures, name your modules accordingly with the module statemnt:

module foo.a;
----------
module foo.bar.b;
-------------

> 3. read only sematics that work as a strong reminder that one is not suposed to modify somthing (but can bee subverted by a cast)

Walter has answered on this very many times earlier, and he thinks const ain't the correct solution. Whether he'll find some other is still an open question.

> 4. overlodable assignment and copy constructors.

Also discussed very many times in the past, Walter's opinion is that they're bad for you ;)

> 5. library and other minor issues

Library is IMHO a community issue, nothing to do with the language, which was the question here.

> 
>>> 4. library
>>> ...
>> I don't find the STL compelling, either, and that's the only library thing standard C++ has over libc. Furthermore, large chunks of STL are simply irrelevant in D because D has core arrays, strings, and associative arrays.
> 
> I agree on this one. So wath is your plan for the D standard library?

I do agree that phobos is not the most compelling std library out there, which is why I encourage helping out with Ares.