digitalmars.D - The Thermopylae excerpt of TDPL available online

• Andrei Alexandrescu (5/5) Oct 28 2009 It's a rough rough draft, but one for the full chapter on arrays,
• dsimcha (3/8) Oct 28 2009 Given that new is all over the place, does this mean we're not getting r...
• Lars T. Kyllingstad (7/16) Oct 29 2009 It's a very pleasant read, and it looks good. I guess I'll have to buy
• Andrei Alexandrescu (9/29) Oct 29 2009 Oops... I'd planned to simply pretend it doesn't exist. Thanks, I fixed
• =?ISO-8859-1?Q?Pelle_M=E5nsson?= (5/14) Oct 29 2009 Your "Hallå Värd!" should be "Hallå Värld!", to be Swedish. D:
• bearophile (7/9) Oct 29 2009 So far I've just taken a look, I'll read it when I can. I can see severa...
• Andrei Alexandrescu (9/24) Oct 29 2009 Thanks. Unlike most authors, I provide camera-free to the publisher and
• bearophile (4/6) Oct 29 2009 A problem with Inconsolata that I have forgotten to tell you is that the...
• Jason House (3/9) Oct 29 2009 I still think is expressions are a glaring problem. Somewhere in the tex...
• Lars T. Kyllingstad (8/18) Oct 29 2009 I don't think he uses is(typeof(...)) in the text. The code snippets in
• Denis Koroskin (3/26) Oct 29 2009 ... which is at least as ugly.
• Lars T. Kyllingstad (10/43) Oct 29 2009 I disagree. Pretend you are just learning D, and you are presented with
• Don (11/60) Oct 29 2009 Also is(typeof(XXX)) *doesn't* currently check that XXX is compilable,
• Lars T. Kyllingstad (9/71) Oct 30 2009 Again with the double underscores. :) I'm starting to think we need a
• Don (19/91) Oct 30 2009 Yes. That's why I said "at least as good".
• bearophile (17/27) Oct 30 2009 Cute.
• Danny Wilson (3/9) Oct 30 2009 Not nice. Bad.
• Don (3/19) Oct 30 2009 That is WAY more complicated! It adds a crazy number of keywords, and
• Lars T. Kyllingstad (9/105) Oct 30 2009 I like it. It's a clean, simple solution. The std.traits module will
• Justin Johansson (6/115) Oct 30 2009 I'm in agreement with whoever suggested 'meta' or just about anything el...
• Leandro Lucarella (11/19) Oct 30 2009 "compiler"? That could open the door to other types of access to compile...
• Don (7/18) Oct 30 2009 Yup. I think the 'magic namespace' approach is a simple, clean way to
• Jason House (2/21) Oct 30 2009 What about going one step further? You could require an import statement...
• Don (7/28) Nov 02 2009 It's too fundamental for that. You can't use template constraints
• Don (33/81) Nov 02 2009 See for yourself. For example, the patch below (against svn 234) allows
• Don (7/63) Nov 02 2009 And BTW, to allow 'meta' as another synonym for the same magic
• Leandro Lucarella (10/42) Nov 02 2009 And what about scope(exit) and friends?
• grauzone (2/40) Nov 02 2009 I suggest we use static. static.YYY(), doesn't look that lovely?
• Robert Clipsham (12/40) Oct 30 2009 This could even be implemented in phobos (or object.d to avoid an import...
• Nick Sabalausky (4/44) Oct 30 2009 I'm not sure I see the value in being able to rename that. That's like
• Robert Clipsham (3/5) Oct 31 2009 I don't either, that's just a nice side effect for people who dislike
• Walter Bright (5/7) Oct 29 2009 Because D needed the feature, and it wasn't clear what a good syntax for...
• Leandro Lucarella (13/21) Oct 29 2009 And now, being moderately close to D2 stabilization, isn't a good moment
• Lars T. Kyllingstad (7/21) Oct 30 2009 I'm not convinced about __gshared. As far as I've understood, __gshared
• Leandro Lucarella (17/37) Oct 30 2009 D is a system programming language. I don't see why one should be over
• Jason House (2/16) Oct 29 2009 I disagree. Code that isn't readily understandable is uglier than readab...
• Denis Koroskin (13/35) Oct 29 2009 I was talking about ugliness, not readability.
• Andrei Alexandrescu (5/25) Oct 29 2009 Thanks, fixed. I also would like to see is expressions improved, but so
• Ellery Newcomer (6/15) Oct 29 2009 Maybe I haven't been paying attention lately, but shouldn't
• Saaa (30/35) Oct 29 2009 Makes me want to read the rest!
• Saaa (1/1) Oct 29 2009 Also, no mention about .dup not being a deep dup.
• Saaa (2/3) Oct 29 2009 those <<<< where for myself, to check
• Andrei Alexandrescu (4/33) Oct 29 2009 Thanks much!
• Saaa (2/10) Oct 30 2009 Thanks!
• Andrei Alexandrescu (15/25) Oct 30 2009 I'd put your feedback on my pile of things to do, but now that you ask,
• Andrei Alexandrescu (4/36) Oct 30 2009 It's bytes actually. So finally I rewrote those last words as:
• Saaa (8/44) Oct 30 2009 Thanks !
• Andrei Alexandrescu (54/101) Oct 30 2009 Yes. If you look at the document very closely, you'll see that some
• Saaa (6/107) Oct 30 2009 I Wouldn't accept it being written in C++ !! :D
• Leandro Lucarella (19/25) Oct 29 2009 It looks very nice. A small error in 4.1.7 first code block:
• Leandro Lucarella (16/34) Oct 29 2009 BTW, it looks like array literals will be dynamic arrays, from the code ...
• Bill Baxter (16/41) Oct 29 2009 d
• Andrei Alexandrescu (14/39) Oct 29 2009 I don't have a better explanation than the excerpt:
• Leandro Lucarella (20/43) Oct 29 2009 I saw that, but I think introducing an inconsistency (and depart on how
• Andrei Alexandrescu (10/45) Oct 29 2009 It's me as well. The decision didn't go without a fight (I had your
• Max Samukha (7/10) Oct 29 2009 The argument may be flawed because, out of those 90% of arrays, only
• Denis Koroskin (6/16) Oct 29 2009 I agree. It also involves a hidden allocation and there is no way around...
• Andrei Alexandrescu (6/18) Oct 29 2009 Apparently the need was felt strongly enough that a library made it into...
• Max Samukha (9/14) Oct 31 2009 I guess you mean the assignment library
• bearophile (4/7) Oct 31 2009 In script-like code literals are common. So when you consider your produ...
• Leandro Lucarella (23/70) Oct 29 2009 I don't know how did he come up with that number. At least, talking abou...
• Michael Rynn (45/54) Nov 03 2009 Good chapter, I learned some things, and I liked the Unicode
• Saaa (1/1) Oct 29 2009 Also, no mention about .dup not being a deep dup.
• Saaa (2/3) Oct 29 2009 Sorry, should've been attached to my response
• Andrei Alexandrescu (6/7) Oct 29 2009 I've put this on my todo list, but it's difficult. At this point people
• Andrei Alexandrescu (3/21) Oct 29 2009 Thanks! I fixed that to have a and b as sources and c as destination.
• Robert Jacques (8/13) Oct 29 2009 Still reading, but here's a quick comment. I found it odd that the synta...
• Tom S (11/17) Oct 29 2009 Thanks for the excerpt! I've only had the time to give it a brief skim
• Manuel (7/11) Oct 29 2009 Thanks Andrei, that was an excellent read.
• Jason House (2/29) Oct 30 2009 What's the bugzilla number?
• Justin Johansson (5/17) Oct 30 2009 Is this the same argument as Andrei's rhetorical question
• Mike Parker (3/14) Oct 31 2009 should be
• duser4ever (34/43) Oct 31 2009 Sure I haven't come across anything that someone else hasn't already poi...
• Andrei Alexandrescu (8/60) Oct 31 2009 Thanks, I'd forgotten to clean the intermediate files before building
• Philippe Sigaud (8/12) Nov 11 2009 Well, if that's a rough rough draft, I'll happily read the entire book.....
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 28 2009
dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail 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?

Oct 28 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail 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

Oct 28 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Andrei Alexandrescu wrote:
dsimcha wrote:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail 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

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lars T. Kyllingstad wrote:
Andrei Alexandrescu wrote:
dsimcha wrote:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail 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

Oct 29 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
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.

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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.

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

Oct 29 2009
=?ISO-8859-1?Q?Pelle_M=E5nsson?= <pelle.mansson gmail.com> writes:
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.

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
=?ISO-8859-1?Q?Pelle_M=E5nsson?= <pelle.mansson gmail.com> writes:
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

Oct 29 2009
bearophile <bearophileHUGS lycos.com> writes:
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

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
bearophile <bearophileHUGS lycos.com> writes:
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

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
Jason House <jason.james.house gmail.com> writes:
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.

Oct 29 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
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

Oct 29 2009
"Denis Koroskin" <2korden gmail.com> writes:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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.

Oct 29 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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, ...)

-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

Oct 29 2009
Don <nospam nospam.com> writes:
Lars T. Kyllingstad wrote:
Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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, ...)

-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.

Oct 29 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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, ...)

