Community

Bill Baxter wrote:
> Yigal Chripun wrote:
>> Leandro Lucarella wrote:
>>> Janice Caron, el 11 de mayo a las 12:53 me escribiste:
>>>> On 11/05/2008, Yigal Chripun <yigal100@gmail.com> wrote:
>>>>> also, what if a doesn't actually have a "member" member? this is
>>>>> still
>>>>> syntactically valid D code, but again I think the error would be
>>>>> reported elsewhere.
>>>> On that point, I concede. The reporting of template errors could
>>>> certainly be improved. More than once I have wanted to see the "stack
>>>> trace" of errors, working back from the innermost, to the line of code
>>>> that ultimately triggered it.
>>>>
>>>> However, that it not an argument against templates, it is an argument
>>>> for improved error reporting. And hopefully, one day we'll get that.
>>>>
>>>> This is not the first time that you've argued that some feature or
>>>> strategy is bad because today's D compiler isn't good enough, but you
>>>> need to remember that tomorrow's D compiler will be better. That's
>>>> life on the cutting edge.
>>> I think you can use Token Strings[1] in D2 to have better error
>>> reporting.
>>> It justs do lexical analisys, but it's something:
>>>
>>> sort!(q{a > b})(array);
>>>
>>> [1] http://www.digitalmars.com/d/2.0/lex.html
>>>
>> this was already debated thoroughly, But I'll state my POV again. I
>> don't like the use of strings here at all. in any form.
>> D is a strongly typed language which I like and all those string tricks
>> although cool are bad IMO.
>>
>> my issues with the use of this syntax:
>> a) what if I had a typo? what if i typed n instead of b (they are next
>> to each other on my keyboard)? your solution or any other string
>> solution cannot check this, since it is syntactically valid D code
>> inside the string.
>> b) if I want to compare q{a.member > b.member} there is no check that
>> member exists, or any other type checking. the error would occur in the
>> template code itself not in the string in both of the above examples.
>> c) what if I forgot to type the "q"?
>
> All of these things will cause compile-time errors. You are right that
> the error reported may not point to the actual mistake in a very clear
> way, but you will get a syntax error right away.
>
> The string gets turned into code via mixin(the_string) so if anything is
> not right with the code in the string, the compiler will barf. Maybe
> you were thinking it was doing some sort of parsing of the string to
> generate a comparison function for you? No. Just a raw mixin() in a
> scope in which 'a' and 'b' have been aliased to be the two elements
> being compared.
>
>> d) most IDEs mark strings with a different color or something like that
>> so I treat them automatically as data and not code. ( this is a minor
>> issue, since IDEs could be made to work differently. but, my
>> sub-conscience response to strings as "not code" is harder to fix)
>
> The q{foo} thing was taken from Perl, so any IDE that can highlight perl
> should be able to highlight this in D with some tweaks.
>
> --bb
i know it's a string mixin. my personal issue with it is indeed the
wrong errors. I also dislike perl. I like Smalltalk (and Ruby) though.
also I'd prefer an array.sort(comp); over sort!(comp)(array); but,
AGAIN, that's just MY personal preference (since I like the code blocks
of Ruby/Smalltalk).
it's simpler from the end user's POV.

