ch-ch-changes

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Jan 28 06:01:29 PST 2009


grauzone wrote:
> One thing about std.algorithm: you really seem to like using 
> compile-time strings as literals. However, this makes the use of 
> delegates harder. For example, to use a delegate, you need to do this 
> (quoted from your docs):
> 
>  > int[] a = ...;
>  > static bool greater(int a, int b)
>  > {
>  >     return a > b;
>  > }
>  > sort!(greater)(a);  // predicate as alias
> 
> In my opinion, doing something like
> 
>  > sort(a, (int a, int b) { return a > b; });
> 
> would be simpler and more intuitive than passing a delegate name as 
> template parameter. (The delegate literal syntax still could be 
> improved, though.)

Don and Max addressed many of these points, so allow me just to add a 
couple of comments.

The use above is valid but at the time I first implemented std.algorithm 
and wrote the documentation, bugs in the compiler prevented your syntax 
from happening. Certain bugs still disallow your syntax for certain 
cases; I submitted those bugs as well.

> Does std.algorithm work with closures at all? I see that the greater() 
> function in your example is marked as static. (Sorry, I didn't test it 
> myself.)

Yes, it does.

> Using string mixins messes up syntax highlighting and the code is more 
> obfuscated. If you make an error in your predicate, random funny things 
> internal to the library implementation could happen, and the compiler 
> will spurt out indecipherable error messages for random modules (I guess 
> in this case, std.algorithm or std.functional). How will runtime 
> debugging work? Will the debugger be smart enough to point me to the 
> correct source code location, if there happens a segfault in my 
> predicate? I'm sure it could, if you used delegates instead.

String mixins are meant to be used for short functions, which at least 
in my code there are plenty of. You can e.g. sort by a field by writing 
sort!("a.name < b.name")(vec) without so much as thinking about it. If 
you want syntax highlighting, sort!(q{a.name < b.name})(vec) may do (it 
does in my editor). But then again: almost by definition, if you feel 
like needing syntax highlighting in a string mixin, that string has 
outgrown its charter. Use a delegate.

> Why did you make this so complex? What's your position on this? Do you 
> agree that there are problems, or are you happy with how it is?
 >
> Why did you choose to do it like this? Because it is shorter, or for 
> performance (avoid delegate call)? Does it enable some weird use cases, 
> which wouldn't be possible when using delegates?

(If "this" is std.algorithm, I have no idea how to make it simpler.) The 
thing is, passing by alias allows you a host of options:

* string for short functions
* function name
* delegate literal
* delegate object (there's a bug in the compiler related to that, that 
Walter knows how to fix)
* some struct object that implements opCall()

Really, you have *all* options and *no* disadvantage. It would have been 
silly to not put that straight in the standard library. I've looked at 
the way other languages do higher-order functions and inevitably they 
leave something on the table. Either you don't have enough flexibility, 
or the speed kills you, or the syntax kills you. Solutions that are 
genuinely superior are few and far apart. Going with aliases really puts 
D ahead of all other languages.

The way D instantiates templates locally is a killer and a funny tidbit 
of information is that Walter put that great idea in almost by mistake, 
not really knowing what the consequences might be. At some point I 
figured how awesome that is and really pushed it through. I recall there 
was a discussion here - Dee Girl figured that out, too, there was a long 
thread about it. (Where's Dee? Where's Janice? We seem to treat our 
women badly.)

> Regarding performance: I don't think performance justifies all these 
> problems. Standard library functions should be as fast as possible, but 
> this goal should come second after robustness and simplicity.

I hope I can change your mind that the problem does not exist.

> Another problem is, that using string mixins seems to be quite 
> problematic, because they are mixed in in a different scope. If I'm not 
> mistaken, you can't do this:
> 
>  > int foo(...) {...}
>  > sort!("foo(a, b);");
> 
> You might think that "sort!("a>b", a);" is elegant and short, but this 
> probably only works out in toy-examples.

You can call sort!(foo)(...). I completely disagree about the toy 
examples assessment. In my daily work I use probably 70-80% of 
std.algorithm. A large percentage of time I use string mixins no problem 
to solve rather real problems.

> And macros, which are supposed to magically cure all those problems, 
> were postponed to D3.0.
> 
> I'm also worried about compile times. You use nested templates with 
> string mixins, which only can be slower to compile than using e.g. the 
> builtin .sort. I don't know if this a problem, but in my opinion, 
> compile times are already high enough. Times will add up!
> 
> For one, I'm sure that this will generate an additional gazillion of 
> nearly useless linker symbols with very long names.

I haven't perceived that as a problem yet, but indeed it's a good thing 
to keep one's eye on. Probably the solution I'd suggest would be 
improved compiler technology (a trend that Walter has relentlessly 
demonstrated for a good while now).


Andrei



More information about the Digitalmars-d mailing list