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