On 12/05/2008, Yigal Chripun <yigal100@gmail.com> wrote:
> > The type of a is the type of the array element. This is obvious.
>
> again, obvious to you, not that dude five years from now reading your
> code. documented is not the same as compiler checked, and we both know
> that documentation could get out of sync with the code.
I'm talking about the documentation for std.algorithm.sort. What are
you talking about?
It is perfectly reasonable to expect that anyone using
std.algorithm.sort will have read the documentation on how to use it.
> also, why do I have to go and search the docs if the code is in front of me?
You don't. You learn how to use std.algorithm.sort, and then you use
it, going back to the docs only occasionally.
It's the same with anything. If I want to use a std::vector in C++,
I'd better have read up on what std::vectors are and how to use them
first.
So yes, it's obvious what the "a" and "b" mean.
> > The benefit is choice.
>
> choice of what?
Of everything. Of having it do whatever you want, whatever that is.
> You've said so yourself, both templated and
> non-templated versions of the sort-with-delegate are identical.
I have said no such thing! (And I take great offense at being misquoted)
I may have said that *one particular instantiation* of the template is
identical to the delegate version. Fair enough. But I can also make
different instantiations.
> you want those string templates (which i don't like) than fine, define
> them as templates and i won't use them. but the version with the
> delegate is needlessly a template.
There /is/ no "version with the delegate". But you can /make/ a
version with a delegate out of the template.
And those string parameters are brilliant! Today I wanted to strip out
all underscores from a string. So I sat down to write the function -
it's not really hard, after all - but then, with a flash of
inspiration, I realised the function already exists. It is:
filter!("a != '_'")(s);
That is just /so/ amazing.
> ideally (not possible in current D) both forms should have the
> same syntax, so the end user (me) doesn't need to know nor care about
> what sort of implementation was chosen.
You haven't heard of aliases or wrapper functions then?

Yigal Chripun Wrote:
> > The benefit is choice.
>
> choice of what? You've said so yourself, both templated and
> non-templated versions of the sort-with-delegate are identical.
Yigal-san this is incorrect again. I am sorry!! Did you do the disassembly I sent you? It is very simple to change to use alias (not string). You can see how sort makes direct call to the alias, not indirect! It is always good to test first and write after.
> you want those string templates (which i don't like) than fine, define
> them as templates and i won't use them. but the version with the
> delegate is needlessly a template.
>
> I guess I wouldn't object as much if D's syntax for calling templated
> code weren't different from regular functions which would bring a more
> uniform syntax (take a look at macros in Nemerle).
> Does it irritate only me? maybe I am the odd one here. I just don't want
> to care if one array function is a generic template, while another
> isn't. ideally (not possible in current D) both forms should have the
> same syntax, so the end user (me) doesn't need to know nor care about
> what sort of implementation was chosen.
There are many things you write and then write is your opinion and others can disagree. It is good when opinion is about subjective things. And opinions are equal on subjective things like the syntax you write about. But some times you write just wrong things and do not want to try and see what is true. It does not work to say it is an opinion and others can disagree. Wrong is not an opinion. Wrong and right are not equal. It is good to try find the truth, not write wrong things as opinions. If you want truth take the disassembly and see. Thank you, Dee Girl

Please read my response to Bill.
Dee Girl wrote:
> Yigal Chripun Wrote:
>
>> my issues with the use of this syntax: a) what if I had a typo?
>
> algorithm.d(2528): Error: binaryFun(ElementType1,ElementType2) is not
> an lvalue algorithm.d(2528): static assert "void*"
>
> Maybe the static assert message should be better. What if it says:
> Your comparison function is invalid?
But it doesn't. also, the file name and line number are wrong. that IS
one of my problems with this.
>
>> what if i typed n instead of b (they are next to each other on my
>> keyboard)?
>
> Same message is written.
again, The error I get points me to the wrong place with the wrong error.
>
>> your solution or any other string solution cannot check this, since
>> it is syntactically valid D code inside the string. b) if I want to
>> compare q{a.member > b.member} there is no check that member
>> exists, or any other type checking. the error would occur in the
>> template code itself not in the string in both of the above
>> examples.
>
> Same message is written again.
should I repeat the above, again?
>
>> c) what if I forgot to type the "q"?
>
> ../test.d(9): found '}' when expecting ';' following 'statement'
>
> At least now it is in your file ^_^
oh, god! finally! (that's my inner atheist talking ;) )
and yet, I still need to type that q which is meaningless to me.
>
>> d) most IDEs mark strings with a different color or something like
>> that so I treat them automatically as data and not code. ( this is
>> a minor issue, since IDEs could be made to work differently. but,
>> my sub-conscience response to strings as "not code" is harder to
>> fix)
>
> The strings are short otherwise they anyway are better as functions.
> I do not think this could be a problem.
>
>> the only benefit to this is a slight performance benefit (though a
>> good compiler could provide the same performance by inlining a
>> function call) and a slightly shorter syntax which is a personal
>> preference since you type less but IMHO it becomes less readable
>> and less obvious.
>
> I think it is very readable and obvious for reasons below.
>
>> I prefer: sort!((int a, int b) {return a.member >
>> b.member;})(array); this is more typing but provides all the checks
>> and is more readable.
>
> It is nice you can do both. You can put a string when it is small.
> You double the size of the code to write. When you have long
> comparison, you make it separate function. What I think is best of D
> when coming from other languages is that it gives so much options in
> such small core.
code is read 100 times more then it's written you need to type more
"once" but I get to read it many times.
>
>> Think of the poor guy that will need to do maintenance on your code
>> years from now. now the string is a cool quick'n'dirty solution to
>> the problem at hand but in the future that other programmer will
>> have no idea what those "a" and "b" are. especially since you
>> didn't write the types of them.
>
> Here you may be wrong two times. First I tell from experience. I
> worked internship for a biotech company in Boston. I thought it will
> be research but it was so much work! ^_^ They used Perl and I did not
> know Perl when I began. But then I learned it and it has many nice
> things. One is sort which looks like this
>
> sort { $a <=> $b } array;
>
> I remember: first time I saw sort I understood how it works. The only
> odd thing was <=> but that means -1, 0 or 1 if a is less, equal or
> greater than b. I thought Perl has the most elegant definition of
> sort but now I think D has it.
personally, I dislike Perl. You think that the above example is
elegant?! in what way does the above make it obvious that array is
sorted in ascending order?? <=> look to me as the mathematical sign for
"if and only if" (iff, i think is the short form) which doesn't mean
anything regarding sort order. in what way does it make clear that the
sort here is a function call applied to array? this is the opposite of
readable to me.
>
> Second you may be wrong because you think types help. They do not
> help in fact they may un-help. Write this
>
> long array[] = ...; sort!((int a, int b) {return a > b;})(array);
>
> Sadly D lets long -> int conversion go through. Code will compile and
> run! But it gives wrong results for big numbers.
>
So a bug in DMD makes me wrong? That's a compiler bug that needs to be
fixed. the only thing your example here shows is that DMD has bugs. on
the other hand I can give simple example where types do help:
class A { int member();}
class B { int member(); int value;}
sort!(q{a.member > b.member})(array);
if i change element type from A to B the string will compile. what if
those classes are unrelated and the member functions do completely
different things, that's just a coincidence they have the same name.
when i changed to B i wanted to sort by value instead. but i could miss
one of the calls to sort and the compiler will not yell at me with the
string solution, thus i've introduced a search-and replace bug (i didn't
replace all the instances, by mistake)
a proper function will produce an error since the type of the elements
is not the same at the elements in the array.
> For sort type deduction is best. You should write
>
> sort!((auto a, auto b) {return a > b;})(array);
>
> And that works with int, long, float, string and all types that have
> >. It is the best writing of the intent of the sort. But I do not
> know how much type inference the D compiler can do.
That's an interesting idea, I don't know how much work does it take to
implement this, but it worth discussing in a different thread. also, you
can define a templated delegate:
bool comp!(T)(T a, T b) {return a > b;}
sort!(comp)(array);
however, I'd imagine that those either need to be already provided in
the standard library,or there should be a default way for sorting:
so, for regular ascending sort:
array.sort; // no need to provide comperator.
actually, I'd want sort to have another parameter to define
ascending/descending sort (bool or enum or something like that).
the idea is making the common case the simplest so if you just need a
regular sort, just call array.sort and it'll do the right thing. you
only need to actually provide a comperator if you're not doing a regular
sort. and in that case, I'd prefer a function/delegate so the compiler
could check that my class does have the members I'm comparing and give
me the right error.
>
>> also the performance could be the same if I used a function instead
>> of a delegate allowing the compiler to inline it (hopefully).
>
> Good abstraction is the best. Performance is a good bonus ^_^
>
Agreed.
"first make sure the program is correct, then make sure it's fast"
>> since this is identical to: sort(array, (int a, int b) {return
>> a.member > b.member;}); there is no benefit in making it a
>> template, IMO.
>
> I hoped I convinced you otherwise. After all effort still no
> understanding? Templates are best. They give you static and dynamic.
> Dynamic only gives dynamic.
take a delegate, and you'll see that both solutions are identical. if
you want static, provide a function instead of a delegate. It's a
standard practice to overload functions and provide a version for both.
(or wrapping it in a new type that handles this internally).
there is a function call here in any case, template or no template. the
compiler can inline a static function call if it's suitable (short).
this is possible in both ways.
>
>> side note: using a feature of arrays in D this could be also
>> rewritten as: array.sort((int a, int b) {return a.member >
>> b.member;});
>
> Would be nice to allow array.sort!(cmp).
>
>> Again, this is only my opinion (and I do prefer higher level
>> solutions and think the compler/linker can do a better job
>> optimizing than I can). you do not have to agree with this view,
>> and there are already people that disagree.
>
> Different views of same issues is good. But I see there are some
> things about which you are simply wrong because you do not understand
> how they work. Then I waste time explaining ^_^ Thank you, Dee Girl
>
since there are language issues involved here (both of us are not native
English speakers) I'll ignore the implied insult in that you waste time
on this discussion with me (you choose to answer, you know...). I try
not to insult people, please try and do the same.
besides, had it occurred to you that maybe, you didn't understand what I
was saying, either because of my explanation which is not clear enough,
or cause you didn't understand it?
there are two things we discuss here, one of which is personal
preference regarding syntax. In what way am I wrong that I like typing
one and not the other? it's not a right vs. wrong issue but a Yigal's
preferred style vs Janice's and Dee's preferred style.
I prefer mine because I like to think it's more consistent from an
end-users point of view. even if it is indeed implemented with templates
under the hood.
with my syntax, I just use array, then a dot and than the behavior I
want to get.
i.e. -
array.sort; //same as array.sort(ASC);
array.sort(DESC);
array.sort(someStaticComperator);
array.sort(aDelegateComperator);
array.someOtherfunction(params);
//and also
List.sort;
someOtherCollection.sort;
int.sort; //compile time error, no sort method for int
etc...
I know my examples are lame (Janice is much better than me in explaining
stuff). I hope you see now, what I mean by a consistent API.
this is what I think the end user would prefer.
what is wrong with the above, in your opinion?

