Re: User defined attributes use
On Sunday, 15 September 2013 at 18:31:40 UTC, simendsjo wrote: On Sunday, 15 September 2013 at 17:34:06 UTC, matovitch wrote: Hi everyone, I read the documentation about user defined attributes, but I don't see their uses. Ok, it'a a template expression you can link to a declaration, but what are they useful for ? (not sure about the syntax ;-)) Can you declare a template constraint as a user defined attribute to do something like : void template_function_which_go_back_and_forth(@(Bidirectional) @(Range) BR)(BR br) {...} This would be awesome (even if not really occidental) to do something like: @(SmallTypeSet) @(MediumTypeSet) @(LargeTypeSet) Type This could allow to build tree based category structure. It enables declarative programming. And because this is D, there is no runtime overhead. A common use is to add semantics to types and instances that is difficult or very intrusive to do by creating structs/classes by hand. A little validation example: @nonNull // An instance shouldn't be allowed to be null class C { @matches([0-9]+) string someNumber; @interval!(](0, 10) // (0, 10] range int someInt; } C c; validate(c); // returns [C is null, someNumber doesn't match '[0-9]+', someInt is outside the interval '(0, 10]'] And ORMs usually use annotations: @table(some_tablename) class C { @id(id_field_name) int id; } Take a look at C# and Java libraries to see how many uses attributes/annotations - they are still quite new in D, so they are still underutilized. A very big difference is of course that UDAs are available at compile time :) Can you print a full examle? For example, can you implement matches UDA and validate function. It's intresting how can I create new UDA and check if it's available for class/field.
Question about pure functions
Hello, ich habe a pure method bar() in a class Foo: class Foo { int i = 0; void bar() pure { i++; } } main() { auto foo = new Foo(); foo.bar() } The pure method bar changes the inst var i. Nevertheless, the code above compiles and runs which I find confusing. I assumed that changing an inst var by a pure function is considered creating a side efect. But the compiler has no problems with this. Am I getting something wrong here? Thanks for any hints. Regards, Bienlein
Re: User defined attributes use
On Monday, 16 September 2013 at 06:47:40 UTC, ilya-stromberg wrote: On Sunday, 15 September 2013 at 18:31:40 UTC, simendsjo wrote: On Sunday, 15 September 2013 at 17:34:06 UTC, matovitch wrote: Hi everyone, I read the documentation about user defined attributes, but I don't see their uses. Ok, it'a a template expression you can link to a declaration, but what are they useful for ? (not sure about the syntax ;-)) Can you declare a template constraint as a user defined attribute to do something like : void template_function_which_go_back_and_forth(@(Bidirectional) @(Range) BR)(BR br) {...} This would be awesome (even if not really occidental) to do something like: @(SmallTypeSet) @(MediumTypeSet) @(LargeTypeSet) Type This could allow to build tree based category structure. It enables declarative programming. And because this is D, there is no runtime overhead. A common use is to add semantics to types and instances that is difficult or very intrusive to do by creating structs/classes by hand. A little validation example: @nonNull // An instance shouldn't be allowed to be null class C { @matches([0-9]+) string someNumber; @interval!(](0, 10) // (0, 10] range int someInt; } C c; validate(c); // returns [C is null, someNumber doesn't match '[0-9]+', someInt is outside the interval '(0, 10]'] And ORMs usually use annotations: @table(some_tablename) class C { @id(id_field_name) int id; } Take a look at C# and Java libraries to see how many uses attributes/annotations - they are still quite new in D, so they are still underutilized. A very big difference is of course that UDAs are available at compile time :) Can you print a full examle? For example, can you implement matches UDA and validate function. It's intresting how can I create new UDA and check if it's available for class/field. I don't have a full example without adding a lot of code, but this partial example might give you the gist of it. // This is the type that validates struct matches(string mustMatch) { alias re = ctRegex!(mustMatch); static string[] validate(T)(const ref T t) { static if(!isSomeString!T) static assert(0, matches only works on strings, not ~T.stringof); return match(t, re).empty ? [no match] : null; } } // and this is the code that runs all validators for a variable void validate(alias T)(ref Appender!(string[]) app) { static if(isTupleWrapper!T) { validate!(T.Head)(app); validate!(T.Tail)(app); } else { foreach(memberAttr; getValidaterAttrs!T) { foreach(attr; memberAttr.Tail) { foreach(msg; attr.validate(T)) if(msg.length) app.put(msg); } } } } // .. And here is some of the plumbing string[] validate(Vars...)() { auto app = appender!(string[])(); validate!Vars(app); return app.data(); } // The getMembersAndAttributesWhere are templates in my little library that isn't released. Uses quite some custom __traits stuff, but it's basically __traits(getAttributes template getValidaterAttrs(alias T) { alias getValidaterAttrs = TypeTuple!(getMembersAndAttributesWhere!(T, isValidationAttr).Elements, getMembersAndAttributesWhere!(TypeOf!T, isValidationAttr).Elements); } // Well.. Incomplete template isValidationAttr(alias T) { enum isValidationAttr = hasMember!(TypeOf!T, validate); }
Re: Question about pure functions
On Monday, 16 September 2013 at 07:01:52 UTC, Bienlein wrote: Hello, ich habe a pure method bar() in a class Foo: class Foo { int i = 0; void bar() pure { i++; } } main() { auto foo = new Foo(); foo.bar() } The pure method bar changes the inst var i. Nevertheless, the code above compiles and runs which I find confusing. I assumed that changing an inst var by a pure function is considered creating a side efect. But the compiler has no problems with this. Am I getting something wrong here? Thanks for any hints. Regards, Bienlein (Weak) pure functions are allowed to mutate their arguments. Methods take the object via a hidden parameter, so that's an argument, too. Mark all parameters const to get a strong pure function. For this const goes on the method: class Foo { int i = 0; void bar() const pure { // can't mutate i here } } See also: http://dlang.org/function.html#pure-functions
Re: Question about pure functions
Mark all parameters const to get a strong pure function. For this const goes on the method: class Foo { int i = 0; void bar() const pure { // can't mutate i here } } See also: http://dlang.org/function.html#pure-functions I see, thanks a lot. I like this pure feature and was already disappointed. Scala doesn't have it (has to remain interoperable with Java), so I was really happy to see it in D. Your answer saved my day :-) -- Bienlein
Problems setting up Eclipse/DDT
What with all the IDE discussion going on, I thought I'd have a go at trying out Eclipse with the DDT plugin. I'm running Eclipse 3.8 installed from system repos on Ubuntu 13.10. Adding the DDT plugin as per the instructions here: http://code.google.com/p/ddt/wiki/Installation ... seems to work fine. Now I go to the Window menu and select Preferences, and then click on DDT Compilers, and click the Search button. The search process freezes when it discovers LDC, with the Progress Information window reading: Found 3007 - Searching /opt/ldc/bin/ldmd2 ... and I'm forced to kill Eclipse manually. Can anyone advise what the problem might be and how to correct it? I asked this on the DDT Google Group but had no response, so thought I'd ask here. Suffice to say that I think that, even if LDC isn't supported via DDT yet, it's pretty bad that the search for compilers should freeze up if LDC is installed.
Re: User defined attributes use
All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null
Re: User defined attributes use
On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null Very interesting. Does this go beyond annotations in Java? Just out of curiosity, no language war intended. -- Bienlein
Re: N step fft in D language
I think you are not aswering his question (but maybe I am wrong). If you want a Fourier transform with less frequencies than temporal samples you can perform a fft to get a result of same length like this : 9 2 7 6 1 8 (amplitude) 0 2 4 6 8 10 (frequency) Then transform it like this : 11 13 9 (amplitude) (integrate the amplitudes) 1 5 9 (frequency) (according to your frequencies) This is a trivial example...I hope it's clear enougth...
Re: User defined attributes use
On Monday, 16 September 2013 at 10:36:16 UTC, Bienlein wrote: On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null Very interesting. Does this go beyond annotations in Java? Just out of curiosity, no language war intended. -- Bienlein And with template parameters. fun(@Arithmetic T)(...) {...} alias fun!string funstr; //compilation error since a string is not an arithmetic type
Re: Problems setting up Eclipse/DDT
On 2013-09-16 11:56, Joseph Rushton Wakeling wrote: What with all the IDE discussion going on, I thought I'd have a go at trying out Eclipse with the DDT plugin. I'm running Eclipse 3.8 installed from system repos on Ubuntu 13.10. Adding the DDT plugin as per the instructions here: http://code.google.com/p/ddt/wiki/Installation ... seems to work fine. Now I go to the Window menu and select Preferences, and then click on DDT Compilers, and click the Search button. The search process freezes when it discovers LDC, with the Progress Information window reading: Found 3007 - Searching /opt/ldc/bin/ldmd2 ... and I'm forced to kill Eclipse manually. Can anyone advise what the problem might be and how to correct it? I asked this on the DDT Google Group but had no response, so thought I'd ask here. Suffice to say that I think that, even if LDC isn't supported via DDT yet, it's pretty bad that the search for compilers should freeze up if LDC is installed. I think it's better that you manually add paths to the compiler, then searching for it, if possible, -- /Jacob Carlborg
Re: Errors compiling in release mode (phobos bug..?)
On Saturday, 14 September 2013 at 13:10:54 UTC, simendsjo wrote: Compiling with --build=unittest and debug works, but not --build=release: $ dub build --build=debug Checking dependencies in 'C:\code\d\myapp' Building configuration application, build type debug Copying files... Running dmd (compile)... Compiling diet template 'about.dt' (compat)... Linking... $ dub build --build=release Checking dependencies in 'C:\code\d\myapp' Building configuration application, build type release Copying files... Running dmd (compile)... Compiling diet template 'about.dt' (compat)... C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2407): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2407): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2410): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2410): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2410): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2411): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2407): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2407): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2410): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2410): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2410): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2411): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2415): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2415): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2418): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2418): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2418): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2419): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, char[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2415): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2415): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)[]).put C:\dmd\windows\bin\..\..\src\phobos\std\string.d(2418): Error: function std.string.sformat!(char, long).sformat is a nested function and cannot be accessed from std.range.put!(Sink, const(char)[]).put Error: Build command failed with exit code 1 I am having almost this exact same problem, but I'm also getting linker errors complaining about undefined symbols. I've got a thread about it on the Vibe forums.
Re: User defined attributes use
On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null No, this isn't doable with UDAs because what you want requires runtime check. It is doable using other language features.
Re: User defined attributes use
On Monday, 16 September 2013 at 15:12:05 UTC, Maxim Fomin wrote: On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null No, this isn't doable with UDAs because what you want requires runtime check. It is doable using other language features. It's intresting how can I check that pointer is not null at the compile time. Can you print a example, please? I know that we can use contract programming, but it requires runtime check.
Re: Question about pure functions
On Monday, September 16, 2013 10:08:22 anonymous wrote: Mark all parameters const to get a strong pure function. For this const goes on the method: That's not actually enough. At present, in order for a function to be considered strongly pure, all of its parameters must be either immutable or implicitly convertible to pure (including the this reference). A const reference type is neither. In principle, a function could be considered strongly pure if its parameters were const but its arguments were immutable, but the compiler isn't that smart about it at this point. The parameters themselves must be immutable or implicitly convertible to immutable. So, at present, for a member function to be considered strongly pure, it must be an immutable member function, not const. In theory it could be const if the object itself were immutable, but again, the compiler isn't that smart about it at this point. In either case, the actual object would have to be immutable, which is not the case in most code. And if you make the member functions immutable, they can only be called by immutable objects, forcing you to either duplicate your functions or make it so that your class can only be constructed as immutable. pure member functions are useful, because they guarantee that the function is not accessing global mutable state, and because it makes it so that they can be called from strongly pure functions, but in general, pure member functions can't be strongly pure and therefore can't be optimized. If you want to see how many times a pure function is being called, then put a call to writeln inside of a debug {} block inside of it and compile with -debug, since debug blocks are not checked for purity (since they're for debugging). It should then print out every time it's being called, which should allow you to see whether multiple calls with the same arguments within an expression are actually being optimized out (though you might have to compile with -O for the compiler to do the optimizations - I don't know). - Jonathan M Davis
Re: User defined attributes use
On Monday, 16 September 2013 at 15:47:36 UTC, ilya-stromberg wrote: On Monday, 16 September 2013 at 15:12:05 UTC, Maxim Fomin wrote: On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null No, this isn't doable with UDAs because what you want requires runtime check. It is doable using other language features. It's intresting how can I check that pointer is not null at the compile time. Can you print a example, please? I know that we can use contract programming, but it requires runtime check. That isn't possible. ;)
Re: User defined attributes use
On Monday, 16 September 2013 at 16:50:43 UTC, Namespace wrote: On Monday, 16 September 2013 at 15:47:36 UTC, ilya-stromberg wrote: On Monday, 16 September 2013 at 15:12:05 UTC, Maxim Fomin wrote: On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null No, this isn't doable with UDAs because what you want requires runtime check. It is doable using other language features. It's intresting how can I check that pointer is not null at the compile time. Can you print a example, please? I know that we can use contract programming, but it requires runtime check. That isn't possible. ;) Similar effect can be achieved by different way. If some function takes S as parameter, one cannot pass directly instance of A or null - error will be issued which is some sort of compile-time protection. class A { int i; } struct S { A a; A getA() { if (a is null) a = new A; return a; } alias getA this; } void main() { S s; assert (s.i is 0); S ss = S.init; assert (ss.i is 0); } Unfortunately D does not have non-nullable classes which is a problem #1. Ideally structs should have default constructors (hello to those who miss them - problem #2) which could initialize class instance. Since they are absent, wrapping struct can be enhanced by inserting disabled constructor to ensure that no default struct instances with null references are created. However, since disabled constructors are also flawed (they don't prevent from producing T.init values by design and in some situations dmd is not smart enough to detect other cases by mistake) which is a problem #3, non-null classes can be simulated by code above using alias this + rt check. At least this works with two most problematic cases of struct initilialization: without initializer and with T.init value.
Re: User defined attributes use
On Monday, 16 September 2013 at 17:50:16 UTC, Maxim Fomin wrote: Ideally structs should have default constructors (hello to those who miss them - problem #2) which could initialize class instance. Do you know why D structs don't have default constructors? I really miss.
Re: User defined attributes use
On Monday, 16 September 2013 at 17:50:16 UTC, Maxim Fomin wrote: On Monday, 16 September 2013 at 16:50:43 UTC, Namespace wrote: On Monday, 16 September 2013 at 15:47:36 UTC, ilya-stromberg wrote: On Monday, 16 September 2013 at 15:12:05 UTC, Maxim Fomin wrote: On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null No, this isn't doable with UDAs because what you want requires runtime check. It is doable using other language features. It's intresting how can I check that pointer is not null at the compile time. Can you print a example, please? I know that we can use contract programming, but it requires runtime check. That isn't possible. ;) Similar effect can be achieved by different way. If some function takes S as parameter, one cannot pass directly instance of A or null - error will be issued which is some sort of compile-time protection. class A { int i; } struct S { A a; A getA() { if (a is null) a = new A; return a; } alias getA this; } void main() { S s; assert (s.i is 0); S ss = S.init; assert (ss.i is 0); } Unfortunately D does not have non-nullable classes which is a problem #1. Ideally structs should have default constructors (hello to those who miss them - problem #2) which could initialize class instance. Since they are absent, wrapping struct can be enhanced by inserting disabled constructor to ensure that no default struct instances with null references are created. However, since disabled constructors are also flawed (they don't prevent from producing T.init values by design and in some situations dmd is not smart enough to detect other cases by mistake) which is a problem #3, non-null classes can be simulated by code above using alias this + rt check. At least this works with two most problematic cases of struct initilialization: without initializer and with T.init value. Yes, I know. Search for my name and not null, you will find many topics. I hate this NotNull struct hack. It is the same crap as the current scope solution. BTW: I'm curious which built-in feature will be removed next, maybe AA? An annotation like Foo! f would be much nicer than NotNull!Foo or @NotNull Foo, but it would be an agreement. And I agree absolute, to disable default CTor's by struct's was a huge mistake. But D is full of those. ;)
Re: User defined attributes use
On Monday, 16 September 2013 at 18:44:25 UTC, ilya-stromberg wrote: On Monday, 16 September 2013 at 17:50:16 UTC, Maxim Fomin wrote: Ideally structs should have default constructors (hello to those who miss them - problem #2) which could initialize class instance. Do you know why D structs don't have default constructors? I really miss. My favorites: http://forum.dlang.org/thread/ij6kl4$2jv9$1...@digitalmars.com http://forum.dlang.org/thread/bvuquzwfykiytdwsq...@forum.dlang.org http://forum.dlang.org/thread/icjwbtlxsaekksyol...@forum.dlang.org
Re: User defined attributes use
On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote: All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ? For example : class C { ... } void fun(@nonNull C c) { ... }; C c; fun(c); //compilation error since C is null As others have noted, the compiler cannot know what any of your attributes mean. But you can do this: class C { invariant() { validate(this); } }
Re: User defined attributes use
On Mon, Sep 16, 2013 at 08:56:17PM +0200, Namespace wrote: [...] I hate this NotNull struct hack. It is the same crap as the current scope solution. BTW: I'm curious which built-in feature will be removed next, maybe AA? [...] That wouldn't be a bad idea, actually. The current AA implementation is so horribly broken, and so wrong in so many ways (there are at least 75 bugs related to AA's, some of the worst of which are 11037, 11025, 10916, 10525, 10381, 10380, 10046, just to name a few), that it would do a world of good to get rid of them altogether, and then reintroduce a properly-designed library solution for them. Of course, in the meantime everyone whose code breaks because of that will form a mob to lynch me, so I'll have to survive long enough to get the library solution working first. :-P T -- Microsoft is to operating systems security ... what McDonalds is to gourmet cooking.
Re: User defined attributes use
Long time not heard from each other. ;) On Monday, 16 September 2013 at 19:28:22 UTC, Andrei Alexandrescu wrote: On 9/16/13 11:56 AM, Namespace wrote: I hate this NotNull struct hack. It is the same crap as the current scope solution. Scoped variables in the language were a lot worse. Why? The escaping problem could be solved, not? Wouldn't it be better, if scope would stay and would be rewritten internal to the library solution? The compiler could then detect and solve many of the current problems. BTW: I'm curious which built-in feature will be removed next, maybe AA? If we're diligent and lucky, hopefully. That was a joke of me. So I hope that is also a joke. Otherwise it would be a huge step in the C++ direction. If it wasn't a joke: what are the rationale for that? An annotation like Foo! f would be much nicer than NotNull!Foo or @NotNull Foo, but it would be an agreement. Is annotation the only or main problem? My problem are the nullable classes. But I would be happy with an annotation. And I agree absolute, to disable default CTor's by struct's was a huge mistake. But D is full of those. ;) They are not disabled. It seems many people are having trouble with getting default constructors to evaluate code, so I assume you mean that. One possibility (or first step) would be to relax the language to allow CTFE-executable code in default constructors. Andrei Example?
Re: User defined attributes use
On 9/16/13 11:56 AM, Namespace wrote: I hate this NotNull struct hack. It is the same crap as the current scope solution. Scoped variables in the language were a lot worse. BTW: I'm curious which built-in feature will be removed next, maybe AA? If we're diligent and lucky, hopefully. An annotation like Foo! f would be much nicer than NotNull!Foo or @NotNull Foo, but it would be an agreement. Is annotation the only or main problem? And I agree absolute, to disable default CTor's by struct's was a huge mistake. But D is full of those. ;) They are not disabled. It seems many people are having trouble with getting default constructors to evaluate code, so I assume you mean that. One possibility (or first step) would be to relax the language to allow CTFE-executable code in default constructors. Andrei
Re: User defined attributes use
On Monday, 16 September 2013 at 19:28:22 UTC, Andrei Alexandrescu wrote: On 9/16/13 11:56 AM, Namespace wrote: And I agree absolute, to disable default CTor's by struct's was a huge mistake. But D is full of those. ;) They are not disabled. It seems many people are having trouble with getting default constructors to evaluate code, so I assume you mean that. One possibility (or first step) would be to relax the language to allow CTFE-executable code in default constructors. Yes, we REALLY need this. I know that we can init struct fields via user-defined value, but for many cases is not enough. And in that days I remembered C++. Buy the way, what does it mean They are not disabled? struct Foo { int i = 5; //works } struct Bar { int i; this() { i = 5; } } DMD: src/app.d(10): Error: constructor app.Bar.this default constructor for structs only allowed with @disable and no body
Re: User defined attributes use
On Mon, Sep 16, 2013 at 12:28:21PM -0700, Andrei Alexandrescu wrote: On 9/16/13 11:56 AM, Namespace wrote: I hate this NotNull struct hack. It is the same crap as the current scope solution. Scoped variables in the language were a lot worse. One thing I'd *really* like to have is proper escape analysis and inlining of scope delegates. I've been waiting a long time for this, and there are no signs of implementation in sight. :-( BTW: I'm curious which built-in feature will be removed next, maybe AA? If we're diligent and lucky, hopefully. I don't see what luck has to do with it... Currently, I lack just time and adequate understanding of DMD internals; if I had both, I'd rip out the AA implementation from DMD right now, and replace it with something saner. [...] And I agree absolute, to disable default CTor's by struct's was a huge mistake. But D is full of those. ;) They are not disabled. [...] Huh, what? struct S { this() {} } DMD output: /tmp/test.d(2): Error: constructor test.S.this default constructor for structs only allowed with @disable and no body T -- You are only young once, but you can stay immature indefinitely. -- azephrahel
Re: User defined attributes use
On Monday, 16 September 2013 at 19:21:47 UTC, H. S. Teoh wrote: On Mon, Sep 16, 2013 at 08:56:17PM +0200, Namespace wrote: [...] I hate this NotNull struct hack. It is the same crap as the current scope solution. BTW: I'm curious which built-in feature will be removed next, maybe AA? [...] That wouldn't be a bad idea, actually. The current AA implementation is so horribly broken, and so wrong in so many ways (there are at least 75 bugs related to AA's, some of the worst of which are 11037, 11025, 10916, 10525, 10381, 10380, 10046, just to name a few), that it would do a world of good to get rid of them altogether, and then reintroduce a properly-designed library solution for them. Of course, in the meantime everyone whose code breaks because of that will form a mob to lynch me, so I'll have to survive long enough to get the library solution working first. :-P T Built-in Arrays have also problems. What should we do? Remove and rewrite them also as library solution? With Arrays and AA's we would lose a lot of good differences to C++. Why should anyone switch to D if it is nothing else as a new C++?
Re: User defined attributes use
On Monday, 16 September 2013 at 19:58:51 UTC, Namespace wrote: Why should anyone switch to D if it is nothing else as a new C++? It's worth pointing out that the library AAs proposed here would still have the same syntax as the built-in ones now. int[string] a; would just be magically rewritten into AssociativeArray!(int, string) a; and [one : 1, two : 2], would just become something like AALiteral([one, two], [1, 2]);, or whatever, I'm not sure exactly what they were going to do there. Anyway though, all the sugar is still there, just a new implementation as a regular D struct instead of a bunch of calls to _d_assocarray and the other dozen magic functions and typeinfo things it uses now. BTW part of the bugginess is because this move to the library was half-assed. It does do the AssocativeArray rewrite... but it also still uses the magic functions. So there's all kinds of weird crap going on that can make programs fail to link and other bugs since we've been stuck in this no-man's land for years.
Re: User defined attributes use
On Monday, 16 September 2013 at 20:15:26 UTC, Namespace wrote: On Monday, 16 September 2013 at 20:09:53 UTC, Adam D. Ruppe wrote: On Monday, 16 September 2013 at 19:58:51 UTC, Namespace wrote: Why should anyone switch to D if it is nothing else as a new C++? It's worth pointing out that the library AAs proposed here would still have the same syntax as the built-in ones now. int[string] a; would just be magically rewritten into AssociativeArray!(int, string) a; and [one : 1, two : 2], would just become something like AALiteral([one, two], [1, 2]);, or whatever, I'm not sure exactly what they were going to do there. Then of course I have not said anything. The same thing I would suggest for scope. It exists as a library solution and is rewritten magical. And maybe also for delete: we need something to delete the memory manually.
Re: User defined attributes use
On Monday, 16 September 2013 at 20:09:53 UTC, Adam D. Ruppe wrote: On Monday, 16 September 2013 at 19:58:51 UTC, Namespace wrote: Why should anyone switch to D if it is nothing else as a new C++? It's worth pointing out that the library AAs proposed here would still have the same syntax as the built-in ones now. int[string] a; would just be magically rewritten into AssociativeArray!(int, string) a; and [one : 1, two : 2], would just become something like AALiteral([one, two], [1, 2]);, or whatever, I'm not sure exactly what they were going to do there. Then of course I have not said anything. The same thing I would suggest for scope. It exists as a library solution and is rewritten magical.
Re: Compile time data structure
Ali Çehreli wrote: Could you please provide complete code. Sure. This is of course stripped down just for demonstration purposes: struct Attr { string name; } mixin template Model() { static string[string] columns () { string[string] cols; alias type = typeof(this); // Basically - get all members with @Attr UDA and build AA out of those foreach( field; __traits(derivedMembers, type)) { static if( is(typeof(__traits(getAttributes, __traits(getMember, type, field))) blah)) { foreach( uda; __traits(getAttributes, __traits(getMember, type, field))) { static if (is (typeof(uda) == Attr)) { static if (uda.name == ) cols[field] = field; else cols[field] = uda.name; } } } } return cols; } alias typeof(this) Me; static Me initialize () { Me me = new Me(); foreach( attr, col; columns() ) { __traits(getMember, me, attr) = typeof(__traits(getMember, me, attr)).init; } return me; } } class ExampleModel { @Attr() int id; @Attr( field_id ) int fieldId; mixin Model; } void main () { ExampleModel ex = ExampleModel.initialize(); } -- Marek Janukowicz
Re: User defined attributes use
On Monday, 16 September 2013 at 20:16:45 UTC, Namespace wrote: And maybe also for delete: we need something to delete the memory manually. And we need built-in memory allocators, not only GC.
public alias to private template implementation
Reduced: // module A; alias fun = Impl!int; private template Impl(T) { void Impl(){} } // void main() { fun(); } // Error: function A.Impl!int.Impl is not accessible from module main // I'm trying to implement a set of public funtions, in terms of a template. Said template has no business being know to the user, so I want to mark it as private. Unfortunately, if I do this, then I can't use the alias, because Impl is private. Question 1: Is this the correct behavior? I'd have expected that if my alias is public, it would allow any one from outside to make the call correctly. Question 2: Is there a correct way to do this? I possible, I'd want to avoid nesting the template, eg: auto fun(){return Impl!int();} As that would: a) require more typing ^^ b) incur an extra function call in non-inline c) if at all possible, I actually need fun to be a template, so that it can be inlined.
Re: User defined attributes use
On 09/16/13 22:38, Namespace wrote: [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high. Why to high? Too much compiler magic or dmd internal dependences? Too much (language) change for too little gain; there are many, many much more important things that need to be fixed. Being able to have several user-defined kinds of arrays is a nice-to-have feature, but not one that determines whether the language is usable or not. artur
Re: User defined attributes use
On Monday, 16 September 2013 at 21:11:00 UTC, Artur Skawina wrote: On 09/16/13 22:52, H. S. Teoh wrote: On Mon, Sep 16, 2013 at 10:38:58PM +0200, Namespace wrote: D is not only about arrays. It's a big plus. ;) [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high. Why to high? Too much compiler magic or dmd internal dependences? I disagree that it's too high. It just needs *somebody* with the right knowledge about DMD internals (and enough free time on their hands :-)) to pull it off. I thought (s)he was asking about *arrays*, not AAs. There's no disagreement about removing AA magic - that does not involve language changes. artur Yes, he was. ;) Thanks for explanation.
Re: ref + operator overloading question
On Monday, 16 September 2013 at 20:53:18 UTC, Namespace wrote: On Monday, 16 September 2013 at 20:43:01 UTC, Aleksey wrote: I get strange type errors in the following code, and I don't understand why =( Could anybody help? struct I { int i; I opBinary(string op)(ref I that) if (op == +) { return I(i + that.i); } } void main() { auto a = I(1); auto d = a + (a + a); } Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I' If I remove ref or parens around (a+a) the code compiles just fine. opBinary returns a rvalue. But your code accepts only lvalues. (a + a) produce an rvalue so a + (a + a) is the same as lvalue + rvalue and rvalues aren't accepted. You could use auto ref for that purpose. Thank you! auto ref is exactly what I was looking for!
Re: Mixin namespace ambiguity?
Kenji Hara wrote: Currently this is not a bug. Looking from the module 'main', the mixin identifier 'X' declared in main.d is *closer* than the 'X' declared in aux.d, because the latter exists beyond the module import boundary. Therefore, the use of 'X' in main.d would prefere the `mixin A!(a in main) X`. I get this one - if X was eg. a class and I was calling it's static member it would work the same way. On the other hand, when the name search, all mixed-in symbols are treated as if they are just imported at the mixed-in scope. Could you please elaborate a bit more or point me to some documentation where this is described? If the mixins are imported at mixed-in scope, my understanding would be the one in 'main' is closer than the one in 'aux'. Therefore, even from main.d, the two mixed-in functions 'a' have same closeness, and the call is ambiguous because they have exactly same signature. -- Marek Janukowicz
Re: ref + operator overloading question
On Monday, 16 September 2013 at 20:43:01 UTC, Aleksey wrote: I get strange type errors in the following code, and I don't understand why =( Could anybody help? struct I { int i; I opBinary(string op)(ref I that) if (op == +) { return I(i + that.i); } } void main() { auto a = I(1); auto d = a + (a + a); } Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I' If I remove ref or parens around (a+a) the code compiles just fine. opBinary returns a rvalue. But your code accepts only lvalues. (a + a) produce an rvalue so a + (a + a) is the same as lvalue + rvalue and rvalues aren't accepted. You could use auto ref for that purpose.
Re: User defined attributes use
D is not only about arrays. It's a big plus. ;) [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high. Why to high? Too much compiler magic or dmd internal dependences?
Re: User defined attributes use
On 09/16/13 22:52, H. S. Teoh wrote: On Mon, Sep 16, 2013 at 10:38:58PM +0200, Namespace wrote: D is not only about arrays. It's a big plus. ;) [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high. Why to high? Too much compiler magic or dmd internal dependences? I disagree that it's too high. It just needs *somebody* with the right knowledge about DMD internals (and enough free time on their hands :-)) to pull it off. I thought (s)he was asking about *arrays*, not AAs. There's no disagreement about removing AA magic - that does not involve language changes. artur
ref + operator overloading question
I get strange type errors in the following code, and I don't understand why =( Could anybody help? struct I { int i; I opBinary(string op)(ref I that) if (op == +) { return I(i + that.i); } } void main() { auto a = I(1); auto d = a + (a + a); } Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I' If I remove ref or parens around (a+a) the code compiles just fine.
Re: User defined attributes use
On 09/16/13 21:58, Namespace wrote: On Monday, 16 September 2013 at 19:21:47 UTC, H. S. Teoh wrote: On Mon, Sep 16, 2013 at 08:56:17PM +0200, Namespace wrote: [...] I hate this NotNull struct hack. It is the same crap as the current scope solution. BTW: I'm curious which built-in feature will be removed next, maybe AA? [...] That wouldn't be a bad idea, actually. The current AA implementation is so horribly broken, and so wrong in so many ways (there are at least 75 [...] Built-in Arrays have also problems. What should we do? Remove and rewrite them also as library solution? Yes. Without any doubt whatsoever. [1] With Arrays and AA's we would lose a lot of good differences to C++. Removing hardwired builtin magic does not imply syntax changes. And, the syntax that matters in practice is not the declarations, but the literals, which is where the language could do much better anyway. Why should anyone switch to D if it is nothing else as a new C++? D is not only about arrays. artur [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high.
Re: ref + operator overloading question
On Monday, 16 September 2013 at 21:01:48 UTC, Aleksey wrote: On Monday, 16 September 2013 at 20:53:18 UTC, Namespace wrote: On Monday, 16 September 2013 at 20:43:01 UTC, Aleksey wrote: I get strange type errors in the following code, and I don't understand why =( Could anybody help? struct I { int i; I opBinary(string op)(ref I that) if (op == +) { return I(i + that.i); } } void main() { auto a = I(1); auto d = a + (a + a); } Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I' If I remove ref or parens around (a+a) the code compiles just fine. opBinary returns a rvalue. But your code accepts only lvalues. (a + a) produce an rvalue so a + (a + a) is the same as lvalue + rvalue and rvalues aren't accepted. You could use auto ref for that purpose. Thank you! auto ref is exactly what I was looking for! You should know, that auto ref is only useable for template functions/methods. Maybe this will change, but not in the next years.
Re: User defined attributes use
On Mon, Sep 16, 2013 at 10:38:58PM +0200, Namespace wrote: D is not only about arrays. It's a big plus. ;) [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high. Why to high? Too much compiler magic or dmd internal dependences? I disagree that it's too high. It just needs *somebody* with the right knowledge about DMD internals (and enough free time on their hands :-)) to pull it off. The problem with the current AA implementation is that it's schizophrenically split across DMD, aaA.d, and object.di. Martin Nowak recently cleaned it up somewhat (removed the horrible code duplication between aaA.d and object.di that used to be there) but fundamental issues remain, a major cause of which is the fact that aaA.d operates on typeinfo's rather than the direct types (this isn't a problem in and of itself, but the problem is that *only* AA keys have the benefit of their typeinfo's being available to AA functions, which means AA *values* that require non-trivial postblits and other such things are fundamentally broken in horrible ways). Moreover, DMD still retains way too much knowledge about AA internals, so sometimes it gets mapped to struct AssociativeArray, sometimes directly mapped to aaA.d, and sometimes a buggy inconsistent mixture of both. And the code that emits these different schizophrenic parts are sprinkled all over different unrelated parts of DMD, making any cleanup attempt rather challenging, to say the least. And of course, any non-correspondence between any of these parts means yet another AA bug waiting to happen. Cleaning up this mess once and for all will unquestionably do a world of good to D. T -- You are only young once, but you can stay immature indefinitely. -- azephrahel
Re: User defined attributes use
On Mon, Sep 16, 2013 at 10:59:10PM +0200, Artur Skawina wrote: On 09/16/13 22:38, Namespace wrote: [1] Obviously, not a practical short term option for the existing D2 language. That's probably clear from the context, and the question was meant to be rhetorical -- but it could actually be done and would make sense; it's just not a change that would make enough of a difference on its own; the cost would be to high. Why to high? Too much compiler magic or dmd internal dependences? Too much (language) change for too little gain; there are many, many much more important things that need to be fixed. Being able to have several user-defined kinds of arrays is a nice-to-have feature, but not one that determines whether the language is usable or not. [...] Hmm. I find D arrays just fine the way they are, actually. (In fact, I rather *liked* the way D arrays worked as compared with, say, C/C++.) What's wrong with them? T -- Famous last words: I *think* this will work...
Re: public alias to private template implementation
On Monday, 16 September 2013 at 21:00:21 UTC, monarch_dodra wrote: I'm trying to implement a set of public funtions, in terms of a template. Said template has no business being know to the user, so I want to mark it as private. Unfortunately, if I do this, then I can't use the alias, because Impl is private. Question 1: Is this the correct behavior? I'd have expected that if my alias is public, it would allow any one from outside to make the call correctly. Question 2: Is there a correct way to do this? I possible, I'd want to avoid nesting the template, eg: auto fun(){return Impl!int();} As that would: a) require more typing ^^ b) incur an extra function call in non-inline c) if at all possible, I actually need fun to be a template, so that it can be inlined. It makes sense to me, and seems like it would be analogous to returning a private member from a public method in structs or classes. However, since an alias rewritten to what it is aliased to (they completely disappear at compile time), I think your code would be equivalent to this: // module A; private template Impl(T) { void Impl(){} } // module B; //I'm assuming that main is supposed to be in a different module? import A; void main() { Impl!int(); } So you're really directly accessing a private symbol. Perhaps a workaround could be something like this: // module Test; static const fun = Impl!int; private template Impl(T) { void Impl(){} } // module main; import Test; void main() { fun(); } I had to do fun = Impl!int because the compiler complained about fun = Impl!int.
Re: User defined attributes use
On Monday, 16 September 2013 at 19:21:47 UTC, H. S. Teoh wrote: On Mon, Sep 16, 2013 at 08:56:17PM +0200, Namespace wrote: [...] I hate this NotNull struct hack. It is the same crap as the current scope solution. BTW: I'm curious which built-in feature will be removed next, maybe AA? [...] That wouldn't be a bad idea, actually. The current AA implementation is so horribly broken, and so wrong in so many ways (there are at least 75 bugs related to AA's, some of the worst of which are 11037, 11025, 10916, 10525, 10381, 10380, 10046, just to name a few), that it would do a world of good to get rid of them altogether, and then reintroduce a properly-designed library solution for them. Of course, in the meantime everyone whose code breaks because of that will form a mob to lynch me, so I'll have to survive long enough to get the library solution working first. :-P T This demonstrates an interesting issue. I think the primary reason why you are complaining about AAs is not because their implementation is flawed but because you can't fix it without dmd's internals knowledge :) I always consider ability to hack dmd as important skill (at least in better language understanding because it is not defined by standard but by reference implementation) in D and that's why I am skeptical about many ideas proposed in form of DIPs - (unless they are proposed by those folks whose names often appear in dmd git commit log) because such proposals are not implementable without dmd's knowledge. I remember one point made recently by one regular D forum participant that it is more important 'to know the language itself', 'to be abstract from one particular implementation' rather then knowing 'dirty implementation details' to propose DIPs and that those who know dmd will eventually implement DIPs - yet number of DIPs is close to 50 and judging by ratio implemented DIPs/total DIPs it obvious that such assumption doesn't hold. As a result community is stuck with many features of language are flawed but they can be hardly fixed - plenty discussions and DIPs are generated but problems are not moved by an inch. I think if a person who has druntime/phobos commits to fix some issue but no dmd's one should ask in a forum thread/directly address to Walter/Kenji for a help request (addressing Walter should happen without hesitation because he is the first to be blamed :) ).