Re: DConf Reception sponsored by the HipHop team at Facebook
On Apr 24, 2013, at 8:21 PM, Vladimir Panteleev vladi...@thecybershadow.net wrote: On Friday, 1 March 2013 at 11:12:02 UTC, Andrei Alexandrescu wrote: (details to follow) So, are there any details? Like, e.g. is there a dress code? :) I believe you're expected to wear clothes.
Re: DUB 0.9.13 released
On Tuesday, 16 April 2013 at 21:50:10 UTC, Sönke Ludwig wrote: Changes: - Support for a new buildRequirements field to be able to specify things like Don't treat warnings as errors or Allow use of deprecated features - A lot of improvements to the VisualD project generator - Some important bug fixes Change log: https://github.com/rejectedsoftware/dub/blob/master/CHANGELOG.md Download: http://registry.vibed.org/download I want to inform you that Mono-D v0.5.2.4 can open Dub projects natively now - no need for creating .dproj files explicitly anymore, just opening package.json is required in order to have the project there. It also handles include paths in the most common cases. Btw, what about nested dependencies? How are they handled in dub? Are all sub-packages in the .dub folder read for further dependency information? Great work though!
Re: DUB 0.9.13 released
Am 26.04.2013 21:37, schrieb alex: I want to inform you that Mono-D v0.5.2.4 can open Dub projects natively now - no need for creating .dproj files explicitly anymore, just opening package.json is required in order to have the project there. It also handles include paths in the most common cases. Cool! I'll try that out tomorrow. Do you execute the dub binary to generate a project file or do you parse the package.json directly? If it helps, it would be relatively easy to add a mode where all build settings for the project, including all of its dependencies, are output to stdout as JSON. Btw, what about nested dependencies? How are they handled in dub? Are all sub-packages in the .dub folder read for further dependency information? Yes, the ones in .dub, in the system- and user-wide package folders, as well as any package added with dub add-local are scanned for matches recursively and their build settings are merged-in accordingly. Great work though! Thanks, the same must be said about Mono-D! (which is a lot more complex, of course)
Re: DUB 0.9.13 released
On Friday, 26 April 2013 at 20:16:15 UTC, Sönke Ludwig wrote: Am 26.04.2013 21:37, schrieb alex: I want to inform you that Mono-D v0.5.2.4 can open Dub projects natively now - no need for creating .dproj files explicitly anymore, just opening package.json is required in order to have the project there. It also handles include paths in the most common cases. Cool! I'll try that out tomorrow. Do you execute the dub binary to generate a project file or do you parse the package.json directly? If it helps, it would be relatively easy to add a mode where all build settings for the project, including all of its dependencies, are output to stdout as JSON. It parses the package.json directly, no .sln or .dproj is generated. It runs dub build for building and dub for executing the program -- where do I specify run arguments btw? Btw, what about nested dependencies? How are they handled in dub? Are all sub-packages in the .dub folder read for further dependency information? Yes, the ones in .dub, in the system- and user-wide package folders, as well as any package added with dub add-local are scanned for where is the list of packages added with 'add-local' stored at? matches recursively and their build settings are merged-in accordingly. I think I might open up all the dependency projects as well when opening the 'root' package.json - do you think that it's a good idea or just distracting the user from the main project? Great work though! Thanks, the same must be said about Mono-D! (which is a lot more complex, of course) :-)
Re: DUB 0.9.13 released
I'd say opening all dependencies is distracting. But being able to open them quickly is really useful. On Fri, Apr 26, 2013 at 10:26 PM, alex i...@alexanderbothe.com wrote: On Friday, 26 April 2013 at 20:16:15 UTC, Sönke Ludwig wrote: Am 26.04.2013 21:37, schrieb alex: I want to inform you that Mono-D v0.5.2.4 can open Dub projects natively now - no need for creating .dproj files explicitly anymore, just opening package.json is required in order to have the project there. It also handles include paths in the most common cases. Cool! I'll try that out tomorrow. Do you execute the dub binary to generate a project file or do you parse the package.json directly? If it helps, it would be relatively easy to add a mode where all build settings for the project, including all of its dependencies, are output to stdout as JSON. It parses the package.json directly, no .sln or .dproj is generated. It runs dub build for building and dub for executing the program -- where do I specify run arguments btw? Btw, what about nested dependencies? How are they handled in dub? Are all sub-packages in the .dub folder read for further dependency information? Yes, the ones in .dub, in the system- and user-wide package folders, as well as any package added with dub add-local are scanned for where is the list of packages added with 'add-local' stored at? matches recursively and their build settings are merged-in accordingly. I think I might open up all the dependency projects as well when opening the 'root' package.json - do you think that it's a good idea or just distracting the user from the main project? Great work though! Thanks, the same must be said about Mono-D! (which is a lot more complex, of course) :-)
Re: DUB 0.9.13 released
On Friday, 26 April 2013 at 20:47:42 UTC, Rory McGuire wrote: I'd say opening all dependencies is distracting. But being able to open them quickly is really useful. I think I should create greyed-out references in the pseudo-solution which can be enabled and loaded afterwards if wanted. Or so..
Re: 1 matches bool, 2 matches long
On 4/25/2013 10:49 PM, Ali Çehreli wrote: It certainly behaves that way but it isn't an integer type and that's why it is unintuitive. But it is an integer type. bool is a type with two values: false and true with the following conversion rules: false - 0 true - 1 0 value - false non-zero value - true 0 literal - false The following are the problematic ones: 1 literal - true non-zero and non-one *literal* - Not a bool! That last rule is the problem. Since we cannot get rid of the last rule, to be consistent, we should make literal 1 match an integer type better than bool. Whether it's a problem or not depends on one's perspective. The next issue is the notion of a better match. This notion is very complex in C++, and still produces odd results. Very few people can explain how it works - it's kind of shoot and hope you hit the target. D tries very hard to avoid the notion of a better match. It goes with an exact match, followed by one with implicit conversions. All implicit conversions are considered equally good. Ambiguity is resolved by invoking partial ordering, which was explained elsewhere in this thread. Partial ordering does not at all consider better matches. Once you venture down the path of better matches, it's all roses at first, but look at where C++ wound up with it. It didn't intend to arrive there, it inevitably arrived there. The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast?
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 05:02:50 UTC, Walter Bright wrote: On 4/25/2013 7:54 PM, Kapps wrote: This is just silly. Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a different overload. This does: import core.stdc.stdio; enum x = 1; enum y = 4; int foo(short s) { return 1; } int foo(long s) { return 2; } void main() { printf(%d\n, foo(x)); printf(%d\n, foo(y)); } - A bool is an integer with the range 0..1 This feature never has been useful to me. It has caused bug. Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? Yes.
Re: rvalue references
On Friday, 26 April 2013 at 04:15:24 UTC, Manu wrote: Why bother with 'auto'? Why not just make this default behaviour? That is the kind of question that we can answer when safety problem are solved. This is why I would love to see both problem separated : they are different. Still need to specify precisely the lifetime of temporaries, which is a difficult (but solvable) problem.
Re: InvalidMemoryOperationError when calling functions from destructors
On 2013-04-25 19:57, Vladimir Panteleev wrote: Regardless, the above (accessing objects in destructors) is not related to the InvalidMemoryOperationError. See the documentation for it: http://dlang.org/phobos/core_exception.html#.InvalidMemoryOperationError Yeah, I though that was weird. -- /Jacob Carlborg
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:18:29 UTC, deadalnix wrote: On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? Yes. +1 What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion? How about yet another compiler flag?
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 02:13:03 UTC, Ali Çehreli wrote: On 04/25/2013 06:44 PM, Maxim Fomin wrote: On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote: Looks like value range propagation bug because 1 is integer literal and should be converted to long. There is no way for 1 to be converted to bool here That special conversion rule of literal 0 and literal 1 being implicitly convertible to false and true gets in the way. (from TDPL long is below int and it is the shortest way, value range propagation can work upwards, but the path would be longer). Ali Sorry but I am not aware of how 1 is converted to bool here. True, that 1 is convertible to true, but here there is function with long parameter.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: On 4/25/2013 10:49 PM, Ali Çehreli wrote: It certainly behaves that way but it isn't an integer type and that's why it is unintuitive. But it is an integer type. Regarding bool type as integer type is C atavism and should be abandoned. This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:16:29 UTC, deadalnix wrote: On Friday, 26 April 2013 at 05:02:50 UTC, Walter Bright wrote: A bool is an integer with the range 0..1 This feature never has been useful to me. +1
Re: 1 matches bool, 2 matches long
On 4/25/2013 11:42 PM, Manipulator wrote: What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion? Implicit conversions make the menagerie of integer types tractable. Explicit casts are a sledgehammer that often causes bugs rather than eliminates them. How about yet another compiler flag? Compiler flags that alter the meaning of the language are not the solution.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:42:28 UTC, Manipulator wrote: On Friday, 26 April 2013 at 06:18:29 UTC, deadalnix wrote: On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? Yes. +1 What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion? How about yet another compiler flag? No no no no, please no.
Re: 1 matches bool, 2 matches long
On 4/25/2013 11:16 PM, deadalnix wrote: This feature never has been useful to me. It has been useful to me. So there! It has caused bug. The bug is not providing an overload for int. Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version. It is not inconsistent - you forgot a foo(int) overload. '1' is an int. If you don't supply and int overload, it must implicitly convert, and those conversions are considered equivalent.
Re: 1 matches bool, 2 matches long
On 4/26/2013 12:07 AM, Maxim Fomin wrote: Regarding bool type as integer type is C atavism and should be abandoned. There's a very lng history of 0 being regarded as false and 1 as true - it goes well beyond C. This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching. Yet I showed an analogous example where different overloads were selected based on a different integer value. There's no getting away from having to pay attention when declaring different overloads of a function. In the original example, the correct solution is to provide a foo(int). I'd be suspicious of any code that only had overloads on just bool and long - it doesn't make sense.
Re: Mixin template parameters / mixin template literals
Are you really saying that 'sort!((a, b) = a b)(array);' is too verbose?? I consider 'sort!(a b)(array);' to be **too terse**: there is nothing here telling the reader what a and b are supposed to be. BR, renoX
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote: On 4/26/2013 12:07 AM, Maxim Fomin wrote: Regarding bool type as integer type is C atavism and should be abandoned. There's a very lng history of 0 being regarded as false and 1 as true - it goes well beyond C. This should be irrelevant in case of long parameter. Such conversion should not be in the language (like feature of array to pointer conversion and function to pointer to function conversion is present in C but not in D). This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching. Yet I showed an analogous example where different overloads were selected based on a different integer value. There's no getting away from having to pay attention when declaring different overloads of a function. In the original example, the correct solution is to provide a foo(int). I'd be suspicious of any code that only had overloads on just bool and long - it doesn't make sense. I argue the correct solution is to call integer function with integer parameter when integer value is passed. Adjusting to buggy compiler behavior isn't a good idea.
Re: 1 matches bool, 2 matches long
On 4/26/2013 1:14 AM, Maxim Fomin wrote: I argue the correct solution is to call integer function with integer parameter when integer value is passed. I'm sorry, but that's an assertion not an argument. The other issue with your assertion, as I explained to Ali, is that D does not have a notion of better implicit conversions, and it would be a tragedy to add them. Adjusting to buggy compiler behavior isn't a good idea. It's working as designed - it is not a compiler bug.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 08:03:14 UTC, Walter Bright wrote: On 4/25/2013 11:16 PM, deadalnix wrote: This feature never has been useful to me. It has been useful to me. So there! It has caused bug. The bug is not providing an overload for int. Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version. It is not inconsistent - you forgot a foo(int) overload. '1' is an int. If you don't supply and int overload, it must implicitly convert, and those conversions are considered equivalent. Because bool value range should be used as a failover mecanism IMO. And bool shouldn't be considered as an integral.
Re: rvalue references
On 04/26/2013 01:58 AM, Zach the Mystic wrote: ... I also thought of the trick mentioned by Timon, where the compiler infers the need or lack thereof for the value/reference type in templates based on what things are done within the function body. But as you said, figuring out the rules for making the compiler smart enough to choose the right one seems like a hard task. I think it is easy. If it forwards to another 'auto ref' template parameter, it needs to descend into that template, determine *its* type of parameter, and then assign the type of its own parameter accordingly. ... No, when forwarding to another template, non-lazy parameters will always have an address, ref or not ref. lazy auto ref parameters should be restricted to the template case. The cases where it makes a difference are auto ref returns, __traits(isRef, ...), and lazy auto ref parameters. (If there are more, they will be detected by grepping the compiler source for occurrences of the 'ref' storage class representation, presumably an enum value.) The compiler does not have to be particularly smart. IMO this is the way to generalize auto ref to non-template functions.
Re: Mixin template parameters / mixin template literals
On Friday, 26 April 2013 at 08:13:48 UTC, renoX wrote: I consider 'sort!(a b)(array);' to be **too terse**: there is nothing here telling the reader what a and b are supposed to be. Sure there is - it's called convention. Since all the functions in `std.algorithm` that accept delegates also accept string literals for a mixin that use `a` and `b` as the arguments, the reader should know what `a` and `b` means, just like they know what `sort` means.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: On 4/25/2013 10:49 PM, Ali Çehreli wrote: It certainly behaves that way but it isn't an integer type and that's why it is unintuitive. But it is an integer type. It is an integral type _internally_. A bool type should have the values true/false. When someone sees foo(45) he expects it to call an overload that receives an _integral_ value. Which overload is going to be called is a detail (short or long in this example). It is confusing to call an overload that takes bool. Boolean are true/false, not 0, 1 or anything else.
Re: 1 matches bool, 2 matches long
On 04/26/2013 07:02 AM, Walter Bright wrote: A bool is an integer with the range 0..1 This is True for the type but for the actual code it looks different. There 0 == false. and everything else is true. import std.stdio; void main() { if(10) { writefln(%d is also true, 10); } } if(value) proberly becomes: cmp value, 0 jne ifblock Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than...
Re: 1 matches bool, 2 matches long
And indeed they do. I did face some very weird bugs caused by that already. What sort of bugs has it caused for you? Just interested, not questioning whether or not it's a source of bugs.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote: On 4/26/2013 12:07 AM, Maxim Fomin wrote: Regarding bool type as integer type is C atavism and should be abandoned. There's a very lng history of 0 being regarded as false and 1 as true - it goes well beyond C. Assembly, PL/I, Algol, ...? Just asking as a language geek. Personally, given my strong typing background, I dislike the automatic conversion to booleans. Even my C code has explicit comparisons for NULL pointers, instead of relying in implicit conversions. -- Paulo
Re: Is there any plans to make working signals in D?
24.04.2013 12:47, deadalnix пишет: On Wednesday, 24 April 2013 at 08:27:15 UTC, Denis Shelomovskij wrote: 19.04.2013 11:45, deadalnix пишет: On Friday, 19 April 2013 at 07:31:16 UTC, Denis Shelomovskij wrote: Another try to describe the problem: When I get a delegate, I'd like to use it unless it become invalid. How does using an object solve that ? Unless this is a struct-member delegate (which is not often used anyway and can be marked as dangerous e.g.): --- T delegate(A) del = ...; rt_attachDisposeEvent(_d_toObject(del.ptr), onDelegateDisposed); --- I still see many possibilities without changing the language. For instance, allowing to attach dispose event to something else than an object. Thus making that something else almost class but not class and I don't see why not just use class instead of creating a new entity. -- Денис В. Шеломовский Denis V. Shelomovskij
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 12:34:55 UTC, ixid wrote: And indeed they do. I did face some very weird bugs caused by that already. What sort of bugs has it caused for you? Just interested, not questioning whether or not it's a source of bugs. The last time I experienced that feature was with a char getting casted to bool implicitly and then appended to a string, causing super weird behavior after when using the resulting (corrupted) string. I don't have the actual code as I threw it away (because it was bogous) but took me several hours to figure it out.
Re: Stable D version?
On Monday, 22 April 2013 at 22:17:33 UTC, eles wrote: On Monday, 22 April 2013 at 14:25:21 UTC, David Nadlinger wrote: On Sunday, 21 April 2013 at 19:58:14 UTC, Tourist wrote: Sorry, I was rude here and I apologize. Finally, D is (at least) a wonderful place to discuss and test new ideas and, while I would like it to take off faster, a too early rush won't make any good.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 08:03:14 UTC, Walter Bright wrote: On 4/25/2013 11:16 PM, deadalnix wrote: This feature never has been useful to me. It has been useful to me. So there! If you want an int to behave like a bool, then by all means go ahead and write the code yourself, I don't want the compiler to do it for me in a silent manner. It has caused bug. The bug is not providing an overload for int. That kind of nonintuitive requirement is easily overlooked. Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version. It is not inconsistent - you forgot a foo(int) overload. '1' is an int. If you don't supply and int overload, it must implicitly convert, and those conversions are considered equivalent. Seriously, let's fix this once and for all. Bool is bool, it's not int and never should have been. I don't understand why we're having this debate. --rt
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote: On 4/26/2013 12:07 AM, Maxim Fomin wrote: Regarding bool type as integer type is C atavism and should be abandoned. There's a very lng history of 0 being regarded as false and 1 as true - it goes well beyond C. That is true, but even in theses elder languages, bool is handled as a special case, and not as an regular integral type. For instance, when integral conversion to smaller type is done by applying a mask (or doing a modulo, this is the same thing in this case) it is done by comparing to 0 to compare to bool.
Array void init
Should this be supported? double[8] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; (it's not supported at the moment)
Re: Array void init
Just to clarify, this is supported, of course: double[8] foo = void; foo[0] = 1.0; foo[1] = 2.0; foo[3] = 3.0; foo[4] = 3.5;
Re: Array void init
Luís Marques: Should this be supported? double[8] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; (it's not supported at the moment) I think I have not needed this so far. It looks dangerous. Generally D tries to initialize variables. What are your use cases? Bye, bearophile
Re: Array void init
Hi bearophile. This was just an academic question. It just seemed to me that if double[8] foo = void was deemed to warrant support, that it is a bit unorthogonal not to support the void in the specific indexes. This is just nitpicking, but I thought it might be worth asking, it could be that support for this was just an oversight or DMD limitation.
Object.factory() and module name
Creating a class instance from a string with Object.factory() method requires the name of the module: http://www.informit.com/articles/article.aspx?p=1381876seqNum=6 module main; Human person = cast(Human)Object.factory(main.Human); However, if one rename the module (let's say into newmain), he also has to replace all the occurences of main.Human into newmain.Human inside the same source file. The situation is somewhat worse if the default module name is kept, that is the name of the source file. Renaming the source file will instantly break use of the .factory() method and, if the programmer is not careful to test for !is null after each .factory(), things get easily corrupted. For these reasons, classes that belongs to the current module should (well, it's a proposal) allow a faster creation method. Proposals: Object.factory(Human); // idem as Object.factory(module name.Human); or Object.factory(.Human); // idem as Object.factory(module name.Human); or Object.factory(module.Human); // idem as Object.factory(module name.Human); The third proposal is, however, a bit cumbersome since requires the compiler to reinterpret part of a string, but it takes advantage of the fact that one canot name a module module. This way, one could rename source files without worrying for this issue. More, maybe it is better for the Object.factory() method to throw an exception instead of simply returning a null pointer (this will be seen even if the programmer forgot to test for null and is an alternative solution to the above proposals). Opinions?
Re: Object.factory() and module name
On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote: Alternatively, a function/variable could be provided inside the module, returning the module name as a string, so that one could write: Object.factory(__MODULE__, .Human);
Re: Array void init
On Friday, 26 April 2013 at 14:58:35 UTC, Luís Marques wrote: Should this be supported? double[8] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; (it's not supported at the moment) which reminds me about the proposal to allow declaration of static arrays with double[$] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; which is more convenient since one discovers a counting error only when compiles. Has a decision been reached for this issue? Currently in gdc: double[$] foo = [1.0, 2.0]; fails with main.d:18: Error: undefined identifier __dollar double[1] foo = [1.0, 2.0]; fails with main.d:18: Error: array initializer has 2 elements, but array length is 1 but double[4] foo = [1.0, 2.0]; is accepted, which is a bit strange (I think the compiler should give at least a warning if too many elements are reserved for an array).
Re: Object.factory() and module name
On Fri, 26 Apr 2013 17:36:31 +0200, eles wrote: On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote: Alternatively, a function/variable could be provided inside the module, returning the module name as a string, so that one could write: Object.factory(__MODULE__, .Human); Instead of modifying the library, why not simply do this yourself? Object.factory(__MODULE__ ~ .Human);
Re: Array void init
On Friday, 26 April 2013 at 15:45:27 UTC, eles wrote: which reminds me about the proposal to allow declaration of static arrays with double[$] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; Seems nice. double[4] foo = [1.0, 2.0]; is accepted, which is a bit strange (I think the compiler should give at least a warning if too many elements are reserved for an array). I just read that as the other are NaN/.init initialized, which seems reasonable. The dollar notation is better than the warning here, to say that the array initializer is the authoritative source of the array length.
Re: Object.factory() and module name
On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote: Proposals: Object.factory(.Human); // idem as Object.factory(module name.Human); Can't this one be done with a trivial change to the library, for strings known at compile time, by checking at compile time if the string starts with a dot? Would that be enough to alleviate the problem, or do you think more dynamic scenarios also suffer significantly from this limitation?
Re: Object.factory() and module name
BTW, I was working on a Object.factory scenario right now (!) and stumbled on the limitation that the class can only have a default constructor. Couldn't you call a non-default constructor by passing var args to Object.factory()?
Re: Object.factory() and module name
On Friday, 26 April 2013 at 15:36:32 UTC, eles wrote: On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote: Alternatively, a function/variable could be provided inside the module, returning the module name as a string, so that one could write: Object.factory(__MODULE__, .Human); I believe __MODULE__ will be available in the next release of dmd. https://github.com/D-Programming-Language/dmd/pull/1462 --rt
Re: InvalidMemoryOperationError when calling functions from destructors
Further inspection suggests that the BetaClass object I was accessing was already finalized by the time the AlphaClass object got around to trying to mess with it. Conclusion is that whether it's the in-destructor access or not, it's simply not safe to try to clean things up this way. I think I have a safer alternative. What was interesting is that even after the BetaClass object has been cleaned up, I can access any variables it may have contained. If, for example, it has an integer value that's publicly visible, I can still read that.(haven't tried writing.)
Re: Object.factory() and module name
On Friday, 26 April 2013 at 16:06:14 UTC, Luís Marques wrote: On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote: Proposals: Object.factory(.Human); // idem as Object.factory(module name.Human); Can't this one be done with a trivial change to the library, for strings known at compile time, by checking at compile time if the string starts with a dot? Would that be enough to alleviate the problem, or do you think more dynamic scenarios also suffer significantly from this limitation? The change may be trivial (and I think it is), but a decision must be reached first.
Re: Object.factory() and module name
On Friday, 26 April 2013 at 15:52:02 UTC, Justin Whear wrote: On Fri, 26 Apr 2013 17:36:31 +0200, eles wrote: On Friday, 26 April 2013 at 15:34:01 UTC, eles wrote: Alternatively, a function/variable could be provided inside the module, returning the module name as a string, so that one could write: Object.factory(__MODULE__, .Human); Instead of modifying the library, why not simply do this yourself? Object.factory(__MODULE__ ~ .Human); Sorry, this is what I intended to write, just put a comma instead of the tilda operator. However, I wasn't aware that the __MODULE__ symbol is predefined.
Re: Object.factory() and module name
On Friday, 26 April 2013 at 16:13:44 UTC, Luís Marques wrote: BTW, I was working on a Object.factory scenario right now (!) and stumbled on the limitation that the class can only have a default constructor. Couldn't you call a non-default constructor by passing var args to Object.factory()? This too, seems a good idea, but let's the more experienced to decide.
Re: Array void init
On Friday, 26 April 2013 at 15:59:32 UTC, Luís Marques wrote: On Friday, 26 April 2013 at 15:45:27 UTC, eles wrote: which reminds me about the proposal to allow declaration of static arrays with double[$] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; Seems nice. double[4] foo = [1.0, 2.0]; is accepted, which is a bit strange (I think the compiler should give at least a warning if too many elements are reserved for an array). I just read that as the other are NaN/.init initialized, which seems reasonable. The dollar notation is better than the warning here, to say that the array initializer is the authoritative source of the array length. I thought about it. However, it is not very nice. What if somebody types 1024 instead of 024 for an array length? The error could pass through the compiler and crash an out of memory after years of use. OTOH, I would like to be able to specify a partial initialization of the first elements of an array, then a default/imposed value for the remaining elements. So, what about: double[4] foo = [1.0, 2.0 .. ]; //initializes last 3 elements to 2.0 In this case, obviously, one cannot write double[$] foo = [1.0, 2.0 .. ]; //the compiler cannot deduce length of static array Speaking about the proposal of using $ in declaring static arrays whose elements the compiler is able to count (just like in the double[$] foo = [1.0, 2.0];) I wonder sometimes why so much reluctance to implement those simple changes (and almost obvious), while other more dramatic changes are sometimes taken in a rush. Do not ask for examples, it is a feeling mainly derived from the discussions about those @property-ies. Speaking about, what decision was reached to get rid of the compiler -property flag which is a monster per se? (changes the way the language is defined).
Re: 1 matches bool, 2 matches long
On 04/26/2013 12:03 AM, Maxim Fomin wrote: On Friday, 26 April 2013 at 02:13:03 UTC, Ali Çehreli wrote: On 04/25/2013 06:44 PM, Maxim Fomin wrote: On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote: Looks like value range propagation bug because 1 is integer literal and should be converted to long. There is no way for 1 to be converted to bool here That special conversion rule of literal 0 and literal 1 being implicitly convertible to false and true gets in the way. (from TDPL long is below int and it is the shortest way, value range propagation can work upwards, but the path would be longer). Ali Sorry but I am not aware of how 1 is converted to bool here. True, that 1 is convertible to true, Yes, through an implicit conversion. but here there is function with long parameter. Since the type of literal 1 is int, calling foo(long) would require an implicit conversion as well: from int to long. In the end, both functions are candidates because they both accept 1 by one implicit conversion. Ali
Re: Array void init
On Friday, 26 April 2013 at 14:58:35 UTC, Luís Marques wrote: Should this be supported? double[8] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; (it's not supported at the moment) Why would you ever want this? I can't even think of a hypothetical use case.
Re: 1 matches bool, 2 matches long
On 4/26/2013 6:51 AM, deadalnix wrote: The last time I experienced that feature was with a char getting casted to bool implicitly and then appended to a string, causing super weird behavior after when using the resulting (corrupted) string. void main() { bool b = 'c'; } dmd -c foo foo.d(4): Error: cannot implicitly convert expression ('c') of type char to bool
Re: 1 matches bool, 2 matches long
On 4/26/2013 5:01 AM, Robert Schadek wrote: Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than... I've used a language with no implicit casts. It didn't get better, and I have an enduring dislike of it.
Re: 1 matches bool, 2 matches long
On 4/26/2013 7:33 AM, deadalnix wrote: On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote: On 4/26/2013 12:07 AM, Maxim Fomin wrote: Regarding bool type as integer type is C atavism and should be abandoned. There's a very lng history of 0 being regarded as false and 1 as true - it goes well beyond C. That is true, but even in theses elder languages, bool is handled as a special case, and not as an regular integral type. For instance, when integral conversion to smaller type is done by applying a mask (or doing a modulo, this is the same thing in this case) it is done by comparing to 0 to compare to bool. I've also spent time with embedded systems that manipulated things by writing out 0's and 1's to ports, designed ABEL (a language for programming PLDs), and simply worked a lot with digital math. 0 and 1 being synonymous with false and true is deeply embedded. A bool is a one bit integer. I remember once a language that tried to define true and false as something other than 1 and 0. It was horrible.
Re: rvalue references
On Friday, April 26, 2013 14:15:07 Manu wrote: I mean is that the way that auto ref should work with non-templated functions is that auto foo(auto ref T param) {...} becomes auto foo(ref T param) {...} underneath the hood. Then when you pass an rvalue to it - e.g. foo(T(5)) - that gets translated to something like T __temp = T(5); foo(__temp); Then auto ref works with both lvalues and rvalues with only one function definition, and ref is unchanged in how it works (it still only accepts lvalues). Why bother with 'auto'? Why not just make this default behaviour? For the same reason that T doesn't take rvalues in C++ while const T does. There's a big difference between wanting an argument to be passed as efficiently as possible and specifically wanting to alter the argument being passed in. Plain ref is for cases where you explicitly want to mutate the argument. You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. - Jonathan M Davis
Re: 1 matches bool, 2 matches long
On Thursday, April 25, 2013 23:01:30 Walter Bright wrote: On 4/25/2013 10:49 PM, Ali Çehreli wrote: It certainly behaves that way but it isn't an integer type and that's why it is unintuitive. But it is an integer type. That was one of C's big mistakes. There's nothing whatsoever about bool that makes sense as an integral type. true and false have nothing to do with 1 and 0 or any other integeral values. Having non-boolean values such as 1 and 0 implicitly convert to bool under some set of circumstances can be very useful (which is why cast(bool) is implicitly used in conditions), but in the general case, it just causes bugs. The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? Emphatically yes. The main place where casting would be annoying - if conditions and loop conditions - already insert an explicit cast underneat the hood. Other cases should require explicit casts; otherwise, we're just going to have bugs as has already been pointed out in this thread and has come up a number of times previously in the newsroup (one of the favorites being foo ~ true). - Jonathan M Davis
Re: 1 matches bool, 2 matches long
On 04/26/2013 09:11 PM, Walter Bright wrote: On 4/26/2013 5:01 AM, Robert Schadek wrote: Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than... I've used a language with no implicit casts. It didn't get better, and I have an enduring dislike of it. What language? (In my experience it actually gets better.)
Re: rvalue references
On Friday, 26 April 2013 at 10:33:17 UTC, Timon Gehr wrote: On 04/26/2013 01:58 AM, Zach the Mystic wrote: But as you said, figuring out the rules for making the compiler smart enough to choose the right one seems like a hard task. I think it is easy. If it forwards to another 'auto ref' template parameter, it needs to descend into that template, determine *its* type of parameter, and then assign the type of its own parameter accordingly. ... No, when forwarding to another template, non-lazy parameters will always have an address, ref or not ref. This suggestion simplifies the problem greatly. Is the suggestion made precisely because it simplifies the problem, or do you also consider it better with regard to performance and safety? The cases where it makes a difference are auto ref returns, __traits(isRef, ...), and lazy auto ref parameters. (If there are more, they will be detected by grepping the compiler source for occurrences of the 'ref' storage class representation, presumably an enum value.) The compiler does not have to be particularly smart. IMO this is the way to generalize auto ref to non-template functions. I think it's useful to realize that if the end result of an action is the same, it's not necessary to know exactly how the compiler solved the problem. If both creating a temporary, and passing the argument to its own template-instantiated function produce the same semantics, then to some extent it doesn't matter how the compiler did it. That leaves the question of performance. If it were demonstrated that neither mechanism outperforms the other, then it *really* doesn't matter which it chooses.
Re: Reducing the inter-dependencies (in Phobos and at large)
26-Apr-2013 03:20, Zach the Mystic пишет: On Wednesday, 24 April 2013 at 19:33:51 UTC, Dmitry Olshansky wrote: 24-Apr-2013 20:08, qznc пишет: What are you actually worried about? Compile times? Program size? Startup time? It affects all of it. I don't know if you are right, but I think the case would be made visible and compelling with some benchmarks showing the compile time, executable size, and run-time differences between the existing mode and the proposed mode. So the keyword is evidence. I'll give it a go then. -- Dmitry Olshansky
Re: Reducing the inter-dependencies (in Phobos and at large)
26-Apr-2013 07:23, Jonathan M Davis пишет: On Wednesday, April 24, 2013 16:03:47 Dmitry Olshansky wrote: What we need is to re-arrange the module hierarchy (and we need that anyway) so that we split off the concept part of modules to a separate package. Thoughts? Other ideas? I'm a bit divided on the idea. On the one hand, it allows us to reduce interdependencies. On the other hand, it's definitely complicating the module hierarchy. This whole idea is a bit like the .h/.cpp or .di/.d separation. In general what I propose is a special case of reducing artificial dependencies due to coarse-grained modularization. Now C had a crude mechanism for hiding details and achieving modularization, we have proper modules (and OT: awful visibility rules). On the whole, I prefer the model of shoving it all in one file, but given that Phobos is the standard library (of a _systems_ language no less), the added complication may very well be worth the benefits in dependency reduction. Yup. Still, given that we're talking about templates here, most of it shouldn't end up in the generated executable or library if it's not used, and we've already been moving away from static constructors in Phobos, and global/module level variables should already be quite rare. Still not the case, hence the proposal. In general there are globals (and TLS) and they are useful in their own right and there is nothing better when you need that functionality. And once Phobos is a shared library, the few global/module level variables we have should cost even less. False - the cost is _always_ there as dynamic linker still has to pull that stuff off disk and run ctors/dtors. The only gain is that running multiple D binaries linked against the same phobos will share its code in memory. That and the binaries look small argument :) If D was the default systems language on some platform (like C does) it would also mean having run-time always there (thus you wouldn't have to ship it). So, I'm not sure that the extra complication is really worth it. If the compiler and linker are doing their job, the only real difference should be in how much the various modules in Phobos need to be parsed, which is very fast with dmd, and most programs of any size are going to pull in all of the dependencies anyway. Have you read the description? I gave the exact cases where regardless of templates or no templates you do pull in the module. This is a problem that defeat the whole goodness of generating only the code you use (via templates). In fact I'll post about more specific problem separately (need to gather the solid data). And I would question the most programs of any size are going to pull in all of the dependencies anyway. All programs are different. And I'm more concerned with Phobos itself and libraries. The proverbial sufficiently smart compiler that trims down things to establish true per symbol dependency may never come (unless we change compilation model at the same time) I'm inclined to avoid doing this if we don't really need to, but if there's a solid benefit to it, then it may be that we really should do something like this. Would have to show it then. One such benefit may as well be being able to avoid forward reference hell with the current compiler. Fake circular dependencies is the 2nd one. Thinking more of it - the idea would have been neat and elegant with a variation on DIP 15. Then std.xyz.trait would be the trait part of a package. http://wiki.dlang.org/DIP15 On a side note, given that we sometimes call eponymous templates like isForwardRange traits, calling the sub-module trait or traits rather than concepts might be better (probably std.trait given that std.traits is already taken, though that would probably then become std.trait.traits given that it's entirely made up of traits). Yeah, I thought as much. Concept has no established usage in D culture, so trait it is. -- Dmitry Olshansky
Re: Official D Grammar
On Saturday, 20 April 2013 at 08:31:34 UTC, Brian Schott wrote: This uses ANTLR, as the other parser generators can't handle D's grammar. I'm beginning to think that ANTRL is not up to the task either. I've somehow managed to get the grammar to the point where it correctly parses several phobos modules but takes a half hour to do so.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 19:37:48 UTC, Jonathan M Davis wrote: The main place where casting would be annoying - if conditions and loop conditions - already insert an explicit cast underneat the hood. IMO it still makes no sense to have the implicit casting done in conditional statements because it is not obvious why a given conditional should treat a zero differently than all other values. However at this stage retaining that old convention is perhaps unavoidable. At the very least, D should be minimizing the potential for programmers falling into the traps caused by non-intuitive implicit casting. In the case of bool, there's no obvious relationship with the int data type, so let's get rid of that arbitrary association, make casting explicit, and move on. --rt
Re: 1 matches bool, 2 matches long
On 4/26/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: An even better example: import std.stdio; void foo(bool x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(1); // 1 foo(false ? 2 : 1); // 2 } Kill it with fire.
Re: 1 matches bool, 2 matches long
On 4/26/2013 1:16 PM, Timon Gehr wrote: On 04/26/2013 09:11 PM, Walter Bright wrote: On 4/26/2013 5:01 AM, Robert Schadek wrote: Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than... I've used a language with no implicit casts. It didn't get better, and I have an enduring dislike of it. What language? (In my experience it actually gets better.) An early Pascal.
Re: 1 matches bool, 2 matches long
Whatever the choices are of whether bool is a 1-bit integer or a a logical true/false value, this should not happen: enum e = 1; void main() { foo(e); // bool } static e = 1; void main() { foo(e); // long } The reason being that according to the language spec, the constant 1 should be an int. Whether or not it implicitly converts to a bool, this means that enum e should have a type of int as well. The actual value shouldn't be taken into account when determining which overload to call, only the type should matter, and an unknown int value should implicitly convert to a long not a bool. Automatic conversion of 1 to bool should only be able to happen at the point where the literal is used if at all: enum bool e = 1; Ideally such an implicit conversion would only apply if it was the only possible valid implicit conversion, so this: foo(1) Should at least warn of the ambiguity. Compile-time conversions based on value rather than type are by definition going to break the type system. Therefore the only way to get 1 to normally be an int but automatically convert to a bool without being inconsistent is to effectively introduce a new type for the literal 1 which has the desired conversions (the same way that zero has a special type in C/C++ which can convert to both an integer or a pointer). The important thing is that this special type for 1 should never transfer to other things: the type of the literal should be fixed to a normal type at the point where it is used to prevent surprising the user (this is what C/C++ does). At the moment enum e = 1; transfers the special properties of 1 to e and I think that's more than a little surprising.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? The idea of a true number and a false number doesn't make sense, so yes.
Re: 1 matches bool, 2 matches long
On 4/26/2013 12:37 PM, Jonathan M Davis wrote: There's nothing whatsoever about bool that makes sense as an integral type. This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Take a look at this, for example: http://d.puremagic.com/issues/show_bug.cgi?id=9963 Mathematically, they behave like 1 bit integers and are useful that way.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote: A bool is a 1 bit integer type. .sizeof returns bytes, not bits, and says that bool is of size 1.
Re: rvalue references
You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. The only purpose of rvalue references is to allow the callee to mutate the value... Otherwise you would just use a const ref. In C++ you can do this: void foo(const int p) { } int bar() { return 1; } foo(1); // literals pass just fine by const reference foo(bar()) // and r-values... The only reason for r-value references is to implement move semantics (which means completely destroying the original value, and I think that counts as mutating it) And the only reason r-value references have a different syntax is so that you can override your function and provide two implementations: one which accepts rvalue references and is destructive, and the other which accept const references and makes a copy. The reason normal references couldn't be used in C++ is that normal non-const lvalues would cause the destructive overload to be called by default rather than the non-destructive one because they convert to T more easily than const T, and the desired behaviour is that for lvalues move semantics must be explicit to prevent surprises. An alternative I am in favour of is just to give the conversion to const T a higher priority than the conversion to T for lvalues, so that overloads that take both will normally choose the non-destructive one. To explicitly use the destructive form one can just explicitly cast to T or call a helper function T move(T) which just makes the syntax nicer. In D this would obviously be ref const(T) and ref T instead but the same ideas apply.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote: On 4/26/2013 12:37 PM, Jonathan M Davis wrote: There's nothing whatsoever about bool that makes sense as an integral type. This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Take a look at this, for example: Uh, uh, that's not a bool. It is a bit (binary digit, just to be sure). That is: a figure of the base 2. The very definition of bit. I still have to see some computer course introducing a byte/octet as a group of 8... booleans. No: boolean is a logical entity and is true or false, while the bit is a figure (a number) and is 0 or 1. They may overlay for programming purposes to some extent (a bijection, after all), but let's not take the one for another. Why the computer theory invented the notion of bit? The term of boolean was available for centuries.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott wrote: On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? The idea of a true number and a false number doesn't make sense, so yes. I find the current implementation perfectly intuitive and I wouldn´t want it any other way... it models the underlying hardware, just the way it should be. Sometimes due to bad coding standards I´m forced to write... if((.long expression with not immediately apparent operator precedence)!=0) ... absolutely appalling, kills readability with extra () etc. doesn´t matter how many years, I was forced to do it, I still cringe every time I see a line like that and itch to rewrite it more readable. I also dont know any book(including Knuth), nor online article, which doesn´t clearly define it as 0,1... am very confused by the reactions in this thread, is my background so different from everyone elses?
Re: 1 matches bool, 2 matches long
On 4/26/2013 1:59 PM, Diggory wrote: The actual value shouldn't be taken into account when determining which overload to call, only the type should matter, D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value. For example: ubyte b; b = 100;// ok b = 300;// error This has been very successful in reducing the noise of having to insert casts all over the place. For: enum e = 1; then e is a value that is known to be one. Hence VRP applies, and it can be implicitly cast to bool, ubyte, short, etc. For: static e = 1; the compiler cannot assume that e is always 1, hence e is treated as an int that could hold any value. Hence, it cannot be implicitly cast to bool, ubyte, short, etc. Ideally such an implicit conversion would only apply if it was the only possible valid implicit conversion, This was how D originally worked. However, it produced a list of foolish errors, and a lot of complaints. The current scheme attempts to resolve ambiguities by doing a partial ordering (described elsewhere in this thread). This has been very successful. To make use of overloading, there's no avoiding understanding this. A program that breaks due to different overloadings of: enum e = 1; static x = 1; is misusing overloading just like one that breaks on different overloads of: enum e = 3; static x = 4; I.e.: void foo(short) { ... back up my files ... } void foo(long) { ... launch nuclear missiles ... } is a bad program.
Re: 1 matches bool, 2 matches long
On 4/26/2013 1:59 PM, Andrej Mitrovic wrote: On 4/26/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: An even better example: import std.stdio; void foo(bool x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(1); // 1 foo(false ? 2 : 1); // 2 } Kill it with fire. How about this one: import std.stdio; void foo(short x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(3); // 1 foo(false ? 4 : 3); // 2 }
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:32:32 UTC, Tove wrote: On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott wrote: On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: Sometimes due to bad coding standards I´m forced to write... if((.long expression with not immediately apparent operator precedence)!=0) I assume you are doing C or C++. Under the preprocessor, why do not #define a ifnonzero() and a ifzero() macro, if that bothers you so much? (also works for testing against NULL). In D, it is less possible to do so (curse of lacking processor...). Or maybe it is and I am missing it.
Re: 1 matches bool, 2 matches long
Tove: Sometimes due to bad coding standards I´m forced to write... if((.long expression with not immediately apparent operator precedence)!=0) ... absolutely appalling, kills readability with extra () etc. I think here people are not asking to disallow that. A 0 and 1 can be false and true in a boolean evaluation context even if they don't implicitly cast to int in other situations. Bye, bearophile
Re: 1 matches bool, 2 matches long
On Friday, April 26, 2013 14:14:55 Walter Bright wrote: On 4/26/2013 12:37 PM, Jonathan M Davis wrote: There's nothing whatsoever about bool that makes sense as an integral type. This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Take a look at this, for example: http://d.puremagic.com/issues/show_bug.cgi?id=9963 Mathematically, they behave like 1 bit integers and are useful that way. Sure, it may be useful sometimes to have code that treats true as 1 and false as 0 for math, but I'd argue for casting being required for it, and in a large number of cases, casting would be required already due to the fact that it would be a narrowing conversion. But it seems very wrong to me that foo(1) would call a bool overload or that foo ~ true would compile. There have been a number of posts over time discussing bugs caused by that behavior being legal. I don't think that it's a huge problem, but I do think that it's a problem. However, we are clearly coming from very different points of view here. - Jonathan M Davis
Re: Reducing the inter-dependencies (in Phobos and at large)
On Saturday, April 27, 2013 00:26:05 Dmitry Olshansky wrote: Thinking more of it - the idea would have been neat and elegant with a variation on DIP 15. Then std.xyz.trait would be the trait part of a package. http://wiki.dlang.org/DIP15 We really do need a variant of DIP 15 or 16. I actually started looking into it briefly at one point, but that's way outside my area of expertise, and I'm annoyingly busy these days. - Jonathan M Davis
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote: On 4/26/2013 1:59 PM, Andrej Mitrovic wrote: On 4/26/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: An even better example: import std.stdio; void foo(bool x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(1); // 1 foo(false ? 2 : 1); // 2 } Kill it with fire. How about this one: import std.stdio; void foo(short x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(3); // 1 foo(false ? 4 : 3); // 2 } We all know that short and long are integer numerics, however most of us do not think of bool as being a 1 bit integer type. We expect values of 'true' and 'false' because D has explicit 'true' and 'false' values, which presumably are there because 1 and 0 which are not the same thing as 'true' and 'false', otherwise there would be no need for 'true' and 'false'. --rt
Re: rvalue references
On Friday, 26 April 2013 at 21:21:50 UTC, Diggory wrote: You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. The only purpose of rvalue references is to allow the callee to mutate the value... Otherwise you would just use a const ref. The forum I'm using suggests that your post was written in response to me, although it is not my writing!
Re: rvalue references
On Friday, April 26, 2013 23:21:49 Diggory wrote: You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. The only purpose of rvalue references is to allow the callee to mutate the value... Otherwise you would just use a const ref. Except that const ref doesn't accept rvalues, and D's const is _far_ more restrictive than C++'s const, so requiring that a parameter be const in order to not care whether it's given an rvalue or lvalue but still pass it efficiently would be a major negative. auto ref doesn't require or imply const, and it shouldn't. Granted, it should be logically const, but that can't be guaranteed by the type system without guaranteeing physical constness, which is often too strong a requirement. So, it would be a big mistake to make it so that constness had anything to do with our solution for passing arguments efficiently without caring about refness. - Jonathan M Davis
Re: 1 matches bool, 2 matches long
On Friday, April 26, 2013 14:34:45 Walter Bright wrote: D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value. VRP is a fantastic feature, but I think that it's coming back to bite us somewhat if foo(1) calls an overload which takes bool. - Jonathan M Davis
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote: void foo(short) { ... back up my files ... } void foo(long) { ... launch nuclear missiles ... } is a bad program. The government of North Korea would probably be perfectly happy with this program, but then again, that's a bad government.
Re: 1 matches bool, 2 matches long
On Fri, Apr 26, 2013 at 08:05:45PM -0400, Jonathan M Davis wrote: On Friday, April 26, 2013 14:34:45 Walter Bright wrote: D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value. VRP is a fantastic feature, but I think that it's coming back to bite us somewhat if foo(1) calls an overload which takes bool. [...] Does VRP work only with literals, or does it work with general variables (by inferring from, say, if-conditions)? void func(int i) { ubyte b; if (i = 0 i 256) { b = i; // OK without cast? } ... } T -- That's not a bug; that's a feature!
Re: rvalue references
On 27 April 2013 05:31, Jonathan M Davis jmdavisp...@gmx.com wrote: On Friday, April 26, 2013 14:15:07 Manu wrote: I mean is that the way that auto ref should work with non-templated functions is that auto foo(auto ref T param) {...} becomes auto foo(ref T param) {...} underneath the hood. Then when you pass an rvalue to it - e.g. foo(T(5)) - that gets translated to something like T __temp = T(5); foo(__temp); Then auto ref works with both lvalues and rvalues with only one function definition, and ref is unchanged in how it works (it still only accepts lvalues). Why bother with 'auto'? Why not just make this default behaviour? For the same reason that T doesn't take rvalues in C++ while const T does. There's a big difference between wanting an argument to be passed as efficiently as possible and specifically wanting to alter the argument being passed in. Plain ref is for cases where you explicitly want to mutate the argument. You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. So you're saying it should be const ref instead of auto ref... I agree.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 19:22:51 UTC, Walter Bright wrote: I remember once a language that tried to define true and false as something other than 1 and 0. It was horrible. Don't need to look far away. Most shell do that.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote: On 4/26/2013 12:37 PM, Jonathan M Davis wrote: There's nothing whatsoever about bool that makes sense as an integral type. This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Then why does it convert from int by comparing with 0 ? That isn't the behavior of an integral.
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:32:32 UTC, Tove wrote: On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott wrote: On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote: The real issue is do you want to have the implicit conversions: 0 = false 1 = true or would you require a cast? The idea of a true number and a false number doesn't make sense, so yes. I find the current implementation perfectly intuitive and I wouldn´t want it any other way... it models the underlying hardware, just the way it should be. Sometimes due to bad coding standards I´m forced to write... if((.long expression with not immediately apparent operator precedence)!=0) ... absolutely appalling, kills readability with extra () etc. doesn´t matter how many years, I was forced to do it, I still cringe every time I see a line like that and itch to rewrite it more readable. That is totally irrelevant as a cast is already inserted automatically.
Re: rvalue references
On Saturday, April 27, 2013 10:21:32 Manu wrote: Why bother with 'auto'? Why not just make this default behaviour? For the same reason that T doesn't take rvalues in C++ while const T does. There's a big difference between wanting an argument to be passed as efficiently as possible and specifically wanting to alter the argument being passed in. Plain ref is for cases where you explicitly want to mutate the argument. You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. So you're saying it should be const ref instead of auto ref... I agree. Not at all. const is so much more restrictive in D that it really doesn't make sense to have const be required in order to be able to pass an argument to a function efficiently without caring whether it's an rvalue or an lvalue. auto ref permits const but doesn't require it - which is what we need - whereas const ref is always const. I'm arguing that we need an attribute which differs from naked ref which indicates that the function doesn't care whether it's given an lvalue or an rvalue - it just wants it to be passed as efficiently as possible. auto ref is supposed to serve this purpose. Naked ref on the other hand is specifically for when the function needs to alter the argument and not a copy of the argument. const ref is ultimately kind of useless IMHO. The only real hangup with that at this point is that templated functions should be able to use the auto ref solution that non-templated functions should use (invisibly creating a variable when an rvalue is passed so that an lvalue can be passed), but we also need the current auto ref functionality that we have for templated functions. So, either we need a new attribute, or we need to do what Timon suggested and make the compiler smart enough to figure out when it can get away with using the non-templated auto ref solution with a templated function without changing the function's semantics. - Jonathan M Davis
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote: On 4/26/2013 1:59 PM, Andrej Mitrovic wrote: On 4/26/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: An even better example: import std.stdio; void foo(bool x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(1); // 1 foo(false ? 2 : 1); // 2 } Kill it with fire. How about this one: import std.stdio; void foo(short x) { writeln(1); } void foo(long x) { writeln(2); } void main() { foo(3); // 1 foo(false ? 4 : 3); // 2 } Walter, you're completely missing the point. The point is that people can live with the consequences of your short/long example, but they can't do the same with Andrej's bool/long example. No matter how right you are, if you keep insisting your way is correct, D will continue never becoming popular because people will continue finding it hard to use. I think at some point it's worth noticing that ease of use is _not_ a linear function of technical correctness. You may be right in technicality but that doesn't mean you're right on the UI side.
Re: 1 matches bool, 2 matches long
On Saturday, 27 April 2013 at 01:43:12 UTC, deadalnix wrote: On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote: On 4/26/2013 12:37 PM, Jonathan M Davis wrote: There's nothing whatsoever about bool that makes sense as an integral type. This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Then why does it convert from int by comparing with 0 ? That isn't the behavior of an integral. +1
Re: rvalue references
On 27 April 2013 12:26, Jonathan M Davis jmdavisp...@gmx.com wrote: On Saturday, April 27, 2013 10:21:32 Manu wrote: Why bother with 'auto'? Why not just make this default behaviour? For the same reason that T doesn't take rvalues in C++ while const T does. There's a big difference between wanting an argument to be passed as efficiently as possible and specifically wanting to alter the argument being passed in. Plain ref is for cases where you explicitly want to mutate the argument. You're just asking for bugs if you allow ref to accept rvalues. We've had problems like this before when some literals were treated as lvalues. The behavior of a function which takes its argument by ref and the behavior of one which takes its argument by auto ref are fundamentally different. So you're saying it should be const ref instead of auto ref... I agree. Not at all. const is so much more restrictive in D that it really doesn't make sense to have const be required in order to be able to pass an argument to a function efficiently without caring whether it's an rvalue or an lvalue. auto ref permits const but doesn't require it - which is what we need - whereas const ref is always const. I'm arguing that we need an attribute which differs from naked ref which indicates that the function doesn't care whether it's given an lvalue or an rvalue - it just wants it to be passed as efficiently as possible. auto ref is supposed to serve this purpose. Naked ref on the other hand is specifically for when the function needs to alter the argument and not a copy of the argument. const ref is ultimately kind of useless IMHO. The only real hangup with that at this point is that templated functions should be able to use the auto ref solution that non-templated functions should use (invisibly creating a variable when an rvalue is passed so that an lvalue can be passed), but we also need the current auto ref functionality that we have for templated functions. So, either we need a new attribute, or we need to do what Timon suggested and make the compiler smart enough to figure out when it can get away with using the non-templated auto ref solution with a templated function without changing the function's semantics. I don't see myself ever getting on board with this auto-ref idea. I just think it's crazy. It makes no sense to me, they are completely unrelated concepts. It will only lead to confusion. I'm back at scope-ref. Kenji is right as far as I'm concerned. Not to mention, he actually did the work. It makes perfect sense, and I can't see any reason why auto-ref should be used instead of something that actually makes intuitive sense, and people will eventually want to use anyway...
Re: rvalue references
I don't see myself ever getting on board with this auto-ref idea. I just think it's crazy. It makes no sense to me, they are completely unrelated concepts. It will only lead to confusion. I'm back at scope-ref. Kenji is right as far as I'm concerned. Not to mention, he actually did the work. It makes perfect sense, and I can't see any reason why auto-ref should be used instead of something that actually makes intuitive sense, and people will eventually want to use anyway... I'm against scope ref as the one thing scope means is that the parameter cannot be returned, and preventing rvalue references being returned breaks the one thing they are useful for. The primary use of rvalue references in C++ is so that these three cases work: vectorT vec; T t; vec.push_back(T()) // Move semantics (temporary is destroyed in the process) vec.push_back(t) // Copy semantics ('t' is unmodified) vec.push_back(move(t)) // Move semantics ('t' is destroyed in the process) This allows best efficiency (move is at least as fast as copy, so when the original is no longer needed a move should be performed) The way it works is that push_back() has two overloads: push_back(T v) { // Move 'v' into the vector, afterwards 'v' will have had its guts ripped out so to speak... } push_back(const T v) { // Copy 'v' into the vector, 'v' is unmodified } - r-values such as 'T()' will default to the first overload. - l-values such as 't' will default to the second overload. - 'move(t)' returns an r-value causing the first overload to be called. As you can see, using scope ref will break this third case because 'move()' won't be able to return an r-value, and if only the first two cases are going to be possible, this can be done without any special notion of r-value references anyway. I'm starting to think there does need to be new syntax if all three of the above cases are to be covered - it would work just making ref accept rvalues but then move would be the default for lvalues, and that would be confusing - but I don't think using scope solves any problems, as the semantics required for rvalues are orthogonal to what scope actually means. As good as it is to avoid adding new keywords, I think this might be a case where it's warranted...
Re: 1 matches bool, 2 matches long
On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote: On 4/26/2013 1:59 PM, Diggory wrote: The actual value shouldn't be taken into account when determining which overload to call, only the type should matter, D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value. For example: Then perhaps ban VRP on arguments if it affects overloading?
Re: Array void init
On Fri, 26 Apr 2013 07:58:34 -0700, Luís Marques luismarq...@gmail.com wrote: Should this be supported? double[8] foo = [1.0, 2.0, void, 3.0, 3.5, void, void, void]; (it's not supported at the moment) Have you considered what this does? Consider a standard [1.0, 2.0] call: In essence, it pushes 1.0 and 2.0 onto the stack, then calls a function to allocate the memory and use the given data. What will end up happening is the data is copied from the stack to the heap. It's just in your case, the data copied is garbage. I see little point in supporting this. -Steve
Re: Array void init
On Friday, 26 April 2013 at 17:58:04 UTC, John Colvin wrote: Why would you ever want this? I can't even think of a hypothetical use case. The questions started as academic, motivated by the apparent lack of orthogonality. As far as a practical scenario, right now this is the best I can come up with: // emulator, ROM and RAM accessible from the same bus (von Neumann) byte[1024] romAndRam = [0x42, 0x77, 0xAF, 0x44, void]; (this relies also on eles' suggestion, the void is assumed for the remaining elements -- the RAM part). I'm not saying that this should be supported. I was asking if something like this should be :-)
Re: 1 matches bool, 2 matches long
On Saturday, 27 April 2013 at 01:37:22 UTC, deadalnix wrote: On Friday, 26 April 2013 at 19:22:51 UTC, Walter Bright wrote: I remember once a language that tried to define true and false as something other than 1 and 0. It was horrible. Don't need to look far away. Most shell do that. D can still cast true to 1 and false to 0. It is solely the implicit casting that is inappropriate under rather common circumstances. --rt
Re: 1 matches bool, 2 matches long
Is this what some of you are asking for? bool a = true; // ok bool b = false;// ok bool c = 1; // error, no implicit conversion bool c = getInt();// error? ok? int x = 42; if(x) { ... } // ok (doesn't this imply c = getInt() ok too? if(42) { ... } // ok
How/why can toStringz() and toUTFz() be used as properties?
Hey all, Can someone please explain to me how and why it is that toStringz() and toUTFz() can be used in the following way? string a = 123; auto b = a.toStringz; auto c = a.toUTFz; Also, how is it that they can even be called as if they were class methods? That is: string a = 123; auto b = a.toStringz(); // -- Note I've added parentheses auto c = a.toUTFz(); As opposed to being limited to: string a = 123; auto b = toStringz(a); auto c = toUTFz(a); I need to understand this, as I wish to write a function toWinStr() that can be used in the same way which will accept any string type, and, based on something like version(Unicode) and const-ness, output a WinAPI LPSTR, LPCSTR, LPWSTR or LPCWSTR as appropriate. Is such a thing possible?