Re: dcollections 1.0 and 2.0a beta released

2010-05-27 Thread Steven Schveighoffer
On Wed, 26 May 2010 10:06:32 -0400, Bruno Medeiros  
brunodomedeiros+s...@com.gmail wrote:



On 24/05/2010 16:45, Andrei Alexandrescu wrote:

In the past I have built a C++ library that abstracted features of
the OS. My goal was to make it possible to dynamically load a module
that abstracted things like setting the IP address of a network
interface. My modules used std::string instead of char * to lookup
services to get objects that implement the interface. Big mistake. On
a later version of the standard C++ runtime, the private
implementation of std::string changed, so the dynamically loaded
libraries crashed horribly. No change in string's interface, just the
private stuff changed, but because it's a template, the code that
uses it necessarily has to be aware of it. We ended up ditching the
standard C++ library's version of string, and used STLPort so we
could control the library.

I envision this same sort of problem would be likely with D
collection objects that were not used via interfaces.


I see no problem retrofitting a no-interface container into a formal
interface if so needed.



I don't understand this discussion: isn't the reason above pretty much a  
dead-on hard requirement for the collections to have interfaces?

Something like, for example, an interface version of the range traits?


Only if you wish to have binary compatibility with dynamic libs.  Such a  
thing isn't likely today since dynamic libs aren't very well supported in  
D, and even phobos or dcollections isn't a dynamic lib.


And I have specifically decided not to use interfaces with ranges because  
that makes them reference types.  Ranges work well as value types, but not  
well as reference types.  Therefore, to use dcollections as interfaces,  
you must not require the range traits.


-Steve


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

Don wrote:
snip

IMHO, one of the most important bugs to fix is actually a spec bug:

4056 Template instantiation with bare parameter not documented

snip

Why single out that one?

This is the one that needs fixing most of all:

http://d.puremagic.com/issues/show_bug.cgi?id=677

Stewart.


Re: Bug fix week

2010-05-27 Thread Don

Stewart Gordon wrote:

Don wrote:
snip

IMHO, one of the most important bugs to fix is actually a spec bug:

4056 Template instantiation with bare parameter not documented

snip

Why single out that one?


Because it's a feature that is used in almost every non-trivial D2 
program, and the spec gives no hint that it even exists. Without it, you 
can't even make sense of many of the Phobos docs. It's an absolute 
disaster for anyone taking a first look at the language -- something 
which we expect to happen frequently in the next few weeks.


Re: dmd 1.061 and 2.046 release

2010-05-27 Thread Stewart Gordon

Jérôme M. Berger wrote:

Ary Borenszweig wrote:

Jérôme M. Berger wrote:

Walter Bright wrote:

snip

I'm using firefox. Even on their main
developer.apple.com/iphone/index.action, most of the text is light grey
on white.


Text is black here. But it is very thin, are you sure this isn't an
anti-aliasing issue?


In Windows Vista at least, anti-aliasing (whether Standard or ClearType) 
clearly isn't a straight average, considering that zooming out doesn't 
cause it to fade.  AIUI, part of M$'s patent on ClearType is about how 
it differs from straight average anti-aliasing by colour stripes.  I 
don't really know how it works.  Nor do I know how the anti-aliasing in 
other OSs compares.  But there, there's also the issue of system gamma 
vs. CSS standard gamma (well, sRGB) and whether or not the browser corrects.



It's #323232


Well, that's dark grey, not light grey like Walter said he gets...


Which text?

In the top half, most of the text is #33 (obscure grey, according to 
the VisiBone naming).


In the bottom half, most of the text is #66 (dark grey) or #77.

(Firefox 3.6.3, examined using Firebug)

Stewart.


[OT] Web font sizing (was: dmd 1.061 and 2.046 release)

2010-05-27 Thread Stewart Gordon

Nick Sabalausky wrote:
Walter Bright newshou...@digitalmars.com wrote in message 
news:hspj3m$1c9...@digitalmars.com...

snip
Web sites should avoid setting specific font sizes, so low vision 
users can enlarge it.


I agree a lot with most of this, but any web browser that doesn't 
scale so-called fixed-size fonts when zooming has a broken, archaic 
zoom function, period.

snip

Correct.  Indeed, here's a post I once made here
http://www.facebook.com/group.php?gid=2384051749
--
6. For partially sighted persons, there is no way to adjust text size. 
You say wow, they are demanding, this is something really easy to do.


Yes there is a way. Just stop using Internet Exploiter and get yourself 
a real web browser. But still

--

But you could well ask: Is it right to punish people for using broken 
browsers?  Especially if you're going out of your way to do so by 
specifying font sizes in pt or px.  I've always told people it just 
shouldn't be done.


Moreover, some have sensibly pointed out that web authors shouldn't 
change the body text size from the default, since the user's default is 
the size the user is comfortable with.


But maybe it's acceptable if all you're doing is compensating for the 
font you've chosen looking a little bigger or smaller at the same point 
size than the default Times New Roman.  That said:
- somebody might have set a different font as default in browser 
settings or a user stylesheet
- who decreed that the factory default in all graphical browsers shall 
be Times New Roman, anyway?


Stewart.


Re: [OT] Web font sizing

2010-05-27 Thread Walter Bright

Stewart Gordon wrote:
But maybe it's acceptable if all you're doing is compensating for the 
font you've chosen looking a little bigger or smaller at the same point 
size than the default Times New Roman.  That said:
- somebody might have set a different font as default in browser 
settings or a user stylesheet
- who decreed that the factory default in all graphical browsers shall 
be Times New Roman, anyway?


With style sheets, you can set the font size as larger or smaller than the 
default. This should be good enough. Setting fonts as pixel sizes is just wrong.


Re: To interface or not to interface

2010-05-27 Thread Kagamin
Steven Schveighoffer Wrote:

 On Tue, 25 May 2010 02:26:02 -0400, Kagamin s...@here.lot wrote:
 
  Recently I've hit a problem with collections in C#. Given classes
  class A {}
  class B {}
  And two collections CollectionA and CollectionB it's possible to  
  concat them into an array A[]. The efficient way to do it is to use  
  CopyTo(T[],int) method, but it accepts only array of exact collection  
  item's type, so I had to change the CollectionB type to CollectionA.
 
 Did you mean
 
 class B : A {} ?

Ah, yes.

 According to this page, it says that an exception could be thrown if Type  
 T cannot be cast automatically to the type of the destination array.   
 This implies that a destination array type to which T could automatically  
 be cast should work.

ICollectionA acoll;
ICollectionB bcoll;
A[] cat;
ICollectionA.CopyTo(A[],int)
ICollectionB.CopyTo(B[],int) - note the signature, the destination array 
can't be an array of supertype. There's no chance to throw an exception because 
the code doesn't pass type check at compile time.


Re: To interface or not to interface

2010-05-27 Thread Kagamin
 ICollectionA acoll;
 ICollectionB bcoll;
 A[] cat;
 ICollectionA.CopyTo(A[],int)
 ICollectionB.CopyTo(B[],int) - note the signature, the destination array 
 can't be an array of supertype. There's no chance to throw an exception 
 because the code doesn't pass type check at compile time.

To ease understanding:

ICollectionAnimal acoll;
ICollectionCat ccoll;
Animal[] animals;
ICollectionAnimal.CopyTo(Animal[],int)
ICollectionCat.CopyTo(Cat[],int)


Re: Uniform function call syntax

2010-05-27 Thread Jacob Carlborg

On 2010-05-27 01.41, retard wrote:

Wed, 26 May 2010 22:05:48 +0200, Jacob Carlborg wrote:


I've asked this before, probably several times: if and when will D get
the uniform function call syntax that has been talked about? Example:

void foo (int i) {}
3.foo();

And please don't say it's already implemented because it isn't, I've
heard that before.


Are you sure you're not confusing two things.

The uniform access says that client code should not be affected by a
decision to implement an attribute as a field or method. -- Programming
in Scala

The other is a term known as extension methods. Extension methods enable
you to add methods to existing types without creating a new derived
type, recompiling, or otherwise modifying the original type. -- http://
msdn.microsoft.com/en-us/library/bb383977.aspx


This was talked about at the first D conference and the term used there 
was uniform/unified function call syntax.


--
/Jacob Carlborg


Re: Uniform function call syntax

2010-05-27 Thread Jacob Carlborg

On 2010-05-27 01.52, Simen kjaeraas wrote:

On Thu, 27 May 2010 01:41:16 +0200, retard r...@tard.com.invalid wrote:


Wed, 26 May 2010 22:05:48 +0200, Jacob Carlborg wrote:


I've asked this before, probably several times: if and when will D get
the uniform function call syntax that has been talked about? Example:

void foo (int i) {}
3.foo();

And please don't say it's already implemented because it isn't, I've
heard that before.


Are you sure you're not confusing two things.

The uniform access says that client code should not be affected by a
decision to implement an attribute as a field or method. -- Programming
in Scala

The other is a term known as extension methods. Extension methods enable
you to add methods to existing types without creating a new derived
type, recompiling, or otherwise modifying the original type. -- http://
msdn.microsoft.com/en-us/library/bb383977.aspx


http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf

Page 9. The idea is that foo(bar) may be replaced with bar.foo() and vice
versa, making function calls 'uniform' in that both member functions and
free functions may be called in the same manner.


What he said ^


--
/Jacob Carlborg


Re: Uniform function call syntax

2010-05-27 Thread Jacob Carlborg

On 2010-05-27 07.17, Robert Jacques wrote:

On Wed, 26 May 2010 16:05:48 -0400, Jacob Carlborg d...@me.com wrote:


I've asked this before, probably several times: if and when will D get
the uniform function call syntax that has been talked about? Example:

void foo (int i) {}
3.foo();

And please don't say it's already implemented because it isn't, I've
heard that before.



Is your patch still current or does it need to be looked at?
(http://d.puremagic.com/issues/show_bug.cgi?id=3382)


1. I assume that the line numbers in the diff is not correct anymore, 
don't know how sensitive that is
2. As I say in the bug report literals don't work, i.e. 3.foo();, 
x.foo(); works though.


To make 2. work I assume additional changes need to made in the lexer 
and/or parser. What I've heard 2. will never work until .1 and/or 1. 
are not allowed anymore.


--
/Jacob Carlborg


Re: container stuff

2010-05-27 Thread bearophile
Jonathan M Davis:

 Well, I've never needed to do that particular operation on _any_ container, 
 so it does strike me as weird regardless. I've basically always been looking 
 to remove a specific element or elements or to remove the element at a 
 specific location.

You have probably missed my other answer. But I can add some more. That 
operation is common. You use it every time you have a container that doesn't 
define a deterministic order (like hash sets, hash associative arrays, and so 
on) and you want to process and consume its items. In such collection you can't 
ask to pop the last or first item because they are not defined. So you pop out 
one randomly. I have used it many times in my programs.

Bye,
bearophile


Re: container stuff

2010-05-27 Thread bearophile
Andrei Alexandrescu:
 Done. removeAny was my choice as of a few months ago but I'd forgotten. 

I suggest to call it just pop.

Bye,
bearophile


Static constructors in circularly imported modules - again

2010-05-27 Thread Max Samukha
There was a discussion about those a while ago that terminated with 
Andrei's authoritative it would be a step backward.


I am not entirely convinced that there had been a step forward in the 
first place. Defining static construction order to be determined by the 
module import graph had been a half step forward. Completely disallowing 
static construction of circularly imported modules - a half step 
backward. The result is std.stdiobase and impossibility to initialize 
static data in mixins without resorting to lazy initialization.


I can live with hacks like std.stdiobase when such are possible. What is 
more critical is initialization of mixins. Restating the problem:


module a;
mixin template Foo()
{
   static immutable Object foo;
   shared static this()
   {
   foo = cast(immutable)new Object;
   }
}


module b;
import a;
import c;

mixin Foo;


module c;
import a;
import b;

mixin Foo;

In this scenario one is forced to avoid static constructors by lazily 
initializing foo and using some kind of synchronization, which should be 
absolutely unnecessary and sometimes is not tolerable.


So which of the following is going to happen?

1. The current blinkered design will stay.
2. A solution will be provided before D2 is feature-freezed.

Note that I am well aware of 
http://yosefk.com/c++fqa/ctors.html#fqa-10.12 etc, but simply 
disallowing static construction is not a good solution for static 
construction problems.


Re: container stuff

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 00:20:24 -0400, Jonathan M Davis  
jmdavisp...@gmail.com wrote:



Steven Schveighoffer wrote:


Jonathan M Davis Wrote:

Looks interesting overall. There is one function, however, which makes  
no

sense to me: removeElement()/stableRemoveElement().

So, it basically removes a random element from the container? It could  
be

quite consistent as to which element it removes from the container (it
being implementation-dependent), but effectively, it removes a random
element? What's the point of that? I can't remember the last time - if
ever - that I wanted to remove an element from a container and I didn't
care which. Or am I misunderstanding what it does?


I think you are misunderstanding.  Random element means you can't tell
which one is removed, but it doesn't *have* to be truly random :)  It  
most
likely will be the most convenient element to remove (maybe that would  
be

a better description).  In other words, you can't expect it to always be
the last element, or the first element, or the lowest element, or
whatever.

So essentially, I think that's what you were asking for, and I think
that's what Andrei meant.

-Steve


I don't think that I misunderstood, but I may not have stated it well.  
No,
the element is not _truly_ random, but it is removing an unspecified  
element
which could be any element in the container, and is therefore random in  
the
sense that you aren't telling it which one to remove. I've never been in  
a
situation where it made any sense to do that. So, the function struck me  
as

really weird.

If you wanted truly random, you'd have to implement a function that  
actually
did random number generation or whatnot to decide which element to pick,  
and
presumably, it would be abnormal to use that here (though I think that  
doing
so would still follow the API). So, no, removeElement() (now  
removeAny()) is

not truly random, but it isn't deterministic from the perspective of the
programmer having any clue which one will be removed, and it may or may  
not

be deterministic from the container's perspective.


OK.  I think the point of removeAny is that it removes an element as fast  
as possible, however that can be implemented by the container.  I.e.  
removing the back or front element may not be the fastest operation, think  
about something like a tree, where the fastest element to remove is  
probably the top element.


-Steve


Re: To interface or not to interface

2010-05-27 Thread Steven Schveighoffer
On Tue, 25 May 2010 23:29:34 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



Steven Schveighoffer wrote:
On Mon, 24 May 2010 18:13:38 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



Steven Schveighoffer wrote:
All an interface does is give an abstract representation of functions  
that are *already there*.  Removing the interface does not remove the  
functions that implemented the interface.


Then why do interfaces need to be part of the collection component?  
Why can't the user add them if he wants them?

 How do you add an interface to a class?


Define an interface who's member functions call the class' member  
functions.


Quoting from earlier message:

  Wrapping seems like it would add more overhead than just implementing  
the interface, especially since D's inliner has some strange restrictions.


-Steve


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

Don wrote:
snip

IMHO, one of the most important bugs to fix is actually a spec bug:

4056 Template instantiation with bare parameter not documented

snip

Why single out that one?

This is the one that needs fixing most of all:

http://d.puremagic.com/issues/show_bug.cgi?id=677

Stewart.


Re: container stuff

2010-05-27 Thread Don

bearophile wrote:

Jonathan M Davis:

Well, I've never needed to do that particular operation on _any_ container, 
so it does strike me as weird regardless. I've basically always been looking 
to remove a specific element or elements or to remove the element at a 
specific location.


You have probably missed my other answer. But I can add some more. That operation is common. 



You use it every time you have a container that doesn't define a deterministic 
order (like hash sets, hash associative arrays, and so on) and you want to 
process and consume its items. In such collection you can't ask to pop the last 
or first item because they are not defined. So you pop out one randomly. I have 
used it many times in my programs.


When is it better to do it that way, rather than just iterating over all 
elements, and then completely empty the container?
(Just curious -- I'm having trouble thinking of a use case for this 
feature).


Re: container stuff

2010-05-27 Thread bearophile
Don:
 When is it better to do it that way, rather than just iterating over all 
 elements, and then completely empty the container?
 (Just curious -- I'm having trouble thinking of a use case for this 
 feature).

I'm having troubles understanding why two persons have troubles seeing use 
cases for this feature :-)