-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.

Again with the double underscores. :) I'm starting to think we need a
separate namespace for the CT stuff.

D.compiles(XXX)
D.typeof(foo)
D.stringof(T)
D.allMembers(T)
etc.

-Lars

Oct 30 2009
Don <nospam nospam.com> writes:
Lars T. Kyllingstad wrote:
Don wrote:
Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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,

-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.

Again with the double underscores. :)

Yes. That's why I said "at least as good".

I'm starting to think we need a
separate namespace for the CT stuff.

D.compiles(XXX)
D.typeof(foo)
D.stringof(T)
D.allMembers(T)

That's not bad. Can't be 'D', though, has to look like a keyword. Maybe
something like 'traits' instead. In exchange, get rid of the '__traits'
and 'typeid' keywords. Not sure about typeof, though.

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

IMHO this looks better than __traits(compiles, XXX) but it actually has
the same flexibility, and it's a straightforward transformation inside
the compiler.
For bonus points, allow 'with(traits)':

with(traits) {
if (compiles(XXX)) return stringof(T);
else error("Can't use " ~ stringof(T) ~ " in a transmogrifier.");
}

Oct 30 2009
bearophile <bearophileHUGS lycos.com> writes:
Don:

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

Cute.
Simpler alternative, the dot isn't necessary:

traits_compiles(XXX)
traits_typeid(TTT)
traits_stringof(T)
traits_allmembers(T)
traits_error("message");

Or, more uniformly (all D needs more identifier style uniformity):

traits_compiles(XXX)
traits_type_id(TTT)
traits_string_of(T)
traits_all_members(T)
traits_error("message");

For bonus points, allow 'with(traits)':
with(traits) {
if (compiles(XXX)) return stringof(T);
else error("Can't use " ~ stringof(T) ~ " in a transmogrifier.");
}

Bye,
bearophile

Oct 30 2009
"Danny Wilson" <bluezenix gmail.com> writes:
Op Fri, 30 Oct 2009 11:44:08 +0100 schreef bearophile
<bearophileHUGS lycos.com>:

Simpler alternative, the dot isn't necessary:

traits_compiles(XXX)
traits_typeid(TTT)
traits_stringof(T)
traits_allmembers(T)
traits_error("message");


Oct 30 2009
Don <nospam nospam.com> writes:
bearophile wrote:
Don:

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

Cute.
Simpler alternative, the dot isn't necessary:

traits_compiles(XXX)
traits_typeid(TTT)
traits_stringof(T)
traits_allmembers(T)
traits_error("message");

That is WAY more complicated! It adds a crazy number of keywords, and
isn't extensible.

Oct 30 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
Don wrote:
Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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,

-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.

Again with the double underscores. :)

Yes. That's why I said "at least as good".

I'm starting to think we need a
separate namespace for the CT stuff.

D.compiles(XXX)
D.typeof(foo)
D.stringof(T)
D.allMembers(T)

That's not bad. Can't be 'D', though, has to look like a keyword. Maybe
something like 'traits' instead. In exchange, get rid of the '__traits'
and 'typeid' keywords. Not sure about typeof, though.

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

IMHO this looks better than __traits(compiles, XXX) but it actually has
the same flexibility, and it's a straightforward transformation inside
the compiler.
For bonus points, allow 'with(traits)':

with(traits) {
if (compiles(XXX)) return stringof(T);
else error("Can't use " ~ stringof(T) ~ " in a transmogrifier.");
}

I like it. It's a clean, simple solution. The std.traits module will
just have to be renamed to std.meta or something. Or one could possibly
use 'meta' as the new keyword:

meta.compiles(XXX)
meta.typeid(T)
meta.stringof(T)

Actually, I think I like that better than 'traits'.

-Lars

Oct 30 2009
Justin Johansson <no spam.com> writes:
Lars T. Kyllingstad Wrote:

Don wrote:
Don wrote:
Denis Koroskin wrote:
On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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,

-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.

Again with the double underscores. :)

Yes. That's why I said "at least as good".

