August 04, 2004
"Farmer" <itsFarmer.@freenet.de> wrote in message news:Xns953AE55B1F31EitsFarmer@63.105.9.61...
> DTL looks cool!

Thanks. Although I'd have to say it's a bit of a mess at the mo, since a lot of the code's in there due to experimentation, trying to find my way on the borders of the language. It'll be tidied up a lot in the future.

> Cleanest GP code I've ever seen.

Nice to hear. Or would be if I knew what GP meant. ??

> Just one suggestion: Make the collection interfaces second class citizens.

They are. The containers default to compile-time binding only. If you want an interface, you must explicitly say so in the container parameterisation.

    List!(int)                             // a plain List of int
    List!(int, IContainer!(int))    // a List of int implementing the IContainer!(int) interface

> I
> don't get what's the big benefit of them:
>
> Given three functions foo(), bar() and colFoo():
>
> foo() has a list of integers of type vector!(int)
>
> bar() accepts a list of type Vector!(int, ISequenceContainer)
>
> Therefore bar() can delegate the call to colFoo(), which
> accepts the list as an ISequenceContainer.
>
> Now, foo() cannot efficiently pass its list of integers to bar(), although
> bar() expects nothing else than a list of integers!

Cognitive overload!!! Can you rephrase with more code?

> Wouldn't it be simpler and more flexible if collection interfaces were provided by 'wrapper' classes instead?

Again: more info please.

> Mixins could be included too, so you could create your own container objects to benefit from encapsulation.

I intend to abstract almost all the common functionality out to mixins. Just have to get the code to a stable point soon, as trying to work out some of the compiler errors right now is headaching stuff.



August 04, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:cemt0h$ke1$1@digitaldaemon.com...
> Regarding a TODO in map.d:
>
> replace: foreach(key_type key; m_elements.keys)
> with: foreach(key_type key, inout value_type value; m_elements)
>
> According to the docs on foreach, this should work.

I think the TODO is old, as I remember implementing the two-param delegate. Or I could just be going slowly mad. :)





August 04, 2004
"Sean Kelly" <sean@f4.ca> wrote in message news:cem3oa$bbt$1@digitaldaemon.com...
> Finally had a chance to skim the DTL this morning on my way to work.  Looks nice so far, though I've yet to actually play with it.  Just some random thoughts I had while perusing the code:
>
> Much of DTL uses the C++ naming scheme.  As much as I like it, stuff should be renamed to suint the D convention.

Sure. Just been spending time on other things so far.

> Types should be mixed case with a leading capital: size_type -> SizeType or just Size, etc.
>
> Functions should be mixed with a leading lowercase:
> pop_front -> popFront
> is_open -> isOpen
>
> traits.d: isValue is either not complete or bugged

Hmm. Let me have a look ...

Nope. Don't know what you mean. Please explain.

> I'm kind of torn on the leading "I" for interfaces.  I want to not like it but I can see how it would be useful.

I'm keeping it, unless a royal decree from his-W-ness stipulates to the contrary.


> List.clear() delinks every node.  This may help GC but is it really necessary?

Dunno. :)

> I'd prefer not to have an O(N) clear if an O(1) version works just as well.

I can see your point. The reason I originally went through a pass is that the List is a double-linked list, and hence there's a loop. I assume without clearly at least the forward or the backward nodes, they'd never get reaped. Given that, we need to do at least half, and so why not both (it'd hardly be a much greater cost; maybe 10%??)

> I ran across "mixes Ranges" twice as part of class inheritance lists.  Should this compile?

No. mixins are on the back burner until everything else works

>  And if so, what does it mean? :)

You got me! :)

> Possible shortcut for categories.d:
>
> # class _Function(I, R) : I
> # {
> # public:
> #     alias R     return_type;
> #     alias A0    argument0_type;
> # }
> #
> # template Function(R, A0)
> # {
> #     alias _Function!(IFunction, R, A0) Function;
> # }
> #
> # template Predicate(A0)
> # {
> #     alias _Function!(IPredicate, bool, A0) Predicate;
> # }
>
> Just means less typing.  Three cheers for templated typedefs :)

Yup. I plan to do this along the way.

> Enumerator:
>
> perhaps rename hasMoreElements() to hasMore(), more(), or atEnd().  Rename
> nextElement() to next().

Most certainly. It was a direct reap of the Java interface.

