Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Georg Wrede

bearophile wrote:

Arild Boes:

Here's the link: http://www.vimeo.com/4333802


Globally is a very nice presentation.

I like how Walter is never putting himself over the people that are
listening. He is humble and at the same level.


It has to be a gift! Richard Stallman is the opposite, both on podium 
and in person. Not good PR for FSF.



Using html pages with scroll down... uhm, I am not sure I like that
much.


That hit me too. I've been using PP or OO just because, never really 
thinking. But there are some advantages to using a straight, long 
document.


It's a /lot/ faster to create the presentation. You don't have to split 
stuff into screenfulls (or fight with the presentation software!) And 
once on stage, scrolling back is way easier and faster! And you can 
sroll to exactly where you want, instead of to the nearest screenful.


Heh, now I can say if it's good enough for Walter Bright on a big butt 
guru forum, I can use it, too!





Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Walter Bright

Georg Wrede wrote:
That hit me too. I've been using PP or OO just because, never really 
thinking. But there are some advantages to using a straight, long 
document.


It's a /lot/ faster to create the presentation. You don't have to split 
stuff into screenfulls (or fight with the presentation software!) And 
once on stage, scrolling back is way easier and faster! And you can 
sroll to exactly where you want, instead of to the nearest screenful.


Heh, now I can say if it's good enough for Walter Bright on a big butt 
guru forum, I can use it, too!


Everyone I talked to who was there didn't like it. I've switched to OO 
Impress!


Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Walter Bright

Daniel Keep wrote:

There's always S5: it lets you make slideshows in HTML.

http://meyerweb.com/eric/tools/s5/


After playing with OO Impress for a while, I've found it to be quicker 
and easier to produce a slideshow with it than with html. For another 
thing, the fonts render obviously better than in firefox. I have no idea 
why.


Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Daniel Keep


Walter Bright wrote:
 Georg Wrede wrote:
 That hit me too. I've been using PP or OO just because, never really
 thinking. But there are some advantages to using a straight, long
 document.

 It's a /lot/ faster to create the presentation. You don't have to
 split stuff into screenfulls (or fight with the presentation
 software!) And once on stage, scrolling back is way easier and faster!
 And you can sroll to exactly where you want, instead of to the nearest
 screenful.

 Heh, now I can say if it's good enough for Walter Bright on a big
 butt guru forum, I can use it, too!
 
 Everyone I talked to who was there didn't like it. I've switched to OO
 Impress!

There's always S5: it lets you make slideshows in HTML.

http://meyerweb.com/eric/tools/s5/

  -- Daniel


Slide design

2009-05-04 Thread Andrei Alexandrescu

flGeorg Wrede wrote:

Walter Bright wrote:
Everyone I talked to who was there didn't like it. 


I think there's the *subconscious* notion of not respecting the 
audience by bothering to do a Proper Presentation. And they let it seep 
through, instead of pausing to think about the upsides. (The more we 
think we're Thinking Individuals, the less we're wary of such 
seep-through. I see it all the time with professionals.)


The presentation software format is more restrictive than we usually 
think. Everything has to be crunched to ridiculous screenfuls, mostly 
containing a couple of bullet items. And if you want the audience to 
follow the presentation where you are you have to do all kinds of 
one-at-a-time appearing bullets. It's really pathetic. (And I, at least, 
end up spending inordinate time figuring should they fly in from the 
left or rignt, or should they emerge, or whatever.) Instead of simply 
scrolling them into view when needed.


Yes, PP co make for an audience experience, but as the Columbia 
disaster taught NASA, it's not really the way to go.

(http://en.wikipedia.org/wiki/Edward_Tufte)

PP is for M$ style sales pitches, not for disseminating serious content. 
IMNSHO, of course. (And the less there's bread and butter, the more you 
can decorate, having everybody exit, aahing and oohing all the way home.)


And how do you present conveniently a code snippet that exceeds a 
screenful? Like, if it's two screens long, do you split it into three 
screens, first half, middle part (showing latter half of first screen 
and first half of last screen), and second half? Instead of conveniently 
being able to scroll it as the discussion goes.


To prove my point, what if a lecturer 20 years ago had began by drawing 
a square on the chalkboard, and then only writing bullet items there, 
always erasing them before writing more. And leaving the rest of the 
chalkboard unused. (The rest of the chalkboard here represents scrolling 
back and forth the long document.)


If PP was the superior format, then all web pages would be just a few 
bullets and a goto next page button at the bottom.


I don't agree. I think there is much more at work here. Slides are 
limited in size and text content simply because there is so much 
information a person can absorb simultaneously by hearing and seeing. So 
the slide with text is simply an anchor, a high-level memento to rest 
one's eyes on, while the speaker gives some detail pertaining to the 
high-level points that the slide makes.


The slide is not meant to convey complex information with completeness. 
There is, for example, no hope in putting complex proofs or formulae on 
the slide. Instead, you give the conclusion and e.g. some top-level 
formula and point to the paper or whatever for people interested in 
details. The typical conference talk is 15-20 minutes regardless of the 
fields' complexity. The only hope an author can make is not to explain 
everything done, but instead to raise interest in reading the actual paper.


If a code snippet is larger than a screenful, then there is a problem 
with the presentation. Most people will tune out if they have to sit 
down and understand code while at the same time somebody is talking 
their ear off. Good code slides focus on one small but 
unusual/interesting/relevant code portion at a time, have the author 
explain what's going on, and then move to another portion of the code.


I've been in Walter's HTML-based talks. Yes, my perception was indeed 
that the talk was not properly prepared, although I knew it was. I have 
no idea why that is, though I can speculate that the scrolling style 
leads to looser presentations as the format does not force one to 
present ideas crisply, one at a time.


Anyway (and unrelated), IMHO a much worse mistake a speaker might do is 
to go over allocated time. I'm sure few mean it that way, but the 
perceived message is that they assume what they have to say is important 
and interesting enough to trump your and whatever events' schedule. My 
slides are mediocre, but I make a point at landing to a tee when it 
comes about time.


The second largest mistake (since you mention worrying about 
bulletpoints flying, oh boy) is to use effects without reason. It's 
distracting, devoid of any message, and so often completely distasteful, 
it's a safe bet to avoid them altogether. There is precisely one place 
where I saw good (actually great) presentation animation: in SIGGRAPH 
presentations. And of course they never use text effects a la Powerpoint!



Andrei


Re: Slide design

2009-05-04 Thread Walter Bright
I generally agree with Andrei (and he knows what he's doing, his talks 
are both entertaining and informative, several cuts above the usual ones 
I have to sit through).


I find after giving a presentation using a non-traditional format, that 
the non-traditional format becomes the topic of conversation, not the 
ideas in the presentation. It's distracting.



Some more issues:

o Since Impress is wysiwyg, I find it a lot easier to adjust things to 
fit on the screen. I had constant problems with the html one moving from 
one screen size to another.


o Impress has a one-button render as PDF, which is pretty handy.

o If you want to make handouts, print shops know how to deal with pdf. 
It just works, and you get good results.


o pdf renders a lot better than html. Why that should be, I don't know, 
but it is obviously better.


o being able to do boxes and arrows and such in Impress is much better 
than trying to do it in MS Paint and importing a gif.


o Of course I miss the D source code highlighting that Ddoc does.

o Impress doesn't seem to be able to do tables. Bummer.


I recently saw some ppt presentations where the presenter felt compelled 
to try out every single special effect ppt has. It was distracting and 
rather annoying, and certainly took away from his presentation. It 
looked like something his kid put together.


It makes one appreciate all the more a good one, like the ones Andrei 
and Scott Meyers put on.


Re: Slide design

2009-05-04 Thread bearophile
Andrei Alexandrescu:
 Slides are 
 limited in size and text content simply because there is so much 
 information a person can absorb simultaneously by hearing and seeing.

Of course mammal brains have limits, but such limits are always higher than the 
amount of information shown in normal slides.


 I've been in Walter's HTML-based talks. Yes, my perception was indeed 
 that the talk was not properly prepared, although I knew it was. I have 
 no idea why that is, though I can speculate that the scrolling style 
 leads to looser presentations as the format does not force one to 
 present ideas crisply, one at a time.

I haven't appreciated much the html-based presentation, but probably some 
compromise can be found between that and the standard information-starved 
slides.
One problem with Walter's HTML-based talk was the long searching scroll up and 
down. You can create separated pages in Html too. (in my presentations I 
usually use pdf pages with a good amount of stuff. OpenOffice is able to output 
such PDF files too).

Bye,
bearophile


Re: Slide design

2009-05-04 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 The slide is not meant to convey complex information with completeness.
 There is, for example, no hope in putting complex proofs or formulae on
 the slide.

Wow.  I really wish the rest of the Ph.D students in this world would learn 
this.


Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Sean Kelly
== Quote from Georg Wrede (georg.wr...@iki.fi)'s article

 The presentation software format is more restrictive than we usually
 think. Everything has to be crunched to ridiculous screenfuls, mostly
 containing a couple of bullet items. And if you want the audience to
 follow the presentation where you are you have to do all kinds of
 one-at-a-time appearing bullets. It's really pathetic. (And I, at least,
 end up spending inordinate time figuring should they fly in from the
 left or rignt, or should they emerge, or whatever.) Instead of simply
 scrolling them into view when needed.
...
 PP is for M$ style sales pitches, not for disseminating serious content.
 IMNSHO, of course. (And the less there's bread and butter, the more you
 can decorate, having everybody exit, aahing and oohing all the way home.)
 And how do you present conveniently a code snippet that exceeds a
 screenful?

When I went back to finish my degree I was forced to take a Public Speaking
course, and the course basically had one simple message:

The likelihood that an audience will either get lost or bored is an exponential
function of the complexity of the presentation.  As much as I despise the PP-
based presentation format, it does force the speaker to simplify things as
much as possible.


Re: dmd 1.041 and 2.026 releases

2009-05-04 Thread Sean Kelly
== Quote from Walter Bright (newshou...@digitalmars.com)'s article
 dsimcha wrote:
  == Quote from Ellery Newcomer (ellery-newco...@utulsa.edu)'s article
  Walter Bright wrote:
  davesun wrote:
  when can I use dmd on 64bit linux ?
 
  You can now - 32 bit executables work fine on 64 bit linux!
  Maybe I should try it again sometime, but I ran into linker issues when
  I tried using DMD on 64bit linux. Other than that, DMD worked fine.
 
  Same here, but only on some installations of 64-bit Linux.  Others work 
  fine.  I
  think the key is that you need the 32-bit version of GCC and all the 
  libraries
  like libpthread, libgcc, libc, etc. available.  I've been nagging my 
  sysadmin to
  install these, though it matters less for me now that I have the DMD source 
  and
  was able to make DMD work on some other Linux boxes that it previously 
  didn't work
  on for unrelated reasons.  If you have a bunch of Linux boxes around, you 
  can also
  compile on one that has the 32-bit libs and copy the resulting binary over 
  to one
  that doesn't, and it will usually work.
 On Ubuntu64, which is my main linux dev machine, the following is necessary:
 To compile 32 bit programs under ub64:
   sudo apt-get install gcc-multilib libc6-i386 lib6-dev-i386
 To run 32 bit programs:
   sudo apt-get install gcc-multilib
   sudo apt-get install g++-multilib
 (After long bitter experience, I now keep notes on how to configure the
 machine after a fresh install g.)

Seems I might have to as well.  Before installing these, I was getting a file 
not found
error running dmd.  Now everything works perfectly.  Talk about a confusing 
error
message!


Re: Slide design

2009-05-04 Thread Daniel Keep


Walter Bright wrote:
 ...
 
 o pdf renders a lot better than html. Why that should be, I don't know,
 but it is obviously better.

I could be the old Mac feature.  From what I recall, Apple is
fanatical about the on-screen display of something matching, as closely
as possible, the on-page display.  This means that when they render
text, they render it without adjusting the glyphs to fit the pixel grid.
 This tends to lead to slightly blurrier text on-screen.

