Few things

bearophile bearophileHUGS at mailas.com
Fri Aug 3 00:39:41 PDT 2007


Sean Kelly>You can do this with Tango if you define a custom unit tester.<

I'll look at it.

-------------------------

Sean Kelly>What is the use for this over initializing to null?<

With that the creation of an AA becomes an expression, so you can use it inside just a line, like

return AA!(int, string);

Instead of:

string[int] aa;
return aa;

That's a silly example, but expressions are useful in other situations too.
Note that for dynamic arrays you can do that already:

return new string[];

-------------------------

Sean Kelly>It's a good idea, but I actually like the fall-through behavior. I use it regularly.<

I use it too :-)
But I think it causes bugs, now and then, and I've already seen that D cares for common bugs, for example it forbids just the ; at the end of some loops, you have to put an explicit {} that's less easy to miss.

Note (I am not suggesting this for D, I am just showing): Python cares even more to avoid common bugs, you can't even do this:
while (a = b + c) { ... }
Assignments aren't expressions, this is forbidden just to avoid the bugs caused to confusing == and =. (Pascal avoids part of those bugs because it uses := as assignment, that's more easy to distinguish from = to test for equality).

-------------------------

Sean Kelly>I'm not sure if this solves the same problem, but Tango offers a sort routine that takes a predicate.  It can be called as myArray.sort(&cmp) in most cases, making it look much like a built-in feature.<

I have seen that Tango cmp, Python too used to have cmp only as auxiliary sort argument, but in later Pythons they have introduced the key argument that's much much nicer than the cmp of Tango (but it requires more RAM).

-------------------------

Sean Kelly>All sound useful, though it may be confusing to have AA.sort behave differently than array sort.<

I agree. But they are different data structures, so maybe such "confusion" is worth it.

-------------------------

Sean Kelly>I'm not sure I understand.  Could you explain this further?<

Okay, I'll try. Go in the D docs at the "Garbage Collector" page, it says:

>Pointers in D can be broadly divided into two categories [...]
* Do not xor pointers with other values, like the xor pointer linked list trick used in C.
* Do not use the xor trick to swap two pointer values.
* Do not store pointers into non-pointer variables using casts and other tricks.
* Do not take advantage of alignment of pointers to store bit flags in the low order bits:
* Do not store into pointers values that may point into the garbage collected heap:
* Do not store magic values into pointers, other than null.
* Do not write pointer values out to disk and read them back in again.
* Do not use pointer values to compute a hash function. A copying garbage collector can arbitrarily move objects around in memory, thus invalidating the computed hash value.
* Do not depend on the ordering of pointers:
* Do not add or subtract an offset to a pointer such that the result points outside of the bounds of the garbage collected object originally allocated.
* Do not misalign pointers if those pointers may point into the gc heap, such as:
* Do not use byte-by-byte memory copies to copy pointer values.<

The list of diffences between GC pointers and "normal" (non-GC) pointers is so long and *complex*, that I belive the compiler can help the programmer to avoid all those complex pitfalls, creating two kinds (two types) of (mutually convertible with explicit casts) pointers, GC-pointers and nonGC-pointers. If you have two types the compiler can automatically enforce some (or all) those restrictions on the GC-pointers.

-------------------------

BCS>shouldn't that be on line: dmd importer.d -run
or am I misunderstanding?<

Right.

-------------------------

BCS>you should known what will be thrown and the function can do the assert, so I'd go with this<

I am not sure, but it's possible your suggestion gives errors always on the same line, so it's not much useful during debugging.

-------------------------

BCS>-run is at the end because all args after it are passed to the program, it's used a a delimiter<

I undertands now. Then it can't be changed.

-------------------------

Bruno Medeiros>Are you sure of that? It seems that at least for AA's, empty arrays are different than null arrays:<

I see, I didn't know it. I avoid this bug because to test if an AA is empty I usually use if(aa.length){}

(But I think the AA semantic you have shown needs some cleaning, othewise newbies may be bitten by it :-) ).

-------------------------

Kirk McDonald>Greetings!<

Thank you, you are quite friendly.

-------------------------