Iterating over the container and then emptying the container is two operations, 
you have to keep in mind to empty it, while if you pop items out of it 
progressively you just need to keep in mind to do one thing, and you avoid 
forgetting the final cleaning.

Also, the progressive popping out of items allows you to have a collection that 
is correct in every moment, there is no risk of removing two times an item, 
so you can pass around the data structure in any moment of this process of 
wearing it away.

This is what you suggest (Python code):

s = set([ab, bc, de])

def process_item(item):
print item

for item in s:
process_item(item)
s.clear() # removes all items


But this is better, you can print the correct collection in any moment and you 
can't forget the final clear:

s = set([ab, bc, de])

def process_item(item):
print item

def show_data(items):
print items

while s:
process_item(s.pop())
show_data(s)

Bye,
bearophile


Re: Bug fix week

2010-05-27 Thread bearophile
Stewart Gordon:
 This is the one that needs fixing most of all:
 http://d.puremagic.com/issues/show_bug.cgi?id=677

I don't think Walter will fix that bug. If you think that bug is important for 
you, then I suggest you to find other people that agree with you, and write 
down the specs yourself (and then maybe Walter will read your document to tell 
you how to fix its errors).

This is the most voted bug, one of those votes is mine, but now I am not so 
sure Walter takes a look at the vote counts when he fixes bugs:
http://d.puremagic.com/issues/show_bug.cgi?id=314

Bye,
bearophile


Re: Uniform function call syntax

2010-05-27 Thread retard
Wed, 26 May 2010 21:43:38 -0400, Robert Jacques wrote:

 On Wed, 26 May 2010 20:44:50 -0400, retard r...@tard.com.invalid wrote:
 
 Thu, 27 May 2010 01:52:32 +0200, Simen kjaeraas wrote:

 On Thu, 27 May 2010 01:41:16 +0200, retard r...@tard.com.invalid
 wrote:

 Wed, 26 May 2010 22:05:48 +0200, Jacob Carlborg wrote:

 I've asked this before, probably several times: if and when will D
 get the uniform function call syntax that has been talked about?
 Example:

 void foo (int i) {}
 3.foo();

 And please don't say it's already implemented because it isn't, I've
 heard that before.

 Are you sure you're not confusing two things.

 The uniform access says that client code should not be affected by a
 decision to implement an attribute as a field or method. --
 Programming in Scala

 The other is a term known as extension methods. Extension methods
 enable you to add methods to existing types without creating a new
 derived type, recompiling, or otherwise modifying the original type.
 -- http:// msdn.microsoft.com/en-us/library/bb383977.aspx

 http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf

 Page 9. The idea is that foo(bar) may be replaced with bar.foo() and
 vice versa, making function calls 'uniform' in that both member
 functions and free functions may be called in the same manner.

 I understood what you meant. It's just that the idea was invented
 before in C#. I usually give attribution to (and favor the term
 invented by) the original innovator, not the copycat. Those two
 features have only few differences, for example C# requires importing
 the symbols first with 'using'. The proposed D feature is more careless
 here.
 
 Actually, C# is, if anything, the copycat. (Convergent evolution is much
 more likely) Extension methods were introduced in C# 3, which was
 released November 2007. Uniform function call syntax was discussed at D
 language conference in August 2007. And it's a logical extension from
 array 'Functions as Array Properties' which has been around since at
 least 2006.

I've found articles of the proposed extension methods for C# already in 
2004 and blog posts in 2005. Of course C# is a copycat, most of the ideas 
in modern programming languages were already invented 20-50 years ago. 
But AFAIK this feature was presented in C# context long before D 
reinvented it.


AAs of struct or array

2010-05-27 Thread bearophile
I have noticed a significant speed difference between foo1 and foo2 (D2 code):

import std.c.stdio: printf;

int foo1(int x, int y) {
static int[int[2]] cache;
int[2] args = [x, y];
cache[args] = x;
return x;
}

int foo2(int x, int y) {
static struct Pair { int x, y; }
static int[Pair] cache;
Pair args = Pair(x, y);
cache[args] = x;
return x;
}

void main() {
enum int N = 600;
int tot;
foreach (x; 1 .. N)
foreach (y; 1 .. N)
tot += foo2(x, y); // use foo1 or foo2 here
printf(%d\n, tot);
}


Bye,
bearophile


Re: Static constructors in circularly imported modules - again

2010-05-27 Thread Max Samukha

On 05/27/2010 01:37 PM, Max Samukha wrote:



module a;
mixin template Foo()
{
static immutable Object foo;
shared static this()
{
foo = cast(immutable)new Object;
}
}


module b;
import a;
import c;

mixin Foo;


module c;
import a;
import b;

mixin Foo;

In this scenario one is forced to avoid static constructors by lazily
initializing foo and using some kind of synchronization, which should be
absolutely unnecessary and sometimes is not tolerable.



Ok, I've just thought of a way to avoid synchronization (using __gshared 
for simplicity):


module a;
mixin template Foo()
{
static __gshared Object foo; // shared foo
static Object tlFoo; // thread-local foo

Object getFoo()
{
if (!tlFoo)
{
synchronized(lock)
{
if (!foo)
foo = new Object;
}
tlFoo = foo;
}
return tlFoo;
}
}

There is still unnecessary overhead of accessing and testing the 
thread-local variable.





Re: container stuff

2010-05-27 Thread Don

bearophile wrote:

Don:
When is it better to do it that way, rather than just iterating over all 
elements, and then completely empty the container?
(Just curious -- I'm having trouble thinking of a use case for this 
feature).


I'm having troubles understanding why two persons have troubles seeing use 
cases for this feature :-)

Iterating over the container and then emptying the container is two operations, 
you have to keep in mind to empty it, while if you pop items out of it 
progressively you just need to keep in mind to do one thing, and you avoid 
forgetting the final cleaning.


Yes, but if I understand correctly, the only reason to have removeAny 
_as a primitive_ is for speed. And iterating over the container followed 
by a single removal is almost always going to be much faster.


If, however, speed is not critical, removeAny can be a generic function 
-- call removeFront() if present, else call removeBack().

And your examples would work just fine with that.

I'm having trouble identifying a use case where it needs to be a primitive.


Re: Static constructors in circularly imported modules - again

2010-05-27 Thread Jason House
Max Samukha Wrote:

 There was a discussion about those a while ago that terminated with 
 Andrei's authoritative it would be a step backward.
 
 I am not entirely convinced that there had been a step forward in the 
 first place. Defining static construction order to be determined by the 
 module import graph had been a half step forward. Completely disallowing 
 static construction of circularly imported modules - a half step 
 backward. The result is std.stdiobase and impossibility to initialize 
 static data in mixins without resorting to lazy initialization.
 
 I can live with hacks like std.stdiobase when such are possible. What is 
 more critical is initialization of mixins. Restating the problem:
 
 module a;
 mixin template Foo()
 {
 static immutable Object foo;
 shared static this()
 {
 foo = cast(immutable)new Object;
 }
 }
 
 
 module b;
 import a;
 import c;
 
 mixin Foo;
 
 
 module c;
 import a;
 import b;
 
 mixin Foo;
 
 In this scenario one is forced to avoid static constructors by lazily 
 initializing foo and using some kind of synchronization, which should be 
 absolutely unnecessary and sometimes is not tolerable.
 
 So which of the following is going to happen?
 
 1. The current blinkered design will stay.
 2. A solution will be provided before D2 is feature-freezed.
 
 Note that I am well aware of 
 http://yosefk.com/c++fqa/ctors.html#fqa-10.12 etc, but simply 
 disallowing static construction is not a good solution for static 
 construction problems.

In module b, delete the import of c. In module c, delete the import of b. Your 
sample code will then  compile and run. It probably wouldn't do what you want 
though; you'll have two globals (b.foo and c.foo).  I suspect what you really 
want is one global a.foo?


Re: std.container update

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 00:36:24 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


I just implemented a singly-linked list type to illustrate the container  
abstraction.


http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

One interesting aspect is that SList must cooperate with Take. More  
details are to be found in code, but essentially SList ranges are all  
sentinel-terminated, which makes them right-bound. If you want to only  
remove a few elements from the middle of a list, you need to construct a  
range that spans a limited portion of the list. I encoded that by using  
the Take abstraction in std.range.


Please let me know of how you find it. There are a few refinements and  
ancillary functions to define, but those are pretty clear given the rest.


Well, one thing I don't like about it is that you cannot do O(1) insertion  
or removal.  insertBefore requires O(n) complexity and insertAfter  
requires O(m) complexity.  Removal will require O(n) complexity, even  
though it doesn't exist right now.


Fast removal and insertion are key to having a linked list.  I'd suggest  
modifying the range so it uses a Node ** instead, which points to the  
_next element of the previous node of the one currently being iterated, or  
_root if it's the first node in the list.


-Steve


Re: std.container update

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 09:23:03 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Thu, 27 May 2010 00:36:24 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


I just implemented a singly-linked list type to illustrate the  
container abstraction.


http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

One interesting aspect is that SList must cooperate with Take. More  
details are to be found in code, but essentially SList ranges are all  
sentinel-terminated, which makes them right-bound. If you want to  
only remove a few elements from the middle of a list, you need to  
construct a range that spans a limited portion of the list. I encoded  
that by using the Take abstraction in std.range.


Please let me know of how you find it. There are a few refinements and  
ancillary functions to define, but those are pretty clear given the  
rest.


Well, one thing I don't like about it is that you cannot do O(1)  
insertion or removal.  insertBefore requires O(n) complexity and  
insertAfter requires O(m) complexity.  Removal will require O(n)  
complexity, even though it doesn't exist right now.


Fast removal and insertion are key to having a linked list.  I'd suggest  
modifying the range so it uses a Node ** instead, which points to the  
_next element of the previous node of the one currently being iterated,  
or _root if it's the first node in the list.


In fact, I'd say that it would be critical to split the insert and remove  
functions to slow (O(n) or greater) versions and fast( O(lg(n) or less))  
functions.  Some algorithms may depend on fast insertion and removal, such  
as mergesort on a linked list.


-Steve


Re: container stuff

2010-05-27 Thread Andrei Alexandrescu

On 05/27/2010 06:49 AM, Don wrote:

bearophile wrote:

Jonathan M Davis:


Well, I've never needed to do that particular operation on _any_
container, so it does strike me as weird regardless. I've basically
always been looking to remove a specific element or elements or to
remove the element at a specific location.


You have probably missed my other answer. But I can add some more.
That operation is common.



You use it every time you have a container that doesn't define a
deterministic order (like hash sets, hash associative arrays, and so
on) and you want to process and consume its items. In such collection
you can't ask to pop the last or first item because they are not
defined. So you pop out one randomly. I have used it many times in my
programs.


When is it better to do it that way, rather than just iterating over all
elements, and then completely empty the container?
(Just curious -- I'm having trouble thinking of a use case for this
feature).


Again, any worklist-based algorithm will remove and add work items 
without minding for a specific order.


http://cseweb.ucsd.edu/classes/sp00/cse231/report/node12.html


Andrei


Re: std.container update

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 09:27:39 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Thu, 27 May 2010 09:23:03 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Thu, 27 May 2010 00:36:24 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


I just implemented a singly-linked list type to illustrate the  
container abstraction.


http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

One interesting aspect is that SList must cooperate with Take. More  
details are to be found in code, but essentially SList ranges are all  
sentinel-terminated, which makes them right-bound. If you want to  
only remove a few elements from the middle of a list, you need to  
construct a range that spans a limited portion of the list. I encoded  
that by using the Take abstraction in std.range.


Please let me know of how you find it. There are a few refinements and  
ancillary functions to define, but those are pretty clear given the  
rest.


Well, one thing I don't like about it is that you cannot do O(1)  
insertion or removal.  insertBefore requires O(n) complexity and  
insertAfter requires O(m) complexity.  Removal will require O(n)  
complexity, even though it doesn't exist right now.


