July 30, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:ceca7q$213u$1@digitaldaemon.com...
> Walter wrote:
>
> > "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cec0fl$1t7c$1@digitaldaemon.com...
> >
> >>I'm with Sean on this one. Since D doesn't have implicit instantion, how
> > can an accumulate template be instantiated as
> >>shown above?
> >
> >
> > Can you post a complete example, and I can verify whether it is fixed or not.
>
> Just to be pedantic:
>
> # template accumulate( Iter, ValT )
> # {
> #     ValT accumulate( Iter begin, Iter end, ValT val = ValT.init ) {}
> # }
> #
> # // what Matthew wants
> # char* b, e;
> # accumulate( b, e, 0 );
> #
> # // what we've got to do
> # accumulate!(char*, char)( b, e, 0 );
>
> So in this case it's not a bug but a language issue :)

Well, to be equally pedantic, I'm not too troubled about pointers, but in essence you're correct.

I agree that it's not a bug. If I've given the impression that this is a bug, I'm sorry, because I see it entirely as a language deficiency, not a compiler bug



July 30, 2004
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
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.

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.
July 30, 2004
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cebr2j$1qic$1@digitaldaemon.com...
> > or bugs
> > in our thinking
> Not a chance. :)

Bugs in our thinking are very likely.

> > - perhaps we haven't discovered the right D way to do generic programming.
>
> In terms of using and manipulating the elements in containers, as opposed
to manipulating containers themselves (i.e.
> adding/removing/moving elements), then I believe we do have the right
approach: foreach.
>
> Since I've devised ways to be able to apply filters/transformation to
containers that are themselves foreach-able (and
> can also be subject to filters/transformations themselves), then I believe
we are on the right road, or at least one of
> several right roads.

I think we might be, too. More experience will tell, so far there have been no users of your design. I expect that experience will force changes, just as experience has forced changes in D and some rethinking of some of my cherished erroneous ideas. Some of the Wright brothers' ideas have survived into modern aircraft, many were scrapped as obviously (in hindsight) the wrong way. That funky hip control for roll was one of those <g>.


> > > Alas, this crashes the compiler. Sigh ...
> > That's my problem, send me the test case!
> That's my problem. There is no test case.

Of course you have a test case. The whole thing, if need be. Hopefully, at least provide a .bat file that will result in the crash.

> I really think you need to come up with a better way to diagnose flaws in
the compiler, such that we can just send you
> dumps.

I've been at this game for decades. There is no better way than having the code that tickles the tiger.

> The iterator types that are currently coded have the following interface:
>
>     class SomeIterator
>     {
>             void next()
>             value_type value()
>             int opEquals(class_type rhs)
>     }
>
> The point is that without op*(), we cannot support pointers as iterators.
As a library implementor, that's actually a
> blessing, since I can now prescribe that all iterators exhibit certain
member types, which means that some of the worst
> crimes of STL (actually, they're crimes of badly implemented standard
libraries, mentioning no names ...) can be
> avoided.

D tries to move away from using pointers, so I think not directly supporting pointers as iterators might be a good idea. But remember, a pointer can be wrapped in a struct:

struct Pointer(T)
{        T* ptr;
            void next()
            value_type value()
            int opEquals(class_type rhs)
 }

and used that way.

> Basically, if F does not have a default constructor, then the compiler
craps on
>
>              m_f = new F(); << this line
>

I think I can fix that.


July 30, 2004
"Carlos Santander B." <carlos8294@msn.com> wrote in message news:cec3is$1ug7$1@digitaldaemon.com...
> Sometimes just
> reorganizing modules makes everything stop working. And it's certainly
> impossible to reproduce it.

Compilers are very deterministic. If you have a series of steps that "doesn't work", it's reproducible.


July 30, 2004
Ok, I see. I thought it was something else.


July 30, 2004
"Walter" <newshound@digitalmars.com> wrote in message news:cecrat$2830$1@digitaldaemon.com...
>
> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cebr2j$1qic$1@digitaldaemon.com...
> > > or bugs
> > > in our thinking
> > Not a chance. :)
>
> Bugs in our thinking are very likely.
>
> > > - perhaps we haven't discovered the right D way to do generic programming.
> >
> > In terms of using and manipulating the elements in containers, as opposed
> to manipulating containers themselves (i.e.
> > adding/removing/moving elements), then I believe we do have the right
> approach: foreach.
> >
> > Since I've devised ways to be able to apply filters/transformation to
> containers that are themselves foreach-able (and
> > can also be subject to filters/transformations themselves), then I believe
> we are on the right road, or at least one of
> > several right roads.
>
> I think we might be, too. More experience will tell, so far there have been no users of your design.

Well, that's because I've not really been able to get it stably compilable.