I'm starting to think we need a
separate namespace for the CT stuff.

D.compiles(XXX)
D.typeof(foo)
D.stringof(T)
D.allMembers(T)

That's not bad. Can't be 'D', though, has to look like a keyword. Maybe
something like 'traits' instead. In exchange, get rid of the '__traits'
and 'typeid' keywords. Not sure about typeof, though.

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

IMHO this looks better than __traits(compiles, XXX) but it actually has
the same flexibility, and it's a straightforward transformation inside
the compiler.
For bonus points, allow 'with(traits)':

with(traits) {
if (compiles(XXX)) return stringof(T);
else error("Can't use " ~ stringof(T) ~ " in a transmogrifier.");
}

I like it. It's a clean, simple solution. The std.traits module will
just have to be renamed to std.meta or something. Or one could possibly
use 'meta' as the new keyword:

meta.compiles(XXX)
meta.typeid(T)
meta.stringof(T)

Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about anything else
except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more user-friendly.
Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what it's about.
For some reason,
I don't know why, 'meta' has an aire of karma about it.

Justin

Oct 30 2009
Leandro Lucarella <llucax gmail.com> writes:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about anything else
except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what it's about.
For some reason,
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to compiler
internals, AST, etc.

--
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Yo soy peperino el que siempre pone el vino, yo soy aquel que come los
huevos con tocino.
-- Peperino PÃ³moro

Oct 30 2009
Don <nospam nospam.com> writes:
Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about anything else
except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what it's about.
For some reason,
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way to
incorporate reflection. It could be like Object and TypeInfo, implicitly
available in every module and tightly coupled to the compiler, but can
be viewed by the user as if it were just a module. It'd be particularly
interesting if some of the functions _were_  actually implemented in
library code, when possible.

Oct 30 2009
Jason House <jason.james.house gmail.com> writes:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about anything else
except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what it's about.
For some reason,
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way to
incorporate reflection. It could be like Object and TypeInfo, implicitly
available in every module and tightly coupled to the compiler, but can
be viewed by the user as if it were just a module. It'd be particularly
interesting if some of the functions _were_  actually implemented in
library code, when possible.

What about going one step further? You could require an import statement to use
traits. For example, import traits=std.traits could reproduce your earlier
suggestion, but gives added flexibility to the programmer. It also eliminates a
keyword.

Oct 30 2009
Don <nospam nospam.com> writes:
Jason House wrote:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about anything else
except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what it's about.
For some reason,
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way to
incorporate reflection. It could be like Object and TypeInfo, implicitly
available in every module and tightly coupled to the compiler, but can
be viewed by the user as if it were just a module. It'd be particularly
interesting if some of the functions _were_  actually implemented in
library code, when possible.

What about going one step further? You could require an import statement to
use traits. For example, import traits=std.traits could reproduce your earlier
suggestion, but gives added flexibility to the programmer. It also eliminates a
keyword.

It's too fundamental for that. You can't use template constraints
without it.
BTW, 'scope' is another possible magic namespace.

scope.compiles(XXX) -- true if XXX compiles in the current scope.

More generally, scope.YYY()  would provide metaprogramming information
about the property YYY of the current scope.

Nov 02 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
Jason House wrote:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about
anything else except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to
compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way to
incorporate reflection. It could be like Object and TypeInfo,
implicitly available in every module and tightly coupled to the
compiler, but can be viewed by the user as if it were just a module.
It'd be particularly interesting if some of the functions _were_
actually implemented in library code, when possible.

What about going one step further? You could require an import
statement to use traits. For example, import traits=std.traits could
programmer. It also eliminates a keyword.

It's too fundamental for that. You can't use template constraints
without it.
BTW, 'scope' is another possible magic namespace.

scope.compiles(XXX) -- true if XXX compiles in the current scope.

More generally, scope.YYY()  would provide metaprogramming information
about the property YYY of the current scope.

traits/meta/compiler namespace?

If it's just about avoiding new keywords I think this feature is
fundamental enough to deserve its own keyword, and all of the above are
more descriptive than 'scope'.

Is this "magic namespace" proposal technically difficult to implement in
the compiler?

-Lars

Nov 02 2009
Don <nospam nospam.com> writes:
Lars T. Kyllingstad wrote:
Don wrote:
Jason House wrote:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about
anything else except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to
compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way
to incorporate reflection. It could be like Object and TypeInfo,
implicitly available in every module and tightly coupled to the
compiler, but can be viewed by the user as if it were just a module.
It'd be particularly interesting if some of the functions _were_
actually implemented in library code, when possible.

What about going one step further? You could require an import
statement to use traits. For example, import traits=std.traits could
programmer. It also eliminates a keyword.

It's too fundamental for that. You can't use template constraints
without it.
BTW, 'scope' is another possible magic namespace.

scope.compiles(XXX) -- true if XXX compiles in the current scope.

More generally, scope.YYY()  would provide metaprogramming information
about the property YYY of the current scope.

traits/meta/compiler namespace?

It's another namespace suggestion. Just brainstorming.

If it's just about avoiding new keywords I think this feature is
fundamental enough to deserve its own keyword, and all of the above are
more descriptive than 'scope'.

Is this "magic namespace" proposal technically difficult to implement in
the compiler?

See for yourself. For example, the patch below (against svn 234) allows
'__traits' as the magic namespace. The existing __traits stuff continues
to compile. <g>

__traits.compiles(XXX);
__traits.isArithmetic; // note, property syntax OK if no arguments
__traits.isArithmetic(int*);

(Any error messages involving __traits are wrong, of course).

Index: parse.c
===================================================================
--- parse.c	(revision 234)
+++ parse.c	(working copy)
-4934,6 +4934,20
Objects *args = NULL;

