Few things

Kirk McDonald kirklin.mcdonald at gmail.com
Wed Aug 1 12:38:24 PDT 2007


bearophile wrote:
> Hello, this is my second post on digitalmars newsgroups (the first
> one is on digitalmars.D.learn). Here are some ideas, suggestions (and
> some problems too) I have found. I am currently using dmd 1.020 on
> Windows. Probably some of them are useless (maybe because already
> present, in the same or different form), or already
> discussed/refused, or even plain stupid, but you may find something
> interesting too among them.
> 

Greetings!

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

> 
> 1) This is quite important for me: dmd may look for the needed
> modules by itself, starting from the current directory and package
> directories (the -I parameter is useful still for more complex
> situations), and the exploring the directories in the "path"
> variable. So instead of:
> 
> dmd importer.d amodule1.d amodule2.d ...
> 
> To compile/run you just need:
> 
> dmd importer.d dmd -run importer.d
> 
> So the programmer can avoid giving the module names two times, once
> inside the code and once again to the compiler. Later I have found
> that the good "bud" utility does that and quite more, but I belive
> the compiler can have that basic capability of looking for modules by
> itself.
> 

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.

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.

> -------------------------
> 
> 3) I think it may be better to import "statically" by default (as in
> python, in that language people suggest to avoid the "from amodule
> import *" that means import all names from amodule).
> 

Personally, I almost always try to use selective imports in D:

import std.stdio : writefln;

But maybe that's my Python background. :-)

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. 
(However, imports were changed from public to private by default at that 
time.)

A curious feature of D's imports is that with a regular "import foo;" 
you can still access the contents of foo by their fully-qualified name. 
This differs from Python's "from foo import *" in that, though all these 
imported names have been introduced into the namespace, you can still 
get at them if they have been shadowed by another name. Combined with 
the fact that someone importing your module will not get those imported 
names (since imports are private), the situation is just fine.

> -------------------------
> 
> 6) It can be useful a way to create an empty associative array with
> something like: new int[char[]]();
> 
> I have succed creating something similar, but I think a standard
> built-in way is better:
> 
> template AA(KeyType, ValueType) { const ValueType[KeyType] AA =
> AA_impl!(KeyType, ValueType).res; } template AA_impl(KeyType,
> ValueType) { ValueType[KeyType] result; const ValueType[KeyType] res
> = result; }
> 
> Usage: AA!(char[], int)
> 

Simply assign the AA to null. That is the empty AA.

> -------------------------
> 
> 8) From the docs: >If the KeyType is a struct type, a default
> mechanism is used to compute the hash and comparisons of it based on
> the binary data within the struct value. A custom mechanism can be
> used by providing the following functions as struct members:< I think
> structs can have a default way to sort them too, lexicographically,
> that can be replaced by a custom mechanism when needed. How I have
> implemented it:
> 
> int scmp(TyStruct1, TyStruct2)(TyStruct1 s1, TyStruct2 s2) { static
> if (s1.tupleof.length < s2.tupleof.length) { foreach(i, field;
> s1.tupleof) { if (field < s2.tupleof[i]) return -1; else if (field >
> s2.tupleof[i]) return 1; } return -1; } else { foreach(i, field;
> s2.tupleof) { if (field < s1.tupleof[i]) return 1; else if (field >
> s1.tupleof[i]) return -1; } static if (s1.tupleof.length ==
> s2.tupleof.length) return 0; else return 1; } }
> 
> How I use it, to shorten the code I use to sort structs: struct P1 { 
> char[] k; int v; int opCmp(P1 other) { return scmp(this, other); } }
> 
> I think dmd can do something like that by default.
> 

Alternately, it could simply do a flat comparison of the bits behind the 
struct. If the structs have different members, I'm not sure how much 
sense it makes to do a lexicographical comparison of their members like 
that.

> -------------------------
> 
> 10) I think few useful properties/methods can be added to the
> built-in AAs: - aa.clear() to remove all key/val from the AA. -
> aa.dup, to create a copy of the AA. - aa.sort, that compulsively
> takes a 'key' function (that takes two arguments, key and value) and
> returns the sorted array of the keys. Here is a simple example of
> such sorting:
> 
> TyKey[] sortedAA(TyKey, TyVal, TyFun)(TyVal[TyKey] aa, TyFun key) { 
> struct Pair { TyKey k; ReturnType!(TyFun) key_kv;
> 
> int opCmp(Pair otherPair) { if (key_kv == otherPair.key_kv) return 0;
>  return (key_kv < otherPair.key_kv) ? -1 : 1; } }
> 
> Pair[] pairs; pairs.length = aa.length; uint i = 0; foreach(k, v; aa)
> { pairs[i] = Pair(k, key(k, v)); i++; }
> 
> TyKey[] result; result.length = aa.length; foreach(ii, p; pairs.sort)
>  result[ii] = p.k;
> 
> return result; }
> 
> You can use it with any key, like: TyV Vgetter(TyK, TyV)(TyK k, TyV
> v) { return v; } For the 10% of the lines of the program that need
> max speed or low memory usage, you can write sorting code the usual
> lower-level way.
> 

An aa.dup would be nice. An a.clear() isn't necessarily needed; you can 
simply assign the AA reference to null, though of course this doesn't 
mutate the old AA.

> -------------------------
> 
> 12) From the docs:>Pointers in D can be broadly divided into two
> categories: those that point to garbage collected memory, and those
> that do not.< GC pointers don't support some operations, so why not
> define two kinds of pointers (gcpointer?), so the compiler can raise
> an error when the code tries to do one of the many illegal operations
> (= that produces undefined behavior) on GC pointers? (If it's needed
> a cast() may be used to convert a GC pointer to a normal pointer and
> vice versa).
> 

Although it says there are two kinds of pointers, there is really only 
one kind of pointer. The only difference between these two kinds of 
pointers is the value: Some point to memory addresses in the range 
controlled by the GC, and some do not.

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

> -------------------------
> 
> 15) On windows, expecially for newbies I think it can be positive to
> have a single zip with all necessary to use D (with dmd, dmc, bud and
> maybe dfl too).
> 

I would say a dmd, dmc, and dsss package would be great.

> -------------------------
> 
> 17) It may be good if in dmd the -run parameter can be positioned
> anywhere in the command line.
> 

As was mentioned in another branch of the thread, anything after the 
-run is considered as command-line arguments to the compiled program. 
-run terminates the option list to dmd.

> -------------------------
> 
> 18) In Python I find rather useful the built-in ** infix operator (it
> works among integers or floating point numbers):
> 
> 
>>>> 2 ** 3
> 
> 8
> 
>>>> 2 ** 0.5
> 
> 1.4142135623730951
> 
>>>> -2 ** -2.5
> 
> -0.17677669529663689
> 
> std.math.pow is less useful when both arguments are integral.
> 

I'd like to see this, too.

> -------------------------
> 
> 19) The dmd compiler can tell what variables aren't used (Delphi
> Pascal does this) or the ones that aren't modified after the
> initialization... (that is that are essentially unused).
> 

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.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org



More information about the Digitalmars-d mailing list