Re: Legal operator overloading
On Monday, 30 May 2016 at 05:54:42 UTC, Nicholas Wilson wrote: Is it legal/possible to overload the unary * operator? Also is it legal/possible to individually overload the comparison operators and not return a bool? Yes to unary * (see [1]). No to the rest. Comparisons are always lowered to opEquals or opCmp by the compiler as per [2]. [1] https://dlang.org/spec/operatoroverloading.html#unary [2] https://dlang.org/spec/operatoroverloading.html#eqcmp
Legal operator overloading
Is it legal/possible to overload the unary * operator? Also is it legal/possible to individually overload the comparison operators and not return a bool? (Before you ask no I'm not crazy, I am trying to make a library solution to multiple address spaces for supporting OpenCL/CUDA in D, and vector comparisons.)
Re: String compare in words?
On average there would be less than 4 bytes remaining to compare. So a simple straightforward byte comparison should do the job efficiently.
Re: String compare in words?
On Sunday, 29 May 2016 at 20:40:52 UTC, qznc wrote: On Sunday, 29 May 2016 at 18:15:16 UTC, qznc wrote: On Sunday, 29 May 2016 at 17:38:17 UTC, Jonathan M Davis wrote: And if you're not simply comparing for equality, what are you looking to figure out? Without more information about what you're trying to do, it's kind of hard to help you. If I write the comparison naively, the assembly clearly shows a "movzbl" [0]. It loads a single byte! The other single byte load is encoded in the address mode of "cmp". Implementation: bool stringcmp(string x, string y) { foreach(i; 0..x.length) { if (x[i] != y[i]) // byte compare return false; } return true; } It makes no sense to load single bytes here. Since we only want to check for equality, we could load two full words and compare four or eight bytes in one go. Ok, to answer my own question, this looks good: bool string_cmp_opt(immutable(ubyte)[] x, immutable(ubyte)[] y) { pragma(inline, false); if (x.length != y.length) return false; int i=0; // word-wise compare is faster than byte-wise if (x.length > size_t.sizeof) for (; i < x.length - size_t.sizeof; i+=size_t.sizeof) { size_t* xw = cast(size_t*) &x[i]; size_t* yw = cast(size_t*) &x[i]; if (*xw != *yw) return false; } // last sub-word part for (; i < x.length; i+=1) { if (x[i] != y[i]) // byte compare return false; } return true; } Any comments or recommendations? I don't know if this would be faster, but here is my attempt. It assumes the arrays start at an address multiple of 8. if (x is y) return true; if (x.length != y.length) return false; size_t l = x.length; ubyte* a = x.ptr, b = y.ptr; for (size_t n = l>>3; n != 0; --n, a+=8, b+=8) if (*cast(long*)a ^ *cast(long*)b) return false; if (l & 4) { if (*cast(int*)a ^ *cast(int*)b) return false; a+= 4; b+= 4; } if (l & 2) { if (*cast(short*)a ^ *cast(short*)b) return false; a+=2; b+=2; } return (l & 1) && (*a ^ *b) ? false : true; If the pointers are not on an address multiple of 8, one has to inverse the trailing tests to consume the bytes in front of the array until the address becomes a multiple of 8. The trailing tests could eventually be replaced by a simple sequential byte compare. I don't know which is faster.
Re: Read registry keys recursively
On Sunday, 29 May 2016 at 16:46:34 UTC, Era Scarecrow wrote: you should see the problem. Here's the correct line! writeRegistryKeys(k.getKey(key.name())); this just occurred to me i tried to keep to the example but i shouldn't have. Since you already have the inner key, just pass that and it works. Far more obvious what's going on now. writeRegistryKeys(key);
Re: String compare in words?
On Sunday, 29 May 2016 at 20:51:19 UTC, Seb wrote: On Sunday, 29 May 2016 at 20:40:52 UTC, qznc wrote: [...] Isn't that something that the compiler should optimize for you when you do an equality comparison? Is it really faster than ldc (with all optimzations turned on)? It can be faster because of inlining. memcmp is a runtime call.
Re: full copies on assignment
On Friday, 27 May 2016 at 08:59:43 UTC, Marc Schütz wrote: Yes indeed it does. Thanks. Something in my version must have been different.
Re: String compare in words?
On Sunday, 29 May 2016 at 20:40:52 UTC, qznc wrote: On Sunday, 29 May 2016 at 18:15:16 UTC, qznc wrote: [...] Ok, to answer my own question, this looks good: bool string_cmp_opt(immutable(ubyte)[] x, immutable(ubyte)[] y) { pragma(inline, false); if (x.length != y.length) return false; int i=0; // word-wise compare is faster than byte-wise if (x.length > size_t.sizeof) for (; i < x.length - size_t.sizeof; i+=size_t.sizeof) { size_t* xw = cast(size_t*) &x[i]; size_t* yw = cast(size_t*) &x[i]; if (*xw != *yw) return false; } // last sub-word part for (; i < x.length; i+=1) { if (x[i] != y[i]) // byte compare return false; } return true; } Any comments or recommendations? Isn't that something that the compiler should optimize for you when you do an equality comparison? Is it really faster than ldc (with all optimzations turned on)?
Re: String compare in words?
On Sunday, 29 May 2016 at 17:42:48 UTC, Era Scarecrow wrote: Worse I'm not sure if the code generation already does that and possibly does a better job than what we could do by hand... Not with dmd v2.071.0 or ldc 0.17.1. At least not in all the variations I tried to trick them with, like copying into fixed-size array. Well, they did insert a memcmp and libc is probably optimized like that, but they copied data first, which is unnecessary.
Re: String compare in words?
On Sunday, 29 May 2016 at 18:15:16 UTC, qznc wrote: On Sunday, 29 May 2016 at 17:38:17 UTC, Jonathan M Davis wrote: And if you're not simply comparing for equality, what are you looking to figure out? Without more information about what you're trying to do, it's kind of hard to help you. If I write the comparison naively, the assembly clearly shows a "movzbl" [0]. It loads a single byte! The other single byte load is encoded in the address mode of "cmp". Implementation: bool stringcmp(string x, string y) { foreach(i; 0..x.length) { if (x[i] != y[i]) // byte compare return false; } return true; } It makes no sense to load single bytes here. Since we only want to check for equality, we could load two full words and compare four or eight bytes in one go. Ok, to answer my own question, this looks good: bool string_cmp_opt(immutable(ubyte)[] x, immutable(ubyte)[] y) { pragma(inline, false); if (x.length != y.length) return false; int i=0; // word-wise compare is faster than byte-wise if (x.length > size_t.sizeof) for (; i < x.length - size_t.sizeof; i+=size_t.sizeof) { size_t* xw = cast(size_t*) &x[i]; size_t* yw = cast(size_t*) &x[i]; if (*xw != *yw) return false; } // last sub-word part for (; i < x.length; i+=1) { if (x[i] != y[i]) // byte compare return false; } return true; } Any comments or recommendations?
Re: Keeping a mutable reference to a struct with immutable members
On Sunday, 29 May 2016 at 19:52:37 UTC, Basile B. wrote: Do yo have a simple, concise runnable example to show ? This is the example I was using to test solutions, it's similar to where I encountered the problem in the first place import core.stdc.stdlib : malloc, free; import std.stdio; import std.range; import std.traits; struct RepeatRange(Range) if(isForwardRange!Range){ Range* source; Range original; this(Range original){ this.original = original; this.repeat(original.save); } @property auto ref front(){ return this.source.front; } void popFront(){ this.source.popFront(); if(this.source.empty) this.repeat(this.original.save); } @nogc void repeat(Range from){ if(this.source) free(this.source); ubyte* newptr = cast(ubyte*) malloc(Range.sizeof); assert(newptr !is null, "Failed to allocate memory."); ubyte* fromptr = cast(ubyte*) &from; for(size_t i; i < Range.sizeof; i++) newptr[i] = fromptr[i]; this.source = cast(Range*) newptr; } this(this){ auto source = *this.source; this.source = null; this.repeat(source); } ~this(){ if(this.source) free(this.source); } enum bool empty = false; } struct SomeForwardRange{ int value = 0; const int other = 1; // Immutable member enum bool empty = false; @property auto ref save(){ return SomeForwardRange(this.value); } @property auto ref front(){ return this.value; } void popFront(){ this.value++; } } void main(){ auto range = RepeatRange!SomeForwardRange(SomeForwardRange(0)); foreach(item; range.take(10)){ writeln(item); } }
Re: Keeping a mutable reference to a struct with immutable members
On Sunday, 29 May 2016 at 19:09:13 UTC, pineapple wrote: On Sunday, 29 May 2016 at 18:52:36 UTC, pineapple wrote: What's the best way to handle something like this? Well I did get something to work but it's ugly and I refuse to believe there isn't a better way to handle this. Where `Range` is an alias to a struct with an immutable member, and `this.source` is the attribute that I need to be able to re-assign to a locally scoped return value: this.source = cast(Range*) newptr; Do yo have a simple, concise runnable example to show ?
Re: Keeping a mutable reference to a struct with immutable members
On Sunday, 29 May 2016 at 18:52:36 UTC, pineapple wrote: What's the best way to handle something like this? Well I did get something to work but it's ugly and I refuse to believe there isn't a better way to handle this. Where `Range` is an alias to a struct with an immutable member, and `this.source` is the attribute that I need to be able to re-assign to a locally scoped return value: import core.stdc.stdlib : malloc, free; if(this.source) free(source); ubyte* newptr = cast(ubyte*) malloc(Range.sizeof); assert(newptr !is null, "Failed to allocate memory."); Range saved = this.original.save; ubyte* savedptr = cast(ubyte*) &saved; for(size_t i; i < Range.sizeof; i++){ newptr[i] = savedptr[i]; } this.source = cast(Range*) newptr;
Keeping a mutable reference to a struct with immutable members
I found another post on this subject and the advice there was "don't put const members in your structs" - http://forum.dlang.org/thread/m87ln2$idv$1...@digitalmars.com This doesn't work out so well when the templated struct is referring to what happens to be a const array. I thought I could get it done with pointers, but then I realized my data was going out-of-scope. I tried using `Unqual!T thing_i_need_to_reassign_sometimes` where T was immutable but that didn't solve anything, either. What's the best way to handle something like this?
Re: String compare in words?
On Sunday, 29 May 2016 at 17:38:17 UTC, Jonathan M Davis wrote: And if you're not simply comparing for equality, what are you looking to figure out? Without more information about what you're trying to do, it's kind of hard to help you. If I write the comparison naively, the assembly clearly shows a "movzbl" [0]. It loads a single byte! The other single byte load is encoded in the address mode of "cmp". Implementation: bool stringcmp(string x, string y) { foreach(i; 0..x.length) { if (x[i] != y[i]) // byte compare return false; } return true; } It makes no sense to load single bytes here. Since we only want to check for equality, we could load two full words and compare four or eight bytes in one go. This example is simplified and far-fetched. Actually, this is about the find algorithm [1]. [0] http://goo.gl/ttybAB [1] http://forum.dlang.org/post/vdjraubhtoqtxeshj...@forum.dlang.org
Re: @trusting generic functions
On 5/28/16 7:50 AM, Lodovico Giaretta wrote: Let's say I have a generic function that uses pointers. It will be inferred @system by the compiler, but I know that the pointer usage can be @trusted. The problem is that if I declare the function @trusted, I'm also implicitly trusting any call to @system methods of the template parameter. Dumb example (pointer usage can be trusted, but doSomething may not): auto doSomethingDumb(T)(ref T t) // I want it @trusted if doSomething is at least @trusted { T* pt = &t; return pt.doSomething(); } Is there any way around this? Any way to declare a function @trusted as long as the methods of the template argument are at least @trusted? Thank you in advance. You can create a trusted expression by using a lambda and immediately calling it. ag0aep6g brought it up. I would write it like this (untested, but I think this works): return (()@trusted => &t)().doSomething(); The key is to limit your code that is tainted by @trusted to as little code as possible. Note that doSomethingDumb will be inferred @safe and not @trusted. The compiler should NEVER infer @trusted (for obvious reasons). -Steve
Re: String compare in words?
On Sunday, 29 May 2016 at 17:38:17 UTC, Jonathan M Davis wrote: In what way are you trying to compare them? If all you're doing is comparing them for equality, then just use ==. e.g. if(str1 == str2) { } And if you're not simply comparing for equality, what are you looking to figure out? Without more information about what you're trying to do, it's kind of hard to help you. I'm reminded that the GNU stdlib has a string compare function which defaults to using larger double words to get a speedup, and I think he wants to do that the same way. Although unless they are both the same size and both divisible by the size of size_t, then it's a multi-stage process to do correctly. Worse I'm not sure if the code generation already does that and possibly does a better job than what we could do by hand...
Re: String compare in words?
On Sunday, May 29, 2016 17:13:49 qznc via Digitalmars-d-learn wrote: > Given two string (or char[] or ubyte[]) objects, I want to > compare them. The naive loop accesses the arrays byte-wise. How > could I turn this into a word-wise compare for better performance? > > Is a cast into size_t[] ok? Some Phobos helper functions? In what way are you trying to compare them? If all you're doing is comparing them for equality, then just use ==. e.g. if(str1 == str2) { } And if you're not simply comparing for equality, what are you looking to figure out? Without more information about what you're trying to do, it's kind of hard to help you. - Jonathan M Davis
Re: String compare in words?
On Sunday, 29 May 2016 at 17:13:49 UTC, qznc wrote: Given two string (or char[] or ubyte[]) objects, I want to compare them. The naive loop accesses the arrays byte-wise. How could I turn this into a word-wise compare for better performance? Is a cast into size_t[] ok? Some Phobos helper functions? Assuming you don't have codepoints and only want to do a raw compare, i believe you can as long as the sizes align.
String compare in words?
Given two string (or char[] or ubyte[]) objects, I want to compare them. The naive loop accesses the arrays byte-wise. How could I turn this into a word-wise compare for better performance? Is a cast into size_t[] ok? Some Phobos helper functions?
Re: Read registry keys recursively
On Sunday, 29 May 2016 at 15:48:49 UTC, TheDGuy wrote: Hello, i am wondering what is wrong with my code: import std.windows.registry; import std.stdio; void main(){ Key lclM = Registry.localMachine(); Key hrdw = lclM.getKey("HARDWARE"); writeRegistryKeys(hrdw); } void writeRegistryKeys(Key k){ foreach(Key key; k.keys){ writeRegistryKeys(key.getKey(key.name())); } writeln(k.name()); } i get: std.windows.registry.RegistryException@std\windows\registry.d(511): Failed to open requested key: "ACPI" Even though there is a key called 'ACPI' under localmachine/hardware? Well this was a fun thing to figure out. Geez... You have everything good except for one line. writeRegistryKeys(key.getKey(key.name())); Let's translate that. Assume key = ACPI... SO... ACPI.getkey("ACPI") you should see the problem. Here's the correct line! writeRegistryKeys(k.getKey(key.name()));
Re: How to hash any type to an integer?
On Sunday, 29 May 2016 at 11:05:21 UTC, Gary Willoughby wrote: I'm currently implementing a hash map as an exercise and wondered if there is a built-in function I could use to hash keys effectively? What I'm looking for is a function that hashes any variable (of any type) to an integer. I've been looking at the `getHash` function of the `TypeInfo` class but that only seems to return the passed pointer. Any ideas? How about hashOf? https://dlang.org/phobos/object.html#.hashOf
Read registry keys recursively
Hello, i am wondering what is wrong with my code: import std.windows.registry; import std.stdio; void main(){ Key lclM = Registry.localMachine(); Key hrdw = lclM.getKey("HARDWARE"); writeRegistryKeys(hrdw); } void writeRegistryKeys(Key k){ foreach(Key key; k.keys){ writeRegistryKeys(key.getKey(key.name())); } writeln(k.name()); } i get: std.windows.registry.RegistryException@std\windows\registry.d(511): Failed to open requested key: "ACPI" Even though there is a key called 'ACPI' under localmachine/hardware?
Re: D, GTK, Qt, wx,…
On Sunday, 29 May 2016 at 11:03:36 UTC, Russel Winder wrote: From what I can tell QtD is in need of effort or restarting. I will probably give it another shot when D has better interop with C++. Particularly, when multiple inheritance of C++ interfaces is implemented, Walter admits that mingling C++ namespaces into D name hierarchy is a horrible idea, and so on.
Re: Why does std.container.array does not work with foraech( i, a; array ) {} ?
On Sunday, 29 May 2016 at 09:07:07 UTC, Jonathan M Davis wrote: On Sunday, May 29, 2016 07:14:12 ParticlePeter via Digitalmars-d-learn wrote: Which of the op(Index) operators is responsible for enabling this kind of syntax? Would it be possible to get it work with UFCS or would I have to wrap the array? std.container.array.Array works with foreach via ranges. foreach(e; myContainer) { } gets lowered to foreach(e; myContainer[]) { } which in turn gets lowered to something like for(auto r = myContainer[]; !r.empty; r.popFront()) { auto e = r.front; } Ranges do not support indices with foreach, and that's why you're not able to get the index with foreach and Array. However, if you use std.range.lockstep, you can wrap a range to get indices with foreach. e.g. foreach(i, e; lockstep(myContainer[])) { } http://dlang.org/phobos/std_range.html#.lockstep - Jonathan M Davis Thanks, due to your answer I found a way which is even better for me. I pimped the Array containers with some UFCS functions anyway, one of them returns the array data as a slice and this works nicely with that foreach variant as well auto data( T )( Array!T array ) { if( array.length == 0 ) return null; return (&array.front())[ 0..array.length ]; } // this works now foreach( i, a; someArrayContainer.data ) { ... } - PP
Re: D, GTK, Qt, wx,…
El 29/05/16 a les 13:03, Russel Winder via Digitalmars-d-learn ha escrit: > GKT+ has a reputation for being dreadful on OSX and even worse on > Windows. Qt on the other hand has a reputation for being the most > portable – though clearly wx is (arguable) the most portable. > > We have GtkD which is brilliant, especially as it has GStreamer > support. > > From what I can tell QtD is in need of effort or restarting. > > Is there even a wxD? > > Or perhaps there is an alternative that fits the bill of being > production ready now, and either gives the same UI across all platforms > or provides a platform UI with no change of source code, just a > recompilation. > https://github.com/nomad-software/tkd
Re: is my code to get CTFE instantiated object valid D ?
On Sunday, 29 May 2016 at 05:43:31 UTC, Mike Parker wrote: On Sunday, 29 May 2016 at 05:35:33 UTC, Mike Parker wrote: Well then, this completely breaks my understanding of variable scope. OK, I see now at [1] the following: " Immutable data doesn't have synchronization problems, so the compiler doesn't place it in TLS." I've read that page more than once, but I had forgotten this bit. Still, I don't see anything there about const. I would not expect const variables to behave the same way, given the weaker guarantee about modification. But if they are intended to behave that way, then, IMO, it should not be possible to reinitialize them in a static constructor. https://dlang.org/migrate-to-shared.html It's reasonable to treat const variables like immutable when the const variable has no indirections. However, it shouldn't allow rewriting the variable in each thread ctor. -Steve
Re: Why does std.container.array does not work with foraech( i, a; array ) {} ?
On Sunday, 29 May 2016 at 09:07:07 UTC, Jonathan M Davis wrote: On Sunday, May 29, 2016 07:14:12 ParticlePeter via Digitalmars-d-learn wrote: [...] std.container.array.Array works with foreach via ranges. foreach(e; myContainer) { } gets lowered to foreach(e; myContainer[]) { } which in turn gets lowered to something like for(auto r = myContainer[]; !r.empty; r.popFront()) { auto e = r.front; } Ranges do not support indices with foreach, and that's why you're not able to get the index with foreach and Array. However, if you use std.range.lockstep, you can wrap a range to get indices with foreach. e.g. foreach(i, e; lockstep(myContainer[])) { } http://dlang.org/phobos/std_range.html#.lockstep - Jonathan M Davis I'd say that std.range.enumerate is more indicative of intent: http://dlang.org/phobos/std_range.html#enumerate
How to hash any type to an integer?
I'm currently implementing a hash map as an exercise and wondered if there is a built-in function I could use to hash keys effectively? What I'm looking for is a function that hashes any variable (of any type) to an integer. I've been looking at the `getHash` function of the `TypeInfo` class but that only seems to return the passed pointer. Any ideas?
Re: Newbie to D, first impressions and feedback on the 5 (and more) first minutes.
On Wed, 2016-05-25 at 13:57 +, qznc via Digitalmars-d-learn wrote: > On Wednesday, 25 May 2016 at 09:41:10 UTC, Russel Winder wrote: > > I do not really have the proper resources to host such a > > repository and because of this I have not built one. I know I > > should rather than just moan, but Debian is my main platform > > and that is covered. > > Yes, this is the core problem. There is no single person, which > (a) cares enough about Fedora and (b) can fix it. Unless this > champion appears, Fedora will continue to suck for newbies. Are there enough people around such that we can make a start at something that is not separate as d-apt is from Debian, but is an integral stepping stone to the Fedora repository. It may be that doing a Fedora equivalent of d-apt is a first step. Given the relatively low traffic initially, I can host a repository at some URL such as fedora.dlang.org or some such, we can experiment with fedora.winder.org.uk maybe. The issue is setting up a Git build framework that does all the RPM builds automatically. This is the successful basis for Debian, Fedora and I suspect d-apt. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
D, GTK, Qt, wx,…
GKT+ has a reputation for being dreadful on OSX and even worse on Windows. Qt on the other hand has a reputation for being the most portable – though clearly wx is (arguable) the most portable. We have GtkD which is brilliant, especially as it has GStreamer support. From what I can tell QtD is in need of effort or restarting. Is there even a wxD? Or perhaps there is an alternative that fits the bill of being production ready now, and either gives the same UI across all platforms or provides a platform UI with no change of source code, just a recompilation. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Why does std.container.array does not work with foraech( i, a; array ) {} ?
On Sunday, May 29, 2016 07:14:12 ParticlePeter via Digitalmars-d-learn wrote: > Which of the op(Index) operators is responsible for enabling this > kind of syntax? > Would it be possible to get it work with UFCS or would I have to > wrap the array? std.container.array.Array works with foreach via ranges. foreach(e; myContainer) { } gets lowered to foreach(e; myContainer[]) { } which in turn gets lowered to something like for(auto r = myContainer[]; !r.empty; r.popFront()) { auto e = r.front; } Ranges do not support indices with foreach, and that's why you're not able to get the index with foreach and Array. However, if you use std.range.lockstep, you can wrap a range to get indices with foreach. e.g. foreach(i, e; lockstep(myContainer[])) { } http://dlang.org/phobos/std_range.html#.lockstep - Jonathan M Davis
Re: is my code to get CTFE instantiated object valid D ?
On Sunday, 29 May 2016 at 06:49:42 UTC, chmike wrote: What is the right way to use it ? I answer to my self after testing so that people looking for that info can find it here. The right way would be immutable Category category_; Rebindable!(immutable Category) instance() { return rebindable(category_); } it is equivalent and shorter (for the lazy) to write auto instance() { return rebindable(category_); } The disadvantage of this form is that the reader of documentation generated automatically from the source file will only see this : auto instance() and he won't know what this instance method effectively returns. If we want a mutable reference that accept mutable and immutable Category objects, we should define this Rebindable!(const Category) x = Category.instance(); x = new Category; The concept of immutable and constness of D was the most difficult thing to learn because it is radically different from the const concept of C and C++. Now that I understood it and stopped getting hit with immutability and constness compiler errors, I start to like it. So the only problem I see with Rebindable is the inefficiency of reference comparison in the generated assembly code with DMD64 D Compiler v2.071.0. This will hopefully get fixed in next versions. Thank you very much to everybody who took the time to help me learn D and answer my so many questions.
Weird "nested function cannot be accessed" error
This code fails to compile: void bar(alias f)() { f(); } void foo(alias f)() { bar!f(); } void main() { void f()() { } foo!f(); } Error: function test.main.f!().f is a nested function and cannot be accessed from test.bar!(f).bar But non-template nested functions are accepted: void main() { void f() { } foo!f(); // ok } What's going on here?
Re: Operator overloading through UFCS doesn't work
On Friday, May 27, 2016 09:08:20 Marc Schütz via Digitalmars-d-learn wrote: > On Thursday, 26 May 2016 at 06:23:17 UTC, Jonathan M Davis wrote: > > The difference is that it's impossible to do > > 10.opBinary!"+"(15), so if you're forced to do > > foo.opBinary!"+"(bar) to get around a symbol conflict, it won't > > work with built-in types. > > Well, that begs the question: Why don't built-in types define > `opBinary`? That's just another arbitrary irregularity, isn't it. It was never intended that any op* function be called by anyone except where the compiler lowers code to use them. They're for declaring overloaded operators on user-defined types so that those types can be used with those operators. If you're calling opBinary in your own code, you're doing it wrong. And it would be downright silly to then add opBinary to the built-in types. They don't need operator overloading. They already have the operators. Operators are supposed to be used as operators, not functions, and if there's any need to use them as functions, then there's something seriously wrong. And the fact that allowing free functions to overload operators via UFCS sends us into that territory just highlights the fact that they're a horrible idea. - Jonathan M Davis
Why does std.container.array does not work with foraech( i, a; array ) {} ?
Which of the op(Index) operators is responsible for enabling this kind of syntax? Would it be possible to get it work with UFCS or would I have to wrap the array?