Since PDF is for print output, it probably does the same thing.  Firefox
would be using the system text libraries which fit glyphs to a pixel
grid, and often don't antialias at low point sizes.

 ...
 
 o Of course I miss the D source code highlighting that Ddoc does.

You should be able to copy+paste HTML with its formatting in-tact.

 o Impress doesn't seem to be able to do tables. Bummer.

I know that 3.0 does.  Just don't use too many of them, or Impress will
start coughing up blood.

 ...

  -- Daniel


Re: Slide design

2009-05-04 Thread superdan
Sean Kelly Wrote:

 == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 
  I don't agree. I think there is much more at work here. Slides are
  limited in size and text content simply because there is so much
  information a person can absorb simultaneously by hearing and seeing. So
  the slide with text is simply an anchor, a high-level memento to rest
  one's eyes on, while the speaker gives some detail pertaining to the
  high-level points that the slide makes.
 
 For lectures I basically have a choice between two options:
 
 1. Take notes and not remember a darn thing that was said.
 2. Not take any notes and remember the lecture.
 
 I've seen a few raised eyebrows at times, but this is why I never write
 anything down at a meeting or lecture I'm attending--it draws my focus
 away from the material being presented.

yeah da raised brow. fuck that shit. i took a pascal class at motherfuck 
memorial comm college in b'more. i'd take a front seat  not write shit. teach 
couldn't tell a lambda from da mole on his face anyway. at the finals i finish 
first. the mo'fucker is like, 'well giving up already?' gave him mah look if i 
didn't need ur fucking grade my ankle would be up yer fucking asshole by now, 
asshole'. to his credit the mo'fucker had enough decency left to fuckin' 
apologize. so i tell him he had a bug in problem 4  went mah way.



Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Georg Wrede

Sean Kelly wrote:

== Quote from Georg Wrede (georg.wr...@iki.fi)'s article

The presentation software format is more restrictive than we usually
think. Everything has to be crunched to ridiculous screenfuls, mostly
containing a couple of bullet items. And if you want the audience to
follow the presentation where you are you have to do all kinds of
one-at-a-time appearing bullets. It's really pathetic. (And I, at least,
end up spending inordinate time figuring should they fly in from the
left or rignt, or should they emerge, or whatever.) Instead of simply
scrolling them into view when needed.

...

PP is for M$ style sales pitches, not for disseminating serious content.
IMNSHO, of course. (And the less there's bread and butter, the more you
can decorate, having everybody exit, aahing and oohing all the way home.)
And how do you present conveniently a code snippet that exceeds a
screenful?


When I went back to finish my degree I was forced to take a Public Speaking
course, and the course basically had one simple message:

The likelihood that an audience will either get lost or bored is an exponential
function of the complexity of the presentation.  As much as I despise the PP-
based presentation format, it does force the speaker to simplify things as
much as possible.


That's certainly true with non-techie audiences. I wish we had had 
speaking classes when I went to school. The first time I gave a lecture 
at the university, my hands trembled visibly on the OH.


Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Sean Kelly

Georg Wrede wrote:


That's certainly true with non-techie audiences. I wish we had had 
speaking classes when I went to school. The first time I gave a lecture 
at the university, my hands trembled visibly on the OH.


I'm fine if I can just sit down and talk, but if I have to stand in 
front of people I still get nervous and scattered.  I was told my talk 
at the D conference actually went reasonably well, but I forgot or 
missed about half the points I'd meant to cover out of sheer terror :-)


During a public speaking course in high school one of our lectures was 
supposed to be a published work of some sort, so I did the part of a 
evangelical preacher in a Steven King novel.  It was a breeze to do and 
I had a lot of fun with it, playing with pace and tone.  Something about 
the fact that I was acting instead of simply speaking as myself made 
all the difference in the world.  If I had to give talks regularly I'd 
probably prepare them pretty much word for word just to feel more like I 
was doing this, at least until I got more comfortable with speaking.


Re: Metaprogramming in D tonight at the NWCPP

2009-05-04 Thread Brad Roberts
Sean Kelly wrote:
 Georg Wrede wrote:

 That's certainly true with non-techie audiences. I wish we had had
 speaking classes when I went to school. The first time I gave a
 lecture at the university, my hands trembled visibly on the OH.
 
 I'm fine if I can just sit down and talk, but if I have to stand in
 front of people I still get nervous and scattered.  I was told my talk
 at the D conference actually went reasonably well, but I forgot or
 missed about half the points I'd meant to cover out of sheer terror :-)
 
 During a public speaking course in high school one of our lectures was
 supposed to be a published work of some sort, so I did the part of a
 evangelical preacher in a Steven King novel.  It was a breeze to do and
 I had a lot of fun with it, playing with pace and tone.  Something about
 the fact that I was acting instead of simply speaking as myself made
 all the difference in the world.  If I had to give talks regularly I'd
 probably prepare them pretty much word for word just to feel more like I
 was doing this, at least until I got more comfortable with speaking.

Most of that is just repetition.  I used to be scared as hell.. just rushed
through whatever I had to tell people and finish as fast as I could.  I've now
done enough presentations that the terror has subsided and I can give a decent
talk.  It took years and lots of terror though.

Later,
Brad


Re: D compiler embedding

2009-05-04 Thread Simen Kjaeraas

Peloto wrote:


Can I embed the D compiler into my application? For example:

Dcompiler c;
Dcompiler::result *r = c.compile(mySource.d);
fstream f(result.bin);
f.write(r-GetBuffer(),r-GetNBytes());


Short answer: No.

Long answer: Several people have been asking for this, and there has been at 
least one implementation. Burton Radons wrote 
http://members.shaw.ca/burton-radons/The%20Joy%20and%20Gibbering%20Terror%20of%20Custom-Loading%20Executables.html,
 which I have not myself tried, but it seems like it should do what you ask for.


--
 Simen


Re: Many questions

2009-05-04 Thread Robert Fraser

Ellery Newcomer wrote:

Nick Sabalausky wrote:

-
//File: foo/fooA.d
module foo.fooA;
class fooA {}

//File: foo/fooB.d
module foo.fooB;
class fooB {}

//File: foo/fooC.d
module foo.fooC;
class fooC {}

//File: foo/all.d
module foo.all;
public import foo.fooA;
public import foo.fooB;
public import foo.fooC;

//File: main.d
import foo.all;
void main() {...}
-

This works fine and does exactly what you want.



How well will this work if there is fairly tight coupling between these 
three classes?


Not well at all :-). Technically, it should work the same as if they 
were in the same module, but compiler bugs dealing with forward 
references keep this from happening. I think a while back there was a 
version of LDC that pretty much fixed forward reference issues, but it 
introduced a bunch of regressions.


Re: D compiler embedding

2009-05-04 Thread Robert Fraser

Peloto wrote:

And other doubt... where's the Solaris port for the D compiler? I see only 
Windows, linux, freeBSD and MacOSX.


http://www.dsource.org/projects/ldc



Re: Throwable, Exception, and Error

2009-05-04 Thread Steve Teale
Jarrett Billingsley Wrote:

 On Sun, May 3, 2009 at 4:14 PM, Denis Koroskin 2kor...@gmail.com wrote:
  PHP allows function definition like this:
 
  void foo(Args args, string fileName = __FILE__, int line = __LINE__)
  {
   // do stuff
  }
 
 Hidden feature: D2 allows it too, at least with templates.
 
 void Throw(T : Throwable, string file = __FILE__, int line = __LINE__)(T ex)
 {
   ex.file = file;
   ex.line = line;
   throw ex;
 }
 
 void foobar()
 {
   Throw(new Exception(o hai));
 }
 
 void main()
 {
   try
   foobar();
   catch(RangeError e)
   writefln((%s: %d) %s, e.file, e.line, e.msg);
 }
 
 I did find a sort of bug when trying a slightly different
 implementation of this though - any kind of explicit instantiation of
 the Throw template causes the __FILE__ and __LINE__ to be evaluated in
 the scope of the template rather than at the call site.

Sadly this is a subterfuge that makes it impossible as far as I can see to 
write code that compiles and works the same with both D1 and D2.

D1 compiles it, but reports the exception at the line where the template 
function is defined.

;=(



Re: Fixing the imaginary/complex mess

2009-05-04 Thread Don

Walter Bright wrote:

Don wrote:
I don't think anyone expects to be able to divide an integer by an 
imaginary, and then assign it to an integer. I was astonished that the 
compiler accepted it.


There actually is a reason - completeness. Mathematically, there is a 
definite answer to it, so why not fill in all the entries for all the 
combinations?


In the case complex = int/complex, there's no problem. It's the case int 
= int/complex that doesn't make sense.
And that's fundamentally because cast(real)(2 + 3i) doesn't have a 
definite answer.

There's no mathematical operation to convert a complex number to a real.
Normally, to get a real result, you need to do something like 
multiplying by the complex conjugate. You CAN take the real part of a 
complex number, and you can also take the modulus (which makes a lot of 
sense if you're using polar represantation).


Of course, cast() is not a mathematical operation, it's a D operation, 
so we can define it however we like. But defining it

cast(real)z = z.re;
is an arbitrary decision, which introduces lots of complexity to the 
language, and the many compiler bugs are a consequence.
It's confusing for newbies (there's been questions on D.learn asking, I 
can get the real part of a complex number with cast(real), but how do I 
get the imaginary part? cast(ireal) gives me an ireal, not a real!).


Since D supports the very nice .re syntax, there's really no reason to 
define cast(real) at all. z.re is better in 100% of use cases. There are 
*NO* use cases for cast(real); any use of cast(real) is a bug. We should 
kill it.




Re: Many questions

2009-05-04 Thread Liang Du
Nick Sabalausky Wrote:

 Fractal d294...@bsnow.net wrote in message 
 news:gtlihm$tt...@digitalmars.com...
 
  The namespaces: i used them with C++, and the idea of separation between 
  the uses of types, makes a very good layout. Because some namespaces 
  requires more types, always i write each class in separate files. D simply 
  breaks it, making a big amount of lines for imports.
 
 
 That is easy to work around. Instead of this (which doesn't work in D):
 
 -
 //File: foo/fooA.d
 module foo;
 class fooA {}
 
 //File: foo/fooB.d
 module foo;
 class fooB {}
 
 //File: foo/fooC.d
 module foo;
 class fooC {}
 
 //File: main.d
 import foo;
 void main() {...}
 -
 
 Do this:
 
 -
 //File: foo/fooA.d
 module foo.fooA;
 class fooA {}
 
 //File: foo/fooB.d
 module foo.fooB;
 class fooB {}
 
 //File: foo/fooC.d
 module foo.fooC;
 class fooC {}
 
 //File: foo/all.d
 module foo.all;
 public import foo.fooA;
 public import foo.fooB;
 public import foo.fooC;
 
 //File: main.d
 import foo.all;
 void main() {...}
 -
 
 This works fine and does exactly what you want.
 


The namespaces is better !!!


Re: Fixing the imaginary/complex mess

2009-05-04 Thread Don

Frits van Bommel wrote:

Don wrote:
In the case complex = int/complex, there's no problem. It's the case 
int = int/complex that doesn't make sense.
And that's fundamentally because cast(real)(2 + 3i) doesn't have a 
definite answer.


Devil's advocate: one could argue it's the same as cast(int) of a float 
-- it returns the closest representable value, for some definition of 
closest.


Sure, you're at liberty to argue anything. But mathematicians don't do 
that. Nor should we. It's misleading, and just not helpful.
BTW, another equally reasonable and equally unhelpful way you could 
define cast(real)(x + iy) is as sqrt(x*x - y*y).


The most justifiable way to do it would be to say
cast(real)(x+iy) is:
 if (y==0) return x; else throw(CastError);
But again, it's just not helpful. Make it a compile-time error.


Re: Fixing the imaginary/complex mess

2009-05-04 Thread Frits van Bommel

Don wrote:
In the case complex = int/complex, there's no problem. It's the case int 
= int/complex that doesn't make sense.
And that's fundamentally because cast(real)(2 + 3i) doesn't have a 
definite answer.


Devil's advocate: one could argue it's the same as cast(int) of a float -- it 
returns the closest representable value, for some definition of closest.


Re: Fixing the imaginary/complex mess

2009-05-04 Thread Georg Wrede

Don wrote:

Walter Bright wrote:

Don wrote:
I don't think anyone expects to be able to divide an integer by an 
imaginary, and then assign it to an integer. I was astonished that 
the compiler accepted it.


There actually is a reason - completeness. Mathematically, there is a 
definite answer to it, so why not fill in all the entries for all the 
combinations?


In the case complex = int/complex, there's no problem. It's the case int 
= int/complex that doesn't make sense.
And that's fundamentally because cast(real)(2 + 3i) doesn't have a 
definite answer.

There's no mathematical operation to convert a complex number to a real.
Normally, to get a real result, you need to do something like 
multiplying by the complex conjugate. You CAN take the real part of a 
complex number, and you can also take the modulus (which makes a lot of 
sense if you're using polar represantation).


Of course, cast() is not a mathematical operation, it's a D operation, 
so we can define it however we like. But defining it

cast(real)z = z.re;
is an arbitrary decision, which introduces lots of complexity to the 
language, and the many compiler bugs are a consequence.
It's confusing for newbies (there's been questions on D.learn asking, I 
can get the real part of a complex number with cast(real), but how do I 
get the imaginary part? cast(ireal) gives me an ireal, not a real!).


Since D supports the very nice .re syntax, there's really no reason to 
define cast(real) at all. z.re is better in 100% of use cases. There are 
*NO* use cases for cast(real); any use of cast(real) is a bug. We should 
kill it.


Walter, could the error message then include Please use z.re or z.im to 
get the parts, instead of a cast. or something. Otherwise we have to 
explain to all users separately what's going on, /and/ that the omission 
of implementing the cast in D isn't an omission.


Re: Fixing the imaginary/complex mess

2009-05-04 Thread bearophile
Don Wrote:
 Since D supports the very nice .re syntax, there's really no reason to 
 define cast(real) at all. z.re is better in 100% of use cases. There are 
 *NO* use cases for cast(real); any use of cast(real) is a bug. We should 
 kill it.

I am with you. Making the language tidy is the way to go :-)
Thank you for your work, and keep improving things when you can.

Bye,
bearophile


Re: Fixing the imaginary/complex mess

2009-05-04 Thread Derek Parnell
On Mon, 04 May 2009 10:56:41 +0200, Frits van Bommel wrote:

 Don wrote:
 In the case complex = int/complex, there's no problem. It's the case int 
 = int/complex that doesn't make sense.
 And that's fundamentally because cast(real)(2 + 3i) doesn't have a 
 definite answer.
 
 Devil's advocate: one could argue it's the same as cast(int) of a float -- it 
 returns the closest representable value, for some definition of closest.

Hmmm. not quite because we can not do ...

   int i = floatnum.integer;

but we can do 

   real r = complexnum.re;

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell


Re: Fixing the imaginary/complex mess

2009-05-04 Thread Jason House
Frits van Bommel Wrote:

 Don wrote:
  In the case complex = int/complex, there's no problem. It's the case int 
  = int/complex that doesn't make sense.
  And that's fundamentally because cast(real)(2 + 3i) doesn't have a 
  definite answer.
 
 Devil's advocate: one could argue it's the same as cast(int) of a float -- it 
 returns the closest representable value, for some definition of closest.

I consider this to be a much different case. Assuming the float to an int 
results on approximately the same number... And everyone knows what to expect. 
It's also possible to convert back to float and still have approximately the 
same number. 

For complex to int, the same things are not true. Conversion to float and then 
back to real can give a much different number... And not just for overflow, but 
normal uses of complex numbers. It's also unclear to mathematically inclined 
folk like me and Don what the conversion is supposed to do. A magnitude makes 
as much, if not more, sense.

Adding to all this, there are easier, shorter, and clearer ways to do all of 
these conversions, and you _have_ to agree with Don ;)


