February 26, 2007
Michiel wrote:
> Frits van Bommel wrote:
> 
>>>> But if you really want to do put such things in your code you could try
>>>> this:
>>>> struct Set(T) {
>>>>     ...
>>>>     void opApplyReverse()() {static assert(0,"don't be silly");}
>>>> }
>>>>
[snip Michiel's disbelief and my explanation]
>> Here, let me show you (some modifications made to above code)
>> <SNIP>
> 
> Interesting trick. I missed the extra (). One problem, though. If I use
> it like this:
> 
> foreach_reverse(e ; x) { }
> 
> Not specifying the element type (int). I get the "cannot infer type"
> error, instead of our custom error message. Why can't the compiler infer
> the type? Isn't it right in its face?

The code you <SNIP>ped didn't have that problem, so I presume you used the declaration Bill Baxter posted. Guess why I changed it for my example ;).
The compiler can't infer the type in Bill's code because his opApplyReverse has the wrong signature. In order to get type deduction (as well as instantiation) opApplyReverse needs to have as parameter a delegate with the correct number of (inout) arguments that returns int.
In my code I had
---
void opApplyReverse()(int delegate(inout T)) { static assert(0,"don't be silly");}
---
and it worked.
February 26, 2007
Frits van Bommel wrote:

>> Interesting trick. I missed the extra (). One problem, though. If I use
>> it like this:
>>
>> foreach_reverse(e ; x) { }
>>
>> Not specifying the element type (int). I get the "cannot infer type" error, instead of our custom error message. Why can't the compiler infer the type? Isn't it right in its face?
> 
> The code you <SNIP>ped didn't have that problem, so I presume you used
> the declaration Bill Baxter posted. Guess why I changed it for my
> example ;).
> The compiler can't infer the type in Bill's code because his
> opApplyReverse has the wrong signature. In order to get type deduction
> (as well as instantiation) opApplyReverse needs to have as parameter a
> delegate with the correct number of (inout) arguments that returns int.
> In my code I had
> ---
> void opApplyReverse()(int delegate(inout T)) { static assert(0,"don't be
> silly");}
> ---
> and it worked.

No, I used your code. I just tested again to be sure. It doesn't work. If you leave out the 'int' in the foreach_reverse statement, the silly error message doesn't get displayed.

-- 
Michiel
February 26, 2007
Michiel wrote:
> No, I used your code. I just tested again to be sure. It doesn't work.
> If you leave out the 'int' in the foreach_reverse statement, the silly
> error message doesn't get displayed.

Oh, did I put an 'int' in there?

Then I guess type inference doesn't work with template functions :(.
February 26, 2007
Stephan Diehl wrote:

> the python people have 'set' and 'frozenset' (http://docs.python.org/lib/types-set.html). The main difference between these two is basicly, that a 'set' can't be the key to a dict (and therefore not being a member of a set. To make it short: every member of a set must be immutable, or, to be more technical, must always produce the same hash value. This really makes sense, if one thinks about it a bit (and one wants to model sets in the more mathematical sense)

Yes, this does make sense. But my set implementation doesn't provide any write access to its members anyway, so you could say that everything you put into it automatically becomes 'frozen'.

Now that I think about it, I suppose it's possible to have another reference to an object that you are going to put into a set and change it through that reference. I'm not quite sure what to do with that.

How does D handle this with its associative arrays?

You know, I liked C++ better in that regard. If you do an assignment or pass something as an argument it's automatically a copy. In Java and in D you have to explicitly copy something, except if it's a base type. I don't like exceptions like that.

-- 
Michiel
February 26, 2007
Frits van Bommel wrote:

>> No, I used your code. I just tested again to be sure. It doesn't work. If you leave out the 'int' in the foreach_reverse statement, the silly error message doesn't get displayed.
> 
> Oh, did I put an 'int' in there?
> 
> Then I guess type inference doesn't work with template functions :(.

Sounds like room for improvement to me.

Not that I'm ruling out that we just don't know how to do this yet. Any clarification would be appreciated. Until then I'm sticking with my runtime error message. I agree it's a shame, because this is exactly the sort of error the compiler should catch. I would think this should be able to expand to self-written error messages.

-- 
Michiel
February 26, 2007
Michiel wrote:
> Stephan Diehl wrote:
> 
>> the python people have 'set' and 'frozenset'
>> (http://docs.python.org/lib/types-set.html). The main difference between
>> these two is basicly, that a 'set' can't be the key to a dict (and
>> therefore not being a member of a set. To make it short: every member of
>> a set must be immutable, or, to be more technical, must always produce
>> the same hash value. This really makes sense, if one thinks about it a
>> bit (and one wants to model sets in the more mathematical sense)
> 
> Yes, this does make sense. But my set implementation doesn't provide any
> write access to its members anyway, so you could say that everything you
> put into it automatically becomes 'frozen'.

Actually, the frozenset type doesn't allow things like add() and remove(). And both set and frozenset disallow changing the elements.
At least, according to the page he linked.

> Now that I think about it, I suppose it's possible to have another
> reference to an object that you are going to put into a set and change
> it through that reference. I'm not quite sure what to do with that.

You could require that any user-defined type to be put in a set has a .dup property/member function with postcondition ((orig !is dup) && (orig == dup) && (orig.opCmp(dup) == 0)), i.e. that returns a copy. And that it also doesn't store a reference to it anywhere else...
But then opApply would also need to .dup the value to ensure it wasn't modified...

This may just be more trouble than it's worth. Perhaps you should just say that things can get really screwed up if you change elements of a set...

> How does D handle this with its associative arrays?

I'm pretty sure it messes up if keys get altered while referenced by the AA, but I can't find that statement in the section of the spec dealing with AAs.
[later] Ah, here we go, from the comments page:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=12062
Walter responds: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=12085

So yeah, don't change AA keys.

> You know, I liked C++ better in that regard. If you do an assignment or
> pass something as an argument it's automatically a copy. In Java and in
> D you have to explicitly copy something, except if it's a base type. I
> don't like exceptions like that.

IIRC there have been suggestions to add .dup to base types that just returns their value, for use in generic programming (i.e. templates).
February 26, 2007
Frits van Bommel wrote:

>> Yes, this does make sense. But my set implementation doesn't provide any write access to its members anyway, so you could say that everything you put into it automatically becomes 'frozen'.
> 
> Actually, the frozenset type doesn't allow things like add() and
> remove(). And both set and frozenset disallow changing the elements.
> At least, according to the page he linked.

Yes, I meant the elements of the set ('everything you put into it').

> This may just be more trouble than it's worth. Perhaps you should just say that things can get really screwed up if you change elements of a set...

I think I will. Since that's how D handles this problem at the moment.

>> How does D handle this with its associative arrays?
> 
> <SNIPPYSNAPSNAP>
> 
> So yeah, don't change AA keys.

Hm.. This is not a good thing. I'm not saying I have the perfect solution, but this is not a good thing.

>> You know, I liked C++ better in that regard. If you do an assignment or pass something as an argument it's automatically a copy. In Java and in D you have to explicitly copy something, except if it's a base type. I don't like exceptions like that.
> 
> IIRC there have been suggestions to add .dup to base types that just returns their value, for use in generic programming (i.e. templates).

Well, that would be a start. :) But I'd still like the C++ way better. It could still have Java-style references, but the copy behavior isn't necessary.

-- 
Michiel
1 2
Next ›   Last »