July 30, 2004
"teqDruid" <me@teqdruid.com> wrote in message news:pan.2004.07.29.15.13.34.724295@teqdruid.com...
> I've read over your rant.  I'll not pretend to understand all of it, and I don't have any suggestions for your specific problems, except to that the Java route is not the way to go. I'm a Java guy, and I hate the Java collections API.
>
> Whenever I work on an open-source project, I put my code in a publicly accessable repository (a subversion repository, specifically) and I generally commit my code to it after each new change (even small changes, like a since bug fix) and generally before I stop for the day.  This way, I can get input from others, not that there are many (hell, let's face it: any) followers of my projects.  (Plus, the code gets backed up, but that's OT.) It's kind of a "release early, release often" approach (btw, if you haven't read ESR's "The Cathedral and the Bazaar", it's a good read.) I think your decision to release what you've got in a day or two is a good one. It's always good to have more people reading the code. The more perspectives one can get input from, the more successful a project will be, in my opinion.  I would even encourage you to put the project on dsource, and commit to the repository often.  I know I'd definately be more help giving advice (or even patches) if I could see the entire source.

The problem I've had is that the things that have held me up are not things that anyone other than Walter could help me with, since they've been compiler bugs and (missing) language features. Were I to have posted it, people would've seen nothing more than non-compilable, or crashing, code

The actual containment aspects of the library were implemented in March, and I've been fighting the compiler/language on the "advanced" issues ever since. I certainly see now that I should have released those parts, as I plan to this w/e, some time ago, but all along I've expected that the compiler/language enhancements were days away, rather than the months it's taken. This is not a gripe at Walter, more my having been too optimistic.

> On a very positive note, from what I understood of your post, it appears to me that should the language/compiler problems get worked out, DTL will be a very powerful, robust tool.  I am most impressed.

I am very confident that will be the case.

> As always, I salute you for your effort, and intellect.

Well, I'll accept the former. Not sure I deserve the latter. <G>