The bits that do work at the moment are hardly breathtaking in vision.

> I expect that experience will force changes, just
> as experience has forced changes in D and some rethinking of some of my
> cherished erroneous ideas. Some of the Wright brothers' ideas have survived
> into modern aircraft, many were scrapped as obviously (in hindsight) the
> wrong way. That funky hip control for roll was one of those <g>.
>
>
> > > > Alas, this crashes the compiler. Sigh ...
> > > That's my problem, send me the test case!
> > That's my problem. There is no test case.
>
> Of course you have a test case. The whole thing, if need be. Hopefully, at least provide a .bat file that will result in the crash.

I will do so very before the end of the w/e.

> > I really think you need to come up with a better way to diagnose flaws in
> the compiler, such that we can just send you
> > dumps.
>
> I've been at this game for decades. There is no better way than having the code that tickles the tiger.

I agree. My objection was your requirement for boiled down cases. Sometimes it's just not practical, and sometimes it's just not possible. (I concede that the remainder of circumstances boil down to laziness.)

> > The iterator types that are currently coded have the following interface:
> >
> >     class SomeIterator
> >     {
> >             void next()
> >             value_type value()
> >             int opEquals(class_type rhs)
> >     }
> >
> > The point is that without op*(), we cannot support pointers as iterators.
> As a library implementor, that's actually a
> > blessing, since I can now prescribe that all iterators exhibit certain
> member types, which means that some of the worst
> > crimes of STL (actually, they're crimes of badly implemented standard
> libraries, mentioning no names ...) can be
> > avoided.
>
> D tries to move away from using pointers, so I think not directly supporting pointers as iterators might be a good idea.

Same here.


> But remember, a pointer can be
> wrapped in a struct:
>
> struct Pointer(T)
> {        T* ptr;
>             void next()
>             value_type value()
>             int opEquals(class_type rhs)
>  }
>
> and used that way.

Of course. That's all planned. :)

> > Basically, if F does not have a default constructor, then the compiler
> craps on
> >
> >              m_f = new F(); << this line
> >
>
> I think I can fix that.

If you can, I will kiss you. :)

I shall try and start funnelling stuff your way shortly.


July 30, 2004
"Charlie" <Charlie_member@pathlink.com> wrote in message news:cebotu$1plh$1@digitaldaemon.com...
> I personally think generics are over-rated, if i wanted typeless variables i'd use a scripting language ( or VB ).

Is this related to something in my post (if so what?), or just a statement of your position?

> >    template Vector(T, B = EmptyBase)
> >    {
> >        class Vector
> >            : public BaseSelector!(B).selected_type
>
> I realize you do alot of C++ and D programming, so you want to keep the syntax roughly the same, but this looks dangerously close to C++.  Why noy use the D way :)
>
> class Vector(T,B = EmptyBase) : BaseSelector!(B).selected_type

I do a lot of programming in a lot of languages, and I always lay out my inheritance lists in the same way. AFAIAC it's got nothing specifically to do with C++.

> I only mention this because I wonder how much ( unconsiously ) your applying
> C++'s soloutions to D.

Undoubtedly. I am also _consciously_ applying ideas from many languages. Is that a problem? Since D doesn't yet have established methodologies for all this kind of thing - apart from foreach - what would you suggest instead?

> I for one am investing a large amount of
> >time to the D cause, with all the consequences wrt to more materially lucrative activities. Since I find that boiling down the code generally takes me at least as long to write the code in the first place, I just don't see that it's justified that I should do the boiling as well. Give me a -dump switch, and I can send it all off to Walter.
>
> I hear you on that one.
>
> >[btw: both of the above forms work now and, fwiw, I hope to release some of the containers supporting this in the
next
> >c/o days.]
>
> Youve been saying that for months ;).  But im not downing you I know your busy and all good things take time, but _please_ do release it , so that we can look at it too, theres lots of talent on the newsgroup.

This w/e, I promise.

> >4. D's import stuff just blows my mind!
>
> Maybe we can convince walter to give us a written and posted on the website description, as this seems to be a problem everyone has had at one time or another.  I know hes answered it a few times, but it needs to be easily accessible.