Re: Absolutely horrible default string hashing

2009-05-04 Thread Steven Schveighoffer
On Sun, 03 May 2009 08:10:43 -0400, Frits van Bommel  
fvbom...@remwovexcapss.nl wrote:



Jarrett Billingsley wrote:

Here's something bizarre: porting this example to Tango yields 7
unique hashes, which is right in line with your estimate.  But I think
it's bizarre since, well, shouldn't druntime use _the same typeinfo
code?_


No, Tango recently upgraded its hashing algorithms. This was done after  
druntime was created, and presumably before the Tango version on your  
machine :).


Reading dsimcha's followup, it's probably because tango is D1 only, which  
doesn't use immutable(char)[].  (man, I gotta get back to working on  
Tango4D2)


-Steve



Re: D compiler embedding

2009-05-04 Thread Jason House
Robert Fraser Wrote:

 Peloto wrote:
  And other doubt... where's the Solaris port for the D compiler? I see only 
  Windows, linux, freeBSD and MacOSX.
 
 http://www.dsource.org/projects/ldc
 

The Phobos changelog implies the next D1 release will have Dolaris support. D2 
support is on hold due to other drastic changes. Regardless, LDC is a good 
recommendation; it supports a lot of platforms dmd does not. I'm still hoping 
for 64 bit support in dmd.


Re: Error: xxx is not an lvalue

2009-05-04 Thread Steven Schveighoffer
On Sun, 03 May 2009 05:25:09 -0400, Unknown W. Brackets  
unkn...@simplemachines.org wrote:



This code works fine (D 2.x only):

class Test
{
   private int[int] _testMap;
   public ref int[int] testMap() {return _testMap;}
}

void main()
{
   Test test = new Test();
   test.testMap[0] = 1;
}

Note the ref.  Otherwise, a value is returned which is not modifiable.  
  This will also fix test.array.length.  Nothing wrong here, no creepy  
bad temporary property problems.


The original code should work, this is a problem.  An AA is not a value  
type.


-Steve


Re: Fixing the imaginary/complex mess

2009-05-04 Thread Steven Schveighoffer
On Mon, 04 May 2009 09:44:18 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Georg Wrede wrote:
Walter, could the error message then include Please use z.re or z.im  
to get the parts, instead of a cast. or something. Otherwise we have  
to explain to all users separately what's going on, /and/ that the  
omission of implementing the cast in D isn't an omission.


If we cut the limb, why first apply an ointment to it?


I think the point is relevant to D1, where you can't really remove the  
limb, but you can apply make-up to make it look less deformed ;)


-Steve


New regex: Find?

2009-05-04 Thread dsimcha
Is there an *efficient* way to simply test whether a given string contains a
given regex in the new std.regex?  Using match() and testing for empty works,
but this apparently triggers a bunch of unnecessary heap allocation.  If not,
is this a universal enough feature to warrant an enhancement request?


Re: New regex: Find?

2009-05-04 Thread Andrei Alexandrescu

dsimcha wrote:

Is there an *efficient* way to simply test whether a given string contains a
given regex in the new std.regex?  Using match() and testing for empty works,
but this apparently triggers a bunch of unnecessary heap allocation.  If not,
is this a universal enough feature to warrant an enhancement request?


If you only search once, there will be allocation. However, if you 
search for the same regex several times there will be no extra 
allocation so the cost will be amortized.


Andrei


Re: For Leandro

2009-05-04 Thread Leandro Lucarella
bearophile, el  3 de mayo a las 15:03 me escribiste:
 Another small one for Leandro Lucarella:
 
 struct S { int a;  S* p; }
 void main() {
   foreach (ref s; new S*[4_000_000])
 s = new S;
 }

Thanks! =)

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/

GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)



Re: Many questions

2009-05-04 Thread BCS

Hello Saaa,


mixins are just code in string form, right?


No that's mixin(string), there is also mixin Template!(); that plops 
the template content into its scope.





Re: Many questions

2009-05-04 Thread BCS

Hello Fractal,


Templates: i dont use templates or mixins. they really confuses me and
i think so that they only should be used for array classes or
something similar.



I'm biased (as I love playing with them) but templates can be used for a 
LOT more than that. Most of the time the end user doesn't need to understand 
how it works, just how to use it and that generally isn't hard to figure out.





Re: RFC: naming for FrontTransversal and Transversal ranges

2009-05-04 Thread Leandro Lucarella
Andrei Alexandrescu, el  3 de mayo a las 11:55 me escribiste:
 If the array is a reference type, the array dies when the garbage
 collector decides to run sometime after all live references to the array
 have died, so RAII is not possible.
 
 RAII can be implemented even with reference semantics. The mechanics would 
 involve reference counting.

I was not following this discussion, so I might be speaking out of
ignorance, but I thing you are underestimating the problems of reference
counting again.

Circular references break it, and when comes to RAII, you probably loose
the ordering guarantees it needs if you implement some kind of algorithm
to deal with cycles.

Another option is trust the program be smart enough not to create cycles
(weark references can help a lot here), but if the RC is hidden in the
language it can be a little hard to remember this restriction.

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/

GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)



could someone check this on another system?

2009-05-04 Thread BCS
The attached (er. Can't seem to attach the file, I'll e-mail it to anyone 
who's willing to take a look) has a bug on WinXP DMD 1.040. I can't seem 
to reduce it at all as anything but trivial changes (like removing dead code) 
seems to make the bug vanish.


The short description is I have some code that looks something like this:


bool Foo()
{
  bool ret = true;
  writef(ret,'\n');
  return ret;
}

unittest
{
   auto ret = Foo();
   writef(ret,'\n');
   assert(ret);
}

output:

true
false
Assert Failed




Re: Many questions

2009-05-04 Thread Saaa
Ah, ok thanks.

I should really start reading about those template things :)

 Hello Saaa,

 mixins are just code in string form, right?

 No that's mixin(string), there is also mixin Template!(); that plops 
 the template content into its scope.

 




Re: could someone check this on another system?

2009-05-04 Thread Georg Wrede

BCS wrote:
The attached (er. Can't seem to attach the file, I'll e-mail it to 
anyone who's willing to take a look) has a bug on WinXP DMD 1.040. I 
can't seem to reduce it at all as anything but trivial changes (like 
removing dead code) seems to make the bug vanish.


The short description is I have some code that looks something like this:


bool Foo()
{
  bool ret = true;
  writef(ret,'\n');
  return ret;
}

unittest
{
   auto ret = Foo();
   writef(ret,'\n');
   assert(ret);
}

output:

true
false
Assert Failed


Prints
true
true
on Fedora-10, dmd v1.042


Re: Error: xxx is not an lvalue

2009-05-04 Thread Unknown W. Brackets
I've always though of arrays and associative arrays as structs (which 
really is what they are.)  Thinking that way, this behavior makes exact 
sense - down to .length being unchangeable and associative arrays being 
unchangeable.


I mean, you wouldn't want to make it work the way you suggest by making 
arrays and associative arrays simply pointers to their current structs 
(just like a class would be.)  You could make such a class easily 
yourself, anyway.


If you are right, I guess the right solution would be to make the ref 
implicit when returning (or, I suppose, passing?) such arrays and 
associative arrays.  But that seems wrong to me too, and wouldn't come 
free (speaking of efficiency) either.


-[Unknown]


Steven Schveighoffer wrote:
On Sun, 03 May 2009 05:25:09 -0400, Unknown W. Brackets 
unkn...@simplemachines.org wrote:



This code works fine (D 2.x only):

class Test
{
   private int[int] _testMap;
   public ref int[int] testMap() {return _testMap;}
}

void main()
{
   Test test = new Test();
   test.testMap[0] = 1;
}

Note the ref.  Otherwise, a value is returned which is not 
modifiable.   This will also fix test.array.length.  Nothing wrong 
here, no creepy bad temporary property problems.


The original code should work, this is a problem.  An AA is not a value 
type.


-Steve


Re: Error: xxx is not an lvalue

2009-05-04 Thread Steven Schveighoffer
On Mon, 04 May 2009 14:53:41 -0400, Unknown W. Brackets  
unkn...@simplemachines.org wrote:


I've always though of arrays and associative arrays as structs (which  
really is what they are.)  Thinking that way, this behavior makes exact  
sense - down to .length being unchangeable and associative arrays being  
unchangeable.