nextToken();
+	    if (token.value == TOKdot) {
+	        // __traits.identifier(args, ...)
+		nextToken();
+		if (token.value != TOKidentifier)
+		{   error("__traits.identifier(args...) expected");
+			goto Lerr;
+		}
+		ident = token.ident;
+		nextToken();
+		if (token.value==TOKlparen)
+		args = parseTemplateArgumentList2();
+	        e = new TraitsExp(loc, ident, args);
+		break;
+	    }
check(TOKlparen);
if (token.value != TOKidentifier)
{   error("__traits(identifier, args...) expected");

Nov 02 2009
Don <nospam nospam.com> writes:
Don wrote:
Don wrote:
Jason House wrote:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about
anything else except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand
what it's about.  For some reason,
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to
compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way
to incorporate reflection. It could be like Object and TypeInfo,
implicitly available in every module and tightly coupled to the
compiler, but can be viewed by the user as if it were just a
module. It'd be particularly interesting if some of the functions
_were_  actually implemented in library code, when possible.

What about going one step further? You could require an import
statement to use traits. For example, import traits=std.traits could
the programmer. It also eliminates a keyword.

It's too fundamental for that. You can't use template constraints
without it.
BTW, 'scope' is another possible magic namespace.

scope.compiles(XXX) -- true if XXX compiles in the current scope.

More generally, scope.YYY()  would provide metaprogramming
information about the property YYY of the current scope.

traits/meta/compiler namespace?

It's another namespace suggestion. Just brainstorming.

If it's just about avoiding new keywords I think this feature is
fundamental enough to deserve its own keyword, and all of the above
are more descriptive than 'scope'.

Is this "magic namespace" proposal technically difficult to implement
in the compiler?

See for yourself. For example, the patch below (against svn 234) allows
'__traits' as the magic namespace. The existing __traits stuff continues
to compile. <g>

And BTW, to allow 'meta' as another synonym for the same magic
namespace, add this line to lexer.c, line 2960.

{	"__traits",	TOKtraits	},
+    {	"meta",	        TOKtraits	},

(Hmm. Didn't know __overloadset was a keyword. The things you find...)

Nov 02 2009
Leandro Lucarella <llucax gmail.com> writes:
Don, el  2 de noviembre a las 11:14 me escribiste:
Jason House wrote:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about anything else
except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more user-friendly.
Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what it's about.
For some reason,
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean
way to incorporate reflection. It could be like Object and
TypeInfo, implicitly available in every module and tightly
coupled to the compiler, but can be viewed by the user as if it
were just a module. It'd be particularly interesting if some of
the functions _were_  actually implemented in library code, when
possible.

What about going one step further? You could require an import statement to use
traits. For example, import traits=std.traits could reproduce your earlier
suggestion, but gives added flexibility to the programmer. It also eliminates a
keyword.

It's too fundamental for that. You can't use template constraints
without it.
BTW, 'scope' is another possible magic namespace.

scope.compiles(XXX) -- true if XXX compiles in the current scope.

More generally, scope.YYY()  would provide metaprogramming
information about the property YYY of the current scope.

And what about scope(exit) and friends?

--
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Borrowing money from a friend is like having sex. It just completely changes
the relationship.
-- George Constanza

Nov 02 2009
grauzone <none example.net> writes:
Don wrote:
Jason House wrote:
Don Wrote:

Leandro Lucarella wrote:
Justin Johansson, el 30 de octubre a las 08:42 me escribiste:
Actually, I think I like that better than 'traits'.

-Lars

I'm in agreement with whoever suggested 'meta' or just about
anything else except  'traits'.
'meta', whilst perhaps an overloaded keyword, is still much more
user-friendly.  Whenever
I see 'traits' I get the feeling I need a Ph.D. to understand what
I don't know why, 'meta' has an aire of karma about it.

"compiler"? That could open the door to other types of access to
compiler
internals, AST, etc.

Yup. I think the 'magic namespace' approach is a simple, clean way to
incorporate reflection. It could be like Object and TypeInfo,
implicitly available in every module and tightly coupled to the
compiler, but can be viewed by the user as if it were just a module.
It'd be particularly interesting if some of the functions _were_
actually implemented in library code, when possible.

What about going one step further? You could require an import
statement to use traits. For example, import traits=std.traits could
programmer. It also eliminates a keyword.

It's too fundamental for that. You can't use template constraints
without it.
BTW, 'scope' is another possible magic namespace.

scope.compiles(XXX) -- true if XXX compiles in the current scope.

More generally, scope.YYY()  would provide metaprogramming information
about the property YYY of the current scope.

I suggest we use static. static.YYY(), doesn't look that lovely?

Nov 02 2009
Robert Clipsham <robert octarineparrot.com> writes:
Don wrote:
I'm starting to think we need a
separate namespace for the CT stuff.

D.compiles(XXX)
D.typeof(foo)
D.stringof(T)
D.allMembers(T)

That's not bad. Can't be 'D', though, has to look like a keyword. Maybe
something like 'traits' instead. In exchange, get rid of the '__traits'
and 'typeid' keywords. Not sure about typeof, though.

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

IMHO this looks better than __traits(compiles, XXX) but it actually has
the same flexibility, and it's a straightforward transformation inside
the compiler.
For bonus points, allow 'with(traits)':

with(traits) {
if (compiles(XXX)) return stringof(T);
else error("Can't use " ~ stringof(T) ~ " in a transmogrifier.");
}

This could even be implemented in phobos (or object.d to avoid an import
when you want to use it), using something like:

pragma(traits) struct traits
{
// Members automatically added by the compiler, or maybe just their
// declarations eg:
static T delegate()[] allMembers(T)(T type);
}

This way there's no need to force a certain name, as it can be chosen by
the developer (by either using renaming imports or just giving the
struct a different name eg pragma(traits) struct meta {}).

Oct 30 2009
"Nick Sabalausky" <a a.a> writes:
"Robert Clipsham" <robert octarineparrot.com> wrote in message
news:hcg0qr$fce$1 digitalmars.com...
Don wrote:
I'm starting to think we need a
separate namespace for the CT stuff.

D.compiles(XXX)
D.typeof(foo)
D.stringof(T)
D.allMembers(T)

That's not bad. Can't be 'D', though, has to look like a keyword. Maybe
something like 'traits' instead. In exchange, get rid of the '__traits'
and 'typeid' keywords. Not sure about typeof, though.

traits.compiles(XXX)
traits.typeid(TTT)
traits.stringof(T)
traits.allMembers(T)
traits.error("message");

IMHO this looks better than __traits(compiles, XXX) but it actually has
the same flexibility, and it's a straightforward transformation inside
the compiler.
For bonus points, allow 'with(traits)':

with(traits) {
if (compiles(XXX)) return stringof(T);
else error("Can't use " ~ stringof(T) ~ " in a transmogrifier.");
}

This could even be implemented in phobos (or object.d to avoid an import
when you want to use it), using something like:

pragma(traits) struct traits
{
// Members automatically added by the compiler, or maybe just their
// declarations eg:
static T delegate()[] allMembers(T)(T type);
}

This way there's no need to force a certain name, as it can be chosen by
the developer (by either using renaming imports or just giving the struct
a different name eg pragma(traits) struct meta {}).

I'm not sure I see the value in being able to rename that. That's like
making sure people can rename "for".

Oct 30 2009
Robert Clipsham <robert octarineparrot.com> writes:
Nick Sabalausky wrote:
I'm not sure I see the value in being able to rename that. That's like
making sure people can rename "for".

I don't either, that's just a nice side effect for people who dislike
whatever name is decided on.

Oct 31 2009
Walter Bright <newshound1 digitalmars.com> writes:
Lars T. Kyllingstad wrote:
What I cannot for the life of me understand is WHY the double
underscores? What's wrong with just "traits"?

Because D needed the feature, and it wasn't clear what a good syntax for
it would be. So __traits is a "put something out there, make it work, if
it proves its usefulness and a good syntax for it appears, then that can

Oct 29 2009
Leandro Lucarella <llucax gmail.com> writes:
Walter Bright, el 29 de octubre a las 16:06 me escribiste:
What I cannot for the life of me understand is WHY the double
underscores? What's wrong with just "traits"?

Because D needed the feature, and it wasn't clear what a good syntax
for it would be. So __traits is a "put something out there, make it
work, if it proves its usefulness and a good syntax for it appears,

And now, being moderately close to D2 stabilization, isn't a good moment
to think about a better syntax or just live with traits() as it is (but

Same for __gshared.

--
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Es mucho mas probable que el salchichÃ³n sea primavera a que la primavera
sea salchichÃ³n.
-- Peperino PÃ³moro

Oct 29 2009
"Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Leandro Lucarella wrote:
Walter Bright, el 29 de octubre a las 16:06 me escribiste:
What I cannot for the life of me understand is WHY the double
underscores? What's wrong with just "traits"?

Because D needed the feature, and it wasn't clear what a good syntax
for it would be. So __traits is a "put something out there, make it
work, if it proves its usefulness and a good syntax for it appears,

And now, being moderately close to D2 stabilization, isn't a good moment
to think about a better syntax or just live with traits() as it is (but

Same for __gshared.

I'm not convinced about __gshared. As far as I've understood, __gshared
is a "don't use this unless you know what you are doing" feature. As
such, it should probably be a bit ugly.

__traits(), on the other hand, is more of a "hey you guys, you should
try this traits thing, it's totally neat" feature.

-Lars

Oct 30 2009
Leandro Lucarella <llucax gmail.com> writes:
Lars T. Kyllingstad, el 30 de octubre a las 08:55 me escribiste:
Leandro Lucarella wrote:
Walter Bright, el 29 de octubre a las 16:06 me escribiste:
What I cannot for the life of me understand is WHY the double
underscores? What's wrong with just "traits"?

Because D needed the feature, and it wasn't clear what a good syntax
for it would be. So __traits is a "put something out there, make it
work, if it proves its usefulness and a good syntax for it appears,

And now, being moderately close to D2 stabilization, isn't a good moment
to think about a better syntax or just live with traits() as it is (but

Same for __gshared.

I'm not convinced about __gshared. As far as I've understood,
__gshared is a "don't use this unless you know what you are doing"
feature. As such, it should probably be a bit ugly.

D is a system programming language. I don't see why one should be over
patronizing. It's enough to clarify what the keyword does in the
documentation. __gshared is not *that* rare, if you are interfacing with
C, every C global have to be __gshared, it just makes the code uglier for
no reason. Maybe it can be renamed to cglobal? I think we need a good
descriptive name so people can know what it's about, not an ugly
obfuscated one to confuse and scare them.

--
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
I can't watch TV for four minutes without thinking
I have five serious diseases.
Like: "Do you ever wake up tired in the mornings?"
Oh my god I have this, write this down. Whatever it is, I have this.

Oct 30 2009
Jason House <jason.james.house gmail.com> writes:
Denis Koroskin Wrote:

On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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.

code. Certainly, __traits is ugly, but it is easier to understand when readig
code and easier to write.

Oct 29 2009
"Denis Koroskin" <2korden gmail.com> writes:
On Thu, 29 Oct 2009 15:32:51 +0300, Jason House
<jason.james.house gmail.com> wrote:

Denis Koroskin Wrote:

On Thu, 29 Oct 2009 15:12:51 +0300, Lars T. Kyllingstad
<public 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, ...)

-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.

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);

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
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)

?

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
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

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
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.

Oct 29 2009
"Saaa" <empty needmail.com> writes:
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?
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

That's all :)

Oct 29 2009
"Saaa" <empty needmail.com> writes:
Also, no mention about .dup not being a deep dup.

Oct 29 2009
"Saaa" <empty needmail.com> writes:
crp
p20. 40 words? <<<<

those <<<< where for myself, to check

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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?
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

That's all :)

Thanks much!

Andrei

Oct 29 2009
"Saaa" <empty needmail.com> writes:
Could anybody clear these up for me?

p16. Is there anything other than the random values, unsafe about void
assignment?

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. 10 int take up 40 words?

Thanks!

Oct 30 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Saaa wrote:
Could anybody clear these up for me?

p16. Is there anything other than the random values, unsafe about void
assignment?

I'd put your feedback on my pile of things to do, but now that you ask,
I made this change to the incriminated paragraph:

===========
Such  uninitialized arrays  are particularly  useful for  large arrays
that serve  as temporary buffers.   An uninitialized integral  may not
cause  too   much  harm,  but  uninitialized  values   of  types  with
indirections (such as arrays themselves) are unsafe.
===========

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

T[] fun() { T[10] a; return a; }
...

There's no change in size there.

p20. 10 int take up 40 words?

The example given has a per-row payload of 10 ints, i.e. 40 words.

Andrei

Oct 30 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Andrei Alexandrescu wrote:
Saaa wrote:
Could anybody clear these up for me?

p16. Is there anything other than the random values, unsafe about
void assignment?

I'd put your feedback on my pile of things to do, but now that you ask,
I made this change to the incriminated paragraph:

===========
Such  uninitialized arrays  are particularly  useful for  large arrays
that serve  as temporary buffers.   An uninitialized integral  may not
cause  too   much  harm,  but  uninitialized  values   of  types  with
indirections (such as arrays themselves) are unsafe.
===========

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

T[] fun() { T[10] a; return a; }
...

There's no change in size there.

p20. 10 int take up 40 words?

The example given has a per-row payload of 10 ints, i.e. 40 words.

It's bytes actually. So finally I rewrote those last words as:

"... small  per-row payload of~10   int s (40 bytes)."

Andrei

Oct 30 2009
"Saaa" <empty needmail.com> writes:
Andrei Alexandrescu wrote:
Andrei Alexandrescu wrote:
Saaa wrote:
Could anybody clear these up for me?

p16. Is there anything other than the random values, unsafe about void
assignment?

I'd put your feedback on my pile of things to do, but now that you ask, I
made this change to the incriminated paragraph:

===========
Such  uninitialized arrays  are particularly  useful for  large arrays
that serve  as temporary buffers.   An uninitialized integral  may not
cause  too   much  harm,  but  uninitialized  values   of  types  with
indirections (such as arrays themselves) are unsafe.
===========

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

T[] fun() { T[10] a; return a; }
...

There's no change in size there.

p20. 10 int take up 40 words?

The example given has a per-row payload of 10 ints, i.e. 40 words.

It's bytes actually. So finally I rewrote those last words as:

"... small  per-row payload of~10   int s (40 bytes)."

Andrei

Thanks !

Out of interest, do you keep a list of common error or something alike that
helps you keep errors at a minimum?
Also, do you have automated example checking?
Or, more general, I would be interested in a small article explaining how a
book like this is written.

Maybe After the book is finished :)

Oct 30 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Saaa wrote:
Andrei Alexandrescu wrote:
Andrei Alexandrescu wrote:
Saaa wrote:
Could anybody clear these up for me?

p16. Is there anything other than the random values, unsafe about void
assignment?

I'd put your feedback on my pile of things to do, but now that you ask, I
made this change to the incriminated paragraph:

===========
Such  uninitialized arrays  are particularly  useful for  large arrays
that serve  as temporary buffers.   An uninitialized integral  may not
cause  too   much  harm,  but  uninitialized  values   of  types  with
indirections (such as arrays themselves) are unsafe.
===========

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

T[] fun() { T[10] a; return a; }
...

There's no change in size there.

p20. 10 int take up 40 words?

The example given has a per-row payload of 10 ints, i.e. 40 words.

It's bytes actually. So finally I rewrote those last words as:

"... small  per-row payload of~10   int s (40 bytes)."

Andrei

Thanks !

Out of interest, do you keep a list of common error or something alike that
helps you keep errors at a minimum?

I got as sophisticated as having an email folder dedicated to TDPL.

Also, do you have automated example checking?

Yes. If you look at the document very closely, you'll see that some
snippets have a thin line above and below them. Those are automatically
checked every time I save the document. (There are 1-2 examples that
aren't checked in the Thermopylae excerpt because I switched editing to
a 64-bit machine that can't build D programs (I'll post a question later
today). But in the meantime I fixed those.)

