Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Pelle Månsson wrote:

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Your Hallå Värd! should be Hallå Värld!, to be Swedish. D:


Thanks! Ouch, two mistakes in one word. Also, should I put a comma in 
between the words?


Also, I am wondering, why is the undefined behavior of opCatAssign kept? 
Couldn't every T[] know if it is the owner of the memory in question? 
Sorry if I bring outdated discussions up unnecessarily.


We don't know how to do that cheaply.


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Ellery Newcomer wrote:

Andrei Alexandrescu wrote:

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.

http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Maybe I haven't been paying attention lately, but shouldn't

assert(x == 0)

be

assert(x[] == 0)

?


Where does the former occur?

Thanks,

Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Saaa
Also, no mention about .dup not being a deep dup. 




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Saaa
crp
 p20. 40 words? 
those  where for myself, to check 




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Ellery Newcomer
Andrei Alexandrescu wrote:
 Ellery Newcomer wrote:
 Andrei Alexandrescu wrote:
 It's a rough rough draft, but one for the full chapter on arrays,
 associative arrays, and strings.

 http://erdani.com/d/thermopylae.pdf

 Any feedback is welcome. Thanks!


 Andrei

 Maybe I haven't been paying attention lately, but shouldn't

 assert(x == 0)

 be

 assert(x[] == 0)

 ?
 
 Where does the former occur?
 
 Thanks,
 
 Andrei

top of page 102


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Robert Jacques wrote:
On Thu, 29 Oct 2009 00:38:33 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:


It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Still reading, but here's a quick comment. I found it odd that the 
syntax for element-wise copying (4.1.7) comes sections after the section 
on copying (4.1.4). Perhaps a sentence mentioning where element-wise 
copying can be found would be appropriate. (Props though on including a 
memory layout figure. It may not seem like much, but I've seen Java 
students have no idea what an array is in memory.)


Good point, thanks.

Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Tom S

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Thanks for the excerpt! I've only had the time to give it a brief skim 
so far, but it's looking good. This is what I found:


p16: int quadrupeds[100], int legs[4 * quadrupeds.length]  -  is the 
C-style array declaration syntax intended?

p20: No mention of the new T[][](rows, cols) syntax?
p26 (User-Defined Types as Keys): No need for opEquals?


--
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode


Re: LLVM 2.6 Release!

2009-10-29 Thread Nick B

bearophile wrote:

Andrei Alexandrescu:

[snip]
 You can see an example of this from the missing videos/PDFs of the 
last conference, they were not allowed to show them, because Apple is 
sometimes even more corporative than Microsoft:

http://llvm.org/devmtg/2009-10/

Bye,
bearophile


Bearophile

Thanks for the link. By the way there is quite a interesting talk from
David Greene from CRAY using LLVM titled LLVM on 180k Cores.

cheers
Nick B.


Re: ICE: template.c:806: failed assertion `i parameters-dim'

2009-10-29 Thread Don

grauzone wrote:

Don wrote:

Jacob Carlborg wrote:

On 10/28/09 16:32, Don wrote:

Jacob Carlborg wrote:

I have quite a big project and when I compile it I get this internal
compiler error: template.c:806: failed assertion `i  
parameters-dim'.

I don't know what could cause that error so I don't know where to look
in my code to try to produce a small test case and report an issue.
I'm using quite a lot of templates, template mixins and string mixins.


Bugzilla 2229. Was fixed in DMD1.049.
There have been about 60 ICE bugs fixed since 1.045.
I want to find out what the regressions are that are stopping people
from using the latest DMD -- it's time for the ICE age to end.


I haven't been using any later version because of various known 
regressions, I think they've been solved know. I tried to compile 
Tango trunk with DMD trunk and it failed with:


/Users/doob/development/d/tango-trunk/build/user/../../user/tango/io/compress/BzipStream.d(270): 
Error: var has no effect in expression (w)


It's returning a value in a void function.

I don't know if it's a regression that hasn't been solved or if it's 
something wrong with Tango.


The compiler now catches a few bugs that used to slip past before. 
Just change the return w; into return;.


I thought that was a feature?


It's OK for a void function to return another void function, and it's OK 
if the expression has side-effects. The situations which have been 
disallowed are ones where the compiler used to completely ignore the 
expression, generating no code at all. It's now treated exactly the same 
as if you wrote:


 w;
 return;

The bug was that although the compiler has always done that 
transformation, it wasn't running the semantic pass on it.


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Lars T. Kyllingstad

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei



It's a very pleasant read, and it looks good. I guess I'll have to buy 
the book. :) I just have two comments:


Code snippet in 4.2.1: Why do you suddenly use postfix array declaration 
here?


Code snippet just before 4.4.3: (yowza !in aa) doesn't work, at least 
not with DMD 2.035. It has to be !(yowza in aa). Very annoying.


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Lars T. Kyllingstad

Andrei Alexandrescu wrote:

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

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.
http://erdani.com/d/thermopylae.pdf
Any feedback is welcome. Thanks!
Andrei


Given that new is all over the place, does this mean we're not getting 
rid of new

before D2 goes gold?


I guess we need to compromise.

Andrei



I got the impression from previous discussions that this would be a 
rather simple thing to implement. Also, the community mostly seemed to 
agree that ditching new would be a good thing. What are the obstacles?


-Lars


Re: What Does Haskell Have to Do with C++?

2009-10-29 Thread Don

Andrei Alexandrescu wrote:

Don wrote:

Jeremie Pelletier wrote:
http://bartoszmilewski.wordpress.com/2009/10/21/what-does-haskell-have-to-do-with-c/ 



Bartosz's second part of 'Template Metaprogramming Made Easy (Huh?)', 
its quite a read :)


Yes, it is excellent. Two comments:
(1) Bartosz's D examples make me seriously question 'static foreach' 
which is scheduled for implementation (bugzilla 3377).
If implemented, it will be a source of frustration, since it will not 
be very usable inside templates. The ability to exit from a 'static 
foreach' is something which is possible with a 'return'-style syntax, 
but is not possible with the 'eponymous template hack'.


I think breaking early out of a static foreach is not necessary (but 
indeed convenient) for writing good loops.


(2) It seems pretty clear that we need to allow the eponymous trick to 
continue to work when more than one template member is present. I 
think everyone who's ever attempted template metaprogramming in D has 
proposed  it!


Yes, that was on the list for a long time. Bartosz even has participated 
to many related discussions. I'm surprised the article made it seem an 
unescapable matter of principles, when it clearly is a trivially fixable 
bug in the language definition.


Yes, looking at the compiler source, it doesn't look too difficult.  The 
fact that something like this works:


template foo(int X)
{
   static if (bar!(X)) { const int foo = 57; }
   else { const char [] foo = abc; }
}
makes it pretty clear that the difficult part has already been done.

I don't know what happens with template mixins, though. I hate template 
mixins (and I'm not convinced they're useful for anything, either).


We discussed using this instead of the template's name, but that has a 
few ambiguity problems. Currently, we want to allow a template to define 
private symbols in addition to the eponymous trick (a term that Bartosz 
shouldn't have implied paternity of, sigh). Those private members would 
be accessible from inside the template's definition, but not from the 
outside. That would effectively remove the issue.



Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Pelle Månsson

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Your Hallå Värd! should be Hallå Värld!, to be Swedish. D:

Also, I am wondering, why is the undefined behavior of opCatAssign kept? 
Couldn't every T[] know if it is the owner of the memory in question? 
Sorry if I bring outdated discussions up unnecessarily.


Re: What Does Haskell Have to Do with C++?

2009-10-29 Thread Kagamin
Don Wrote:

 I don't know what happens with template mixins, though. I hate template 
 mixins (and I'm not convinced they're useful for anything, either).

Sometimes in C macros are used like template mixins in D.


Re: Shared Hell

2009-10-29 Thread Kagamin
Walter Bright Wrote:

 A function that accesses shared data has to put in fences. There's no 
 way to have the same code deal with shared and unshared code.

Shared code perfectly deals with unshared data (it's not guaranteed that shared 
data is accessed by more than one thread). In other words unshared data is 
implicitly castable to shared.


Re: Shared Hell

2009-10-29 Thread Kagamin
Kagamin Wrote:

 Walter Bright Wrote:
 
  A function that accesses shared data has to put in fences. There's no 
  way to have the same code deal with shared and unshared code.
 
 Shared code perfectly deals with unshared data (it's not guaranteed that 
 shared data is accessed by more than one thread). In other words unshared 
 data is implicitly castable to shared.

Uh... this post was a little fast, ignore it, please.


Re: Shared Hell

2009-10-29 Thread Kagamin
Christopher Wright Wrote:

  A function that accesses shared data has to put in fences. There's no 
  way to have the same code deal with shared and unshared code.
 
 Acquiring a lock on a non-shared instance is safe, just an unnecessary 
 expense. I would have looked into optimizing this expense away rather 
 than punting the problem to the programmer.

Shared code can put data into *really* shared environment, which must not 
happen for unshared data.


Re: What Does Haskell Have to Do with C++?

2009-10-29 Thread Bill Baxter
On Thu, Oct 29, 2009 at 1:47 AM, Don nos...@nospam.com wrote:
 Andrei Alexandrescu wrote:

 Don wrote:

 Jeremie Pelletier wrote:


 http://bartoszmilewski.wordpress.com/2009/10/21/what-does-haskell-have-to-do-with-c/

 Bartosz's second part of 'Template Metaprogramming Made Easy (Huh?)',
 its quite a read :)

 Yes, it is excellent. Two comments:
 (1) Bartosz's D examples make me seriously question 'static foreach'
 which is scheduled for implementation (bugzilla 3377).
 If implemented, it will be a source of frustration, since it will not be
 very usable inside templates. The ability to exit from a 'static foreach' is
 something which is possible with a 'return'-style syntax, but is not
 possible with the 'eponymous template hack'.

 I think breaking early out of a static foreach is not necessary (but
 indeed convenient) for writing good loops.

 (2) It seems pretty clear that we need to allow the eponymous trick to
 continue to work when more than one template member is present. I think
 everyone who's ever attempted template metaprogramming in D has proposed
  it!

 Yes, that was on the list for a long time. Bartosz even has participated
 to many related discussions. I'm surprised the article made it seem an
 unescapable matter of principles, when it clearly is a trivially fixable bug
 in the language definition.

 Yes, looking at the compiler source, it doesn't look too difficult.  The
 fact that something like this works:

 template foo(int X)
 {
   static if (bar!(X)) { const int foo = 57; }
   else { const char [] foo = abc; }
 }
 makes it pretty clear that the difficult part has already been done.

 I don't know what happens with template mixins, though. I hate template
 mixins (and I'm not convinced they're useful for anything, either).

I don't think there's a problem with template mixins.  Templates for
mixin purposes are not generally the eponymous variety.  I don't think
any of the eponymous magic comes into play when you mix-in a template.
 At least I don't see why it would.

And I do think template mixins are useful.  I've seen some pretty
nifty things done where you pass in a template as an alias template
parameter to a class, and then mix that in.  That can be a pretty
powerful way to create extensible classes (or structs even) without
inheritance.

--bb


Re: GC Precision

2009-10-29 Thread bearophile
dsimcha:

 A moving GC, one that doesn't stop the world on collection,
 and one that's fully precise including stack would be nice, but they're 
 several
 orders of magnitude less important and would also have more ripple effects.

I agree that here doing something simple now is better than doing nothing or 
doing something very refined in an unknown future.

And in future things may be improved. In D objects are always managed by 
reference, and I think that most programs don't alter or cast such references 
to something else (objects allocated on memory specified by the programmer, and 
scoped objects allocated on the stack may be excluded from this). So I think 
that it can be safe to move objects, to compact the heap.

So you may have 5 memory zones:
- C heap. (The type system of the D compiler may see the C-heap pointers and 
D-heap pointers as two different types, as I have proposed in the past. So you 
need casts if you want to mix them, and the compiler can use the D moving heap 
in a safer way).
- Pinned D heap for everything can't be moved, like structs managed by pointers 
(eventually a D compiler can infer at compile time that some structs too may be 
moved around, because their pointer is used only in clean ways (you don't need 
to introduce struct references for this)). I think SafeD modules will not use 
this heap a lot (but they can use unsafe modules that may use pinned objects. 
Is D safety transitive? I think it is not, so from a SafeD module you can call 
and use an unsafe module);
- Old object generation managed with compaction (I think there's no need for 
the permanent objects zone in D);
- Two from and to zones for the young generation, that don't use a true 
compaction strategy, young objects bounce between them;
- New generation Eden where new object allocations happen managed as a memory 
arena.

All this has the disadvantage of requiring a more complex GC, and probably 
requiring 2-4 times more RAM at runtime. It hopefully has the advantage of 
allowing new programmers, that have learnt Java at university, to program in 
almost like in Java. (I have found a not-synthetic Java benchmark program that 
converted to D is something like 18 times slower on LDC. I'll put the code in 
my site in the following days).

