Re: Do we have GC-free hash map implementation sitting somewhere?
On 15-10-2012 08:49, Alex Rønne Petersen wrote: Hi, Is there a GC-free hash map implementation for D somewhere on the intertubes? (Preferably in a Git repository and under a liberal/non-viral license.) ... s/have/have a/ ... -- Alex Rønne Petersen a...@lycus.org http://lycus.org
Do we have GC-free hash map implementation sitting somewhere?
Hi, Is there a GC-free hash map implementation for D somewhere on the intertubes? (Preferably in a Git repository and under a liberal/non-viral license.) -- Alex Rønne Petersen a...@lycus.org http://lycus.org
Re: Specifying precision in %(...%) print format
On 10/14/2012 10:43 PM, H. S. Teoh wrote: I have an array of reals that I want to format with writefln, but the precision field needs to be passed in a variable. For a single real, it would be writefln("%.*f", precision, x); but when I try this: int precision = ...; real[] array = ...; writefln("%(%.*f, %)", precision, array); I get a runtime exception with the message "integral". I assume that's because %(%) is expecting an array, but sees an int, so it fails. But swapping the order of parameters doesn't help either: writefln("%(%.*f, %)", array, precision); produces "floating point format failure". What's the right way to do this? T Here is a way with format: import std.stdio; import std.string; void main() { int precision = 2; real[] array = [ 1.234 ]; writefln(format("%%(%%.%sf, %%)", precision), array); } Ali
Specifying precision in %(...%) print format
I have an array of reals that I want to format with writefln, but the precision field needs to be passed in a variable. For a single real, it would be writefln("%.*f", precision, x); but when I try this: int precision = ...; real[] array = ...; writefln("%(%.*f, %)", precision, array); I get a runtime exception with the message "integral". I assume that's because %(%) is expecting an array, but sees an int, so it fails. But swapping the order of parameters doesn't help either: writefln("%(%.*f, %)", array, precision); produces "floating point format failure". What's the right way to do this? T -- Trying to define yourself is like trying to bite your own teeth. -- Alan Watts
Re: std.stream, BOM, and deprecation
On Sat, 13 Oct 2012 18:53:48 -0700 Charles Hixson wrote: > If std.stream is being deprecated, what is the correct way to deal > with file BOMs. This is particularly concerning utf8 files, which I > understand to be a bit problematic, as there isn't, actually, a utf8 > BOM, merely a convention which isn't a part of a standard. But the > std.stdio documentation doesn't so much as mention byte order marks > (BOMs). > > If this should wait until std.io is released, then I could use > std.stream until them, but the documentation is already warning to > avoid using it. Personally, I think it's kind of cumbersome to deal with in Phobos, so I wrote this wrapper that I use instead, which handles everything: https://bitbucket.org/Abscissa/semitwistdtools/src/977820d5dcb0/src/semitwist/util/io.d?at=master#cl-24 And then there's the utfConvert below it if you already have the data in memory instead of on disk. (Maybe I should add some range capability and make a Phobos pull request. I don't know if it'd fly though. It uses a lot of custom endian- and bom-related code since I found the existing endian/bom stuff in phobos inadequate. So that stuff would have to be accepted, and then this too, and it's usually a bit of a pain to get things approved.)
Re: To: Johannes Pfau
On 10/15/12 02:14, Andrej Mitrovic wrote: > Johannes, are you still working on gobject introspection? libgit has > gobject bindings so I remembered you mentioning something about > working on gobject for D. FWIW gobject bindings are part of my gtk2 bindings too; http://repo.or.cz/w/girtod.git/blob/refs/heads/gtk2:/gtk2/gobject2.d artur
Re: How many std.concurrency receivers?
On Oct 14, 2012, at 9:59 AM, Dmitry Olshansky wrote: > On 14-Oct-12 20:19, Sean Kelly wrote: >> On Oct 12, 2012, at 2:29 AM, Russel Winder wrote: >> >>> On Thu, 2012-10-11 at 20:30 -0700, Charles Hixson wrote: >>> […] I'm not clear on what Fibers are. From Ruby they seem to mean co-routines, and that doesn't have much advantage. But it also seems as >>> […] >>> >>> I think the emerging consensus is that threads allow for pre-emptive >>> scheduling whereas fibres do not. So yes as in Ruby, fibres are >>> collaborative co-routines. Stackless Python is similar. >> >> Yep. If fibers were used in std.concurrency there would basically be an >> implicit yield in send and receive. > > Makes me wonder how it will work with blocking I/O and the like. If all of > (few of) threads get blocked this way that going to stall all of (thousands > of) fibers. Ideally, IO would be nonblocking with a yield there too, at least if the operation would block.
Re: toStringz note about keeping references
On Monday, October 15, 2012 02:04:44 Andrej Mitrovic wrote: > On 10/15/12, Jonathan M Davis wrote: > > snip > > Hmm ok, this sheds some light on things. > > If a C function takes a const pointer and has no documentation about > ownership then maybe it's a good guess to say it won't store that > pointer anywhere and will only use it as a temporary? Generally speaking yes. It's rare for them to keep pointers around, and if they do and don't tell you, then they're creating bugs in C code too. Most C functions (especially if you're talking OS functions) which keep memory that you pass to them or give you memory thaty you didn't pass to them will inform you about it in their documentation. - Jonathan M Davis
Re: toStringz note about keeping references
On 10/15/12, Jonathan M Davis wrote: > snip Hmm ok, this sheds some light on things. If a C function takes a const pointer and has no documentation about ownership then maybe it's a good guess to say it won't store that pointer anywhere and will only use it as a temporary?
Re: toStringz note about keeping references
On Monday, October 15, 2012 01:36:27 Andrej Mitrovic wrote: > On 10/15/12, Jonathan M Davis wrote: > > I'd have to see exactly what TDPL says to comment on that accurately > > Maybe I've misread it. On Page 288 it says: > > "An immutable value is cast in stone: as soon as it's been > initialized, you may as well > consider it has been burned forever into the memory storing it. It > will never change > throughout the execution of the program." > > Perhaps what was missing is: "as long as there is a reference to that data". That says _nothing_ about collection. It's only saying that the value won't ever change. It's trying to highlight the difference between const and immutable. It would make _no_ sense for immutable data to not be collected when all references to it were gone. > I'd really like to know for sure if the GC implementation actually > collects immutable data or not. I guarantee that if it doesn't, it's a bug. There are exceptions (e.g. string literals in Linux - because they go in ROM), and the GC isn't exactly enthusiastic about reclaiming memory, which means that stuff can hang around for quite a while, but normally, immutability should have no effect on the lifetime of an object. > I've always used toStringz in direct > calls to C without caring about keeping a reference to the source > string in D code. It's perfectly safe as long as the C function doesn't hold on to the pointer. If it does, then you could get screwed later on when that pointer gets used, and whether it works or not then becomes non-deterministic (since it depends on whether the GC has collected the memory or not and whether that memory has been reused) which could cause some really nasty bugs. That's why the note on toStringz is there in the first place. It would not surprise me at all if it's a common bug when interfacing with C that references are not kept around when they should be. I suspect that the main reason that it doesn't cause more issues is because most C functions don't keep pointers around. > Anyway this stuff is important for OOP wrappers of C/C++ libraries. If > the string reference must kept on the D side then this makes writing > wrappers harder. That's true, but to some extent, that's just life when dealing with interfacing with code outside of the GC's reach. However, I believe that another option is to explicitly tell the GC not collect a chunk of memory (glancing at core.memory, I suspect that removeRoot is the function to use for that, but I've never done it before, so I'm not well acquainted with the details). But if you want it to ever be collected, you'd need to make sure that it was readded to the GC again later, which could also complicate wrappers. It _is_ another option though if keeping a reference around in the D code is problematic. > And what about multiple calls? What if on each call to c_Foo_test() > the C library stores each 'input' pointer internally? That would mean > we have to keep an array of these pointers on the D side. Potentially, yes. > It's not know what the C library does without inspecting the source of > the C library. So it becomes very difficult to write wrappers which > are GC-safe. Unfortunately, that's true. However, remember that in C, you normally have to manage your own memory, so if C functions aren't appropriately clear about who owns what memory or which pointers get kept, then they'll run into serious problems in pure C. So, in general, I would expect a C function to be fairly clear when it keeps a pointer around or gives you a pointer to memory that it allocated or controls. But it's fairly rare that C functions keep pointers around (that would mean using global variables which are generally rare), so in most cases, it's a non-issue. > There are wrappers out there that seem to expect the source won't be > collected. For example GtkD also uses toStringz in calls to C without > ever storing a reference to the input string. As long as the function doesn't keep any of the pointers that it's given, then it's fine. If it _does_ keep a pointer around, then it's a bug for the D code not to keep a reference around. But as I said, it's fairly rare for C code to do that, which is probably why this doesn't cause more issues. But the note on toStringz is there precisely because most people aren't going to think of that problem, and they need to be aware of it when using toStringz. - Jonathan M Davis
Re: toStringz note about keeping references
On 10/14/2012 04:36 PM, Andrej Mitrovic wrote: > On 10/15/12, Jonathan M Davis wrote: >> I'd have to see exactly what TDPL says to comment on that accurately > > Maybe I've misread it. On Page 288 it says: > > "An immutable value is cast in stone: as soon as it's been > initialized, you may as well > consider it has been burned forever into the memory storing it. It > will never change > throughout the execution of the program." > > Perhaps what was missing is: "as long as there is a reference to that data". Andrei must have written that only D in mind, without any C interaction. When we consider only D, then the statement is correct: If there is no more references, how can the application tell that the data is gone or not? > I'd really like to know for sure if the GC implementation actually > collects immutable data or not. It does. Should be easy to test with an infinite loop that generates immutable data. > I've always used toStringz in direct > calls to C without caring about keeping a reference to the source > string in D code. I'm sure others have used it like this as well. It depends on whether the C-side keeps a copy of that pointer. > Maybe the only reason my apps which use C don't crash is because a GC > cycle doesn't often run, and when it does run it doesn't collect the > source string data (either on purpose or because of buggy behavior, or > because the GC is imprecise). > > Anyway this stuff is important for OOP wrappers of C/C++ libraries. If > the string reference must kept on the D side then this makes writing > wrappers harder. For example, let's say you've had this type of > wrapper: > > extern(C) void* get_Foo_obj(); > extern(C) void* c_Foo_test(void* c_obj, const(char)* input); > > class Foo > { > this() { c_Foo_obj = get_Foo_obj(); } // init c object by calling > a C function > > void test(string input) > { > c_Foo_test(c_Foo_obj, toStringz(input)); > } > > void* c_Foo_obj; // reference to C object > } > > Should we always store a reference to 'input' to avoid GC collection? If the C function copies the pointer, yes. > E.g.: > > class Foo > { > this() { c_Foo_obj = get_Foo_obj(); } // init c object by calling > a C function > > void test(string input) > { > input_ref = input > c_Foo_test(c_Foo_obj, toStringz(input)); > } > > string input_ref; // keep it alive, C might use it after test() returns That's exactly what I do in a C++ library that wraps C types. > void* c_Foo_obj; // reference to C object > } > > And what about multiple calls? What if on each call to c_Foo_test() > the C library stores each 'input' pointer internally? That would mean > we have to keep an array of these pointers on the D side. Again, that's exactly what I do in C++. :) There is a global container that keeps the objects alive. > It's not know what the C library does without inspecting the source of > the C library. So it becomes very difficult to write wrappers which > are GC-safe. Most functions document what they do with the input parameters. If not, it is usually obvious. > There are wrappers out there that seem to expect the source won't be > collected. For example GtkD also uses toStringz in calls to C without > ever storing a reference to the input string. Must be verified case-by-case. Ali
Re: toStringz note about keeping references
On 10/15/12, Jonathan M Davis wrote: > I'd have to see exactly what TDPL says to comment on that accurately Maybe I've misread it. On Page 288 it says: "An immutable value is cast in stone: as soon as it's been initialized, you may as well consider it has been burned forever into the memory storing it. It will never change throughout the execution of the program." Perhaps what was missing is: "as long as there is a reference to that data". I'd really like to know for sure if the GC implementation actually collects immutable data or not. I've always used toStringz in direct calls to C without caring about keeping a reference to the source string in D code. I'm sure others have used it like this as well. Maybe the only reason my apps which use C don't crash is because a GC cycle doesn't often run, and when it does run it doesn't collect the source string data (either on purpose or because of buggy behavior, or because the GC is imprecise). Anyway this stuff is important for OOP wrappers of C/C++ libraries. If the string reference must kept on the D side then this makes writing wrappers harder. For example, let's say you've had this type of wrapper: extern(C) void* get_Foo_obj(); extern(C) void* c_Foo_test(void* c_obj, const(char)* input); class Foo { this() { c_Foo_obj = get_Foo_obj(); } // init c object by calling a C function void test(string input) { c_Foo_test(c_Foo_obj, toStringz(input)); } void* c_Foo_obj; // reference to C object } Should we always store a reference to 'input' to avoid GC collection? E.g.: class Foo { this() { c_Foo_obj = get_Foo_obj(); } // init c object by calling a C function void test(string input) { input_ref = input c_Foo_test(c_Foo_obj, toStringz(input)); } string input_ref; // keep it alive, C might use it after test() returns void* c_Foo_obj; // reference to C object } And what about multiple calls? What if on each call to c_Foo_test() the C library stores each 'input' pointer internally? That would mean we have to keep an array of these pointers on the D side. It's not know what the C library does without inspecting the source of the C library. So it becomes very difficult to write wrappers which are GC-safe. There are wrappers out there that seem to expect the source won't be collected. For example GtkD also uses toStringz in calls to C without ever storing a reference to the input string.
Re: toStringz note about keeping references
On Monday, October 15, 2012 00:51:34 Andrej Mitrovic wrote: > On 10/15/12, Jonathan M Davis wrote: > > Anything and everything with no references to it any > > longer should be up for collection. > > I think this is fuzzy territory and it's a good opportunity to > properly document GC behavior. I don't see how it could be fuzzy at all. It makes no sense whatsoever to keep _any_ data around once it has nothing referencing it. The constness of an object should have _zero_ affect on its scope or lifetime. immutable _does_ implicitly make a variable shared, but that has nothing to do with the object's lifetime. That just makes it so that it can be used across threads. Once no more threads reference it, it should collected. Keeping the data around would simply result in the effective equivalent of leaked memory. > For example, TDPL states that immutable data is always available, and > that a user should treat such data as if it existed throughout the > lifetime of the program. I'd have to see exactly what TDPL says to comment on that accurately, but if it means that all immutable data is expected to be around for the entire lifetime of the program, then that's a huge problem. If it's something that was specifically allocated in ROM when the program started, then that makes sense (e.g. string literals on Linux), but nothing allocated on the normal GC heap should be kept alive simply because it's immutable. References to it must exist. - Jonathan M Davis
Re: toStringz note about keeping references
On Sunday, October 14, 2012 23:38:48 Andrej Mitrovic wrote: > toStringz takes a string (immutable(char)[]), and the GC will not > reclaim immutable data until app exit. If the GC never collects immutable data which has no references to it until the app closes, then there's a serious problem. Immutability shouldn't factor into that at all. Anything and everything with no references to it any longer should be up for collection. Any other behavior would effectively result in huge memory leaks - especially if you're doing a lot with strings. Maybe you're seeing the behavior that you're seeing because the GC mistakingly thinks that something points to it (as happens sometimes - especially in 32- bit programs). - Jonathan M Davis
Re: COM Example work for anyone?
On Sunday, 14 October 2012 at 19:04:22 UTC, Richard Webb wrote: I haven't tried to run it, but as a random guess, does the user your running it as have permissions to write to HKEY_CLASSES_ROOT ? Guess that would be it. Specifically told the program to run as admin and it works. Should have checked if you left a message here first, but GitHub is better about telling me new messages. My comserver branch's example also has the registration through manifest which I'm not getting to work. Wonder if it is the same issue... This should at least get me started building customer servers such that I can build a much better understanding of how these all fit together and test what works vs what is an environment issue. But I'm getting a little tired for now so I'll probably look at some other aspects for a bit. Thanks for watching my work and helping.
Re: Operator overloading through UFCS doesn't work
On Sunday, 14 October 2012 at 07:14:25 UTC, Maxim Fomin wrote: If this request is approved and compiler has opUnary definition outside type (which suits better then alias this) such function would hijack alias this. Free functions cannot and must not ever hijack, i.e. modify existing functionality of a type. Free functions should only be able to add new functionality to a type. This is what currently happens with alias this vs free function which is accessed through UFCS: struct B { void fun() { writeln("B.fun()"); } } struct A { B b; alias b this; } void fun(A a) { writeln(".fun(A)"); } void main() { A a; a.fun(); // prints B.fun() as it should } It shouldn't be any different if fun was some operator function, like opUnary; the free function mustn't hijack type A's existing functionality (which is currently being provided to A by that alias this thingy).
Re: Operator overloading through UFCS doesn't work
On 10/14/12 08:13, Maxim Fomin wrote: > The only mentioned reason is to allow writing operator overloading methods > outside type scope - just because somebody (currently two people) consider it > logical to broaden UFCS usage. It's more than two people... Also, it's not about "broadening UFCS usage", it's about making UFCS work properly. > This doesn't solve ay practical issue. Obviously, it does. Otherwise this issue wouldn't come up repeatedly. artur
Re: COM Example work for anyone?
I haven't tried to run it, but as a random guess, does the user your running it as have permissions to write to HKEY_CLASSES_ROOT ?
Re: Ignoring defaults from sc.ini?
On Sunday, 14 October 2012 at 09:40:36 UTC, Benjamin Thaut wrote: Is there a way to make dmd ignore the default imports and library search paths inside sc.ini? Currently I have to keep two versions of dmd around, one with a modified sc.ini and one with the original one, which is a bit annoying. A command line option for the compiler to ignore the defaults inside sc.ini would be really great. You might want to have a look at DVM: https://bitbucket.org/doob/dvm/wiki/Home -- /Jacob Carlborg
Re: How many std.concurrency receivers?
On 14-Oct-12 20:19, Sean Kelly wrote: On Oct 12, 2012, at 2:29 AM, Russel Winder wrote: On Thu, 2012-10-11 at 20:30 -0700, Charles Hixson wrote: […] I'm not clear on what Fibers are. From Ruby they seem to mean co-routines, and that doesn't have much advantage. But it also seems as […] I think the emerging consensus is that threads allow for pre-emptive scheduling whereas fibres do not. So yes as in Ruby, fibres are collaborative co-routines. Stackless Python is similar. Yep. If fibers were used in std.concurrency there would basically be an implicit yield in send and receive. Makes me wonder how it will work with blocking I/O and the like. If all of (few of) threads get blocked this way that going to stall all of (thousands of) fibers. -- Dmitry Olshansky
Re: How many std.concurrency receivers?
On Oct 12, 2012, at 2:29 AM, Russel Winder wrote: > On Thu, 2012-10-11 at 20:30 -0700, Charles Hixson wrote: > […] >> I'm not clear on what Fibers are. From Ruby they seem to mean >> co-routines, and that doesn't have much advantage. But it also seems as > […] > > I think the emerging consensus is that threads allow for pre-emptive > scheduling whereas fibres do not. So yes as in Ruby, fibres are > collaborative co-routines. Stackless Python is similar. Yep. If fibers were used in std.concurrency there would basically be an implicit yield in send and receive.
Re: Ignoring defaults from sc.ini?
On 10/14/12, Benjamin Thaut wrote: > Is there a way to make dmd ignore the default imports and library search > paths inside sc.ini? See http://dlang.org/dmd-windows.html#sc_ini
Re: What am I doing wrong here?
On Sunday, 14 October 2012 at 12:58:24 UTC, Simen Kjaeraas wrote: On 2012-10-14, 14:28, Martin wrote: Hey everyone, I'm new to D so bare with me please. I've been trying to figure out what's up with the strange forward refernce errors the compiler (DMD 2.060) is giving me. Here's a code snippet that's generating a forward reference error: public class AliasTestClass(alias func) { static assert(__traits(isStaticFunction, func)); } public class TestClass { private AliasTestClass!(randomFunction) test; // <- public static void randomFunction() { } } The strange part about it is that if I surround the randomFunction parameter with another pair of paranthesis like so private AliasTestClass!((randomFunction)) test; It works just fine. If I don't, however, I get a forward reference error: "Error: template instance main.AliasTestClass!(randomFunction) forward reference of randomFunction" Am I doing anything wrong or is this some kind of bug? It's a bug. Maybe it's already in Bugzilla (there are some forward-ref bugs there already). Please file: http://d.puremagic.com/issues/enter_bug.cgi Oh, thank you for clarifying, I thought I was doing something wrong :)
Re: What am I doing wrong here?
On 2012-10-14, 14:28, Martin wrote: Hey everyone, I'm new to D so bare with me please. I've been trying to figure out what's up with the strange forward refernce errors the compiler (DMD 2.060) is giving me. Here's a code snippet that's generating a forward reference error: public class AliasTestClass(alias func) { static assert(__traits(isStaticFunction, func)); } public class TestClass { private AliasTestClass!(randomFunction) test; // <- public static void randomFunction() { } } The strange part about it is that if I surround the randomFunction parameter with another pair of paranthesis like so private AliasTestClass!((randomFunction)) test; It works just fine. If I don't, however, I get a forward reference error: "Error: template instance main.AliasTestClass!(randomFunction) forward reference of randomFunction" Am I doing anything wrong or is this some kind of bug? It's a bug. Maybe it's already in Bugzilla (there are some forward-ref bugs there already). Please file: http://d.puremagic.com/issues/enter_bug.cgi -- Simen
What am I doing wrong here?
Hey everyone, I'm new to D so bare with me please. I've been trying to figure out what's up with the strange forward refernce errors the compiler (DMD 2.060) is giving me. Here's a code snippet that's generating a forward reference error: public class AliasTestClass(alias func) { static assert(__traits(isStaticFunction, func)); } public class TestClass { private AliasTestClass!(randomFunction) test; // <- public static void randomFunction() { } } The strange part about it is that if I surround the randomFunction parameter with another pair of paranthesis like so private AliasTestClass!((randomFunction)) test; It works just fine. If I don't, however, I get a forward reference error: "Error: template instance main.AliasTestClass!(randomFunction) forward reference of randomFunction" Am I doing anything wrong or is this some kind of bug?
Re: equivalent of c++ private inheritance with using
On Friday, 12 October 2012 at 23:05:27 UTC, Jonathan M Davis wrote: You can have the variable be private and alias a function which returns by ref instead of the variable itself. Something like class C { @property ref inout(Impl) get() inout { return _impl; } alias get this; private: Impl _impl; } - Jonathan M Davis Thanks, that is interesting, but is it the same? I don't think that this then provides any encapsulation? The idea is the client gets no access to Impl methods unless I say so and I say so with a using declaration. Then you can introduce more functionality, so it is implementation inheritance. It might not be possible to get the exact same thing, since the RateCurve struct is not really Array!DateValue, it just looks like it with the alias. The closest I can get is to alias each of what is needed and add forwarding functions. So, for example, with this new RateCurve, clients can call insert() but not call clear(). struct RateCurve { alias Array!DateRate ContainerType; alias ContainerType.Range Range; alias _impl this; size_t insert(Stuff)(Stuff stuff) { enforce(_impl.empty || (stuff.when >= _impl.back.when), text("Can not insert items out of order ", _impl.back, " is newer than ", stuff)); return _impl.insert(stuff); } DateRate getRate(Date asOf) { auto needle = DateRate(asOf, 0); if(!_impl.empty) { auto sortedRage = assumeSorted!("a.when <= b.when", Range)(opSlice()); auto lowerBound = sortedRage.lowerBound(needle); if(!lowerBound.empty) { needle = lowerBound.back; } } return needle; } Range opSlice() { return _impl.opSlice(); } this(U)(U[] values...) if (isImplicitlyConvertible!(U, DateRate)) { foreach (value; values) { insert(value); } } private: ContainerType _impl; }
Ignoring defaults from sc.ini?
Is there a way to make dmd ignore the default imports and library search paths inside sc.ini? Currently I have to keep two versions of dmd around, one with a modified sc.ini and one with the original one, which is a bit annoying. A command line option for the compiler to ignore the defaults inside sc.ini would be really great. Kind Regards Benjamin Thaut
Re: Operator overloading through UFCS doesn't work
On Sunday, 14 October 2012 at 07:01:30 UTC, Tommi wrote: Actually, it seems that alias this has precedence over UFCS. So, a free function opUnary wouldn't ever suit better than an actual method opUnary of the thing referred to by that alias this. http://dpaste.dzfl.pl/d0a4431d Free function doesn't suit better than actual method. The issue is absence of the actual method. opUnary method has priority over alias this, which does make sense because alias this is chosen only when it is impossible to apply operation over A type. If this request is approved and compiler has opUnary definition outside type (which suits better then alias this) such function would hijack alias this. If not, there is a new case when something is going special than at usual cases and only for the purpose of writing operator overloading methods outside the body of the type.
Re: Operator overloading through UFCS doesn't work
On Saturday, 13 October 2012 at 19:50:02 UTC, Timon Gehr wrote: On 10/13/2012 06:02 PM, Maxim Fomin wrote: ... Different groups of people have different mind and same things produce different sense on them. From my point of view operator overloading methods are special functions and not treating them as candidates for UFCS does make more sense. I do not understand how an operation that happens to be called '+' is fundamentally different from an operation that is called 'add'. The first one is an operator, which sometimes, may be rewritten to function call, the second one is a function call. Even if you convince in your opinion, language addition without applied purposes makes no benefit. I guess the functionality could be achieved in DMD mostly by removing code. (Code for good error messages excluded!) I don't understand what you are trying to say. Anyway, you can write a pull request and propose it at github. It would be interesting to see reaction of others.
Re: Operator overloading through UFCS doesn't work
On Sunday, 14 October 2012 at 06:22:03 UTC, Maxim Fomin wrote: On Saturday, 13 October 2012 at 17:01:27 UTC, Tommi wrote: Another way to describe my reasoning... According to TDPL, if var is a variable of a user-defined type, then: ++var gets rewritten as: var.opUnary!"++"() Not always. If user-defined type has an alias this to integer member, than something different would happen. Yeah, I wasn't specific enough with that example. It would be also interesting to see, how operation ++T would differ because somebody imported module with opUnary method. Because opUnary suits better than alias this, dmd will issue call to that function, it it see its declaration. Actually, it seems that alias this has precedence over UFCS. So, a free function opUnary wouldn't ever suit better than an actual method opUnary of the thing referred to by that alias this.