Agreed

 >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! :-(
>
> Well i hope you don't give up, hate to lose you at this stage, but I feel your frustration :S.

Don't really know how to give up. Probably a character flaw, that ..

> Charlie
>
>
> In article <ceaeid$18ir$1@digitaldaemon.com>, Matthew says...
> >
> >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.
> >
> >Before I preface this, I should reiterate the "modes" of DTL, to inform on any thoughts anyone might have on this:
> >
> >1. foreach - client code uses foreach. This all works well for all containers. The problem with this is only that
it's
> >an unsophisticated view of looking at a container: you get everything, and have to do all filtering and
transformations
> >yourself in client code. This can result in verbose and tedious coding. Good libraries should provide more power.
> >
> >2. Transformations/filtering - based on "Ranges" (a concept John Torjo and I concocted for C++, but which is
eminently
> >suitable for D.). Basically, each container provides a set of methods (eventually via a mixin) that returns a
"range".
> >For example, the "select()" method takes either a function/delegate/functor predicate, and returns a freachable range that "contains" only the elements matching the predicate, e.g.
> >
> >    List!(int)        list = . . .; // Assume it's filled with numbers 0 - 9
> >    bool IsOdd(int i)
> >    {
> >        return 0 != (i & 0x2);
> >    }
> >    foreach(int i; list.select(IsOdd))
> >    {
> >        printf("%d ", i);
> >    }
> >
> >This will print out "1 3 5 7 9"
> >
> >The power of this is that the returned "range" itself provides the same transformation methods, which means that the transformations are composable, as in:
> >
> >    List!(int)        list = . . .; // Assume it's filled with numbers 0 - 9
> >    bool IsOdd(int i)
> >    {
> >        return 0 != (i & 0x2);
> >    }
> >    int Times2(int i)
> >    {
> >        return 2 * i;
> >    }
> >    foreach(int i; list.select(IsOdd).collect(Times2))
> >    {
> >        printf("%d ", i);
> >    }
> >
> >This will print out "2 6 10 14 18"
> >
> >I'm sure you can see the power in this approach, as well as the potential efficiency savings, where the
transformation
> >"criteria" may be tunnelled into the original container's foreach (I've not done that yet).
> >
> >3. Interface-based containers
> >
> >Each container in DTL is declared as follows:
> >
> >    template Vector(T, B = EmptyBase)
> >    {
> >        class Vector
> >            : public BaseSelector!(B).selected_type
> >
> >
> >This means that by default the container will be do as the STL does, and will just be all compile-time typing, e.g.
> >
> >    alias    Vector!(int)     int_vector_t;
> >
> >    int_vector_t    v = new ...;
> >
> >    v[10] = 3;
> >    size_t n = v.length;
> >
> >    int    r = v[0] + v[1];
> >
> >Such a type is great, as long as we want to manipulate it in/with code that knows its exact type.
> >
> >Alternatively, we can also support the old-style Java approach, whereby one can specify a base interface, e.g.
> >
> >    void dump(IObjectContainer c)
> >    {
> >        for(IEnumerator e = c.enumerate(); e.hasMoreElements; )
> >        {
> >            printf("%.*s ", e.nextElement().toString());
> >        }
> >        printf("\n");
> >    }
> >
> >    alias    Vector!(int, IObjectContainer)    int_vector_IObjectContainer_t;
> >    alias    List!(int, IObjectContainer)        int_list_IObjectContainer_t;
> >
> >    int_vector_IObjectContainer_t   v = new ...;
> >    int_list_IObjectContainer_t        l = new ...;
> >
> >    dump(v);
> >    dump(l);
> >
> >Now we can pass instances of any container implementing IObjectContainer this to *any* function that knows how to manipulate that interface.
> >
> >[btw: both of the above forms work now and, fwiw, I hope to release some of the containers supporting this in the
next
> >c/o days.]
> >
> >The downside to the IObjectContainer type approach is that (i) fundamental types must be "boxed" (I've already worked
up
> >std.box), and (ii) it's not generic, since one must downcast object types to their "real" types from Object. Pretty
> >pukey stuff, except in the minority of circumstances where the IObject-stuff is what you're after (e.g. a message
> >board).
> >
> >Further to these two approaches, which I've been working on today, is inheritance via parameterised-interfaces, e.g.
> >
> >    template dump(T) { void dump(IContainer!(T) c)
> >    {
> >        for(IEnumerator e = c.enumerate(); e.hasMoreElements; )
> >        {
> >            T    t    =    e.nextElement();
> >
> >            // ... write generically, presumably via writef() (which I've not used yet <g>)
> >        }
> >        printf("\n");
> >    }
> >
> >    alias    IContainer!(int)                         int_IContainer_t;
> >    alias    Vector!(int, int_IContainer_t)    int_vector_IContainer_int_t;
> >    alias    List!(int, int_IContainer_t)        int_list_IContainer_int_t;
> >
> >    int_vector_IContainer_int_t      v = new ...;
> >    int_list_IContainer_int_t            l = new ...;
> >
> >    dump(v);
> >    dump(l);
> >
> >Note: this approach does _not_ require boxing or downcasting.
> >
> >Alas, this crashes the compiler. Sigh ...
> >
> >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 *(). Neither of these preclude the creation of iterators - and I've done
a
> >little of that - including adaptors for arrays/pointers, but it means they're not really very usable. The only way to use them "generically" in algorithms would be polymorphically if the iterator classes derived from interfaces, and
that
> >would preclude efficiency mechanisms (such as Random Access iterator advancement in STL), without some nasty hacks.
> >
> >It's my belief that iterators are not for D, and that we thus have the modes 1-3 described above.
> >
> >And now on to my litany of woes ...
> >
> >Some tasters:
> >
> >1. Beyond a significant, but indefinable level of complexity, the linker/compiler loose the ability to find all
required
> >symbols, while chopping out any *unrelated* parts makes them locatable again. Boil it down? I wish!!
> >
> >Nonetheless, that's a bug in the compiler/linker, and doesn't get my blood up, since one can usually find
workarounds,
> >and at this stage a little bugginess is not the crime of the century.
> >
> >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*!
> >
> >I'm yet to work out a workaround to this one - all I do at the moment is not use certain operations with certain container instantiations in the test programs. Woo hoo!
> >
> >3. There's no implicit instantiation. This has *massive* consequences, including:
> >
> >- We can't have iterators (as noted above). This is fine for reading from containers, but consider how we might "generically" insert into container ranges in the same (or any analogous) way as is the case with STL.
> >
> >- 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. Naturally, this has much wider consequences
> >
> >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'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.
> >
> >
> >So, what do we do about this? Walter's stock response is to boil it down, but it's either impossible to do so with non-trivial projects such as DTL, or I'm simply not smart enough to do it. Sure, one might argue that this is
indicative
> >of a too-complex design, but I think that's crap: the concept is simple, and the code is simple; it just doesn't
work.
> >(Very similar techniques that I've experimented on in C++ work fine.)
> >
> >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. I do know that it's totally bogus for us to be
made
> >to feel guilty for not having the time or the talent to do this boiling down. I for one am investing a large amount
of
> >time to the D cause, with all the consequences wrt to more materially lucrative activities. Since I find that boiling down the code generally takes me at least as long to write the code in the first place, I just don't see that it's justified that I should do the boiling as well. Give me a -dump switch, and I can send it all off to Walter.
> >
> >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.
> >
> >What's to be done? Well, one might say let's just have vanilla containers, and skip all the transformation stuff.
That's
> >fine, but then where're the generics? We can't have algorithms, remember, because we've not got implicit
instantiation!
> >The only remaining way to be generic is to follow the Java-route, and go with polymorphic container interfaces, but
(i)
> >they can't contain structures, and (ii) we're in Java-la-la land where everything has to be downcast. Yeuch! Even if
we
> >can get the compiler to accept parameterisable container interfaces, it's still a runtme indirection, with the concomitant efficiency costs.
> >
> >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?
> >
> >Matthew
> >
> >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
"Andy Friesen" <andy@ikagames.com> wrote in message news:cece6h$22hj$1@digitaldaemon.com...
> Matthew wrote:
>
> > No. Where is it? How to I get it? I'd like to get a look at that.
> >
> > btw, do you mean Andy Friesen? Andy, want to knock heads together on this?
> >
> > Mine was just a stab to get me what I needed, and was not intended to be the all-things-for-all-men (or women!) approach. However, I thought it might serve as a base for that.
>
> Yeah, that's me.  I put a copy online at <http://andy.tadan.us/d/variant.d>
>
> It's about as simple as it can get. :)

It seems to be a different approach to mine, and not really conflicting/redundant. My Box!() template (included) is almost offensively simple, it merely turns a built-in type into an Object-derived type, as in:

alias Box!(int)    BoxedInt_t;

int                    i    =    10;
BoxedInt_t      bi = new BoxedInt_t(i);

i = bi.value;

if(bi == i)
{}

if(bi != i)
{}

if(bi < i)
{}

(Actually, not all of that is yet implemented, but it will be.)





July 30, 2004
"J C Calvarese" <jcc7@cox.net> wrote in message news:ceb3ui$1gfa$1@digitaldaemon.com...
> In article <ceaeid$18ir$1@digitaldaemon.com>, Matthew says...
> >So, what do we do about this? Walter's stock response is to boil it down, but it's either impossible to do so with non-trivial projects such as DTL, or I'm simply not smart enough to do it. Sure, one might argue that this is
indicative
> >of a too-complex design, but I think that's crap: the concept is simple, and the code is simple; it just doesn't
work.
> >(Very similar techniques that I've experimented on in C++ work fine.)
>
> If you're unable (or unwilling) to boil it down for Walter, maybe someone else is. (I've worked on shortening problem code from Mango a while back.) If you post some code that produces a compiler error, I'll look at making it Walter-sized.

Good to know. I guess a lot of people will be able to help out in a variety of ways as soon as I damn-well post something. ;)