I mean, you wouldn't want to make it work the way you suggest by making  
arrays and associative arrays simply pointers to their current structs  
(just like a class would be.)  You could make such a class easily  
yourself, anyway.


If you are right, I guess the right solution would be to make the ref  
implicit when returning (or, I suppose, passing?) such arrays and  
associative arrays.  But that seems wrong to me too, and wouldn't come  
free (speaking of efficiency) either.


-[Unknown]



The underlying struct of an AA is:

struct AA
{
   AA_Implementation *impl;
}

or something like that ;)  Look at the D runtime source.

But in any case, if you return an array slice, would you not want to be  
able to update an element of the slice?


I think there is a difference between a value struct (where all internals  
are non-reference types), and a reference struct (where at least one  
element is a reference type).  A reference struct should be able to pass  
those references to other functions without having to be ref'd.  It forces  
non-transparent type wrapping if that isn't the case.  I should be able to  
replace a reference or pointer type with a wrapper struct where I can  
modify the interface, and it should be transparent that I have done so  
(except for the interface changes of course).  I think this is one of the  
goals D2 is working towards.


It makes sense that a value struct or the value types inside a reference  
struct (i.e. the length of an array) should not be changeable as rvalues,  
since you aren't going to use them later.


Both arrays (as the current implementation) and AA's are reference structs.

-Steve


Re: could someone check this on another system?

2009-05-04 Thread BCS

Reply to Georg,


BCS wrote:


The attached (er. Can't seem to attach the file, I'll e-mail it to
anyone who's willing to take a look) has a bug on WinXP DMD 1.040. I
can't seem to reduce it at all as anything but trivial changes (like
removing dead code) seems to make the bug vanish.

The short description is I have some code that looks something like
this:

bool Foo()
{
bool ret = true;
writef(ret,'\n');
return ret;
}
unittest
{
auto ret = Foo();
writef(ret,'\n');
assert(ret);
}
output:

true
false
Assert Failed

Prints
true
true
on Fedora-10, dmd v1.042


As I said, it's something like the above (but not exactly) and even minor 
changes make it vanish so it's no surprise that exact code works.





Re: could someone check this on another system?

2009-05-04 Thread BCS

Reply to Benjamin,


The attached (er. Can't seem to attach the file, I'll e-mail it to
anyone who's willing to take a look) has a bug on WinXP DMD 1.040. I
can't seem to reduce it at all as anything but trivial changes (like
removing dead code) seems to make the bug vanish.

The short description is I have some code that looks something like
this:

bool Foo()
{
bool ret = true;
writef(ret,'\n');
return ret;
}
unittest
{
auto ret = Foo();
writef(ret,'\n');
assert(ret);
}
output:

true
false
Assert Failed


I've posted the code here:

http://smplsite.com/filebox/error.zip




Re: could someone check this on another system?

2009-05-04 Thread Nick Sabalausky
BCS n...@anon.com wrote in message 
news:a6268ff56558cb9ab074256...@news.digitalmars.com...
 The attached (er. Can't seem to attach the file, I'll e-mail it to anyone 
 who's willing to take a look) has a bug on WinXP DMD 1.040. I can't seem 
 to reduce it at all as anything but trivial changes (like removing dead 
 code) seems to make the bug vanish.

 The short description is I have some code that looks something like this:


 bool Foo()
 {
   bool ret = true;
   writef(ret,'\n');
   return ret;
 }

 unittest
 {
auto ret = Foo();
writef(ret,'\n');
assert(ret);
 }

 output:

 true
 false
 Assert Failed



Prepending the following to the above:

import std.stdio;
void main() {}

I got the following on WinXP 32-bit DMD 1.041:
true
true




Re: could someone check this on another system?

2009-05-04 Thread BCS

Reply to Nick,


BCS n...@anon.com wrote in message
news:a6268ff56558cb9ab074256...@news.digitalmars.com...


The attached (er. Can't seem to attach the file, I'll e-mail it to
anyone who's willing to take a look) 


I got the following on WinXP 32-bit DMD 1.041:
true
true


try the version that actuly has the bug:

http://smplsite.com/filebox/error.zip




Self function

2009-05-04 Thread bearophile
Sometimes I rename recursive functions, or I duplicate and modify them, and 
they stop working because inside them there's one or more copy of their old 
name, so for example they recurse to their old name.
So inside a function I'd like to have a standard name to call the function 
itself, useful for recursivity.
(If you have two or more recursive functions that call each other this idea 
can't be used, but I think such situations are uncommon enough to not deserve 
help from the language).

I have just discussed this in the Python newsgroup too:
http://groups.google.com/group/comp.lang.python/browse_thread/thread/d265da85d4b70eaf#

I use more recursivity in D than in Python, because Python has troubles with it.

In future in D2 you may use:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
mixin(__FUNCTION__ ~ (n - 1) * n);
}

But you can't use __FUNCTION__ into a delegate/function pointer/lambda because 
the name isn't available, and it's a bit ugly syntax anyway...

This looks a bit better:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
__self(n - 1) * n;
}

Other syntaxes are possible.

__self is a way to denote the pointer/delegate of the function currently being 
run, so I think the compiler is always able to that, for delegate/ function 
pointers/ lambdas/ methods/ virtual methods/ opCalls too.

Bye,
bearophile


Re: could someone check this on another system?

2009-05-04 Thread Nick Sabalausky
BCS a...@pathlink.com wrote in message 
news:78ccfa2d3f7098cb9acac6a47...@news.digitalmars.com...
 Reply to Nick,

 BCS n...@anon.com wrote in message
 news:a6268ff56558cb9ab074256...@news.digitalmars.com...

 The attached (er. Can't seem to attach the file, I'll e-mail it to
 anyone who's willing to take a look)

 I got the following on WinXP 32-bit DMD 1.041:
 true
 true

 try the version that actuly has the bug:

 http://smplsite.com/filebox/error.zip


Ok, WinXP 32-bit, and on both 1.040 and 1.041 (byte-for-byte identical 
output on both), my output from go.bat was:

--
D:\DevProject\Test\D\NewsgroupRequest\errordel *.obj

D:\DevProject\Test\D\NewsgroupRequest\errordmd -c -unittest -Icairod 
by_loop.d
[%lg,%lg|%lg,%lg]

D:\DevProject\Test\D\NewsgroupRequest\errordmd -c -unittest -Icairod 
output.d
[%lg,%lg|%lg,%lg]

D:\DevProject\Test\D\NewsgroupRequest\errordmd -c -unittest -Icairod 
graph.d
[%lg,%lg|%lg,%lg]

D:\DevProject\Test\D\NewsgroupRequest\errordmd -c -unittest -Icairod geom.d
[%lg,%lg|%lg,%lg]

D:\DevProject\Test\D\NewsgroupRequest\errordmd -c -unittest -Icairod 
utmain.d

D:\DevProject\Test\D\NewsgroupRequest\errordmd utmain.obj by_loop.obj 
output.obj graph.obj geom.obj cairo.lib

D:\DevProject\Test\D\NewsgroupRequest\errorutmain
true
false
true
true
true
true
true
true
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
true
true
false
false
false
false
false
false
false
false
false
false
false
false
true
true
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
true
true
---true
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
true
true
false
false
false
false
true
false
false
false
false
true
false
false
false
false
true
false
false
false
false
true
--




Re: Self function

2009-05-04 Thread Frank Benoit
bearophile schrieb:
 Sometimes I rename recursive functions, or I duplicate and modify them, and 
 they stop working because inside them there's one or more copy of their old 
 name, so for example they recurse to their old name.
 So inside a function I'd like to have a standard name to call the function 
 itself, useful for recursivity.
 (If you have two or more recursive functions that call each other this idea 
 can't be used, but I think such situations are uncommon enough to not deserve 
 help from the language).
 
 I have just discussed this in the Python newsgroup too:
 http://groups.google.com/group/comp.lang.python/browse_thread/thread/d265da85d4b70eaf#
 
 I use more recursivity in D than in Python, because Python has troubles with 
 it.
 
 In future in D2 you may use:
 
 int ANUGLYNAME(int n) {
 if (n = 1)
 return 1;
 else
 mixin(__FUNCTION__ ~ (n - 1) * n);
 }
 
 But you can't use __FUNCTION__ into a delegate/function pointer/lambda 
 because the name isn't available, and it's a bit ugly syntax anyway...
 
 This looks a bit better:
 
 int ANUGLYNAME(int n) {
 if (n = 1)
 return 1;
 else
 __self(n - 1) * n;
 }
 
 Other syntaxes are possible.
 
 __self is a way to denote the pointer/delegate of the function currently 
 being run, so I think the compiler is always able to that, for delegate/ 
 function pointers/ lambdas/ methods/ virtual methods/ opCalls too.
 
 Bye,
 bearophile

how about

scope.function// the surrounding function
scope.method  // the surrounding method
scope.class   // the surrounding class
scope.class.outer // the outer class of the surrounding class

The current functions name, was requested so often:
scope.function.name

?


Re: could someone check this on another system?

2009-05-04 Thread BCS

Reply to Nick,


Ok, WinXP 32-bit, and on both 1.040 and 1.041 (byte-for-byte identical
output on both), my output from go.bat was:


...


true

---true



Hmm. IIRC my home box gave:

 true
--- false

but I just ran it on my work  boxes and got:

 false
--- false

I'll have to recheck the home machine. With a bit more digging it seems that 
right now I'm getting an almost equal error that writef was hiding by rounding. 
I've already got a fuzzy equal so I guess I just need to do some tuning.






Phobos2: iota, ranges, foreach and more

2009-05-04 Thread bearophile
I am learning a bit more about ranges. They aren't hard to use for simple 
things. Now I think I understand about 10% of this topic.

--

Can you tell me what is the name of the Phobos2 functioid that given a lazy 
argument, iterates on it and returns the eager array of all its items? (it's 
named array() in my libs and list() in Python).

--

Now I think iota() with just one argument is useful. When just one argument is 
specified, then it's meant as the stop value, and the start value is meant to 
be 0. This is handy, and it's the one used by range/xrange of Python.

--

While reading the source code of Phobos2 function calls like .front confuse 
me, I find .front() more readable. I think I am not the only one to think 
like this.

--

Into the source code of filter of algorithms I have seen something like:

ref SomeName opSlice() { return this; }

Recently Andrei has exmplained me:

People said, that sucks! With opApply I don't need to append the .all thingie! 
So I told Walter to automatically call [] against the container. So people can 
now write: [...] All the container has to to is define opSlice() to return its 
all range.

But if I comment out such ref opSlice() the Filter keeps working. What's the 
purpose of that operator inside Filter?

(And I have to learn still about that usage of ref of the return).

--

Regarding the popFront() name, isn't a name like next() (for forward 
iteration) enough and nicer? (But see below too).

--

empty(), front(), etc are operators of struct/classes. So why not use the 
standard name syntax for D operators?

popFront() = opNext()
empty() == opEmpty
front() == opFront()
etc.

--

Is Phobos2 missing the groupby() of my dlibs (and Python itertools) still?
I think this is a very important iterator. It simplifies lot of situations, 
because it represents a quite common idiom.

In a few days I may become able to write it myself for D2 too.

--

D2 ranges don't yet support the index (and other values, there can be more than 
two!), as you can use with opApply.

When the index is a simple integer, Python2.6 solves this simple indexing 
problem with the built-in enumerate() iterable that yields pairs (the 
starting point defaults to 0):

 s = hello
 for i, c in enumerate(s):
...   print i, c
...
0 h
1 e
2 l
3 l
4 o
 for i, c in enumerate(s, 10):
...   print i, c
...
10 h
11 e
12 l
13 l
14 o

I don't see enumerate() yet in Phobos2, it may often be a cleaner solution.

To solve the more general problem in D2, we can think about having more than 
one opFront():

opFront(), opFront2(), opFront3(), etc, that return Tuple!() with 1, 2, 3 
arguments.

And then the machinery of foreach can upack them:

int opFront() { return this.current; }
Tuple!(int, int) opFront2() { return tuple(count, this.current); }
Tuple!(int, int, int) opFront3() { return tuple(count, 10, this.current); }