Bye,
bearophile


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread bearophile
Andrei Alexandrescu:

 http://erdani.com/d/thermopylae.pdf
 Any feedback is welcome. Thanks!

So far I've just taken a look, I'll read it when I can. I can see several 
warnings in red.
The look of the text is really nice! Elegant, and the images are good and 
necessary. Are you going to write a book with all pages coloured? If true this 
will increase the book price, I think.
I have seen that you use a nice fount for the nonproportional text (like code), 
it looks similar to the Consolas. You may try this one too (but it's not a 
professional product, it may have some rough details):
http://www.fantascienza.net/leonardo/ar/inconsolatag/inconsolata-g_font.zip

Bye,
bearophile


Re: associative arrays: iteration is finally here

2009-10-29 Thread bearophile
Andrei Alexandrescu:

 I'll make aa.remove(key) always work and return a bool that tells you 
 whether there was a mapping or not.

I think that's a small design mistake. In a high level language you want things 
to not fail silently. You want them to fail in an explicit way because 
programmers often forget to read and use return values.

So AAs may have two methods, remove and drop (Python sets use remove and 
discard for this). The remove can be the safer one and used by default in D 
programs (especially in SafeD modules, safety is in things like this too), that 
raises an exception when you try to remove a missing key. drop/discard is 
faster and silent, it removes the key if it's present, as you want.

Bye,
bearophile


Re: Shared Hell

2009-10-29 Thread Christopher Wright

Kagamin wrote:

Christopher Wright Wrote:

A function that accesses shared data has to put in fences. There's no 
way to have the same code deal with shared and unshared code.
Acquiring a lock on a non-shared instance is safe, just an unnecessary 
expense. I would have looked into optimizing this expense away rather 
than punting the problem to the programmer.


Shared code can put data into *really* shared environment, which must not 
happen for unshared data.


Okay, but the compiler can try copying the method, removing the 'shared' 
storage class, and running semantic on the result. If that succeeds, 
you're guaranteed not to be doing anything that would be unsafe unless 
you're casting, and you can call the shared method on a local instance.


This lets you avoid whole program analysis and blacklisting unsafe 
operations.


In this case, the compiler can also point to the line of code that 
prevents the method from being marked not shared.


Re: What Does Haskell Have to Do with C++?

2009-10-29 Thread Christopher Wright

Don wrote:

Andrei Alexandrescu wrote:

Don wrote:

Jeremie Pelletier wrote:
http://bartoszmilewski.wordpress.com/2009/10/21/what-does-haskell-have-to-do-with-c/ 



Bartosz's second part of 'Template Metaprogramming Made Easy 
(Huh?)', its quite a read :)


Yes, it is excellent. Two comments:
(1) Bartosz's D examples make me seriously question 'static foreach' 
which is scheduled for implementation (bugzilla 3377).
If implemented, it will be a source of frustration, since it will not 
be very usable inside templates. The ability to exit from a 'static 
foreach' is something which is possible with a 'return'-style syntax, 
but is not possible with the 'eponymous template hack'.


I think breaking early out of a static foreach is not necessary (but 
indeed convenient) for writing good loops.


(2) It seems pretty clear that we need to allow the eponymous trick 
to continue to work when more than one template member is present. I 
think everyone who's ever attempted template metaprogramming in D has 
proposed  it!


Yes, that was on the list for a long time. Bartosz even has 
participated to many related discussions. I'm surprised the article 
made it seem an unescapable matter of principles, when it clearly is a 
trivially fixable bug in the language definition.


Yes, looking at the compiler source, it doesn't look too difficult.  The 
fact that something like this works:


template foo(int X)
{
   static if (bar!(X)) { const int foo = 57; }
   else { const char [] foo = abc; }
}
makes it pretty clear that the difficult part has already been done.

I don't know what happens with template mixins, though. I hate template 
mixins (and I'm not convinced they're useful for anything, either).


My mock object library http://dsource.org/projects/dmocks/ uses:
mixin(method!(name, returnType, arguments...));

The implementation is a long and ugly string mixin.

There's a bug that prevents you from implementing interface methods with 
aliases. If this were removed, I could replace the long and ugly string 
mixin with a very short string mixin and a short template mixin.