As a general rule, please send in all your naming criticisms, but bear in mind that they're just there to hang my hat on at the moment. Naturally we'll have a single consistent naming convention throughout DTL, and which is (hopefully!) consistent with Phobos.



August 04, 2004
Matthew wrote:
> "Farmer" <itsFarmer.@freenet.de> wrote in message news:Xns953AE55B1F31EitsFarmer@63.105.9.61...

>>Cleanest GP code I've ever seen.
> 
> 
> Nice to hear. Or would be if I knew what GP meant. ??

Generic Programming?
August 04, 2004
"Lars Ivar Igesund" <larsivar@igesund.net> wrote in message news:ceq0qp$20dh$1@digitaldaemon.com...
> Matthew wrote:
> > "Farmer" <itsFarmer.@freenet.de> wrote in message news:Xns953AE55B1F31EitsFarmer@63.105.9.61...
>
> >>Cleanest GP code I've ever seen.
> >
> >
> > Nice to hear. Or would be if I knew what GP meant. ??
>
> Generic Programming?

Doh!

I'm really not terribly good with acronyms. <g>



August 04, 2004
Matthew schrieb:

>>List.clear() delinks every node.  This may help GC but is it really necessary?
> 
> Dunno. :)

I'm not sure of it being a very good idea. For the one, GC only scans for an active set and doesn't care for any permutations of the dead part, and for the other, i don't know how it's here, but i got used from one functional language to a sort-of copy-on-write semantics. Which in other words means, that as long as the whole tail was not copied, some tail of the list currently being cleared might be assigned to another valid list. Of course, functional language would not allow one to permutate the list in the first place. One would rather get it as an input, and create a new one and assign in place, which would result in a sort-of copy on write.


>>I'd prefer not to have an O(N) clear if an O(1) version works just as well.
> 
> I can see your point. The reason I originally went through a pass is that the List is a double-linked list, and hence
> there's a loop. I assume without clearly at least the forward or the backward nodes, they'd never get reaped. Given
> that, we need to do at least half, and so why not both (it'd hardly be a much greater cost; maybe 10%??)

? why half?

head->e->e->e->last
head<-e<-e<-e-<last

Simply cleanly remove head, than the rest is detached and would be collected. Or even this loop would be collected if nothing points into it from the "living set", which is determined recursively from stack and static area.

-eye
August 04, 2004
I'm not even sure clear() is needed. I had a clear() in MinTL but removed it in favor of assigning .init since this is the standard way of clearing D variables. The one reason I can see having it in DTL is that DTL uses classes so assigning .init just affects the one variable but calling a clear() will affect all variables with references to the object. In any case I agree clear() should just break the head and tail references and let the rest be GC'ed.

Ilya Minkov wrote:

> Matthew schrieb:
> 
>>>List.clear() delinks every node.  This may help GC but is it really
>>>necessary?
>> 
>> Dunno. :)
> 
> I'm not sure of it being a very good idea. For the one, GC only scans for an active set and doesn't care for any permutations of the dead part, and for the other, i don't know how it's here, but i got used from one functional language to a sort-of copy-on-write semantics. Which in other words means, that as long as the whole tail was not copied, some tail of the list currently being cleared might be assigned to another valid list. Of course, functional language would not allow one to permutate the list in the first place. One would rather get it as an input, and create a new one and assign in place, which would result in a sort-of copy on write.
> 
> 
>>>I'd prefer not to have an O(N) clear if an O(1) version works just as
>>>well.
>> 
>> I can see your point. The reason I originally went through a pass is that the List is a double-linked list, and hence there's a loop. I assume without clearly at least the forward or the backward nodes, they'd never get reaped. Given that, we need to do at least half, and so why not both (it'd hardly be a much greater cost; maybe 10%??)
> 
> ? why half?
> 
> head->e->e->e->last
> head<-e<-e<-e-<last
> 
> Simply cleanly remove head, than the rest is detached and would be collected. Or even this loop would be collected if nothing points into it from the "living set", which is determined recursively from stack and static area.
> 
> -eye

August 04, 2004
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in news:ceq007$209e$1@digitaldaemon.com:

>> Just one suggestion: Make the collection interfaces second class citizens.
> 
> They are.

Then make them third class citizens :-)