Very short snippets do not have a thin line above and below them. Those
are not checked because they are short enough to warrant that I know
what I'm doing.

Some checked snippets wouldn't compile without being in a function, for
example:

enum size_t columns = 128;
// Allocate a matrix with 64 rows and 128 columns
auto matrix = new double[columns][64];
// No need to allocate each row - they already exist in-situ
foreach (ref row; matrix) {
... // use row of type double[columns]
}

These are automatically entered inside a unittest. Also, my code
extraction script (written in D!) automatically eliminates unneeded
"...", so the code as seen by the compiler is:

unittest {
enum size_t columns = 128;
// Allocate a matrix with 64 rows and 128 columns
auto matrix = new double[columns][64];
// No need to allocate each row - they already exist in-situ
foreach (ref row; matrix) {
// use row of type double[columns]
}
}

which passes compilation.

Some other examples need "invisible" support:

writeln("hey");

For those I have a special mechanism to insert invisible code, so my
text for the above actually looks like this:

\begin{D-invisible}
import std.stdio;
\end{D-invisible}
\begin{D-snippet}
writeln("hey");
\end{D-snippet}

What the compiler sees is a file importing std.stdio and including the
writeln inside a unittest.

I wouldn't know how to pull this off reasonably with e.g. Word, but I'm
sure it now has mechanisms or extensions that allow that kind of thing.
One thing I don't need to worry about with LaTeX is that it's text-based
so I can process it easily myself.

