Clay language

Stanislav Blinov stanislav.blinov at gmail.com
Tue Dec 28 03:38:56 PST 2010


On 12/28/2010 11:19 AM, bearophile wrote:
> Adam D. Ruppe:
>
>> That's the ideal situation. Writing out qualified paths by default
>> is just awful, and I can't understand why you keep asking for it.
>
> Importing all names from a module on default is against modularity. While you read a module code you don't know where the imported names it uses come from. Take also a look at how Ada specifies interfaces across modules. A language needs to be designed with a balance between low verbosity and safety, here in my opinion D has chosen too much for the low verbosity (as Walter reminds D's anti-hijacking support in imports is a nice idea, but I think it's not enough).
>
> (Reading about safer language subsets like SPARK and MISRA I have learnt that having a language safe on default is better (because this safety spreads in the whole ecosystem of the language users, and not just in a small subset of it), but where that's not possible, then sometimes an acceptable replacement is to have a language design that allows an external tool to statically disallow an unsafe coding style or feature (in many cases this is not possible for C, or it's possible but leads to a very limited language). In this case for an external tool it's easy to statically disallow not-static D imports.)
>
> Bye,
> bearophile

Taking an example from std.algorithm documentation:

1)
int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
auto squares = map!("a * a")(chain(arr1, arr2));
assert(equal(squares, [ 1, 4, 9, 16, 25, 36 ]));
// 146 characters

2)
int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
auto squares = std.algorithm.map!("a * a")(std.range.chain(arr1, arr2));
assert(std.algorithm.equal(squares, [ 1, 4, 9, 16, 25, 36 ]));
// 184 characters

How is 2) is better/safer than 1)? I took a pretty short example, but I 
easily imagine as real code would blow up to 25-40% more characters just 
for the sake of explicit qualification, especially when using 
third-party (or own) libraries with nested structure (like, e.g., in 
Tango). And nothing is actually gained with this, except that it is 
"clear" from what modules those names come. In C++, you sometimes have 
to fully qualify names "just in case" to prevent hijacking. But D is 
hijacking-proof at compile time, so there is no need in those "just in 
case" qualifiers, the compiler will tell you when the "case" is here.

And what would you propose to do with uniform function call syntax if 
"import all" is not the default? Even considering that currently it 
works only for arrays, would you replace every use arr.front, arr.back, 
arr.empty with std.array.front(arr), std.array.back(arr) and 
std.array.empty(arr) in favor of "import safety"? Or would you instead 
put a long "disqualifying" import line at the top of every module that 
uses std.array?

My resume:

 > Importing all names from a module on default is against modularity.

It is not. It does not break modularity, it simplifies module 
interfacing, it reduces amount of code (and is therefore DRY-friendly).

 > If in your module you don't want to use qualified paths you use:
import foo: bar, spam;

...which quickly expands to a lot of *long* import lines, with "don't 
forget to add another" constantly pushing the door-bell.


More information about the Digitalmars-d mailing list