foreach(x; Iter()) = calls opFront()
foreach(x,y; Iter()) = calls opFront2()
foreach(x,y,z; Iter()) = calls opFront3()
etc.

Then the front-end must guarantee to simplify away those temporary structs to 
remove the overhead.

You can't have two different 2-len structs, because overload on the return 
value doesn't exists, so the following (doable with opApply) may be impossible 
with ranges, but I think this is an acceptable limitation:

foreach(float x; Iter()) = calls one opFront()
foreach(int y; Iter()) = calls another opFront()

--

After thinking about it I am unable to find a better design: I now think that 
your splitter() has to work like the xsplitter() of my dlibs (mine is 
specialized for strings, and this is good, because you often use it for them), 
that is like the str.split() method of Python strings, but lazy.

The current design of splitter of Phobos2 is not good enough (beside the fact 
that it splits in a non intuitive way, but I think you have already fixed this 
in the next version of dmd). I'll probably ask again for this in future if you 
don't listen to this now, because as groupby() a splitter() is a very widely 
used operation.
See also the rsplit().

You can find the semantics of split/rsplit here:
http://docs.python.org/library/stdtypes.html#string-methods

Playing Five minutes with the Python shell (or with the xsplit of my dlibs) may 
help you copy the semantics correctly (I use the word copy because copying 
that semantics, for a lazy range, is the best thing to do here).

--

I have done some simple experiments with ranges, I'll write about them in a 
future post.

Bye,
bearophile


Re: New regex: Find?

2009-05-04 Thread Derek Parnell
On Mon, 04 May 2009 10:09:56 -0500, Andrei Alexandrescu wrote:

 dsimcha wrote:
 Is there an *efficient* way to simply test whether a given string contains a
 given regex in the new std.regex?  Using match() and testing for empty works,
 but this apparently triggers a bunch of unnecessary heap allocation.  If not,
 is this a universal enough feature to warrant an enhancement request?
 
 If you only search once, there will be allocation. However, if you 
 search for the same regex several times there will be no extra 
 allocation so the cost will be amortized.

ranslation: No, there isn't an *efficient* way.

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell


Re: Self function

2009-05-04 Thread Denis Koroskin

On Mon, 04 May 2009 23:52:56 +0400, bearophile bearophileh...@lycos.com wrote:

Sometimes I rename recursive functions, or I duplicate and modify them,  
and they stop working because inside them there's one or more copy of  
their old name, so for example they recurse to their old name.
So inside a function I'd like to have a standard name to call the  
function itself, useful for recursivity.
(If you have two or more recursive functions that call each other this  
idea can't be used, but I think such situations are uncommon enough to  
not deserve help from the language).


I have just discussed this in the Python newsgroup too:
http://groups.google.com/group/comp.lang.python/browse_thread/thread/d265da85d4b70eaf#

I use more recursivity in D than in Python, because Python has troubles  
with it.


In future in D2 you may use:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
mixin(__FUNCTION__ ~ (n - 1) * n);
}

But you can't use __FUNCTION__ into a delegate/function pointer/lambda  
because the name isn't available, and it's a bit ugly syntax anyway...


This looks a bit better:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
__self(n - 1) * n;
}

Other syntaxes are possible.

__self is a way to denote the pointer/delegate of the function currently  
being run, so I think the compiler is always able to that, for delegate/  
function pointers/ lambdas/ methods/ virtual methods/ opCalls too.


Bye,
bearophile


It was proposed awhile ago: 
http://www.digitalmars.com/d/archives/digitalmars/D/FUNCTION_84985.html

Andrei's respond:

I think instead of __FUNCTION__ we'll define a much more comprehensive 
static reflection facility.


You will have it as a human readable identifier too. The problem with
__FUNCTION__, __CLASS__ etc. is that the list of ad-hoc names (what
happened to __STRUCT__, __MODULE__ et al?) can go forever.

D2 will have reflection. (Walter doesn't know yet. He thinks D3 will 
have reflection.) It will be compile-time reflection because only 
run-time reflection only is missing the point.



This is a long discussion, but in brief any runtime reflection engine 
needs some sort of compile-time metadata infrastructure. Some languages 
don't make that accessible within the language itself. Runtime 
reflection has been explored extensively, its possibilities and 
limitations are pretty well understood, I hardly smothered a yawn 
reading all you wrote. Compile-time reflection is much less understood 
and hides many more exciting possibilities. With the advances in 
compiler technology implemented by Walter, we have a chance to tackle 
reflection in a systematic manner.




Re: Self function

2009-05-04 Thread bearophile
Denis Koroskin:
 It was proposed awhile ago: 
 http://www.digitalmars.com/d/archives/digitalmars/D/FUNCTION_84985.html

I am not asking for a static __function__ name, because you can't use it inside 
lambdas or function pointers/delegates. The __func I am talking about is a 
pointer/delegate, and I don't know if you can use a static solution once you 
start juggling function pointers around.

Bye,
bearophile


Re: Many questions

2009-05-04 Thread Yigal Chripun

Daniel Keep wrote:


Liang Du wrote:

Nick Sabalausky Wrote:

Fractal d294...@bsnow.net wrote in message 
news:gtlihm$tt...@digitalmars.com...
The namespaces: i used them with C++, and the idea of separation between 
the uses of types, makes a very good layout. Because some namespaces 
requires more types, always i write each class in separate files. D simply 
breaks it, making a big amount of lines for imports.



...

This works fine and does exactly what you want.


The namespaces is better !!!


That's debatable.  The hateful thing about namespaces is that they give
you absolutely ZERO clue as to where any particular thing is coming from.

If I see tango.io.device.File, I know exactly where the source for
that module is.

  -- Daniel


the downside to the current system is when you have one class in a file, 
the full name of it will be SomeClass.SomeClass instead of just 
SomeClass. (because of the redundancy of the module decl. in this case)


Ideally, I'd want at most one public root entity per file.
where entity can be a type (class/struct/union/etc..) _or_ a module. 
where a module is just a struct with all methods declared static by 
default (that exactly the same thing as today). that's also the same 
thing as the object in scala (if you look at this from an OO perspective).

i.e
object {
 ...
}

also, packaging needs to be enhanced to allow easier management of 
bigger projects.
for example, what if i want to have internal APIs to be used by my 
packages which are not exposed to the end user? the design should 
restrict the package layout as little as reasonably possible.


Re: Self function

2009-05-04 Thread Denis Koroskin

On Tue, 05 May 2009 02:30:49 +0400, bearophile bearophileh...@lycos.com wrote:


Denis Koroskin:
It was proposed awhile ago:  
http://www.digitalmars.com/d/archives/digitalmars/D/FUNCTION_84985.html


I am not asking for a static __function__ name, because you can't use it  
inside lambdas or function pointers/delegates. The __func I am talking  
about is a pointer/delegate, and I don't know if you can use a static  
solution once you start juggling function pointers around.


Bye,
bearophile


If you read carefully, you'll see that there's more than just __FUNCTION__. For 
example, I suggested to use some literal to denote current function, 
fthis/self/whatever. Others suggested scope.function/scope.class/etc. Andrei 
agreed that there should be a compile-time reflection that would allow function 
to call itself in some generic way.



Re: Many questions

2009-05-04 Thread bearophile
Yigal Chripun:
 the downside to the current system is when you have one class in a file, 
 the full name of it will be SomeClass.SomeClass instead of just 
 SomeClass. (because of the redundancy of the module decl. in this case)

Generally if classes or functions are small, you put more than one of them 
(related ones) in the same module.


 Ideally, I'd want at most one public root entity per file.

That's the Java ideal world.

Bye,
bearophile


Re: Many questions

2009-05-04 Thread Fractal
 That's debatable.  The hateful thing about namespaces is that they give
 you absolutely ZERO clue as to where any particular thing is coming from.
 
 If I see tango.io.device.File, I know exactly where the source for
 that module is.
 
   -- Daniel

Yes it is true. But the thing is not where is it. The thing that i want to 
remark is what long.

If you use a namespace, you can write many big classes in separate files 
without problem, and also, with the same namespace. (and also allowing separate 
a multiplatform class in different files, for each one).

With modules you are limited in a single file. And it will grow potentially 
with multiplatform code, and makes hard to find a error or line...
Added to it, the amout of version statements.

Also Namespaces can use upper case characters... documentation indicates that 
package and module names should be written all in lower case.

A good point for modules is the permisson to access private or protected 
members of types declared in the same module or package, without the friend 
keyword anywhere.
In namespaces, it can be done by sharing access to all namespace types.

Really module, packages, and namespaces are the same thing. The unique thing 
that i want, is the possibility of use many files as one (for modules)


Re: Many questions

2009-05-04 Thread bearophile
Fractal:
 Really module, packages, and namespaces are the same thing.

Not really :-) There are semantic differences.

Bye,
bearophile


Re: New regex: Find?

2009-05-04 Thread Derek Parnell
On Mon, 04 May 2009 16:45:35 -0500, Andrei Alexandrescu wrote:

 Your answer sounds as if it came from a politian. 
 
 I emphatically think not, as my answer was precise and did not try to 
 hide anything. Oh, whatever.

I apologize without reservation. 

I'm the type of person that thinks that if an answer can be stated as yes
or no, but with some qualifiations, then the answer ought to be given as
yes or no followed by the however part. But that's just me, going by the
response I get from most everyone I talk to. :-)

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell


Re: Many questions

2009-05-04 Thread Daniel Keep


Fractal wrote:
 That's debatable.  The hateful thing about namespaces is that they give
 you absolutely ZERO clue as to where any particular thing is coming from.

 If I see tango.io.device.File, I know exactly where the source for
 that module is.

   -- Daniel
 
 Yes it is true. But the thing is not where is it. The thing that i want to 
 remark is what long.
 
 If you use a namespace, you can write many big classes in separate files 
 without problem, and also, with the same namespace. (and also allowing 
 separate a multiplatform class in different files, for each one).

public import and mixin.

 With modules you are limited in a single file. And it will grow potentially 
 with multiplatform code, and makes hard to find a error or line...
 Added to it, the amout of version statements.

public import and mixin.

 Also Namespaces can use upper case characters... documentation indicates that 
 package and module names should be written all in lower case.

Oh what rubbish.  You can use whatever case you please.

 A good point for modules is the permisson to access private or protected 
 members of types declared in the same module or package, without the friend 
 keyword anywhere.
 In namespaces, it can be done by sharing access to all namespace types.
 
 Really module, packages, and namespaces are the same thing. The unique thing 
 that i want, is the possibility of use many files as one (for modules)

But you see, this would break bud, rebuild, etc.  I'm pretty sure that
if you somehow convinced Walter to do this, you would have a lot of VERY
angry people coming after you for completely breaking their build tools.

I know I would be.  I'm not going back to Make!  You can't make me!
Viva la laziness!

  -- Daniel


Re: Self function

2009-05-04 Thread Georg Wrede

bearophile wrote:

Sometimes I rename recursive functions, or I duplicate and modify

them, and they stop working because inside them there's one or more copy
of their old name, so for example they recurse to their old name.

So inside a function I'd like to have a standard name to call the

function itself, useful for recursivity.

(If you have two or more recursive functions that call each other
this

idea can't be used, but I think such situations are uncommon enough to
not deserve help from the language).


I have just discussed this in the Python newsgroup too:
http://groups.google.com/group/comp.lang.python/browse_thread/thread/d265da85d4b70eaf#

I use more recursivity in D than in Python, because Python has troubles with it.

In future in D2 you may use:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
mixin(__FUNCTION__ ~ (n - 1) * n);
}

But you can't use __FUNCTION__ into a delegate/function
pointer/lambdabecause the name isn't available, and it's a bit ugly
syntax anyway...

This looks a bit better:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
__self(n - 1) * n;
}

Other syntaxes are possible.

__self is a way to denote the pointer/delegate of the function
currently being run, so I think the compiler is always able to that, for
delegate/ function pointers/ lambdas/ methods/ virtual methods/ opCalls too.



Since you need this at compile time, then you don't need a pointer. A 
name would be enough.


