Safer casts

Dee Girl deegirl at noreply.com
Mon May 12 17:24:12 PDT 2008


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



More information about the Digitalmars-d mailing list