Fast removal and insertion are key to having a linked list.  I'd  
suggest modifying the range so it uses a Node ** instead, which points  
to the _next element of the previous node of the one currently being  
iterated, or _root if it's the first node in the list.


In fact, I'd say that it would be critical to split the insert and  
remove functions to slow (O(n) or greater) versions and fast( O(lg(n) or  
less)) functions.  Some algorithms may depend on fast insertion and  
removal, such as mergesort on a linked list.




Actualy mergesort could not be implemented without some sort of way to  
restructure the list without allocating new nodes, requiring knowledge of  
the link structure.  I'm not sure it could be generic... I'll think about  
this a bit.


-Steve


Re: std.container update

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 00:36:24 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


I just implemented a singly-linked list type to illustrate the container  
abstraction.


http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

One interesting aspect is that SList must cooperate with Take. More  
details are to be found in code, but essentially SList ranges are all  
sentinel-terminated, which makes them right-bound. If you want to only  
remove a few elements from the middle of a list, you need to construct a  
range that spans a limited portion of the list. I encoded that by using  
the Take abstraction in std.range.


Please let me know of how you find it. There are a few refinements and  
ancillary functions to define, but those are pretty clear given the rest.



I have another general question in general about these collections.

Ranges fix a very bad problem with iterators -- non-matching begin and end  
iterators.  For example, passing a begin from one list and and end from  
another.


However, all your range functions such as remove, insertBefore, etc. are  
called via the container type, using a range as an argument.  But there  
can be no static verification that a range actually is part of a given  
container.  Should there be some requirement that a container validates  
that a range is part of the container before performing the operation?   
This is the case for dcollections.


In your current implementation of SList, verification seems incidental for  
insertBefore because you must find the previous node from the root anyways  
(and that will throw on enforce if it cannot find it).  But insertAfter  
does not, so something like this will compile, run, and result in strange  
behavior:


auto sl1 = make(SList!int, 1, 2, 3, 4, 5); // I may not have this correct,  
but it's not important

auto sl2 = make(SList!int, 6, 7, 8, 9, 10);

auto r1 = sl1[];
r1.popFront();
r1.popFront();

auto r2 = take(r1, 2);
sl2.insertAfter(r2, 666); // actually inserts into sl1

-Steve


Re: Static constructors in circularly imported modules - again

2010-05-27 Thread Max Samukha

On 05/27/2010 03:47 PM, Jason House wrote:


In module b, delete the import of c. In module c, delete the import of b. Your sample code will then  compile and run.  It probably wouldn't do what you want though; you'll have two globals 

(b.foo and c.foo).  I suspect what you really want is one global a.foo?

Two distinct globals. There is a more concrete example:

module QObject;

class QMetaObject
{
...
}

mixin template Q_OBJECT()
{
...

immutable(QMetaObject) metaObject() immutable
{
return staticMetaObject;
}

static immutable QMetaObject staticMetaObject;
shared static this()
{
staticMetaObject = 
cast(immutable)QMetaObject.create!(typeof(this));

}
}


module a;
import QObject;
import b;

class A : QObject
{
B b;
mixin Q_OBJECT;
}


module b;
import QObject;
import a;

class B :
{
A a;
mixin Q_OBJECT;
}

When mixed in a class, Q_OBJECT, among other things, associates a global 
RTTI object with that class. Ideally, this object should be created at 
program startup.


We cannot impose on the user of Q_OBJECT the requirement that a and b 
should not be circularly imported or that he has to manually call an 
initialization function etc.


Re: std.container update

2010-05-27 Thread Andrei Alexandrescu

On 05/27/2010 08:23 AM, Steven Schveighoffer wrote:

You're making a number of great points in the four posts starting with
this. Since they sort of augment one another, let me quote and answer
them all here.


On Thu, 27 May 2010 00:36:24 -0400, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:


I just implemented a singly-linked list type to illustrate the
container abstraction.

http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

Please let me know of how you find it. There are a few refinements
 and ancillary functions to define, but those are pretty clear
given the rest.


Well, one thing I don't like about it is that you cannot do O(1)
insertion or removal. insertBefore requires O(n) complexity and
insertAfter requires O(m) complexity. Removal will require O(n)
complexity, even though it doesn't exist right now.

Fast removal and insertion are key to having a linked list. I'd
suggest modifying the range so it uses a Node ** instead, which
points to the _next element of the previous node of the one currently
being iterated, or _root if it's the first node in the list.

-Steve


The performance profile of SList is what one would expect for a
straightforward singly-linked list implemented with nodes, pointer to
root, and the such. You are making a good point that adding one 1-2
extra indirections would lead to improvements of certain primitives.
There have been various experiments with STL-like slist implementations
that dwell on such ideas. See e.g.
http://manpages.ubuntu.com/manpages/lucid/man3/std::forward_list.3cxx.html
with functions like before_begin() in addition to begin(), and also
insert_after() instead of insert().

It has become clear to STL implementors that adding hidden indirections
puts forward_list at a disadvantage compared to the straightforward
lists against which they compete. I want to avoid that by abiding to the
straight storage strategy and deal with its consequences.

Second post:


In fact, I'd say that it would be critical to split the insert and
remove functions to slow (O(n) or greater) versions and fast( O(lg(n)
or less)) functions.  Some algorithms may depend on fast insertion
and removal, such as mergesort on a linked list.


This is a good idea, which generalizes linearRemove(). I'd suspected if
there's one place to distinguish linear from better, then there ought to
be more.

From here we have a fork in the road:

a) Tighten complexity requirements for e.g. insertBefore(Range, Stuff)
and let containers that can't implement them just not have them.

b) Define linearInsertBefore(Range, Stuff) etc.

I'm leaning towards (a) because a list can insert virtually anywhere by
only using insertAfter(Take!Range, Stuff) (which I haven't defined yet
but I will, and which also takes care of the complexity issue) and 
insertFront(Stuff).


Third post:


Actualy mergesort could not be implemented without some sort of way
to restructure the list without allocating new nodes, requiring
knowledge of the link structure.  I'm not sure it could be
generic... I'll think about this a bit.


You are entirely right. A mergesort that relies on link shuffling needs
to have intimate knowledge of the node structure. It would most likely
be a member of the list.

Fourth post:


I have another general question in general about these collections.

Ranges fix a very bad problem with iterators -- non-matching begin
and end iterators.  For example, passing a begin from one list and
and end from another.


Right.


However, all your range functions such as remove, insertBefore, etc.
are called via the container type, using a range as an argument.  But
there can be no static verification that a range actually is part of
a given container.  Should there be some requirement that a container
validates that a range is part of the container before performing the
operation?  This is the case for dcollections.

In your current implementation of SList, verification seems
incidental for insertBefore because you must find the previous node
from the root anyways (and that will throw on enforce if it cannot
find it).  But insertAfter does not, so something like this will
compile, run, and result in strange behavior:

auto sl1 = make(SList!int, 1, 2, 3, 4, 5); // I may not have this
correct, but it's not important auto sl2 = make(SList!int, 6, 7, 8,
9, 10);

auto r1 = sl1[]; r1.popFront(); r1.popFront();

auto r2 = take(r1, 2); sl2.insertAfter(r2, 666); // actually inserts
into sl1


It's a good question.

My current view of the matter is to maximize library flexibility and 
versatility. Following the adage that you can build safe on fast but not 
the other way around, I'd go with the following philosophy: checking of 
range membership to their collections should be made only to the extent 
of ensuring memory safety. Beyond that, if efficiency is in tension with 
verifiability (as is the case with your example above), leave it to the 
programmer or the supra-structure to 

Re: Bug fix week

2010-05-27 Thread Don

Stewart Gordon wrote:

Don wrote:
snip

IMHO, one of the most important bugs to fix is actually a spec bug:

4056 Template instantiation with bare parameter not documented

snip

Why single out that one?


Because it's a feature that is used in almost every non-trivial D2 
program, and the spec gives no hint that it even exists. Without it, you 
can't even make sense of many of the Phobos docs. It's an absolute 
disaster for anyone taking a first look at the language -- something 
which we expect to happen frequently in the next few weeks.


Re: container stuff

2010-05-27 Thread BLS

On 27/05/2010 06:06, Andrei Alexandrescu wrote:

std.container will not contain hot-swappable components. It will contain
components that could be used in some of the hot swaps. It's just one
level lower than what you are discussing.

That doesn't make it any more or less incompatible with dcollections.


Andrei


Thanks for taking the time to explain.
Whatever direction D collections will take, I think we all agree that 
collections are the missing link in D. Once done, I am convinced that 
a number of D2 add on libs will grow drastically.
Just can speak for myself, f.i.  creating a dock /undock, tabbed MDI GUI 
without having a solid collection lib is not really a pleasure..

Bjoern


Re: container stuff

2010-05-27 Thread bearophile
Don:
 Yes, but if I understand correctly, the only reason to have removeAny 
 _as a primitive_ is for speed. And iterating over the container followed 
 by a single removal is almost always going to be much faster.

Most things in Python are designed to be handy first, and fast later. So I 
doubt performance has has any significance in this small piece of Python design.

In both Python and D is pop() is useful because it allows your collection to 
represent coherently its decreased or increased number of items at all times 
(Andrei ha shown an example where you have to add and remove items 
continuously).

Bye,
bearophile


Re: To interface or not to interface

2010-05-27 Thread Martin Hinsch
== Quote from Steven Schveighoffer (schvei...@yahoo.com)'s article
 On Tue, 25 May 2010 23:29:34 -0400, Walter Bright
 newshou...@digitalmars.com wrote:
  Steven Schveighoffer wrote:
  On Mon, 24 May 2010 18:13:38 -0400, Walter Bright
  newshou...@digitalmars.com wrote:
 
  Steven Schveighoffer wrote:
  All an interface does is give an abstract representation of functions
  that are *already there*.  Removing the interface does not remove the
  functions that implemented the interface.
 
  Then why do interfaces need to be part of the collection component?
  Why can't the user add them if he wants them?
   How do you add an interface to a class?
 
  Define an interface who's member functions call the class' member
  functions.
 Quoting from earlier message:
Wrapping seems like it would add more overhead than just implementing
 the interface, especially since D's inliner has some strange restrictions.
 -Steve

I think the main problem is that adding an interface post-hoc on the user's side
is a cumbersome error-prone process. This problem has been avoided quite 
elegantly
by Go by the way, which allows interfaces to be applied to all types that
conform without requiring inheritance (can't resist to mention that I proposed
this exact approach some years ago (long before Go was released) in this news
group ;-) ).

cheers
Martin


Re: Static constructors in circularly imported modules - again

2010-05-27 Thread Michel Fortin

On 2010-05-27 09:57:30 -0400, Max Samukha spam...@d-coding.com said:

We cannot impose on the user of Q_OBJECT the requirement that a and b 
should not be circularly imported or that he has to manually call an 
initialization function etc.


Just a small note...

In the D/Objective-C bridge, I've resorted to lazy initialization for 
this kind of thing. This way there is no module constructors and 
circular imports work as expected. But it isn't thread-safe, and I 
expect it would be a pain to make lazy initialization thread-safe, 
although I haven't tried yet.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: std.container update

2010-05-27 Thread Pillsy
== Quote from Andrei Alexandrescu
(seewebsiteforem...@erdani.org)'s article:
 I just implemented a singly-linked list type to illustrate
 the container abstraction.
 http://erdani.com/d/phobos/std_container.html
 http://erdani.com/d/phobos/container.d
[...]
 Please let me know of how you find it.

One thing worries me a bit, but may be based on a misunderstanding
of how D's GC works. In dup, you allocate all the nodes at once as
an array and then go through them one by one setting their payload_
and next_ values to make the list.

My worry is that the array is allocated as a single block and
(presumably) GC'd as a single block. If I copy a 1000 element list
and then remove 999 elements from the front using removeFront(),
won't I end up leaking memory for the first 999 nodes?

Cheers,
Pillsy


Re: Static constructors in circularly imported modules - again

2010-05-27 Thread Max Samukha

On 27.05.2010 18:38, Michel Fortin wrote:

But it isn't thread-safe, and I
expect it would be a pain to make lazy initialization thread-safe,
although I haven't tried yet.


That has been the very point of this thread (no pun). In my other post I 
supplied a hack that uses two variables, shared and TLS, to reduce the 
cost of accessing the global. Not ideal at all but at least it requires 
synchronization only during the first access.


Re: container stuff

2010-05-27 Thread Bill Baxter
On Thu, May 27, 2010 at 5:44 AM, Don nos...@nospam.com wrote:
 bearophile wrote:

 Don:

 When is it better to do it that way, rather than just iterating over all
 elements, and then completely empty the container?
 (Just curious -- I'm having trouble thinking of a use case for this
 feature).

 I'm having troubles understanding why two persons have troubles seeing use
 cases for this feature :-)

 Iterating over the container and then emptying the container is two
 operations, you have to keep in mind to empty it, while if you pop items out
 of it progressively you just need to keep in mind to do one thing, and you
 avoid forgetting the final cleaning.

 Yes, but if I understand correctly, the only reason to have removeAny _as a
 primitive_ is for speed. And iterating over the container followed by a
 single removal is almost always going to be much faster.

 If, however, speed is not critical, removeAny can be a generic function --
 call removeFront() if present, else call removeBack().
 And your examples would work just fine with that.

 I'm having trouble identifying a use case where it needs to be a primitive.


Think of a graph algorithm where you add all the nodes you know about
to a Set.  Pop one, process it, and then add any nodes it's connected
to that you haven't seen yet back to the Set.  Repeat until nothing
left to pop.

--bb


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

bearophile wrote:

Stewart Gordon:

This is the one that needs fixing most of all:
http://d.puremagic.com/issues/show_bug.cgi?id=677


I don't think Walter will fix that bug.


So you suspect that he's going to leave D until the end of time as a 
language that cannot be implemented by third parties because the spec is 
incomplete?



If you think that bug is important for you,


And if I don't _think_ that it's important for _me_, but _know_ that 
it's important to _the community_, then what?


then I suggest you to find other people that agree with you, and 
write down the specs yourself (and then maybe Walter will read your 
document to tell you how to fix its errors).


