Re: DIP 45 - approval discussion
On Tuesday, 12 November 2013 at 07:16:03 UTC, Andrei Alexandrescu wrote: That really proves nothing. That doesn't prove anything. But that doesn't smell good for the usefulness of the feature either. I have bunch of D code in there, not simply mine. So first thing : it is unused. Secondly, the only useful things you can do with that require to upcast (and break basic OOP principle, which is kind of ironic for a feature that produce objects). The design of the feature is unsound. I think you're wrong here (even after one discounts for s/upcast/downcast/). There's no breakage of any basic OOP principle. There's no irony. Polymorphic creation aka the factory pattern is a classic in object-oriented design. You'd have a bad time arguing against it with anyone. A Factory is always a factory of something. A factory fit nicely into the OOP paradigm as it allow the user of the object to not know what is the actual type of the object, but its interface. A factory is also in charge of all the work necessary to put the object in a useful state. Object.factory do not allow any of this. It doesn't make any sense to provide a factory of everything. The factory user will have to know what is built, at least partially to use it. This defeat the whole principle of a factory. It is not that surprising as different possible uses case are better solved with compile time reflection and metaprograming. These don't take care of the dynamic case, which is sometimes needed (wherever factories are useful: serialization, scripting, ...). It is actually quite easy to create runtime capabilities from these basic blocs. CTFE allow to create AA, and at this point, the user can get whatever is desired at runtime. This feature has more to do with runtime reflection than OOP. Implementationwise, this feature require to pull into the application some unoptimizable bloat. This is a good point. But I presume the dedicated code is small in size. The code in itself isn't really the problem. The compiler have to emit a bunch of wiring to make it work. Wiring which is almost never used. Basically, the compiler have to emit runtime reflection informations, but just for classes. This seems to be the wrong tradeoff : we get the constraint of runtime reflection in term of design, but with very limited benefices. It is also a tedious constraint for shared objects as we see in this thread. My reading of the thread is that there are concerns about DIP 45 beyond support of factories for shared objects. This is A concern. Surely not the only one. That is why I didn't expanded myself on the subject in the first place. Simply that if we had to choose between this DIP and Object.factory, it is a braindead choice.
Re: D parsing
On 2013-11-12 08:52, Andrei Alexandrescu wrote: Fine, although a sense of futility is hard to shake seeing as we won't replace those existing features. I think a much stronger point would be made if the power of the feature were demonstrated on problems not accessible with the existing ones. You just said we shouldn't replace existing features. "The point here is that there is significant difficulty to remove features that already exist" http://forum.dlang.org/thread/bwsofbnigfbrxwoui...@forum.dlang.org?page=9#post-l5s44b:242c36:241:40digitalmars.com About DIP 50: I will say "no" but please do not take it personally. It's great there is discussion about this, and I encourage it, but at this time I think we should make no plans to add macros to D. I don't think we should add macros now either. This proposal is far from ready. If Martin hadn't suggested I should create a DIP, I wouldn't have, at least now at this time. BTW, just saying "no" doesn't help a bit. You could just have said "foo". That's extremely annoying. You're shooting down very many suggestions/proposal/ideas with just a "no", or the more elaborated answer "no, never going to happen". On the other hand when you have a proposal it should be consider pre-approved and is a more of a FYI. -- /Jacob Carlborg
Re: D parsing
On 11/11/13 11:50 PM, Jacob Carlborg wrote: On 2013-11-12 03:35, Andrei Alexandrescu wrote: So... there is rote addition to the context.caller structure. It's just spelled differently. No? Have you seen the other posts? Yes. Don't assume whoever disagrees with you is misinformed. Have even read the proposal? Yes. If you think that I just want a different syntax for __LINE__ and __FILE__ you're way, way off. That's just an extremely small part of the proposal. __LINE__ and __FILE__ would not be removed. This is putting words in my mouth. Andrei
Re: D parsing
On 2013-11-12 09:00, Andrei Alexandrescu wrote: Yes. Don't assume whoever disagrees with you is misinformed. I absolutely do not. But when I read this: "An argument for macros would have to do a lot more than 'we don't need __FILE__ etc. anymore'" I find it hard to believe anything else. http://forum.dlang.org/thread/bwsofbnigfbrxwoui...@forum.dlang.org?page=8#post-l5p5b8:241kju:241:40digitalmars.com -- /Jacob Carlborg
Re: AA literals/initialisation
On Monday, 11 November 2013 at 11:39:06 UTC, Daniel Murphy wrote: "Manu" wrote in message news:mailman.355.1384158631.9546.digitalmar...@puremagic.com... immutable string[string] priorityMap = [ "1" : "blocker", "2" : "critical", "3" : "critical", "4" : "major", "5" : "major", "6" : "major", "7" : "minor", "8" : "minor", "9" : "trivial" ]; main.d(56): Error: non-constant expression ["1":"blocker", "2":"critical", "3":"critical", "4":"major", "5":"major", "6":"major", "7":"minor", "8":"minor", "9":"trivial"] This is tedious, how long has it been now? Seriously, static map's are super-important, they should be able to be made immutable, and also be able to be initialised. Maybe this could be factored into the improvements for 2.065? I think yes, it can be done for 2.065. Someone remind me if we get close and it isn't done yet. IIRC the poor performance of array literals and AA literals is because they're not always literals, sometimes they are variables (!) and the compiler assumes the worst case. You are allowed to write: void foo(int some_param) { immutable string[int] = [ 1: "abc", some_param: "def"]; } I wish we could get rid of that silliness entirely. If the members are compile-time expressions, you probably want to mark the variable as static const/static immutable.
Re: Sorting floating-point values, and NaN
On Tuesday, November 12, 2013 05:41:55 Vladimir Panteleev wrote: > double[] arr = [1, 2, 3, double.nan, 1, 2]; > assert(arr.isSorted); > arr.sort(); > > This code will fail with an assert error, but not the one on the > second line. Rather, it will fail inside std.range, when sort > calls assumeSorted, which checks elements in an order different > than sort and isSorted. > > Here's a case where the odd way NaN interacts with generic code > messes things up in an ugly way. > > This is concerning. It's very easy to overlook this while writing > an application, and it can become a hidden vulnerability. > > We can't fix the operators... but, perhaps, we could define a > safe default comparison predicate (e.g. std.algorithm.less) for > use with sorting and related tasks? Aside from bitwise > comparison, is it even possible to efficiently compare > floating-point values in a way suitable for sorting? The check could be special-cased for floating point values so that it takes NaN into account, but NaN pretty much screws with everything. Once it's there, pretty much anything involving math or comparisons is going to go bad. So, you could argue that it's a bug in the program if sort is passed a NaN and that the assertion in sort is therefore perfectly valid. You can't really sort anything with NaN in it anyway. - Jonathan M Davis
Re: DIP 45 - approval discussion
On 2013-11-12 08:52, Jacob Carlborg wrote: I used it in my serialization library, Orange, and it will be used in std.serialization when I finish that project. Well, technically I'm using ClassInfo.find. -- /Jacob Carlborg
Re: D parsing
On 11/12/13 12:09 AM, Jacob Carlborg wrote: On 2013-11-12 09:00, Andrei Alexandrescu wrote: Yes. Don't assume whoever disagrees with you is misinformed. I absolutely do not. But when I read this: "An argument for macros would have to do a lot more than 'we don't need __FILE__ etc. anymore'" I find it hard to believe anything else. http://forum.dlang.org/thread/bwsofbnigfbrxwoui...@forum.dlang.org?page=8#post-l5p5b8:241kju:241:40digitalmars.com It's very simple. Timon got into that part as if it were important. I pointed out it's not important. Andrei
Re: D parsing
On 11/12/13 12:02 AM, Jacob Carlborg wrote: On 2013-11-12 08:52, Andrei Alexandrescu wrote: Fine, although a sense of futility is hard to shake seeing as we won't replace those existing features. I think a much stronger point would be made if the power of the feature were demonstrated on problems not accessible with the existing ones. You just said we shouldn't replace existing features. "The point here is that there is significant difficulty to remove features that already exist" http://forum.dlang.org/thread/bwsofbnigfbrxwoui...@forum.dlang.org?page=9#post-l5s44b:242c36:241:40digitalmars.com Yes. So I said. I don't get why you'd provide a link - it's in my text that you quote. Indeed, we shouldn't replace existing features. About DIP 50: I will say "no" but please do not take it personally. It's great there is discussion about this, and I encourage it, but at this time I think we should make no plans to add macros to D. I don't think we should add macros now either. This proposal is far from ready. If Martin hadn't suggested I should create a DIP, I wouldn't have, at least now at this time. Fine. BTW, just saying "no" doesn't help a bit. You could just have said "foo". That's extremely annoying. You're shooting down very many suggestions/proposal/ideas with just a "no", or the more elaborated answer "no, never going to happen". On the other hand when you have a proposal it should be consider pre-approved and is a more of a FYI. So how could we express a "no" that doesn't annoy you in the extreme? In case the answer would be "you haven't explained why", allow me to retort. I've mentioned the argument before: at this point we should focus on quality of implementation and making good use of the features we have. In fact I am repeating myself: http://goo.gl/1thq1j. As has been publicly known for a while now, our strategy has been to improve quality and to double down on the assets we have. People ask for a roadmap, and what's missing from a roadmap is as important as what's there. This is a strategy that Walter and I agree with, have been transparent about, and that may work or not, with various degrees of success. Reasonable people may disagree what the best step moving forward should be, but at some point some step must be made and we can't adopt your strategy, with which we disagree, as our strategy, just to be nice and not offend your sensibility. (I'm using "we" here because Walter and I discussed this at large.) There must be a way to say "no" that doesn't offend you. Please advise what that is. Andrei
Re: D parsing
On 2013-11-12 09:14, Andrei Alexandrescu wrote: It's very simple. Timon got into that part as if it were important. I pointed out it's not important. Ok, fair enough. I'm sorry for wrongly interpreting it. -- /Jacob Carlborg
Re: D parsing
On 2013-11-12 09:13, Andrei Alexandrescu wrote: So how could we express a "no" that doesn't annoy you in the extreme? In case the answer would be "you haven't explained why", allow me to retort. I've mentioned the argument before: at this point we should focus on quality of implementation and making good use of the features we have. In fact I am repeating myself: http://goo.gl/1thq1j. As has been publicly known for a while now, our strategy has been to improve quality and to double down on the assets we have. People ask for a roadmap, and what's missing from a roadmap is as important as what's there. This is a strategy that Walter and I agree with, have been transparent about, and that may work or not, with various degrees of success. Reasonable people may disagree what the best step moving forward should be, but at some point some step must be made and we can't adopt your strategy, with which we disagree, as our strategy, just to be nice and not offend your sensibility. (I'm using "we" here because Walter and I discussed this at large.) There must be a way to say "no" that doesn't offend you. Please advise what that is. Thank you for the explanation. I do understand your and Walter's position in this. Just giving a short reason, to accompany the "no" with helps a lot. It doesn't need to be as long as the explanation above, just a sentence, like: "no, at this time we don't want to make such a big change, we're trying to stabilize". This is not just for me. I'm hoping proposal from others also can get a fair reason to why the "no". -- /Jacob Carlborg
Re: D parsing
On 11/12/13 12:31 AM, Jacob Carlborg wrote: Just giving a short reason, to accompany the "no" with helps a lot. It doesn't need to be as long as the explanation above, just a sentence, like: "no, at this time we don't want to make such a big change, we're trying to stabilize". This is not just for me. I'm hoping proposal from others also can get a fair reason to why the "no". OK, thanks. I'll do my best to improve on that in the future. Andrei
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 07:33:57 UTC, qznc wrote: On Tuesday, 12 November 2013 at 04:41:56 UTC, Vladimir Panteleev wrote: double[] arr = [1, 2, 3, double.nan, 1, 2]; assert(arr.isSorted); arr.sort(); This code will fail with an assert error, but not the one on the second line. Rather, it will fail inside std.range, when sort calls assumeSorted, which checks elements in an order different than sort and isSorted. Here's a case where the odd way NaN interacts with generic code messes things up in an ugly way. This is concerning. It's very easy to overlook this while writing an application, and it can become a hidden vulnerability. We can't fix the operators... but, perhaps, we could define a safe default comparison predicate (e.g. std.algorithm.less) for use with sorting and related tasks? Aside from bitwise comparison, is it even possible to efficiently compare floating-point values in a way suitable for sorting? You cannot sort NaNs. A comparison with NaN must always evaluate to false. One could change isSorted to check for false instead of true, so it would accept NaN. That would probably break too much code, though. arr[n] < arr[n+1] => !(arr[n+1] < arr[n]) But that is exactly what it does. https://github.com/D-Programming-Language/phobos/blob/8372da44f66f20c67b69b4b8fb39233ce42d493c/std/algorithm.d#L10021 And that is the reason the second line "assert(arr.isSorted);" passes, while it should fail as the array is clearly not sorted. Instead modifying !(arr[n+1] < arr[n]) => arr[n] <= arr[n+1] would make the function work correctly (return false if the range contains nans), but then the template parameter "less" should be replaced by "lessOrEqual". An alternative would be to check for nans explicitly.
Re: DIP 45 - approval discussion
On 11/11/13 11:58 PM, deadalnix wrote: On Tuesday, 12 November 2013 at 07:16:03 UTC, Andrei Alexandrescu wrote: That really proves nothing. That doesn't prove anything. But that doesn't smell good for the usefulness of the feature either. My code doesn't use that, either. But it also doesn't use things like .toString for classes. It's just that I don't do much OOP in D - doesn't mean OOP and/or factory etc are bankrupt. I think you're wrong here (even after one discounts for s/upcast/downcast/). There's no breakage of any basic OOP principle. There's no irony. Polymorphic creation aka the factory pattern is a classic in object-oriented design. You'd have a bad time arguing against it with anyone. A Factory is always a factory of something. A factory fit nicely into the OOP paradigm as it allow the user of the object to not know what is the actual type of the object, but its interface. Yes. Generalized, it stands to reason that Object (as the most inclusive class type) could plausibly have a factory. A factory is also in charge of all the work necessary to put the object in a useful state. Object.factory do not allow any of this. But default class constructors can be elaborate, so one can assume the default constructor puts the object in a useful state. Granted, we could have added constructors with e.g. Variant parameters. But that would be just an enhancement. It doesn't make any sense to provide a factory of everything. The factory user will have to know what is built, at least partially to use it. This defeat the whole principle of a factory. I don't see any defeating here. I do see a desire to specialize factories for specific subhierarchies, which is entirely fine. I don't see how that doesn't make a factory dealing in Object bad. It is not that surprising as different possible uses case are better solved with compile time reflection and metaprograming. These don't take care of the dynamic case, which is sometimes needed (wherever factories are useful: serialization, scripting, ...). It is actually quite easy to create runtime capabilities from these basic blocs. CTFE allow to create AA, and at this point, the user can get whatever is desired at runtime. What's missing is a list of all class types in the system. This is a fundamental issue with factories. This feature has more to do with runtime reflection than OOP. Implementation-wise, yes. Conceptually, people often see them as virtual constructors (i.e. an OOP notion extended to construction). Implementationwise, this feature require to pull into the application some unoptimizable bloat. This is a good point. But I presume the dedicated code is small in size. The code in itself isn't really the problem. The compiler have to emit a bunch of wiring to make it work. Wiring which is almost never used. Basically, the compiler have to emit runtime reflection informations, but just for classes. One question would be whether the same work is needed for e.g. typeid() or toString. If not, maybe there is a case against factory. This seems to be the wrong tradeoff : we get the constraint of runtime reflection in term of design, but with very limited benefices. I don't see how the existing system prevents you from rolling your own. It is also a tedious constraint for shared objects as we see in this thread. My reading of the thread is that there are concerns about DIP 45 beyond support of factories for shared objects. This is A concern. Surely not the only one. That is why I didn't expanded myself on the subject in the first place. Simply that if we had to choose between this DIP and Object.factory, it is a braindead choice. The time difference is crucial here. If this DIP came up in 2006 (when I estimate we introduced Object.factory) probably a lot of things would have come down differently. Proposals made in different epochs are, I think, very difficult to compare. Andrei
Re: D parsing
On 2013-11-12 09:37, Andrei Alexandrescu wrote: OK, thanks. I'll do my best to improve on that in the future. Thanks again. Sorry for being frustrated. -- /Jacob Carlborg
Re: DIP 50 - AST macros
On 11/10/2013 1:20 PM, Jacob Carlborg wrote: I've been thinking quite long of how AST macros could look like in D. I've been posting my vision of AST macros here in the newsgroup a couple of times already. I've now been asked to create a DIP out of it, so here it is: http://wiki.dlang.org/DIP50 I confess I have some serious reservations about AST macros in general: 1. I've seen very heavy use of such macros in macro assemblers. What happens is people use it to invent their own (very baroque) language on top of the existing assembler one. Anyone trying to read the code has to learn this new unique language, and given the limitations of the macro capability, it often comes with unfixable bizarre corner cases and limitations. This got so bad that in some cases I know of, the poor sap who is given the job of making improvements resorted to running the assembler to generate an object file, then disassembling the object file back into source code! Something went very wrong for this to be necessary. I know in my own assembler work I have abandoned all use of macros. (Note that macros in typical assemblers are far more powerful than C's macro language, which stands out for being pathetically underpowered.) 2. Macros are something that should be used very sparingly. However, this is not what happens. I used to be perplexed that even top shelf C/C++ programmers tend to write what I not so humbly consider to be pretty abusive use of macros. Now it just saddens me. 3. Lisp is a language that encourages users to write macros to pretty much invent a custom language for the task at hand. Heavy use of such makes the code unrecognizable as being Lisp code. I believe a language ought to have some "anchors" that the person reading the code can reliably recognize. (GO has taken this idea pretty far.) 4. AST macros, pretty much by definition, manipulate the AST. However, if you examine the semantic routines in DMD, a *lot* more is required to do more significant things. The symbol table must be consulted, etc. I just don't see how one could hope to implement something like function overloading with AST macros. Or template type deduction. Or closure semantics, attribute inference, etc. Sure, some forms of foreach can be rewritten into for statements by manipulating the AST, but not the more interesting forms, such as the ones that deal with opApply(). There are some statements in the DIP about the Context parameter and it'll provide semantic information, but I don't see how this can work without making it an ever-expanding collection of arbitrary methods. 5. We've said "no" in the past to things like user-defined tokens, which are closely related. 6. Note that D has a limited form of AST macros with mixin templates. To sum up, any AST macro proposal has some tough barriers to get over. Within its necessarily severe semantic limitations, it has to deliver a pretty compelling set of solutions, while avoiding the morass of incomprehensibility that far too many macro systems become in practice. For example, the Linq example in the DIP is not compelling, as aesthetically nicer code can be written using D's ranges and algorithms: auto data = arr.filter!(x => x > 5).array; I see no compelling advantage in trying to make D code look like C#; to be blunt it's like the old: #define BEGIN { #define END } macros used in old C code to make it look like Pascal.
Re: DIP 45 - approval discussion
Am 12.11.2013 09:50, schrieb Andrei Alexandrescu: The time difference is crucial here. If this DIP came up in 2006 (when I estimate we introduced Object.factory) probably a lot of things would have come down differently. Proposals made in different epochs are, I think, very difficult to compare. Andrei Wait. Whats the actual issue here? This DIP does not prevent object.factory from working across DLL boundaries. This DIP does also not conflict with object.factory. So what is the actual problem at hand?
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 08:54:35 UTC, tn wrote: On Tuesday, 12 November 2013 at 07:33:57 UTC, qznc wrote: On Tuesday, 12 November 2013 at 04:41:56 UTC, Vladimir Panteleev wrote: double[] arr = [1, 2, 3, double.nan, 1, 2]; assert(arr.isSorted); arr.sort(); This code will fail with an assert error, but not the one on the second line. Rather, it will fail inside std.range, when sort calls assumeSorted, which checks elements in an order different than sort and isSorted. Here's a case where the odd way NaN interacts with generic code messes things up in an ugly way. This is concerning. It's very easy to overlook this while writing an application, and it can become a hidden vulnerability. We can't fix the operators... but, perhaps, we could define a safe default comparison predicate (e.g. std.algorithm.less) for use with sorting and related tasks? Aside from bitwise comparison, is it even possible to efficiently compare floating-point values in a way suitable for sorting? You cannot sort NaNs. A comparison with NaN must always evaluate to false. One could change isSorted to check for false instead of true, so it would accept NaN. That would probably break too much code, though. arr[n] < arr[n+1] => !(arr[n+1] < arr[n]) But that is exactly what it does. https://github.com/D-Programming-Language/phobos/blob/8372da44f66f20c67b69b4b8fb39233ce42d493c/std/algorithm.d#L10021 And that is the reason the second line "assert(arr.isSorted);" passes, while it should fail as the array is clearly not sorted. Instead modifying !(arr[n+1] < arr[n]) => arr[n] <= arr[n+1] would make the function work correctly (return false if the range contains nans), but then the template parameter "less" should be replaced by "lessOrEqual". An alternative would be to check for nans explicitly. Actually, you could also use "!>=" instead of "<" so that the compasison would become: !(arr[n+1] !>= arr[n]) This is also correct for floating point numbers. However, it might be problematic for user defined types that also implement something similar to nan (eg. bigfloat). I could not find any documentation on how the unordered comparison operators (<>, !<>=, !<=, !<, !>=, !>, !<>) translate into opCmp calls.
Re: D parsing
On 11/4/2013 11:27 PM, Brian Schott wrote: Seriously. We don't have a real grammar for D. We have the language spec on dlang.org, but it isn't complete, consistent, or updated when the language changes. Want examples? I have a tracker for them here: http://d.puremagic.com/issues/show_bug.cgi?id=10233 Thank you, Brian, for finding and reporting these issues.
Re: Sorting floating-point values, and NaN
On 11/12/2013 1:33 AM, tn wrote: I could not find any documentation on how the unordered comparison operators (<>, !<>=, !<=, !<, !>=, !>, !<>) translate into opCmp calls. That's because they just don't translate to opCmp calls. At one point I was going to set up an opExtendedCmp or something like that for those operators, but then we went ahead and deprecated those operators, rendering the idea moot.
Re: Sorting floating-point values, and NaN
On Tuesday, November 12, 2013 10:33:26 tn wrote: > I could not find any > documentation on how the unordered comparison operators (<>, > !<>=, !<=, !<, !>=, !>, !<>) translate into opCmp calls. As I understand it, they only work with the built-in floating point types and are supposed to be deprecated. So, writing new code which uses them - particularly generic code - wouldn't make sense. - Jonathan M Davis
Re: DIP 50 - AST macros
I forgot to mention that "expression templates" can be used in D in an equivalent manner that they are used in C++, and can cover much of the functionality used in AST macros. Eric Anderton who wrote a regex expression template module a few years back: http://www.dsource.org/projects/ddl/browser/trunk/meta/regex.d
Re: AA literals/initialisation
"Don" wrote in message news:bdmmimwuqsgphgprd...@forum.dlang.org... > > IIRC the poor performance of array literals and AA literals is because > they're not always literals, sometimes they are variables (!) and the > compiler assumes the worst case. You are allowed to write: > > void foo(int some_param) > { > immutable string[int] = [ 1: "abc", some_param: "def"]; > } > > I wish we could get rid of that silliness entirely. > > > If the members are compile-time expressions, you probably want to mark the > variable as static const/static immutable. Yeah, IIRC the missing piece is putting AAs in the data segment so they can cross from compile to run-time with out an aaliteral call. At least then we could use enum aas in runtime code without allocating. It would be great if we could make aa literals default to immutable (array literals too), and force adding .dup to get a mutable version.
Re: DIP 50 - AST macros
On 11/12/2013 1:55 AM, Walter Bright wrote: I forgot to mention that "expression templates" can be used in D in an equivalent manner that they are used in C++, and can cover much of the functionality used in AST macros. Eric Anderton who wrote a regex expression template module a few years back: http://www.dsource.org/projects/ddl/browser/trunk/meta/regex.d Here's a project to add Linq support to C++: http://www.codeproject.com/Articles/17844/CLinq-LINQ-support-for-the-C-CLI-language There's also: http://pfultz2.github.io/Linq/ https://github.com/hjiang/linqxx/wiki
What’s Wrong with OOP and FP
I think you will be pleased with the argument, given D's philosophy: https://yinwang0.wordpress.com/2013/11/09/oop-fp/
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 09:55:20 UTC, Walter Bright wrote: I forgot to mention that "expression templates" can be used in D in an equivalent manner that they are used in C++, They are crippled compared to C++, because you have no control over the return type of opCmp and opEquals, which means that you can't have expression templates involving comparisons. That's extremely limiting. My feeling with AST macros is: (1) AST macros are basically syntax sugar for string mixins. The one and only thing that string mixins have in their favour, is that they have almost no syntax. But that is actually a *huge* plus. Because it's syntax sugar, an AST macro syntax would be most convincing if you took some existing string mixins from various real projects, and show how beautiful they would become with macros. (2) The big functionality we don't have, is comprehensive reflection. I'd like to see more thought in that area. It seems challenging to define reflection in a way that doesn't expose compiler internals. The question I find particularly interesting is, "if we had macros, would reflection look different?"
Re: What’s Wrong with OOP and FP
On Tuesday, November 12, 2013 12:09:23 =?UTF-8?B?Ikx1w61z?=.Marques @puremagic.com wrote: > I think you will be pleased with the argument, given D's > philosophy: > > https://yinwang0.wordpress.com/2013/11/09/oop-fp/ Yeah. Both OO and functional programming are useful, but trying to use any one paradigm exclusively always ends up contorting things. To make this clean, you really need to be able to mix and match paradigms as appropriate. On a related note, a classic blog post that I quite like on how Java takes OO too far is http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html The balanced approach that C++ and D take is definitely the better one IMHO (and D tends to do it better IMHO, since it better supports functional programming than C++ does, meaning that you end up with fewer FP solutions in C++ even when they'd be appropriate). - Jonathan M Davis
Re: What’s Wrong with OOP and FP
Also, in the spirit of non-technical discussion, pro-D stuff, see slide 26: http://www.slideshare.net/jpetazzo/docker-and-go-why-did-we-decide-to-write-docker-in-go
Re: What’s Wrong with OOP and FP
On Tuesday, 12 November 2013 at 11:27:51 UTC, Jonathan M Davis wrote: On Tuesday, November 12, 2013 12:09:23 =?UTF-8?B?Ikx1w61z?=.Marques @puremagic.com wrote: I think you will be pleased with the argument, given D's philosophy: https://yinwang0.wordpress.com/2013/11/09/oop-fp/ Yeah. Both OO and functional programming are useful, but trying to use any one paradigm exclusively always ends up contorting things. To make this clean, you really need to be able to mix and match paradigms as appropriate. On a related note, a classic blog post that I quite like on how Java takes OO too far is http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html If Java takes OO too far, what to say about Smalltalk and derivatives? The balanced approach that C++ and D take is definitely the better one IMHO (and D tends to do it better IMHO, since it better supports functional programming than C++ does, meaning that you end up with fewer FP solutions in C++ even when they'd be appropriate). - Jonathan M Davis The future belongs to multi-paradigm languages, I would say. What I miss still in languages like D, is the Hindley–Milner type inference, algebraic data types and pattern matching. -- Paulo
Re: What’s Wrong with OOP and FP
Luís Marques: https://yinwang0.wordpress.com/2013/11/09/oop-fp/ From the article: but you can also write pure functions in C, for example: int f(int x) { int y = 0; int z = 0; y = 2 * x; z = y + 1; return z / 3; } You can do the same with assembly language too. Pure functions don’t just belong to purely functional languages. You can write pure functions in any language, but the important thing is, you should be allowed to use side-effects too. Do you want to inform that author about the purity in D? :-) Bye, bearophile
Re: What’s Wrong with OOP and FP
On Tuesday, 12 November 2013 at 11:39:23 UTC, Luís Marques wrote: Also, in the spirit of non-technical discussion, pro-D stuff, see slide 26: http://www.slideshare.net/jpetazzo/docker-and-go-why-did-we-decide-to-write-docker-in-go Yes, Go has a big PR rolling machine on the web. Given its spartan set of features and religious decisions, I doubt anyone would care, if it wasn't being developed at Google. On the other hand, more people using strong typed languages with GC support as C and C++ replacement, is always positive. Hopefully D will also have a piece of the pie. -- Paulo
Re: What’s Wrong with OOP and FP
Paulo Pinto: What I miss still in languages like D, is the Hindley–Milner type inference, algebraic data types and pattern matching. Global type inference is too much complex in D, because of Turing-complete templates, OOP, very weak interfaces between modules in presence of separate compilation, etc, so it can't be done or it will become too much hard/complex/slow to do, so it's better to forget about it. Also, even in Haskell it's a good practice to write down the type signature of all global functions. The algebraic data types are handy, and Algebraic should improve (and if needed some feature should be added to D to make Algebraic better!). Regarding pattern matching, it introduces a significant complexity, but a limited form of it could be a good idea for D, with improvements in the switch and introducing an optional standard method unapply for structs and classes: https://d.puremagic.com/issues/show_bug.cgi?id=596 Bye, bearophile
Re: Early review of std.logger
On Tuesday, 5 November 2013 at 02:51:54 UTC, SomeDude wrote: We added it. I don't know of any logging library doing that. It's BufferingForwardingAppender in log4net. We use it to improve logging performance.
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 09:20:07 UTC, Walter Bright wrote: 5. We've said "no" in the past to things like user-defined tokens, which are closely related. Regarding this point, I get that arbitrary expansion is out, but would you be amenable to adding a small, _strictly-defined_ set of operators that are compile-time errors unless overloaded? #define BEGIN { #define END } macros used in old C code to make it look like Pascal. A plague o' their houses! -Wyatt
Re: Thoughts about D package management on Gentoo
On Tuesday, 12 November 2013 at 06:37:03 UTC, Marco Leise wrote: GCC releases are as often as D releases now when I compare the 4.8.x series with the last D versions: 2 to 5 months. Yeah and Ubuntu still has 4.6 in main repos ;) It isn't as much GCC upstream issue as problem with being forced to sync with GCC suite updates in distributions (and thus being tied to stability requirements for C compiler updates in that distributions).
Re: Review of std.signal
Upping the thread as it did not receive much review attention is is slowly getting fading away. Robert, for someone who has only vague knowledge of signal stuff (me), can you explain why exactly this design was necessary? (mixing in global variable and wrapper function which returns its restricted version) Is the desire to separate protection attributes the only motivation or there are some other concerns?
Re: Thoughts about D package management on Gentoo
On Monday, 11 November 2013 at 21:31:50 UTC, Iain Buclaw wrote: It can work this way. Perhaps with the realisation of a more stable releases (eg: exercising that certain point releases get maintained for a year). I would have fully supported it but if it has not happened so far despite all the breaking change debates I can't see it happening in future just because of GCC.
Re: DIP 50 - AST macros
On 2013-11-12 10:20, Walter Bright wrote: For example, the Linq example in the DIP is not compelling, as aesthetically nicer code can be written using D's ranges and algorithms: auto data = arr.filter!(x => x > 5).array; I was actually not the one that added the Linq examples. I like the above better. I've used a similar example as well: auto person = Person.where(e => e.name == "John"); Translates to: select * from person where name = 'John' But I don't see how that can currently be done in D. Operator overloading in D isn't flexible enough. For example, when implementing opEquals, you don't know if it's "==" or "!=" that's being called. Same with the comparison operators. I see no compelling advantage in trying to make D code look like C#; to be blunt it's like the old: #define BEGIN { #define END } macros used in old C code to make it look like Pascal. I agree with this. -- /Jacob Carlborg
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 09:40:52 UTC, Walter Bright wrote: On 11/12/2013 1:33 AM, tn wrote: I could not find any documentation on how the unordered comparison operators (<>, !<>=, !<=, !<, !>=, !>, !<>) translate into opCmp calls. That's because they just don't translate to opCmp calls. Well, they seem to translate to something, because this works as expected: struct S { private double v; auto opCmp(S rhs) { return v - rhs.v; } } S v1 = S(1); S v2 = S(2); S vn = S(double.nan); assert((v2 < v1) == false); assert((v1 < v2) == true); assert((v1 < v1) == false); assert((v1 < vn) == false); assert((v2 !>= v1) == false); assert((v1 !>= v2) == true); assert((v1 !>= v1) == false); assert((v1 !>= vn) == true); but then we went ahead and deprecated those operators Maybe the spec then needs to be updated: http://dlang.org/expression.html#RelExpression http://dlang.org/expression.html#floating_point_comparisons
Re: xdc: A hypothetical D cross-compiler and AST manipulation tool.
On Tuesday, 12 November 2013 at 05:49:23 UTC, Andrei Alexandrescu wrote: On 11/11/13 5:53 PM, Chad Joan wrote: What would you suggest as an alternative for targeting disparate hardware like microcontrollers (ALL of them), newly released game consoles, and legacy platforms that could use D for migration tools (like OpenVMS on IA64)? Oh, and I want instantaneous release times. I need to be able to stick the compiler on a machine it has NEVER seen and say, "Use POSIX libraries to fulfill Phobos' deps. Use reference counting. DO WORK!". Or maybe I would say, "Ditch Phobos, we in da sticks. Use reference counting. GOGOGO!" And I want to be running my D program 5 minutes later. Let me initially dismiss these: LLVM: not /everywhere/ yet, and missing on many of the targets I mentioned. C--: also not everywhere; this is the first I've heard of it. Java/Javascript/.NET: Actually also good backends, but a different ecosystems. Thus, I suggest that C is an AWESOME backend (with C++ for exceptions, but ONLY if it's available). Destroy :) Fine with me. I have no stake in this. I don't see how you reach the conclusion that C is "awesome" given it makes exceptions tenuous to implement. It does have the advantage of being universally available. If that's everything you need, sure. Andrei I call it "awesome" because you seem to have objections to the whole notion, and your objections are usually very interesting. So I'm just pulling your chain in the hopes that you bestow insights on me :) Honestly, I look forward to being able to implement exception handling in C! It sounds like a fun couple coding sessions waiting to happen. I already did it with C macros, so giving me an entire code generator to work with might make it /too/ easy. And it scratches an itch that current compiler's can't (well, maybe LDC is catching up). Perhaps this is just the difference between choosing a good IR (which C is not) and choosing a good compilation target (where C is needed).
Re: xdc: A hypothetical D cross-compiler and AST manipulation tool.
On Tuesday, 12 November 2013 at 06:40:25 UTC, Kelly wrote: ... Amber is an offshoot of D1, with some small parts of D2 where it made sense, so it may not be very close to what you are looking for, but it might be worth checking out. It compiles best on linux with dmd and ldc 1.074 and needs Tango to compile (Tango is also our main standard lib for Amber...though we can only compile about 25-30% of Tango with the Amber compiler right now). Good luck with xdc, whichever way you go with it. Thanks, Kelly Hi Kelly, Thank you for the words of encouragement! I didn't know about Amber. I'll have to check it out. Thanks!
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 13:50:49 UTC, Jacob Carlborg wrote: auto person = Person.where(e => e.name == "John"); Translates to: select * from person where name = 'John' for those of us entirely unfamiliar with linq, what is this supposed to do? Select people with name "John" from a collection of people, like in sql? It seems trivial to do this using filter, or am I missing something...?
Re: What’s Wrong with OOP and FP
On 11/12/2013 04:20 AM, bearophile wrote: > Do you want to inform that author about the purity in D? :-) The author claims to have done programming language research. So, I guess he knows about D. (Come to think of it, people who created the Go language supposedly had such research as well but they did not (!) know about D. ;) ) I am surprised that the Reddit thread has not mentioned D yet: http://www.reddit.com/r/programming/comments/1qg5x8/whats_wrong_with_oop_and_fp/ Ali
Re: DIP 50 - AST macros
On 11/12/2013 06:38 AM, John Colvin wrote: On Tuesday, 12 November 2013 at 13:50:49 UTC, Jacob Carlborg wrote: auto person = Person.where(e => e.name == "John"); Translates to: select * from person where name = 'John' for those of us entirely unfamiliar with linq, what is this supposed to do? Select people with name "John" from a collection of people, like in sql? It seems trivial to do this using filter, or am I missing something...? linq provides an interface to query any collection, but what is interesting in this case is Person.where(e => e.name == "John") invokes an engine that builds the necessary sql to issue an equivalent query to your sql database and assembles the results into a range of Person. And it can do this for any arbitrary predicate (well, almost. It doesn't handle function calls to arbitrary code too well). the .NET framework can do this because it exposes an api for querying, building, and compiling asts. D cannot do this because it doesn't. (and I have tried to make it work)
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 14:38:44 UTC, John Colvin wrote: for those of us entirely unfamiliar with linq, what is this supposed to do? Select people with name "John" from a collection of people, like in sql? It seems trivial to do this using filter, or am I missing something...? I don't know much about linq but in macro context I'd expect it to generate an actual SQL query to database (and execute it) based on in-language filter statement (via reflection)
Re: What’s Wrong with OOP and FP
Ali Çehreli: The author claims to have done programming language research. So, I guess he knows about D. From what I am seeing in the last years in the good Lambda the Ultimate Blog, most people doing programming language research know everything about monads and zippers, but ignore D :-) Bye, bearophile
Re: What’s Wrong with OOP and FP
On Tuesday, 12 November 2013 at 15:27:36 UTC, bearophile wrote: Ali Çehreli: The author claims to have done programming language research. So, I guess he knows about D. From what I am seeing in the last years in the good Lambda the Ultimate Blog, most people doing programming language research know everything about monads and zippers, but ignore D :-) Bye, bearophile Sometimes I have feeling language researchers live in some strange imaginary world and never actually check how their ideas work in production code.
Re: Review of std.signal
Robert, for someone who has only vague knowledge of signal stuff (me), can you explain why exactly this design was necessary? (mixing in global variable and wrapper function which returns its restricted version) Is the desire to separate protection attributes the only motivation or there are some other concerns? No this is the only reason. Usually it is the common case that you only want the "owner" of the signal to emit it. Without the mixin, this would require the following boilerplate for every single signal: ref RestrictedSignal!(SomeTemplate!int) mysig() { return _mysig;} private Signal!(SomeTemplate!int) _mysig; which is a bit tedious. I am currently considering the suggestions of Jacob Carlborg: - using an enum for the protections - provide an additional template mixin wrapper for another minor reduction of boilerplate. Signal slot frameworks in C++ usually either only allow the owner to emit the signal (Qt) or you are required to write some wrapper functions for restrictions on the public API (e.g. boost signal). Best regards, Robert
Re: Sorting floating-point values, and NaN
On 11/12/13 12:54 AM, tn wrote: On Tuesday, 12 November 2013 at 07:33:57 UTC, qznc wrote: On Tuesday, 12 November 2013 at 04:41:56 UTC, Vladimir Panteleev wrote: double[] arr = [1, 2, 3, double.nan, 1, 2]; assert(arr.isSorted); arr.sort(); This code will fail with an assert error, but not the one on the second line. Rather, it will fail inside std.range, when sort calls assumeSorted, which checks elements in an order different than sort and isSorted. Here's a case where the odd way NaN interacts with generic code messes things up in an ugly way. This is concerning. It's very easy to overlook this while writing an application, and it can become a hidden vulnerability. We can't fix the operators... but, perhaps, we could define a safe default comparison predicate (e.g. std.algorithm.less) for use with sorting and related tasks? Aside from bitwise comparison, is it even possible to efficiently compare floating-point values in a way suitable for sorting? You cannot sort NaNs. A comparison with NaN must always evaluate to false. One could change isSorted to check for false instead of true, so it would accept NaN. That would probably break too much code, though. arr[n] < arr[n+1] => !(arr[n+1] < arr[n]) But that is exactly what it does. https://github.com/D-Programming-Language/phobos/blob/8372da44f66f20c67b69b4b8fb39233ce42d493c/std/algorithm.d#L10021 And that is the reason the second line "assert(arr.isSorted);" passes, while it should fail as the array is clearly not sorted. Instead modifying !(arr[n+1] < arr[n]) => arr[n] <= arr[n+1] would make the function work correctly (return false if the range contains nans), but then the template parameter "less" should be replaced by "lessOrEqual". An alternative would be to check for nans explicitly. I think NaNs are singular unordered values that make invalid inputs for either sort or isSorted. We should simply add an assert to isSorted. Andrei
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 08:10:16 UTC, Jonathan M Davis wrote: On Tuesday, November 12, 2013 05:41:55 Vladimir Panteleev wrote: double[] arr = [1, 2, 3, double.nan, 1, 2]; assert(arr.isSorted); arr.sort(); This code will fail with an assert error, but not the one on the second line. Rather, it will fail inside std.range, when sort calls assumeSorted, which checks elements in an order different than sort and isSorted. Here's a case where the odd way NaN interacts with generic code messes things up in an ugly way. This is concerning. It's very easy to overlook this while writing an application, and it can become a hidden vulnerability. We can't fix the operators... but, perhaps, we could define a safe default comparison predicate (e.g. std.algorithm.less) for use with sorting and related tasks? Aside from bitwise comparison, is it even possible to efficiently compare floating-point values in a way suitable for sorting? The check could be special-cased for floating point values so that it takes NaN into account, but NaN pretty much screws with everything. Once it's there, pretty much anything involving math or comparisons is going to go bad. So, you could argue that it's a bug in the program if sort is passed a NaN and that the assertion in sort is therefore perfectly valid. You can't really sort anything with NaN in it anyway. Here is the problem: 1) NaN values are accepted as input almost anywhere where doubles are. std.conv recognizes the string "nan" and converts it to double.nan, 2) It is unreasonable to expect every D user out there dealing with floating point numbers to be forced to check every source of floating point values in their program against NaNs. 3) If the program is compiled in debug mode, it will crash quasi-randomly, since the assumeSorted assert does not check every pair. For these reasons, this problem can become a sort of time bomb in their application: even with 100% test coverage, one NaN in the wrong place inputted by a malicious end user can cause a situation the program's authors have not foreseen. It can be argued that it is a flaw in the language in that it allowed such a situation to arise in the first place. P.S. Please enable RFC 2646 (format=flowed) support in your email client. It is emitting unreflowable text, which causes jagged quotes as seen above.
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 15:56:25 UTC, Andrei Alexandrescu wrote: I think NaNs are singular unordered values that make invalid inputs for either sort or isSorted. We should simply add an assert to isSorted. Considering their effect on the program state, NaNs can be seen as invalid input, and asserts are not suitable for input validation.
Re: What’s Wrong with OOP and FP
On Tuesday, 12 November 2013 at 15:35:48 UTC, Dicebot wrote: On Tuesday, 12 November 2013 at 15:27:36 UTC, bearophile wrote: Ali Çehreli: Sometimes I have feeling language researchers live in some strange imaginary world and never actually check how their Lambda the Ultimate and Javaland.
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 15:21:16 UTC, Ellery Newcomer wrote: On 11/12/2013 06:38 AM, John Colvin wrote: On Tuesday, 12 November 2013 at 13:50:49 UTC, Jacob Carlborg wrote: auto person = Person.where(e => e.name == "John"); Translates to: select * from person where name = 'John' for those of us entirely unfamiliar with linq, what is this supposed to do? Select people with name "John" from a collection of people, like in sql? It seems trivial to do this using filter, or am I missing something...? linq provides an interface to query any collection, but what is interesting in this case is Person.where(e => e.name == "John") invokes an engine that builds the necessary sql to issue an equivalent query to your sql database and assembles the results into a range of Person. And it can do this for any arbitrary predicate (well, almost. It doesn't handle function calls to arbitrary code too well). the .NET framework can do this because it exposes an api for querying, building, and compiling asts. D cannot do this because it doesn't. (and I have tried to make it work) oh, I see. Would AST macros really be enough to make this work in D? "Arbitrary code" is a huge feature space in D, including much that doesn't map well to anything outside of a relatively low-level language, let alone SQL. I can see it quickly becoming a nightmare that would be worse than just issuing the predicate as an sql string or some generic equivalent.
Re: DIP 50 - AST macros
On 11/12/13 7:21 AM, Ellery Newcomer wrote: the .NET framework can do this because it exposes an api for querying, building, and compiling asts. D cannot do this because it doesn't. (and I have tried to make it work) Maybe the problem needs to be reformulated for D. I think an SQL mixin that either stays unchanged (for DB engines) or translates to a D expression (for native D data types) would be doable, nontrivial, interesting, and instantly usable for people who already know SQL without any extra learning. In other words... actually better than Linq. Andrei
Re: Sorting floating-point values, and NaN
On 11/12/13 8:00 AM, Vladimir Panteleev wrote: 1) NaN values are accepted as input almost anywhere where doubles are. std.conv recognizes the string "nan" and converts it to double.nan, They are still singular values. Code has no business comparing them unwittingly. 2) It is unreasonable to expect every D user out there dealing with floating point numbers to be forced to check every source of floating point values in their program against NaNs. I find that perfectly reasonable. How do you mean that? 3) If the program is compiled in debug mode, it will crash quasi-randomly, since the assumeSorted assert does not check every pair. It should always crash. As I said: insert an assert in assumeSorted and be done with it. For these reasons, this problem can become a sort of time bomb in their application: even with 100% test coverage, one NaN in the wrong place inputted by a malicious end user can cause a situation the program's authors have not foreseen. It can be argued that it is a flaw in the language in that it allowed such a situation to arise in the first place. The language allows NaN floating point number with the semantics of IEEE 754. We hardly have any leeway in the matter unless we want to irate a lot of people for no good reason. I don't understand your entire point here. I agree with something like "NaNs are a nuisance." We need to fix the corresponding bugs in assumeSorted, isSorted etc. by inserting sanity checks such as: if (a[i] < a[i + 1]) { assert(!(a[i + 1] < a[i])); ... } else { assert(a[i + 1] >= a[i]); ... } etc. Andrei
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 16:39:18 UTC, Andrei Alexandrescu wrote: Maybe the problem needs to be reformulated for D. I think an SQL mixin that either stays unchanged (for DB engines) or translates to a D expression (for native D data types) would be doable, nontrivial, interesting, and instantly usable for people who already know SQL without any extra learning. In other words... actually better than Linq. It does not matter that much if it is macro or mixin. Key feature is AST reflection which allows to augment valid D code with additional semantics when appropriate. It is very similar to how UDA's augment declarative approach, but applied to imperative/procedural instead. We can't do that in D right now. Only way is to import own source file and parse it which does not really sound sane.
Re: Sorting floating-point values, and NaN
On 11/12/13 8:05 AM, Vladimir Panteleev wrote: On Tuesday, 12 November 2013 at 15:56:25 UTC, Andrei Alexandrescu wrote: I think NaNs are singular unordered values that make invalid inputs for either sort or isSorted. We should simply add an assert to isSorted. Considering their effect on the program state, NaNs can be seen as invalid input, and asserts are not suitable for input validation. I should know, since I dedicated a chapter to the topic in TDPL :o). It's all a matter of boundaries, i.e. what you consider "input" and what you consider "precondition". When user code reads floating point data off of disk, they should do real validation. For isSorted we could say that the output is only defined for inputs that are comparable. Or indeed we could specify that isSorted throws if unordered data is presented, and verify everything at runtime, at a cost in efficiency. It's a judgment call, not a cut and dried decision. In this case I think assert is the better call. Andrei
Re: DIP 50 - AST macros
On 11/12/13 8:47 AM, Dicebot wrote: On Tuesday, 12 November 2013 at 16:39:18 UTC, Andrei Alexandrescu wrote: Maybe the problem needs to be reformulated for D. I think an SQL mixin that either stays unchanged (for DB engines) or translates to a D expression (for native D data types) would be doable, nontrivial, interesting, and instantly usable for people who already know SQL without any extra learning. In other words... actually better than Linq. It does not matter that much if it is macro or mixin. Key feature is AST reflection which allows to augment valid D code with additional semantics when appropriate. I don't see how AST reflection is needed for generating correct D code from an SQL expression. Dmitry did exactly that with ctRegex. Please illuminate. Andrei
Re: DIP 50 - AST macros
Am 12.11.2013 17:39, schrieb Andrei Alexandrescu: Maybe the problem needs to be reformulated for D. I think an SQL mixin that either stays unchanged (for DB engines) or translates to a D expression (for native D data types) would be doable, nontrivial, interesting, and instantly usable for people who already know SQL without any extra learning. In other words... actually better than Linq. "actually better than Linq" good statement without knowing it deep linq allows construction and querieng of non table-like hierarchical data, so its more an object-hierarchy store/retrival system which can "also" work with the lower just-tables-like world of sql results
Re: DIP 50 - AST macros
On 11/12/13 8:56 AM, dennis luehring wrote: Am 12.11.2013 17:39, schrieb Andrei Alexandrescu: Maybe the problem needs to be reformulated for D. I think an SQL mixin that either stays unchanged (for DB engines) or translates to a D expression (for native D data types) would be doable, nontrivial, interesting, and instantly usable for people who already know SQL without any extra learning. In other words... actually better than Linq. "actually better than Linq" good statement without knowing it deep linq allows construction and querieng of non table-like hierarchical data, so its more an object-hierarchy store/retrival system which can "also" work with the lower just-tables-like world of sql results Yah, it was an exaggeration. Linq is very powerful. Andrei
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 16:54:19 UTC, Andrei Alexandrescu wrote: I don't see how AST reflection is needed for generating correct D code from an SQL expression. Dmitry did exactly that with ctRegex. Please illuminate. Other way around. Generating arbitrary output (including but not limited to SQL expressions) from D code. As I have already mentioned, it is the very same thing we do now with __traits and UDA's but not limited to only declarations.
Re: DIP 50 - AST macros
On 11/12/13 9:03 AM, Dicebot wrote: On Tuesday, 12 November 2013 at 16:54:19 UTC, Andrei Alexandrescu wrote: I don't see how AST reflection is needed for generating correct D code from an SQL expression. Dmitry did exactly that with ctRegex. Please illuminate. Other way around. Generating arbitrary output (including but not limited to SQL expressions) from D code. Yah. That I agree with. That's why I said we should reformulate the problem that LINQ solves. As I have already mentioned, it is the very same thing we do now with __traits and UDA's but not limited to only declarations. Interesting. Andrei
Re: DIP 45 - approval discussion
On Tuesday, 12 November 2013 at 08:50:29 UTC, Andrei Alexandrescu wrote: One question would be whether the same work is needed for e.g. typeid() or toString. If not, maybe there is a case against factory. That isn't the same. toString itself rely on typeid. And the typeid object is stored with the virtual function table. The code can retrieve that information for any object, even the ones that the code never heard about. Object.factory require the inverse: finding the typeid from the name of the class. It require to build some structure that associate the name of a class and its typeid, and make it available for Object.factory. I don't see how the existing system prevents you from rolling your own. It doesn't, but I still need to pay for it. The time difference is crucial here. If this DIP came up in 2006 (when I estimate we introduced Object.factory) probably a lot of things would have come down differently. Proposals made in different epochs are, I think, very difficult to compare. I understand some design has been made for historical reasons. That happen to every system. That doesn't mean much.
Re: DIP 45 - approval discussion
On 11/12/13 1:30 AM, Benjamin Thaut wrote: Am 12.11.2013 09:50, schrieb Andrei Alexandrescu: The time difference is crucial here. If this DIP came up in 2006 (when I estimate we introduced Object.factory) probably a lot of things would have come down differently. Proposals made in different epochs are, I think, very difficult to compare. Andrei Wait. Whats the actual issue here? This DIP does not prevent object.factory from working across DLL boundaries. This DIP does also not conflict with object.factory. So what is the actual problem at hand? You're right. I was meaning that in the abstract - generally feature creation is strongly conditioned by existing context. Andrei
Re: DIP 45 - approval discussion
Am 12.11.2013 07:59, schrieb deadalnix: On Tuesday, 12 November 2013 at 05:46:19 UTC, Andrei Alexandrescu wrote: ... well time to substantiate. Andrei OK, but first, it has to be noted that this is putting the burden of proof on the wrong side of the argument. But what is the actual argument? What problem do you see regarding object.factory and this DIP?
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 16:14:57 UTC, John Colvin wrote: On Tuesday, 12 November 2013 at 15:21:16 UTC, Ellery Newcomer wrote: On 11/12/2013 06:38 AM, John Colvin wrote: On Tuesday, 12 November 2013 at 13:50:49 UTC, Jacob Carlborg wrote: auto person = Person.where(e => e.name == "John"); Translates to: select * from person where name = 'John' for those of us entirely unfamiliar with linq, what is this supposed to do? Select people with name "John" from a collection of people, like in sql? It seems trivial to do this using filter, or am I missing something...? linq provides an interface to query any collection, but what is interesting in this case is Person.where(e => e.name == "John") invokes an engine that builds the necessary sql to issue an equivalent query to your sql database and assembles the results into a range of Person. And it can do this for any arbitrary predicate (well, almost. It doesn't handle function calls to arbitrary code too well). the .NET framework can do this because it exposes an api for querying, building, and compiling asts. D cannot do this because it doesn't. (and I have tried to make it work) oh, I see. Would AST macros really be enough to make this work in D? "Arbitrary code" is a huge feature space in D, including much that doesn't map well to anything outside of a relatively low-level language, let alone SQL. I can see it quickly becoming a nightmare that would be worse than just issuing the predicate as an sql string or some generic equivalent. Actually, s/arbitrary code/simple to moderately complex expressions that don't call functions that aren't explicitly handled by the translation engine/ and this is a better representation of what linq can do in e.g. entity framework. and you could go the route of django models, e.g. Place.objects.filter(name="Bob's Cafe") as long as you had enough metadata set up. you could probably get this to work in D, but A. it looks like crap B. it in no way resembles sql C. it would look like even worse crap in D (no named parameters!) D. it doesn't readily permit you to make queries with complex expression trees (idk, maybe something like linq's Places.Where(p => p.Elev < 200 && Addresses.Any(a => a.State == p.State)) why am I arguing against this? nobody wants this, nobody asked for this. Also, sql is to databases what assembly is to cpus. It's low level, [moderately] untyped, and it differs on every single platform. provide access to it, sure, but please don't use it to build your abstractions.
Re: What’s Wrong with OOP and FP
Am 12.11.2013 17:10, schrieb eles: On Tuesday, 12 November 2013 at 15:35:48 UTC, Dicebot wrote: On Tuesday, 12 November 2013 at 15:27:36 UTC, bearophile wrote: Ali Çehreli: Sometimes I have feeling language researchers live in some strange imaginary world and never actually check how their Lambda the Ultimate and Javaland. Well, in defence of Javaland, it is a consequence how easy it is for enterprise architects to try out their crazy ideas in Java. Except for a few years at CERN, I always worked in enterprise land, so I have seen FactoryFactoryAbstractThingy being done in: - C based platform which used its own concept of pointers, requiring conversions between framework pointers and C pointers - A Frankenstein framework done in CORBA with a healthy mix of C++ and Perl code - A Perl framework for generating code for control of telecommunication networks with a thousands plugins, which affected the way the whole code generation was done, requiring multiple passes - A transformation engine done in XML/XSLT (yes really!) with a JavaScript API being called from a Java driver application - A framework done on top of J2EE, as if J2EE wasn't enough Better stop here. :) -- Paulo
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 16:48:01 UTC, Andrei Alexandrescu wrote: On 11/12/13 8:00 AM, Vladimir Panteleev wrote: 1) NaN values are accepted as input almost anywhere where doubles are. std.conv recognizes the string "nan" and converts it to double.nan, They are still singular values. Code has no business comparing them unwittingly. 2) It is unreasonable to expect every D user out there dealing with floating point numbers to be forced to check every source of floating point values in their program against NaNs. I find that perfectly reasonable. How do you mean that? Both of the above hinge on the relative obscurity of NaNs and the problems they could cause. People who are not specifically familiar with NaNs and how they interact with other floating-point values will treat floating-point values as "just numbers", and expect them to compare and sort in the same way as integers. The language allows NaN floating point number with the semantics of IEEE 754. We hardly have any leeway in the matter unless we want to irate a lot of people for no good reason. It's a judgment call, not a cut and dried decision. Agreed - however, I think there might be more than one way to deal with this. 1) As above, introduce a "less" function which guarantees transitivity for basic types, and use it in examples throughout. 2) Improve documentation and visibility of this problem. For example, add this to the documentation of sort: "The predicate must be transitive (`aorder for `sort` to behave properly - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode. Note that `apoints, because the expression will always be `false` when either `a` or `b` is `NaN`." We should simply add an assert to isSorted. How would this be implemented, anyway? I stumbled upon this problem with this code: enum sortPred = q{a.hits > b.hits || (a.hits == b.hits && a.value < b.value)}; all.sort!sortPred(); (I know about multiSort, but it currently seems to be buggy - I do have a test case, but it has a few million entries and I need to reduce it.) if (a[i] < a[i + 1]) { assert(!(a[i + 1] < a[i])); ... } else { assert(a[i + 1] >= a[i]); ... } Sort et al don't know how to check "a>=b"... and they can't use "a
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 11:06:17 UTC, Don wrote: On Tuesday, 12 November 2013 at 09:55:20 UTC, Walter Bright wrote: I forgot to mention that "expression templates" can be used in D in an equivalent manner that they are used in C++, They are crippled compared to C++, because you have no control over the return type of opCmp and opEquals, which means that you can't have expression templates involving comparisons. That's extremely limiting. My feeling with AST macros is: (1) AST macros are basically syntax sugar for string mixins. The one and only thing that string mixins have in their favour, is that they have almost no syntax. But that is actually a *huge* plus. Because it's syntax sugar, an AST macro syntax would be most convincing if you took some existing string mixins from various real projects, and show how beautiful they would become with macros. (2) The big functionality we don't have, is comprehensive reflection. I'd like to see more thought in that area. It seems challenging to define reflection in a way that doesn't expose compiler internals. The question I find particularly interesting is, "if we had macros, would reflection look different?" My personal main need for macros at this point, is to make up for a lack of better reflection, but as has been pointed out, it's not clear how macros would help anyway without access to the sort of reflection that I'm currently lacking. What we seem to be discussing, is the need to unify within D the abilities to perform better reflection along with a means to automate code generation during compile time. The current way reflection and mixins are done, are totally different, almost like two different languages with D, so it would be nice to have a more unified system that more closely resembles D itself. BTW, I agree with Walters concerns about AST macros. It would be ugly to work with code that is not comprehensible due to over use of macros that attempt to redefine the language into something else. OTOH there's also significant advantages to be able to add certain things into the language that are currently lacking. For example, I've experimented with a method of implementing co-routines that use switch statements, but it's very ugly to do without macro support to the point of being impractical. --rt
Re: Why the @ in @safe? & UDAs
I don't disagree with what you are saying, however I think it is healthy to always question the status quo and continue to try and find innovative ways to destroy established thinking that otherwise limits what can and cannot be done. Currently, the most acceptable methods discussed in here of moving forward and getting rid of old inadequate concepts, seems to be through very carefully considered deprecation and the implementing of automated methods for updating old code to conform to newer and better standards. We do have deprecation, but so far I have not seen methods of automated updates so maybe that's something worth considering down the road. I do have some experience with automating updates of old code. Certain databases I've worked on required updates, and the only foolproof method of doing it was to automate the process as much as possible, and I've had very good success doing it that way. Manually updating code is very stressful and error prone, no one wants to do it, but if you can click on a button and have the code updated for you without concern that it will fail miserably or cause weird side effects, upgrades become a good thing instead of a bad thing. --rt On Monday, 11 November 2013 at 00:13:34 UTC, Jonathan M Davis wrote: On Monday, November 11, 2013 00:39:04 Rob T wrote: On Sunday, 10 November 2013 at 23:08:11 UTC, Nick wrote: > The alternative is to slowly build up a menagerie of quirks > that put us on the same path as C++. It seems that a buildup of quirks is underway as is evidenced by this discussion. The other solution is to at some point place a freeze on D2 with bug support only and move on to D3 with at least the worse of the known baggage removed. There are of course disadvantages and dangers with doing that, but it is an option. Ultimately if we try and keep everyone happy, at some point no one will be happy, so I think it's worth trying to find good solutions to enable the language to evolve in ways that can leave baggage from the past behind. I think that it's naive to think that any serious language will avoid building up quirks and rough corners over time. You never get a language completely right (assuming that's even possible), and you only have so long after you create it to tweak stuff before it has to be more or less set in stone for it to be useable in the real world. Some stuff can be tweaked over time even after you're "stable," but you have to be very careful about it in order to minimize if not outright eliminate breakage. And the longer that a language is around, the more unwieldy it's going to get. Either it doesn't innovate at all and avoids building up more quirks, or it innovates and ends up with quirks as it adds and adjusts stuff after the fact. Eventually, the baggage from those quirks will be big enough that if you want to get rid of them, you'll be forced to either create a new language or to create a new version of the language which breaks backwards compatiibiity, which tends to be little different from just creating a new language. I really don't think that there's any way around that. D doesn't have all of the baggage of C and C++, because it's a new language which breaks compatibility with them, but it's building up its own quirks and mistakes and will continue to do so. We should do our best to minimize that, but I really don't think that there's any way avoid it completely. Languages _need_ to be more or less set in stone in order to be useable in the real world, and if you set them in stone, then you're going to end up with quirks and baggage when you add onto them later. That's just the way it is, and I think that anyone who thinks that D can avoid the same fate as C++ in that regard is being naive. Some day, there will be a D++, or a D3, or an E, or whatever for the same reason that we created D instead of continuing to use C++ and for the same reason that the python developers created python 3. But that's a _long_ way off. First, we have to make D2 work, and part of that means living with at least some of the mistakes that we've made and quirks that the language has acquired. And honestly, many of those are tradeoffs that I don't think that anyone has a good solution for at this point anyway. So, even if someone went and created D3 right now, I don't think that it would be appreciably better than D2 (in some regards maybe, but not enough to be worth the split that that would cause to the code and to the community). - Jonathan M Davis
Re: DIP 50 - AST macros
There is significant regret about the way macros are defined in Scala. Probably not an example to follow. Andrei Not an example to follow, but it would definitely be worth looking into how they defined macros and what aspect of that caused problems, so we can avoid making the same mistakes.
Re: Sorting floating-point values, and NaN
Both of the above hinge on the relative obscurity of NaNs and the problems they could cause. People who are not specifically familiar with NaNs and how they interact with other floating-point values will treat floating-point values as "just numbers", and expect them to compare and sort in the same way as integers. Please, please, please just no. As someone who works with floating point daily, you cannot idiot proof it like this. They will never behave like "just numbers" and you can't make them. Even leaving out NAN, you have issues with precision, accumulated error, denormals, equality comparison, and on and on. If you don't know what you are doing with them, then you just shouldn't be touching them. Unicode has similar issues.
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 15:56:25 UTC, Andrei Alexandrescu wrote: On 11/12/13 12:54 AM, tn wrote: ... An alternative would be to check for nans explicitly. I think NaNs are singular unordered values that make invalid inputs for either sort or isSorted. We should simply add an assert to isSorted. But sort and isSorted both allow user to provide a custom "less" function. What if the user needs NaNs and, for example, wants to sort them before all the other values? Then he calls "arr.sort!((a,b) => a < b || (isnan(a) && !isnan(b)))" and the code asserts?
Re: Sorting floating-point values, and NaN
On 11/12/2013 9:59 AM, Vladimir Panteleev wrote: Both of the above hinge on the relative obscurity of NaNs and the problems they could cause. People who are not specifically familiar with NaNs and how they interact with other floating-point values will treat floating-point values as "just numbers", and expect them to compare and sort in the same way as integers. NaNs are valid values for floating point numbers. Trying to pretend they don't exist is a doomed strategy for programmers. I regard this as analogous to the regular proposals to hide the fact that char[] are sequences of unicode code points, attempts to pretend that integers don't overflow, etc. Floating point math has some strange characteristics (NaNs are only one such), and anyone writing a non-toy fp app needs to learn that stuff. There's no other way.
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 18:31:40 UTC, Walter Bright wrote: NaNs are valid values for floating point numbers. Trying to pretend they don't exist is a doomed strategy for programmers. I regard this as analogous to the regular proposals to hide the fact that char[] are sequences of unicode code points, attempts to pretend that integers don't overflow, etc. Floating point math has some strange characteristics (NaNs are only one such), and anyone writing a non-toy fp app needs to learn that stuff. There's no other way. On Tuesday, 12 November 2013 at 18:25:10 UTC, Bigsandwich wrote: Please, please, please just no. As someone who works with floating point daily, you cannot idiot proof it like this. They will never behave like "just numbers" and you can't make them. Even leaving out NAN, you have issues with precision, accumulated error, denormals, equality comparison, and on and on. That doesn't change the reality that not everyone is aware of these issues, and that even people who are aware of them may overlook something somewhere. We can't pretend that there is no problem just because it's something you "have to know" and "have to be careful about" - if we can improve the situation without making a compromise elsewhere, then it must be done. I don't see this stance as any different than shouting "RTFM!!!" at anyone who makes a mistake which, in theory, could be avoided by studying, memorization and careful application of the appropriate documentation located ... somewhere. This approach does not work - even if that user has learned his lesson the hard way, more new users will make the same mistake. Instead, you must actually make the problem less likely to manifest - improve your documentation, or improve the design of your system such that such errors will be less likely to occur. This particular situation affects only one specific property of floating-point numbers, so other properties are not relevant to this discussion. Personally, I've been taught about floating-point precision issues back in school, but I've only learned about NaNs while learning D. Call me an unlearned idiot if that makes you feel better, but it is rather likely that there will be more users making the same mistake in the future if the situation is not addressed. Furthermore, the problem is aggravated by that it is hidden by generic code. This thread isn't a complaint that "the line `if (aexplicit floating-point comparisons in the example in the original post. We are calling sort, a function in the standard library, with its default predicate, as specified in the standard library, using a built-in type, which is part of the language, and it fails its own assertion on certain input. This is a problem! I have suggested possible improvements earlier in this thread, so I'd like to ask you to comment on those rather than hand-waving the problem away.
Re: C++ namespace support (@Walter)
On Thursday, 7 November 2013 at 16:17:35 UTC, Dejan Lekic wrote: After a year and a half ( https://d.puremagic.com/issues/show_bug.cgi?id=7961 ) I have to remind Walter and Co. about this enhancement request. :) This is becoming increasingly important not just to me, but to the D community in general. Think about, for an example, the Tizen platform ( http://www.tizen.org ) , C++ namespace support would considerably help us develop an environment where D programmers could easily develop native applications for the Tizen platform. Speaking about Tizen, I humbly believe Tizen will soon become one of the major players in the mobile application world, and having ability to develop Tizen apps using D is beneficial to all of us. Kind regards FYI: This news item was posted today. Samsung Tizen OS touted as Android alternative http://www.cbc.ca/news/business/samsung-tizen-os-touted-as-android-alternative-1.2423682
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 17:59:37 UTC, Vladimir Panteleev wrote: 1) As above, introduce a "less" function which guarantees transitivity for basic types, and use it in examples throughout. 2) Improve documentation and visibility of this problem. For example, add this to the documentation of sort: "The predicate must be transitive (`ain order for `sort` to behave properly - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode. Note that `apoints, because the expression will always be `false` when either `a` or `b` is `NaN`." But 'acondition (`acases where a and b (or b and c) are incomparable. Transitivity is not the problem Sort et al don't know how to check "a>=b"... and they can't use "a This is the problem, that is, the fact that with '<' you can't tell the difference between equal values and incomparable values (one or both are NaNs). On the other hand, with '<=' you can. See: (a a b (not possible) !(a a==b OR incomparable but (a<=b) && !(b<=a) --> a b a==b !(a<=b) && !(b<=a) --> incomparable Thus, the correct solution would be to modify the functions to take "lessOrEqual" as a template parameter instead of "less". If "less" is kept, then we need another template argument to separate equality and incomparability (something like "equals(a,b)", or "incomparable(a,b)").
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 19:26:12 UTC, tn wrote: But 'acondition (`acases where a and b (or b and c) are incomparable. Transitivity is not the problem Whoops, you're right. I meant transitivity of the negated expression: !(a>b) && !(b>c) implies !(a>c). This fails for [3, NaN, 1]. Sort et al don't know how to check "a>=b"... and they can't use "a This is the problem, that is, the fact that with '<' you can't tell the difference between equal values and incomparable values (one or both are NaNs). On the other hand, with '<=' you can. See: (a a b (not possible) !(a a==b OR incomparable but (a<=b) && !(b<=a) --> a b a==b !(a<=b) && !(b<=a) --> incomparable Thus, the correct solution would be to modify the functions to take "lessOrEqual" as a template parameter instead of "less". Too late for that now... just like it's too late to change IEEE comparison logic. If "less" is kept, then we need another template argument to separate equality and incomparability (something like "equals(a,b)", or "incomparable(a,b)"). Is this to allow generic partial ordering (rather than to fix sorting NaNs specifically)? I remember seeing a thread about partial ordering and opCmp: http://forum.dlang.org/post/dpfbtu$1ocf$1...@digitaldaemon.com
[Poll] On Linux, what should we commonly use as sub-directory name for D?
I've seen people use both 'd' and 'dlang' now, so I created a poll. Everyone assembling Linux packages is then free use the results to create a similar experience on all distributions. http://www.easypolls.net/poll.html?p=52828149e4b06cfb69b97527 -- Marco
Re: Sorting floating-point values, and NaN
On 11/12/13 9:59 AM, Vladimir Panteleev wrote: On Tuesday, 12 November 2013 at 16:48:01 UTC, Andrei Alexandrescu wrote: On 11/12/13 8:00 AM, Vladimir Panteleev wrote: 1) NaN values are accepted as input almost anywhere where doubles are. std.conv recognizes the string "nan" and converts it to double.nan, They are still singular values. Code has no business comparing them unwittingly. 2) It is unreasonable to expect every D user out there dealing with floating point numbers to be forced to check every source of floating point values in their program against NaNs. I find that perfectly reasonable. How do you mean that? Both of the above hinge on the relative obscurity of NaNs and the problems they could cause. People who are not specifically familiar with NaNs and how they interact with other floating-point values will treat floating-point values as "just numbers", and expect them to compare and sort in the same way as integers. I think that's their problem, not ours. The language allows NaN floating point number with the semantics of IEEE 754. We hardly have any leeway in the matter unless we want to irate a lot of people for no good reason. It's a judgment call, not a cut and dried decision. Agreed - however, I think there might be more than one way to deal with this. 1) As above, introduce a "less" function which guarantees transitivity for basic types, and use it in examples throughout. This is a bit much. 2) Improve documentation and visibility of this problem. For example, add this to the documentation of sort: "The predicate must be transitive (`a Great idea, just file an enh request or just write the pull request. We should simply add an assert to isSorted. How would this be implemented, anyway? I stumbled upon this problem with this code: enum sortPred = q{a.hits > b.hits || (a.hits == b.hits && a.value < b.value)}; all.sort!sortPred(); (I know about multiSort, but it currently seems to be buggy - I do have a test case, but it has a few million entries and I need to reduce it.) if (a[i] < a[i + 1]) { assert(!(a[i + 1] < a[i])); ... } else { assert(a[i + 1] >= a[i]); ... } Sort et al don't know how to check "a>=b"... and they can't use "a It really implies "a and b are in the same equivalence class". Building on that notion, we can figure what's wrong with NaNs and how to assert against their failings. Consider we define equiv(a, b) as (a, b) => !less(a, b) && !less(b, a). If at least one of the numbers is NaN, all comparisons return false. That puts NaN in the same equivalence class with all numbers, including numbers that are deemed in distinct equivalence classes. That's where NaNs mess things up, and that's what we need to assert. Consider three numbers a, b, and c. Then the following must pass: assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c)); ("<=" on Booleans is actually implication.) That test will fail with NaNs and should be part of isSorted, sort etc. We should also check such as: assert(!less(a, a)); assert(less(a, b) <= !less(b, a)); These should be checked in sort only; isSorted does not need these. Andrei
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 11:06:17 UTC, Don wrote: On Tuesday, 12 November 2013 at 09:55:20 UTC, Walter Bright wrote: I forgot to mention that "expression templates" can be used in D in an equivalent manner that they are used in C++, They are crippled compared to C++, because you have no control over the return type of opCmp and opEquals, which means that you can't have expression templates involving comparisons. That's extremely limiting. My feeling with AST macros is: (1) AST macros are basically syntax sugar for string mixins. The one and only thing that string mixins have in their favour, is that they have almost no syntax. But that is actually a *huge* plus. Because it's syntax sugar, an AST macro syntax would be most convincing if you took some existing string mixins from various real projects, and show how beautiful they would become with macros. (2) The big functionality we don't have, is comprehensive reflection. I'd like to see more thought in that area. It seems challenging to define reflection in a way that doesn't expose compiler internals. The question I find particularly interesting is, "if we had macros, would reflection look different?" After using string mixins for a while I have come to feel much like your statement in (1). I like the power and flexibility of string mixins. Text and strings are understandable and straightforward to manipulate. This is a clear win in my opinion. There are also some things I find difficult at the moment. - One is the process of what to do when things do not go as expected. To debug I currently use pragma statements and try to visualize what is going on in my mind. This is do-able. But I feel it could be better. - It would be nice to be able to use some more D language concepts to construct the string mixin inside the template. For example, sometimes I would like to use a loop to construct the result. If these two items could be addressed I would be pretty satisfied with using string mixins as they are. One win that the AST macro concept provides that string mixins does not is manipulation of code syntax trees (either at compile or run time). It would be nice to combine the various code manipulation ideas that have been tossed around before into a single module, say std.meta or std.reflection. In addition to combining the various current code manipulation functionality into a single api (e.g. __traits, std.traits), it could provide functionality to work with code-in-use. For example, it would be pretty cool to be able to do the following (the actual syntax for constructing the code is not that important to me, but the underlying functionality for manipulating code is). sample.d import std.meta; void main(string[] args) { auto e = construct("a + %s", args[1]); writefln("%s", e(5)); auto f = construct(e + "b"); writefln("%s", f(?, 10).toDebugString); writefln("%s", f(5, 10)); } - ./sample 2 7 Numerical Expression: a + 2 + 10 17 Implementing the "expression tree" side of AST macros seems like it could be done as a library, which would be a win for maintainability and cross-compiler portability. There is probably required, compiler-related functionality that I cannot see making this unfeasable or possibly difficult to do. Still, looks good to me on paper at least. Perhaps going this route could gain the good functionality of AST macros while also making use of the already implemented features? Seems to me like some of these ideas tie into previous discussions. Here are two I remember. I am sure there are others. http://forum.dlang.org/thread/juf7sk$16rl$1...@digitalmars.com http://forum.dlang.org/thread/mailman.1716.1340388570.24740.digitalmar...@puremagic.com Joseph
Re: How is std.traits.isInstanceOf supposed to work?
On 11/10/2013 05:03 PM, Tommi wrote: On Sunday, 10 November 2013 at 23:43:21 UTC, TheFlyingFiddle wrote: The template isInstanceOf checks to see if the second parameter is a template instantiation of the first parameter. But in this example of mine: isInstanceOf!(SuperSt, SubSt) ...the second parameter is not a template instantiation of the first parameter, yet isInstanceOf evaluates to true. I think what this all boils down to is that this is a compiler-bug: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static assert(!is(B == A!int)); // OK static assert(is(B == A!T, T)); // BUG (shouldn't compile) } The compiler magically deduces T as int: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static if (is(B == A!T, T)) { pragma(msg, T);// prints int } } Ali
Re: [Poll] On Linux, what should we commonly use as sub-directory name for D?
On Tuesday, 12 November 2013 at 19:50:32 UTC, Marco Leise wrote: I've seen people use both 'd' and 'dlang' now, so I created a poll. Everyone assembling Linux packages is then free use the results to create a similar experience on all distributions. http://www.easypolls.net/poll.html?p=52828149e4b06cfb69b97527 "dlang" should supersede "d" in all domains, it is a simple matter of ambiguity (I, personally, won't change it whatever poll results are)
Re: Sorting floating-point values, and NaN
On 11/12/13 10:31 AM, tn wrote: On Tuesday, 12 November 2013 at 15:56:25 UTC, Andrei Alexandrescu wrote: On 11/12/13 12:54 AM, tn wrote: ... An alternative would be to check for nans explicitly. I think NaNs are singular unordered values that make invalid inputs for either sort or isSorted. We should simply add an assert to isSorted. But sort and isSorted both allow user to provide a custom "less" function. What if the user needs NaNs and, for example, wants to sort them before all the other values? Then he calls "arr.sort!((a,b) => a < b || (isnan(a) && !isnan(b)))" and the code asserts? I think this is a misunderstanding. I never advocated inserting specialized asserts for floating-point numbers. http://goo.gl/3dGGkf takes care of that the right way - by making sure that the less predicate is sensible for the kind of work isSorted and sort do. That is regardless of the nature of the objects being sorted. Andrei
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 19:39:19 UTC, Vladimir Panteleev wrote: On Tuesday, 12 November 2013 at 19:26:12 UTC, tn wrote: Thus, the correct solution would be to modify the functions to take "lessOrEqual" as a template parameter instead of "less". Too late for that now... just like it's too late to change IEEE comparison logic. Yes, I was expecting this. :) If "less" is kept, then we need another template argument to separate equality and incomparability (something like "equals(a,b)", or "incomparable(a,b)"). Is this to allow generic partial ordering (rather than to fix sorting NaNs specifically)? I remember seeing a thread about partial ordering and opCmp: http://forum.dlang.org/post/dpfbtu$1ocf$1...@digitaldaemon.com I had generic partial orderings in my mind too, but I think it is also needed for user defined floating point types such as bigfloat. (Unless "isnan" function is defined for the bigfloat type too and detected automatically.)
Re: Sorting floating-point values, and NaN
On 11/12/13 11:06 AM, Vladimir Panteleev wrote: That doesn't change the reality that not everyone is aware of these issues, and that even people who are aware of them may overlook something somewhere. We can't pretend that there is no problem just because it's something you "have to know" and "have to be careful about" - if we can improve the situation without making a compromise elsewhere, then it must be done. I agree. I'll just add that people who plan to get work done with floating point will inevitably stumble upon NaN. There's no two ways about it. I don't see this stance as any different than shouting "RTFM!!!" at anyone who makes a mistake which, in theory, could be avoided by studying, memorization and careful application of the appropriate documentation located ... somewhere. This approach does not work - even if that user has learned his lesson the hard way, more new users will make the same mistake. Instead, you must actually make the problem less likely to manifest - improve your documentation, or improve the design of your system such that such errors will be less likely to occur. I agree here, too. Again, I'll add that "improving the documentation" helps little unless RTFM is at work :o). This particular situation affects only one specific property of floating-point numbers, so other properties are not relevant to this discussion. Personally, I've been taught about floating-point precision issues back in school, but I've only learned about NaNs while learning D. Call me an unlearned idiot if that makes you feel better, but it is rather likely that there will be more users making the same mistake in the future if the situation is not addressed. You're young. I guarantee you were to hit NaN whether or not D had anything to do with it. Furthermore, the problem is aggravated by that it is hidden by generic code. This thread isn't a complaint that "the line `if (a Yes. I have suggested possible improvements earlier in this thread, so I'd like to ask you to comment on those rather than hand-waving the problem away. I think your solutions are not good. I also think my solution in http://goo.gl/3dGGkf is good. (I know it sounds awful, but I hope you'll appreciate the brevity :o).) The solution I propose explains exactly how NaN messes up the ordering comparison operator, in a way that doesn't make the tests refer to NaN or floating point numbers in particular. Andrei
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 17:20:20 UTC, Andrei Alexandrescu wrote: Other way around. Generating arbitrary output (including but not limited to SQL expressions) from D code. Yah. That I agree with. That's why I said we should reformulate the problem that LINQ solves. I had an impression it was exactly the context in which linq was originally mentioned, no idea why discussion has moved from that to expressing DSL's (which is not really a problem in D) :) As I have already mentioned, it is the very same thing we do now with __traits and UDA's but not limited to only declarations. Interesting. Reason why I am doing this comparison is that some of the cases why UDA's are so useful applies to AST reflection capabilities too. Most importantly, it allows to have the code which is both valid (and used) D code on its own and used to generate some co-product from it in automatic mode. Similar declarative approach has been used to huge success in vibe.d code (rest, forms) and I see no reasons why it can't be so for imperative one.
Re: Sorting floating-point values, and NaN
On 11/12/2013 12:24 PM, Andrei Alexandrescu wrote: You're young. I guarantee you were to hit NaN whether or not D had anything to do with it. I want to add that NaN has been a reality on x86 machines since about 1983. C (and C++) compilers for decades have utterly ignored its existence - but that didn't make it go away. It just meant that things like the fp functions in the Standard library exhibited undefined behavior with NaNs, which is far worse than at least having sensible documented behavior. The C compilers I wrote (and C++) always made an effort to handle NaN correctly (and overflows, underflows, and subnormals), and I often felt that I was the only one who cared about it :-) What D does is simply recognize that NaNs are an inevitable characteristic of the floating point hardware, and deal with them in the most straightforward manner practical. Deciding and documenting what .sort should do with NaNs is part of that. Trying to pretend that NaNs aren't a fact of life with IEEE floating point hardware is not going to work. Note: http://dlang.org/phobos/std_math.html#.exp and how the behavior with NaN arguments is all carefully documented.
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 17:20:20 UTC, Andrei Alexandrescu wrote: As I have already mentioned, it is the very same thing we do now with __traits and UDA's but not limited to only declarations. Interesting. The thing I'd like to be able to do it to create a async/await/yield like mechanism, purely as library. @generator uint foo() { writeln("generating !"); return 0; return 1; writeln("and the last one"); return 2; } => auto foo() { enum States { S0, S1, S2, } struct Generator { State s; uint current; @property front() { return current; } void popFront() { final switch(s) with(State) { case S0: current = 1; s = S1; return; case S1: writeln("and the last one"); current = 2; s = S2; return; case S2: assert(0, "Nothing more in here"); } } @property empty() { return s == State.S2; } } auto g = Generator(); writeln("generating !"); g.current = 0; g.state = State.S0; return g; }
Re: Sorting floating-point values, and NaN
On 11/12/2013 10:25 AM, Bigsandwich wrote: Please, please, please just no. As someone who works with floating point daily, you cannot idiot proof it like this. They will never behave like "just numbers" and you can't make them. Even leaving out NAN, you have issues with precision, accumulated error, denormals, equality comparison, and on and on. If you don't know what you are doing with them, then you just shouldn't be touching them. Unicode has similar issues. I think it's apropos to reference this famous document: "What Every Computer Scientist Should Know About Floating-Point Arithmetic" http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html I know, I know, RTFM, but one cannot ignore this stuff and write professional quality fp code, nor is it practical to have the language ignore it for you.
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 20:03:37 UTC, Andrei Alexandrescu wrote: Both of the above hinge on the relative obscurity of NaNs and the problems they could cause. People who are not specifically familiar with NaNs and how they interact with other floating-point values will treat floating-point values as "just numbers", and expect them to compare and sort in the same way as integers. I think that's their problem, not ours. (I partially disagree here - see my reply to Walter.) Sort et al don't know how to check "a>=b"... and they can't use "a either, because !(a It really implies "a and b are in the same equivalence class". Building on that notion, we can figure what's wrong with NaNs and how to assert against their failings. Consider we define equiv(a, b) as (a, b) => !less(a, b) && !less(b, a). If at least one of the numbers is NaN, all comparisons return false. That puts NaN in the same equivalence class with all numbers, including numbers that are deemed in distinct equivalence classes. That's where NaNs mess things up, and that's what we need to assert. Consider three numbers a, b, and c. Then the following must pass: assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c)); OK, we're on the same page so far (although you've presented the problem more eloquently). ("<=" on Booleans is actually implication.) (Cool!) That test will fail with NaNs and should be part of isSorted, sort etc. OK, but which a, b and c will be checked? Taking all adjacent triples will not work with two adjacent NaNs. We should also check such as: assert(!less(a, a)); assert(less(a, b) <= !less(b, a)); Again, for which a/b?
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 20:24:11 UTC, Andrei Alexandrescu wrote: Again, I'll add that "improving the documentation" helps little unless RTFM is at work :o). The distinction between good and bad documentation in this context is whether the respective information is discoverable. That is, don't make users ask "How should I have known that?". A warning on the documentation of std.algorithm.sort is good, but an article on floating-points merely included together with the documentation, and not referenced from anywhere, isn't. I think your solutions are not good. I also think my solution in http://goo.gl/3dGGkf is good. (I know it sounds awful, but I hope you'll appreciate the brevity :o).) Brevity appreciated :D
Re: DIP 50 - AST macros
12-Nov-2013 21:03, Dicebot пишет: On Tuesday, 12 November 2013 at 16:54:19 UTC, Andrei Alexandrescu wrote: I don't see how AST reflection is needed for generating correct D code from an SQL expression. Dmitry did exactly that with ctRegex. Please illuminate. Other way around. Generating arbitrary output (including but not limited to SQL expressions) from D code. As I have already mentioned, it is the very same thing we do now with __traits and UDA's but not limited to only declarations. Actually I couldn't shake off the feeling that macros are just CTFE functions on Ast objects. How objects are created and converted back to source code is a separate question. If we just had: //this would invoke compiler's parser at CTFE auto ast = "x = y;".astof and have it work at CTFE to return sensible AST (a big if btw). And then (after some manipulations): ast.toString() //get back a string of D code It may help code generation of D --> DSL. Alternatively one can implement D parser that works at CTFE and watch it crawl :) -- Dmitry Olshansky
Re: GCC Looks To Turn Off Java, Replace With Go Or ADA - why not D?
And, of course, D doesn't work on ARM which is probably the single biggest target for GCC.
Re: xdc: A hypothetical D cross-compiler and AST manipulation tool.
On Tuesday, 12 November 2013 at 01:32:16 UTC, Chad Joan wrote: On Monday, 11 November 2013 at 08:11:06 UTC, Kai Nacke wrote: On Friday, 19 July 2013 at 13:38:12 UTC, Chad Joan wrote: I think a C backend would get us farther than an LLVM backend. Hi, LLVM has a C++ backend in the git tree. The old C backend is still maintained outside the git tree (search the dev mailing list for an url). So if you like C-output, you can start with LDC today. For sure, you have to port druntime to this new environemnt... Regards, Kai Is there any built-in support for using this C++ backend in LDC right now? Something like "ldc --target=c++ main.d -o main.cpp"? Careful: The "cpp" LLVM backend actually creates C++ code that constructs the corresponding LLVM IR and is mostly useful for developers working on LLVM-based compilers. But as Kai mentioned, there also is backend that emits equivalent C. Last time I checked, it was still being worked on, even though it isn't in the official LLVM source tree. David
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 20:03:37 UTC, Andrei Alexandrescu wrote: Consider we define equiv(a, b) as (a, b) => !less(a, b) && !less(b, a). If at least one of the numbers is NaN, all comparisons return false. That puts NaN in the same equivalence class with all numbers, including numbers that are deemed in distinct equivalence classes. That's where NaNs mess things up, and that's what we need to assert. Consider three numbers a, b, and c. Then the following must pass: assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c)); ("<=" on Booleans is actually implication.) Shouldn't the implication be to the other direction? Then it becomes assert((equiv(a, b) && equiv(b, c)) => equiv(a, c)); That test will fail with NaNs and should be part of isSorted, sort etc. But it requires that the input contains at least three elements. And it has to test a lot of possible triples (a,b,c), which I think requires at least O(n^2) time. And it does not fail consistently whenever the input contains at least one NaN (consider an input that contains only NaNs). We should also check such as: assert(!less(a, a)); assert(less(a, b) <= !less(b, a)); These should be checked in sort only; isSorted does not need these. The latter fails also if a==b. (Unless the direction of the implication is again wrong.)
Re: Sorting floating-point values, and NaN
On 11/12/13 1:03 PM, tn wrote: On Tuesday, 12 November 2013 at 20:03:37 UTC, Andrei Alexandrescu wrote: Consider we define equiv(a, b) as (a, b) => !less(a, b) && !less(b, a). If at least one of the numbers is NaN, all comparisons return false. That puts NaN in the same equivalence class with all numbers, including numbers that are deemed in distinct equivalence classes. That's where NaNs mess things up, and that's what we need to assert. Consider three numbers a, b, and c. Then the following must pass: assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c)); ("<=" on Booleans is actually implication.) Shouldn't the implication be to the other direction? Then it becomes assert((equiv(a, b) && equiv(b, c)) => equiv(a, c)); It is in the other direction, but the latter doesn't compile :o). Again, it just turns out "a <= b" has the meaning of "a implies b". It's not a particularly intuitive way to express it. That test will fail with NaNs and should be part of isSorted, sort etc. But it requires that the input contains at least three elements. And it has to test a lot of possible triples (a,b,c), which I think requires at least O(n^2) time. And it does not fail consistently whenever the input contains at least one NaN (consider an input that contains only NaNs). I agree. Ideas? We should also check such as: assert(!less(a, a)); assert(less(a, b) <= !less(b, a)); These should be checked in sort only; isSorted does not need these. The latter fails also if a==b. (Unless the direction of the implication is again wrong.) Try it! Andrei
Re: Sorting floating-point values, and NaN
On Tuesday, 12 November 2013 at 21:03:03 UTC, tn wrote: assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c)); ("<=" on Booleans is actually implication.) Shouldn't the implication be to the other direction? Then it becomes assert((equiv(a, b) && equiv(b, c)) => equiv(a, c)); <= as in ≤ (less or equal), not ⇐ (reverse implies). <= can be used on booleans as "implies" due to the way it treats booleans as integers (true as 1, false as 0).
Re: Sorting floating-point values, and NaN
On 11/12/13 12:45 PM, Vladimir Panteleev wrote: assert((equiv(a, b) && equiv(b, c)) <= equiv(a, c)); OK, we're on the same page so far (although you've presented the problem more eloquently). ("<=" on Booleans is actually implication.) (Cool!) (... the disadvantage being b is evaluated even if a is false. Shouldn't; false implies everything.) That test will fail with NaNs and should be part of isSorted, sort etc. OK, but which a, b and c will be checked? Taking all adjacent triples will not work with two adjacent NaNs. We can make that work if we insert the tests at the end of a run of equivalent values. That would still miss other cases though in isSorted (I think sort() can actually be much more thorough there). The point here is that we should work together on an innovative solution. Getting bogged in the "there's a problem with the language here" mindset prevents the forming of good ideas. We should also check such as: assert(!less(a, a)); assert(less(a, b) <= !less(b, a)); Again, for which a/b? In the isSorted case, for all adjacent values inspected. For sort, assertions can be added after each less() that does work. Andrei
Re: DIP 50 - AST macros
On Tuesday, 12 November 2013 at 20:56:34 UTC, Dmitry Olshansky wrote: If we just had: //this would invoke compiler's parser at CTFE auto ast = "x = y;".astof and have it work at CTFE to return sensible AST (a big if btw). And then (after some manipulations): ast.toString() //get back a string of D code It may help code generation of D --> DSL. Add there "foo.codeof" in the toolset and it will pretty much give core needed stuff. However, it will destroy compilation times if not coupled with compiler internal parsing/semantic phase. Actual "macro" keyword syntax sugar is hardly important to me.