> John
>
> I hope to see Walter reply on this one.  I will be throughly disappointed should he not.
>
> On Thu, 29 Jul 2004 19:04:11 +1000, Matthew wrote:
>
> > I'm almost at the end of my tether here. There are so many problems with the language/compiler, that I'm wondering
> > seriously whether it's going to be possible to have a decent generic template library.
> > ...
> > If all this sounds like I'm down on D, and I've spent several weeks -
> > actually it's several months, but who's counting? - working against all
> > these issues and more, then you'd be about spot on. I can't remember
> > being this technically frustrated in the last 10 years, and I'm
> > generally known as a practical pragmatist! :-(
>


July 30, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:ceb8vu$1ibm$1@digitaldaemon.com...
> In article <ceaeid$18ir$1@digitaldaemon.com>, Matthew says...
> >
> >4. Iterator based approach. There are two reasons why STL-iterators are not possible in D: (i) there is no implicit
> >instantiation, and (ii) there is no operator *().
>
> In my more evil moments I've considered requesting an overloaded dot operator for much the same reason operator-> can be overloaded in C++.  I find it unfortunate that smart pointers can't really be implemented in D either, even though GC makes them far less necessary.

He he.

Actually, I like the fact that smart pointers are not really possible in D. I pretty much hate smart pointers in C++. (There was going to be a chapter in "Imperfect C++" on smart pointers, but I was told by the publisher to "Cut! Cut! Cut!", so it's one of the topics that got shelved. I do discuss some of the more heinous abuses, such as overloading operator &. Anyway, Maybe I'll discuss the issue in my next C++ book, although that's not going to be done until next year.)

Anyway, to the point: since pointers are second-class citizens in D, I really can't see the point of smart-pointers at all, and I think it's actually a net boon that we won't have them.

> >2. Templates in D are instantiated en masse. What "en masse" actually means is beyond me, since I am yet to work out
the
> >true rules regarding instantation. But what I can say is that having a template such as the following is totally f**cked:
> >
> >    template TransformedRange(R, F, T) { class TransformedRange
> >     : public NotionalRange!(T)
> >    {
> >      . . .
> >        this(R r, F f)
> >        {
> >            m_r = r.dup;
> >            m_f = f;
> >        }
> >        this(R r)
> >        {
> >            m_r = r.dup;
> >            m_f = new filter_type();
> >        }
> >
> >Without worrying too much about the details of what a TransformedRange does, the problem is pretty obvious. If F does not have a default constructor, one cannot instantiate TransformedRange even in the case where the single parameter
ctor
> >*is never called*!
>
> Your example is confusing.  I don't see "new F()" anywhere.  Why the need for a
> default constructor?

My bad. filter_type is an alias of F, which I elided for clarity (!), but left one of them in. It should be

> >        this(R r)
> >        {
> >            m_r = r.dup;
> >            m_f = new F();
> >        }

> But this raises an interesting point.  One useful but little mentioned feature of C++ is that primitive types support default constructor semantics just like user defined classes do.  For generic programming it might be nice to have the same thing:

It certainly would. I assumed they did. Is that not the case in D?

> MyClass c = new MyClass();
> int i = new int(); // equivalent to "int i;"
>
> This makes the difference between pointers and nonpointers a tad confusing but it would make life much easier in some cases.

Ah, no. It will create one on the heap. Nasty!

> >3. There's no implicit instantiation. This has *massive* consequences, including:
> ..
> >
> >- In order to support the parameterisable interface (e.g. IContainer!(int)) described above, there needs to be a
common
> >way to manipulate built-in types, objects and structs. For some things, one can use traits, for others, overloaded functions. Alas, there seems to be no way to discriminate structs via overloaded functions. Hence, currently the DTL containers do not support polymorphic interfaces when storing structs.
>
> See my comment above.  This is pretty important.  We should be able to use the same semantics for all types in D and be able to distinguish between them.

Agreed. I'm sure we can sort this out in the long run. I suspect that as soon as Walter looks at the issue he'll point out some bit of template arcana that I should have been applying.

> TypeInfo is a good start, though someone mentioned that structs and pointers have the same base TypeInfo class?

I know virtually nothing about TypeInfo. I guess I should correct that. :)

> >4. D's import stuff just blows my mind! As a related issue to the boxing utility class described above, I'm running
into
> >conflicts between the toString() functions in std.string and my box and boxutil modules.
>
> I ran into this problem when trying to import std.ctype and std.c.string into the same module.  I ended up just adding extern declarations for the C functions I wanted, but it's an outstanding issue.  IMO an import should import everything it can and leave conflicting symbols out.  Then they could still be referenced via std.string.strcmp or whatever.  Perhaps this is a good instance where a compiler warning would be useful?
>
> I've tried all kinds of use of
> >private imports, to no avail. I concede that this might be my fault, and I might have just failed to grok D's import rules, but as it currently looks to me, it looks bad and stupid.
>
> I haven't found any way around this either, but I think this may be more a bug with the import functionality than any language deficiency.  It's something I haven't taken the time to experiment with sufficiently.
>
> >Rather than having things boiled down, I think the compiler should be amended to provide *copious" debugging information, so we can email a dump of that to Walter, and which will be useful to him. I don't know what that information should be, but I know that it's simply not practical for me, or anyone else, to "boil down" these precipitating bugs when they only manifest in highly complex code.
>
> That's a handy idea, provided doing so doesn't take up weeks of Walter's time to add.
>
> >Anyway, that's just the compiler, and my main problem is with the language. I'm coming to the conclusion that D
either
> >will never be suitable for generic programming, or such suitability is years away. Given that, my aims for DTL are starting to seem naive at best, unattainable at worst.
>
> I think some language issues may just need to be refined.  Implicit instantiation is a big one for me, though I know that it is not a simple feature to add.  Ideally, I would like to do everything GP-wise in D that I can in C++. Perhaps a set of examples of what works and what doesn't followed by a discussion of language features D may be lacking?  In some respects I've found D more capable (alias template parameters) and in others, less.

Same here.

> > We can't have algorithms, remember, because we've not got implicit instantiation!
>
> Well, we can in some cases because we've got typeof, it just means more typing. But I'm sure there are cases where types are determined in odd ways in C++ that a wrapper template in D couldn't work around.

I think so.

> >So please, someone enlighten me (since I am quite prepared to believe I've missed something simple and obvious here): how can we do generic programming in D?
>
> Let's try and work it out.  I'll admit I've been focusing on other things until now.  Another day and I'll be finished with unFormat and I'll be able to play with a new project.  Perhaps trying to implement <algorithm> and <functional> would be a good place to start.  At the very least it would help to determine just what D can and can't do so far as templates are concerned.
>
> The iterator thing is a tough one though, because so much depends on that.  Is there truly no way to generate them?  I had played with creating a list type and thought I'd got the basics of one working, though I didn't experiment much with primitves vs. structs vs. classes.

We need some kind of implicit instantiation, however limited, in order to get true generic programming with iterators. Without it, we're going to have to have iterator interfaces, and be accessing elements polymorphically, which is not generic programming IME.




July 30, 2004
You talking about the 4786 issue, or something else?


"Sean Kelly" <sean@f4.ca> wrote in message news:ceci6c$243h$2@digitaldaemon.com...
> Matthew wrote:
> >
> > Well, to be equally pedantic, I'm not too troubled about pointers, but in essence you're correct.
>
> Just wanted a simple example.  The fact that the MSVC++ debugger chokes on debug symbols longer than 256 chars (and does this quite regularly) shows just how long template names can get ;)
>
>
> Sean


July 30, 2004
"Nick" <Nick_member@pathlink.com> wrote in message news:cec8k4$209b$1@digitaldaemon.com...
> In article <cebp7v$1pt7$2@digitaldaemon.com>, Matthew says...
>
> >[Actually, since all iterators must be classes, I've prescribed that they all have a standard set of member types, so it's possible to deduce the value type, as in:
> >
> >    int j = accumulate!(List!(int).iterator)(l.begin ...)
> >]
>
> Actually, you could do it this way even with pointers:
>
> # template accumulate(T: T*) { /* pointer iterators go here */ }
> # template accumulate(T: IteratorBase) { /* class iterators here */ }
>
> but it would mean you'd have to implement everything twice, which isn't exactly optimal :)
>
> >Given that the (currently) only useful mode for iterators is where the type
> > is explicit, it's my opinion (and that of others, I think) that there's no benefit over foreach, hence the focus on foreach for the container enumeration,
>
> I hope this doesn't mean you want to drop algorithms from DTL altogether? I think replacing sort() with a foreach will be a tad difficult.

I think we will end up with some form of iterator-based algorithm support, but I am with Walter in thinking that the "D" way will not revolve around iterators. Rather it will be (possibly transformed and filtered) foreach-able entities.

Notwithstanding that, it's my intent all along that DTL will also support Java-style enumeration and STL-style enumeration. I don't see why anyone should be forced to go one way, when we can support them all (without efficiency costs of features not being used, of course).





July 30, 2004
"Norbert Nemec" <Norbert.Nemec@gmx.de> wrote in message news:cecmf7$26e2$1@digitaldaemon.com...
> Walter wrote:
>
> >
> > "Matthew" <admin.hat@stlsoft.dot.org> wrote in message news:ceaeid$18ir$1@digitaldaemon.com...
> >> I'm almost at the end of my tether here. There are so many problems with
> > the language/compiler, that I'm wondering
> >> seriously whether it's going to be possible to have a decent generic
> > template library.
> >
> > I think that's to be expected with a new generic language design. After all, the creator of STL (Stepanov?) went through multiple design iterations with Stroustrup. None of us are smart enough to get it all right the first, second, or even third time. You do have a tendency to push the envelope past its limits (I see that in your C++ code!), and that's good for finding what those limits and weaknesses are.
> >
> > Generic programming in D is also going to be in a different style than in C++, and use different techniques. We have to carefully think about whether the problems are bugs in the compiler, bugs in the language design, or bugs in our thinking - perhaps we haven't discovered the right D way to do generic programming.
>
> Now, this sounds like D has become an experimental language after all. If there is no grand concept yet of how generic programming should be done, we are just going down the same road that C++ went: templates were introduced and lateron, when people had found ways to really exploit them, they found their limitations, but it was too late to change.

Aren't we going down the rod in the opposite direction? We know what we want, but we don't have the (template) tools to get it?

> Now, for D, if it is left to the future to re-discover generic programming from ground up, we are very likely to find out that the current concept of templates is sub-optimal as well. Are we really ready for 1.0 before we know where we want to go in that important area?
>
> I think it is rather dangerous to separate the development of the language and the standard library so much. The language should certainly not be called 1.0 before we have a clear concept of how the DTL should be designed. A 1.0 language without an 1.0 library isn't worth much anyway.

I agree with these two paras.


July 30, 2004
Regan Heath wrote:

> I think in addition to simple properties like:
>    template foo(T : struct)
> 
> A whole new thing should be used to specify several, like an interface but not, i.e.
> 
> requirements Bob {
>    interface Interface1,..
>    typeof ParentClass,..
>    type unsigned,..
> }

You have my vote, for the feature and for the syntax!
July 30, 2004
Matthew wrote:

> "Walter" <newshound@digitalmars.com> wrote in message news:cebm6f$1o79$1@digitaldaemon.com...
> 
>>"C. Sauls" <ibisbasenji@yahoo.com> wrote in message
>>news:cebjlk$1n2q$1@digitaldaemon.com...
>>
>>>Walter wrote:
>>>
>>>>I hadn't realized that structs and classes cannot be discriminated in
>>>>template specialization, you're right. How does the following look:
>>>>    template foo(T : struct)
>>>>and:
>>>>    template foo(T : class)
>>>>?
>>>
>>>Looks promising to me... how likely would the following be, as well?
>>>template foo(T : signed)
>>>template foo(T : unsigned)
>>>template foo(T : enum)
>>>
>>>I figure the more ways to narrow down the parameters, the better.  Maybe
>>>templates could be further revised to have complex filters, such as:
>>>template foo(T : struct || (signed && enum))
>>
>>It's a good idea. I've been thinking something along those lines for 2.0.
> 
> 
> Think 1.0!
> 
> 
> 
We can't all get want we want for the first try around. Believe me, as a novice programmer I wish I could but then again I'm not building something as complicated as a compiler that supports templates.

This is a feature I was hoping to see also but I guess that if it wasn't in the docs then it probably won't be supported anytime soon. I just hope 2.0 doesn't take as long as 1.0 because that would suck. Five years just to see better template controls, well, maybe it won't take that long if Walter keeps releasing builds.
July 30, 2004
Matthew wrote:

> 
> "Norbert Nemec" <Norbert.Nemec@gmx.de> wrote in message
>> Now, this sounds like D has become an experimental language after all. If there is no grand concept yet of how generic programming should be done, we are just going down the same road that C++ went: templates were introduced and lateron, when people had found ways to really exploit them, they found their limitations, but it was too late to change.
> 
> Aren't we going down the rod in the opposite direction? We know what we want, but we don't have the (template) tools to get it?

Looking at Walters messages it does not look like this. In many cases when he rejects feature requests concerning generic programming, it boils down to "you are thinking C++, start thinking D instead" - unfortunately, looking at the message I was replying to, it seems not at all clear what the D approach to generic programming is.


July 30, 2004
In article <cecvci$2as7$3@digitaldaemon.com>, Matthew says...
>
>
>"Sean Kelly" <sean@f4.ca> wrote in message news:ceb8vu$1ibm$1@digitaldaemon.com...
>>
>> MyClass c = new MyClass();
>> int i = new int(); // equivalent to "int i;"
>>
>> This makes the difference between pointers and nonpointers a tad confusing but it would make life much easier in some cases.
>
>Ah, no. It will create one on the heap. Nasty!

Yeah the syntax kind of stinks.  I suppose we could fix this now with templates (see below) but it would still be nice to have some sort of language support for this, though I don't have any ideas offhand.  Perhaps this?

T val = T.new;

>>  We should be able to use the
>> same semantics for all types in D and be able to distinguish between them.
>
>Agreed. I'm sure we can sort this out in the long run. I suspect that as soon as Walter looks at the issue he'll point out some bit of template arcana that I should have been applying.

This was meant for generating copies but it could be adapted for plain ol' construction.

# template gen( Ty )
# {
#     Ty copy( Ty val )
#     {
#         return val;
#     }
# }
#
#
# template gen( Ty : Object )
# {
#     Ty copy( Ty val )
#     {
#         return new Ty( val );
#     }
# }

The new class and struct keywords Walter suggestede would make this even more foolproof.


Sean


July 30, 2004
In article <ced03n$2b4a$1@digitaldaemon.com>, Matthew says...
>
>You talking about the 4786 issue, or something else?

Yup.  Only useful in that it shows that complete template names often get quite large, even if they're generally compacted in code with nesting and typedefs.


Sean