Simen Kjaeraas wrote:
> Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>> Now, if you casting to be able to rebind ptr, then I think you would need
>> some crazy casting like you stated.
>>
>> -Steve
>
> Actually, I had no other intent than to see if I could break the system.
> For a better (or worse, mayhaps) version: const(C*)* (or whatever, really)
> to const(invariant(C)*)*. For this, I'd prefer Janice's suggestion of
> const cast, as I understand it:
>
> const(C*)* foo;
>
> cast(const(invariant(C)*)*)foo; // error, cast can't change constancy
>
> const cast(const(invariant(C)*)*)foo; // works like a charm
>
> The const cast looks good to me, whereas what I used in the last example
> was downright ugly. Casting to a different constancy should be one cast,
> not first making it all mutable, and then put const back in there.
>
> -- Simen
if I'm not mistaken, the other example was both a cast of constancy and
of type. that needs two casts (that's one of the main principles of this
proposal). in the latest version of this proposal, the above would be:
const(C*)* foo;
cast!(const(invariant(C)*)*)foo; // works like a charm
a cast without the ! is not defined for constancy casts, so the compiler
would err and suggest using cast! instead (maybe with a message than
warn the user that this can be dangerous)

Yigal Chripun escribió:
> my issues with the use of this syntax:
> a) what if I had a typo? what if i typed n instead of b (they are next
> to each other on my keyboard)? your solution or any other string
> solution cannot check this, since it is syntactically valid D code
> inside the string.
> b) if I want to compare q{a.member > b.member} there is no check that
> member exists, or any other type checking. the error would occur in the
> template code itself not in the string in both of the above examples.
> c) what if I forgot to type the "q"?
> d) most IDEs mark strings with a different color or something like that
> so I treat them automatically as data and not code. ( this is a minor
> issue, since IDEs could be made to work differently. but, my
> sub-conscience response to strings as "not code" is harder to fix)
I mostly agree with you. The problem with defining these things is
strings is that... they are strings! They are not bind to symbols in the
language. So in that sense you can't expect any help from an IDE: no
autocompletion, no refactor, no go to definition, no nothing.
If you take a look at two top languages of the moment (C# and Java) you
can see the designers take careful steps to make the language good,
eficcient, and IDE-enabled (making an IDE for those languages is
relatively easy).
Even for extension methods C# makes a lot of restrictions: they must be
defined in a static class, and the first parameter must have a "this".
In that way, an IDE must only search in static classes, and in those,
just the methods that have a "this". In D, if there are no restrictions,
you could potentially need to make a big search in order to see where an
extension method can or cannot be proposed.

Janice Caron wrote:
> On 12/05/2008, Yigal Chripun <yigal100@gmail.com> wrote:
>> > The type of a is the type of the array element. This is obvious.
>>
>> again, obvious to you, not that dude five years from now reading your
>> code. documented is not the same as compiler checked, and we both know
>> that documentation could get out of sync with the code.
>
> I'm talking about the documentation for std.algorithm.sort. What are
> you talking about?
>
> It is perfectly reasonable to expect that anyone using
> std.algorithm.sort will have read the documentation on how to use it.
>
>
>> also, why do I have to go and search the docs if the code is in front of me?
>
> You don't. You learn how to use std.algorithm.sort, and then you use
> it, going back to the docs only occasionally.
>
> It's the same with anything. If I want to use a std::vector in C++,
> I'd better have read up on what std::vectors are and how to use them
> first.
>
> So yes, it's obvious what the "a" and "b" mean.
>
>
>
>>> The benefit is choice.
>> choice of what?
>
> Of everything. Of having it do whatever you want, whatever that is.
>
>
>> You've said so yourself, both templated and
>> non-templated versions of the sort-with-delegate are identical.
>
> I have said no such thing! (And I take great offense at being misquoted)
>
> I may have said that *one particular instantiation* of the template is
> identical to the delegate version. Fair enough. But I can also make
> different instantiations.
>
I am talking about *one particular instantiation* of the template!
>
>> you want those string templates (which i don't like) than fine, define
>> them as templates and i won't use them. but the version with the
>> delegate is needlessly a template.
>
> There /is/ no "version with the delegate". But you can /make/ a
> version with a delegate out of the template.
Again, this is exactly what I want. this should be in the standard library.
>
> And those string parameters are brilliant! Today I wanted to strip out
> all underscores from a string. So I sat down to write the function -
> it's not really hard, after all - but then, with a flash of
> inspiration, I realised the function already exists. It is:
>
> filter!("a != '_'")(s);
>
> That is just /so/ amazing.
>
for string manipulation I agree that this is useful.
>
>
>> ideally (not possible in current D) both forms should have the
>> same syntax, so the end user (me) doesn't need to know nor care about
>> what sort of implementation was chosen.
>
> You haven't heard of aliases or wrapper functions then?
I meant possible *directly* not via wrappers.
example time:
I want the following API:
(I don't care now for the internal implementation and the wrapper
functions/aliases should be provided by the standard library)
array.sort; //same as array.sort(ASC);
array.sort(DESC);
array.sort(someStaticComperator);
array.sort(aDelegateComperator);
array.someOtherfunction(params);
List.sort;
someOtherCollection.sort;
int.sort; //compile time error, no sort method for int
etc...

Ary Borenszweig wrote:
> I mostly agree with you. The problem with defining these things is
> strings is that... they are strings! They are not bind to symbols in the
> language. So in that sense you can't expect any help from an IDE: no
> autocompletion, no refactor, no go to definition, no nothing.
>
> If you take a look at two top languages of the moment (C# and Java) you
> can see the designers take careful steps to make the language good,
> eficcient, and IDE-enabled (making an IDE for those languages is
> relatively easy).
>
> Even for extension methods C# makes a lot of restrictions: they must be
> defined in a static class, and the first parameter must have a "this".
> In that way, an IDE must only search in static classes, and in those,
> just the methods that have a "this". In D, if there are no restrictions,
> you could potentially need to make a big search in order to see where an
> extension method can or cannot be proposed.
Good Points! I thought about the IDE issue, but I wasn't sure how the
IDE handles this.

Dee Girl wrote:
<snip>
maybe I still didn't explain myself properly. I've used the term
"sort-with-delegates" meaning a specific instance of sort when given a
delegate as input. I thought this was clear enough, otherwise I would
have simply said "sort".
before you start sending me assembly code, let's go over it again and
make sure we both understand each other:
you take the sort template, stick in a delegate, mix for five minutes
let is simmer for one more and viola: you got the exact same thing if
you would have written sort as a regular function which receives a
delegate parameter.
the template takes the symbol it receives (the delegate name) and
"embeds" it in the sort instance.
both ways you get:
1) a call to sort
2) a call to the delegate
the only difference is the number of parameters the sort function
receives when called.
the regular sort function can run different delegates at runtime (this
is what you call "dynamic". the template has the call to the specific
delegate embedded so for different delegates you need different sort
instances.

Yigal Chripun Wrote:
> Please read my response to Bill.
> Dee Girl wrote:
> > Yigal Chripun Wrote:
> >
> >> my issues with the use of this syntax: a) what if I had a typo?
> >
> > algorithm.d(2528): Error: binaryFun(ElementType1,ElementType2) is not
> > an lvalue algorithm.d(2528): static assert "void*"
> >
> > Maybe the static assert message should be better. What if it says:
> > Your comparison function is invalid?
>
> But it doesn't. also, the file name and line number are wrong. that IS
> one of my problems with this.
Indeed it is not nice. Like in C++. But I learned to be happy with only an error. I thought errors in C++ looked bad but when I used Haskell I think C++ errors are easy ^_^
> > It is nice you can do both. You can put a string when it is small.
> > You double the size of the code to write. When you have long
> > comparison, you make it separate function. What I think is best of D
> > when coming from other languages is that it gives so much options in
> > such small core.
>
> code is read 100 times more then it's written you need to type more
> "once" but I get to read it many times.
This argument may be not correct. It is true code is read many times but if it is long then it is hard to read not only to write. In software engineering class I learned metrics that bug rate is proportional to code size in many languages.
> >> Think of the poor guy that will need to do maintenance on your code
> >> years from now. now the string is a cool quick'n'dirty solution to
> >> the problem at hand but in the future that other programmer will
> >> have no idea what those "a" and "b" are. especially since you
> >> didn't write the types of them.
> >
> > Here you may be wrong two times. First I tell from experience. I
> > worked internship for a biotech company in Boston. I thought it will
> > be research but it was so much work! ^_^ They used Perl and I did not
> > know Perl when I began. But then I learned it and it has many nice
> > things. One is sort which looks like this
> >
> > sort { $a <=> $b } array;
> >
> > I remember: first time I saw sort I understood how it works. The only
> > odd thing was <=> but that means -1, 0 or 1 if a is less, equal or
> > greater than b. I thought Perl has the most elegant definition of
> > sort but now I think D has it.
>
> personally, I dislike Perl. You think that the above example is
> elegant?! in what way does the above make it obvious that array is
> sorted in ascending order?? <=> look to me as the mathematical sign for
> "if and only if" (iff, i think is the short form) which doesn't mean
> anything regarding sort order. in what way does it make clear that the
> sort here is a function call applied to array? this is the opposite of
> readable to me.
The point I make is that I found it easy to learn in practice. It is not a hypothesis. It is a story. Maybe if we worked together at the company we would both easily learned sort in perl.
> > Second you may be wrong because you think types help. They do not
> > help in fact they may un-help. Write this
> >
> > long array[] = ...; sort!((int a, int b) {return a > b;})(array);
> >
> > Sadly D lets long -> int conversion go through. Code will compile and
> > run! But it gives wrong results for big numbers.
> >
> So a bug in DMD makes me wrong? That's a compiler bug that needs to be
> fixed. the only thing your example here shows is that DMD has bugs. on
> the other hand I can give simple example where types do help:
> class A { int member();}
> class B { int member(); int value;}
> sort!(q{a.member > b.member})(array);
> if i change element type from A to B the string will compile. what if
> those classes are unrelated and the member functions do completely
> different things, that's just a coincidence they have the same name.
> when i changed to B i wanted to sort by value instead. but i could miss
> one of the calls to sort and the compiler will not yell at me with the
> string solution, thus i've introduced a search-and replace bug (i didn't
> replace all the instances, by mistake)
> a proper function will produce an error since the type of the elements
> is not the same at the elements in the array.
I understand what you say. Then you have option to specify type if you want. But some other times (maybe more often) you prefer generic.
> > For sort type deduction is best. You should write
> >
> > sort!((auto a, auto b) {return a > b;})(array);
> >
> > And that works with int, long, float, string and all types that have
> > >. It is the best writing of the intent of the sort. But I do not
> > know how much type inference the D compiler can do.
> That's an interesting idea, I don't know how much work does it take to
> implement this, but it worth discussing in a different thread. also, you
> can define a templated delegate:
> bool comp!(T)(T a, T b) {return a > b;}
> sort!(comp)(array);
I looked in std.functional and this is exactly how it works ^_^
> however, I'd imagine that those either need to be already provided in
> the standard library,or there should be a default way for sorting:
> so, for regular ascending sort:
> array.sort; // no need to provide comperator.
> actually, I'd want sort to have another parameter to define
> ascending/descending sort (bool or enum or something like that).
> the idea is making the common case the simplest so if you just need a
> regular sort, just call array.sort and it'll do the right thing.
But this works with std.algorithm: sort(array). If you want to say array.sort is much better I think becomes pity (pety?) meaning minor issue. But you can not say you hate one and love the other just because this detail. And I see sort was wrote so that it is generic and works with others not only arrays. STL style. Then if another container appears then std.sort works with it. But if sort is forced to work only for arrays then it need many implementations (example for deque). If that works we can say std.sort is objectivally superior.
> you
> only need to actually provide a comperator if you're not doing a regular
> sort. and in that case, I'd prefer a function/delegate so the compiler
> could check that my class does have the members I'm comparing and give
> me the right error.
You can use mysort. std.sort is good because it lets you do so. If you only give me mysort then it does not let others do the static way.
> >> also the performance could be the same if I used a function instead
> >> of a delegate allowing the compiler to inline it (hopefully).
> >
> > Good abstraction is the best. Performance is a good bonus ^_^
> >
>
> Agreed.
> "first make sure the program is correct, then make sure it's fast"
>
> >> since this is identical to: sort(array, (int a, int b) {return
> >> a.member > b.member;}); there is no benefit in making it a
> >> template, IMO.
> >
> > I hoped I convinced you otherwise. After all effort still no
> > understanding? Templates are best. They give you static and dynamic.
> > Dynamic only gives dynamic.
>
> take a delegate, and you'll see that both solutions are identical. if
> you want static, provide a function instead of a delegate. It's a
> standard practice to overload functions and provide a version for both.
> (or wrapping it in a new type that handles this internally).
> there is a function call here in any case, template or no template. the
> compiler can inline a static function call if it's suitable (short).
> this is possible in both ways.
I do not understand. Can you please write a bit of code that would be better than std.sort?
> >> side note: using a feature of arrays in D this could be also
> >> rewritten as: array.sort((int a, int b) {return a.member >
> >> b.member;});
> >
> > Would be nice to allow array.sort!(cmp).
> >
> >> Again, this is only my opinion (and I do prefer higher level
> >> solutions and think the compler/linker can do a better job
> >> optimizing than I can). you do not have to agree with this view,
> >> and there are already people that disagree.
> >
> > Different views of same issues is good. But I see there are some
> > things about which you are simply wrong because you do not understand
> > how they work. Then I waste time explaining ^_^ Thank you, Dee Girl
> >
> since there are language issues involved here (both of us are not native
> English speakers) I'll ignore the implied insult in that you waste time
> on this discussion with me (you choose to answer, you know...). I try
> not to insult people, please try and do the same.
I am so sorry!! I used a wrong word. It was meant as spending time on explaining instead of working on my project. Sorry!
> besides, had it occurred to you that maybe, you didn't understand what I
> was saying, either because of my explanation which is not clear enough,
> or cause you didn't understand it?
It is always possible. Preferences are always not to contradict about so I never contradict about them. But some times I see a sentence or two that I think is wrong. Then I try to explain how it can be corrected. I do not know if the thinking is wrong, but if the sentence is wrong then it can be corrected.
> there are two things we discuss here, one of which is personal
> preference regarding syntax. In what way am I wrong that I like typing
> one and not the other? it's not a right vs. wrong issue but a Yigal's
> preferred style vs Janice's and Dee's preferred style.
Yes. I never wanted to say your preference is wrong. Please forgive me if I did. In things of preference maybe we agree on this. If there is serious advantage to a library then we can agree that we can accept both array.sort or sort(array).
> I prefer mine because I like to think it's more consistent from an
> end-users point of view. even if it is indeed implemented with templates
> under the hood.
> with my syntax, I just use array, then a dot and than the behavior I
> want to get.
> i.e. -
> array.sort; //same as array.sort(ASC);
Here I may prefer array.sort("a < b") instead of array.sort(ASC). Maybe I think ASC means ASCII. But if I see the comparison it is clear instantly. But it is just preference.
> array.sort(DESC);
Is DESC a shortcut for DESCRIPTION? ^_-
> array.sort(someStaticComperator);
> array.sort(aDelegateComperator);
> array.someOtherfunction(params);
> //and also
> List.sort;
> someOtherCollection.sort;
> int.sort; //compile time error, no sort method for int
> etc...
But now again we seem out of preference domain. Maybe I misunderstand but each collection implements its own sort? Then this solution is objectivally inferior because deque.sort and array.sort are duplicated. I think STL style is superior. It implements sort for anything that has iterator and swap.
> I know my examples are lame (Janice is much better than me in explaining
> stuff). I hope you see now, what I mean by a consistent API.
> this is what I think the end user would prefer.
> what is wrong with the above, in your opinion?
Subjective preferences are always good. May be not if they lead to bad design. Then if you only have a syntax preference as argument then it is too little power. If you write a design that is better than std.sort then it is perfect. I am very curious.
About examples. My adviser (software engineering) tells me: if you can not show good examples for your idea then your idea has a problem. Good ideas have good examples. Thank you, Dee Girl