>(I rewrapped your post's linebreaks, but it seems this destroyed your code formatting. Oops.)<

I see. It doesn't matter much, others can look at my original post.

-------------------------

Kirk McDonald>I also suggest looking at DSSS:
http://www.dsource.org/projects/dsss/
The rebuild utility is part of dsss. Rebuild is very much like bud, but is more actively maintained. I also prefer its treatment of object files to bud's.<

I'll take a look at it. The only thing I don't like of "bud" is that if you use -exec it doesn't delete the executable from the disk after the running (as dmd too does if you use -run).

-------------------------

Kirk McDonald>The issue of bundling bud-like functionality into dmd has been brought up before, but I don't think Walter is all that keen on the idea.<

I don't see the advantage of having the programmer to state twice what modules to import. (But bud essentially solves the problem anyway, so it's not a big problem anymore for me).

-------------------------

Kirk McDonald>Personally, I almost always try to use selective imports in D:<
import std.stdio : writefln;<

Me too. 

-------------------------

Kirk McDonald>But maybe that's my Python background. :-)<

I too use Python a lot (You can see I have "thousands" of posts on Python newsgroups), and I use other languages as well. And I have already seen D contains tons of ideas directly copied/adapted from Python (and 95% of the times that's positive because the main quality of Python is that it is user friendly, the programmer is more important than the other things).

-------------------------

Kirk McDonald>There was a massive thread on this newsgroup just before static, selective, and renaming imports were added. These were indeed inspired by Python's import semantics, but making everything a static import by default would have broken too much code, and was not deemed worth it.<

I understand.
D 2.0+ isn't compatible with D 1.0+, so now with D2.0 it's a good time to fix all such problems (Python too is going toward the 3.0 version whose main purpose is to clean up things, breaking compatibility with older versions).

-------------------------

Kirk McDonald>(However, imports were changed from public to private by default at that time.)<

That's very important.

My general advice: copying one Python feature is often fine if you copy a certain Python feature all the way, if you stop and you copy only half of that feature than you may end in troubles :-) Regarding modules I belive D has copied only part of Python, and this causes some (little) problems.

-------------------------

Kirk McDonald>Simply assign the AA to null. That is the empty AA.<

It seems you all have missed my point here (probably for my fault), I was talking about creating (and defining) an AA, not cleaning an existing one. See my answer to Sean Kelly.

-------------------------

Kirk McDonald>If the structs have different members,<

I was mostly talking about two structs with the same member types.
But even when members aren't exactly the same, some times they can implicitely casted to the other (example: byte <==> int).

-------------------------

Kirk McDonald>Although it says there are two kinds of pointers, there is really only
one kind of pointer.<

My suggestion it to create two types, so they become really two different kinds of poiters for the compiler.

-------------------------

Kirk McDonald>I am not sure what qualifies as an illegal operation on one of these pointers that wouldn't on another. (Aside from deleting it, I suppose...)<

The D docs list all those differences (you can see a summary in my answer for Sean Kelly too).

-------------------------

Kirk McDonald>I would say a dmd, dmc, and dsss package would be great.<

Some other person can do this packaging, I think it's not necessary for Walter himself to do that. I presume he is already busy enough. With time he will learn to delegate more more work to others.

-------------------------

Kirk McDonald>It could. But Walter has said he doesn't like compiler warnings. But D is relatively easy to parse. A sufficiently advanced IDE could handle this sort of thing.<

Beside Delphi, I think C# compiler too shows such "suggestions" to the programmer, and the C# programmers I know seem rather happy to receive such things, so I belive D can have them too. They are quite handy and I don't see anything they can harm if they are well chosen and they are few.

-------------------------

Bill Baxter>Or you need to have a slick IDE that parses everything and figures out for you where various symbols are coming from.<

In real D code I always use only selective imports, and I add a comment that shows what's the usage of those imported things:

import std.string: join; // for bar() function
import std.math: abs; // for foo() function
...

In Python the
from modulename import *
(that imports all names from a module into the current namespace) is considered bad practice, and acceptable only during interactive usage from the shell (that I miss in D, but I don't think it's easy to create a *full* D interpreter) or for tiny single-usage progams.

-------------------------

Thank you for the many answers, you are quite friendly!
After the weekend I'll try to write a second post of things/suggestions (but I have already shown you most of the important ones).

Bear hugs,
bearophile



More information about the Digitalmars-d mailing list