Please enable wiki and issues at github
Hi, there has been no objection in this thread[1], that the current D wiki is a burden and should be replaced. The only two proposals were the wiki engine build inside github (gollum[2], free software) and a Mediawiki instance like Haskell. [1] http://forum.dlang.org/thread/k6jak1$quh$1...@digitalmars.com [2] https://github.com/github/gollum I propose to go forward with the gollum proposal and enable the wiki functionality in the d-programming-language.org github project[3]. In addition it might also be a good idea to enable issues in the same project to track website and wiki related issues. [3] https://github.com/D-Programming-Language/d-programming-language.org Github is a proprietary, non-free, cloud service. But it allows you to export all your data. There's the debian package github-backup[5] that one can run by cron to clone all data (wiki, issues) related to a github project. http://packages.qa.debian.org/g/github-backup.html Afterwards I'd kindly ask the current wiki4d[5] maintainer Helmut Leitner to add a static notice to all wiki4d pages pointing to the new wiki. [5] http://www.prowiki.org/wiki4d Do you agree? Regards, Thomas Koch
Re: deprecate deprecated?
On Wednesday, November 07, 2012 08:03:54 monarch_dodra wrote: > On Tuesday, 6 November 2012 at 23:56:13 UTC, Walter Bright wrote: > > I know there's been some long term unhappiness about the > > deprecated attribute - it's all-or-nothing approach, poor > > messages, etc. Each change in it changes the language and the > > compiler. > > I *just* had a conversation about this, but there *needs* to be a > way to to tell the compiler: "don't use deprecated stuff": If it > merely issues a warning, then you'll end up calling deprecated > code, because traits will answer positively to something that is > actually deprecated: > > For example if a range has "deprecated opIndex", and you try a > search on that range, the implementation will take the RA road... > > I had proposed a "three state -d": > -- : Deprecated stuff just can't be used > -d : You can use deprecated stuff, but you get no warning > -dw : You can use deprecated stuff, and are served with a warning It would be better if deprecated stuff warned by default and only errored if you ask it to. The problem is that as it is now, if you mark anything is deprecated, you instantly break all code using it without warning. The only way that anyone can know if you intended for something to be deprecated and get the chance to fix their code before it breaks is if you tell them in the documenation or changelog or whatnot, which doesn't tell them where in their code they're using it, and is frequently going to be outright ignored. Certainly, from Phobos' perspective, the fact that deprecating something makes it so that it doesn't compile is a problem, because it means that as soon as we deprecate something, we break people's code (essentially without warning), and we don't want to do that. So, if we refuse to ever break people's code like that, we can't use deprecated. It would be nice to have a two-tiered approach where something is soft deprecated (and therefore warns) or is hard deprecated (and therefore gives an error), but that's been rejected in the past due to the extra complication that it adds. If we don't want to complicate the feature any further, then flags _could_ be used to control it, but then we'd probably need to make warn the default and have flags for making it an error or be ignored (or maybe even make it impossible to ignore, since it's a warning rather than an error). However, it would be bad if it were treated like a normal warning is and turned into an error with -w, because plenty of folks compile with -w, and so it would then once again become the case that deprecating anything would instantly break code without warning. As such, part of me wants to make it so that deprecated _never_ stops compilation, but you do bring up a good point that there are times that you need to (particularly where conditional compilation is concerned). - Jonathan M Davis
Re: deprecate deprecated?
On Wednesday, 7 November 2012 at 07:03:55 UTC, monarch_dodra wrote: -- : Deprecated stuff just can't be used -d : You can use deprecated stuff, but you get no warning -dw : You can use deprecated stuff, and are served with a warning Or some other default (I don't really care), but there needs to be a switch to say "don't use anything but the bleeding edge valid code". dw seems like a good "default" compromise, and the two others beeing user specified.
Re: deprecate deprecated?
On Tuesday, 6 November 2012 at 23:56:13 UTC, Walter Bright wrote: I know there's been some long term unhappiness about the deprecated attribute - it's all-or-nothing approach, poor messages, etc. Each change in it changes the language and the compiler. I *just* had a conversation about this, but there *needs* to be a way to to tell the compiler: "don't use deprecated stuff": If it merely issues a warning, then you'll end up calling deprecated code, because traits will answer positively to something that is actually deprecated: For example if a range has "deprecated opIndex", and you try a search on that range, the implementation will take the RA road... I had proposed a "three state -d": -- : Deprecated stuff just can't be used -d : You can use deprecated stuff, but you get no warning -dw : You can use deprecated stuff, and are served with a warning
Re: How do you remove/insert elements in a dynamic array without allocating?
On Wednesday, November 07, 2012 04:45:04 Malte Skarupke wrote: > I don't anticipate that I will ever run into a situation where I > want to append to a range without caring about whether it > allocates and copies or not. If I want to append to a range, I > will write the extra line to create a copy manually. > Because of that I don't need the syntactic ambiguity of treating > a range the same as an array. In general, you can't append to ranges. You can chain ranges together with std.range.chain, but appending is not one of the operations that ranges support. That's the sort of thing that you'd do to a container, not a range. Granted, it doesn't help that arrays are containers of sorts in addition to being ranges, but that's abnormal. Normally ranges have no control over whatever is actually holding their data. - Jonathan M Davis
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:34:25 UTC, martin wrote: On Wednesday, 7 November 2012 at 02:06:09 UTC, Rob T wrote: What about the case where we want to pass a source argument either by reference or as a copy depending on the l/r value situation? eg void f( ref a ); void f( a ); --rt I don't get what you mean - that's why the 2 overloads are for (you forgot the const/in keyword - beware! :)) void f( in ref T a ); void f( in T a ); rvalue binds to the latter overload (argument not copied, but moved directly). lvalue binds to the first overload (reference). Works with v2.060. Sorry, my explanation was very poor. I'll try again. I'm trying to describe the case where you want to modify the ref argument so that the source is also changed. For example, let's say you want to move a resource instead of coping it. Moving means the resource is transfered from one object to another, and the original is reset without destoying the resource. That way only one object can have the same resource. So for moving a resource, you cannot use "in ref" or "const ref", you need to just use "ref". void f( ref T a ){ // take resource away from a this.resource = a.resource; a.resetResource(); // this now owns the resource } ref T works fine, but if you wish to use f( ref T a ) on a temp value returned from another function call, you'll need to overload f() to pass by value, which means creating a duplicate. void f( ref T a ){ // take resource away from a this.resource = a.resource; a.resetResource(); // this now owns the resource } Example: T g(){ T temp; // create resource which is stored inside T temp.createResource(); // move temp contents to return value return move(temp); } f( g() ); // won't compile with ref It's annoying to have to create overloaded duplicates for a situation like moving, esp if the duplicate is a lot of code. In C++ the move problem was solved using && move semantics, and this is what I'm trying to emulate in D but I feel like I'm fighting with the language. It is possible that D has a specific way of solving this problem that I'm not aware of yet, so correct me if I'm asking for something that is simply not needed. I tried f( move(g()) ) but that fails to work. My best guess is that D does a hidden move of the temp instead of a copy to value. I can't say for sure because the documentation is not clear and is missing important details like this. I also cannot rely on clever compiler optimizations that may or may not be implemented as a guarantee. --rt
Re: [ ArgumentList ] vs. @( ArgumentList )
On Wednesday, 7 November 2012 at 05:53:35 UTC, Jakob Ovrum wrote: I want to hear what people think about [] at declaration scope and @[] at statement scope. Too complicated to remember? This is quite bad for a variety of reasons, I'll change my vote for purely having @[] then.
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: No hitting below the belt! Let the games begin! I think that [] is sufficiently distinct from built-in attributes, unlike @(), but sadly, there's no nice way to parse it at statement scope. There are in fact a couple of ambiguous cases in the parser already; let's not introduce any more, lest we lose the ability to call D easy to parse. @(foo) looks too similar to built-in attributes. And let's face it; these annotations are actually quite different (I too prefer the more accurate name, 'annotations') from built-in attributes, the former cannot replace the latter any time soon. I want to hear what people think about [] at declaration scope and @[] at statement scope. Too complicated to remember?
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 04:36:59 UTC, Era Scarecrow wrote: Maybe... But when working with non built-in types can you guarantee that behavior? Sure, try it out. What you are referring to here has nothing to do with rvalues. It is about side results which are only sometimes needed. It is clear that you have to use lvalue arguments for those in order to access them after the function call. Using bogus rvalue arguments in case you're not interested in them wouldn't really help - you'd save the variable declaration, but the function signature would still be ugly, and you can't always provide hypothetical default values to hide them (depending on parameter order). In my experience, these cases are very rare anyway (unless dealing with porting old C-style code which you seem to be doing) and function overloading is the most elegant way to handle it - take a look at the large number of overloads in modern language libraries such as .NET. This is how I would implement it: // magical, super-fast function ;) int divide(in int number, in int divisor, int* remainder = null); auto bla = divide(13, 4); // => 3 // remainder needed as well, hiding the pointer as reference: int divide(in int number, in int divisor, out int remainder) { return divide(number, divisor, &remainder); } int remainder; auto bla = divide(13, 4, remainder); // => 3, remainder = 1 // only remainder needed: int modulus(in int number, in int divisor) { int tmp; divide(number, divisor, tmp); return tmp; } auto bla = modulus(13, 4); // => 1 But this is all really off-topic here, let's stop spamming this thread.
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 04:05:32 UTC, martin wrote: int func(in ref int x); int func(int x) { return func(x); } The latter overload is for rvalues (no need to cast to const) and wouldn't be required if the first one took rvalues directly (having a _const_ ref parameter). That's not an example for mutable references though, it's basically a shortcut so as to not having to declare all rvalues for x manually. Maybe... But when working with non built-in types can you guarantee that behavior? //same as 'const ref' basically, unless 'in ref' is accepted struct S //int func(in ref S x); //? int func(const ref S x); int func(S x) { return func(x); } //potentially infinitely self calling compress(output, input, null); compress(output2, input, state); Where's the rvalue? You're talking about an optional mutable reference here, which is only doable via a pointer (references cannot be null, not in C++ and not in D): Perhaps null is wrong in this case, but had it been Zlib.init or Zlib(), then it would still be applicable. Since it's a reference I would think it could accept a null pointer and realize to create a temporary which has it's default values. That would be correct. But you're completely missing the point here. Let's assume you wanted to require a state to be passed: ZlibEnum compress(void[] output, void[] input, ref Zlib state); You could now use: Zlib state; // lvalue compress(output, input, state); but not: compress(output, input, Zlib()); // rvalue And that is most likely a good thing, since your state would be lost after the compress() call. If you don't want it, you don't pass it, and as I said, the only way to do that is to pass a nullable pointer. So this is off-topic I'm afraid. True, but rather than having to create a temporary you don't plan on using just to satisfy the signature, and you know you don't NEED it afterwards, why do you have to go through the extra steps? How many wrappers are made in general just to work around minor issues like this? Quite often we ignore return types if they aren't interesting, but we can't ignore a rvalue we only need for one call (or just to satisfy the signature)? Say we have a divide function (who knows what for), and this is more efficient than normal. So... //perhaps '@ref int remainder = 0'? int divide(int number, int divisor, ref int remainder); Now in this case what if we don't care about the remainder? Create a temporary (or a wrapper function)? //satisfy remainder int divide(int number, int divisor) { int tmp; return divide(number, divisor, tmp); } int modulus(int number, int divisor) { int tmp; divide(number, divisor, tmp); return tmp; } But if we want the result of the division AND the remainder should we have to make a separate modulus function when the original divide can clearly give you the answer? This cuts closer to the instruction set as an example.
Re: One old problem with associative arrays
On Wed, Nov 07, 2012 at 05:08:43AM +0100, bearophile wrote: [...] > So the associative array is updated before taking its length. I > suggest to try to fix this AA behavour before too much D2 code relies > on this. I'd like to avoid this to become a permanent wart of D2. > > My bug report is from February 2010, it's in the most important 20 > bug reports of mine. In my opinion it's wrong to add new features to > D before similar bugs are fixed: > > http://d.puremagic.com/issues/show_bug.cgi?id=3825 [...] I'd love to fix AA's once for all. The problem is that right now the AA code is scattered all over the compiler, and even within druntime it's a schizophrenic mosaic of half-duplicated code, partly in aaA.d and partly in object_.d. It's a major undertaking even just to refactor this code in a sane way. Would you like to help in this effort? ;-) I tried to do it myself some time ago, and I did get as far as a struct that works pretty much like the built-in AA's with quite a good number of current issues fixed, but it got stuck with handling const, pure, IFTI bugs, and a number of related issues. Frankly, at this point I believe that it's going to take more than one person to do it. We need a team of about 2-3 to tackle different aspects of it so that we can clean up the whole thing properly. My code is already up on github, but so far it seems that no one has been interested to contribute yet. I do agree that cleaning up AA's should be quite an important item in D2. There are quite a lot of IMO serious problems with the current implementation. But it ain't gonna happen unless more people help. T -- Meat: euphemism for dead animal. -- Flora
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 03:35:19 UTC, Era Scarecrow wrote: Still that zlib entry is coming to mind. But more importantly is that you still need code duplication to get both accessible. //many possible combinations thereof int func(const ref x); int func(int x) { return func(cast(const int) x); } int func(in ref int x); int func(int x) { return func(x); } The latter overload is for rvalues (no need to cast to const) and wouldn't be required if the first one took rvalues directly (having a _const_ ref parameter). That's not an example for mutable references though, it's basically a shortcut so as to not having to declare all rvalues for x manually. enum ZlibEnum {} ZlibEnum compress(void[] output, void[] input, &ref Zlib state) nothrow pure; string input = "something long"; ubyte[1000] output; ubyte[5] output2; Zlib state; compress(output, input, null); compress(output2, input, state); Where's the rvalue? You're talking about an optional mutable reference here, which is only doable via a pointer (references cannot be null, not in C++ and not in D): ZlibEnum compress(void[] output, void[] input, Zlib* state = null); ... compress(output, input); compress(output2, input, &state); That would be correct. But you're completely missing the point here. Let's assume you wanted to require a state to be passed: ZlibEnum compress(void[] output, void[] input, ref Zlib state); You could now use: Zlib state; // lvalue compress(output, input, state); but not: compress(output, input, Zlib()); // rvalue And that is most likely a good thing, since your state would be lost after the compress() call. If you don't want it, you don't pass it, and as I said, the only way to do that is to pass a nullable pointer. So this is off-topic I'm afraid.
One old problem with associative arrays
import std.stdio; void main() { int[] a; int[int] aa; a ~= a.length; aa[10] = aa.length; writeln(a, " ", aa); a ~= a.length; aa[20] = aa.length; writeln(a, " ", aa); } It prints: [0] [10:1] [0, 1] [20:2, 10:1] So the associative array is updated before taking its length. I suggest to try to fix this AA behavour before too much D2 code relies on this. I'd like to avoid this to become a permanent wart of D2. My bug report is from February 2010, it's in the most important 20 bug reports of mine. In my opinion it's wrong to add new features to D before similar bugs are fixed: http://d.puremagic.com/issues/show_bug.cgi?id=3825 Thank you, bye, bearophile
Re: How do you remove/insert elements in a dynamic array without allocating?
On Tuesday, 6 November 2012 at 09:10:08 UTC, bearophile wrote: Malte Skarupke: I will most certainly never use dynamic arrays or slices again for anything that needs to grow or shrink dynamically. And doing so you will miss an important and handy part of D :-/ Bye, bearophile I implemented my own DynamicArray struct which behaves more like I want it to and is still giving me all of the benefits that I want from dynamic arrays. Having no clear ownership for the array is not something I am willing to accept. Same thing for the non-deterministic copying and destruction behavior for the elements. That's the kind of thing which looks convenient at first, but will create many small performance problems. Once those add up to a big problem, it's incredibly frustrating to fix because your slow downs are from all over the place. I don't anticipate that I will ever run into a situation where I want to append to a range without caring about whether it allocates and copies or not. If I want to append to a range, I will write the extra line to create a copy manually. Because of that I don't need the syntactic ambiguity of treating a range the same as an array.
Re: deprecate deprecated?
On 11/6/2012 6:55 PM, Andrei Alexandrescu wrote: I don't think that's possible. One would need a mechanism to hook into all calls to a function (adorned with a specific attribute) and emit the message during compilation. That is missing. It would be interesting to see where those pain points are, and whether a general "hook" mechanism for user plugins would be a good idea.
Re: deprecate deprecated?
On 11/6/2012 5:12 PM, Jonathan M Davis wrote: And how would this interact with -d? It's one thing to give symbols attributes which can be examined at compile time. It's quite another to make it so that they don't compile without a specific compiler flag. The -version flag can be used to turn things on and off in user code. I also don't really get what we gain from this. The only thing that I'm aware of which is really up for debate at this point is whether deprecated should result in an error or a warning. We even have messages for it now. The gain is in reducing the demand for constant language changes. It's similar to the ability to now do GC introspection entirely in the library, rather than changing the compiler. Adding custom attributes which somehow indicate "scheduled for deprecation" or something like that might make sense, but what is beneficial abou removing deprecated itself from the language? How could that even work given that deprecated does more than simply tag the symbol with information? I didn't say remove it. I said deprecate it.
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 03:13:22 UTC, martin wrote: void func1(ref int x); //D lvalue-only ref void func2(@ref int x); //works like c++'s ref Seems fairly easy to tell apart, and still leaves const-ness as an option. Afaik C++ doesn't allow rvalues to be passed to _mutable_ references (T&), only to const references, making perfect sense imo. I really do not see the point for an additional syntax for C++-like const references (const T&) which would also take rvalues. Please give me an example where you want to pass an rvalue to a _mutable_ reference parameter. I would simply continue to disallow that, since that would mean that changes to the referenced rvalue would not be visible for the caller (a temporary/literal is changed - how could someone possibly want that?). Still that zlib entry is coming to mind. But more importantly is that you still need code duplication to get both accessible. //many possible combinations thereof int func(const ref x); int func(int x) { return func(cast(const int) x); } But regarding zlib.. It's function is something like: int compress(char *output, int *size, char *input, int inputSize); So... if we convert that to something similar we get.. enum ZlibEnum {} ZlibEnum compress(void[] output, void[] input, &ref Zlib state) nothrow pure; The idea in this case is 'state' would continue to hold the input/output pointers and all information needed, so you could continue to use it and if it has any 'unflushed' data (output size too small?) then it could retain that. however if you knew you didn't need it you could ignore it. ZlibEnum could be for output C calling code, so success/failure needs to be known right away. It makes sense for it to return a Zlib type as well, but depends on what has higher priority and why. string input = "something long"; ubyte[1000] output; ubyte[5] output2; Zlib state; compress(output, input, null); //we know the buffer is large enough compress(output2, input, state);
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 03:13:22 UTC, martin wrote: void func1(ref int x); //D lvalue-only ref void func2(@ref int x); //works like c++'s ref Seems fairly easy to tell apart, and still leaves const-ness as an option. Afaik C++ doesn't allow rvalues to be passed to _mutable_ references (T&), only to const references, making perfect sense imo. I really do not see the point for an additional syntax for C++-like const references (const T&) which would also take rvalues. Please give me an example where you want to pass an rvalue to a _mutable_ reference parameter. I would simply continue to disallow that, since that would mean that changes to the referenced rvalue would not be visible for the caller (a temporary/literal is changed - how could someone possibly want that?). Still that zlib entry is coming to mind. But more importantly is that you still need code duplication to get both accessible. //many possible combinations thereof int func(const ref x); int func(int x) { return func(cast(const int) x); } But regarding zlib.. It's function is something like: int compress(char *output, int *size, char *input, int inputSize); So... if we convert that to something similar we get.. enum ZlibEnum {} ZlibEnum compress(void[] output, void[] input, &ref Zlib state) nothrow pure; The idea in this case is 'state' would continue to hold the input/output pointers and all information needed, so you could continue to use it and if it has any 'unflushed' data (output size too small?) then it could retain that. however if you knew you didn't need it you could ignore it. ZlibEnum could be for output C calling code, so success/failure needs to be known right away. It makes sense for it to return a Zlib type as well, but depends on what has higher priority and why. string input = "something long"; ubyte[1000] output; ubyte[5] output2; Zlib state; compress(output, input, null); //we know the buffer is large enough compress(output, input, state);
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:58:57 UTC, Era Scarecrow wrote: Maybe a very simple change/addition; Like perhaps @ref? (Attribute ref, Alternate ref, auto ref.. All sorta fit for it's meaning). So... void func1(ref int x); //D lvalue-only ref void func2(@ref int x); //works like c++'s ref Seems fairly easy to tell apart, and still leaves const-ness as an option. Afaik C++ doesn't allow rvalues to be passed to _mutable_ references (T&), only to const references, making perfect sense imo. I really do not see the point for an additional syntax for C++-like const references (const T&) which would also take rvalues. Please give me an example where you want to pass an rvalue to a _mutable_ reference parameter. I would simply continue to disallow that, since that would mean that changes to the referenced rvalue would not be visible for the caller (a temporary/literal is changed - how could someone possibly want that?).
Re: deprecate deprecated?
On 11/7/12 1:56 AM, Walter Bright wrote: I know there's been some long term unhappiness about the deprecated attribute - it's all-or-nothing approach, poor messages, etc. Each change in it changes the language and the compiler. Perhaps it could be done with a user defined attribute instead? Anyone want to take on the challenge? I don't think that's possible. One would need a mechanism to hook into all calls to a function (adorned with a specific attribute) and emit the message during compilation. That is missing. Andrei
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:45:15 UTC, martin wrote: Please discard option 1, I'm afraid it creates too much confusion and was not well thought through. The objective was to expand 'auto ref T' to either 'in ref T' for lvalues or 'in T' for rvalues (I.e., only for const parameters!), but then its caption would be horribly misleading (and something like 'in auto ref' would be way too ambiguous). Maybe a very simple change/addition; Like perhaps @ref? (Attribute ref, Alternate ref, auto ref.. All sorta fit for it's meaning). So... void func1(ref int x); //D lvalue-only ref void func2(@ref int x); //works like c++'s ref Seems fairly easy to tell apart, and still leaves const-ness as an option.
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/7/12 2:27 AM, kraybourne wrote: @(Attr...) and @attr1 @attr2 Because I secretly dream about stuff like: alias @(nothrow,safe,memoizable) @memosafe; Sure you mean alias @memosafe = @(nothrow,safe,memoizable); Andrei
Re: deprecate deprecated?
Walter Bright: Perhaps it could be done with a user defined attribute instead? Maybe we need more ways to better attach some semantics to UDAs :-) Bye, bearophile
Re: Const ref and rvalues again...
On Tuesday, 6 November 2012 at 23:37:25 UTC, martin wrote: 1) The previously described auto-templates (identical 'auto ref' semantics), where a function with 'auto ref' parameters is treated as implicit template. This may lead to code-bloating (for larger functions) and/or higher performance for rvalue arguments (rvalues passed to value arguments are moved, not copied; we therefore gain nothing by passing a reference, but incur a slight performance hit due to pointer indirection instead of accessing directly the rvalue on the stack). OR 2) Simple under-the-hood temporary lvalue declaration by the compiler (for rvalues passed to 'const ref' parameters) - that would be a handy implementation of the first workaround. Please discard option 1, I'm afraid it creates too much confusion and was not well thought through. The objective was to expand 'auto ref T' to either 'in ref T' for lvalues or 'in T' for rvalues (i.e., only for const parameters!), but then its caption would be horribly misleading (and something like 'in auto ref' would be way too ambiguous).
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:06:09 UTC, Rob T wrote: What about the case where we want to pass a source argument either by reference or as a copy depending on the l/r value situation? eg void f( ref a ); void f( a ); --rt I don't get what you mean - that's why the 2 overloads are for (you forgot the const/in keyword - beware! :)) void f( in ref T a ); void f( in T a ); rvalue binds to the latter overload (argument not copied, but moved directly). lvalue binds to the first overload (reference). Works with v2.060.
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 01:33:49 UTC, Jonathan M Davis wrote: The most recent discussion where Walter and Andrei were part of the discussion was here: http://forum.dlang.org/post/4f84d6dd.5090...@digitalmars.com That thread is quite misleading and, I'm sad to say, not very useful (rather damaging to this discussion) in my opinion - especially because the distinction between rvalue => 'const ref' and rvalue => ref is largely neglected, and that distinction is of extremely high importance, I can't stress that enough. Walter's 3 C++ examples (2 of them invalid anyway afaik) don't relate to _const_ references. The implicit type conversion problem in that thread isn't a problem for _const_ references, just to point out one tiny aspect. rvalue => ref/out propagation makes no sense imho, as does treating literals as lvalues (proposed by Walter iirc). The current 'auto ref' semantics also fail to cover the special role of _const_ references for rvalues (also illustrated by Scarecrow's post). Certainly, it's not a simple matter of just making const ref work with rvalues like most of the people coming from C++ want and expect. Well I absolutely do _not_ share this point of view. It just seems so logical to me. I'm still waiting for a plausible argument to prove me wrong. All the required info is in this thread, e.g., we covered the escaping issue you mentioned.
Re: Const ref and rvalues again...
On Tuesday, 6 November 2012 at 23:37:25 UTC, martin wrote: void func(T)(in auto ref T m); This template, as I understand it, gets expanded to: void func(T)(in ref T m); // for lvalues void func(T)(in T m); // for rvalues So for non-templated functions, I suggest 2 options: 1) The previously described auto-templates (identical 'auto ref' semantics), where a function with 'auto ref' parameters is treated as implicit template. This may lead to code-bloating (for larger functions) and/or higher performance for rvalue arguments (rvalues passed to value arguments are moved, not copied; we therefore gain nothing by passing a reference, but incur a slight performance hit due to pointer indirection instead of accessing directly the rvalue on the stack). OR 2) Simple under-the-hood temporary lvalue declaration by the compiler (for rvalues passed to 'const ref' parameters) - that would be a handy implementation of the first workaround. I hope you get my point. :) What about the case where we want to pass a source argument either by reference or as a copy depending on the l/r value situation? eg void f( ref a ); void f( a ); --rt
Re: Simple implementation of __FUNCTION
On Tuesday, 6 November 2012 at 07:46:47 UTC, Don Clugston wrote: It fails because you're asking for the full function name, before its type has been determined. (There's no real return type 'auto', 'auto' just means 'work it out for me'). In our case, the function name that is returned is nothing but the function's symbol name by itself, which of course is known ahead of time no matter if auto is stated or not. This is why it seems more like a bug to me. --rt
Re: std.signals2 proposal
On 11/06/2012 04:10 AM, Robert Klotzner wrote: Not sure I understand why such hatred is rational? nvm in emit: if(slot.indirect.ptr) { }else{ slot.indirect.ptr = slot.indirect(i); } will not be executed more than once? is: "slot.indirect(cast(void*)(objs[index]), i);" and gets executed for every slot. I am not sure I understand your question. // slot[i].indirect.ptr == null thing.emit(params); // slot[i].indirect.ptr != null thing.emit(params); well yes, because every class derives from Object. But the requirement I need is that T2 is derived from Object, so it makes the intent more clear. IsExpression rarely does what you want it to, especially with that colon. I have come across many such IsExpression usages. Off the top of my head in your case: is(shared(Object) : Object); is(const(Object) : Object); is(immutable(Object) : Object); is(AnyInterface : Object); std.traits.BaseTypeTuple might be the way to go if you want clarity. Also, this brings us to the spectre of const correctness, which I will drop just as quickly (but keep it in mind - phobos already has too much code that isn't const correct) -> No I should not, at least in the current implementation this would be wrong. I did not yet made up my mind how I want to implement it in the end, so I left it for now. Ah. Well, do something so I stop double-taking every time I see objs[slot_idx-1] or somesuch. That you can not pass some arbitrary slot like: Ok, I'm starting to see what you're doing here. I knew this was coming. Well I haven't done anything with closures yet, the usage is an escaping of a reference so the compiler should allocate it on the heap, if not than you got a problem, but its not specific to signals -> So I still consider the signal API safe ;-) Heh. Perhaps trusted is a more apt description. Also I did not really get the point why a mixin was used in the first place, it does not really gain us anything? What was the reasoning about it? So you can do b.connect in the simplest case? Yes, that's the only reason that comes to mind. I personally think that a struct is a cleaner solution, that also avoids cluttering the containing objects namespace. I think you're right.
Re: Slicing static arrays should be @system
On Wednesday, November 07, 2012 12:44:26 Daniel Murphy wrote: > Slicing static arrays on the stack is equivalent to taking the address of a > local variable, which is already illegal in SafeD. Which is what I'm arguing, but a number of people seem to really not like the idea of making slicing static arrays on the stack @system even though it _is_ the same thing as taking the address of a local variable, which is @system. - Jonathan M Davis
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 01:15:27 UTC, martin wrote: I simply and utterly fail to comprehend the need for a compiler to distinguish between a const reference to a named variable and a const reference to an unnamed temporary/literal (which the compiler is free to allocate wherever it makes most sense). Let me be more precise: I don't see why a called function would need to know whether a passed const reference is named or unnamed at the caller's site. The developer's reasoning for a const reference is simply to avoid costly copying of the argument to be passed (only applicable for lvalues) which is guaranteed not to be modified by the callee. Decorating such a parameter with 'const ref' seems as logical as it gets (don't pass me a copy of the real thing, pass me a reference instead - I'm not going to modify it). The only reason I can think of to distinguish between lvalues and rvalues at the callee is the slight performance hit due to pointer indirection for rvalues. And that would be addressable by preferring by-value-passing of rvalues when selecting between function overloads.
Re: Slicing static arrays should be @system
"Jonathan M Davis" wrote in message news:mailman.1518.1352007101.5162.digitalmar...@puremagic.com... >I just thought that I should bring greater attention to > > http://d.puremagic.com/issues/show_bug.cgi?id=8838 > > As it stands, I think that the slicing static arrays being considered > @safe is > a major hole in SafeD's safety, and I think that it's one that many of us > aren't aware of. But there seems to be some resistance to outright making > the > slicing of static arrays @system within that bug report, and I recall > similar > resistance in the thread that prompted that bug report (unfortunately, I > don't > remember what thread it was - somewhere in D.Learn I think). > Slicing static arrays on the stack is equivalent to taking the address of a local variable, which is already illegal in SafeD.
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 00:32:04 UTC, martin wrote: So we do not really need 'auto ref' for non-templated functions or a new, even more confusing keyword which you, Jonathan, seem to insist on - 'const ref' (or, more elegantly 'in ref') is all we need. We simply want the compiler to automatically declare rvalues passed to 'const ref' parameters as local lvalues - problem solved for the majority of cases. For the remaining few which care about the involved cost for rvalue arguments, allow them to provide a function overload for rvalues (either manually or via 'auto ref' templates) - problem solved completely in my point of view. And that is actually exactly what the thread starter Malte proposes (and I already pointed that out in an earlier post). 'in ref' may work, but what it implies doesn't quite make sense. 'auto ref' already being used for templates should be able to carry over to functions, however auto in the same section along with type declaration may seem a little confusing. Let's glance at a few of how they would be called. //either void func(int x); void func(const int x); //lvalue void func(ref int x); void func(const ref int x); //either? auto ref/in ref void func(auto ref int x); void func(const auto ref int x); void func(in ref int x); Assuming auto can't be used to do type referencing the 'const auto ref int' seems rather long. alternatively perhaps inout? (accepts any type, partially skewed?) void func(inout ref int x); void func(const inout ref int x); At this point for const it's just as large as the const auto ref.. So.. void func(inout ref int x); //mutable void func(in ref int x);//const version void func(out ref int x); //optional write-only variable 'out ref int x' could then be legal.. Somehow reminds me of zlib's compress utility function that returns how many bytes the output buffer used but sometimes you didn't care. So.. if we defined and used... void func(out ref int x) { x = 100; } int x; func(x); assert(x == 100); func(0);//0 and null (and legal) basically ignored. func(null);
Re: Const ref and rvalues again...
On Wednesday, November 07, 2012 02:15:26 martin wrote: > Wow, now this finally sheds some light on this topic. Do you have > any links regarding their reasoning? The most recent discussion where Walter and Andrei were part of the discussion was here: http://forum.dlang.org/post/4f84d6dd.5090...@digitalmars.com A key component of the problem is that conversions cause problems. Also, IIRC allowing const ref to take rvalues causes some issues with overloading. Making some changes to ref with regards to escaping apparently could change the situation a bit, and there's even some discussion in there of allowing ref to take rvalues if certain other things in the language are changed, but it's all up in the air at this point. Certainly, it's not a simple matter of just making const ref work with rvalues like most of the people coming from C++ want and expect. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/07/12 00:21, Jonathan M Davis wrote: > On Tuesday, November 06, 2012 22:53:36 Artur Skawina wrote: >> On 11/06/12 22:02, Jonathan M Davis wrote: >>> On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: No hitting below the belt! Let the games begin! >>> >>> Definitely @(ArgumentList). It fits with what other languages do, and it >>> matches what we're already doing for attributes. I also think that's what >>> pretty much everyone was figuring would be used for user-defined >>> attributes. The only major problem would be if @ArgumentList is allowed >>> when there's only a single argument, then code could break when new >>> built-in attributes are added. >> Easy - do not introduce any new *global* built-in attributes, ever. There's >> no reason why they all can't use the same look-up rules. > > That's not really acceptable IMHO. Not being able to add new attributes to > the > language itself in the future is way too restrictive, and I expect that we'll > come up with more that we want to add eventually. Designing custom attributes > in a way that is guaranteed to conflict with that is a bad idea. We're > restricting ourselves and causing problems for ourselves later when we could > easily avoid doing so. What I'm saying is that any new "built-in" attributes (and there *will* be many of these) can have their own namespace. Yeah, it could make the code a little more verbose, but it makes several problems go away. Eg import attr = core.attr; // Could be implicit, ie in object.d. int f() @[attr.pure, attr.deprecated("Use something else"), attr.inline] {return 42;} I said @attr.pure, but migrating the existing built-ins is not worth the cost, at least not until other language changes happen. The above is too verbose? Then int f() @attr[pure, deprecated("Use something else"), inline] {return 42;} is possible (which works just as the above - looks for the named attributes in the "attr" scope). Almost as terse as the current approach, but more powerful. And not as bad as context sensitive keywords (which would be another way to reduce collisions with other user-defined identifiers w/o resorting to pragmas, strings, etc). artur
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 00:47:04 UTC, Jonathan M Davis wrote: No, because that would be doing the same thing as C++, which Walter and Andrei have already rejected. They specifically do _not_ want there to be any ambiguity between whether a const ref variable is an lvalue or rvalue. If they were willing to make const ref work the same as C++'s const&, then we would never have had this problem in the first place. We specifically need something other than const ref. The const ref can continue to work as it does now, but we'll have a way to get semantics similar to C++'s const& when we want them. Wow, now this finally sheds some light on this topic. Do you have any links regarding their reasoning? I simply and utterly fail to comprehend the need for a compiler to distinguish between a const reference to a named variable and a const reference to an unnamed temporary/literal (which the compiler is free to allocate wherever it makes most sense). Especially since the compiler could simply allocate and name the original rvalue as local variable on the caller's stack before the function call and hence transform it automatically to an lvalue, i.e., do that, what currently most of us have to painfully do by hand.
Re: [ ArgumentList ] vs. @( ArgumentList )
On Wednesday, November 07, 2012 02:07:53 deadalnix wrote: > As you stated, this is true for ANY identifier, so I don't see why this > pop in this particular discussion. Because it sucks, and being able to avoid having that problem spread is a good thing. Just because something is a problem in one place doesn't mean that it's okay to have that same problem somewhere else. - Jonathan M Davis
Re: deprecate deprecated?
On Tuesday, November 06, 2012 15:56:09 Walter Bright wrote: > I know there's been some long term unhappiness about the deprecated > attribute - it's all-or-nothing approach, poor messages, etc. Each change > in it changes the language and the compiler. > > Perhaps it could be done with a user defined attribute instead? > > Anyone want to take on the challenge? And how would this interact with -d? It's one thing to give symbols attributes which can be examined at compile time. It's quite another to make it so that they don't compile without a specific compiler flag. I also don't really get what we gain from this. The only thing that I'm aware of which is really up for debate at this point is whether deprecated should result in an error or a warning. We even have messages for it now. Adding custom attributes which somehow indicate "scheduled for deprecation" or something like that might make sense, but what is beneficial abou removing deprecated itself from the language? How could that even work given that deprecated does more than simply tag the symbol with information? - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 07/11/2012 00:29, Jonathan M Davis a écrit : On Tuesday, November 06, 2012 23:26:28 deadalnix wrote: Le 06/11/2012 22:53, Walter Bright a écrit : On 11/6/2012 1:41 PM, deadalnix wrote: Le 06/11/2012 22:02, Jonathan M Davis a écrit : On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: No hitting below the belt! Let the games begin! Definitely @(ArgumentList). It fits with what other languages do, and it matches what we're already doing for attributes. I also think that's what pretty much everyone was figuring would be used for user-defined attributes. The only major problem would be if @ArgumentList is allowed when there's only a single argument, then code could break when new built-in attributes are added. Can you explain that code breakage ? C++11 has had problems adding new keywords, as about every identifier somewhere has been used by someone's C++ source code, and they don't want to break existing code. So C++11 winds up with awful things like "decltype". OK I understand. This is fixable easily by adding thoses magic attribute in object and using regular lookup rules. It would still break code, because then there would be a conflict which would have to be resolved. It's the same as if we were to do something like add a function to std.file called find. Anything importing both std.algorithm and std.file would break (assuming that the arguments matched both). To some extent, this is unavoidable. Adding _any_ function to a library risks breaking user code if there's any other function that it uses which has the same name and similar enough arguments. That's what we get for automatically inferring which function and requiring the full path for disambiguation rather than requiring the full path unless a specific command makes it so that it's unnecessary (e.g. aliasing std.algorithm.find to find). So, if we want to avoid breaking code when adding new built-in attributes, we're going to have to define custom attributes in a way which they can't ever conflict with built-in ones - which would probably mean making @customAttribute illegal and require @(customAttribute). But if we're willing to break user code when adding a new attribute, forcing user code to change its attribute names or give their full path, then we can allow @customAttribute. - Jonathan M Davis As you stated, this is true for ANY identifier, so I don't see why this pop in this particular discussion.
Re: deprecate deprecated?
Le 07/11/2012 00:56, Walter Bright a écrit : I know there's been some long term unhappiness about the deprecated attribute - it's all-or-nothing approach, poor messages, etc. Each change in it changes the language and the compiler. Perhaps it could be done with a user defined attribute instead? Anyone want to take on the challenge? That sound like a perfect use case for attribute.
Re: [ ArgumentList ] vs. @( ArgumentList )
On Wednesday, November 07, 2012 00:58:47 Andrej Mitrovic wrote: > Actually, let me give you a better argument. > > Let's say you implement your own @(NoGC) attribute that you use in > your own library. You use it like so: > > @(NoGC) class Foo { } > > And somewhere down the road 5 months from now druntime introduces it's > own @NoGC attribute. Personally I would rather have a compile-time > error due to clashing symbol names right then and there. Otherwise I > could easily end up in a situation where I **forget** to parenthesize > my custom NoGC attribute and end up using the druntime one: That seems like a pretty good argument. - Jonathan M Davis
Re: Const ref and rvalues again...
On Wednesday, November 07, 2012 01:32:03 martin wrote: > So we do not really need 'auto ref' for non-templated functions > or a new, even more confusing keyword which you, Jonathan, seem > to insist on - 'const ref' (or, more elegantly 'in ref') is all > we need. No, because that would be doing the same thing as C++, which Walter and Andrei have already rejected. They specifically do _not_ want there to be any ambiguity between whether a const ref variable is an lvalue or rvalue. If they were willing to make const ref work the same as C++'s const&, then we would never have had this problem in the first place. We specifically need something other than const ref. The const ref can continue to work as it does now, but we'll have a way to get semantics similar to C++'s const& when we want them. - Jonathan M Davis
Re: Const ref and rvalues again...
Thanks Jonathan for the detailed info. So 'auto ref' is implemented the way I thought, by simply duplicating functions. That is actually the only way (I can think of) to solve your problem 'pass this argument in the most efficient way possible (do not copy)'. But that is not the only problem. More commonly, we want to avoid copying lvalues for read-only parameters and therefore pass by reference. At the same time, we want to use the same function for rvalues - we simply can't stand having to declare temporaries manually or having to overload functions! Since the parameter is read-only, we couldn't care less if the argument is actually an lvalue or an rvalue. The only thing is that a dedicated function overload for rvalues would be slightly more efficient (for rvalues only) since the rvalue would be accessed directly on the stack instead of having to access it indirectly via its reference. This problem here would be 'pass this argument as read-only in the most efficient way possible for lvalues (do not copy) but also allow rvalues at a slight cost (compared to a dedicated function overload)'. So we do not really need 'auto ref' for non-templated functions or a new, even more confusing keyword which you, Jonathan, seem to insist on - 'const ref' (or, more elegantly 'in ref') is all we need. We simply want the compiler to automatically declare rvalues passed to 'const ref' parameters as local lvalues - problem solved for the majority of cases. For the remaining few which care about the involved cost for rvalue arguments, allow them to provide a function overload for rvalues (either manually or via 'auto ref' templates) - problem solved completely in my point of view. And that is actually exactly what the thread starter Malte proposes (and I already pointed that out in an earlier post). Again hoping to be clear enough. :)
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 19:47:57 UTC, Manu wrote: I actually quite liked Tristan's argument. [attr, attr2] feels more like what it is, an annotation. It does nothing, has no effect on the declaration on its own. the @attr syntax looks like existing attributes, and with that kinda comes the presumption that they actually DO something, affect the code generated in some way. For that reason, I buy the argument that [attrs...] being visually distinct makes more sense, more like what it is. Perhaps it should be termed 'annotation' rather than 'attribute'? On 6 November 2012 21:38, ponce wrote: I like @(ArgumentList) better for stated reason: it looks like existing @attributes. If you want, you can take some history into consideration. This DIP is the reason for the @property/@safe syntax http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP6 Maybe not that specific page, but it comes from the big annotation discussions.
Re: [ ArgumentList ] vs. @( ArgumentList )
@(Attr...) and @attr1 @attr2 Because I secretly dream about stuff like: alias @(nothrow,safe,memoizable) @memosafe; @memosafe int foo(){...}
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 23:23:47 UTC, Jonathan M Davis wrote: Designing custom attributes in a way that is guaranteed to conflict with that is a bad idea. Well, the same could be said about language keywords as well, or really just adding names in general. I don't see a good reason why special contortions for user defined annotations should be required, if simply adding a name to Phobos (even a private one!) can have just the same effect. David
Re: deprecate deprecated?
On 07-11-2012 00:56, Walter Bright wrote: I know there's been some long term unhappiness about the deprecated attribute - it's all-or-nothing approach, poor messages, etc. Each change in it changes the language and the compiler. Perhaps it could be done with a user defined attribute instead? Anyone want to take on the challenge? Just fix the compiler behavior. https://github.com/D-Programming-Language/phobos/pull/904#issuecomment-10038838 -- Alex Rønne Petersen a...@lycus.org http://lycus.org
deprecate deprecated?
I know there's been some long term unhappiness about the deprecated attribute - it's all-or-nothing approach, poor messages, etc. Each change in it changes the language and the compiler. Perhaps it could be done with a user defined attribute instead? Anyone want to take on the challenge?
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/7/12, Andrej Mitrovic wrote: > On 11/7/12, Jonathan M Davis wrote: >> It would still break code, because then there would be a conflict which >> would have to be resolved. > > I really doubt we're going to create any new language properties > (you're the only one I can see suggesting this). And if we are, we > should use special identifiers that begin with underscores. In any > case, we can always use an alias to resolve conflicts. > Actually, let me give you a better argument. Let's say you implement your own @(NoGC) attribute that you use in your own library. You use it like so: @(NoGC) class Foo { } And somewhere down the road 5 months from now druntime introduces it's own @NoGC attribute. Personally I would rather have a compile-time error due to clashing symbol names right then and there. Otherwise I could easily end up in a situation where I **forget** to parenthesize my custom NoGC attribute and end up using the druntime one: @(NoGC) class Foo { } @NoGC class Bar { } // oops, I meant @(NoGC) I really don't think we should have parenthesis dictate name lookup, it's way too easy to screw things up like that. Let the symbols clash so I can fix the problem with the already existing alias tools in D: alias mymod.NoGC MyNoGC; @(MyNoGC) class Foo { } @MyNoGC class Bar { } or simply: @(mymod.NoGC) class Foo { } @mymod.NoGC class Bar { } Then I can be at ease knowing I'm not accidentally using one attribute or the other because of an issue with missing parens.
Re: Const ref and rvalues again...
If the compiler started generating 2 copies of all my ref functions, I'd be rather unimpressed... bloat is already a problem in D. Perhaps this may be a handy feature, but I wouldn't call this a 'solution' to this issue. Also, what if the function is external (likely)... auto ref can't work if the function is external, an implicit temporary is required in that case. On 7 November 2012 01:37, martin wrote: > On Tuesday, 6 November 2012 at 22:32:57 UTC, Manu wrote: > >> But it only really makes sense in the context of templates...? >> Why should something called 'auto ref' provide fabrication of temporaries >> for the purpose of passing rvalues to functions that receive ref args? >> >> How does auto ref (under some different definition/implementation) address >> the rvalue problem? >> > > The thing is that currently there are 2 workarounds. You described the > first one - allocating temporaries manually to obtain referenceable lvalues: > > > void func(ref in Vector m); > Vector v1v2PlusSomeStuff = v1*v2 + Vector(10, 20, 30); > func(v1v2PlusSomeStuff); > > The other, also painfully annoying workaround is overloading func: > > void func(in ref Vector m); > void func(in Vector m); > > func(v1*v2 + Vector(10, 20, 30)); > > 'auto ref' implements the second workaround (via a template) and therefore > requires a single, but templated func() implementation: > > void func(T)(in auto ref T m); > > This template, as I understand it, gets expanded to: > > void func(T)(in ref T m); // for lvalues > void func(T)(in T m); // for rvalues > > So for non-templated functions, I suggest 2 options: > > 1) The previously described auto-templates (identical 'auto ref' > semantics), where a function with 'auto ref' parameters is treated as > implicit template. This may lead to code-bloating (for larger functions) > and/or higher performance for rvalue arguments (rvalues passed to value > arguments are moved, not copied; we therefore gain nothing by passing a > reference, but incur a slight performance hit due to pointer indirection > instead of accessing directly the rvalue on the stack). OR > 2) Simple under-the-hood temporary lvalue declaration by the compiler (for > rvalues passed to 'const ref' parameters) - that would be a handy > implementation of the first workaround. > > I hope you get my point. :) >
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/7/12, Jonathan M Davis wrote: > It would still break code, because then there would be a conflict which > would have to be resolved. I really doubt we're going to create any new language properties (you're the only one I can see suggesting this). And if we are, we should use special identifiers that begin with underscores. In any case, we can always use an alias to resolve conflicts.
Re: Const ref and rvalues again...
On Wednesday, November 07, 2012 00:32:48 Manu wrote: > But it only really makes sense in the context of templates...? > Why should something called 'auto ref' provide fabrication of temporaries > for the purpose of passing rvalues to functions that receive ref args? > > How does auto ref (under some different definition/implementation) address > the rvalue problem? The idea behind auto ref was to create a function which would take its argument in the most efficient way possible, whatever that was (be it ref or by value), and that the compiler would figure that out. That way, the function wouldn't care whether it was given an rvalue or lvalue or a value type or reference type or whatever. What actually got implemented was simply duplicating functions with auto ref so that there's a ref version of lvalues and non-ref versions for rvalues, which really doesn't do the job and only works with templates. What we need is an attribute which indicates that you don't care whether the argument is an lvalue or rvalue. You just don't want it to be copied, and you don't want the function to mutate it - which is what const& in C++ is normally used for. Whether auto ref is the attribute used for that is more or less irrelevant except for the fact that that's the problem that it was trying to solve in the first place. Making auto ref do that for non-templated functions would solve the problem for non-templated functions but would mean that auto ref on parameters in templated functions and non-templated functions would have different (albeit similar) semantics, which would be a bit of problem and may or may not be acceptable. And I'd have to think it through more to say whether or not auto ref as it is on templated functions really solves the problem well enough for templated functions or not. If it does, then it may be acceptable to just have auto ref on non-templated functions with slightly different semantics. If it doesn't, then we either need to change what auto ref does with templated functions to match what we want for non-templated ones (which could be a problem, since some people have found the current semantics of auto ref useful for other stuff like propagating attributes), or we'd need to use a new attribute rather than auto ref. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 07/11/2012 00:21, Jonathan M Davis a écrit : On Tuesday, November 06, 2012 22:53:36 Artur Skawina wrote: On 11/06/12 22:02, Jonathan M Davis wrote: On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: No hitting below the belt! Let the games begin! Definitely @(ArgumentList). It fits with what other languages do, and it matches what we're already doing for attributes. I also think that's what pretty much everyone was figuring would be used for user-defined attributes. The only major problem would be if @ArgumentList is allowed when there's only a single argument, then code could break when new built-in attributes are added. Easy - do not introduce any new *global* built-in attributes, ever. There's no reason why they all can't use the same look-up rules. That's not really acceptable IMHO. Not being able to add new attributes to the language itself in the future is way too restrictive, and I expect that we'll come up with more that we want to add eventually. Designing custom attributes in a way that is guaranteed to conflict with that is a bad idea. We're restricting ourselves and causing problems for ourselves later when we could easily avoid doing so. - Jonathan M Davis Language attribute can be added in object.d and regular lookup rule apply.
Re: Const ref and rvalues again...
On Tuesday, 6 November 2012 at 22:32:57 UTC, Manu wrote: But it only really makes sense in the context of templates...? Why should something called 'auto ref' provide fabrication of temporaries for the purpose of passing rvalues to functions that receive ref args? How does auto ref (under some different definition/implementation) address the rvalue problem? The thing is that currently there are 2 workarounds. You described the first one - allocating temporaries manually to obtain referenceable lvalues: void func(ref in Vector m); Vector v1v2PlusSomeStuff = v1*v2 + Vector(10, 20, 30); func(v1v2PlusSomeStuff); The other, also painfully annoying workaround is overloading func: void func(in ref Vector m); void func(in Vector m); func(v1*v2 + Vector(10, 20, 30)); 'auto ref' implements the second workaround (via a template) and therefore requires a single, but templated func() implementation: void func(T)(in auto ref T m); This template, as I understand it, gets expanded to: void func(T)(in ref T m); // for lvalues void func(T)(in T m); // for rvalues So for non-templated functions, I suggest 2 options: 1) The previously described auto-templates (identical 'auto ref' semantics), where a function with 'auto ref' parameters is treated as implicit template. This may lead to code-bloating (for larger functions) and/or higher performance for rvalue arguments (rvalues passed to value arguments are moved, not copied; we therefore gain nothing by passing a reference, but incur a slight performance hit due to pointer indirection instead of accessing directly the rvalue on the stack). OR 2) Simple under-the-hood temporary lvalue declaration by the compiler (for rvalues passed to 'const ref' parameters) - that would be a handy implementation of the first workaround. I hope you get my point. :)
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, November 06, 2012 23:26:28 deadalnix wrote: > Le 06/11/2012 22:53, Walter Bright a écrit : > > On 11/6/2012 1:41 PM, deadalnix wrote: > >> Le 06/11/2012 22:02, Jonathan M Davis a écrit : > >>> On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: > No hitting below the belt! Let the games begin! > >>> > >>> Definitely @(ArgumentList). It fits with what other languages do, and > >>> it matches > >>> what we're already doing for attributes. I also think that's what > >>> pretty much > >>> everyone was figuring would be used for user-defined attributes. The > >>> only major > >>> problem would be if @ArgumentList is allowed when there's only a single > >>> argument, then code could break when new built-in attributes are added. > >> > >> Can you explain that code breakage ? > > > > C++11 has had problems adding new keywords, as about every identifier > > somewhere has been used by someone's C++ source code, and they don't > > want to break existing code. So C++11 winds up with awful things like > > "decltype". > > OK I understand. This is fixable easily by adding thoses magic attribute > in object and using regular lookup rules. It would still break code, because then there would be a conflict which would have to be resolved. It's the same as if we were to do something like add a function to std.file called find. Anything importing both std.algorithm and std.file would break (assuming that the arguments matched both). To some extent, this is unavoidable. Adding _any_ function to a library risks breaking user code if there's any other function that it uses which has the same name and similar enough arguments. That's what we get for automatically inferring which function and requiring the full path for disambiguation rather than requiring the full path unless a specific command makes it so that it's unnecessary (e.g. aliasing std.algorithm.find to find). So, if we want to avoid breaking code when adding new built-in attributes, we're going to have to define custom attributes in a way which they can't ever conflict with built-in ones - which would probably mean making @customAttribute illegal and require @(customAttribute). But if we're willing to break user code when adding a new attribute, forcing user code to change its attribute names or give their full path, then we can allow @customAttribute. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, November 06, 2012 22:53:36 Artur Skawina wrote: > On 11/06/12 22:02, Jonathan M Davis wrote: > > On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: > >> No hitting below the belt! Let the games begin! > > > > Definitely @(ArgumentList). It fits with what other languages do, and it > > matches what we're already doing for attributes. I also think that's what > > pretty much everyone was figuring would be used for user-defined > > attributes. The only major problem would be if @ArgumentList is allowed > > when there's only a single argument, then code could break when new > > built-in attributes are added. > Easy - do not introduce any new *global* built-in attributes, ever. There's > no reason why they all can't use the same look-up rules. That's not really acceptable IMHO. Not being able to add new attributes to the language itself in the future is way too restrictive, and I expect that we'll come up with more that we want to add eventually. Designing custom attributes in a way that is guaranteed to conflict with that is a bad idea. We're restricting ourselves and causing problems for ourselves later when we could easily avoid doing so. - Jonathan M Davis
Re: Transience of .front in input vs. forward ranges
On 11/06/2012 07:56 AM, Andrei Alexandrescu wrote: On 11/6/12 7:48 AM, H. S. Teoh wrote: On Tue, Nov 06, 2012 at 05:49:44AM +0100, Tommi wrote: On Tuesday, 6 November 2012 at 04:31:56 UTC, H. S. Teoh wrote: The problem is that you can't do this in generic code, because generic code by definition doesn't know how to copy an arbitrary type. I'm not familiar with that definition of generic code. But I do feel that there's a pretty big problem with a language design if the language doesn't provide a generic way to make a copy of a variable. To be fair, e.g. C++ doesn't provide that either. OK I worded that poorly. All I meant was that currently, there is no generic way to make a copy of something. It could be construed to be a bug or a language deficiency, but that's how things are currently. One *could* introduce a new language construct for making a copy of something, of course, but that leads to all sorts of issues about implicit allocation, how to eliminate unnecessary implicit copying, etc.. It's not a simple problem, in spite of the simplicity of stating the problem. Here's where user defined @tributes would help a lot. We'd then define @owned to mention that a class reference field inside an object must be duplicated upon copy: class A { ... } struct B { @owned A payload; A another; ... } That way a generic clone() routine could be written. Andrei That is actually the first thing that I will use the new attribute system for.
Re: C++ to catch up?
On 11/05/2012 04:54 PM, deadalnix wrote: Le 05/11/2012 11:22, Nick Sabalausky a écrit : On Mon, 05 Nov 2012 11:00:27 +0100 "jdrewsen" wrote: It seems like the C++ committee is speeding up development adding lots of the goodies from D like Ranges, static if, template contraints etc. Will D still have a case when C++ gets this done? Yes, even if they go and add all of D's features, D will still be much cleaner. (IMO) You never heard about @property ? The enhanced C++ as specified by Nick will have it as well, so it is not too relevant here whether you consider it clean or not. :)
Re: std.signals2 proposal
> What happens when a callback removes itself from the signal when called? > What happens when it adds a new callback? Since these operations modify the > list that's currently being iterated across, the implementation typically has > to be done in a way that accounts for this. Damn it. That's why the check for null was there. Thank you! So in the old implementation it would simply miss to call a slot in the list on removal, in the new implementation it would crash currently. (Because of the removed check) But also the original behavior is not really acceptable. Also this means that: slots[slots_idx] = null;// not strictly necessary in the original implementation was not as effectless as it seemed. Thanks for this very good hint, I will improve it in this regard!
Re: std.signals2 proposal
Completely working version online, all unit tests pass: https://github.com/eskimor/phobos/blob/new_signal/std/signals.d Although I will add some more, especially for the new functionality. I don't expect signals in D being as overused as in Qt (because we have delegates which are often the better choice), but nevertheless very often signals will be declared for a class but not used for many objects, so I think it is important to reduce the memory requirements of an empty signal to a bare minimum. I intent to do this by using a single array for both the delegates and the object pointers, this will also simplify the implementation. For this to work I would put everything in a standard D array (no malloc) and will simply invert the object pointer so it won't keep the object in memory on garbage collection. This could also save us the slot_idx variable, by using assumeSafeAppend. I don't think that using malloc for this single array will buy me anything, because I would have to add elements of the array to the gc roots, which can't really be more efficient in any way.
Re: Const ref and rvalues again...
But it only really makes sense in the context of templates...? Why should something called 'auto ref' provide fabrication of temporaries for the purpose of passing rvalues to functions that receive ref args? How does auto ref (under some different definition/implementation) address the rvalue problem? On 6 November 2012 23:08, Jonathan M Davis wrote: > On Tuesday, November 06, 2012 20:40:38 Manu wrote: > > Yeah I really don't understand how 'auto ref' entered this conversation? > It > > completely misses the point. > > The _entire_ reason that auto ref was introduced in the first place was to > solve the const ref problem. That's what it's for. It wouldn't exist > otherwise. So, > it's completely relevant to any discussion of const ref. > > However, Walter misunderstood what Andrei meant by the feature, so it only > got > implemented for templates, and given how Walter implemented it, it _can't_ > be > implemented with non-templated functions. But it could be implemented with > slightly > different semantics such that it solves the const ref problem as orignally > intended. > It's just that it would then have slightly different semantics between > templated > and non-templated functions. > > - Jonathan M Davis >
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 06/11/2012 22:53, Walter Bright a écrit : On 11/6/2012 1:41 PM, deadalnix wrote: Le 06/11/2012 22:02, Jonathan M Davis a écrit : On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: No hitting below the belt! Let the games begin! Definitely @(ArgumentList). It fits with what other languages do, and it matches what we're already doing for attributes. I also think that's what pretty much everyone was figuring would be used for user-defined attributes. The only major problem would be if @ArgumentList is allowed when there's only a single argument, then code could break when new built-in attributes are added. Can you explain that code breakage ? C++11 has had problems adding new keywords, as about every identifier somewhere has been used by someone's C++ source code, and they don't want to break existing code. So C++11 winds up with awful things like "decltype". OK I understand. This is fixable easily by adding thoses magic attribute in object and using regular lookup rules.
Re: Discussion on using module-scoped variables (was 'with' bug?)
On 06/11/2012 21:12, Chris Cain wrote: ... I looked over what you said, and I'm more curious as to what you might be using modules for. It seems to me like you're using modules similar to a singleton. Would this be correct? Or am I missing something? No, you are correct. I was annoyed with a lone struct in a module which needed only one instantiation and I thought: why not just drop drop the struct encapsulation. Static import the module and viola no difference. Also makes the code very clean and easy to read.
Re: std.signals2 proposal
On Nov 6, 2012, at 2:09 PM, eskimo wrote: > On Tue, 2012-11-06 at 11:16 -0800, Sean Kelly wrote: >> On Nov 5, 2012, at 5:36 AM, Robert wrote: >>> >>> I just developed a proof-of-concept implementation of an improved >>> std.signals. >> >> Make sure that the behavior when calling std.signals operations from within >> a callback is well-defined. It should either explicitly disallow this or, >> ideally, support it with deterministic results. > > I am pretty sure I don't understand what you mean. Calling std.signals > methods from an invoked slot is as safe as from any other random > function. Am I missing something? What happens when a callback removes itself from the signal when called? What happens when it adds a new callback? Since these operations modify the list that's currently being iterated across, the implementation typically has to be done in a way that accounts for this.
Re: std.signals2 proposal
On Tue, 2012-11-06 at 11:16 -0800, Sean Kelly wrote: > On Nov 5, 2012, at 5:36 AM, Robert wrote: > > > > I just developed a proof-of-concept implementation of an improved > > std.signals. > > Make sure that the behavior when calling std.signals operations from within a > callback is well-defined. It should either explicitly disallow this or, > ideally, support it with deterministic results. I am pretty sure I don't understand what you mean. Calling std.signals methods from an invoked slot is as safe as from any other random function. Am I missing something?
Re: Const ref and rvalues again...
On Tuesday, November 06, 2012 20:40:38 Manu wrote: > Yeah I really don't understand how 'auto ref' entered this conversation? It > completely misses the point. The _entire_ reason that auto ref was introduced in the first place was to solve the const ref problem. That's what it's for. It wouldn't exist otherwise. So, it's completely relevant to any discussion of const ref. However, Walter misunderstood what Andrei meant by the feature, so it only got implemented for templates, and given how Walter implemented it, it _can't_ be implemented with non-templated functions. But it could be implemented with slightly different semantics such that it solves the const ref problem as orignally intended. It's just that it would then have slightly different semantics between templated and non-templated functions. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/6/2012 1:41 PM, deadalnix wrote: Le 06/11/2012 22:02, Jonathan M Davis a écrit : On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: No hitting below the belt! Let the games begin! Definitely @(ArgumentList). It fits with what other languages do, and it matches what we're already doing for attributes. I also think that's what pretty much everyone was figuring would be used for user-defined attributes. The only major problem would be if @ArgumentList is allowed when there's only a single argument, then code could break when new built-in attributes are added. Can you explain that code breakage ? C++11 has had problems adding new keywords, as about every identifier somewhere has been used by someone's C++ source code, and they don't want to break existing code. So C++11 winds up with awful things like "decltype".
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/06/12 22:02, Jonathan M Davis wrote: > On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: >> No hitting below the belt! Let the games begin! > > Definitely @(ArgumentList). It fits with what other languages do, and it > matches > what we're already doing for attributes. I also think that's what pretty much > everyone was figuring would be used for user-defined attributes. The only > major > problem would be if @ArgumentList is allowed when there's only a single > argument, then code could break when new built-in attributes are added. Easy - do not introduce any new *global* built-in attributes, ever. There's no reason why they all can't use the same look-up rules. As to the syntax - it doesn't matter, as long as it isn't "[ArgumentList]" as that one is ambiguous (from a programmer POV, even if the compiler could deal with it - which i'm not convinced is the case here, considering all contexts where attributes have to be allowed and the inevitable evolution of this feature). "@[ArgumentList]". artur
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/06/2012 01:39 PM, Walter Bright wrote: > On 11/6/2012 1:26 PM, Caligo wrote: >> On Tue, Nov 6, 2012 at 1:18 PM, Walter Bright >> wrote: >>> >>> No hitting below the belt! Let the games begin! >> >> If those are our only choices, then I vote for @( ArgumentList ). >> >> Otherwise, I think these look better: >> >> [: ArgumentList :] >> >> or >> >> |: ArgumentList :| >> > > :-) > More explicitly: (-: ArgumentList :-) Ali
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 06/11/2012 22:02, Jonathan M Davis a écrit : On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: No hitting below the belt! Let the games begin! Definitely @(ArgumentList). It fits with what other languages do, and it matches what we're already doing for attributes. I also think that's what pretty much everyone was figuring would be used for user-defined attributes. The only major problem would be if @ArgumentList is allowed when there's only a single argument, then code could break when new built-in attributes are added. Can you explain that code breakage ?
Re: [ ArgumentList ] vs. @( ArgumentList )
@
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tue, Nov 06, 2012 at 03:26:53PM -0600, Caligo wrote: > On Tue, Nov 6, 2012 at 1:18 PM, Walter Bright > wrote: > > > > No hitting below the belt! Let the games begin! > > If those are our only choices, then I vote for @( ArgumentList ). > > Otherwise, I think these look better: > > [: ArgumentList :] > > or > > |: ArgumentList :| They look like smileys to me. To me, they look worse than @Arg. T -- Once bitten, twice cry...
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/6/2012 1:07 PM, Tavi Cacina wrote: On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: No hitting below the belt! Let the games begin! @ 2 penalty points for that one!
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/6/2012 1:26 PM, Caligo wrote: On Tue, Nov 6, 2012 at 1:18 PM, Walter Bright wrote: No hitting below the belt! Let the games begin! If those are our only choices, then I vote for @( ArgumentList ). Otherwise, I think these look better: [: ArgumentList :] or |: ArgumentList :| :-)
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 20:01:27 UTC, Jacob Carlborg wrote: On 2012-11-06 20:52, Manu wrote: I'd like to re-enforce the consideration that @attribute() makes it looks like they affect the code generation somehow... they're really just annotations. I still like the syntax. I'd also like to add that the OP argument is false. Sure, the attributes themselves are just meta-data and you can use them for purely informative purposes (to annotate with documentation, author names, versions, license, etc..) but more commonly attributes are intended to be introspected on at CT or RT and used to *indirectly cause some processing*. The end result is the same and user defined attributes should be consistent with built-in ones. Syntax wise, I agree the C# version is /slightly/ more pleasant to the eye than the Java one but given the possible grammar ambiguities and the consistency with buit-ins, @(attributes) win by a landslide.
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tue, Nov 6, 2012 at 1:18 PM, Walter Bright wrote: > > No hitting below the belt! Let the games begin! If those are our only choices, then I vote for @( ArgumentList ). Otherwise, I think these look better: [: ArgumentList :] or |: ArgumentList :|
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, November 06, 2012 11:18:34 Walter Bright wrote: > No hitting below the belt! Let the games begin! Definitely @(ArgumentList). It fits with what other languages do, and it matches what we're already doing for attributes. I also think that's what pretty much everyone was figuring would be used for user-defined attributes. The only major problem would be if @ArgumentList is allowed when there's only a single argument, then code could break when new built-in attributes are added. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/06/2012 01:19 PM, deadalnix wrote: > Le 06/11/2012 22:07, Tavi Cacina a écrit : >> On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: >>> No hitting below the belt! Let the games begin! >> >> @ >> >> > > Who will make that even shorter ? Not shorter but definitely more in line with C and C++ heritage: static() with optional () Ali
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 06/11/2012 22:07, Tavi Cacina a écrit : On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: No hitting below the belt! Let the games begin! @ Who will make that even shorter ?
Re: [ ArgumentList ] vs. @( ArgumentList )
I agree with David and deadalnix agument wise, so: @(attriblist) or @attrib1 @attrib2 with the hope that this syntax is extensible enough to make it possible to implement something like @safe or @noheap as library functionality at some day.
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: No hitting below the belt! Let the games begin! @
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/06/2012 11:18 AM, Walter Bright wrote: For User Defined Attributes. @() with optional (). Ali
Re: Transience of .front in input vs. forward ranges
Le 06/11/2012 07:49, Andrei Alexandrescu a écrit : On 11/6/12 4:36 AM, H. S. Teoh wrote: Hmm. Another idea just occurred to me. The basic problem here is that we are conflating two kinds of values, transient and persistent, under a single name .front. What if we explicitly name them? Say, .copyFront for the non-transient value and .refFront for the transient value (the names are unimportant right now, let's consider the semantics of it). We could transfer that matter to the type of .front itself, i.e. define a function copy(x) that returns e.g. x for for string and x.dup for char[] etc. There would be problems on e.g. defining copy for structs with pointer and class reference fields etc. One quite simple approach would be to define (on the contrary) .peekFront, which means "yeah, I'd like to take a peek at the front but I don't plan to store it anywhere". That would entail we define eachLine etc. to return string from .front and char[] from .peekFront, and deprecate byLine. Andrei Is it possible to have the pro and cons of peekFront vs transient ?
Re: [ ArgumentList ] vs. @( ArgumentList )
@( ArgumentList ) is the winner for me. On 2012-11-06 13:18, Walter Bright wrote: For User Defined Attributes. In the north corner we have the current champon: --- [ ArgumentList ] Pros: precedent with C# looks nice Cons: not so greppable parsing ambiguity with [array literal].func(); -- In the south corner, there's the challenger: @( ArgumentList ) Pros: looks like existing @attribute syntax no parsing problems Cons: not as nice looking -- No hitting below the belt! Let the games begin!
Re: [ ArgumentList ] vs. @( ArgumentList )
I vote for @(ArgumentList). Or @Arg1 @Arg2 ... as somebody mentioned. It's more consistent with existing @-syntax. Reusing [] is bad because it visually conflicts with array literals (and makes parsing harder to boot). @ is a unique symbol that, so far, is associated with attributes, so it makes sense to use it also to mark user-defined attributes. I don't buy the argument that other languages have a different syntax. We're talking about D here, and what is chosen should make sense in the context of D, without undue influence from other languages. T -- If the comments and the code disagree, it's likely that *both* are wrong. -- Christopher
Re: dcollections
On Tuesday, November 06, 2012 15:10:26 Joseph Rushton Wakeling wrote: > Hello all, > > Very naive question about dcollections 2.0 and std.container -- what are the > reasons why dcollections has had to be developed as a standalone library, > and what's in the way of incorporating that functionality into Phobos? > > I have some potential use-cases where some of the not-in-Phobos stuff (e.g. > sets) might be a good solution. It'd clearly be much nicer to be able to > rely purely on the standard library instead of something outside. So, if > there are some trivial things that can be done to get code transferred > (e.g. if it's just a matter of time that people don't have), it'd be nice > to know, in case I can do something to assist. There are fundamental differences in how the two work. In particular, dcollections supports the ideas of cursors, which I believe are a hybrid of sorts between iterators and ranges, while std.container only supports ranges. Andrei does not want to add cursors to std.container. Also, IIRC, dcollections does more with interfaces, whereas std.container is purely template-based (though I'm not 100% sure on that). So, the philosophies behind the two libraries are fundamentally different. If someone wants to take containers from dcollections and port them to std.container, they're welcome to do so (that's where RedBlackTree came from), but it's not simply a matter of copying what dcollections is doing to Phobos. They're too different. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
On 11/06/2012 02:18 PM, Walter Bright wrote: For User Defined Attributes. In the north corner we have the current champon: --- [ ArgumentList ] Pros: precedent with C# looks nice Cons: not so greppable parsing ambiguity with [array literal].func(); -- In the south corner, there's the challenger: @( ArgumentList ) Pros: looks like existing @attribute syntax no parsing problems Cons: not as nice looking -- No hitting below the belt! Let the games begin! One more vote for @( ArgumentList ) with optional () for simple ones - they seem like they would fit with the rest of the language much more nicely
Re: Proposal for "Classic DList" (CDList)
On Tuesday, November 06, 2012 13:22:10 monarch_dodra wrote: > On Tuesday, 6 November 2012 at 12:18:47 UTC, monarch_dodra wrote: > > [SNIP] > > Still under construction of course. Still writting up docs and > stuff. Given some of the issues that std.container has, I'd honestly argue for just outright changing the containers in there if we need to, or at least making names like CDList temporary, and replace DList with it later rather than keeping the worse names around permanently. One thing that came up recently in D.Learn ( http://forum.dlang.org/thread/lozpofrboxsfybmhk...@forum.dlang.org ) is the fact that SList and DList make the unfortunate choice of having their insert* functions return the number of items inserted rather than a range starting at those elements like C++ would have done (std::list's insert* functions return iterators). In general, it's a royal pain to get at ranges to anything other than the whole list, and I think that while the basic API of std.container is good, a number of the functions need some tweaks if they're really going to be range-friendly. AFAIK, it's the first set of purely range-based containers, and I think that the result is still very rough around the edges due to a lack of experience with using ranges with containers instead of iterators. std.container is a good start, but it still needs work. So, I think that it's great if you want to spend time trying to iron out some of the kinks in it. - Jonathan M Davis
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 06/11/2012 21:17, Jacob Carlborg a écrit : On 2012-11-06 20:52, Manu wrote: I'd like to re-enforce the consideration that @attribute() makes it looks like they affect the code generation somehow... they're really just annotations. Then we just have to make it possible to generate code with these attributes :) That seems the most reasonable option.
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 19:52:45 UTC, Manu wrote: I'd like to re-enforce the consideration that @attribute() makes it looks like they affect the code generation somehow... they're really just annotations. Why would @ look like that to you? Actually, @ seems to yell »annotation« to me, probably because of my (limited) exposure to Python. And don't forget that UDAs _do_ in practice have an effect on code generation, at least a lot more than @safe-ty attributes. Whether the mechanism by which they gain that effect is built into the compiler or implemented in a library doesn't matter to the user of a library. David
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 20:13:32 UTC, Manu wrote: this is a really good point. they are a tuple, you can slice it, iterate it... further supports [] to my mind ;) Not really – [] represents an array, not a tuple. David
Re: [ ArgumentList ] vs. @( ArgumentList )
On 2012-11-06 20:52, Manu wrote: I'd like to re-enforce the consideration that @attribute() makes it looks like they affect the code generation somehow... they're really just annotations. Then we just have to make it possible to generate code with these attributes :) -- /Jacob Carlborg
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 06/11/2012 20:46, David Nadlinger a écrit : On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: [ ArgumentList ] Pros: precedent with C# I guess »precedent with Java« should be added to the respective @() list then. David And python. By themselves, they represent a much bigger user base than C#
Re: [ ArgumentList ] vs. @( ArgumentList )
On 6 November 2012 22:01, Jacob Carlborg wrote: > On 2012-11-06 20:52, Manu wrote: > >> I'd like to re-enforce the consideration that @attribute() makes it >> looks like they affect the code generation somehow... they're really >> just annotations. >> > > I still like the syntax. I liked it initially too, but reason changed my mind...
Re: Discussion on using module-scoped variables (was 'with' bug?)
On Tuesday, 6 November 2012 at 15:34:41 UTC, Faux Amis wrote: I would have loved an answer to this: Is there any reason to encapsulate this kind of code in a struct? --- module a; private int _a; int a(){ return _a; } void a(int aIn){ _a = aIn; } void useA(){ } --- module main; static import a; void main(){ a.useA(); } --- What I am trying to get answered here is whether there is something special about a struct or a class which makes it a 'correct' data encapsulator where a module does not. So --- module a; private int _a; int a(){ return _a; } void a(int aIn){ _a = aIn; } void useA(){ } // and more using the shared state _a? --- vs. --- module a; struct S { private int _a; void a(int aIn) { _a = aIn; } void a() { return _a; } void doSLikeThings() { // uses A } } // and more in the module using the shared state of S which encapsulates _a? --- ? Well, let's start off with the way that I think about using modules. They represent a logical grouping of many concepts and ideas. If you have a "compression module", it would probably hold functions, structures, and classes which are used in compression. If you want to create a struct, it needs to represent some singular concept or idea that will encapsulate the data "a" (and presumably more data: "b","c","d" ...etc). If you can do that (and you usually can) then it certainly makes sense to encapsulate it in a struct (or a class, especially it is a concept that benefits from inheritance or if you want reference semantics by default). And you should avoid using module-level encapsulation of data for the reasons stated in previous posts. If you are trying to share some data, then it would be better to explicitly share it among the parts of your module: --- module a; struct S { // common information int a, b, c, d; // methods/functions which help the information stay consistent } struct T { S* s; // Maybe some other information // uses data from the shared s } struct U { // Some methods use S* (or ref S) as arguments, but not all. } struct V { // Doesn't need S for anything } struct W { T* t; // Uses shared state of s indirectly via shared state of t } void fun(ref S s, ref V v) pure { // does things with s and v which is reflected to anyone using this particular s or v } --- The alternative, implicitly sharing information using module-scoped variables, has the advantage of being somewhat less to type (after all, you wouldn't pass in the information via args). However, as I showed before, it has several disadvantages that make it significantly less compelling. Does that answer your question? I'm not sure how else to answer "whether there is something special about a struct or a class which makes it a 'correct' data encapsulator where a module does not" other than by showing how module-scoped data is bad (which is what previous posts have covered the most) and how you could alternatively use structs (which is what this post is trying to cover). ... I looked over what you said, and I'm more curious as to what you might be using modules for. It seems to me like you're using modules similar to a singleton. Would this be correct? Or am I missing something?
Re: dcollections
On Tuesday, 6 November 2012 at 14:10:35 UTC, Joseph Rushton Wakeling wrote: Hello all, Very naive question about dcollections 2.0 and std.container -- what are the reasons why dcollections has had to be developed as a standalone library, and what's in the way of incorporating that functionality into Phobos? I have some potential use-cases where some of the not-in-Phobos stuff (e.g. sets) might be a good solution. It'd clearly be much nicer to be able to rely purely on the standard library instead of something outside. So, if there are some trivial things that can be done to get code transferred (e.g. if it's just a matter of time that people don't have), it'd be nice to know, in case I can do something to assist. Thanks & best wishes, -- Joe dcollections is Boost and the author fully supports moving anything into Phobos, several existing came from dcollections. The design of dcollections is at odds with the intended design of std.collections. I believe it was Cursor vs Range. And much of std.collections is waiting on finalization of what custom allocators will look like. ... seems dsource is barfing...
Re: [ ArgumentList ] vs. @( ArgumentList )
Le 06/11/2012 20:47, Manu a écrit : I actually quite liked Tristan's argument. [attr, attr2] feels more like what it is, an annotation. It does nothing, has no effect on the declaration on its own. the @attr syntax looks like existing attributes, and with that kinda comes the presumption that they actually DO something, affect the code generated in some way. This is definitively what they should do at some point. For that reason, I buy the argument that [attrs...] being visually distinct makes more sense, more like what it is. Perhaps it should be termed 'annotation' rather than 'attribute'? On 6 November 2012 21:38, ponce mailto:s...@spam.org>> wrote: I like @(ArgumentList) better for stated reason: it looks like existing @attributes.
Re: [ ArgumentList ] vs. @( ArgumentList )
On 6 November 2012 21:55, Faux Amis wrote: > On 06/11/2012 20:18, Walter Bright wrote: > >> For User Defined Attributes. >> >> In the north corner we have the current champon: >> >> --- >> [ ArgumentList ] >> >> Pros: >> precedent with C# >> looks nice >> >> Cons: >> not so greppable >> parsing ambiguity with [array literal].func(); >> >> -- >> In the south corner, there's the challenger: >> >> @( ArgumentList ) >> >> Pros: >> looks like existing @attribute syntax >> no parsing problems >> >> Cons: >> not as nice looking >> -- >> >> No hitting below the belt! Let the games begin! >> > > With [] I expect array operations; can I slice it? > this is a really good point. they are a tuple, you can slice it, iterate it... further supports [] to my mind ;)
Re: [ ArgumentList ] vs. @( ArgumentList )
On Tuesday, 6 November 2012 at 19:18:39 UTC, Walter Bright wrote: For User Defined Attributes. In the north corner we have the current champon: --- [ ArgumentList ] Pros: precedent with C# looks nice Cons: not so greppable parsing ambiguity with [array literal].func(); -- In the south corner, there's the challenger: @( ArgumentList ) Pros: looks like existing @attribute syntax no parsing problems Cons: not as nice looking -- No hitting below the belt! Let the games begin! @() with optional ().
Re: [ ArgumentList ] vs. @( ArgumentList )
On 2012-11-06 20:52, Manu wrote: I'd like to re-enforce the consideration that @attribute() makes it looks like they affect the code generation somehow... they're really just annotations. I still like the syntax. -- /Jacob Carlborg