Or, more general, I would be interested in a small article explaining how a
book like this is written.

Maybe After the book is finished :)

I think the topic is well worth an article indeed. I continuously
streamline the process of building the book, and it's gotten pretty
sophisticated but very helpful as well. Index building is also an
interesting subtopic.

Andrei

Oct 30 2009
"Saaa" <empty needmail.com> writes:
Andrei Alexandrescu wrote
Saaa wrote:
Andrei Alexandrescu wrote:
Andrei Alexandrescu wrote:
Saaa wrote:
Could anybody clear these up for me?

p16. Is there anything other than the random values, unsafe about
void assignment?

I'd put your feedback on my pile of things to do, but now that you ask,
I made this change to the incriminated paragraph:

===========
Such  uninitialized arrays  are particularly  useful for  large arrays
that serve  as temporary buffers.   An uninitialized integral  may not
cause  too   much  harm,  but  uninitialized  values   of  types  with
indirections (such as arrays themselves) are unsafe.
===========

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

T[] fun() { T[10] a; return a; }
...

There's no change in size there.

p20. 10 int take up 40 words?

The example given has a per-row payload of 10 ints, i.e. 40 words.

It's bytes actually. So finally I rewrote those last words as:

"... small  per-row payload of~10   int s (40 bytes)."

Andrei

Thanks !

Out of interest, do you keep a list of common error or something alike
that helps you keep errors at a minimum?

I got as sophisticated as having an email folder dedicated to TDPL.

Also, do you have automated example checking?

Yes. If you look at the document very closely, you'll see that some
snippets have a thin line above and below them. Those are automatically
checked every time I save the document. (There are 1-2 examples that
aren't checked in the Thermopylae excerpt because I switched editing to a
64-bit machine that can't build D programs (I'll post a question later
today). But in the meantime I fixed those.)

Very short snippets do not have a thin line above and below them. Those
are not checked because they are short enough to warrant that I know what
I'm doing.

:)
Some checked snippets wouldn't compile without being in a function, for
example:

enum size_t columns = 128;
// Allocate a matrix with 64 rows and 128 columns
auto matrix = new double[columns][64];
// No need to allocate each row - they already exist in-situ
foreach (ref row; matrix) {
... // use row of type double[columns]
}

These are automatically entered inside a unittest. Also, my code
extraction script (written in D!) automatically eliminates unneeded

I Wouldn't accept it being written in C++ !! :D

"...", so the code as seen by the compiler is:

unittest {
enum size_t columns = 128;
// Allocate a matrix with 64 rows and 128 columns
auto matrix = new double[columns][64];
// No need to allocate each row - they already exist in-situ
foreach (ref row; matrix) {
// use row of type double[columns]
}
}

which passes compilation.

Some other examples need "invisible" support:

writeln("hey");

For those I have a special mechanism to insert invisible code, so my text
for the above actually looks like this:

\begin{D-invisible}
import std.stdio;
\end{D-invisible}
\begin{D-snippet}
writeln("hey");
\end{D-snippet}

What the compiler sees is a file importing std.stdio and including the
writeln inside a unittest.

nice