Due to problems with .stringof, my current system usually fails for 
methods with templated arguments or return types (eg void 
filter(HashSet!(int) integers).


Now that I think of it, I could probably make things better by using a 
forwarding function.


Re: GC Precision

2009-10-29 Thread Jacob Carlborg

On 10/29/09 11:47, bearophile wrote:

dsimcha:


A moving GC, one that doesn't stop the world on collection,
and one that's fully precise including stack would be nice, but they're several
orders of magnitude less important and would also have more ripple effects.


I agree that here doing something simple now is better than doing nothing or 
doing something very refined in an unknown future.

And in future things may be improved. In D objects are always managed by 
reference, and I think that most programs don't alter or cast such references 
to something else (objects allocated on memory specified by the programmer, and 
scoped objects allocated on the stack may be excluded from this). So I think 
that it can be safe to move objects, to compact the heap.


The current implementation of toHash in Object does that: return 
cast(hash_t)cast(void*)this;



So you may have 5 memory zones:
- C heap. (The type system of the D compiler may see the C-heap pointers and 
D-heap pointers as two different types, as I have proposed in the past. So you 
need casts if you want to mix them, and the compiler can use the D moving heap 
in a safer way).
- Pinned D heap for everything can't be moved, like structs managed by pointers 
(eventually a D compiler can infer at compile time that some structs too may be 
moved around, because their pointer is used only in clean ways (you don't need 
to introduce struct references for this)). I think SafeD modules will not use 
this heap a lot (but they can use unsafe modules that may use pinned objects. 
Is D safety transitive? I think it is not, so from a SafeD module you can call 
and use an unsafe module);
- Old object generation managed with compaction (I think there's no need for 
the permanent objects zone in D);
- Two from and to zones for the young generation, that don't use a true 
compaction strategy, young objects bounce between them;
- New generation Eden where new object allocations happen managed as a memory 
arena.

All this has the disadvantage of requiring a more complex GC, and probably 
requiring 2-4 times more RAM at runtime. It hopefully has the advantage of 
allowing new programmers, that have learnt Java at university, to program in 
almost like in Java. (I have found a not-synthetic Java benchmark program that 
converted to D is something like 18 times slower on LDC. I'll put the code in 
my site in the following days).

Bye,
bearophile




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Jason House
Andrei Alexandrescu Wrote:

 It's a rough rough draft, but one for the full chapter on arrays, 
 associative arrays, and strings.
 
 http://erdani.com/d/thermopylae.pdf
 
 Any feedback is welcome. Thanks!

I still think is expressions are a glaring problem. Somewhere in the text, you 
use assert(!is(typeof(... as support for what you're talking about. That 
particular construct feels more like a hack someone stumbled into than clean, 
easy to read code. It's the type of thing a programmer will get wring unless 
they use it frequently. Even you've screwed it up in past Phobos releases!  
IMHO all is(...) expressions should be revisited. Have you written the 
section(s) on them yet?

Also, on page 8? a code comment says average of a and b even though the 
variables don't exist. 


Re: GC Precision

2009-10-29 Thread bearophile
Jacob Carlborg:

 The current implementation of toHash in Object does that: return 
 cast(hash_t)cast(void*)this;

I agree, such things will have to change when D wants a moving GC.

Bye,
bearophile


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Lars T. Kyllingstad

Jason House wrote:

Andrei Alexandrescu Wrote:

It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


I still think is expressions are a glaring problem. Somewhere in the text, you 
use assert(!is(typeof(... as support for what you're talking about. That 
particular construct feels more like a hack someone stumbled into than clean, 
easy to read code. It's the type of thing a programmer will get wring unless 
they use it frequently. Even you've screwed it up in past Phobos releases!  
IMHO all is(...) expressions should be revisited. Have you written the 
section(s) on them yet?


I don't think he uses is(typeof(...)) in the text. The code snippets in 
question are marked Note: normally the code below would not be 
included..., and I suppose he's put them there as a reminder for 
himself and Walter on what needs to be fixed before the book comes out.


I agree with you, though, is(typeof(...)) is quite often misused, or at 
least used in an ugly way. Why not use __traits(compiles, ...) instead?


-Lars


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Denis Koroskin
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad  
pub...@kyllingen.nospamnet wrote:



Jason House wrote:

Andrei Alexandrescu Wrote:

It's a rough rough draft, but one for the full chapter on arrays,  
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!
 I still think is expressions are a glaring problem. Somewhere in the  
text, you use assert(!is(typeof(... as support for what you're talking  
about. That particular construct feels more like a hack someone  
stumbled into than clean, easy to read code. It's the type of thing a  
programmer will get wring unless they use it frequently. Even you've  
screwed it up in past Phobos releases!  IMHO all is(...) expressions  
should be revisited. Have you written the section(s) on them yet?


I don't think he uses is(typeof(...)) in the text. The code snippets in  
question are marked Note: normally the code below would not be  
included..., and I suppose he's put them there as a reminder for  
himself and Walter on what needs to be fixed before the book comes out.


I agree with you, though, is(typeof(...)) is quite often misused, or at  
least used in an ugly way. Why not use __traits(compiles, ...) instead?


-Lars


... which is at least as ugly.


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Lars T. Kyllingstad

Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad 
pub...@kyllingen.nospamnet wrote:



Jason House wrote:

Andrei Alexandrescu Wrote:

It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!
 I still think is expressions are a glaring problem. Somewhere in the 
text, you use assert(!is(typeof(... as support for what you're 
talking about. That particular construct feels more like a hack 
someone stumbled into than clean, easy to read code. It's the type of 
thing a programmer will get wring unless they use it frequently. Even 
you've screwed it up in past Phobos releases!  IMHO all is(...) 
expressions should be revisited. Have you written the section(s) on 
them yet?


I don't think he uses is(typeof(...)) in the text. The code snippets 
in question are marked Note: normally the code below would not be 
included..., and I suppose he's put them there as a reminder for 
himself and Walter on what needs to be fixed before the book comes out.


I agree with you, though, is(typeof(...)) is quite often misused, or 
at least used in an ugly way. Why not use __traits(compiles, ...) 
instead?


-Lars


... which is at least as ugly.



I disagree. Pretend you are just learning D, and you are presented with 
the following two lines of code:


  static assert (is(typeof(XXX));
  static assert (__traits(compiles, XXX));

Which of these would you most likely assume to be a check on whether XXX 
is compilable code?


What I cannot for the life of me understand is WHY the double 
underscores? What's wrong with just traits?


-Lars


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Jason House
Denis Koroskin Wrote:

 On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad  
 pub...@kyllingen.nospamnet wrote:
 
  I don't think he uses is(typeof(...)) in the text. The code snippets in  
  question are marked Note: normally the code below would not be  
  included..., and I suppose he's put them there as a reminder for  
  himself and Walter on what needs to be fixed before the book comes out.
 
  I agree with you, though, is(typeof(...)) is quite often misused, or at  
  least used in an ugly way. Why not use __traits(compiles, ...) instead?
 
  -Lars
 
 ... which is at least as ugly.

I disagree. Code that isn't readily understandable is uglier than readable 
code. Certainly, __traits is ugly, but it is easier to understand when readig 
code and easier to write.


Re: GC Sentinel

2009-10-29 Thread Steven Schveighoffer

On Tue, 27 Oct 2009 19:41:24 -0400, dsimcha dsim...@yahoo.com wrote:

I'm looking at the GC implementation and starting my hacking.  I noticed  
that

the ends of blocks are already being used in some creative ways in the
sentinel version.  This looks like a debugging feature, though I don't
understand it completely.  Can one of the original implementors (Walter,  
Sean)
explain to me what the heck version(SENTINEL) in gcx.d does at a high  
level,
whether it conflicts with storing bit masks for precise heap scanning at  
the

ends of memory blocks, and whether we still even need it?


IIRC, the sentinel byte is to prevent pointers from leaking into the next  
block.


For example, if you did:

byte[] x = new byte[16]; // GC allocates 16 byte block.
x = x[$..$];

Now, if there is no sentinel byte, the pointer in x points to the *next*  
memory block.


It is an interesting problem, there might be a better solution.

-Steve


Re: associative arrays: iteration is finally here

2009-10-29 Thread Pelle Månsson

bearophile wrote:

Andrei Alexandrescu:

I'll make aa.remove(key) always work and return a bool that tells you 
whether there was a mapping or not.


I think that's a small design mistake. In a high level language you want things 
to not fail silently. You want them to fail in an explicit way because 
programmers often forget to read and use return values.

So AAs may have two methods, remove and drop (Python sets use remove and discard for this). 
The remove can be the safer one and used by default in D programs (especially in SafeD modules, safety is in things like this 
too), that raises an exception when you try to remove a missing key. drop/discard is faster and silent, it removes the key if 
it's present, as you want.

Bye,
bearophile


I agree with this. I usually want exceptions.


Re: associative arrays: iteration is finally here

2009-10-29 Thread Steven Schveighoffer
On Wed, 28 Oct 2009 20:08:34 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Denis Koroskin wrote:
On Wed, 28 Oct 2009 23:18:08 +0300, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



I'd also like you to add a few things in an AA interface.
 First, opIn should not return a pointer to Value, but a pointer to a  
pair of Key and Value, if possible (i.e. if this change won't  
sacrifice performance).


I'm coy about adding that because it forces the implementation to hold  
keys and values next to each other. I think that was a minor mistake  
of STL - there's too much exposure of layout details.


 It doesn't have to be the case: key and value are both properties  
(i.e. methods), and they doesn't have to be located next to each other.


I see. So you want a pointer to an elaborate type featuring a key and a  
value.


It could return a struct holding both pointers, instead of a pointer to a  
struct.  I don't see this as unreasonable (in fact, it's what I do in  
dcollections, see the cursor types).  An implementation which stores the  
two close together in actuality may only require one pointer.


The only drawback of this is it can't be part of a formal interface, since  
the return type is defined by the derived type.


-Steve


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Denis Koroskin
On Thu, 29 Oct 2009 15:32:51 +0300, Jason House  
jason.james.ho...@gmail.com wrote:



Denis Koroskin Wrote:


On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
pub...@kyllingen.nospamnet wrote:

 I don't think he uses is(typeof(...)) in the text. The code snippets  
in

 question are marked Note: normally the code below would not be
 included..., and I suppose he's put them there as a reminder for
 himself and Walter on what needs to be fixed before the book comes  
out.


 I agree with you, though, is(typeof(...)) is quite often misused, or  
at
 least used in an ugly way. Why not use __traits(compiles, ...)  
instead?


 -Lars

... which is at least as ugly.


I disagree. Code that isn't readily understandable is uglier than  
readable code. Certainly, __traits is ugly, but it is easier to  
understand when readig code and easier to write.


I was talking about ugliness, not readability.

There are only 2 places where is(typeof(...)) feature is used:

assert(is(typeof(somePrimes) == int[])); // perfectly fine IMO
static assert(!is(typeof(a[length - 1]))); // misused, yes

BTW, typeof is a bit inconsistent with .stringof, .alignof, .sizeof etc  
(typeof(foo) but foo.sizeof).

Any chance this inconsistency is going to be fixed?

Either

assert(typeof(x + y) == int); - assert(is((x + y).typeof == int));

Or

assert((x + y).sizeof == 4); - assert(is(sizeof(x + y) == 4);


Re: associative arrays: iteration is finally here

2009-10-29 Thread Steven Schveighoffer
On Wed, 28 Oct 2009 10:22:00 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


Walter has magically converted his work on T[new] into work on making  
associative arrays true templates defined in druntime and not considered  
very special by the compiler.


This is very exciting because it opens up or simplifies a number of  
possibilities. One is that of implementing true iteration. I actually  
managed to implement last night something that allows you to do:


int[int] aa = [ 1:1 ];
auto iter = aa.each;
writeln(iter.front.key);
writeln(iter.front.value);

Two other iterations are possible: by key and by value (in those cases  
iter.front just returns a key or a value).


One question is, what names should these bear? I am thinking of makign  
opSlice() a universal method of getting the all iterator, a default  
that every container must implement.


For AAs, there would be a iterate keys and iterate values properties  
or functions. How should they be called?


This is one of the benefits of opApply.

Rather than define some new names to make up for the deficiencies of  
range-foreach (especially so near the release of D2), why not focus on  
fixing the deficiencies?


i.e. here is my desired interface:

foreach(key, value; aa) // iterate both keys and values
foreach(value; aa) // default to iterating values (to be consistent with  
arrays)

foreach(key; aa.keys) // iterate keys lazily.

If ranges cannot support this interface, I think the range paradigm needs  
some work.  opApply works great for this since the delegate type defines  
the desired interface.  The problem with ranges is the potential opRange  
method in it's natural form should overload on the return value, and have  
no parameters.


Here's a possible idea: make foreach(X x, Y y, Z z,...; container)  
translate to foreach(X x, Y y, Z z,...; container.opRange!(X, Y, Z,  
...)()).  In the case of inferred types, maybe you can do something like:


opRange!(T : keytype, U : valuetype)() and have the compiler infer types  
for x and y as keytype and valuetype.


The only drawback I see is opRange can't be virtual.  However, how does  
one define a virtual range return, when a range is invariably a struct?   
It might be a moot issue.


Of course, you could always meet the virtual requirement by naming your  
range-generating method...


So with my scheme, the AA becomes:

struct AA(Key, Val)
{
  ... // implementation
  auto opRange(T : Key, U : Val)() { ... }
  auto opRange(T : Val)() { ... }
  auto keys() { ... }
}

One other thing left to define is what foreach calls to get the key(s) in  
the case of multiple arguments to foreach.  The value is generally  
accessed via front().  Might as well tackle the ref possibilities too :)


-Steve


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Don

Lars T. Kyllingstad wrote:

Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad 
pub...@kyllingen.nospamnet wrote:



Jason House wrote:

Andrei Alexandrescu Wrote:

It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!
 I still think is expressions are a glaring problem. Somewhere in 
the text, you use assert(!is(typeof(... as support for what you're 
talking about. That particular construct feels more like a hack 
someone stumbled into than clean, easy to read code. It's the type 
of thing a programmer will get wring unless they use it frequently. 
Even you've screwed it up in past Phobos releases!  IMHO all is(...) 
expressions should be revisited. Have you written the section(s) on 
them yet?


I don't think he uses is(typeof(...)) in the text. The code snippets 
in question are marked Note: normally the code below would not be 
included..., and I suppose he's put them there as a reminder for 
himself and Walter on what needs to be fixed before the book comes out.


I agree with you, though, is(typeof(...)) is quite often misused, or 
at least used in an ugly way. Why not use __traits(compiles, ...) 
instead?


-Lars


... which is at least as ugly.



I disagree. Pretend you are just learning D, and you are presented with 
the following two lines of code:


  static assert (is(typeof(XXX));
  static assert (__traits(compiles, XXX));

Which of these would you most likely assume to be a check on whether XXX 
is compilable code?


What I cannot for the life of me understand is WHY the double 
underscores? What's wrong with just traits?


-Lars


Also is(typeof(XXX)) *doesn't* currently check that XXX is compilable, 
just that it has a type.
OTOH __traits(compiles, XXX) is ugly. traits(compiles, XXX) would be 
better; but I think we need to do better than that. It's the 
bread-and-butter of metaprogramming in D. Using the ugly syntax, it has 
well and truly proved its value.
I've counted 20 uses in what I've seen of Andrei's book -- it appears 
about as often as (say) 'delegate'!


It does a beautiful thing, it deserves a beautiful syntax. Something at 
least as good as __compiles(XXX), I reckon.






Re: Shared Hell

2009-10-29 Thread Steven Schveighoffer
On Thu, 29 Oct 2009 07:25:20 -0400, Christopher Wright  
dhase...@gmail.com wrote:



Kagamin wrote:

Christopher Wright Wrote:

A function that accesses shared data has to put in fences. There's no  
way to have the same code deal with shared and unshared code.
Acquiring a lock on a non-shared instance is safe, just an unnecessary  
expense. I would have looked into optimizing this expense away rather  
than punting the problem to the programmer.
 Shared code can put data into *really* shared environment, which must  
not happen for unshared data.


Okay, but the compiler can try copying the method, removing the 'shared'  
storage class, and running semantic on the result. If that succeeds,  
you're guaranteed not to be doing anything that would be unsafe unless  
you're casting, and you can call the shared method on a local instance.


This lets you avoid whole program analysis and blacklisting unsafe  
operations.


In this case, the compiler can also point to the line of code that  
prevents the method from being marked not shared.


Let's say your shared method your attempting to analyze calls an obscure  
shared method:


int foo(shared C c);

How do you determine if it can be called without the 'shared' qualifier?   
This is one of the problems with not importing from compiled interface  
files.


-Steve


More PC Precision Stuff

2009-10-29 Thread dsimcha
I've gotten underway hacking the GC to add precise heap scanning, but I
thought of one really annoying corner case that really would make things an
order of magnitude more complicated if it were handled properly:  Structs and
classes that have large static arrays embedded.  For example:

class Foo {
Foo next;
void*[4 * 1024 * 1024] hugeArray;
}

The problem here is that scanning this precisely would require me to either
generate a megabyte bitmask that explicitly says scan every element of
hugeArray or to change my bitmask data structure from a flat array to
something nested and an order of magnitude more complex to generate at compile
time.

Since this is such a rare case in practice, I'm tempted to just say that any
object with size above some arbitrary limit, say 1 kb, just gets scanned
conservatively and be done with it.  For arrays, this would be a limit on the
size of the element, i.e. for a T[], it would be a limit on T.sizeof, *not*
T.sizeof * length.  I'd like to get the community's input on this:  Is this
enough of a corner case that I have permission to cop out of solving it
properly for the sake of simplicity?


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Jason House wrote:

Andrei Alexandrescu Wrote:

It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


I still think is expressions are a glaring problem. Somewhere in the
text, you use assert(!is(typeof(... as support for what you're
talking about. That particular construct feels more like a hack
someone stumbled into than clean, easy to read code. It's the type of
thing a programmer will get wring unless they use it frequently. Even
you've screwed it up in past Phobos releases!  IMHO all is(...)
expressions should be revisited. Have you written the section(s) on
them yet?

Also, on page 8? a code comment says average of a and b even though
the variables don't exist.


Thanks, fixed. I also would like to see is expressions improved, but so 
far we couldn't find a good solution. There is a proposal currently in 
Bugzilla which may improve things.


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

bearophile wrote:

Andrei Alexandrescu:


http://erdani.com/d/thermopylae.pdf Any feedback is welcome.
Thanks!


So far I've just taken a look, I'll read it when I can. I can see
several warnings in red. The look of the text is really nice!
Elegant, and the images are good and necessary. Are you going to
write a book with all pages coloured? If true this will increase the
book price, I think.


Thanks. Unlike most authors, I provide camera-free to the publisher and 
carried all of the page design myself. I'm very glad I did.


The book will be in black and white. Notice how every use of color is 
also accompanied by a color-independent cue (e.g. bold/slanted). But the 
book will also sell in electronic format, which will be color.



I have seen that you use a nice fount for the
nonproportional text (like code), it looks similar to the Consolas.
You may try this one too (but it's not a professional product, it may
have some rough details): 
http://www.fantascienza.net/leonardo/ar/inconsolatag/inconsolata-g_font.zip


I did consider Inconsolata seriously, but I had to reject it (I forgot 
why; all I can remember was that it was a good reason).



Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Pelle Månsson wrote:

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Your Hallå Värd! should be Hallå Värld!, to be Swedish. D:


Thanks! Ouch, two mistakes in one word. Also, should I put a comma in 
between the words?


Also, I am wondering, why is the undefined behavior of opCatAssign kept? 
Couldn't every T[] know if it is the owner of the memory in question? 
Sorry if I bring outdated discussions up unnecessarily.


We don't know how to do that cheaply.


Andrei


Re: What Does Haskell Have to Do with C++?

2009-10-29 Thread Andrei Alexandrescu

Don wrote:

Andrei Alexandrescu wrote:

Don wrote:

Jeremie Pelletier wrote:
http://bartoszmilewski.wordpress.com/2009/10/21/what-does-haskell-have-to-do-with-c/ 



Bartosz's second part of 'Template Metaprogramming Made Easy 
(Huh?)', its quite a read :)


Yes, it is excellent. Two comments:
(1) Bartosz's D examples make me seriously question 'static foreach' 
which is scheduled for implementation (bugzilla 3377).
If implemented, it will be a source of frustration, since it will not 
be very usable inside templates. The ability to exit from a 'static 
foreach' is something which is possible with a 'return'-style syntax, 
but is not possible with the 'eponymous template hack'.


I think breaking early out of a static foreach is not necessary (but 
indeed convenient) for writing good loops.


(2) It seems pretty clear that we need to allow the eponymous trick 
to continue to work when more than one template member is present. I 
think everyone who's ever attempted template metaprogramming in D has 
proposed  it!


Yes, that was on the list for a long time. Bartosz even has 
participated to many related discussions. I'm surprised the article 
made it seem an unescapable matter of principles, when it clearly is a 
trivially fixable bug in the language definition.


Yes, looking at the compiler source, it doesn't look too difficult.  The 
fact that something like this works:


template foo(int X)
{
   static if (bar!(X)) { const int foo = 57; }
   else { const char [] foo = abc; }
}
makes it pretty clear that the difficult part has already been done.


That sounds great. If you could operate the changes, that would be 
awesome. Walter and I had already agreed about the feature.



Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Lars T. Kyllingstad wrote:

Andrei Alexandrescu wrote:

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

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.
http://erdani.com/d/thermopylae.pdf
Any feedback is welcome. Thanks!
Andrei


Given that new is all over the place, does this mean we're not 
getting rid of new

before D2 goes gold?


I guess we need to compromise.

Andrei



I got the impression from previous discussions that this would be a 
rather simple thing to implement. Also, the community mostly seemed to 
agree that ditching new would be a good thing. What are the obstacles?


Walter prefers that allocations have a cue. You'd need to convince him.

Andrei


Re: More PC Precision Stuff

2009-10-29 Thread bearophile
dsimcha:

 Since this is such a rare case in practice,

I don't think this is a so uncommon case, I use something similar for my memory 
pools. But if handling this makes your code too much complex, then it may be 
acceptable to ignore it anyway.

Two persons have shown the need for D benchmarks that stress the GC, so I am 
translating the Olden benchmarks to D. You can find two of them already in D on 
my site (in several variants) and I'll add more (but some of those variants use 
memory pools that you will not scan if you adopt that simplification). Such 
benchmarks (and other ones I have already) can be used to test your changes to 
the GC.

Bye,
bearophile


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Lars T. Kyllingstad wrote:

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei



It's a very pleasant read, and it looks good. I guess I'll have to buy 
the book. :)


Thanks! Very glad to hear you like it.


I just have two comments:

Code snippet in 4.2.1: Why do you suddenly use postfix array declaration 
here?


Oops... I'd planned to simply pretend it doesn't exist. Thanks, I fixed 
that now.


Code snippet just before 4.4.3: (yowza !in aa) doesn't work, at least 
not with DMD 2.035. It has to be !(yowza in aa). Very annoying.


Walter is planning to effect that change. By publishing time, there 
won't be any red and any pink in the book! (One nice thing about the 
book is that it gives us a good idea on what to work on. Walter has been 
on an incredible streak lately, and Don adds amazing value.)



Andrei


Re: associative arrays: iteration is finally here

2009-10-29 Thread bearophile
Pelle Månsson:
 I agree with this. I usually want exceptions.

A problem with this is that currently exceptions are very slow in D compiled 
with DMD (something like up to 11 times slower than Java exceptions, about 2-4 
times slower than Python exceptions. I have a benchmark for this on my site).

Bye,
bearophile


Re: More PC Precision Stuff

2009-10-29 Thread dsimcha
== Quote from bearophile (bearophileh...@lycos.com)'s article
 dsimcha:
  Since this is such a rare case in practice,
 I don't think this is a so uncommon case, I use something similar for my 
 memory
pools.

Why not dynamic arrays?  Wouldn't it make more sense to do:

class MemoryPool {
// other stuff
uint[] memory;

this() {
memory = new uint[someHugeNumber];
}
}

This would have negligible additional overhead and would allow you to change the
size of the memory pool at runtime.  I personally find that I almost never use
static arrays, either on the stack or inside heap-allocated objects because the
fact that their size is fixed at compile time is just too restrictive.  About my
only use for them is to store compile-time constants in the static data segment.


Re: associative arrays: iteration is finally here

2009-10-29 Thread Leandro Lucarella
Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:
 Your test looks something up and then removes it.
 
 
 Andrei
 
 Well, my extended test case looks something up, manipulates the
 found value, and then possibly removes it.
 
 Ok, I understand your points, thanks for explaining.

What about and overload of remove() like this:
bool remove(in T key, out U value);

If the element was present, it's returned in value, so you can
manipulate it. I thought about just returning a pointer:
U* remove(in T key);

But I guess that pointer would point to the element stored in the the AA
private data, but that element was just removed, so bad things would
happen, that's why the only option is to copy the data, right?

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Y no es el centro del Universo! El sol gira alrededor de la tierra!
Miles de girasoles no pueden estar equivocados!
-- Inodoro Pereyra


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread bearophile
Andrei Alexandrescu:

 I did consider Inconsolata seriously, but I had to reject it (I forgot 
 why; all I can remember was that it was a good reason).

A problem with Inconsolata that I have forgotten to tell you is that there 
isn't a true bold version yet, so the bold characters don't have the same 
width. So if your code highlighting converts some words to bold, the alignments 
break. This is quite so bad that I have disabled bold highlighting in my Python 
editor where I use that font. In the future I'll create a bold version of 
Inconsolata-g to solve this problem, it requires some tedious work, because it 
seems there are no automatic tools to do this.

Bye,
bearophile


Re: associative arrays: iteration is finally here

2009-10-29 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:

Your test looks something up and then removes it.


Andrei

Well, my extended test case looks something up, manipulates the
found value, and then possibly removes it.

Ok, I understand your points, thanks for explaining.


What about and overload of remove() like this:
bool remove(in T key, out U value);

If the element was present, it's returned in value, so you can
manipulate it. I thought about just returning a pointer:
U* remove(in T key);

But I guess that pointer would point to the element stored in the the AA
private data, but that element was just removed, so bad things would
happen, that's why the only option is to copy the data, right?


I think this all is overdoing it. First, I disagree that remove should 
ever throw an exception. It's not a code that the user is supposed to 
check (with dire consequences if she doesn't), it's just additional 
information just in case you need it.


I think bool remove(key) is better than all other designs suggested so far.


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

bearophile wrote:

Andrei Alexandrescu:

I did consider Inconsolata seriously, but I had to reject it (I forgot 
why; all I can remember was that it was a good reason).


A problem with Inconsolata that I have forgotten to tell you is that there 
isn't a true bold version yet, so the bold characters don't have the same width.


I think that was it indeed.

Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Ellery Newcomer wrote:

Andrei Alexandrescu wrote:

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.

http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Maybe I haven't been paying attention lately, but shouldn't

assert(x == 0)

be

assert(x[] == 0)

?


Where does the former occur?

Thanks,

Andrei


Re: associative arrays: iteration is finally here

2009-10-29 Thread Bill Baxter
On Thu, Oct 29, 2009 at 8:39 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Leandro Lucarella wrote:

 Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:

 Your test looks something up and then removes it.


 Andrei

 Well, my extended test case looks something up, manipulates the
 found value, and then possibly removes it.

 Ok, I understand your points, thanks for explaining.

 What about and overload of remove() like this:
 bool remove(in T key, out U value);

 If the element was present, it's returned in value, so you can
 manipulate it. I thought about just returning a pointer:
 U* remove(in T key);

 But I guess that pointer would point to the element stored in the the AA
 private data, but that element was just removed, so bad things would
 happen, that's why the only option is to copy the data, right?

 I think this all is overdoing it. First, I disagree that remove should ever
 throw an exception. It's not a code that the user is supposed to check (with
 dire consequences if she doesn't), it's just additional information just in
 case you need it.

 I think bool remove(key) is better than all other designs suggested so far.

I agree with the folks who say it's error-prone.  I can just see
myself now removing a key I know is in the dictionary and being
baffled when my program fails somewhere later on because I typed
aa.remove(theKey) when it should have been aa.remove(thekey).  I
knew it was there so I didn't want to clutter up my code with a check
for it.

So the advice would be to always check to make sure the key you remove
got removed to be on the safe side.   If that's the case I'd rather
just have the darn thing throw an exception so I don't have to bother
to write things like
 if (!aa.remove(theKey)) assert(false);
everywhere just to be on the safe side.



--bb


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Saaa
Andrei Alexandrescu wrote
 It's a rough rough draft, but one for the full chapter on arrays, 
 associative arrays, and strings.

 http://erdani.com/d/thermopylae.pdf

 Any feedback is welcome. Thanks!


 Andrei

Makes me want to read the rest!

Will we get the electronic version with the paper version?

p2. typo: eenlists
p9. Is it ok to expect the order of an array expression to be like in 
foreach ?
  Maybe mention a[] = b.
p11. typo: no(t) palindrome
p12. Should in a safe module ~= always create a new array?
p14. further expansions reads as if expansions have been made
especially because the comment is maybe that obvious that I was 
looking for something else to be there.
p16. Is there anything other than the random values, unsafe about void 
assignment?
When you write something to be unsafe, I expect it to not be allowed 
safe modules.
p18. What is unsafe about implicit conversion of static to dynamic array?
Meaning getting a dynamic array pointing to a stack allocated array.
Any operation changing its size could copy the array to the heap. 
What am I missing
p20. An alternative to figure 4.5 could display row/column properties.
p20. change 1,000,000 to 1_000_000 :D to me the comma is a decimal separator 
anyways.
p20. 40 words? 
p21. Why use enum iso immutable? Probably in the previous chapters explained 
:)
p21. Second paragraph reads as a solution to the above
p22. typo: array!literal
p25. Expected to read about ref in foreach

That's all :) 




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Leandro Lucarella
Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:
 It's a rough rough draft, but one for the full chapter on arrays,
 associative arrays, and strings.
 
 http://erdani.com/d/thermopylae.pdf
 
 Any feedback is welcome. Thanks!

It looks very nice. A small error in 4.1.7 first code block:

auto a = new double[4];  // must be already allocated
auto a1 = [ 0.5, -0.5, 1.5, 2 ];
auto a2 = [ 3.5, 5.5, 4.5, -1 ];
a[] = (a1[] + a2[]) / 2; // take the average of b and c
^^^
   take the average of a1 and a2?

(I think it would be easier to follow using b and c though ;)

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Cuando intenté arrimarle mi brazo
Se puso a hablar de Miller, de Anais Nin y Picasso
Y si osaba intentar robarle un beso
Se ponía a leer de Neruda unos versos
Me hizo mucho mal la cumbiera intelectual


Re: associative arrays: iteration is finally here

2009-10-29 Thread Kagamin
Andrei Alexandrescu Wrote:

 Two other iterations are possible: by key and by value (in those cases 
 iter.front just returns a key or a value).

Well, AA already has properties keys and values and you can already iterate 
over them. I think, it's ok to restrict to opApply(int delegate(ref KeyType, 
ref ValueType)).


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Leandro Lucarella
Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste:
 Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:
  It's a rough rough draft, but one for the full chapter on arrays,
  associative arrays, and strings.
  
  http://erdani.com/d/thermopylae.pdf
  
  Any feedback is welcome. Thanks!
 
 It looks very nice. A small error in 4.1.7 first code block:
 
 auto a = new double[4];  // must be already allocated
 auto a1 = [ 0.5, -0.5, 1.5, 2 ];
 auto a2 = [ 3.5, 5.5, 4.5, -1 ];
 a[] = (a1[] + a2[]) / 2; // take the average of b and c
 ^^^
take the average of a1 and a2?
 
 (I think it would be easier to follow using b and c though ;)

BTW, it looks like array literals will be dynamic arrays, from the code in
your book. Can you or Walter explain why this is better to make array
literals statically stored immutable memory like strings (which adds an
inconsistency to the language)? Is this just to avoid [1,2,3].dup; when
you want to get a dynamic array from an array literal or is there other
reasons?

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
En la calle me crucé con un señor muy correcto, que habitualmente anda en
Falcon; iba corriendo con dos valijas en la mano y dijo: Voy para Miami,
tiene algún mensaje o ... y le dije: No, no, no...
-- Extra Tato (1983, Triunfo de Alfonsín)


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Saaa
Also, no mention about .dup not being a deep dup. 




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Saaa
Saaa wrote
 Also, no mention about .dup not being a deep dup.
Sorry, should've been attached to my response 




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Bill Baxter
On Thu, Oct 29, 2009 at 9:31 AM, Leandro Lucarella llu...@gmail.com wrote:
 Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste:
 Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:
  It's a rough rough draft, but one for the full chapter on arrays,
  associative arrays, and strings.
 
  http://erdani.com/d/thermopylae.pdf
 
  Any feedback is welcome. Thanks!

 It looks very nice. A small error in 4.1.7 first code block:

 auto a = new double[4];          // must be already allocated
 auto a1 = [ 0.5, -0.5, 1.5, 2 ];
 auto a2 = [ 3.5, 5.5, 4.5, -1 ];
 a[] = (a1[] + a2[]) / 2;         // take the average of b and c
                                     ^^^
                                    take the average of a1 and a2?

 (I think it would be easier to follow using b and c though ;)

 BTW, it looks like array literals will be dynamic arrays, from the code in
 your book. Can you or Walter explain why this is better to make array
 literals statically stored immutable memory like strings (which adds an
 inconsistency to the language)? Is this just to avoid [1,2,3].dup; when
 you want to get a dynamic array from an array literal or is there other
 reasons?

It's in the chapter.  Basically static arrays just aren't the common use case.

It is a bit of a bummer that there's no way to get a static array with
the elements counted for you.  Some folks suggested things like

 int[auto] = [1,2,3];
or
 int[$] = [1,2,3];

Something like that would be nice.

--bb


Re: associative arrays: iteration is finally here

2009-10-29 Thread KennyTM~

On Oct 29, 09 23:59, Bill Baxter wrote:

On Thu, Oct 29, 2009 at 8:39 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org  wrote:

Leandro Lucarella wrote:


Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:


Your test looks something up and then removes it.


Andrei


Well, my extended test case looks something up, manipulates the
found value, and then possibly removes it.


Ok, I understand your points, thanks for explaining.


What about and overload of remove() like this:
bool remove(in T key, out U value);

If the element was present, it's returned in value, so you can
manipulate it. I thought about just returning a pointer:
U* remove(in T key);

But I guess that pointer would point to the element stored in the the AA
private data, but that element was just removed, so bad things would
happen, that's why the only option is to copy the data, right?


I think this all is overdoing it. First, I disagree that remove should ever
throw an exception. It's not a code that the user is supposed to check (with
dire consequences if she doesn't), it's just additional information just in
case you need it.

I think bool remove(key) is better than all other designs suggested so far.


I agree with the folks who say it's error-prone.  I can just see
myself now removing a key I know is in the dictionary and being
baffled when my program fails somewhere later on because I typed
aa.remove(theKey) when it should have been aa.remove(thekey).  I
knew it was there so I didn't want to clutter up my code with a check
for it.


Um what? aa[theKey] = 1 doesn't fail, why should aa.remove(theKey) 
be special?


(Meanwhile, C++'s map::erase returns the number of elements removed, 
C#'s (CLR in general) Dictionary.Remove returns a bool, Javascript's 
delete x[y] returns a bool, Perl, Ruby, Objective-C, Java, etc. all 
won't throw exceptions (Python being the only exceptional case). Do all 
languages clutter up with checks?)




So the advice would be to always check to make sure the key you remove
got removed to be on the safe side.   If that's the case I'd rather
just have the darn thing throw an exception so I don't have to bother
to write things like
  if (!aa.remove(theKey)) assert(false);
everywhere just to be on the safe side.



void discard(K,V)(ref V[K] aa, in K key) {
  if (!aa.remove(key)) assert(false);
}

...

aa.discard(theKey);




--bb




Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Saaa
crp
 p20. 40 words? 
those  where for myself, to check 




Re: associative arrays: iteration is finally here

2009-10-29 Thread bearophile
KennyTM~:

 Um what? aa[theKey] = 1 doesn't fail, why should aa.remove(theKey) 
 be special?

That's a different situation.
You probably meant to say: If aa[theKey]++; doesn't fail, why should 
aa.remove(theKey) be special?


 void discard(K,V)(ref V[K] aa, in K key) {
if (!aa.remove(key)) assert(false);
 }

This is stupid. Part of the point of built-in AAs is to avoid to import things. 
If I need to import (or worse define) that discard template in all programs 
where I use an AA, then I will create my own AAs and I'll just import and use 
them in the first place.

Bye,
bearophile


Re: associative arrays: iteration is finally here

2009-10-29 Thread Bill Baxter
On Thu, Oct 29, 2009 at 9:57 AM, KennyTM~ kenn...@gmail.com wrote:
 On Oct 29, 09 23:59, Bill Baxter wrote:

 On Thu, Oct 29, 2009 at 8:39 AM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org  wrote:

 Leandro Lucarella wrote:

 Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:

 Your test looks something up and then removes it.


 Andrei

 Well, my extended test case looks something up, manipulates the
 found value, and then possibly removes it.

 Ok, I understand your points, thanks for explaining.

 What about and overload of remove() like this:
 bool remove(in T key, out U value);

 If the element was present, it's returned in value, so you can
 manipulate it. I thought about just returning a pointer:
 U* remove(in T key);

 But I guess that pointer would point to the element stored in the the AA
 private data, but that element was just removed, so bad things would
 happen, that's why the only option is to copy the data, right?

 I think this all is overdoing it. First, I disagree that remove should
 ever
 throw an exception. It's not a code that the user is supposed to check
 (with
 dire consequences if she doesn't), it's just additional information just
 in
 case you need it.

 I think bool remove(key) is better than all other designs suggested so
 far.

 I agree with the folks who say it's error-prone.  I can just see
 myself now removing a key I know is in the dictionary and being
 baffled when my program fails somewhere later on because I typed
 aa.remove(theKey) when it should have been aa.remove(thekey).  I
 knew it was there so I didn't want to clutter up my code with a check
 for it.

 Um what? aa[theKey] = 1 doesn't fail, why should aa.remove(theKey) be
 special?

Huh?  aa[theKey] also doesn't delete entries, so why should it have
any bearing on what remove does?  The closest analogy would be the
case where aa[theKey]=1 can't do what you ask it to, which would be
an out-of-memory error, which does generate an error of some kind, I
think.

 (Meanwhile, C++'s map::erase returns the number of elements removed,

Erase is also used for multimaps, so it's not exactly apples to
apples.  Your other examples are ok AFAIK.


 void discard(K,V)(ref V[K] aa, in K key) {
  if (!aa.remove(key)) assert(false);
 }

 ...

 aa.discard(theKey);

Yep, that would be perfect if it were part of the standard AA
interface.  That would actually be my preferred solution, to have two
methods for removing elements from AAs.  One that throws and one that
doesn't.

--bb


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Saaa wrote:

Will we get the electronic version with the paper version?


I'm not exactly sure how things will roll out. Probably yes.


p2. typo: eenlists
p9. Is it ok to expect the order of an array expression to be like in 
foreach ?

  Maybe mention a[] = b.
p11. typo: no(t) palindrome
p12. Should in a safe module ~= always create a new array?
p14. further expansions reads as if expansions have been made
especially because the comment is maybe that obvious that I was 
looking for something else to be there.
p16. Is there anything other than the random values, unsafe about void 
assignment?
When you write something to be unsafe, I expect it to not be allowed 
safe modules.

p18. What is unsafe about implicit conversion of static to dynamic array?
Meaning getting a dynamic array pointing to a stack allocated array.
Any operation changing its size could copy the array to the heap. 
What am I missing

p20. An alternative to figure 4.5 could display row/column properties.
p20. change 1,000,000 to 1_000_000 :D to me the comma is a decimal separator 
anyways.

p20. 40 words? 
p21. Why use enum iso immutable? Probably in the previous chapters explained 
:)

p21. Second paragraph reads as a solution to the above
p22. typo: array!literal
p25. Expected to read about ref in foreach

That's all :) 


Thanks much!


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.

http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


It looks very nice. A small error in 4.1.7 first code block:

auto a = new double[4];  // must be already allocated
auto a1 = [ 0.5, -0.5, 1.5, 2 ];
auto a2 = [ 3.5, 5.5, 4.5, -1 ];
a[] = (a1[] + a2[]) / 2; // take the average of b and c
^^^
   take the average of a1 and a2?

(I think it would be easier to follow using b and c though ;)


Thanks! I fixed that to have a and b as sources and c as destination.

Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Saaa wrote:
Also, no mention about .dup not being a deep dup. 


I've put this on my todo list, but it's difficult. At this point people 
only know about statements and expressions, so it would be a bit 
difficult to introduce the subtleties of shallow vs. deep copying. I 
guess I'll have to do it.


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste:

Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.

http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!

It looks very nice. A small error in 4.1.7 first code block:

auto a = new double[4];  // must be already allocated
auto a1 = [ 0.5, -0.5, 1.5, 2 ];
auto a2 = [ 3.5, 5.5, 4.5, -1 ];
a[] = (a1[] + a2[]) / 2; // take the average of b and c
^^^
   take the average of a1 and a2?

(I think it would be easier to follow using b and c though ;)


BTW, it looks like array literals will be dynamic arrays, from the code in
your book. Can you or Walter explain why this is better to make array
literals statically stored immutable memory like strings (which adds an
inconsistency to the language)? Is this just to avoid [1,2,3].dup; when
you want to get a dynamic array from an array literal or is there other
reasons?


I don't have a better explanation than the excerpt:

Beware, however: if you replace @int[3]@ above with @auto@, @a@'s type
will be deduced  as @int[]@, not @int...@.  Although  it seems logical
that the type of  \cc{[1, 2, 3]} should be @int[3]@ which  in a way is
more  ``precise'' than  @int[]@, it  turns out  that dynamically-sized
arrays are used  much more often than fixed-size  arrays, so insisting
on fixed-size  array literals would  have been a  usability impediment
and  a  source  of  unpleasant  surprises.  Effectively,  the  use  of
literals would  have prevented the gainful  use of @a...@.   As it is,
array literals are @T[]@ by  default, and @T[n]@ if you \emph{ask} for
that specific  type and  if @n@  matches the number  of values  in the
literal (as the code above shows).


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Ellery Newcomer
Andrei Alexandrescu wrote:
 Ellery Newcomer wrote:
 Andrei Alexandrescu wrote:
 It's a rough rough draft, but one for the full chapter on arrays,
 associative arrays, and strings.

 http://erdani.com/d/thermopylae.pdf

 Any feedback is welcome. Thanks!


 Andrei

 Maybe I haven't been paying attention lately, but shouldn't

 assert(x == 0)

 be

 assert(x[] == 0)

 ?
 
 Where does the former occur?
 
 Thanks,
 
 Andrei

top of page 102


Re: associative arrays: iteration is finally here

2009-10-29 Thread Andrei Alexandrescu

Bill Baxter wrote:

On Thu, Oct 29, 2009 at 8:39 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

Leandro Lucarella wrote:

Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:

Your test looks something up and then removes it.


Andrei

Well, my extended test case looks something up, manipulates the
found value, and then possibly removes it.

Ok, I understand your points, thanks for explaining.

What about and overload of remove() like this:
bool remove(in T key, out U value);

If the element was present, it's returned in value, so you can
manipulate it. I thought about just returning a pointer:
U* remove(in T key);

But I guess that pointer would point to the element stored in the the AA
private data, but that element was just removed, so bad things would
happen, that's why the only option is to copy the data, right?

I think this all is overdoing it. First, I disagree that remove should ever
throw an exception. It's not a code that the user is supposed to check (with
dire consequences if she doesn't), it's just additional information just in
case you need it.

I think bool remove(key) is better than all other designs suggested so far.


I agree with the folks who say it's error-prone.  I can just see
myself now removing a key I know is in the dictionary and being
baffled when my program fails somewhere later on because I typed
aa.remove(theKey) when it should have been aa.remove(thekey).  I
knew it was there so I didn't want to clutter up my code with a check
for it.


I don't find this reasonable. If you know removal must have succeeded, 
just type enforce(aa.remove(theKey)). I don't think that's the 
overwhelmingly common case though, and if it's, say, about 50/50, then 
it's much more sensible to have a non-throwing primitive than a throwing 
one. And it looks like defining two primitives just to save a call to 
enforce is not a good design. After all, if you argue people forget and 
misspell things and all, I could argue they call the wrong function out 
of two with very similar charters. Honest, I just read a couple of posts 
proposing two primitives and for the life of me I already can't remember 
which was throwing and which wasn't.



So the advice would be to always check to make sure the key you remove
got removed to be on the safe side.


I'm not seeing how that comes about. The advice is to check if you care, 
which is common sense. I'm wondering how such an obvious design came 
into question.



Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Pelle Månsson

Andrei Alexandrescu wrote:

Pelle Månsson wrote:

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Your Hallå Värd! should be Hallå Värld!, to be Swedish. D:


Thanks! Ouch, two mistakes in one word. Also, should I put a comma in 
between the words?


Actually, I see now that you had it as Hallå, värd!, and it should be 
Hallå, värld!, no need to capitalize the second word.


Unless what you want to say is Hello, host!, in which case your värd 
is correct.


Also, I am wondering, why is the undefined behavior of opCatAssign 
kept? Couldn't every T[] know if it is the owner of the memory in 
question? Sorry if I bring outdated discussions up unnecessarily.


We don't know how to do that cheaply.


Andrei


How about doing it expensively? Maybe storing a boolean in each T[]? I 
think undefined behavior is bad.


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Ellery Newcomer wrote:

Andrei Alexandrescu wrote:

Ellery Newcomer wrote:

Andrei Alexandrescu wrote:

It's a rough rough draft, but one for the full chapter on arrays,
associative arrays, and strings.

http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei

Maybe I haven't been paying attention lately, but shouldn't

assert(x == 0)

be

assert(x[] == 0)

?

Where does the former occur?

Thanks,

Andrei


top of page 102


Thanks. Notice that x is an integer because it was fetched as array[5].

Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Robert Jacques
On Thu, 29 Oct 2009 00:38:33 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


It's a rough rough draft, but one for the full chapter on arrays,  
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Still reading, but here's a quick comment. I found it odd that the syntax  
for element-wise copying (4.1.7) comes sections after the section on  
copying (4.1.4). Perhaps a sentence mentioning where element-wise copying  
can be found would be appropriate. (Props though on including a memory  
layout figure. It may not seem like much, but I've seen Java students have  
no idea what an array is in memory.)


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Leandro Lucarella
Andrei Alexandrescu, el 29 de octubre a las 12:23 me escribiste:
 Leandro Lucarella wrote:
 Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste:
 Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:
 BTW, it looks like array literals will be dynamic arrays, from the code in
 your book. Can you or Walter explain why this is better to make array
 literals statically stored immutable memory like strings (which adds an
 inconsistency to the language)? Is this just to avoid [1,2,3].dup; when
 you want to get a dynamic array from an array literal or is there other
 reasons?
 
 I don't have a better explanation than the excerpt:
 
 Beware, however: if you replace @int[3]@ above with @auto@, @a@'s type
 will be deduced  as @int[]@, not @int...@.  Although  it seems logical
 that the type of  \cc{[1, 2, 3]} should be @int[3]@ which  in a way is
 more  ``precise'' than  @int[]@, it  turns out  that dynamically-sized
 arrays are used  much more often than fixed-size  arrays, so insisting
 on fixed-size  array literals would  have been a  usability impediment
 and  a  source  of  unpleasant  surprises.  Effectively,  the  use  of
 literals would  have prevented the gainful  use of @a...@.   As it is,
 array literals are @T[]@ by  default, and @T[n]@ if you \emph{ask} for
 that specific  type and  if @n@  matches the number  of values  in the
 literal (as the code above shows).

I saw that, but I think introducing an inconsistency (and depart on how
literals usually work) is worse than having to explicitly state the type
or adding a .dup to the literal.

But I guess it's just me.

Another question about the book: you explain dynamic arrays are being
represented by a start and end pointer, much like the STL, but that's not
the real implementation. I know you say in the book that the
implementation doesn't necessarily work like that, but I wonder if you
decided to explain things like that because it's planned to change the
dynamic arrays implementation or just because you found it more didactic.

Thanks.

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Algún día los libros desterrarán a la radio y el hombre descubrirá el
oculto poder del Amargo Serrano.
-- Ricardo Vaporeso. El Bolsón, 1909.


Re: associative arrays: iteration is finally here

2009-10-29 Thread Leandro Lucarella
Andrei Alexandrescu, el 29 de octubre a las 12:33 me escribiste:
 Bill Baxter wrote:
 I think bool remove(key) is better than all other designs suggested so far.
 
 I agree with the folks who say it's error-prone.  I can just see
 myself now removing a key I know is in the dictionary and being
 baffled when my program fails somewhere later on because I typed
 aa.remove(theKey) when it should have been aa.remove(thekey).  I
 knew it was there so I didn't want to clutter up my code with a check
 for it.
 
 I don't find this reasonable. If you know removal must have
 succeeded, just type enforce(aa.remove(theKey)). I don't think

I don't agree, this is like saying you should bound-check every array
access. I think it's nice to have safety by default. If you are expecting
to have an error, you will be extra careful to spell the key correctly.
This should cover the cases where you are distracted and not expecting any
errors.

I think the check could be done in non-release mode only though, just
like bound checking.

 that's the overwhelmingly common case though, and if it's, say,
 about 50/50, then it's much more sensible to have a non-throwing
 primitive than a throwing one. And it looks like defining two
 primitives just to save a call to enforce is not a good design.

This is one case where I think practicality beats purity, because the
whole point of throwing an exception is for the cases you don't expect it
to fail. Again, think of array bounds, you can force the programmer to add
lots of enforce() in the code and remove bound checking from the compiler.

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
EXPOSICION INTERNACIONAL DE INODOROS
-- Crónica TV


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Robert Jacques wrote:
On Thu, 29 Oct 2009 00:38:33 -0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:


It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Andrei


Still reading, but here's a quick comment. I found it odd that the 
syntax for element-wise copying (4.1.7) comes sections after the section 
on copying (4.1.4). Perhaps a sentence mentioning where element-wise 
copying can be found would be appropriate. (Props though on including a 
memory layout figure. It may not seem like much, but I've seen Java 
students have no idea what an array is in memory.)


Good point, thanks.

Andrei


Re: associative arrays: iteration is finally here

2009-10-29 Thread Bill Baxter
On Thu, Oct 29, 2009 at 10:33 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Bill Baxter wrote:

 On Thu, Oct 29, 2009 at 8:39 AM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:

 Leandro Lucarella wrote:

 Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste:

 Your test looks something up and then removes it.


 Andrei

 Well, my extended test case looks something up, manipulates the
 found value, and then possibly removes it.

 Ok, I understand your points, thanks for explaining.

 What about and overload of remove() like this:
 bool remove(in T key, out U value);

 If the element was present, it's returned in value, so you can
 manipulate it. I thought about just returning a pointer:
 U* remove(in T key);

 But I guess that pointer would point to the element stored in the the AA
 private data, but that element was just removed, so bad things would
 happen, that's why the only option is to copy the data, right?

 I think this all is overdoing it. First, I disagree that remove should
 ever
 throw an exception. It's not a code that the user is supposed to check
 (with
 dire consequences if she doesn't), it's just additional information just
 in
 case you need it.

 I think bool remove(key) is better than all other designs suggested so
 far.

 I agree with the folks who say it's error-prone.  I can just see
 myself now removing a key I know is in the dictionary and being
 baffled when my program fails somewhere later on because I typed
 aa.remove(theKey) when it should have been aa.remove(thekey).  I
 knew it was there so I didn't want to clutter up my code with a check
 for it.

 I don't find this reasonable. If you know removal must have succeeded, just
 type enforce(aa.remove(theKey)). I don't think that's the overwhelmingly
 common case though, and if it's, say, about 50/50, then it's much more
 sensible to have a non-throwing primitive than a throwing one. And it looks
 like defining two primitives just to save a call to enforce is not a good
 design. After all, if you argue people forget and misspell things and all, I
 could argue they call the wrong function out of two with very similar
 charters. Honest, I just read a couple of posts proposing two primitives and
 for the life of me I already can't remember which was throwing and which
 wasn't.

 So the advice would be to always check to make sure the key you remove
 got removed to be on the safe side.

 I'm not seeing how that comes about. The advice is to check if you care,
 which is common sense. I'm wondering how such an obvious design came into
 question.

Ok.  You convinced me that your way doesn't suck.  And you can ask the
Python designers how the so-called obvious design came into
question.  Apparently it's not as obvious as you think.  And I would
suggest from experience with Python that having two functions is also
not as bad as you think.  But I'm convinced that having two functions
is not significantly better than having one function that doesn't
throw.

--bb


Re: associative arrays: iteration is finally here

2009-10-29 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el 29 de octubre a las 12:33 me escribiste:

Bill Baxter wrote:

I think bool remove(key) is better than all other designs suggested so far.

I agree with the folks who say it's error-prone.  I can just see
myself now removing a key I know is in the dictionary and being
baffled when my program fails somewhere later on because I typed
aa.remove(theKey) when it should have been aa.remove(thekey).  I
knew it was there so I didn't want to clutter up my code with a check
for it.

I don't find this reasonable. If you know removal must have
succeeded, just type enforce(aa.remove(theKey)). I don't think


I don't agree, this is like saying you should bound-check every array
access. I think it's nice to have safety by default.


remove from an associative array is not unsafe.


If you are expecting
to have an error, you will be extra careful to spell the key correctly.
This should cover the cases where you are distracted and not expecting any
errors.

I think the check could be done in non-release mode only though, just
like bound checking.


Bounds checking is eliminated in release mode solely for efficiency 
reasons. There is no other good reason to eliminate checks. But in the 
case of remove, the amount of work done is consistent enough to make a 
check negligible.



that's the overwhelmingly common case though, and if it's, say,
about 50/50, then it's much more sensible to have a non-throwing
primitive than a throwing one. And it looks like defining two
primitives just to save a call to enforce is not a good design.


This is one case where I think practicality beats purity, because the
whole point of throwing an exception is for the cases you don't expect it
to fail. Again, think of array bounds, you can force the programmer to add
lots of enforce() in the code and remove bound checking from the compiler.


I can't think of array bounds. The situations are completely unrelated.


Andrei


Re: associative arrays: iteration is finally here

2009-10-29 Thread Bill Baxter
On Thu, Oct 29, 2009 at 11:16 AM, Leandro Lucarella llu...@gmail.com wrote:
 Andrei Alexandrescu, el 29 de octubre a las 12:33 me escribiste:
 Bill Baxter wrote:
 I think bool remove(key) is better than all other designs suggested so far.
 
 I agree with the folks who say it's error-prone.  I can just see
 myself now removing a key I know is in the dictionary and being
 baffled when my program fails somewhere later on because I typed
 aa.remove(theKey) when it should have been aa.remove(thekey).  I
 knew it was there so I didn't want to clutter up my code with a check
 for it.

 I don't find this reasonable. If you know removal must have
 succeeded, just type enforce(aa.remove(theKey)). I don't think

 I don't agree, this is like saying you should bound-check every array
 access. I think it's nice to have safety by default. If you are expecting
 to have an error, you will be extra careful to spell the key correctly.
 This should cover the cases where you are distracted and not expecting any
 errors.

 I think the check could be done in non-release mode only though, just
 like bound checking.

 that's the overwhelmingly common case though, and if it's, say,
 about 50/50, then it's much more sensible to have a non-throwing
 primitive than a throwing one. And it looks like defining two
 primitives just to save a call to enforce is not a good design.

 This is one case where I think practicality beats purity, because the
 whole point of throwing an exception is for the cases you don't expect it
 to fail. Again, think of array bounds, you can force the programmer to add
 lots of enforce() in the code and remove bound checking from the compiler.

The problem with this argument (which I was also about to make) is
that accessing an array out of bounds is almost never normal behavior.
 But for deleting things, it often is.  Think also about delete
itself.  In C++ and D delete on a null pointer is fine, and is defined
to be a no-op.  This was done explicitly to avoid always having to do
if(p) delete p; all the time.  And really it works out just fine in
practice.   If we're going to keep arguing that remove() should throw,
then really delete should too.

--bb


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el 29 de octubre a las 12:23 me escribiste:

Leandro Lucarella wrote:

Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste:

Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:

BTW, it looks like array literals will be dynamic arrays, from the code in
your book. Can you or Walter explain why this is better to make array
literals statically stored immutable memory like strings (which adds an
inconsistency to the language)? Is this just to avoid [1,2,3].dup; when
you want to get a dynamic array from an array literal or is there other
reasons?

I don't have a better explanation than the excerpt:

Beware, however: if you replace @int[3]@ above with @auto@, @a@'s type
will be deduced  as @int[]@, not @int...@.  Although  it seems logical
that the type of  \cc{[1, 2, 3]} should be @int[3]@ which  in a way is
more  ``precise'' than  @int[]@, it  turns out  that dynamically-sized
arrays are used  much more often than fixed-size  arrays, so insisting
on fixed-size  array literals would  have been a  usability impediment
and  a  source  of  unpleasant  surprises.  Effectively,  the  use  of
literals would  have prevented the gainful  use of @a...@.   As it is,
array literals are @T[]@ by  default, and @T[n]@ if you \emph{ask} for
that specific  type and  if @n@  matches the number  of values  in the
literal (as the code above shows).


I saw that, but I think introducing an inconsistency (and depart on how
literals usually work) is worse than having to explicitly state the type
or adding a .dup to the literal.

But I guess it's just me.


It's me as well. The decision didn't go without a fight (I had your 
viewpoint and Walter didn't). He convinced me with two arguments. One is 
that 90% of the time you actually want T[], not T[n]. The second is that 
string literals already have dynamic (not static) type, although the 
most informative type would be fixed-size.



Another question about the book: you explain dynamic arrays are being
represented by a start and end pointer, much like the STL, but that's not
the real implementation. I know you say in the book that the
implementation doesn't necessarily work like that, but I wonder if you
decided to explain things like that because it's planned to change the
dynamic arrays implementation or just because you found it more didactic.


We will change the implementation at some point, but right now I hope I 
made it clear enough it's about the notion of a bounded chunk of typed 
memory, than the representation of it.



Andrei


Re: Shared Hell

2009-10-29 Thread Walter Bright

Kagamin wrote:

Walter Bright Wrote:

A function that accesses shared data has to put in fences. There's
no way to have the same code deal with shared and unshared code.


Shared code perfectly deals with unshared data (it's not guaranteed
that shared data is accessed by more than one thread). In other words
unshared data is implicitly castable to shared.


Unfortunately, there is a subtle problem with that that makes such 
implicit casts unsafe. Shared data can be handed off to other threads. 
So if thread local data is implicitly cast to shared, then it can be 
handed off to other threads. Meaning it is no longer guaranteed to be 
thread local.


another stack frame optimization issue

2009-10-29 Thread sprucely
So I have this optimization in which I jump from function to function to avoid 
the overhead of setting up and tearing down identical stack frames. Now I want 
to be able to jump from a member function of one object to a member function of 
another object. I accomplished this with g++ by replacing the this pointer that 
is passed in as a hidden parameter. After some difficulty with dmd I realized 
that the this pointer is actually stored in EAX. But simply updating EAX to 
hold the new this pointer doesn't seem to be working. I've verified that EAX 
contains the address of the destination object, but it is still behaving as if 
the this pointer had not changed...

class Test()
{
static byte* jumpTo;
void* nextObject;

int count;

void Run()
{
if (count++  5)
return;
asm
{
mov ECX, EAX;
mov EAX, nextObject[ECX];
jmp dword ptr jumpTo;
}
}
}

int main(char[][] args)
{
//14 is offset for parameterless member function with no stack variables
Test.jumpTo = cast(byte*)(Test.Run) + 14;

auto t1 = new Test();
auto t2 = new Test();

t1.nextObject = cast(void*)t2;
t2.nextObject = cast(void*)t1;

t1.Run();

Stdout(t1.count, t2.count);

return 0;
}

...This gives me the result 7, 0. I don't have the actual disassembled code 
in front of me but IIRC member variables are referenced via offset from the 
location stored in EAX. I'm not sure what else to try.


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Tom S

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Thanks for the excerpt! I've only had the time to give it a brief skim 
so far, but it's looking good. This is what I found:


p16: int quadrupeds[100], int legs[4 * quadrupeds.length]  -  is the 
C-style array declaration syntax intended?

p20: No mention of the new T[][](rows, cols) syntax?
p26 (User-Defined Types as Keys): No need for opEquals?


--
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Manuel
Andrei Alexandrescu Wrote:

 
 Any feedback is welcome. Thanks!
 
 

Thanks Andrei, that was an excellent read.

Some comments:

Page 102, line 23. I'm not a native English speaker, but it seems like you're 
missing a such in the sentence there is a thing as a

Page 116, line 13: shouldn't array be defined as = void, for efficiency?

Section 4.3: As someone who is new to D, I would like to see an example 
involving a multidimensional array in which all dimensions are fixed. Something 
like 

int a[3][2] = [ ??? ];





Re: associative arrays: iteration is finally here

2009-10-29 Thread rmcguire
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote:
 
 Denis Koroskin wrote:
 On Wed, 28 Oct 2009 17:22:00 +0300, Andrei Alexandrescu 
 seewebsiteforem...@erdani.org wrote:
 
 Walter has magically converted his work on T[new] into work on making 
 associative arrays true templates defined in druntime and not 
 considered very special by the compiler.

 
 Wow, this is outstanding! (I hope it didn't have any negative impact on 
 compile-time AA capabilities).
 
 This is very exciting because it opens up or simplifies a number of 
 possibilities. One is that of implementing true iteration. I actually 
 managed to implement last night something that allows you to do:

 int[int] aa = [ 1:1 ];
 auto iter = aa.each;
 writeln(iter.front.key);
 writeln(iter.front.value);

 Two other iterations are possible: by key and by value (in those cases 
 iter.front just returns a key or a value).

 One question is, what names should these bear? I am thinking of makign 
 opSlice() a universal method of getting the all iterator, a default 
 that every container must implement.

 For AAs, there would be a iterate keys and iterate values 
 properties or functions. How should they be called?


 Thanks,

 Andrei
 
 If AA is providing a way to iterate over both keys and values (and it's 
 a default iteration scheme), why should AA provide 2 other iteration 
 schemes? Can't they be implemented externally (using adaptor ranges) 
 with the same efficiency?
 
 foreach (e; keys(aa)) {
 writefln(key: %s, e);
 }
 
 foreach (e; values(aa)) {
 writefln(value: %s, e);
 }
 
 Of course. In fact, given the iterator with .key and .value, you can 
 always apply map!a.key or map!a.value to select the desired member.
 
 I'd also like you to add a few things in an AA interface.
 
 First, opIn should not return a pointer to Value, but a pointer to a 
 pair of Key and Value, if possible (i.e. if this change won't sacrifice 
 performance).
 
 I'm coy about adding that because it forces the implementation to hold 
 keys and values next to each other. I think that was a minor mistake of 
 STL - there's too much exposure of layout details.
 
 Second, AA.remove method should accept result of opIn operation to avoid 
 an additional lookup for removal:
 
 if (auto value = key in aa) {
 aa.remove(key); // an unnecessary lookup
 }
 
 I'll make aa.remove(key) always work and return a bool that tells you 
 whether there was a mapping or not.
 
 Something like this would be perfect:
 
 struct Element(K,V)
 {
 const K key;
 V value;
 }
 
 struct AA(K,V)
 {
 //...
 ref Element opIn(K key) { /* throws an exception if element is not 
 found */ }
 void remove(ref Element elem) { /* removes an element from an AA */ }
 void remove(K key) { remove(key in this); }
 
 AARange!(K,V) opSlice() { /* iterates over both keys and values */ }
 }
 
 Last, I believe foreach loop should automatically call opSlice() on 
 iteratee.
 
 foreach in D2 should already call opSlice() whenever it's defined. If it 
 doesn't, that's a bug in the compiler.
 
 
 Andrei
 


Wouldn't opIn be more useful if it returned a range starting with
the element that was found?



Re: associative arrays: iteration is finally here

2009-10-29 Thread KennyTM~

On Oct 30, 09 01:14, bearophile wrote:

KennyTM~:


Um what? aa[theKey] = 1 doesn't fail, why should aa.remove(theKey)
be special?


That's a different situation.
You probably meant to say: If aa[theKey]++; doesn't fail, why should 
aa.remove(theKey) be special?



void discard(K,V)(ref V[K] aa, in K key) {
if (!aa.remove(key)) assert(false);
}


This is stupid. Part of the point of built-in AAs is to avoid to import things. 
If I need to import (or worse define) that discard template in all programs 
where I use an AA, then I will create my own AAs and I'll just import and use 
them in the first place.

Bye,
bearophile


This does not contradicts with .remove() not throwing an exception when 
a key is not found. If you like you can put it in object.d.


(Moreover, having .remove() to throw means you can't delete any 
dictionary items in nothrow functions. Sure you can silent it with 
try/catch but that's expensive.)


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Andrei Alexandrescu

Tom S wrote:

Andrei Alexandrescu wrote:
It's a rough rough draft, but one for the full chapter on arrays, 
associative arrays, and strings.


http://erdani.com/d/thermopylae.pdf

Any feedback is welcome. Thanks!


Thanks for the excerpt! I've only had the time to give it a brief skim 
so far, but it's looking good. This is what I found:


p16: int quadrupeds[100], int legs[4 * quadrupeds.length]  -  is the 
C-style array declaration syntax intended?


Thanks, fixed.


p20: No mention of the new T[][](rows, cols) syntax?


Oops, completely forgot about that one.


p26 (User-Defined Types as Keys): No need for opEquals?


There currently is, but there shouldn't and it won't.


Andrei


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Max Samukha
On Thu, 29 Oct 2009 13:30:35 -0500, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

It's me as well. The decision didn't go without a fight (I had your 
viewpoint and Walter didn't). He convinced me with two arguments. One is 
that 90% of the time you actually want T[], not T[n].

The argument may be flawed because, out of those 90% of arrays, only
small part may be initialized from array literals. Many (most?) are
created with new or appended. I suspect dynamic arrays created from
literals are as rare as static arrays in real world code. Probably,
I'll investigate how exactly rare.


Re: associative arrays: iteration is finally here

2009-10-29 Thread Andrei Alexandrescu

rmcguire wrote:

Wouldn't opIn be more useful if it returned a range starting with
the element that was found?


Thought about that, but it's hard to justify. Items aren't sorted in any 
particular order, so you'd get pretty much a random bunch of stuff.


Andrei


Re: More PC Precision Stuff

2009-10-29 Thread Michel Fortin

On 2009-10-29 09:42:58 -0400, dsimcha dsim...@yahoo.com said:


I've gotten underway hacking the GC to add precise heap scanning, but I
thought of one really annoying corner case that really would make things an
order of magnitude more complicated if it were handled properly:  Structs and
classes that have large static arrays embedded.  For example:

class Foo {
Foo next;
void*[4 * 1024 * 1024] hugeArray;
}

The problem here is that scanning this precisely would require me to either
generate a megabyte bitmask that explicitly says scan every element of
hugeArray or to change my bitmask data structure from a flat array to
something nested and an order of magnitude more complex to generate at compile
time.


You don't need something with nesting, but something a little more 
complex yes. For instance you could replace the bitmask with an array 
of integers, each telling you in turn how many words to skip and how 
many words have pointers. For instance:


struct Foo {
int a;
void* b1;
void* b2;
void* b3;
int[4] c;
void*[3000] d;
}

ushort[4] fooMemoryMap = [1, 3, 4, 3000];

1word without pointer
3words with pointers
4words without pointer
3000 words with pointers

Now one of the remaining problems is how to handle weak pointers. The 
other problem is that this doesn't scale well if your static array 
contains a struct with pointers and non-pointers. For this you'd need 
to have a way to repeat a pattern (something like a rewind command in 
the above stream). Both can be solved by giving a special meaning to 
the most significant bit:


enum {
// For even values (non pointers)
SKIP_FLAG   = 0  ushort.sizeof*8-1;
REPEAT_FLAG = 1  ushort.sizeof*8-1;
// for odd values (pointers)
STRONG_PTR_FLAG = 0  ushort.sizeof*8-1;
WEAK_PTR_FLAG   = 1  ushort.sizeof*8-1;
}

Giving you this memory map for Foo:

ushort[4] fooMemoryMap = [
1| SKIP_FLAG,   // one word of non-pointers
3| STRONG_PTR_FLAG, // three words of pointers
4| SKIP_FLAG,   // four words of non-pointers
3000 | STRONG_PTR_FLAG, // 3000 words of pointers
];

Now you can encode even a big static array of Foos in the middle of a 
struct with a reasonably-sized memory map (14 bytes):


struct Bar {
Foo[500] a;
int[500] b;
}

ushort[7] barMemoryMap = [
1| SKIP_FLAG,   // one word of non-pointers
3| STRONG_PTR_FLAG, // three words of pointers
4| SKIP_FLAG,   // four words of non-pointers
3000 | STRONG_PTR_FLAG, // 3000 words of pointers
4| REPEAT_FLAG, // rewind 4 instructions
   500 //   and repeat 500 times
   500  | SKIP_FLAG,   // 500 words of non-pointers
];

Here, Foo's memory map just gets inserted at the right place in Bar's 
memory map. No nesting or pointers or anything, just a repeat 
instruction. An it takes only 14 bytes.



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



Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Denis Koroskin
On Thu, 29 Oct 2009 21:59:13 +0300, Max Samukha spam...@d-coding.com  
wrote:



On Thu, 29 Oct 2009 13:30:35 -0500, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:


It's me as well. The decision didn't go without a fight (I had your
viewpoint and Walter didn't). He convinced me with two arguments. One is
that 90% of the time you actually want T[], not T[n].


The argument may be flawed because, out of those 90% of arrays, only
small part may be initialized from array literals. Many (most?) are
created with new or appended. I suspect dynamic arrays created from
literals are as rare as static arrays in real world code. Probably,
I'll investigate how exactly rare.


I agree. It also involves a hidden allocation and there is no way around  
it:


int[] t = [0, 1, 2] ~ [3, 4, 5]; // how many allocations here take place?  
1? No, 3!


Re: associative arrays: iteration is finally here

2009-10-29 Thread Leandro Lucarella
KennyTM~, el 30 de octubre a las 02:55 me escribiste:
 On Oct 30, 09 01:14, bearophile wrote:
 KennyTM~:
 
 Um what? aa[theKey] = 1 doesn't fail, why should aa.remove(theKey)
 be special?
 
 That's a different situation.
 You probably meant to say: If aa[theKey]++; doesn't fail, why should 
 aa.remove(theKey) be special?
 
 
 void discard(K,V)(ref V[K] aa, in K key) {
 if (!aa.remove(key)) assert(false);
 }
 
 This is stupid. Part of the point of built-in AAs is to avoid to import 
 things. If I need to import (or worse define) that discard template in all 
 programs where I use an AA, then I will create my own AAs and I'll just 
 import and use them in the first place.
 
 Bye,
 bearophile
 
 This does not contradicts with .remove() not throwing an exception
 when a key is not found. If you like you can put it in object.d.
 
 (Moreover, having .remove() to throw means you can't delete any
 dictionary items in nothrow functions. Sure you can silent it with
 try/catch but that's expensive.)

Not if it's an Error instead of an exception. I think that should be the
case, .remove() check should be like bound check, something done at
non-release mode, not something to use in the regular flow of a program to
avoid using opIn().

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Esta desenchufada la internet de ese televisor?
-- Osvaldo Lucarella


Re: associative arrays: iteration is finally here

2009-10-29 Thread rmcguire
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote:
 
 rmcguire wrote:
 Wouldn't opIn be more useful if it returned a range starting with
 the element that was found?
 
 Thought about that, but it's hard to justify. Items aren't sorted in any 
 particular order, so you'd get pretty much a random bunch of stuff.
 
 Andrei
 

Oh, I thought that ranges were going to be applied to network/file IO.

I which case there is plenty of places one might want to jump forward in a 
range...

ah but then we're talking AAs.

Well I suppose the Socket class could have opIn return a range.

hehe

Thanks for replying



Re: More PC Precision Stuff

2009-10-29 Thread Lutger
dsimcha wrote:

 I've gotten underway hacking the GC to add precise heap scanning, but I
 thought of one really annoying corner case that really would make things
 an
 order of magnitude more complicated if it were handled properly:  Structs
 and
 classes that have large static arrays embedded.  For example:
 
 class Foo {
 Foo next;
 void*[4 * 1024 * 1024] hugeArray;
 }
 
 The problem here is that scanning this precisely would require me to
 either generate a megabyte bitmask that explicitly says scan every
 element of hugeArray or to change my bitmask data structure from a flat
 array to something nested and an order of magnitude more complex to
 generate at compile time.
 
 Since this is such a rare case in practice, I'm tempted to just say that
 any object with size above some arbitrary limit, say 1 kb, just gets
 scanned
 conservatively and be done with it.  For arrays, this would be a limit on
 the size of the element, i.e. for a T[], it would be a limit on T.sizeof,
 *not*
 T.sizeof * length.  I'd like to get the community's input on this:  Is
 this enough of a corner case that I have permission to cop out of solving
 it properly for the sake of simplicity?

Could you or anyone else solve this problem at a later stage? If that would 
not be made more difficult then I would say cop out, at least for now.


Re: More PC Precision Stuff

2009-10-29 Thread Denis Koroskin
On Thu, 29 Oct 2009 22:32:54 +0300, Lutger lutger.blijdest...@gmail.com  
wrote:



dsimcha wrote:


I've gotten underway hacking the GC to add precise heap scanning, but I
thought of one really annoying corner case that really would make things
an
order of magnitude more complicated if it were handled properly:   
Structs

and
classes that have large static arrays embedded.  For example:

class Foo {
Foo next;
void*[4 * 1024 * 1024] hugeArray;
}

The problem here is that scanning this precisely would require me to
either generate a megabyte bitmask that explicitly says scan every
element of hugeArray or to change my bitmask data structure from a flat
array to something nested and an order of magnitude more complex to
generate at compile time.

Since this is such a rare case in practice, I'm tempted to just say that
any object with size above some arbitrary limit, say 1 kb, just gets
scanned
conservatively and be done with it.  For arrays, this would be a limit  
on
the size of the element, i.e. for a T[], it would be a limit on  
T.sizeof,

*not*
T.sizeof * length.  I'd like to get the community's input on this:  Is
this enough of a corner case that I have permission to cop out of  
solving

it properly for the sake of simplicity?


Could you or anyone else solve this problem at a later stage? If that  
would

not be made more difficult then I would say cop out, at least for now.


Don't worry, it won't have any impact on the existing code.


Re: associative arrays: iteration is finally here

2009-10-29 Thread Leandro Lucarella
Andrei Alexandrescu, el 29 de octubre a las 13:26 me escribiste:
 Leandro Lucarella wrote:
 Andrei Alexandrescu, el 29 de octubre a las 12:33 me escribiste:
 Bill Baxter wrote:
 I think bool remove(key) is better than all other designs suggested so 
 far.
 I agree with the folks who say it's error-prone.  I can just see
 myself now removing a key I know is in the dictionary and being
 baffled when my program fails somewhere later on because I typed
 aa.remove(theKey) when it should have been aa.remove(thekey).  I
 knew it was there so I didn't want to clutter up my code with a check
 for it.
 I don't find this reasonable. If you know removal must have
 succeeded, just type enforce(aa.remove(theKey)). I don't think
 
 I don't agree, this is like saying you should bound-check every array
 access. I think it's nice to have safety by default.
 
 remove from an associative array is not unsafe.

In the sense of memory corruption that's true. But your program will be
at least leaking memory if you thought the key was present in the AA (the
majority of the use cases for remove(), because come on, if you are
removing something is because you think there are very good chances that
the key is in the AA :). If your program then iterate the AA and there is
a key that it doesn't supposed to be there, it will blow in very original,
hard to track ways. What's the point of that?

If you want to remove something you're not sure that it really is in the
AA, you should use a safer method. Maybe try_remove(), or an extra
parameter to remove() or maybe just ask first if key in aa (but this have
an extra lookup, and I think that's the whole point that triggered this
discussion).

 If you are expecting
 to have an error, you will be extra careful to spell the key correctly.
 This should cover the cases where you are distracted and not expecting any
 errors.
 
 I think the check could be done in non-release mode only though, just
 like bound checking.
 
 Bounds checking is eliminated in release mode solely for efficiency
 reasons. There is no other good reason to eliminate checks. But in

Well, same for removing an inexistent key from an AA then :)

 the case of remove, the amount of work done is consistent enough to
 make a check negligible.

Ok, but make it an Error, not an exception, so it can be used in nothrow
functions. Removing an nonexistent key from an AA should be a programming
error, except if you state in some way that you know that maybe the key is
not there (which should be rare).

 that's the overwhelmingly common case though, and if it's, say,
 about 50/50, then it's much more sensible to have a non-throwing
 primitive than a throwing one. And it looks like defining two
 primitives just to save a call to enforce is not a good design.
 
 This is one case where I think practicality beats purity, because the
 whole point of throwing an exception is for the cases you don't expect it
 to fail. Again, think of array bounds, you can force the programmer to add
 lots of enforce() in the code and remove bound checking from the compiler.
 
 I can't think of array bounds. The situations are completely unrelated.

I don't think they are *completely* unrelated. I agree is not exactly the
same because array bound error automatically imply memory corruption and
nonexistent key removal don't, but they are a bug in the vast majority of
the cases. At least this is my experience.

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Fitter, happier, more productive, comfortable, not drinking too much,
regular exercise at the gym (3 days a week),
getting on better with your associate employee contemporaries,


Re: More PC Precision Stuff

2009-10-29 Thread dsimcha
== Quote from Lutger (lutger.blijdest...@gmail.com)'s article
 dsimcha wrote:
  I've gotten underway hacking the GC to add precise heap scanning, but I
  thought of one really annoying corner case that really would make things
  an
  order of magnitude more complicated if it were handled properly:  Structs
  and
  classes that have large static arrays embedded.  For example:
 
  class Foo {
  Foo next;
  void*[4 * 1024 * 1024] hugeArray;
  }
 
  The problem here is that scanning this precisely would require me to
  either generate a megabyte bitmask that explicitly says scan every
  element of hugeArray or to change my bitmask data structure from a flat
  array to something nested and an order of magnitude more complex to
  generate at compile time.
 
  Since this is such a rare case in practice, I'm tempted to just say that
  any object with size above some arbitrary limit, say 1 kb, just gets
  scanned
  conservatively and be done with it.  For arrays, this would be a limit on
  the size of the element, i.e. for a T[], it would be a limit on T.sizeof,
  *not*
  T.sizeof * length.  I'd like to get the community's input on this:  Is
  this enough of a corner case that I have permission to cop out of solving
  it properly for the sake of simplicity?
 Could you or anyone else solve this problem at a later stage? If that would
 not be made more difficult then I would say cop out, at least for now.

I would be much more inclined to cop out on this, except that I would be making 
a
design decision that might not be easy to change in the future w.r.t. how 
bitmasks
are structured.  If we eventually fixed this, it would likely be a breaking 
change
to the GC interface, after D2 had gone gold.  Then again, GC.malloc is a pretty
low-level interface, and most access would be through whatever replaces new, 
which
would likely be in the standard lib and could be modified in lockstep.  
Therefore,
if/when we were to get a more principled scheme, it might be transparent to most
user code, at least at the source level.

One thing I definitely need to know from the insiders (Walter, Sean, etc.) is, 
how
much do we care about having a stable, well thought out, formally specified
interface to the GC routines, both at the source and binary level, at this stage
in the game?  If I did something hackish to get precise heap scanning mostly
working, would the patch likely be rejected because it would create cruft that
would have to be kept for backwards compatibility?


Re: associative arrays: iteration is finally here

2009-10-29 Thread bearophile
KennyTM~:

 (Moreover, having .remove() to throw means you can't delete any 
 dictionary items in nothrow functions. Sure you can silent it with 
 try/catch but that's expensive.)

In nothrow functions you can use a different method, like discard (or a 
similar name less intuitive than remove), that's like remove, but it doesn't 
throw and just returns false when the key was absent.
The idea is to use the safer method by default and the less safe one as a 
performance optimization (or where you are sure you want that semantics) in the 
other places.

Bye,
bearophile


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Leandro Lucarella
Andrei Alexandrescu, el 29 de octubre a las 13:30 me escribiste:
 Leandro Lucarella wrote:
 Andrei Alexandrescu, el 29 de octubre a las 12:23 me escribiste:
 Leandro Lucarella wrote:
 Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste:
 Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste:
 BTW, it looks like array literals will be dynamic arrays, from the code in
 your book. Can you or Walter explain why this is better to make array
 literals statically stored immutable memory like strings (which adds an
 inconsistency to the language)? Is this just to avoid [1,2,3].dup; when
 you want to get a dynamic array from an array literal or is there other
 reasons?
 I don't have a better explanation than the excerpt:
 
 Beware, however: if you replace @int[3]@ above with @auto@, @a@'s type
 will be deduced  as @int[]@, not @int...@.  Although  it seems logical
 that the type of  \cc{[1, 2, 3]} should be @int[3]@ which  in a way is
 more  ``precise'' than  @int[]@, it  turns out  that dynamically-sized
 arrays are used  much more often than fixed-size  arrays, so insisting
 on fixed-size  array literals would  have been a  usability impediment
 and  a  source  of  unpleasant  surprises.  Effectively,  the  use  of
 literals would  have prevented the gainful  use of @a...@.   As it is,
 array literals are @T[]@ by  default, and @T[n]@ if you \emph{ask} for
 that specific  type and  if @n@  matches the number  of values  in the
 literal (as the code above shows).
 
 I saw that, but I think introducing an inconsistency (and depart on how
 literals usually work) is worse than having to explicitly state the type
 or adding a .dup to the literal.
 
 But I guess it's just me.
 
 It's me as well. The decision didn't go without a fight (I had your
 viewpoint and Walter didn't).

Oh, ok. Thanks for the fight ;)

 He convinced me with two arguments.  One is that 90% of the time you
 actually want T[], not T[n].

I don't know how did he come up with that number. At least, talking about
arrays that comes from a literal, I don't think that is the case. In
a program I'm sure more than 90% of the array usage are dynamic arrays,
but when talking about array literals I'm not very convinced, I think you
usually just want an iterable from them.

 The second is that string literals already have dynamic (not static)
 type, although the most informative type would be fixed-size.

Damn! Are you saying that this:
auto s = hello;

Really does something like this in C:
char* s = gc_malloc(5, NO_SCAN);
memcpy(s, hello, 5);
?

I though it was just like C, a pointer to an statcally allocated memory
block. What's the point to heap-allocate an immutable chunk of memory?

 Another question about the book: you explain dynamic arrays are being
 represented by a start and end pointer, much like the STL, but that's not
 the real implementation. I know you say in the book that the
 implementation doesn't necessarily work like that, but I wonder if you
 decided to explain things like that because it's planned to change the
 dynamic arrays implementation or just because you found it more didactic.
 
 We will change the implementation at some point, but right now I
 hope I made it clear enough it's about the notion of a bounded chunk
 of typed memory, than the representation of it.

I think the point is taken, I was just curious about what's the plan.

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Salvajes, de traje, me quieren enseñar
Salvajes, de traje, me quieren educar


Re: The Thermopylae excerpt of TDPL available online

2009-10-29 Thread Ellery Newcomer
Andrei Alexandrescu wrote:
 Ellery Newcomer wrote:
 Andrei Alexandrescu wrote:
 Ellery Newcomer wrote:
 Andrei Alexandrescu wrote:
 It's a rough rough draft, but one for the full chapter on arrays,
 associative arrays, and strings.

 http://erdani.com/d/thermopylae.pdf

 Any feedback is welcome. Thanks!


 Andrei
 Maybe I haven't been paying attention lately, but shouldn't

 assert(x == 0)

 be

 assert(x[] == 0)

 ?
 Where does the former occur?

 Thanks,

 Andrei

 top of page 102
 
 Thanks. Notice that x is an integer because it was fetched as array[5].
 
 Andrei

Oh wow. I'm dyslexic.


  1   2   >