If, as Denis pointed out, Andrei is going to provide that, and if it 
turns out to have a long name (like scope.function.name), then I hope it 
will be implemented so that you can alias that into something shorter, 
like thisf or me.


Re: Self function

2009-05-04 Thread BCS

Reply to Georg,


bearophile wrote:


Sometimes I rename recursive functions, or I duplicate and modify


them, and they stop working because inside them there's one or more
copy of their old name, so for example they recurse to their old name.


So inside a function I'd like to have a standard name to call the


function itself, useful for recursivity.


(If you have two or more recursive functions that call each other
this


idea can't be used, but I think such situations are uncommon enough to
not deserve help from the language).


I have just discussed this in the Python newsgroup too:
http://groups.google.com/group/comp.lang.python/browse_thread/thread/
d265da85d4b70eaf#

I use more recursivity in D than in Python, because Python has
troubles with it.

In future in D2 you may use:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
mixin(__FUNCTION__ ~ (n - 1) * n);
}
But you can't use __FUNCTION__ into a delegate/function
pointer/lambdabecause the name isn't available, and it's a bit ugly
syntax anyway...

This looks a bit better:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
__self(n - 1) * n;
}
Other syntaxes are possible.

__self is a way to denote the pointer/delegate of the function
currently being run, so I think the compiler is always able to that,
for
delegate/ function pointers/ lambdas/ methods/ virtual methods/
opCalls too.

Since you need this at compile time, then you don't need a pointer. A
name would be enough.

If, as Denis pointed out, Andrei is going to provide that, and if it
turns out to have a long name (like scope.function.name), then I hope
it will be implemented so that you can alias that into something
shorter, like thisf or me.




void main()
{
  int i = 0;
  auto dg = (int j)
  {
  i++;
  return j = 1 ? 1 : self(j-1) + self(j-2); 

  // self can't be a name as the function dosn't have a name 
  // and it can't be a compile time const at the context is not known.

  };

  dg(5);
}




Re: Phobos2: iota, ranges, foreach and more

2009-05-04 Thread Georg Wrede

bearophile wrote:


While reading the source code of Phobos2 function calls like .front
confuse me, I find .front() more readable. I think I am not the
only one to think like this.



The docs should be consistent and clear, also in trivial matters. If 
something is a function, then the parens should be there. The reader may 
know that you can omit the parens, but it has to be easy for him to 
recognize a name as a function.


Re: New regex: Find?

2009-05-04 Thread Joel C. Salomon
dsimcha wrote:
 Is there an *efficient* way to simply test whether a given string contains a
 given regex in the new std.regex?  Using match() and testing for empty works,
 but this apparently triggers a bunch of unnecessary heap allocation.  If not,
 is this a universal enough feature to warrant an enhancement request?

You mean to search for a regex match without constructing the regex
engine?  Good luck with that.

—Joel Salomon


Re: Phobos2: iota, ranges, foreach and more

2009-05-04 Thread Andrei Alexandrescu

Georg Wrede wrote:

bearophile wrote:


While reading the source code of Phobos2 function calls like .front
confuse me, I find .front() more readable. I think I am not the
only one to think like this.



The docs should be consistent and clear, also in trivial matters. If 
something is a function, then the parens should be there. The reader may 
know that you can omit the parens, but it has to be easy for him to 
recognize a name as a function.


Omitting parens gives more options. For example, infinite ranges are 
defined and recognized as:


enum bool empty = false;


Andrei


Re: New regex: Find?

2009-05-04 Thread dsimcha
== Quote from Joel C. Salomon (joelcsalo...@gmail.com)'s article
 dsimcha wrote:
  Is there an *efficient* way to simply test whether a given string contains a
  given regex in the new std.regex?  Using match() and testing for empty 
  works,
  but this apparently triggers a bunch of unnecessary heap allocation.  If 
  not,
  is this a universal enough feature to warrant an enhancement request?
 You mean to search for a regex match without constructing the regex
 engine?  Good luck with that.
 —Joel Salomon

Actually, the behavior Andrei describes is what I wanted:  One allocation to
construct the regex engine, amortized.  However, contrary to what Andrei said,
match() apparently allocates additional memory on each call.  The following
program leaks memory like a sieve when the GC is disabled:

import std.regex, core.memory;

void main() {
string s = This is only a test.  Repeat, this is only a test.;
auto r = regex(is.only);

GC.disable;
while(true) {
auto m = match(s, r);
}
}


Re: Many questions

2009-05-04 Thread Robert Fraser

Daniel Keep wrote:

Also Namespaces can use upper case characters... documentation indicates that 
package and module names should be written all in lower case.


Oh what rubbish.  You can use whatever case you please.


On Windows (actually NTFS, I think), you can't two packages/modules that 
differ only in case. But if you have namespaces XML, Xml and xml, 
you probably have some bigger design issues.


Re: Phobos2: iota, ranges, foreach and more

2009-05-04 Thread Nick Sabalausky
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message 
news:gto3np$2bl...@digitalmars.com...
 Georg Wrede wrote:
 bearophile wrote:

 While reading the source code of Phobos2 function calls like .front
 confuse me, I find .front() more readable. I think I am not the
 only one to think like this.


 The docs should be consistent and clear, also in trivial matters. If 
 something is a function, then the parens should be there. The reader may 
 know that you can omit the parens, but it has to be easy for him to 
 recognize a name as a function.

 Omitting parens gives more options. For example, infinite ranges are 
 defined and recognized as:

 enum bool empty = false;



See, this is a good reason why () vs no () should be dictated by the 
API, not the caller. Under the current system, there's nothing preventing 
someone from writing an is this range empty? check that seems to work on 
one range, but then fails to compile on any range that chooses to implement 
empty as in your example above. 




Re: Self function

2009-05-04 Thread Georg Wrede

BCS wrote:

Reply to Georg,


bearophile wrote:


Sometimes I rename recursive functions, or I duplicate and modify


them, and they stop working because inside them there's one or more
copy of their old name, so for example they recurse to their old name.


So inside a function I'd like to have a standard name to call the


function itself, useful for recursivity.


(If you have two or more recursive functions that call each other
this


idea can't be used, but I think such situations are uncommon enough to
not deserve help from the language).


I have just discussed this in the Python newsgroup too:
http://groups.google.com/group/comp.lang.python/browse_thread/thread/
d265da85d4b70eaf#

I use more recursivity in D than in Python, because Python has
troubles with it.

In future in D2 you may use:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
mixin(__FUNCTION__ ~ (n - 1) * n);
}
But you can't use __FUNCTION__ into a delegate/function
pointer/lambdabecause the name isn't available, and it's a bit ugly
syntax anyway...

This looks a bit better:

int ANUGLYNAME(int n) {
if (n = 1)
return 1;
else
__self(n - 1) * n;
}
Other syntaxes are possible.

__self is a way to denote the pointer/delegate of the function
currently being run, so I think the compiler is always able to that,
for
delegate/ function pointers/ lambdas/ methods/ virtual methods/
opCalls too.

Since you need this at compile time, then you don't need a pointer. A
name would be enough.

If, as Denis pointed out, Andrei is going to provide that, and if it
turns out to have a long name (like scope.function.name), then I hope
it will be implemented so that you can alias that into something
shorter, like thisf or me.




void main()
{
  int i = 0;
  auto dg = (int j)
  {
  i++;
  return j = 1 ? 1 : self(j-1) + self(j-2);
  // self can't be a name as the function dosn't have a name   
// and it can't be a compile time const at the context is not known.

  };

  dg(5);
}


Oh boy, I missed half of the post. (Note to self: remember use two eyes 
for reading. Especially at the wee hours.)


Re: New regex: Find?

2009-05-04 Thread Andrei Alexandrescu

dsimcha wrote:

== Quote from Joel C. Salomon (joelcsalo...@gmail.com)'s article

dsimcha wrote:

Is there an *efficient* way to simply test whether a given string contains a
given regex in the new std.regex?  Using match() and testing for empty works,
but this apparently triggers a bunch of unnecessary heap allocation.  If not,
is this a universal enough feature to warrant an enhancement request?

You mean to search for a regex match without constructing the regex
engine?  Good luck with that.
—Joel Salomon


Actually, the behavior Andrei describes is what I wanted:  One allocation to
construct the regex engine, amortized.  However, contrary to what Andrei said,
match() apparently allocates additional memory on each call.  The following
program leaks memory like a sieve when the GC is disabled:

import std.regex, core.memory;

void main() {
string s = This is only a test.  Repeat, this is only a test.;
auto r = regex(is.only);

GC.disable;
while(true) {
auto m = match(s, r);
}
}


Ah... Sigh, I meant to implement the short string optimization in the 
regex range, and put it off forever. It was about time it would come 
back to haunt me :o).


Could you please submit an enhancement request to Bugzilla? Maybe with a 
patch? :o)



Andrei


Re: Many questions

2009-05-04 Thread Christopher Wright

Fractal wrote:

That's debatable.  The hateful thing about namespaces is that they give
you absolutely ZERO clue as to where any particular thing is coming from.

If I see tango.io.device.File, I know exactly where the source for
that module is.

  -- Daniel


Yes it is true. But the thing is not where is it. The thing that i want to remark is 
what long.

If you use a namespace, you can write many big classes in separate files 
without problem, and also, with the same namespace. (and also allowing separate 
a multiplatform class in different files, for each one).

With modules you are limited in a single file. And it will grow potentially 
with multiplatform code, and makes hard to find a error or line...
Added to it, the amout of version statements.

Also Namespaces can use upper case characters... documentation indicates that 
package and module names should be written all in lower case.

A good point for modules is the permisson to access private or protected members of types 
declared in the same module or package, without the friend keyword anywhere.
In namespaces, it can be done by sharing access to all namespace types.

Really module, packages, and namespaces are the same thing. The unique thing 
that i want, is the possibility of use many files as one (for modules)


Modules are compilation units. This makes them different from namespaces.

Packages are for the compiler to find source code. Namespaces are for 
humans to find source code. These have sufficient overlap that they have 
been unified.


For modules to do what you want, a module cannot be the unit of 
compilation. What then will be the unit of compilation? And why is this 
feature important enough to merit the change?


Re: Absolutely horrible default string hashing

2009-05-04 Thread Sean Kelly

Andrei Alexandrescu wrote:


I have exchanged email with Paul Hsieh about using his hash function in 
Phobos (azillionmonkeys.com) and he said his license is very permissive. 
I seem to recall I have introduced his hash function, with credit, in 
Phobos' old runtime but I am not sure whether Sean took that over. I 
suggest we do that in druntime for string, be they mutable or not.


Unfortunately, that request is languishing in the oops, I forgot 
portion of my to-do list.


Re: Destructors and Deterministic Memory Management

2009-05-04 Thread Sean Kelly

dsimcha wrote:

Two closely related topics here:

1.  It is often nice to be able to create a single object that works with both
GC and deterministic memory management.  The idea is that, if delete is called
manually, all sub-objects would be freed deterministically, but the object
could still safely be GC'd.  Since the destructor called by the GC can't
reference sub-objects, would it be feasible to have two destructors for each
class, one that is called when delete is invoked manually and another that is
called by the GC?


You can do this today with both Druntime on D 2.0 and Tango on D 1.0, 
though it isn't the most performant approach.  The code would look 
something like this:


import core.runtime;

interface Disposable
{
void dispose();
}

bool handler( Object o )
{
auto d = cast(Disposable) o;

if( d !is null )
{
d.dispose();
return false;
}
return true;
}

static this()
{
Runtime.collectHandler = handler;
}

If you return false from your collectHandler then the runtime won't call 
the object's dtor.


A Modest Proposal: Final class instances

2009-05-04 Thread dsimcha
Several people have griped in the past that D class methods are virtual by
default.  I've pointed out to them that you can get around this by making the
methods final.  However, this is a bit of a blunt instrument, because some use
cases for a single class may call for polymorphism and other use cases for the
same class may call for fast performance and no polymorphism.  A possible
solution is, given a class:

class Foo {
// Actual implementation.
}

final class FooFinal : Foo{
// Dummy that just makes Foo final.
}

