digitalmars.D.learn - Lazy range of hashes?
- Andrej Mitrovic (12/12) Aug 25 2012 I could use something like this:
- bearophile (13/22) Aug 25 2012 This seems to work:
- Andrej Mitrovic (27/28) Aug 25 2012 It seems it's as simple as defining a struct:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (20/48) Aug 26 2012 Cool! :) If the operator returns the pointer to the element, then the
- Era Scarecrow (23/25) Aug 26 2012 Reminds me, although not for you Ali, but as a pointer return a
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (54/78) Aug 26 2012 It has been argued that the -> operator has not been needed for C anyway...
- Artur Skawina (14/54) Aug 26 2012 opDispatch lets you write the equivalent in D [1]. The 'local' member al...
- Era Scarecrow (17/61) Aug 26 2012 Since D wouldn't ever have a need to emulate pointers (like
I could use something like this: void main() { int[string] x = ["foo":1]; int[string] y = ["bar":1]; assert("bar" in lazyHash(x, y)); } Essentially it would turn into lazy 'in' checks, meaning first opIn_r would be called for 'x', and then for 'y'. Otherwise it might be expensive to have to create a new hash that has all the keys and values of other hashes. Has anyone ever implemented this?
Aug 25 2012
Andrej Mitrovic:void main() { int[string] x = ["foo":1]; int[string] y = ["bar":1]; assert("bar" in lazyHash(x, y)); } Essentially it would turn into lazy 'in' checks, meaning first opIn_r would be called for 'x', and then for 'y'.This seems to work: import std.algorithm; void main() { auto x = ["foo": 1]; auto y = ["bar": 2]; //assert("bar" in lazyHash(x, y)); assert(any!(h => "bar" in h)([x, y])); } Recently I have seen a lazy range struct able to replace that [x,y]. I don't know if it's in Phobos already. Bye, bearophile
Aug 25 2012
On 8/26/12, bearophile <bearophileHUGS lycos.com> wrote:This seems to work:It seems it's as simple as defining a struct: struct LazyHash(T...) { T hashes; bool opIn_r(X)(X x) { foreach (hash; hashes) { if (x in hash) return true; } return false; } } auto lazyHash(T...)(T t) { return LazyHash!T(t); } void main() { auto x = ["foo" : 1]; auto y = ["bar" : 2]; assert("bar" in lazyHash(x, y)); assert("barx" !in lazyHash(x, y)); } I didn't even have to define a ctor since field assignment works.
Aug 25 2012
On 08/25/2012 05:30 PM, Andrej Mitrovic wrote:On 8/26/12, bearophile<bearophileHUGS lycos.com> wrote:Cool! :) If the operator returns the pointer to the element, then the callers can access its value as well: auto opIn_r(X)(X x) { foreach (hash; hashes) { auto p = x in hash; if (p) return p; // <-- return the pointer } return null; } // ... import std.stdio; auto p = "foo" in lazyHash(x, y); if (p) { writeln(*p); // <-- the user can access the value } AliThis seems to work:It seems it's as simple as defining a struct: struct LazyHash(T...) { T hashes; bool opIn_r(X)(X x) { foreach (hash; hashes) { if (x in hash) return true; } return false; } } auto lazyHash(T...)(T t) { return LazyHash!T(t); } void main() { auto x = ["foo" : 1]; auto y = ["bar" : 2]; assert("bar" in lazyHash(x, y)); assert("barx" !in lazyHash(x, y)); } I didn't even have to define a ctor since field assignment works.
Aug 26 2012
On Sunday, 26 August 2012 at 07:29:13 UTC, Ali Çehreli wrote:Cool! :) If the operator returns the pointer to the element, then the callers can access its value as wellReminds me, although not for you Ali, but as a pointer return a question came up. I've wondered and haven't tested this but hypothetically: Due to that you can call structures and class members even from a pointer (transparently compared to C/C++), does it automatically convert from a pointer to a non-pointer type if the return calls for it? In a class that's irrelevant (it's already a reference type and should auto-fix itself); But a struct or non-class? //just to get the idea //potentially ref int, rather than int* as well int getSomeValue(int[string] x, string someValue) { auto sv = someValue in x; return x ? x : 0; //auto convert? Or error? If not, why? } Rather than auto could ref work? Or if it's a exact valueType (with postblitz) or (known to be relocatable) would it make a new copy? I can see the importance of both, but depending on the return type in cases, having it throw an error seems like the best policy if it's a non-built in, since it's trivial changing return x, with return *x; Also as a built in type it could automatically do the copy/conversion for you.
Aug 26 2012
On 08/26/2012 12:55 AM, Era Scarecrow wrote:On Sunday, 26 August 2012 at 07:29:13 UTC, Ali Çehreli wrote:It has been argued that the -> operator has not been needed for C anyway. Interestingly, it has some value in C++ because if a type has defined operator->() (rather, for this discussion, operator.(), which does not exist in C++ today), then the following would cause confusion for types that worked like smart pointers: class P { /* hypothetical operator */ T * operator.(); void foo(); }; P p = bar(); p.foo(); // foo() of the pointer type or the 'pointed to type'? D does not have that question because the dot operator may not be overloaded. (opDot() has been (will be?) deprecated.)Cool! :) If the operator returns the pointer to the element, then the callers can access its value as wellReminds me, although not for you Ali, but as a pointer return a question came up. I've wondered and haven't tested this but hypothetically: Due to that you can call structures and class members even from a pointer (transparently compared to C/C++),does it automatically convert from a pointer to a non-pointer type if the return calls for it?No: The dot does not convert the type. The dot has different meanings on structs vs. classes. With structs, it always operates on the struct object: o.sizeof // The size of the struct object o.foo() // The member of the struct object With classes, it operates sometimes on the reference and sometimes on the referenced object: o.sizeof // The size of the class reference o.foo() // The member of the class object That's D's way of confusing on this topic.In a class that's irrelevant (it's already a reference type and should auto-fix itself); But a struct or non-class? //just to get the idea //potentially ref int, rather than int* as well int getSomeValue(int[string] x, string someValue) { auto sv = someValue in x; return x ? x : 0; //auto convert? Or error? If not, why?You meant sv: return sv ? sv : 0; That is still a compilation error for a statically-typed language like D. The types of sv and 0 don't match. But the line should always be like this anyway: return sv ? *sv : 0; Because sv is always a pointer: // For a struct pointer: *sv // a reference to the struct object // For a class reference: *sv is another reference to the actual class objectRather than auto could ref work?You mean, 'ref' on the return type, right? For opIn_r, it better not be 'ref', because then it would be returning a reference to a local pointer: // Note ref return. I think this is a bug. ref opIn_r(X)(X x) { foreach (hash; hashes) { auto p = x in hash; if (p) return p; // <-- return a reference to the local pointer } return null; } I think that is a bug but the compiler does not give a warning about returning a reference to the local pointer.Or if it's a exact valueType (with postblitz) or (known to be relocatable) would it make a new copy? I can see the importance of both, but depending on the return type in cases, having it throw an error seems like the best policy if it's a non-built in, since it's trivial changing return x, with return *x; Also as a built in type it could automatically do the copy/conversion for you.As you said, returning *x would return a copy of the value if it were a struct. Ali
Aug 26 2012
On 08/26/12 17:28, Ali Çehreli wrote:On 08/26/2012 12:55 AM, Era Scarecrow wrote:opDispatch lets you write the equivalent in D [1]. The 'local' member always has to take precedence over any 'remote' ones (you can hide (rename/wrap etc) the local one if you want, doing it the other way wont work).On Sunday, 26 August 2012 at 07:29:13 UTC, Ali Çehreli wrote:It has been argued that the -> operator has not been needed for C anyway. Interestingly, it has some value in C++ because if a type has defined operator->() (rather, for this discussion, operator.(), which does not exist in C++ today), then the following would cause confusion for types that worked like smart pointers: class P { /* hypothetical operator */ T * operator.(); void foo(); }; P p = bar(); p.foo(); // foo() of the pointer type or the 'pointed to type'? D does not have that question because the dot operator may not be overloaded. (opDot() has been (will be?) deprecated.)Cool! :) If the operator returns the pointer to the element, then the callers can access its value as wellReminds me, although not for you Ali, but as a pointer return a question came up. I've wondered and haven't tested this but hypothetically: Due to that you can call structures and class members even from a pointer (transparently compared to C/C++),The dot means the same thing, you just have to remember that a class reference is actually a pointer to the class instance. IOW 'o.whatever' for classes works just like 'p.whatever' does for structs. What is confusing is the wrong reference_type-to-pointer model, but fixing it up right now is too late. Or maybe not, given the tiny amount of D code out there and the fact that only code dealing with pointers-to-classes would be affected. Such code is probably so rare that the cost could still be acceptable. artur [1] Well, almost - there are things like dealing with ' property' which need improvements. And of course 'alias this' can be used, sometimes.does it automatically convert from a pointer to a non-pointer type if the return calls for it?No: The dot does not convert the type. The dot has different meanings on structs vs. classes. With structs, it always operates on the struct object: o.sizeof // The size of the struct object o.foo() // The member of the struct object With classes, it operates sometimes on the reference and sometimes on the referenced object: o.sizeof // The size of the class reference o.foo() // The member of the class object That's D's way of confusing on this topic.
Aug 26 2012
On Sunday, 26 August 2012 at 15:28:17 UTC, Ali Çehreli wrote:On 08/26/2012 12:55 AM, Era Scarecrow wrote:Interestingly, it has some value in C++ because if a type has defined operator->() (rather, for this discussion, operator.(), which does not exist in C++ today), then the following would cause confusion for types that worked like smart pointers:D does not have that question because the dot operator may not be overloaded. (opDot() has been (will be?) deprecated.)Since D wouldn't ever have a need to emulate pointers (like Iterators for C++) the -> and . overloading seem moot. Some features are best not to be implemented as they would give more trouble than they're worth.No: The dot does not convert the type. The dot has different meanings on structs vs. classes. With structs, it always operates on the struct object: o.sizeof // The size of the struct object o.foo() // The member of the struct object With classes, it operates sometimes on the reference and sometimes on the referenced object: o.sizeof // The size of the class reference o.foo() // The member of the class object That's D's way of confusing on this topic.Only if o.sizeof may refer to the pointer size and not the class object.You meant sv: return sv ? sv : 0;Ack! bad typo! Bad bad typo!That is still a compilation error for a statically-typed language like D. The types of sv and 0 don't match. But the line should always be like this anyway: return sv ? *sv : 0; Because sv is always a pointer:Gotcha.And here i thought it would refer the reference (from in's case) to the original object. Mmmm.Rather than auto could ref work?You mean, 'ref' on the return type, right? For opIn_r, it better not be 'ref', because then it would be returning a reference to a local pointer:// Note ref return. I think this is a bug. ref opIn_r(X)(X x) { foreach (hash; hashes) { auto p = x in hash; if (p) return p; // <-- return a reference to the local pointer } return null; } I think that is a bug but the compiler does not give a warning about returning a reference to the local pointer.I've actually had this problem before. Ended up having to use ref on the input and then force a pointer to get my code elsewhere to work (without copying). But that's kinda unimportant; If the compiler issues a warning than all the better now :)As you said, returning *x would return a copy of the value if it were a struct.K. Glad to get that out of the way.
Aug 26 2012