www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The Thermopylae excerpt of TDPL available online

reply 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
next sibling parent reply 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
parent reply 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
parent reply "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
parent 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
prev sibling next sibling parent reply "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
parent 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.
 I just have two comments:
 
 Code snippet in 4.2.1: Why do you suddenly use postfix array declaration 
 here?

Oops... I'd planned to simply pretend it doesn't exist. Thanks, I fixed that now.
 Code snippet just before 4.4.3: ("yowza" !in aa) doesn't work, at least 
 not with DMD 2.035. It has to be !("yowza" in aa). Very annoying.

Walter is planning to effect that change. By publishing time, there won't be any red and any pink in the book! (One nice thing about the book is that it gives us a good idea on what to work on. Walter has been on an incredible streak lately, and Don adds amazing value.) Andrei
Oct 29 2009
prev sibling next sibling parent reply =?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
parent reply 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
parent =?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 think undefined behavior is bad.
Oct 29 2009
prev sibling next sibling parent reply 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
parent reply 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
parent reply 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
parent 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
prev sibling next sibling parent reply 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
next sibling parent reply "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
next sibling parent reply "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!

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

I don't think he uses is(typeof(...)) in the text. The code snippets in question are marked "Note: normally the code below would not be included...", and I suppose he's put them there as a reminder for himself and Walter on what needs to be fixed before the book comes out. I agree with you, though, is(typeof(...)) is quite often misused, or at least used in an ugly way. Why not use __traits(compiles, ...) instead? -Lars

... which is at least as ugly.