And then, when you need performance and not polymorphism, you would invoke
FooFinal instead of Foo.  However, this requires manual forwarding of
constructors and bloats the name space.  A simple syntactic sugar solution to
this dilemma that would add very little complexity to the language would be to
allow final to describe a class instance, as well as a class.  The following
would apply to a final instance:

1.  Method calls don't need to be virtual.
2.  An instance of a subclass cannot be converted to a final instance of the
base class.
3.  A final instance can be implicitly converted to a non-final instance, but
the opposite would not work.

Using final as an instance attribute like this would also allow another useful
feature:  Storing class instances inline in arrays, structs, or other classes.
 Basically, by marking a class instance as final, you'd be telling the
compiler that you do not need and are not using polymorphism in this case,
even if the class hierarchy uses it for other use cases, and therefore, all
relevant optimizations can be made.


DLLs and headaches

2009-05-04 Thread Unknown W. Brackets

This is kinda complicated, hopefully someone will still read it and try it.

DLLs typically don't have access to the host process.  Sometimes, when 
creating plugins, such access may be desirable.  The typical solution is 
to have the host and plugins both load a secondary DLL.


I've tried to replicate this with D.  I have a stub program, a primary 
dll, and a plugin dll.


Although the solution in itself does work, I'm having a lot of problems 
and they seem related to D.  But, maybe I'm just doing it all wrong?


If I import std.stdio in a DLL, it won't compile.  Period.  Otherwise, 
the primary DLL never finishes - it just dies when it frees the plugin 
library.


There are a bunch of files, unfortunately.  Listing below:

--- test.d ---
import std.c.stdio;
import primary;

extern (C)
void* gc_getProxy();

// Just a stub to load the primary code.
int main()
{
printf(Entering main().\n);

primary_init(gc_getProxy());
int ret = primary_main();
primary_terminate();

printf(Exiting main().\n);
return ret;
}
-

--- plugin.d ---
import core.runtime;
import std.c.stdio;
import std.c.windows.windows;

import primary;

extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
printf(DLL_PROCESS_ATTACH - plugin\n);
Runtime.initialize();
break;

case DLL_PROCESS_DETACH:
printf(DLL_PROCESS_DETACH - plugin\n);
Runtime.terminate();
break;

case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
return false;
}

return true;
}

// This is just here to load a plugin and export anything.
export void dummy()
{
}
-

--- plugin.def ---
LIBRARY plugin
DESCRIPTION 'Plugin Example'
EXETYPE NT
CODEPRELOAD DISCARDABLE
DATAPRELOAD SINGLE
-

--- primary.d ---
import std.c.windows.windows;
import core.runtime;
import std.c.stdio;

// SKIP_RUNTIME uses Windows instead of Runtime.*, makes no difference.

// FAIL2 shows that it won't even compile with std.stdio.
version (FAIL2)
import std.stdio;

extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
printf(DLL_PROCESS_ATTACH - primary\n);
Runtime.initialize();
break;

case DLL_PROCESS_DETACH:
printf(DLL_PROCESS_DETACH - primary\n);
Runtime.terminate();
break;

case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
return false;
}

return true;
}

extern (C)
{
void gc_setProxy(void* p);
void gc_clrProxy();
}

export void primary_init(void* gc)
{
printf(primary_init()\n);
gc_setProxy(gc);
}

export void primary_terminate()
{
printf(primary_terminate()\n);
gc_clrProxy();
}

export int primary_main()
{
HMODULE h;
FARPROC fp;
bool unloaded;

printf(Start Dynamic Link...\n);

version (SKIP_RUNTIME)
h = LoadLibraryA(plugin.dll);
else
h = cast(HMODULE) Runtime.loadLibrary(plugin.dll);
if (h is null)
{
printf(error loading plugin.dll\n);
return 1;
}

version (FAIL2)
writefln(hi);

version (SKIP_RUNTIME)
unloaded = FreeLibrary(h) != 0;
else
unloaded = Runtime.unloadLibrary(h);

if (!unloaded)
{   printf(error freeing plugin.dll\n);
return 1;
}

printf(End...\n);

return 0;
}
-

--- primary.def ---
LIBRARY primary
DESCRIPTION 'Primary Program'
EXETYPE NT
CODEPRELOAD DISCARDABLE
DATAPRELOAD SINGLE
-

--- compilation ---
echo === Compile the primary DLL.
dmd primary.d primary.def -g -L/map
implib /noi /system primary.lib primary.dll

echo === Compile the example plugin.
dmd plugin.d plugin.def primary.lib -g -L/map

echo === Compile the stub.
dmd test.d primary.lib -g
-

Anyone know anything?

-[Unknown]


Re: DLLs and headaches

2009-05-04 Thread Don

Unknown W. Brackets wrote:

This is kinda complicated, hopefully someone will still read it and try it.

DLLs typically don't have access to the host process.  Sometimes, when 
creating plugins, such access may be desirable.  The typical solution is 
to have the host and plugins both load a secondary DLL.


I've tried to replicate this with D.  I have a stub program, a primary 
dll, and a plugin dll.


Although the solution in itself does work, I'm having a lot of problems 
and they seem related to D.  But, maybe I'm just doing it all wrong?


If I import std.stdio in a DLL, it won't compile.  Period.  Otherwise, 
the primary DLL never finishes - it just dies when it frees the plugin 
library.


Is this D1 or D2?
If D2 -- I haven't been able to get D2 DLLs to work at all. They just 
crash during the initialization (something to do with initialising the 
thread-locals, I think, but I haven't been able to track it down 
completely).


Re: DLLs and headaches

2009-05-04 Thread Unknown W. Brackets
D2; but actually, it kinda works.  It crashes on freeing the library, 
but it loads fine.


If I use std.stdio, link says that primary.__ModuleInfo is missing, but 
that just means it crashes during compile/link.


That said, I'm very dissapointed that Runtime doesn't support Posix yet. 
 Means I'll have to roll it myself anyway.


-[Unknown]


Don wrote:

Unknown W. Brackets wrote:
This is kinda complicated, hopefully someone will still read it and 
try it.


DLLs typically don't have access to the host process.  Sometimes, when 
creating plugins, such access may be desirable.  The typical solution 
is to have the host and plugins both load a secondary DLL.


I've tried to replicate this with D.  I have a stub program, a 
primary dll, and a plugin dll.


Although the solution in itself does work, I'm having a lot of 
problems and they seem related to D.  But, maybe I'm just doing it all 
wrong?


If I import std.stdio in a DLL, it won't compile.  Period.  Otherwise, 
the primary DLL never finishes - it just dies when it frees the plugin 
library.


Is this D1 or D2?
If D2 -- I haven't been able to get D2 DLLs to work at all. They just 
crash during the initialization (something to do with initialising the 
thread-locals, I think, but I haven't been able to track it down 
completely).


Re: Need direction guide

2009-05-04 Thread Sam Hu
Hi Denis,

Thanks so much for your prompt response.

  1.Whether D1 is useful to do something,or it is quite worth to wait for  
  the stable or finalized verison of D2?If yes,what can one do using  
  D1,I mean not just a toy,a test product,rather an serious tool?
 
 It is very funny that you write that. D1 is a stable language and there is a 
 lot of code written using it.
 There is absolutely nothing that can be written in C++ and can't be in D 
 (unless you are writing for a memory-limited embedded device).
 In fact, D is a lot more powerful than C++ already, and it allows to you 
 complete the same task faster and with less code.
  
I do know many projects there written by D1,but how come D1 seems to ppl  just 
a  pass-by,please correct me if I am wrong.

  I am lost although I like D so much than C++.I would like to spend as  
  much time as learning C++ and want to gain as much as gain C++ can offer  
  me. Any constructive suggestions or guideline would be much appreicated.
 
 
 I'd suggest you to write more code, experience and knowledge comes with 
 practice. Pick a project and start writing code. Whenever you find a 
 difficulty, ask in newsgroups or in IRC (you usually get instant help there). 
 I'd also recommend you to find some people that use/learn D and speak your 
 language. For example, if you speak Chinese, d-programming-language-china.org 
 is a great resource for you. I believe there are a lot of people that would 
 be glad to help.
 
 Yes,you are right, I am a member of d-programming-language-china.org.Actually 
there is another one D forum which I think is more open,serious,intuitive and 
productive:
http://dlang.group.javaeye.com/
and I has tried to translate several Phobos lib into Chinese just as the others 
did.
But to be honest,almost all D members in the forum are a bit  lost for the 
going of D1 vs D2.We felt that D1 is workable but less less power than D2 or 
C++( almost not worth to use),D2 is what we expected and what we want but it 
seems we can never get it to work.

Thanks again.
Sam


Re: Need direction guide

2009-05-04 Thread Sam Hu
Correctness:
But to be honest,almost all D members in the forum are a bit  lost for the 
going of D1 vs D2---
Here the the forum I mean the Chinese D forums.


Re: Need direction guide

2009-05-04 Thread Denis Koroskin

On Mon, 04 May 2009 12:29:54 +0400, Sam Hu samhudotsa...@gmail.com wrote:

I have learnt C++ for years and can write simple and short toys.I have  
been following and learning D for quite a while but I can do nothing  
except finding ppl like you giant seems just write libs at this moment.I  
believe D2 is getting mre powerful and stronger but it seems to me just  
a legend.So right at this moment,I am wondering:
1.Whether D1 is useful to do something,or it is quite worth to wait for  
the stable or finalized verison of D2?If yes,what can one do using  
D1,I mean not just a toy,a test product,rather an serious tool?


It is very funny that you write that. D1 is a stable language and there is a 
lot of code written using it.
There is absolutely nothing that can be written in C++ and can't be in D 
(unless you are writing for a memory-limited embedded device).
In fact, D is a lot more powerful than C++ already, and it allows to you 
complete the same task faster and with less code.

2.Are those feathers in D2 vital  while D1 does not have?Or all these  
features are just for experienced programmers,a beginner can just ignore  
them at present?




I believe there is little difference between programming in D1 or D2 for a 
novice, but I'd recommend sticking with D1 for now because it is more stable, 
has a lot more code pre-written for you, common problems are solved, more 
experts available etc.

I am lost although I like D so much than C++.I would like to spend as  
much time as learning C++ and want to gain as much as gain C++ can offer  
me. Any constructive suggestions or guideline would be much appreicated.




I'd suggest you to write more code, experience and knowledge comes with 
practice. Pick a project and start writing code. Whenever you find a 
difficulty, ask in newsgroups or in IRC (you usually get instant help there). 
I'd also recommend you to find some people that use/learn D and speak your 
language. For example, if you speak Chinese, d-programming-language-china.org 
is a great resource for you. I believe there are a lot of people that would be 
glad to help.

There is also russian community located at dprogramming.ru


Regards,
Sam





Re: .dup is null

2009-05-04 Thread Qian Xu
Steven Schveighoffer wrote:

 I think you might have a bug?
 
 .dup is the same as s.dup, not sure why you would expect it to be
 not-null.
 
 -Steve

If I have not explained clearly. 
Here is the full code:

  char[] s;
  assert(s is null);
  assert(s.dup is null);

  assert( !is null); // OK
  assert(.dup !is null); // FAILED

At least the last two lines behave not consistent. 
Either both are failed, or both are passed. 



Re: .dup is null

2009-05-04 Thread Steven Schveighoffer
On Mon, 04 May 2009 10:22:49 -0400, Qian Xu quian...@stud.tu-ilmenau.de  
wrote:



Steven Schveighoffer wrote:


I think you might have a bug?

.dup is the same as s.dup, not sure why you would expect it to be
not-null.

-Steve


If I have not explained clearly.
Here is the full code:

  char[] s;
  assert(s is null);
  assert(s.dup is null);

  assert( !is null); // OK
  assert(.dup !is null); // FAILED

At least the last two lines behave not consistent.
Either both are failed, or both are passed.



OK, your original post was this:

  assert( s.dup  is null); // OK
  assert(.dup !is null); // FAILED


The compiler always returns a null array if you dup an empty array.  The  
reason being: why allocate memory for something that is zero length?