I wouldn't know how to pull this off reasonably with e.g. Word, but I'm
sure it now has mechanisms or extensions that allow that kind of thing.
One thing I don't need to worry about with LaTeX is that it's text-based
so I can process it easily myself.

Somehow I only associate LaTeX with b/w scientific articles :)

Or, more general, I would be interested in a small article explaining how
a book like this is written.

Maybe After the book is finished :)

I think the topic is well worth an article indeed. I continuously
streamline the process of building the book, and it's gotten pretty
sophisticated but very helpful as well. Index building is also an
interesting subtopic.

Andrei

Thanks, looking forward to the article ( and the tools used :P )

Oct 30 2009
Leandro Lucarella <llucax gmail.com> writes:
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)
----------------------------------------------------------------------
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

Oct 29 2009
Leandro Lucarella <llucax gmail.com> writes:
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)

Oct 29 2009
Bill Baxter <wbaxter gmail.com> writes:
On Thu, Oct 29, 2009 at 9:31 AM, Leandro Lucarella <llucax 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 =3D new double[4]; =A0 =A0 =A0 =A0 =A0// must be already allocate=

d
auto a1 =3D [ 0.5, -0.5, 1.5, 2 ];
auto a2 =3D [ 3.5, 5.5, 4.5, -1 ];
a[] =3D (a1[] + a2[]) / 2; =A0 =A0 =A0 =A0 // take the average of b and =

c
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =

^^^^^^^^^^^^^^^^^^^^^^^^^^^
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0t=

ake 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 i=

n
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 ca=
se.

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] =3D [1,2,3];
or
int[\$] =3D [1,2,3];

Something like that would be nice.

--bb

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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[3] .  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  auto .   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

Oct 29 2009
Leandro Lucarella <llucax gmail.com> writes:
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[3] .  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  auto .   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.

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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[3] .  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  auto .   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

Oct 29 2009
Max Samukha <spambox d-coding.com> writes:
On Thu, 29 Oct 2009 13:30:35 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail 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.

Oct 29 2009
"Denis Koroskin" <2korden gmail.com> writes:
On Thu, 29 Oct 2009 21:59:13 +0300, Max Samukha <spambox d-coding.com>
wrote:

On Thu, 29 Oct 2009 13:30:35 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail 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!

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Max Samukha wrote:
On Thu, 29 Oct 2009 13:30:35 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail 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.

Apparently the need was felt strongly enough that a library made it into
Boost that does exactly initialization of collections (and vector in
particular), in spite of being based on a very questionable design

Andrei

Oct 29 2009
Max Samukha <spambox d-coding.com> writes:
On Thu, 29 Oct 2009 16:07:14 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

Apparently the need was felt strongly enough that a library made it into
Boost that does exactly initialization of collections (and vector in
particular), in spite of being based on a very questionable design

Andrei

I guess you mean the assignment library
http://www.boost.org/doc/libs/1_40_0/libs/assign/doc/index.html.

"These lists are particularly useful in learning, testing, and
prototyping situations, but can also be handy otherwise."

While those are important, I am still not totally convinced that
dynamic arrays initialized from literals occur often in production
code. It remains a matter of opinion.

Oct 31 2009
bearophile <bearophileHUGS lycos.com> writes:
Max Samukha:

While those are important, I am still not totally convinced that
dynamic arrays initialized from literals occur often in production
code. It remains a matter of opinion.

In script-like code literals are common. So when you consider your production
code you must count that script-like code too. D is not a scripting language,
but it offers some things that allow it to "scale down". Collection literals
are one of the things that make D more handy than other lesser languages like
C++.

Bye,
bearophile

Oct 31 2009
Leandro Lucarella <llucax gmail.com> writes:
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[3] .  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  auto .   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

Oct 29 2009
Michael Rynn <michaelrynn optusnet.com.au> writes:
On Thu, 29 Oct 2009 12:23:18 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

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!

Good chapter, I learned some things, and I liked the Unicode
exposition.

Pg 114.  5

Did not understand why this code is a compiler bug.   To me its a
'feature', consistant with behaviour of underlying realloc, capacity
and length management, and consistant with having average good
efficiency for a ~= item. I do not want a clever compiler trying to
predict existance of an array aliasing.

Its a nice example of aliasing, only it seems just a bit harsh on the
poor old compiler.  Not good to have every page virtually subtitled ,
nice language, shame about the compiler..

I would like to see a function in std.array for D2, that does
efficiently what the example asserts should be possible, to force a
new allocation when required, in a simple one line statement,
syntactically sugared.

// At this point a and b are adjacent
//a ~= [0, 0, 0, 0];
/// Concantenation function which will gaurantee to return array using
only single new memory allocation containing a ~ b, for when you
really need it.
// T[] concat(T[] a, T[] b)  // maybe  more varargs

a = a.concat([0, 0, 0, 0]);

// OR in 2 lines just make the intention clear

auto c = a ~ b; // this should work just the same?
a = c;

assert(b == [40, 50, 60, 70]); // passes; a got reallocated

P114. 40

array.length op=   something.
// compiler  message that array.length is not an lvalue.

I like the compiler message.    Admittedly I would like the shorthand
too, but I do not see it as bug, because it reflects the C heritage.
Another feature.   Would like at least these bugs to be features..

P 123.  30
You didn't mention the in operator for AA returns a pointer to the
keys value, or null  This got me a little worried, as I liked using
the value returned by in operator, and had not used .get at all.

P 128 20-25

.."To support this encoding, Unicode
allocates no valid characters to numbers in the range 0xD800 through
0xDBFF"

Typo  ,   should be:   0xD800 through 0xDFFF here.

--
Michael Rynn <michaelrynn optusnet.com.au>

Nov 03 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michael Rynn wrote:
On Thu, 29 Oct 2009 12:23:18 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

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!

Good chapter, I learned some things, and I liked the Unicode
exposition.

Pg 114.  5

Did not understand why this code is a compiler bug.   To me its a
'feature', consistant with behaviour of underlying realloc, capacity
and length management, and consistant with having average good
efficiency for a ~= item. I do not want a clever compiler trying to
predict existance of an array aliasing.

Its a nice example of aliasing, only it seems just a bit harsh on the
poor old compiler.  Not good to have every page virtually subtitled ,
nice language, shame about the compiler..

I would like to see a function in std.array for D2, that does
efficiently what the example asserts should be possible, to force a
new allocation when required, in a simple one line statement,
syntactically sugared.

// At this point a and b are adjacent
//a ~= [0, 0, 0, 0];
/// Concantenation function which will gaurantee to return array using
only single new memory allocation containing a ~ b, for when you
really need it.
// T[] concat(T[] a, T[] b)  // maybe  more varargs