I disagree. Pretend you are just learning D, and you are presented with the following two lines of code: static assert (is(typeof(XXX)); static assert (__traits(compiles, XXX)); Which of these would you most likely assume to be a check on whether XXX is compilable code? What I cannot for the life of me understand is WHY the double underscores? What's wrong with just "traits"? -Lars
Oct 29 2009
next sibling parent reply 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!

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

I don't think he uses is(typeof(...)) in the text. The code snippets in question are marked "Note: normally the code below would not be included...", and I suppose he's put them there as a reminder for himself and Walter on what needs to be fixed before the book comes out. I agree with you, though, is(typeof(...)) is quite often misused, or at least used in an ugly way. Why not use __traits(compiles, ...) instead? -Lars

... which is at least as ugly.

I disagree. Pretend you are just learning D, and you are presented with the following two lines of code: static assert (is(typeof(XXX)); static assert (__traits(compiles, XXX)); Which of these would you most likely assume to be a check on whether XXX is compilable code? What I cannot for the life of me understand is WHY the double underscores? What's wrong with just "traits"? -Lars

Also is(typeof(XXX)) *doesn't* currently check that XXX is compilable, just that it has a type. OTOH __traits(compiles, XXX) is ugly. traits(compiles, XXX) would be better; but I think we need to do better than that. It's the bread-and-butter of metaprogramming in D. Using the ugly syntax, it has well and truly proved its value. I've counted 20 uses in what I've seen of Andrei's book -- it appears about as often as (say) 'delegate'! It does a beautiful thing, it deserves a beautiful syntax. Something at least as good as __compiles(XXX), I reckon.
Oct 29 2009
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
 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!

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

I don't think he uses is(typeof(...)) in the text. The code snippets in question are marked "Note: normally the code below would not be included...", and I suppose he's put them there as a reminder for himself and Walter on what needs to be fixed before the book comes out. I agree with you, though, is(typeof(...)) is quite often misused, or at least used in an ugly way. Why not use __traits(compiles, ...) instead? -Lars

... which is at least as ugly.

I disagree. Pretend you are just learning D, and you are presented with the following two lines of code: static assert (is(typeof(XXX)); static assert (__traits(compiles, XXX)); Which of these would you most likely assume to be a check on whether XXX is compilable code? What I cannot for the life of me understand is WHY the double underscores? What's wrong with just "traits"? -Lars

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

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
parent reply Don <nospam nospam.com> writes:
Lars T. Kyllingstad wrote:
 Don wrote:
 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!

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

I don't think he uses is(typeof(...)) in the text. The code snippets in question are marked "Note: normally the code below would not be included...", and I suppose he's put them there as a reminder for himself and Walter on what needs to be fixed before the book comes out. I agree with you, though, is(typeof(...)) is quite often misused, or at least used in an ugly way. Why not use __traits(compiles, ...) instead? -Lars

... which is at least as ugly.

I disagree. Pretend you are just learning D, and you are presented with the following two lines of code: static assert (is(typeof(XXX)); static assert (__traits(compiles, XXX)); Which of these would you most likely assume to be a check on whether XXX is compilable code? What I cannot for the life of me understand is WHY the double underscores? What's wrong with just "traits"? -Lars

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

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)

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
next sibling parent reply 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.");
 }

Not nice. Bad. Bye, bearophile
Oct 30 2009
parent 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
prev sibling next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
 Lars T. Kyllingstad wrote:
 Don wrote:
 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!

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

I don't think he uses is(typeof(...)) in the text. The code snippets in question are marked "Note: normally the code below would not be included...", and I suppose he's put them there as a reminder for himself and Walter on what needs to be fixed before the book comes out. I agree with you, though, is(typeof(...)) is quite often misused, or at least used in an ugly way. Why not use __traits(compiles, ...) instead? -Lars

... which is at least as ugly.

I disagree. Pretend you are just learning D, and you are presented with the following two lines of code: static assert (is(typeof(XXX)); static assert (__traits(compiles, XXX)); Which of these would you most likely assume to be a check on whether XXX is compilable code? What I cannot for the life of me understand is WHY the double underscores? What's wrong with just "traits"? -Lars

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

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)

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
parent reply Justin Johansson <no spam.com> writes:
Lars T. Kyllingstad Wrote:

 Don wrote:
 Lars T. Kyllingstad wrote:
 Don wrote:
 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!

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

I don't think he uses is(typeof(...)) in the text. The code snippets in question are marked "Note: normally the code below would not be included...", and I suppose he's put them there as a reminder for himself and Walter on what needs to be fixed before the book comes out. I agree with you, though, is(typeof(...)) is quite often misused, or at least used in an ugly way. Why not use __traits(compiles, ...) instead? -Lars

... which is at least as ugly.

I disagree. Pretend you are just learning D, and you are presented with the following two lines of code: static assert (is(typeof(XXX)); static assert (__traits(compiles, XXX)); Which of these would you most likely assume to be a check on whether XXX is compilable code? What I cannot for the life of me understand is WHY the double underscores? What's wrong with just "traits"? -Lars

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

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)

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
parent reply 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

'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
parent reply 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

'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
parent reply 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

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

internals, AST, etc.

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
next sibling parent reply "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

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 internals, AST, etc.

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.

Do you mean in addition to or instead of the already proposed 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
parent reply 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

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 internals, AST, etc.

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.

Do you mean in addition to or instead of the already proposed 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
parent Don <nospam nospam.com> writes:
Don wrote:
 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

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 internals, AST, etc.

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.

Do you mean in addition to or instead of the already proposed 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 }, { "__overloadset", TOKoverloadset }, (Hmm. Didn't know __overloadset was a keyword. The things you find...)
Nov 02 2009
prev sibling parent 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

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 internals, AST, etc.

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.

I suggest we use static. static.YYY(), doesn't look that lovely?
Nov 02 2009
prev sibling parent reply 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
parent reply "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
parent 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
prev sibling next sibling parent reply 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 be adopted."
Oct 29 2009
parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Leandro Lucarella wrote:
 Walter Bright, el 29 de octubre a las 16:06 me escribiste:
 Lars T. Kyllingstad wrote:
 What I cannot for the life of me understand is WHY the double
 underscores? What's wrong with just "traits"?

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 be adopted."

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 without the leading __)? 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
prev sibling parent 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

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

internals, AST, etc.

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
prev sibling parent 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.

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.
Oct 29 2009
prev sibling next sibling parent "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!

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
prev sibling next sibling parent "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  

 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  

 I agree with you, though, is(typeof(...)) is quite often misused, or  

 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.

I was talking about ugliness, not readability. There are only 2 places where is(typeof(...)) feature is used: assert(is(typeof(somePrimes) == int[])); // perfectly fine IMO static assert(!is(typeof(a[length - 1]))); // misused, yes BTW, typeof is a bit inconsistent with .stringof, .alignof, .sizeof etc (typeof(foo) but foo.sizeof). Any chance this inconsistency is going to be fixed? Either assert(typeof(x + y) == int); -> assert(is((x + y).typeof == int)); Or assert((x + y).sizeof == 4); -> assert(is(sizeof(x + y) == 4);
Oct 29 2009
prev sibling next sibling parent 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
prev sibling parent "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");