If anything, the oddity is this line:

assert( !is null);

But of course, no memory is allocated for literals, so at least needless  
memory allocation does not occur.


To be consistent, I think assert( is null); should pass, but it's a  
minor inconsistency at best.


I usually never compare arrays to null for this reason...

-Steve


.dup is null

2009-05-04 Thread Qian Xu
Hi All,

The following code will throw an exception: 
  char[] s;
  assert( s.dup  is null); // OK
  assert(.dup !is null); // FAILED

.dup is expectly also an empty string. 
Is this a compiler bug?

--Qian




Re: Need direction guide

2009-05-04 Thread Jarrett Billingsley
On Mon, May 4, 2009 at 5:55 AM, Sam Hu samhudotsa...@gmail.com wrote:
 Correctness:
 But to be honest,almost all D members in the forum are a bit  lost for the 
 going of D1 vs D2---
 Here the the forum I mean the Chinese D forums.

Then more of you should speak up in the newsgroups.  Walter doesn't
speak Chinese.


Re: Need direction guide

2009-05-04 Thread Jarrett Billingsley
On Mon, May 4, 2009 at 5:52 AM, Sam Hu samhudotsa...@gmail.com wrote:

 I do know many projects there written by D1,but how come D1 seems to ppl  
 just a  pass-by,please correct me if I am wrong.

Where do you get that impression?  Most code that has been written in
D has been written in D1.  Most D libraries are D1-only or at least
D1-compatible.  There is a very small number of D2 projects, and given
how much D2 and Phobos 2 are changing, I doubt that they're terribly
stable.

If you get the impression that since most of the discussions are about
D2 then D1 is dead, well, no.  It's just that D1 doesn't (and can't)
change anymore, so there's no point discussing it.


Re: .dup is null

2009-05-04 Thread Steven Schveighoffer

On Mon, 04 May 2009 12:09:09 -0400, Georg Wrede georg.wr...@iki.fi wrote:

If I remember correctly, string literals are stored with a null  
appended, so as to make them easier to use with OS calls, etc. Could it  
be that  stores a 1-byte string, consisting with just this null? Then  
this behavior would be understandable.


Yes, that makes complete sense, thanks.

-Steve


Re: D styled data format, Json failed

2009-05-04 Thread nobody
Saaa em...@needmail.com wrote in message 
news:gtlrs3$1b9...@digitalmars.com...

 I looked at the JSON format and it seems very inefficient at loading 
 arrays as it isn't limited to one type per array.
 This is nice when you want to save a small array with different typed 
 elements but for my purposes this is kind of a performance problem.

 This is why I will try and get suggestions again about the D-styled format 
 I tried to suggest a few threads ago :)

 Let me suggest a simple example:
 (Please tell me when something isn't obvious :)

 ---file.dat
 //comment
 int number = 10;

 float [3][2]  simpleArray = [
 [0.1, 0.2, 0.3],
 [0.4, 0.5, 0.6]];
 --

 ---main.d
 static import ddata;
 void main()
 {
 char[][] file = read (`file.dat`);
 int i;
 char c;

 ddata.get(file,'number',i);
 ddata.get(file,'number',c); //type fail, thus returns -1 or throws an 
 exception

 float [3][2] a;

 ddata.get(file,'simpleArray',a);
 ddata.write(file,'simpleArrayCopy', a);

 a[0][0] =3.0;

 ddata.write(file,'simpleArray', a);

 write('file.dat', file);
 }
 --

 resulting data file:

 ---file.dat
 //comment
 int number = 10;

 float [3][2]  simpleArray = [
 [3.0, 0.2, 0.3],
 [0.4, 0.5, 0.6]];

 float [3][2]  simpleArrayCopy = [
 [0.1, 0.2, 0.3],
 [0.4, 0.5, 0.6]];
 -- 



I've run into similar problems when I wanted to save lots of stuff to a 
file, and be able to load them again.
Huge multi-dimensional arrays seem to be an issue with JSON and similar..

Such a file writer as you propose would be very handy to have. 




[Issue 911] expression.c:4257: virtual Expression* DotIdExp::semantic(Scope*): Assertion `0' failed.

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=911





--- Comment #7 from clugd...@yahoo.com.au  2009-05-04 05:29 ---
This all works for me on both DMD1.042 and 2.029 Windows.
Can someone who observed the original bug confirm that it is fixed?


-- 



[Issue 2917] std.date fails for all years before 1970

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2917





--- Comment #1 from ghaec...@idworld.net  2009-05-04 05:39 ---
Created an attachment (id=348)
 -- (http://d.puremagic.com/issues/attachment.cgi?id=348action=view)
patch for std.date.d v. 2.029 fixes issues with negative time values

Rather than whine about the date issues, I decided to lend a hand and address
the issues myself.  If you find the modifications useful you are welcome to use
the code in any way you see fit.  I only added my name as a modifier so that
Walter won't get blamed for any mistakes I made.  You may remove my name or
leave it, as you see fit.  The changes I made aren't anything special; just
some grunt work that needed doing.

I tinkered with some of the more vital functions in this module.  In
particular, I modified floor(), dmod(), day(), and dayFromYear().  The latter
got a little messy with year value 0 and lower.  Of course, pushing the
Gregorian calendar back that far back is purely hypothetical.  I added unittest
sections to day() and dayFromYear, as the proper working of these functions is
vital to the entire module.

I threw in a bit of trivial tidying up as well.  The calls to toInteger() and
timeClip() were removed, since they don't do anything.  I left the functions in
place, in case some existing code calls them.  I changed the name of the 'day'
variable that called the day() function, as it seems like a bad idea to
duplicate the name in the same scope.

I added an overload for dateFromTime(d_time t, int months).  In most cases,
where it's used in the module, the value for month is already known, so there's
no need for dateFromTime() to recalculate it.

My addition of toDbDateTime() is trivial, but I found it useful in testing, and
it has practical value.  It's a fairly common format, and it doesn't add much
weight to the module.

I also added two other functions: addMonths() and addYears().  These are both
common date/time-manipulation tasks, which aren't as straightforward as adding
fixed values like days or weeks.  addMonths() is rather clunky, but it gets the
job done.  It never cranks through more than 11 months on any call.  Beyond 11,
it calls addYears() so that adding 60 months is almost as quick as adding 5
years.

I've rebuilt the 2.029 library with this patch to std.date on linux.  All
appears to be working well.  Someone needs to test the DosDate functions to
make sure my changes didn't break them.  There were no unit tests for them.  I
don't have D installed on a Windows box.

Thanks in advance for considering these changes.


-- 



[Issue 911] expression.c:4257: virtual Expression* DotIdExp::semantic(Scope*): Assertion `0' failed.

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=911


clugd...@yahoo.com.au changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||FIXED




--- Comment #9 from clugd...@yahoo.com.au  2009-05-04 06:58 ---
Fixed sometime before DMD1.042 and D2.029.


-- 



[Issue 1984] Assertion failure: 'e1-type' on line 1198 in file 'constfold.c'

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1984





--- Comment #2 from clugd...@yahoo.com.au  2009-05-04 07:11 ---
Reduced test case shows it's a problem with CTFE and AA literals.

immutable bool [int] map = [ 4:true, 5:true ];
int foo () {
foreach (x; map.keys) {}
return 3;
}

static int x = foo();


-- 



[Issue 302] in/out contract inheritance yet to be implemented

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=302





--- Comment #12 from ma...@pochta.ru  2009-05-04 08:11 ---
Caller can't check descendant contracts, which can succeed.


-- 



[Issue 2913] aliasing a ref type is not possible

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2913





--- Comment #3 from ma...@pochta.ru  2009-05-04 08:44 ---
dup of bug 2753?


-- 



[Issue 2935] New: ICE(out.c) using struct with constructor as function default argument

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2935

   Summary: ICE(out.c) using struct with constructor as function
default argument
   Product: D
   Version: 2.029
  Platform: PC
OS/Version: Windows
Status: NEW
  Keywords: ice-on-valid-code
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: bugzi...@digitalmars.com
ReportedBy: clugd...@yahoo.com.au


This is a variation of bug 2437, but ICEs in a completely different place.
---
struct Foo{
   int z;
   this(int a){z=a;}
}
void bar(Foo a = Foo(1)){ }
void foo() { bar(); }
---
Internal error: ..\ztc\out.c 1199


-- 



[Issue 1994] Assertion failure: 't-deco' on line 597 in file 'mtype.c'

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1994


clugd...@yahoo.com.au changed:

   What|Removed |Added

 CC||ac...@free.fr




--- Comment #10 from clugd...@yahoo.com.au  2009-05-04 08:05 ---
*** Bug 2589 has been marked as a duplicate of this bug. ***


-- 



[Issue 2589] assertion failure when a struct contains a forward referenced, aliased function member.

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2589


clugd...@yahoo.com.au changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||DUPLICATE




--- Comment #2 from clugd...@yahoo.com.au  2009-05-04 08:05 ---


*** This bug has been marked as a duplicate of 1994 ***


-- 



[Issue 2934] New: .dup does not return empty string

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2934

   Summary: .dup does not return empty string
   Product: D
   Version: unspecified
  Platform: PC
OS/Version: Linux
Status: NEW
  Severity: normal
  Priority: P2
 Component: DMD
AssignedTo: bugzi...@digitalmars.com
ReportedBy: qian...@funkwerk-itk.com


The following code will throw an exception: 
  char[] s;
  assert( s.dup  is null); // OK
  assert(.dup !is null); // FAILED

.dup is expectly also an empty string.

Confirmed with dmd v1, gdc


-- 



[Issue 2934] .dup does not return empty string

2009-05-04 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=2934


schvei...@yahoo.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||INVALID




--- Comment #2 from schvei...@yahoo.com  2009-05-04 12:45 ---
From posts in the newsgroup, I've determined that this bug is invalid:

1. Duplicating an empty array should always return a null array.  Otherwise,
you'd have to allocate space to store 0 data bytes in order for the result to
be non-null.

2. String literals have a null character implicitly appended to them by the
compiler.  This is done to ease calling c functions.  So a string literal's
pointer cannot be null, since it has to point to a static zero byte.

The spec identifies specifically item 2 here:
http://www.digitalmars.com/d/1.0/arrays.html#strings

see the section describing C's printf and Strings

I could not find a reference for item 1, but I remember reading something about
it.  Regardless of it is identified specifically in the spec or not, it is not
a bug, as the alternative would be to allocate blocks for 0-sized arrays.


-- 



Re: [Issue 2934] .dup does not return empty string

2009-05-04 Thread Derek Parnell
On Mon, 4 May 2009 17:44:56 + (UTC), d-bugm...@puremagic.com wrote:

 http://d.puremagic.com/issues/show_bug.cgi?id=2934
 
 schvei...@yahoo.com changed:
 
What|Removed |Added
 
  Status|NEW |RESOLVED
  Resolution||INVALID
 
 --- Comment #2 from schvei...@yahoo.com  2009-05-04 12:45 ---
 From posts in the newsgroup, I've determined that this bug is invalid:
 
 1. Duplicating an empty array should always return a null array.  Otherwise,
 you'd have to allocate space to store 0 data bytes in order for the result to
 be non-null.
 
 2. String literals have a null character implicitly appended to them by the
 compiler.  This is done to ease calling c functions.  So a string literal's
 pointer cannot be null, since it has to point to a static zero byte.
 
 The spec identifies specifically item 2 here:
 http://www.digitalmars.com/d/1.0/arrays.html#strings
 
 see the section describing C's printf and Strings
 
 I could not find a reference for item 1, but I remember reading something 
 about
 it.  Regardless of it is identified specifically in the spec or not, it is not
 a bug, as the alternative would be to allocate blocks for 0-sized arrays.

Huh??? Duplicating something should give one a duplicate.

I do not think that this is an invalid bug.

Ok, so duplicating an empty array causes memory to be allocated - so what!
I asked for a duplicate so give me a duplicate, please.

To me, the no surprise path is simple. Duplicating an empty array should
return an empty array. Duplicating a null array should return a null array.

Is that not intuitive?

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell


  1   2   >