a = a.concat([0, 0, 0, 0]);

// OR in 2 lines just make the intention clear

auto c = a ~ b; // this should work just the same?
a = c;

assert(b == [40, 50, 60, 70]); // passes; a got reallocated

P114. 40

array.length op=   something.
// compiler  message that array.length is not an lvalue.

I like the compiler message.    Admittedly I would like the shorthand
too, but I do not see it as bug, because it reflects the C heritage.
Another feature.   Would like at least these bugs to be features..

P 123.  30
You didn't mention the in operator for AA returns a pointer to the
keys value, or null  This got me a little worried, as I liked using
the value returned by in operator, and had not used .get at all.

P 128 20-25

.."To support this encoding, Unicode
allocates no valid characters to numbers in the range 0xD800 through
0xDBFF"

Typo  ,   should be:   0xD800 through 0xDFFF here.

Thanks, I added this to my worklist.

Andrei

Nov 03 2009
"Saaa" <empty needmail.com> writes:
Also, no mention about .dup not being a deep dup.

Oct 29 2009
"Saaa" <empty needmail.com> writes:
Saaa wrote
Also, no mention about .dup not being a deep dup.

Sorry, should've been attached to my response

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

Oct 29 2009
"Robert Jacques" <sandford jhu.edu> writes:
On Thu, 29 Oct 2009 00:38:33 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail 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.)

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Robert Jacques wrote:
On Thu, 29 Oct 2009 00:38:33 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail 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

Oct 29 2009
Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
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:

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

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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:

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

Oct 29 2009
Andrei Alexandrescu Wrote:

Any feedback is welcome. Thanks!

Thanks Andrei, that was an excellent read.

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] = [ ??? ];

Oct 29 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Manuel wrote:
Andrei Alexandrescu Wrote:

Any feedback is welcome. Thanks!

Thanks Andrei, that was an excellent read.

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] = [ ??? ];

Great feedback, thank you!

Andrei

Oct 29 2009
Jason House <jason.james.house gmail.com> writes:
Andrei Alexandrescu 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?

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

What's the bugzilla number?

Oct 30 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
Andrei Alexandrescu 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?

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

What's the bugzilla number?

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

I can't believe I actually found it. Just got lucky - I vaguely know it
was submitted by someone in Poland. I never find anything with bugzilla...

Andrei

Oct 30 2009
Justin Johansson <no spam.com> writes:
Max Samukha Wrote:

On Thu, 29 Oct 2009 13:30:35 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail 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.

Is this the same argument as Andrei's rhetorical question
(in relation to proposed removal of D complex literals),
"Name me five significant complex numbers" from a few weeks ago?

(Sorry can't find the NG link just right now).

Oct 30 2009
Mike Parker <aldacron gmail.com> writes:
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

p.28 line 16:

symbols in less bits

should be

symbols in fewer bits


Oct 31 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Mike Parker 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

p.28 line 16:

>>> symbols in less bits

should be

>>> symbols in fewer bits

Thanks, fixed.

Andrei

Oct 31 2009
duser4ever <no spam.com> writes:
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

Sure I haven't come across anything that someone else hasn't already pointed
out, but here it is any:

P133 "Table 9.1 on page 301 summarizes dynamic array operations"
"Table 3.4 on page 134 summarizes dynamic array operations"

P118 something sounds wrong here also:
"However, if a function returns T[n], that not automatically
converted to T[]--it must be T[n]."

maybe "it is not automatically" vice "that not automatically"?

P117 this sentence does not sound natural to me;
"This means that copying arrays, passing arrays into functions,
and returning arrays from functions -- these all
copy entire arrays."

P111 change "in it" on line 8 to read "into it"

P111 change "bailout" on line 21 to read "bail out"

P110 change "responsible in making" to "responsible for making"

Not clear what you are saying here:

"The compiler is free to assume that when optimizing the operations into
primitive vector operations offered by the host processor."

What is it assuming? That I'm responsible? That the arrays do not overlap?

P109
auto a = [1.0, 2.5, 3.6];
auto b = [4.5, 5.5, 1.4];
auto c = new double[3]; // changing to "auto c = (new double[3])[] = 0.0;"
or adding the line "c[] = 0.0;" should do the trick
c[] += 4 * a[] + b[];

will not work. Since c is of type double[3] it's initial value is set to
[nan, nan, nan];
As a result any transaction performed on this array will result in the
same if it is not first initialized.

P101 change "comes just handy" to "comes in handy"

Oct 31 2009
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
duser4ever 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

Sure I haven't come across anything that someone else hasn't already pointed
out, but here it is any:

P133 "Table 9.1 on page 301 summarizes dynamic array operations"
"Table 3.4 on page 134 summarizes dynamic array operations"

Thanks, I'd forgotten to clean the intermediate files before building
the entire book.

P118 something sounds wrong here also:
"However, if a function returns T[n], that not automatically
converted to T[]--it must be T[n]."

maybe "it is not automatically" vice "that not automatically"?

P117 this sentence does not sound natural to me;
"This means that copying arrays, passing arrays into functions,
and returning arrays from functions -- these all
copy entire arrays."

P111 change "in it" on line 8 to read "into it"

P111 change "bailout" on line 21 to read "bail out"

P110 change "responsible in making" to "responsible for making"

Not clear what you are saying here:

"The compiler is free to assume that when optimizing the operations into
primitive vector operations offered by the host processor."

What is it assuming? That I'm responsible? That the arrays do not overlap?

P109
auto a = [1.0, 2.5, 3.6];
auto b = [4.5, 5.5, 1.4];
auto c = new double[3]; // changing to "auto c = (new double[3])[] =
0.0;" or adding the line "c[] = 0.0;" should do the trick
c[] += 4 * a[] + b[];

will not work. Since c is of type double[3] it's initial value is set to
[nan, nan, nan];
As a result any transaction performed on this array will result in the
same if it is not first initialized.

P101 change "comes just handy" to "comes in handy"

Thanks! Quite a few of these are new. I've added this to my worklist,
and as I see you give no email and no name, please email me privately
your name so I can add it to acknowledgments. (I'll do so for everyone
who sent me feedback.)

Andrei

Oct 31 2009
Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Thu, Oct 29, 2009 at 05:38, Andrei Alexandrescu <
SeeWebsiteForEmail 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!

Well, if that's a rough rough draft, I'll happily read the entire book...

I'm reading the AA part, and found that .dup doesn't exist for associative
arrays (D2.036). It's bug 816, I guess.
What's strange is that it's not listed as a bug in your text (red markings
and such). Did you define a dup(K,V) function somewhere else?

Philippe

Nov 11 2009