By errors, do you mean:
* obvious typos?
* bits that don't coincide with how DMD does things?
* bits that don't coincide with how Walter intended it?
* bits that don't coincide with Walter's current opinion?
* something else?

This is the most voted bug, one of those votes is mine, but now I am 
not so sure Walter takes a look at the vote counts when he fixes 
bugs:

snip

So I'd suspected.  But then, what _does_ Walter use the votes for? 
After all, he advertised the feature

http://www.digitalmars.com/d/archives/digitalmars/D/announce/Vote_for_your_least_favorite_bug_s_14136.html

Stewart.


Re: std.container update

2010-05-27 Thread Andrei Alexandrescu

On 05/27/2010 11:01 AM, Pillsy wrote:

== Quote from Andrei Alexandrescu
(seewebsiteforem...@erdani.org)'s article:

I just implemented a singly-linked list type to illustrate
the container abstraction.
http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

[...]

Please let me know of how you find it.


One thing worries me a bit, but may be based on a misunderstanding
of how D's GC works. In dup, you allocate all the nodes at once as
an array and then go through them one by one setting their payload_
and next_ values to make the list.

My worry is that the array is allocated as a single block and
(presumably) GC'd as a single block. If I copy a 1000 element list
and then remove 999 elements from the front using removeFront(),
won't I end up leaking memory for the first 999 nodes?


There are indeed tradeoffs associated with allocation of nodes that way. 
Technically that's not a leak, but indeed the entire block will stay put 
for as long as at least one node in it it's used.


One improvement would be to put removed nodes in a static freelist to be 
used by all SLists of the same type in the current thread. In that case, 
remove becomes unstable.


I think I hastened a bit with that optimization, it's debatable and 
detracts from the main point of the discussion.



Andrei


Re: AAs of struct or array

2010-05-27 Thread Ali Çehreli

bearophile wrote:

I have noticed a significant speed difference between foo1 and foo2 (D2 code):

import std.c.stdio: printf;

int foo1(int x, int y) {
static int[int[2]] cache;
int[2] args = [x, y];
cache[args] = x;


Most of it comes from the use of that temporary. -O doesn't help either.

This makes foo1 only slightly slower than foo2:

// int[2] args = [x, y];
cache[[x, y]] = x;


return x;
}

int foo2(int x, int y) {
static struct Pair { int x, y; }
static int[Pair] cache;
Pair args = Pair(x, y);
cache[args] = x;
return x;
}

void main() {
enum int N = 600;
int tot;
foreach (x; 1 .. N)
foreach (y; 1 .. N)
tot += foo2(x, y); // use foo1 or foo2 here
printf(%d\n, tot);
}


Bye,
bearophile


Ali


Re: std.container update

2010-05-27 Thread Andrei Alexandrescu

Another update:

http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

I simplified the implementation (no more array allocation etc.), 
eliminated replace() and insertBefore() after convincing myself they are 
not a good fit for lists, and added linearRemove(Take!Range).


Take!Range seems to be the secret recipe for an enjoyable SList experience.

I'll follow up later with an Array sample implementation. Then on the 
radar are an associative container (probably a straight hash or a binary 
tree) and then TightSList and TightArray which use deterministic storage 
management.


I figured out a lot of stuff, and it seems to settle together quite nicely.


Andrei


Re: AAs of struct or array

2010-05-27 Thread Pelle

On 05/27/2010 02:33 PM, bearophile wrote:

I have noticed a significant speed difference between foo1 and foo2 (D2 code):

import std.c.stdio: printf;

int foo1(int x, int y) {
 static int[int[2]] cache;
 int[2] args = [x, y];
 cache[args] = x;
 return x;
}

int foo2(int x, int y) {
 static struct Pair { int x, y; }
 static int[Pair] cache;
 Pair args = Pair(x, y);
 cache[args] = x;
 return x;
}

void main() {
 enum int N = 600;
 int tot;
 foreach (x; 1 .. N)
 foreach (y; 1 .. N)
 tot += foo2(x, y); // use foo1 or foo2 here
 printf(%d\n, tot);
}


Bye,
bearophile


On my machine, foo1 takes around 9 times longer.

Why is this?


Re: Bug fix week

2010-05-27 Thread Don

Stewart Gordon wrote:

bearophile wrote:

Stewart Gordon:

This is the one that needs fixing most of all:
http://d.puremagic.com/issues/show_bug.cgi?id=677


I don't think Walter will fix that bug.


So you suspect that he's going to leave D until the end of time as a 
language that cannot be implemented by third parties because the spec is 
incomplete?


Bearophile seems to always be very pessimistic, for some reason.

This is the most voted bug, one of those votes is mine, but now I am 
not so sure Walter takes a look at the vote counts when he fixes bugs:

snip

So I'd suspected.  But then, what _does_ Walter use the votes for? After 
all, he advertised the feature
http://www.digitalmars.com/d/archives/digitalmars/D/announce/Vote_for_your_least_favorite_bug_s_14136.html 


The situation is a little more complex than bearophile thinks.
For the last six months or so, Walter has concentrated on making sure 
that all of the examples in TDPL will work correctly. This has involved 
implementing all of the new features. Most of the bugs which were fixed 
were submitted patches (though often Walter had to modify the patches).


Votes however are definitely not ignored.
If you search bugzilla, you'll find that there are 86 closed bugs which 
still have votes for them! Compared with 228 open bugs.

So the votes themeselves are far from up-to-date.




Re: Bug fix week

2010-05-27 Thread Steven Schveighoffer

On Thu, 27 May 2010 15:34:38 -0400, Don nos...@nospam.com wrote:


Votes however are definitely not ignored.
If you search bugzilla, you'll find that there are 86 closed bugs which  
still have votes for them! Compared with 228 open bugs.

So the votes themeselves are far from up-to-date.


Indeed, it would be nice if bugzilla reminded you that you have votes for  
closed bugs.  Every time I go to vote for a bug, I remove my votes from  
any closed bugs (which are obvious with the strikethrough text).  But I  
don't notice that until I go to vote for one.  If it reminded me every  
time I logged in that I have votes for closed bugs, then I might pay  
better attention.


-Steve


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

Don wrote:
snip

The situation is a little more complex than bearophile thinks.
For the last six months or so, Walter has concentrated on making sure 
that all of the examples in TDPL will work correctly. This has involved 
implementing all of the new features. Most of the bugs which were fixed 
were submitted patches (though often Walter had to modify the patches).


Votes however are definitely not ignored.
If you search bugzilla, you'll find that there are 86 closed bugs which 
still have votes for them! Compared with 228 open bugs.

So the votes themeselves are far from up-to-date.


What search, exactly, did you do to come up with those figures?

I get:

Status: UNCONFIRMED, NEW, ASSIGNED, REOPENED
Votes: 1
gives 257

Status: UNCONFIRMED, NEW, ASSIGNED, REOPENED
Votes: 2
gives 83

Status: RESOLVED, VERIFIED, CLOSED
Votes: 1
gives 64

Status: RESOLVED, VERIFIED, CLOSED
Votes: 2
gives 21

I'd be amazed if there's been that much change in the last hour.

Peculiarly, nothing with a WONTFIX resolution has any votes.

Stewart.


Re: AAs of struct or array

2010-05-27 Thread bearophile
Ali Çehreli:
 Most of it comes from the use of that temporary. -O doesn't help either.

Right. I will probably put this in Bugzilla, even if it's a low priority thing.

Bye,
bearophile


Method hiding

2010-05-27 Thread bearophile
While answering to Larry Luther in a long thread in D.learn:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learnarticle_id=19913

I have found an interesting difference that I didn't know between Java and D. 
Here I have reduced the test cases:


// Java code
class A {
void foo(A a) {}
}
class B extends A {
void foo(B b) {}

public static void main(String[] args) {
A a = new A();
B b = new B();
b.foo(a);
}
}



// D2 code
class A {
void foo(A a) {}
}
class B : A {
void foo(B b) {}
}
void main() {
A a = new A;
B b = new B;
b.foo(a);// comment this out and use warnings
}


If you comment out the last line in the D2 code, and you use warnings, DMD 
tells you at compile time:

test.d(5): Error: class test.B test.A.foo(A a) is hidden by B


If you uncomment that line DMD shows:

test.d(12): Error: function test.B.foo (B b) is not callable using argument 
types (A)
test.d(12): Error: cannot implicitly convert expression (a) of type test.A to 
test.B


While the Java code compiles and runs with no errors.
It seems in D the B.foo() hides A.foo() even if there is no overriding at all 
here.

The presence of that warning tells me this is not an implementation bug, D is 
designed this way on purpose. But what is the rationale behind this difference 
(that at best will puzzle Java programmers trying to use D)?

Bye,
bearophile


Re: Method hiding

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 17:00:08 -0400, bearophile bearophileh...@lycos.com  
wrote:



While answering to Larry Luther in a long thread in D.learn:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learnarticle_id=19913

I have found an interesting difference that I didn't know between Java  
and D. Here I have reduced the test cases:



// Java code
class A {
void foo(A a) {}
}
class B extends A {
void foo(B b) {}

public static void main(String[] args) {
A a = new A();
B b = new B();
b.foo(a);
}
}



// D2 code
class A {
void foo(A a) {}
}
class B : A {
void foo(B b) {}
}
void main() {
A a = new A;
B b = new B;
b.foo(a);// comment this out and use warnings
}


If you comment out the last line in the D2 code, and you use warnings,  
DMD tells you at compile time:


test.d(5): Error: class test.B test.A.foo(A a) is hidden by B


If you uncomment that line DMD shows:

test.d(12): Error: function test.B.foo (B b) is not callable using  
argument types (A)
test.d(12): Error: cannot implicitly convert expression (a) of type  
test.A to test.B



While the Java code compiles and runs with no errors.
It seems in D the B.foo() hides A.foo() even if there is no overriding  
at all here.


The presence of that warning tells me this is not an implementation bug,  
D is designed this way on purpose. But what is the rationale behind this  
difference (that at best will puzzle Java programmers trying to use D)?


This is actually the first question I posted on this newsgroup in 2007.   
It's called method hijacking, look for it on the D website for a  
thorough explanation.  Note that this is actually the default behavior in  
C++ (I didn't know until I asked the question and tried it, it's pretty  
obscure).


But the behavior is overridable, you can do this:

class B : A {
  alias A.foo foo;
  void foo(A a) {}
}

Which means also look at A for resolving foo.

However, doing this may lead to further issues.  I think if you had a  
class C that derived from B, calling B.foo(c) would result in an ambiguity  
without a cast.


-Steve


Re: Bug fix week

2010-05-27 Thread Don

Stewart Gordon wrote:

Don wrote:
snip

The situation is a little more complex than bearophile thinks.
For the last six months or so, Walter has concentrated on making sure 
that all of the examples in TDPL will work correctly. This has 
involved implementing all of the new features. Most of the bugs which 
were fixed were submitted patches (though often Walter had to modify 
the patches).


Votes however are definitely not ignored.
If you search bugzilla, you'll find that there are 86 closed bugs 
which still have votes for them! Compared with 228 open bugs.

So the votes themeselves are far from up-to-date.


What search, exactly, did you do to come up with those figures?

I get:

Status: UNCONFIRMED, NEW, ASSIGNED, REOPENED
Votes: 1
gives 257




I'd be amazed if there's been that much change in the last hour.


Figured it out -- I did my search using Deskzilla. Although it updates 
its local database very frequently, it turns out that it doesn't update 
the votes very often at all. So I was using stale vote figures.



Peculiarly, nothing with a WONTFIX resolution has any votes.


I think hardly anything has ever been closed with WONTFIX.




Re: Method hiding

2010-05-27 Thread bearophile
Steven Schveighoffer:

 This is actually the first question I posted on this newsgroup in 2007.

I am very late then, sorry for not asking this is D.learn.


 It's called method hijacking, look for it on the D website for a  
 thorough explanation.  Note that this is actually the default behavior in  
 C++ (I didn't know until I asked the question and tried it, it's pretty  
 obscure).

I have read this, about in the middle:
http://www.digitalmars.com/d/2.0/hijack.html
Thank you for the explanations and thanks to Walter for that page. I vaguely 
remember reading that page, but I did remember it only about free functions.
I appreciate D design here :-)


 But the behavior is overridable, you can do this:
 
 class B : A {
alias A.foo foo;
void foo(A a) {}
 }
 
 Which means also look at A for resolving foo.

OK.


 However, doing this may lead to further issues.  I think if you had a  
 class C that derived from B, calling B.foo(c) would result in an ambiguity  
 without a cast.

I will experiment some about this.

Thank you and bye,
bearophile


Bug: compiler crash when using module name twice

2010-05-27 Thread Matthias
I'm very new to D and misused the module identifier, I thought it would 
be the namespace/package name.


The dmd compiler v2.046 produces correct output (Error: module test 
from file xxx.d conflicts with another module test from file yyy.d), if 
multiple placement of same module identifier are in the root of the 
project, however it crashes, when the files are in a subfolder and does 
not display a proper error message.


The output is:
Assertion failure: 'mprev' on line 641 in file 'module.c'

Test case:
--main.d--
import std.stdio;

import folder.File1;
import folder.File2;

int main(char[][] args)
{
writefln(file2);
return 0;
}

--folder\File1.d--
module folder;

const char[] file1 = File1;

--folder\File2.d--
module folder;

const char[] file2 = File2;

Used Code::Blocks.


Re: Method hiding

2010-05-27 Thread bearophile
Steven Schveighoffer:

 However, doing this may lead to further issues.  I think if you had a  
 class C that derived from B, calling B.foo(c) would result in an ambiguity  
 without a cast.

This is D code:

import std.c.stdio: puts;

class A {
void foo(A a) { puts(A.foo); }
}

class B : A {
alias A.foo foo;
void foo(B b) { puts(B.foo); }
}

class C : B {}

void main() {
A a = new A();
B b = new B();
C c = new C();
b.foo(a); // Prints: A.foo
b.foo(c); // Prints: B.foo
}



A Java translation:


class A {
void foo(A a) {
System.out.println(A.foo);
}
}