Not nice. Bad.
Oct 30 2009
prev sibling next sibling parent reply 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
parent reply 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
parent reply 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
parent reply 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

assert(x == 0) be assert(x[] == 0) ?

Thanks, Andrei

top of page 102

Thanks. Notice that x is an integer because it was fetched as array[5]. Andrei
Oct 29 2009
parent 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

assert(x == 0) be assert(x[] == 0) ?

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
prev sibling next sibling parent reply "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? p14. further expansions reads as if expansions have been made especially because the comment is maybe that obvious that I was looking for something else to be there. p16. Is there anything other than the random values, unsafe about void assignment? When you write something to be unsafe, I expect it to not be allowed safe modules. p18. What is unsafe about implicit conversion of static to dynamic array? Meaning getting a dynamic array pointing to a stack allocated array. Any operation changing its size could copy the array to the heap. What am I missing p20. An alternative to figure 4.5 could display row/column properties. p20. change 1,000,000 to 1_000_000 :D to me the comma is a decimal separator anyways. p20. 40 words? <<<< p21. Why use enum iso immutable? Probably in the previous chapters explained :) p21. Second paragraph reads as a solution to the above p22. typo: array!literal p25. Expected to read about ref in foreach That's all :)
Oct 29 2009
next sibling parent "Saaa" <empty needmail.com> writes:
Also, no mention about .dup not being a deep dup. 
Oct 29 2009
prev sibling next sibling parent "Saaa" <empty needmail.com> writes:
crp
 p20. 40 words? <<<<

Oct 29 2009
prev sibling next sibling parent 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?
 p14. further expansions reads as if expansions have been made
         especially because the comment is maybe that obvious that I was 
 looking for something else to be there.
 p16. Is there anything other than the random values, unsafe about void 
 assignment?
         When you write something to be unsafe, I expect it to not be allowed 
 safe modules.
 p18. What is unsafe about implicit conversion of static to dynamic array?
         Meaning getting a dynamic array pointing to a stack allocated array.
         Any operation changing its size could copy the array to the heap. 
 What am I missing
 p20. An alternative to figure 4.5 could display row/column properties.
 p20. change 1,000,000 to 1_000_000 :D to me the comma is a decimal separator 
 anyways.
 p20. 40 words? <<<<
 p21. Why use enum iso immutable? Probably in the previous chapters explained 
 :)
 p21. Second paragraph reads as a solution to the above
 p22. typo: array!literal
 p25. Expected to read about ref in foreach
 
 That's all :) 

Thanks much! Andrei
Oct 29 2009
prev sibling parent reply "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
parent reply 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; } ... auto x = fun(); // gained access to recycled stack memory 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
parent reply 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; } ... auto x = fun(); // gained access to recycled stack memory 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
parent reply "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; } ... auto x = fun(); // gained access to recycled stack memory 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
parent reply 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?


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


... auto x = fun(); // gained access to recycled stack memory There's no change in size there.
 p20. 10 int take up 40 words?



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


... auto x = fun(); // gained access to recycled stack memory There's no change in size there.
 p20. 10 int take up 40 words?



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