> 
>     List!(int)                             // a plain List of int
>     List!(int, IContainer!(int))    // a List of int implementing the
>     IContainer!(int) interface
> 
>> I
>> don't get what's the big benefit of them:
>>
>> Given three functions foo(), bar() and colFoo():
>>
>> foo() has a list of integers of type vector!(int)
>>
>> bar() accepts a list of type Vector!(int, ISequenceContainer)
>>
>> Therefore bar() can delegate the call to colFoo(), which
>> accepts the list as an ISequenceContainer.
>>
>> Now, foo() cannot efficiently pass its list of integers to bar(),
>> although bar() expects nothing else than a list of integers!
> 
> Cognitive overload!!! Can you rephrase with more code?

Sure. Here's a better scenario:

Suppose, function foo() works with a list of integers. Function foo() must call two other functions  bar(...)  and  barDll(...)  that perform some calculations on the list.

void bar(Vector!(int) list);
void barDll(IContainer!(int) list);


Now, this doesn't work:
void foo()
{
   Vector!(int) fooList;
   bar(fooList);
   barDll(foolist);  // error
}


And this, doesn't work either:
void foo()
{
   Vector!(int, IContainer) fooList;
   bar(fooList); // error
   barDll(fooList)
}


Too make it work, you must use a 'wrapper' class_
class List : IContainer!(int)
{
  Vector!(int) m_Data;

  List(Vector!(int) data);
  bit hasMore();
  int next();
}

void foo()
{
   Vector!(int) fooList;
   bar(fooList);
   List list=new List(fooList);
   barDll(list);
}


>> Mixins could be included too, so you could create your own container objects to benefit from encapsulation.
> 
> I intend to abstract almost all the common functionality out to mixins. Just have to get the code to a stable point soon, as trying to work out some of the compiler errors right now is headaching stuff.

I don't see mixins as a priority, either. Rather as interesting 'toy' that sometimes will come handy.


Farmer.
August 05, 2004
Matthew wrote:

> "Sean Kelly" <sean@f4.ca> wrote in message news:cem3oa$bbt$1@digitaldaemon.com...
>
>>Functions should be mixed with a leading lowercase:
>>pop_front -> popFront
>>is_open -> isOpen
>>
>>traits.d: isValue is either not complete or bugged
> 
> Hmm. Let me have a look ...
> 
> Nope. Don't know what you mean. Please explain.

I was referring to the bit at the bottom, but I had missed the /++/ bit commenting it out.  Teach me to rely too much on incomplete syntax hilighting :)


Sean
August 20, 2004
In general I want to take advantage afforded us by D's demotion of pointers, such that "class"-based mechanisms will be favoured, without having all the heartache of trying to write "generic" code (e.g. adaptors, algorithms, anything else that's going to deal with collections in a general way) to work with both pointers and user-defined types.

So, clear() will be preferred over .init, from my pov

"Ben Hinkle" <bhinkle4@juno.com> wrote in message news:ceqk60$2fj2$1@digitaldaemon.com...
> I'm not even sure clear() is needed. I had a clear() in MinTL but removed it in favor of assigning .init since this is the standard way of clearing D variables. The one reason I can see having it in DTL is that DTL uses classes so assigning .init just affects the one variable but calling a clear() will affect all variables with references to the object. In any case I agree clear() should just break the head and tail references and let the rest be GC'ed.
>
> Ilya Minkov wrote:
>
> > Matthew schrieb:
> >
> >>>List.clear() delinks every node.  This may help GC but is it really
> >>>necessary?
> >>
> >> Dunno. :)
> >
> > I'm not sure of it being a very good idea. For the one, GC only scans for an active set and doesn't care for any permutations of the dead part, and for the other, i don't know how it's here, but i got used from one functional language to a sort-of copy-on-write semantics. Which in other words means, that as long as the whole tail was not copied, some tail of the list currently being cleared might be assigned to another valid list. Of course, functional language would not allow one to permutate the list in the first place. One would rather get it as an input, and create a new one and assign in place, which would result in a sort-of copy on write.
> >
> >
> >>>I'd prefer not to have an O(N) clear if an O(1) version works just as
> >>>well.
> >>
> >> I can see your point. The reason I originally went through a pass is that the List is a double-linked list, and hence there's a loop. I assume without clearly at least the forward or the backward nodes, they'd never get reaped. Given that, we need to do at least half, and so why not both (it'd hardly be a much greater cost; maybe 10%??)
> >
> > ? why half?
> >
> > head->e->e->e->last
> > head<-e<-e<-e-<last
> >
> > Simply cleanly remove head, than the rest is detached and would be collected. Or even this loop would be collected if nothing points into it from the "living set", which is determined recursively from stack and static area.
> >
> > -eye
>