class B extends A {
void foo(B b) {
System.out.println(B.foo);
}
}

class C extends B {
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
b.foo(a); // Prints: A.foo
b.foo(c); // Prints: B.foo
}
}


This time they both call the same methods, b.foo(c) calls B.foo(B), probably 
because C is closer to B than A in the hierarchy :-) In normal programs I'd 
like to avoid writing this code.

Bye,
bearophile


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

Don wrote:

Stewart Gordon wrote:

snip

Peculiarly, nothing with a WONTFIX resolution has any votes.


I think hardly anything has ever been closed with WONTFIX.


I get 61 as I look.  At the moment, about 7.5% of bugs filed here have 
any votes, so I'm not sure that 61 counts as hardly anything.


Stewart.


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

Steven Schveighoffer wrote:
snip
Indeed, it would be nice if bugzilla reminded you that you have votes 
for closed bugs.  Every time I go to vote for a bug, I remove my votes 
from any closed bugs (which are obvious with the strikethrough text).  
But I don't notice that until I go to vote for one.  If it reminded me 
every time I logged in that I have votes for closed bugs, then I might 
pay better attention.


Why do you feel the need to remove your votes from closed bugs when 
you're not about to place one on another bug?


This has been discussed extensively on Mozilla's own bugzilla:
https://bugzilla.mozilla.org/show_bug.cgi?id=27553

Stewart.


Re: Bug: compiler crash when using module name twice

2010-05-27 Thread Don

Matthias wrote:
I'm very new to D and misused the module identifier, I thought it would 
be the namespace/package name.


The dmd compiler v2.046 produces correct output (Error: module test 
from file xxx.d conflicts with another module test from file yyy.d), if 
multiple placement of same module identifier are in the root of the 
project, however it crashes, when the files are in a subfolder and does 
not display a proper error message.


Ouch! I hate it when newbies hit compiler crashes.
I've created a bug report:
http://d.puremagic.com/issues/show_bug.cgi?id=4242

Hope to create a patch for it in the next few days.



Re: Bug fix week

2010-05-27 Thread Lutger
Steven Schveighoffer wrote:

 On Thu, 27 May 2010 15:34:38 -0400, Don nos...@nospam.com wrote:
 
 Votes however are definitely not ignored.
 If you search bugzilla, you'll find that there are 86 closed bugs which
 still have votes for them! Compared with 228 open bugs.
 So the votes themeselves are far from up-to-date.
 
 Indeed, it would be nice if bugzilla reminded you that you have votes for
 closed bugs.  Every time I go to vote for a bug, I remove my votes from
 any closed bugs (which are obvious with the strikethrough text).  But I
 don't notice that until I go to vote for one.  If it reminded me every
 time I logged in that I have votes for closed bugs, then I might pay
 better attention.
 
 -Steve

What is the purpose of votes for closed bugs anyway? Should they not just get 
removed automatically?



Re: Bug fix week

2010-05-27 Thread Don

Lutger wrote:

Steven Schveighoffer wrote:


On Thu, 27 May 2010 15:34:38 -0400, Don nos...@nospam.com wrote:


Votes however are definitely not ignored.
If you search bugzilla, you'll find that there are 86 closed bugs which
still have votes for them! Compared with 228 open bugs.
So the votes themeselves are far from up-to-date.

Indeed, it would be nice if bugzilla reminded you that you have votes for
closed bugs.  Every time I go to vote for a bug, I remove my votes from
any closed bugs (which are obvious with the strikethrough text).  But I
don't notice that until I go to vote for one.  If it reminded me every
time I logged in that I have votes for closed bugs, then I might pay
better attention.

-Steve


What is the purpose of votes for closed bugs anyway? Should they not just get 
removed automatically?


The bug might get reopened?



Re: Bug fix week

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 18:09:48 -0400, Stewart Gordon smjg_1...@yahoo.com  
wrote:



Steven Schveighoffer wrote:
snip
Indeed, it would be nice if bugzilla reminded you that you have votes  
for closed bugs.  Every time I go to vote for a bug, I remove my votes  
from any closed bugs (which are obvious with the strikethrough text).   
But I don't notice that until I go to vote for one.  If it reminded me  
every time I logged in that I have votes for closed bugs, then I might  
pay better attention.


Why do you feel the need to remove your votes from closed bugs when  
you're not about to place one on another bug?


This has been discussed extensively on Mozilla's own bugzilla:
https://bugzilla.mozilla.org/show_bug.cgi?id=27553


I don't feel like pouring through a bugzilla discussion, but the reason is  
because I may have gone to vote for an issue, but found I was out of  
votes, and I want to keep my existing ones (or I had to cancel another bug  
vote in order to vote for the new one).  At a later time when one of my  
voted-for bugs gets resolved, then I can vote for the issue I couldn't  
vote on, or removed my vote from.


To this end, if bugzilla could remember bugs I unofficially voted for,  
that would be good too :)


-Steve


Re: Bug fix week

2010-05-27 Thread Stewart Gordon

Lutger wrote:
snip

What is the purpose of votes for closed bugs anyway? Should they not just get 
removed automatically?


On top of the reasons linked to in my previous reply:

- Many of us would probably like to be able to see which bugs they voted 
for have recently been fixed.
- Resolving a bug would reset its vote count to zero.  And so if it's 
reopened, voting would have to start again from scratch.
- As such, an unscrupulous person could remove all votes from a bug just 
by marking it resolved.


https://bugzilla.mozilla.org/show_bug.cgi?id=308505

Stewart.


Re: Bug: compiler crash when using module name twice

2010-05-27 Thread bearophile
Don:
 Ouch! I hate it when newbies hit compiler crashes.

This happens often. People that have more experience in D use it in the way it 
is meant to be used, so they follow the normal usage patterns, that are often 
tested enough (or have already known bugs).
But newbies sometimes use D features in ways they where not meant to be used, 
so they go out of the well walked down footpath (I don't know how this is 
written in English), so they can often find bugs.

Bye,
bearophile


[OT] Votes on resolved bugs (was: Bug fix week)

2010-05-27 Thread Stewart Gordon

Steven Schveighoffer wrote:
snip
I don't feel like pouring through a bugzilla discussion, but the reason 
is because I may have gone to vote for an issue, but found I was out of 
votes, and I want to keep my existing ones (or I had to cancel another 
bug vote in order to vote for the new one).  At a later time when one of 
my voted-for bugs gets resolved, then I can vote for the issue I 
couldn't vote on, or removed my vote from.


The best way to deal with that, IMO, would be for the bugmail to include 
a note like You have voted for this bug when the bug is resolved.  If 
it were done by an alert when you log in, either it would lose its 
effect or you would have to waste time checking the list to see whether 
it's just the same bug(s) that you've deliberately left your vote on as 
before.


Stewart.


Re: Bug: compiler crash when using module name twice

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 18:32:34 -0400, bearophile bearophileh...@lycos.com  
wrote:
out of the well walked down footpath (I don't know how this is written  
in English)


off the well beaten path :)

-Steve


Re: std.container update