Thanks, looking forward to the article ( and the tools used :P )
Oct 30 2009
prev sibling next sibling parent reply 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) ---------------------------------------------------------------------- Cuando intenté arrimarle mi brazo Se puso a hablar de Miller, de Anais Nin y Picasso Y si osaba intentar robarle un beso Se ponía a leer de Neruda unos versos Me hizo mucho mal la cumbiera intelectual
Oct 29 2009
next sibling parent reply "Saaa" <empty needmail.com> writes:
Also, no mention about .dup not being a deep dup. 
Oct 29 2009
next sibling parent "Saaa" <empty needmail.com> writes:
Saaa wrote
 Also, no mention about .dup not being a deep dup.

Oct 29 2009
prev sibling parent 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
prev sibling next sibling parent reply 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!

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
next sibling parent reply 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:

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?

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
parent reply 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
parent reply 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 technique - overloading of the comma operator. Andrei
Oct 29 2009
parent reply 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 
technique - overloading of the comma operator.

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
parent 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
prev sibling parent reply 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
parent 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
prev sibling parent 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
prev sibling next sibling parent 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
prev sibling next sibling parent 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=


 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 =


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


 (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=

 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
prev sibling next sibling parent reply "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
parent 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
prev sibling next sibling parent 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:

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
prev sibling next sibling parent reply 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: p16: int quadrupeds[100], int legs[4 * quadrupeds.length] <- is the C-style array declaration syntax intended? p20: No mention of the "new T[][](rows, cols)" syntax? p26 (User-Defined Types as Keys): No need for opEquals? -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Oct 29 2009
parent 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: p16: int quadrupeds[100], int legs[4 * quadrupeds.length] <- is the C-style array declaration syntax intended?

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

Oops, completely forgot about that one.
 p26 (User-Defined Types as Keys): No need for opEquals?

There currently is, but there shouldn't and it won't. Andrei
Oct 29 2009
prev sibling next sibling parent "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
prev sibling next sibling parent 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:

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?

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
prev sibling next sibling parent Leandro Lucarella <llucax gmail.com> writes:
Walter Bright, el 29 de octubre a las 16:06 me escribiste:
 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 be adopted."

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 without the leading __)? 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
prev sibling next sibling parent 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
prev sibling next sibling parent 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:
Lars T. Kyllingstad wrote:
What I cannot for the life of me understand is WHY the double
underscores? What's wrong with just "traits"?

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 be adopted."

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 without the leading __)? 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
prev sibling next sibling parent reply 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
parent 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
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0016e6d77e3c3189aa0478193fe4
Content-Type: text/plain; charset=ISO-8859-1

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 --0016e6d77e3c3189aa0478193fe4 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Thu, Oct 29, 2009 at 05:38, Andrei Alexandres= cu <span dir=3D"ltr">&lt;<a href=3D"mailto:SeeWebsiteForEmail erdani.org">S= eeWebsiteForEmail erdani.org</a>&gt;</span> wrote:<br><blockquote class=3D"= gmail_quote" style=3D"border-left: 1px solid rgb(204, 204, 204); margin: 0p= t 0pt 0pt 0.8ex; padding-left: 1ex;"> It&#39;s a rough rough draft, but one for the full chapter on arrays, assoc= iative arrays, and strings.<br> <br> <a href=3D"http://erdani.com/d/thermopylae.pdf" target=3D"_blank">http://er= dani.com/d/thermopylae.pdf</a><br> <br> Any feedback is welcome. Thanks!<font color=3D"#888888"></font></blockquote=
<div><br>Well, if that&#39;s a rough rough draft, I&#39;ll happily read th=

esn&#39;t exist for associative arrays (D2.036). It&#39;s bug 816, I guess.= <br> What&#39;s strange is that it&#39;s not listed as a bug in your text (red m= arkings and such). Did you define a dup(K,V) function somewhere else?<br><b= r>=A0 Philippe<br><br>=A0<br></div></div> --0016e6d77e3c3189aa0478193fe4--
Nov 11 2009