2010-05-27 Thread Jonathan M Davis
I take it that Array is basically supposed to be std.container's version of 
C++'s vector or Java's ArrayList? If so, I would suggest that Array is not 
the best of names in that it would become very easy to confuse it with 
built-in arrays when discussing them (particularly in verbal communication 
where you can't see the capital A). Personally, I would have just gone with 
Vector, since it's a fairly standard name for that sort of container and 
wouldn't be confused with anything else. If you really want Array, that's 
fine - it should be clear enough when it's in code - but I would think that 
talking about it could easily be confusing enough that it wouldn't be the 
best of names.

- Jonathan M Davis


Re: std.container update

2010-05-27 Thread Simen kjaeraas

Jonathan M Davis jmdavisp...@gmail.com wrote:


wouldn't be confused with anything else. If you really want Array, that's
Personally, I would have just gone with Vector, since it's a fairly

standard name for that sort of container and wouldn't be confused with
anything else.

I take it you don't work in simulation or games, then? Don't do much linear
algebra?

While I understand the reasoning for it, I dislike the name vector for
arrays. A vector to me, is a geometric object with a length and magnitude,
not a random collection of whatevers.

--
Simen


Re: AAs of struct or array

2010-05-27 Thread bearophile
http://d.puremagic.com/issues/show_bug.cgi?id=4244


Re: std.container update

2010-05-27 Thread Andrei Alexandrescu

On 05/27/2010 06:28 PM, Jonathan M Davis wrote:

I take it that Array is basically supposed to be std.container's version of
C++'s vector or Java's ArrayList? If so, I would suggest that Array is not
the best of names in that it would become very easy to confuse it with
built-in arrays when discussing them (particularly in verbal communication
where you can't see the capital A). Personally, I would have just gone with
Vector, since it's a fairly standard name for that sort of container and
wouldn't be confused with anything else. If you really want Array, that's
fine - it should be clear enough when it's in code - but I would think that
talking about it could easily be confusing enough that it wouldn't be the
best of names.

- Jonathan M Davis


Good point. Other opinions?

Andrei


std.container update - now Array is in

2010-05-27 Thread Andrei Alexandrescu


http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

I defined Array as a straightforward implementation of the homonym 
abstraction. There are a few imperfect corners, but by and large I'm 
starting to believe it's becoming possible to write certain 
cross-container codes.



Andrei


Shared Class Variables

2010-05-27 Thread sybrandy

Evening.

I'm having a bit of a problem and I'm hoping someone can help.  I'm 
trying to create a class that is shared across threads.  The only 
purpose of this class is to write data to somewhere, though currently a 
file.  A single-threaded version of this works fine, however I can't 
seem to get the code to work correctly when dealing with multiple 
threads.  I've gotten sharing issues, compilation issues trying to 
figure out how to use a shared class correctly, and currently an 
exception occurring during class finalization.


So, my question is, what is the correct way to do this?  Would a class 
work or would a struct be better?  Perhaps a singleton?


Thanks.

Casey


Re: Shared Class Variables

2010-05-27 Thread BCS

Hello sybrandy,


Evening.

I'm having a bit of a problem and I'm hoping someone can help.  I'm
trying to create a class that is shared across threads.  The only
purpose of this class is to write data to somewhere, though currently
a file.  A single-threaded version of this works fine, however I can't
seem to get the code to work correctly when dealing with multiple
threads.  I've gotten sharing issues, compilation issues trying to
figure out how to use a shared class correctly, and currently an
exception occurring during class finalization.

So, my question is, what is the correct way to do this?  Would a class
work or would a struct be better?  Perhaps a singleton?



I don't know much about threading but I do know that D1 vs. D2 (you didn't 
say what version) makes a big difference. For example, in D2 globals are 
thread local by default where as in D1 they are not. 


Thanks.

Casey


--
... IXOYE





Re: std.container update

2010-05-27 Thread Leandro Lucarella
Andrei Alexandrescu, el 27 de mayo a las 20:06 me escribiste:
 On 05/27/2010 06:28 PM, Jonathan M Davis wrote:
 I take it that Array is basically supposed to be std.container's version of
 C++'s vector or Java's ArrayList? If so, I would suggest that Array is not
 the best of names in that it would become very easy to confuse it with
 built-in arrays when discussing them (particularly in verbal communication
 where you can't see the capital A). Personally, I would have just gone with
 Vector, since it's a fairly standard name for that sort of container and
 wouldn't be confused with anything else. If you really want Array, that's
 fine - it should be clear enough when it's in code - but I would think that
 talking about it could easily be confusing enough that it wouldn't be the
 best of names.
 
 - Jonathan M Davis
 
 Good point. Other opinions?

I always thought vector was a bad name choice in C++, I had that word
associated with what C++ calls a valarray (a physics vector).

I agree that Array is too generic for D, though, and unfortunately I don't
have a better suggestion, but you asked for other opinions ;)

BTW, what would be the point of an array/vector when you have built-in
arrays? If built-in arrays would be syntax sugar for a real library type,
like AAs, I can see as a good option using Array for that type, since
built-in arrays and the library Array would be the same thing.


-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
DETIENEN A PADRE, MADRE, TIOS Y ABUELOS: TODOS DEPRAVADOS
-- Crónica TV


Re: std.container update - now Array is in

2010-05-27 Thread Michel Fortin
On 2010-05-27 21:08:29 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org said:




http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

I defined Array as a straightforward implementation of the homonym 
abstraction. There are a few imperfect corners, but by and large I'm 
starting to believe it's becoming possible to write certain 
cross-container codes.


I don't get that:

@property void reserve(size_t e)

Why is reserve a property? You want it called like that?

array.reserve = 10;

I'm sure it's just an oversight.

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: std.container update - now Array is in

2010-05-27 Thread Andrei Alexandrescu

On 05/27/2010 09:27 PM, Michel Fortin wrote:

On 2010-05-27 21:08:29 -0400, Andrei Alexandrescu
seewebsiteforem...@erdani.org said:



http://erdani.com/d/phobos/std_container.html
http://erdani.com/d/phobos/container.d

I defined Array as a straightforward implementation of the homonym
abstraction. There are a few imperfect corners, but by and large I'm
starting to believe it's becoming possible to write certain
cross-container codes.


I don't get that:

@property void reserve(size_t e)

Why is reserve a property? You want it called like that?

array.reserve = 10;

I'm sure it's just an oversight.


Sorry, fixed now.

Andrei


Re: std.container update

2010-05-27 Thread Andrei Alexandrescu

On 05/27/2010 08:42 PM, Leandro Lucarella wrote:

Andrei Alexandrescu, el 27 de mayo a las 20:06 me escribiste:

On 05/27/2010 06:28 PM, Jonathan M Davis wrote:

I take it that Array is basically supposed to be std.container's version of
C++'s vector or Java's ArrayList? If so, I would suggest that Array is not
the best of names in that it would become very easy to confuse it with
built-in arrays when discussing them (particularly in verbal communication
where you can't see the capital A). Personally, I would have just gone with
Vector, since it's a fairly standard name for that sort of container and
wouldn't be confused with anything else. If you really want Array, that's
fine - it should be clear enough when it's in code - but I would think that
talking about it could easily be confusing enough that it wouldn't be the
best of names.

- Jonathan M Davis


Good point. Other opinions?


I always thought vector was a bad name choice in C++, I had that word
associated with what C++ calls a valarray (a physics vector).

I agree that Array is too generic for D, though, and unfortunately I don't
have a better suggestion, but you asked for other opinions ;)

BTW, what would be the point of an array/vector when you have built-in
arrays? If built-in arrays would be syntax sugar for a real library type,
like AAs, I can see as a good option using Array for that type, since
built-in arrays and the library Array would be the same thing.


This is a good question. The relationship between Array and T[] is simple:

* Array is a compliant container so it is a reference type

* T[] is Array's range

With built-in associative arrays the question becomes even more 
interesting because the associative array _is_ already a reference type. 
So Walter and I agreed to make built-in associative arrays just 
compliant std.container objects, with three differences:


* AssocArray lives in object.di for various reasons

* The compiler translates the type name V[K] as AssocArray!(K, V)

* The compiler translates associative array literals into associative 
array objects


Other than that... an associative array will be just one of the growing 
offering of collections in std.container. And I think that's the way it 
should be.



Andrei



problem with reduce on array of Tuples

2010-05-27 Thread Adrian Matoga
The following code fails to compile:

double sim(Document doc, string query)
{
alias Tuple!(double, wij, double, wiq) Weights;
Document q = Document.fromString(query);
Weights[] wi;
foreach (s; StrFilt(query))
wi ~= Weights(doc.termFreq(s) * invDocFreq(s), q.termFreq
(s) * invDocFreq(s));
return
reduce!((double acc, Weights w) { return acc + 0; /*w.wij
* w.wiq;*/ })(0.0, wi) /
(sqrt(reduce!((double acc, Weights w) { return acc + 0; /
*sqr(w.wij);*/ })(0.0, wi) *
 sqrt(reduce!((double acc, Weights w) { return acc + 0; /
*sqr(w.wiq);*/ }(0.0, wi);
}

and DMD 2.046 shows the following messages:
ir.d(119): Error: delegate std.algorithm.__dgliteral3 cannot access
frame of fun
ction __dgliteral3
ir.d(232): Error: template instance ir.Index.sim.Reduce!(delegate
double(double
acc, Tuple!(double,wij,double,wiq) w)
{
return acc + 0;
}
) error instantiating
ir.d(119):instantiated from here: reduce!(delegate double
(double acc, Tu
ple!(double,wij,double,wiq) w)
{
return acc + 0;
}
)


Is it my fault because of some misunderstanding or other error, or
should I report it as a bug in compiler/library?
The same function compiled well with reduce on StrFilt(query) instead
of Weights.

I attach the full source.
begin 644 ir.d
M:6UP;W)T('-T9YS=1I;SL-FEM]R=!S=0NW1R:6YG.PT*:6UP;W)T
M('-T9YC;VYV.PT*:6UP;W)T('-T9YF:6QE.PT*:6UP;W)T('-T9YM871H
M.PT*:6UP;W)T('-T9YA;=OFET:T[#0II;7!OG0@W1D+G1Y5C;VYS
M.PT*#0I4('-QBA4*2A4('@I#0I[#0H)F5T=7)N('@@*B!X.PT*?0T*#0IC
M;%SR!3='):6QT#0I[#0H)W1A=EC()O;VQ;W1R:6YG72!PF5PSL-
M@T*7-T871I8R!T:ES*D-@E[#0H)69OF5A8V@@*'-Tc...@6r`b(BP@
M(F$B+`B=AE(BP@(G=H870B+`B8GDB+`B;V8B+`B86YD(BP@(F]R(BP@
M(G1O(BP@(F9R;VTB+`B9\B+`B65S(BP@(FYO(BP@(FYO=(L()B=70B
M+`B:70B+`B:6XB+`B:2(L()Y;W4B+`B:4B+`BVAE(BP@(G1H97DB
M+`B86TB(%TI#0H)7L-@D)7!R97!S6W-TET@/2!TG5E.PT*0E]#0H)
M?0T*#0H)W1A=EC(]P0V%L;AS=')I;F@;EN92D-@E[#0H)7)E='5R
M;B`N9FEL=5R(2...@h82d@R!R971Uf...@82`a:6X@')E',[('TI*'-P;ET
M*QI;F4N=]L;W=EBYTb...@b82uz(BP@(B`B+`B8R(I+G-TFEP*2D[#0H)
M?0T*?0T*#0IC;%SR!$;V-U;65N=`T*PT*7-TFEN9R!F:6QE;F%M93L-
M@EU:6YT('=OF1S.PT*75I;G1;W1R:6YG72!FF5QSL-@EU:6YT(UA
M$9R97$[#0H)#0H)=F]I9!A91,:6YE*'-TFEN9R!L:6YE*0T*7L-@D)
M9F]R96%C:`h=v]r...@4w1r1fel=AL:6YE*2D-@D)PT*0D)*RMFF5Q
MUMW;W)D73L-@D)?0T*7T-@T*79O:6...@8v%l8tua$9R97$H*0T*7L-
M@D);6%X1G)E2`](UI;E!OR$H(F$@/B!B(BDH9G)E7,N=F%L=65S*5LP
M73L-@E]#0H-@ES=%T:6,@1]C=6UE;g...@9g)O;49I;4HW1R:6YG(9I
M;5N86UE*0T*7L-@D)1]C=6UE;g...@9]C(#T@;F5W($1O8W5M96YT.PT*
M0ED;V,N9FEL96YA;64@/2!F:6QE;F%M93L-@D)875T;R!F:6QE(#T@;F5W
M($9I;4H9FEL96YA;64L()R(BD[#0H)69OF5A8V@@*QI;F4[(9I;4N
M8GE,:6YE*0T*0E[#0H)0ED;V,N861D3EN92AT;R%S=')I;FH;EN92DI
M.PT*0E]#0H)61O8RYC86QC36%X1G)E3L-@D)F5T=7)N(1O8SL-@E]
M#0H)#0H)W1A=EC($1O8W5M96YT(9R;VU3=')I;FHW1R:6YG('-TBD-
M@E[#0H)41O8W5M96YT(1O8R`](YE=R!$;V-U;65N=#L-@D)9]C+F%D
M9$QI;F4HW1R*3L-@D)9]C+F-A;--87AF5Q.PT*0ER971Uf...@9]C
M.PT*7T-@T*61O=6)L92!T97)M1G)E2AS=')I;F@=5R;2D-@E[#0H)
M6EF(AT97)M(%I;B!FF5QRD-@D)7)E='5R;B`P+C`[#0H)7)E='5R
M;B!C87-T*1O=6)l...@9g)E7-;=5R;5...@+r!m87aF5Q.PT*7T-@D-
M@EO=F5RFED92!S=')I;F@=]3=')I;FH*0T*7L-@D)F5T=7)N(9I
M;5N86UE.PT*7T-GT-@T*8VQAW,@26y...@-GL-@E$;V-U;65N=%M=
M6W-TFEN9UT@:6y...@[#0h)8F]O;%M$;V-U;65n...@9]CSL-@T*79O
M:6...@861d*$1o8w5m96yt(1O8RD-@E[#0H)6EF(AD;V,@:6...@9]CRD-
M@D)7)E='5R;CL-@D)9]CUMD;V-=(#...@=')U93L-@D)9F]R96%C:`H
M:V5Y+!v86qu...@9]C+F9R97%S*0T*0E[#0H)0EI;F1E%MK97E=('X]
M(1O8SL-@D)?0T*7T-@D-@ED;W5B;4@:6YV1]C1G)E2AS=')I;F@
M=5R;2D-@E[#0H)6EF(AT97)M(%I;B!I;F1ED-@D)7)E='5R;B`P
M.PT*0ER971UFX@;]G*-AW0H9]U8FQE*2!D;V-S+FQE;F=T:`O(EN
M95X6W1EFU=+FQE;F=T:D[#0H)?0T*#0H)9]U8FQE('-I;2A$;V-U;65N
M=!D;V,L('-TFEN9R!Q=65R2D-@E[#0H)6%L:6%S(%1UQE(2AD;W5B
M;4L()W:6HB+!D;W5B;4L()W:7$B*2!796EG:'1S.PT*0E$;V-U;65N
M=!Q(#...@1]C=6UE;G0N9G)O;5-TFEN9RAQ=65R2D[#0H)5=E:6=H='-;
M72!W:3L-@D)9F]R96%C:`Hs...@4w1r1fel=AQ=65R2DI#0H)0EW:2!^
M/2!796EG:'1S*1O8RYT97)M1G)E2AS*2`J(EN=D1O8T9R97$HRDL('$N
M=5R;49R97$Hr...@*b!i;G9$;V-F5Q*',I*3L-@D)F5T=7)N(`T*0D)
MF5D=6-E(2...@h9]U8FQE(%c...@5v5i9vatR!W*2![(')E='5R;B!A8V,@
M*R`P.R`O*GN=VEJ(h...@=ryw:7$[...@?2dh,XP+!W:2...@+pt*0D)*'-Q
MG0HF5D=6-E(2...@h9]U8FQE(%c...@5v5i9vatR!W*2![(')E='5R;B!A
M8V,@*R`P.R`O*G-QBAW+G=I:bd[...@?2dh,XP+!W:2...@*b!s7)T*')E
M9'5C92$H*1O=6)L92!A8V,L(%=E:6=H=',@=RD@R!R971Uf...@86-c(L@
M,#...@+ris7(H=RYW:7$I.RHO('TH,XP+!W:2DI*2DI.PT*7T-@D-@ED
M;W5B;5;1]C=6UE;G1=(')E=')I979E*'-TFEN9R!Q=65R2D-@E[#0H)
M61O=6)L95M$;V-U;65N=%T@F5S=6QT.PT*0EF;W)E86-H(AD;V,L(([
M(1O8W,I#0H)7L-@D)7)EW5L=%MD;V-=(#T@VEM*1O8RP@75EGDI
M.PT*0E]#0H)7)E='5R;B!R97-U;'0[#0H)?0T*?0T*#0II;G0@;6%I;BAS
M=')I;F=;72!AF=S*0T*PT*6%U=\@:6YD97@@/2!N97@26y...@[#0h)
M;ES=1Ib...@b9]CR(L(1E;5G871E()O;v...@*$1iD5N=')Y*B!D92D@
MPT*0EWFET96QN*1E+FYA;64I.R`-@D):6y...@n861d*$1o8w5m96yt
M+F9R;VU:6QE*1E+FYA;64I*3L-@D)F5T=7)N('1R=64[#0H)?0DI.PT*
M0T*69OF5A8V@@*8[(A3='):6QT*%R9W-;,5TI*2D@R!WFET96QN
M*8I.R!]#0H)9F]R96%C:`H:r...@=cl@:6y...@nF5TFEE=F4H87)GULQ
M72DI#0H)PT*0EWFET969L;b...@b)7,@+3X@)7,B+!K+!V*3L-@E]#0H)
,F5T=7)N(#`[#0I]
`
end


Re: Finding and invoking struct destructors in D2

2010-05-27 Thread div0
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Pillsy wrote:
 Hi, all,
 
 I was wondering if there's any way to determine at compile time
 whether a struct has a (non-trivial) destructor associated with it,
 and whether there's any way to call that destructor without using
 the delete operator. It seems like being able to do these two
 things would allow you to make a container that plays well with
 structs that are designed to do (say) reference counting, but I
 don't see anything in the spec on the website that shows how this
 might be accomplished.
 
 Thanks!
 Pillsy

Struct and class destructors are called __dtor.
This is undocumented though and therefore not guaranteed to work in
future versions or other(!) implementations:

struct foo {
~this()
{
}
}

int main(){

foo b;

static if(__traits(compiles, b.__dtor()))
{
pragma (msg, got destructor);
}
else
{
pragma (msg, no destructor);
}

return 0;
}


There are various struct destructor bugs still open though, so I
wouldn't count on being able to do a ref counted objects at the moment:

Most important is this one, which scuppers any change of doing a shared
ptr like struct:

http://d.puremagic.com/issues/show_bug.cgi?id=3516

- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFL/rG7T9LetA9XoXwRAkcyAJ9e/nXmNanAC9L4m6oCRbSk+EruzACfRgOJ
j0xFjV7F4Onz3rSFXeUkq+k=
=1nFQ
-END PGP SIGNATURE-


Re: Finding and invoking struct destructors in D2

2010-05-27 Thread Pillsy
== Quote from div0 (d...@users.sourceforge.net)'s article:
[...]
 Most important is this one, which scuppers any change of doing
 a shared ptr like struct:

 http://d.puremagic.com/issues/show_bug.cgi?id=3516

Yeah, that basically kills the idea until the bug is fixed. :(

Once it is, I think a hasDestructor template would be a good thing
to have in the standard library.

Cheers,
Pillsy


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther
Thank you, I had no idea that scope was doing this.
I thought that when the docs said that it was being allocated on the stack
that I was getting struct like behavior.

Simen kjaeraas simen.kja...@gmail.com wrote in message 
news:op.vc0qlpjovxi...@biotronic-pc.home...
| Larry Luther larry.lut...@dolby.com wrote:
|
| 
|scope B
|  alpha = new B;
| 
|
| 'scope B alpha;' allocates stack space for a reference to a B, and
| space for an instance of B. If the pointer changes, it is simply no longer
| referencing the instance on the stack.
|
| -- 
| Simen 




Re: Finding and invoking struct destructors in D2

2010-05-27 Thread Don

div0 wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Pillsy wrote:

Hi, all,

I was wondering if there's any way to determine at compile time
whether a struct has a (non-trivial) destructor associated with it,
and whether there's any way to call that destructor without using
the delete operator. It seems like being able to do these two
things would allow you to make a container that plays well with
structs that are designed to do (say) reference counting, but I
don't see anything in the spec on the website that shows how this
might be accomplished.

Thanks!
Pillsy


Struct and class destructors are called __dtor.
This is undocumented though and therefore not guaranteed to work in
future versions or other(!) implementations:

struct foo {
~this()
{
}
}

int main(){

foo b;

static if(__traits(compiles, b.__dtor()))
{
pragma (msg, got destructor);
}
else
{
pragma (msg, no destructor);
}

return 0;
}


There are various struct destructor bugs still open though, so I
wouldn't count on being able to do a ref counted objects at the moment:

Most important is this one, which scuppers any change of doing a shared
ptr like struct:

http://d.puremagic.com/issues/show_bug.cgi?id=3516


Yup, that's #3 on my list of Ten Must-fix Bugs.

This related one is pretty bad too.
 http://d.puremagic.com/issues/show_bug.cgi?id=3323



- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFL/rG7T9LetA9XoXwRAkcyAJ9e/nXmNanAC9L4m6oCRbSk+EruzACfRgOJ
j0xFjV7F4Onz3rSFXeUkq+k=
=1nFQ
-END PGP SIGNATURE-


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther
bearophile bearophileh...@lycos.com wrote in message 
news:ht4g3r$vu...@digitalmars.com...
| Larry Luther:
|
|  I did not get an error when building and running with DMD 2.042:
|
| I am using dmd v2.046, and I have taken the good habit of compiling 
with -w (warnings on).
| It seems this error I see is a blocking warning. It's a warning badly 
written, but do you agree it is saying something important? I presume your 
code can lead to bugs. I don't know why this is a warning instead of a true 
error...
|
| On your code it also complains for a missed override that is a good 
thing that eventually will become obligatory even without -w.
|
| When you post here I suggest you to avoid using HTML and use pure text.
|
| Bye,
| bearophile

Ok, I've added -w to compilation commands and I've switched back to pure 
text.

Given:

class A {
  int x, y;

  void copy (const A a) {
x = a.x;
y = a.y;
  }
}

class B : A {
  int z;

  void copy (const B b) {
super.copy( b);
z = b.z;
  }
}

A alpha = new A;
A bravo = new A;

B charlie = new B;
B delta = new B;

---

I don't see the problem with A.copy vs B.copy.
  alpha.copy( bravo)-- should execute A.copy
  alpha.copy( charlie)  -- should execute A.copy
  charlie.copy( delta)  -- should execute B.copy
  charlie.copy( alpha)  -- should execute A.copy

What am I missing?

Larry




Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Larry Luther:

I'm nonplussed. Could you expand on why D class instances don't need to copy 
their contents and instances of D structs do?  While migrating C++ code to D 
I've had to convert structs to classes because of the need for inheritance. 
 Why would the need to copy an instance's contents to another instance 
disappear?

You are an experienced programmer, so if you think well about this topic you 
can probably understand the situation and the purposes behind D design as well 
or better than me. You probably know already what I can tell you about this 
topic.

D is different from C++, it's GC-based, and this changes many things and the 
way they have to be designed and used. D is designed to be a little simpler 
than C++, this means in some cases it prefers to do something in a safer way, 
instead in the most efficient way. D doesn't follow the zero overhead policy of 
C++, because it can lead to hairy code and because Java and C# have plenty 
shown it's often a waste of programmers time with no real performance gain.

In D structs don't support inheritance because they are designed to avoid the 
slicing bug, to be simpler, to be Plain Old Data. So D is designed to have 
different classes and structs because their usage style and purposes are 
different. When more complexity is needed, classes are there to be used. Even 
if currently DMD is not very good at optimizing away the class-derived 
overhead, better future D compilers can solve this. For some situations there's 
even the scope (that Walter is not so sure to keep, while other people like 
me have suggested the opposite, that is to extend its purpose to allocate an 
object inside the memory of another object) that can help performance. In Java 
the HotSpot is able to perform Escape Analysis on objects to avoid many heap 
allocations, and LDC is able to detect some simple cases and do the same.

By design D has no standard way to copy classes. I have not written very large 
object oriented D programs, but from what I have seen, I generally don't need 
to copy objects. I have often the need to move them around, put them in a 
collection, pull them out and put them in another collection, or create them in 
single instance, and so on. But I don't remember the last time I've had to copy 
a class instance in D. I just copy and add and remove class references. When I 
want I can keep many references to the same object and so on. In C++ programs 
this has to be done with care, because there is no GC, or you need some kind of 
smart pointer, while in D (in theory) you can relax and just let the GC do its 
thing.

My experience tells me that when you try to translate a program written in 
language X to language Y you always find some impedance (unless X and Y are 
almost the same language). But most times in language Y there are ways to solve 
the problem in a different way. You, as programmer, have to learn the way Y 
programs are usually written, its idioms and to avoid to force X idioms in Y 
and then complain that X idioms are not well represented in Y.

D design is far from perfect, and in future some things will probably need to 
be fixed (I have written enough text to fill two books about D features that 
can enjoy some change), but behind its design there is also lot of thought. So, 
you can show us some D code where you think there is a need to copy objects. If 
such uncommon need arises you can usually write your own copy functions.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Larry Luther:

Ok, I've added -w to compilation commands and I've switched back to pure text.

Good :-)


What am I missing?

I have modified a bit your D code like this, to have something with a main() 
that runs:


import std.c.stdio: puts;

class A {
int x, y;

void copy(const A a) {
puts(A copy);
x = a.x;
y = a.y;
}
}

class B : A {
int z;

void copy(const B b) {
puts(B copy);
super.copy(b);
z = b.z;
}
}

void main() {
A a1 = new A;
A a2 = new A;

B b1 = new B;
B b2 = new B;

a1.copy(a2); // should execute A.copy
a1.copy(b1); // should execute A.copy
b1.copy(b2); // should execute B.copy
b1.copy(a1); // should execute A.copy
}



I have also translated your the code to Java, because sometimes Java designers 
are more correct thant D designers:


class A {
int x, y;

void mycopy(A a) {
System.out.println(A mycopy);
x = a.x;
y = a.y;
}
}

class B extends A {
int z;

void mycopy(B b) {
System.out.println(B mycopy);
super.mycopy(b);
z = b.z;
}

public static void main(String[] args) {
A a1 = new A();
A a2 = new A();

B b1 = new B();
B b2 = new B();

a1.mycopy(a2); // should execute A.mycopy
a1.mycopy(b1); // should execute A.mycopy
b1.mycopy(b2); // should execute B.mycopy
b1.mycopy(a1); // should execute A.mycopy
}
}


The Java code compiles and runs with no errors, and prints:
A mycopy
A mycopy
B mycopy
A mycopy
A mycopy


But the D version is different. It seems you have found a small difference 
between Java and D that I didn't know about.

If I comment out the last line of the main() in the D code (b1.copy(a1);) and I 
compile the D code with -w it generates the warning I was talking about:

test.d(13): Error: class test.B test.A.copy(const const(A) a) is hidden by B


If I leave that line uncommented then the compilation stops with a different 
error:

test.d(33): Error: function test.B.copy (const const(B) b) is not callable 
using argument types (A)
test.d(33): Error: cannot implicitly convert expression (a1) of type test.A to 
const(B)

It seems in D the copy() of B replaces (hides) the copy() of A, even if no 
override is used. I don't know why D is designed this way, it can even be a 
design/implementation bug. But the presence of that warning suggests me this is 
expected, so it's probably just a difference between Java and D. If no one 
answers to this here then maybe later I will ask about this in the main D group.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
See:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=110554


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther
bearophile bearophileh...@lycos.com wrote in message 
news:ht4krg$17l...@digitalmars.com...
| On the base of your long experience do you like D so far?

There are many things that I like and I strongly agree with the failings
of C++ mentioned in the docs.  I don't like the asymmetry between structs
and classes.  I don't see why structs can't have inheritance.  I haven't
had a memory leak problem in C++ for many years so the need for a GC seems 
minor.
I can only assume that it's needed to support strings and dynamic arrays.
I'm pushing forward on the assumption that I'll discover the paradigm that
will make everything fall into place.  It's hard to get the proper picture
from the documentation available on Digital-mars.  Tango with D didn't
significantly help either.  For example it took a great deal of time to 
learn
that private can be used several ways:

  private member_function () {)

  private {
member_function () {}
  }

  private:
member_function () {}

  I'm anxiously waiting for something of the quality of the Annotated C++ 
Reference Manual.

Larry 




Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Larry Luther:

 There are many things that I like and I strongly agree with the failings
 of C++ mentioned in the docs.

D is designed by people that have a good experience of C++, but while probably 
D avoids some C++ problems, it surely introduces a number of new issues :-)


 I don't like the asymmetry between structs
 and classes.  I don't see why structs can't have inheritance.

One of the first answers given here is that this D design avoids slicing bugs. 
See my other answer for more.


 I haven't
 had a memory leak problem in C++ for many years so the need for a GC seems 
 minor.
 I can only assume that it's needed to support strings and dynamic arrays.

A GC introduces other kind of leaks when there is a reference alive to an 
memory block that is supposed to be dead and not used any more. This can even 
be caused by the not precise nature of the current D GC, it can mismatch 
something for a pointer to a GC-managed memory zone, keeping it alive. For 
example in programs that use large associative arrays this seems a problem.

If you assume the presence of the GC this changes the way you write code. In 
theory you can be more relaxed. In practice D GC is not... well, you have to 
keep your eyes open anyway.


 I'm pushing forward on the assumption that I'll discover the paradigm that
 will make everything fall into place.

If you have some Java programming experience then you probably have nothing to 
discover regarding this aspect of D programming (here the main difference is 
that Oracle Java GC is more precise and quite more efficient).


 For example it took a great deal of time to 
 learn that private can be used several ways:

One of the good things of D design is that it tries to be uniform/consistent, 
in this case all other attributes can be used in the same ways :-)


   I'm anxiously waiting for something of the quality of the Annotated C++ 
 Reference Manual.

The problem here is that D is not very strictly defined in the first place, so 
it's harder to write a very strict D reference manual :-) But Andrei book is 
about to come out, that can be seen as a kind of official D2 reference.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 17:04:35 -0400, Larry Luther larry.lut...@dolby.com  
wrote:



bearophile bearophileh...@lycos.com wrote in message
news:ht4krg$17l...@digitalmars.com...
| On the base of your long experience do you like D so far?

There are many things that I like and I strongly agree with the failings
of C++ mentioned in the docs.  I don't like the asymmetry between structs
and classes.  I don't see why structs can't have inheritance.


Because of the slicing problem.  It's basically something like this:

struct A {virtual void foo();};

struct B : A {virtual void foo();};

void bar(A a)
{
  a.foo();
}

void baz()
{
  B b;
  bar(b); // b is sliced down to an A, and bar will now call A.foo  
instead of the expected B.foo.

}

The really bad part about this is, b might have set up its private  
variables so that to call A.foo would cause an error.


Same thing happens when returning by value.  The general issue is that  
inheritance and value types don't mix.  But reference types (that is,  
types that are always passed by reference) never have the slicing  
problem.  So classes in D (which are reference types) can inherit, while  
structs (which *can be* value types) cannot inherit.  I have hoped that at  
some point, structs can be auto-composed, without a vtable, but you still  
have to do this manually.  Luckily, it's not so much of a chore now that  
alias this is around.



 I haven't
had a memory leak problem in C++ for many years so the need for a GC  
seems

minor.
I can only assume that it's needed to support strings and dynamic arrays.
I'm pushing forward on the assumption that I'll discover the paradigm  
that

will make everything fall into place.


Yes, what it took for me is to write a project in C++ that could really  
have used a GC.


Essentially, here was my issue:

I had a protocol implemented with various messages with a function  
readMessage, which returned a newly-allocated message (which was a  
derivative of some base message type).  Then I used RTTI to cast the  
message to the right type to deal with the data.  However, what sucked is  
how I always had to free the message after receiving it.  I really just  
wanted to process the message and go to the next one.  A GC is great for  
this because memory management is not strewn throughout your code, you  
don't have to remember to free things you should free and leave things you  
should not.  On top of that, in my case, I had to figure out that I was  
responsible for freeing a message via documentation -- the language didn't  
really tell me.  In D, no matter where it comes from, you just forget  
about it, and whoever is responsible (GC or owner) cleans it up later.  It  
makes for much more readable and less error-prone code.


There are many other designs which work well with GC, and some which don't.

D has some power over the memory management so you can force your will  
upon it, but I've found that the best way to write D code is to embrace  
the GC.


Note also that memory leaks are not the worst problem with non-GC code.   
Freeing memory you weren't supposed to is worse.


  I'm anxiously waiting for something of the quality of the Annotated  
C++

Reference Manual.


The D Programming Language is hitting bookstores soon, I think it will be  
a very good reference and educational book.


-Steve


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Steven Schveighoffer:
 I have hoped that at some point, structs can be auto-composed,
 without a vtable, but you still have to do this manually.

I don't understand what you mean here :-)

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Ali Çehreli

bearophile wrote:

Larry Luther:


Ok, I've added -w to compilation commands and I've switched back to pure text.


Good :-)



What am I missing?


I have modified a bit your D code like this, to have something with a main() 
that runs:


import std.c.stdio: puts;

class A {
int x, y;

void copy(const A a) {
puts(A copy);
x = a.x;
y = a.y;
}
}

class B : A {
int z;

void copy(const B b) {
puts(B copy);
super.copy(b);
z = b.z;
}
}

void main() {
A a1 = new A;
A a2 = new A;

B b1 = new B;
B b2 = new B;

a1.copy(a2); // should execute A.copy
a1.copy(b1); // should execute A.copy
b1.copy(b2); // should execute B.copy
b1.copy(a1); // should execute A.copy
}



I have also translated your the code to Java, because sometimes Java designers are more 
correct thant D designers:


class A {
int x, y;

void mycopy(A a) {
System.out.println(A mycopy);
x = a.x;
y = a.y;
}
}

class B extends A {
int z;

void mycopy(B b) {
System.out.println(B mycopy);
super.mycopy(b);
z = b.z;
}

public static void main(String[] args) {
A a1 = new A();
A a2 = new A();

B b1 = new B();
B b2 = new B();

a1.mycopy(a2); // should execute A.mycopy
a1.mycopy(b1); // should execute A.mycopy
b1.mycopy(b2); // should execute B.mycopy
b1.mycopy(a1); // should execute A.mycopy
}
}


The Java code compiles and runs with no errors, and prints:
A mycopy
A mycopy
B mycopy
A mycopy
A mycopy


But the D version is different. It seems you have found a small difference 
between Java and D that I didn't know about.

If I comment out the last line of the main() in the D code (b1.copy(a1);) and I 
compile the D code with -w it generates the warning I was talking about:

test.d(13): Error: class test.B test.A.copy(const const(A) a) is hidden by B


If I leave that line uncommented then the compilation stops with a different 
error:

test.d(33): Error: function test.B.copy (const const(B) b) is not callable 
using argument types (A)
test.d(33): Error: cannot implicitly convert expression (a1) of type test.A to 
const(B)

It seems in D the copy() of B replaces (hides) the copy() of A, even if no 
override is used. I don't know why D is designed this way, it can even be a 
design/implementation bug. But the presence of that warning suggests me this is 
expected, so it's probably just a difference between Java and D. If no one 
answers to this here then maybe later I will ask about this in the main D group.

Bye,
bearophile


For what it's worth, here is a code that uses 'dup' instead of 'copy'. I 
know this is not the same thing; but I find this more intuitive:


import std.stdio;
import std.string;

class A
{
int x, y;

this(int x, int y)
{
this.x = x;
this.y = y;
}

A dup() const
{
writeln(A copy);
return new A(x, y);
}

override string toString() const
{
return format(A(%s,%s), x, y);
}
}

class B : A
{
int z;

this(int x, int y, int z)
{
super(x, y);
this.z = z;
}

override B dup() const
{
writeln(B copy);
return new B(x, y, z);
}

override string toString() const
{
return format(B(%s,%s,%s), x, y, z);
}
}

void main() {
A a1 = new A(1, 1);
A a2 = new A(2, 2);
B b1 = new B(11, 11, 11);
B b2 = new B(22, 22, 22);

a1 = a2.dup;
assert((a1.x == 2)  (a1.y == 2));

a1 = b1.dup;
assert((a1.x == 11)  (a1.y == 11));
assert(typeid(a1) == typeid(B));  // -- personality change

b1 = b2.dup;
assert((b1.x == 22)  (b1.y == 22)  (b1.z == 22));

// b1 = a1.dup; // -- ERROR because not all As are Bs;
//   but as we know that a1 is
//   actually a B at this point;
//   we can down cast:
assert(cast(B)a1 !is null);
b1 = (cast(B)a1).dup;
assert((b1.x == 11)  (b1.y == 11)  (b1.z == 11));

writeln(a1);
writeln(a2);
writeln(b1);
writeln(b2);
}

Ali


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 17:47:20 -0400, bearophile bearophileh...@lycos.com  
wrote:



Steven Schveighoffer:

I have hoped that at some point, structs can be auto-composed,
without a vtable, but you still have to do this manually.


I don't understand what you mean here :-)


I mean simple inheritance.  In C, there has always been manual  
inheritance.  You can see it with the sockaddr system, and even with the X  
toolkit widget system.


essentially, when you derive type B from type A in C++, you get this:

struct B
{
   A _a;
}

A is always put first, that way, a pointer to a B can always be used as a  
pointer to an A.


The other thing that happens is that function calls on B also use A as  
well.  This is not so easy in C, but in D it is currently quite trivial:


struct B
{
   A _a;
   alias _a this;
}

Then a call like b.methodOfA(); gets translated statically to  
b._a.methodOfA().


But there are things I don't like about this, such as you can *set* _a.   
To get around that, you define a property getter, but not a setter:


struct B
{
   private A _a;
   @property ref A a() {return _a;}
   alias a this;
}

What I would like is a common-sense approach to inheritance for structs  
that just does not allow virtual methods or interfaces, and which does not  
cast implicitly to the base (explicit cast is OK).  I think some designs  
would benefit greatly from this simple feature.  I think it's more tricky  
than I've described, but I think with some diligence it can be done.


-Steve


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 18:41:19 -0400, bearophile bearophileh...@lycos.com  
wrote:


Thank you Steven for your explanations, I have done similar things in C  
and D, but I didn't understand what you meant.


A is always put first, that way, a pointer to a B can always be used as  
a pointer to an A.


Are you sure C specs say doing this leads to defined behaviour?
(Recently from a discussion with Walter I have learnt that D follows  
exactly C specs regarding such defined/undefined things.)


Xt and the Berkeley sockets library relies on it.  If it's not in the  
spec, then it's a de-facto standard.  I think the defined behavior is that  
the first member of a struct is positioned at the same address as the  
struct itself.





What I would like is a common-sense approach to inheritance for structs
that just does not allow virtual methods or interfaces, and which does  
not

cast implicitly to the base (explicit cast is OK).  I think some designs
would benefit greatly from this simple feature.  I think it's more  
tricky

than I've described, but I think with some diligence it can be done.


I have desired some form of inheritance in D structs (before the  
creation of alias this, that so far I have not used much). I think  
Walter will not love this idea, but you can think more about its  
details, and then you can post it in the main D newsgroup.


Sadly, I think it is not much more than a wish.  I don't think Walter's  
mind can be changed on this.


-Steve


[Issue 4240] New: Array operations on short fixed-length arrays should be inlined

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4240

   Summary: Array operations on short fixed-length arrays should
be inlined
   Product: D
   Version: 1.020
  Platform: Other
OS/Version: Windows
Status: NEW
  Keywords: performance
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: clugd...@yahoo.com.au


--- Comment #0 from Don clugd...@yahoo.com.au 2010-05-26 23:19:03 PDT ---
If an array operation is performed on a short fixed-length array, for example:

float[3] x,y;
x[] += y[] * 4.0;

then it should not become a function call, it should simply be turned into:

x[0] += y[0] * 4.0;
x[1] += y[1] * 4.0;
x[2] += y[2] * 4.0;

I suspect that the threshold for making the function call will be occur at
length at least 9, possibly higher, since the overhead for the function call is
very large (it needs to check the capabilities of the processor, for example).

This will allow array operations to provide good performance in the
commonly-used case of 2D, 3D and 4D vectors.

For x86, when the code generator supports it, such usage should be turned
directly into SSE instructions. This issue is a step towards that longer-term
goal.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 2879] std.bigint missing from phobos

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2879


Lars T. Kyllingstad bugzi...@kyllingen.net changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||bugzi...@kyllingen.net
 Resolution||FIXED


--- Comment #2 from Lars T. Kyllingstad bugzi...@kyllingen.net 2010-05-26 
23:43:08 PDT ---
New std.bigint documentation available since DMD 2.043.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 4241] New: duplicate union initialization error doesn't give a file location

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4241

   Summary: duplicate union initialization error doesn't give a
file location
   Product: D
   Version: 2.041
  Platform: Other
OS/Version: Windows
Status: NEW
  Keywords: diagnostic
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: mrmoc...@gmx.de


--- Comment #0 from Trass3r mrmoc...@gmx.de 2010-05-27 10:48:54 PDT ---
import std.typetuple;

/// repeat a type count times
template Repeat(T, int count)
{
static if (!count)
alias TypeTuple!() Repeat;
else
alias TypeTuple!(T, Repeat!(T, count-1)) Repeat;
}

struct Vector(T, int dim)
{
static assert (dim = 2  dim = 4);

union
{
// including these gives more errors of the same kind
//T[dim] cell;/// array access
//Repeat!(T, dim) tuple;/// for tuple access

/// normal struct element access
struct
{
static if (dim = 1)union { T x; T r; }
static if (dim = 2)union { T y; T g; }
static if (dim = 3)union { T z; T b; }
static if (dim = 4)union { T w; T a; }
}
}

// these constructors are workarounds for the overlapping initialization
for _tuple_field_0 problem
static if (dim == 2)
this(T ax, T ay)
{
x = ax;
y = ay;
}

static if (dim == 3)
this(T ax, T ay, T az)
{
x = ax;
y = ay;
z = az;
}

static if (dim == 4)
this(T ax, T ay, T az, T aw)
{
x = ax;
y = ay;
z = az;
w = aw;
}

static if (2 == dim) const static Vector zero = Vector(0, 0);
static if (3 == dim) const static Vector zero = Vector(0, 0, 0);
static if (4 == dim) const static Vector zero = Vector(0, 0, 0, 0);
}

alias Vector!(float, 2)Vector2f; ///
alias Vector!(float, 3)Vector3f; ///
alias Vector!(float, 4)Vector4f; ///

yields:
Error: duplicate union initialization for r
Error: duplicate union initialization for g
Error: duplicate union initialization for r
Error: duplicate union initialization for g
Error: duplicate union initialization for b
Error: duplicate union initialization for r
Error: duplicate union initialization for g
Error: duplicate union initialization for b
Error: duplicate union initialization for a


It would be helpful to have a file location.
Unfortunately for some reason loc is null in StructLiteralExp::toDt(dt_t **pdt)
where the error occurs.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 4242] New: ICE(module.c): module naming conflict in subfolder

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4242

   Summary: ICE(module.c): module naming conflict in subfolder
   Product: D
   Version: 2.041
  Platform: Other
OS/Version: Windows
Status: NEW
  Keywords: ice-on-invalid-code
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: clugd...@yahoo.com.au


--- Comment #0 from Don clugd...@yahoo.com.au 2010-05-27 15:06:39 PDT ---
Reported by Matthias.
-
The dmd compiler v2.046 produces correct output (Error: module test from file
xxx.d conflicts with another module test from file yyy.d), if multiple
placement of same module identifier are in the root of the project, however it
crashes, when the files are in a subfolder and does not display a proper error
message.

The output is:
Assertion failure: 'mprev' on line 641 in file 'module.c'

Test case:
--main.d--
import std.stdio;

import folder.File1;
import folder.File2;

int main(char[][] args)
{
writefln(file2);
return 0;
}

--folder\File1.d--
module folder;

const char[] file1 = File1;

--folder\File2.d--
module folder;

const char[] file2 = File2;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 4243] New: [snn.lib] setmode doesn't set stdin/stdout to binary

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4243

   Summary: [snn.lib] setmode doesn't set stdin/stdout to binary
   Product: D
   Version: 2.041
  Platform: x86
   URL: http://www.digitalmars.com/d/archives/digitalmars/D/se
tmode_again_74658.html
OS/Version: Windows
Status: NEW
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: rsi...@gmail.com


--- Comment #0 from Shin Fujishiro rsi...@gmail.com 2010-05-27 15:32:13 PDT 
---
setmode(stdout, O_BINARY) does not set stdout to binary mode.  setmode surely
works for fopen'ed files, but does not work for standard file streams.

 test1.d
import std.c.stdio;
extern(C) int setmode(int, int);
enum O_BINARY = 0x8000;
void main()
{
string s = \n;

// write to stdout
setmode(stdout._file, O_BINARY);// set to binary mode
fwrite(s.ptr, 1, s.length, stdout);

// write to test.dat
auto f = fopen(test.dat, w);// open in text mode
setmode(f._file, O_BINARY); // set to binary mode
fwrite(s.ptr, 1, s.length, f);
fclose(f);
}

dmd -run test1 | od -c
000\r  \n   -- written in text mode
002
od -c test.dat
000\n   -- okay
001


This also does not work:
 test2.d
import std.c.stdio;
enum _IOTRAN = 0x100; // taken from DMC include/stdio.h
void main()
{
string s = \n;
stdout._flag = ~_IOTRAN;
fwrite(s.ptr, 1, s.length, stdout);
}

dmd -run test2 | od -c
000\r  \n   -- written in text mode
002


Only this works:
 test3.d
import std.c.stdio;
void main()
{
string s = \n;
__fhnd_info[stdout._file] = ~FHND_TEXT;
fwrite(s.ptr, 1, s.length, stdout);
}

dmd -run test3 | od -c
000\n   -- okay, written in binary mode
001


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 4244] New: AA insert from fixed-sized array much slower than from equivalent struct

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4244

   Summary: AA insert from fixed-sized array much slower than from
equivalent struct
   Product: D
   Version: future
  Platform: x86
OS/Version: Windows
Status: NEW
  Keywords: performance
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: bearophile_h...@eml.cc


--- Comment #0 from bearophile_h...@eml.cc 2010-05-27 17:08:06 PDT ---
This D2 program gets much slower if foo1() is used inside the main() instead of
foo2() that apparently does something very similar (compiled with dmd v2.046,
__gshared not used, compilation arguments -O -release -inline):


import std.c.stdio: printf;

int foo1(int x, int y) {
static int[int[2]] cache;
int[2] args = [x, y];
cache[args] = x;
return x;
}

int foo2(int x, int y) {
static struct Pair { int x, y; }
static int[Pair] cache;
Pair args = Pair(x, y);
cache[args] = x;
return x;
}

void main() {
enum int N = 600;
int tot;
foreach (x; 1 .. N)
foreach (y; 1 .. N)
tot += foo1(x, y);
printf(%d\n, tot);
}



An experiment shows that foo1 gets quite faster if the [x,y] is written inside
the cache AA itself:

int foo1(int x, int y) {
static int[int[2]] cache;
int[2] args = [x, y];
cache[[x, y]] = x;
return x;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 4235] !in not working (D1)

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4235


Stewart Gordon s...@iname.com changed:

   What|Removed |Added

   Keywords||ice-on-valid-code,
   ||rejects-valid
URL||http://www.digitalmars.com/
   ||d/1.0/expression.html
 CC||s...@iname.com


--- Comment #2 from Stewart Gordon s...@iname.com 2010-05-27 18:56:52 PDT ---
The spec is a more authoritative source than the changelog.

But still, changelogs should be complete.  A particular problem occurs if
something's noted in the changelog, but then later it is reverted without being
noted in the changelog.  See issue 926 for an example.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 4227] Overloading rules not complete in D1 docs

2010-05-27 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=4227


Stewart Gordon s...@iname.com changed:

   What|Removed |Added

   Keywords||spec
 CC||s...@iname.com


--- Comment #1 from Stewart Gordon s...@iname.com 2010-05-27 19:00:03 PDT ---
If I'd like to overload what functions?

Some sample code to explain what you're on about would help.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


  1   2   >