Re: Everything on the Stack
scope/scoped isn't broken, they're just not safe. It's better to have an unsafe library feature than an unsafe language feature.
Compress spaces to one space
Is there a Phobos function to compress all spaces to just one space in a string? E.g. foo bar becomes: foo bar
Re: Everything on the Stack
On 02/21/2012 11:27 AM, Daniel Murphy wrote: scope/scoped isn't broken, they're just not safe. It's better to have an unsafe library feature than an unsafe language feature. scope is broken because it is not enforced by the means of flow-analysis. As a result, it is not safe. Copying it to the library and temporarily disabling 'scope' for classes is a good move however, because this means we will be able to fix it at an arbitrary point in the future without additional code breakage.
Re: Everything on the Stack
On 21/02/12 12:12, Timon Gehr wrote: On 02/21/2012 11:27 AM, Daniel Murphy wrote: scope/scoped isn't broken, they're just not safe. It's better to have an unsafe library feature than an unsafe language feature. scope is broken because it is not enforced by the means of flow-analysis. As a result, it is not safe. Copying it to the library and temporarily disabling 'scope' for classes is a good move however, because this means we will be able to fix it at an arbitrary point in the future without additional code breakage. Does the library solution actually work the same as the language solution?
Re: Compress spaces to one space
Andrej Mitrovic: Is there a Phobos function to compress all spaces to just one space in a string? E.g. foo bar becomes: foo bar import std.string; void main() { assert( foo bar .squeeze() == fo bar ); } Bye, bearophile
Re: Everything on the Stack
Don Clugston: Does the library solution actually work the same as the language solution? Some time ago scoped worked worse than the built-in scope: http://d.puremagic.com/issues/show_bug.cgi?id=5115 But I don't know how well scoped works now, I have never used it any more. Bye, bearophile
interface final members
interface I { final int foo(I other, int a, int b) { return other.foo(a,b) + a*b; } int foo(int a, int b); } class A : I { int foo(int a, int b) { return a*b; } } void main() { A a = new A; a.foo(5,5); a.I.foo(a, 5,5); a.foo(a, 5,5); //line 22 } - $ rdmd interface_final_test interface_final_test.d(22): Error: function interface_final_test.A.foo (int a, int b) is not callable using argument types (A,int,int) interface_final_test.d(22): Error: expected 2 arguments, not 3 for non-variadic function type int(int a, int b) - Why do I need to write a.I.foo instead of a.foo to call the final method of the interface ? Thank you, Joshua
Executable size when compiling with GDC
Hello everybody. Today I've tested GDC (on Windows), and a simple Hello World program results in a 5 MB exe file, while it's only about 200 KB with DMD. Is this normal? What does GDC (GCC?) put in there, to make it so big, and why? Mars
Re: interface final members
21.02.2012 14:46, Joshua Reusch пишет: interface I { final int foo(I other, int a, int b) { return other.foo(a,b) + a*b; } int foo(int a, int b); } class A : I { int foo(int a, int b) { return a*b; } } void main() { A a = new A; a.foo(5,5); a.I.foo(a, 5,5); a.foo(a, 5,5); //line 22 } - $ rdmd interface_final_test interface_final_test.d(22): Error: function interface_final_test.A.foo (int a, int b) is not callable using argument types (A,int,int) interface_final_test.d(22): Error: expected 2 arguments, not 3 for non-variadic function type int(int a, int b) - Why do I need to write a.I.foo instead of a.foo to call the final method of the interface ? Thank you, Joshua I can't comment on the behaviour, but you may find this workaround useful: class A : I { alias I.foo foo; int foo(int a, int b) { return a*b; } }
Re: Compress spaces to one space
Oh cool, it even takes an optional parameter. Thanks! On 2/21/12, bearophile bearophileh...@lycos.com wrote: Andrej Mitrovic: Is there a Phobos function to compress all spaces to just one space in a string? E.g. foo bar becomes: foo bar import std.string; void main() { assert( foo bar .squeeze() == fo bar ); } Bye, bearophile
Re: Executable size when compiling with GDC
Have you tried to strip executable using --strip or --strip-all? Il giorno mar, 21/02/2012 alle 13.51 +0100, Mars ha scritto: Hello everybody. Today I've tested GDC (on Windows), and a simple Hello World program results in a 5 MB exe file, while it's only about 200 KB with DMD. Is this normal? What does GDC (GCC?) put in there, to make it so big, and why? Mars
Naming methods from strings using mixin
Using a mixin, is it possible to have it define a method based on a string passed into the mixin? An example of what I'm hoping to do: mixin template make_method(string name) { void name() { // not sure how to make it become void bark() here writeln(hello); } } class Animal { mixin make_method!(bark); } Animal a; a.bark(); Any help would be appreciated. I'm hoping D can do this since it would make something I'm trying to do easier.
Examples of Windows services in D?
Hi folks, I've got a Windows service that I'd like to write in D, if possible. I see that Andrej Mitrovic has provided a binding for the relevant parts of the Windows API (thanks!): https://github.com/AndrejMitrovic/DWinProgramming/blob/master/win32/ winsvc.d Has anyone used this (or another binding) to write an actual service? Particularly, I was hoping to find a base class that takes care of common tasks (installing, removing, starting, etc.). Thanks! Graham
Re: Naming methods from strings using mixin
On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote: Using a mixin, is it possible to have it define a method based on a string passed into the mixin? Yeah, though you'll have to build a string of the method. Something like this: string make_method_string(string name) { string code = void ; // return type code ~= name; code ~= () {; // arglist code ~= q{ // body (q{ } is just another string literal but prettier for this imo writeln(hello); }; code ~= }; return code; } mixin template make_method(string name) { mixin(make_method_string(name)); // string mixin runs the above function at compile time, and then pastes the resulting code in here to be compiled } // and now to use it struct Test { mixin make_method(bark); } void main() { Test foo; foo.bark(); // works! } The string mixin and string builder helper function pattern can do pretty much anything you can think up, though it can get pretty ugly as it gets bigger just due to being strings.
delegate as memeber
struct stuff { private Exception delegate() exceptionBuilder = delegate Exception() { return new Exception(foobar); }; } The following piece of code trigger a compiler error : delegate module.stuff.__dgliteral1 function literals cannot be class members Why is that ? Is it a bug or a feature ?
Re: Naming methods from strings using mixin
On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote: Using a mixin, is it possible to have it define a method based on a string passed into the mixin? A simpler way: mixin template MakeMethod(string name) { void _MakeMethod_method() { /* ... */ } mixin(alias _MakeMethod_method ~ name ~ ;); }
Re: delegate as memeber
On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote: struct stuff { private Exception delegate() exceptionBuilder = delegate Exception() { return new Exception(foobar); }; } The following piece of code trigger a compiler error : delegate module.stuff.__dgliteral1 function literals cannot be class members Why is that ? Is it a bug or a feature ? Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal.
Re: Executable size when compiling with GDC
On Tuesday, 21 February 2012 at 13:19:11 UTC, Andrea Fontana wrote: Have you tried to strip executable using --strip or --strip-all? Down to 1 MB, a good start, thanks. I guess that's more bearable.
Re: delegate as memeber
Le 21/02/2012 16:32, Vladimir Panteleev a écrit : On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote: struct stuff { private Exception delegate() exceptionBuilder = delegate Exception() { return new Exception(foobar); }; } The following piece of code trigger a compiler error : delegate module.stuff.__dgliteral1 function literals cannot be class members Why is that ? Is it a bug or a feature ? Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal. It doesn't work with function either. But I need delegate here. The default one doesn't require a context, but isn't it possible to pass null as a context, as none is needed ? This value can be changer later, and definitively require to be a delegate.
Re: std.regex named matches
On 21.02.2012 7:34, James Miller wrote: On 20 February 2012 21:34, Dmitry Olshanskydmitry.o...@gmail.com wrote: 08.02.2012 13:07, James Miller пишет: Hi, I am using std.regex and using the named matches. I would like to be able to get at the names that have matched, since this is library code. e.g. auto m = match(test/2, regex(r(?Pword\w+)/(?Pnum\d))); //either auto names = m.names; //or auto names = m.captures.names; or something similar. I've looked at the library and I can't find anything of the sort, and you can't even use `foreach` to get at them that way, I'm guessing because you can have both integer and string indexes for the matches. I know this is two weeks old, but you can do foreach on them: foreach(c; m.captures){ //c is each captured group in turn, the first one is the whole match } Thanks James Miller Yeah, the problem with that is that I want the /names/ of the matches, that only returns the match. This was for library code, so the developer passes the regex. There are workarounds, but I would have liked to be able to do something more like auto names = m.captures.names; foreach (name; names) { writeln(name,: , m.captures[name]); } or even a straight AA-style foreach like this: foreach (name, match; m.captures) { writeln(name,: , match); } Names work as aliases for numbers, so that not every captured group has name. But something along the lines of : foreach(num, match; m.captures) writeln(m.nameOf(num),: ,match); where nameOf(x) should return mm.. empty string for groups with no name? it was decided that more data was needed in regex anyway, but there was no consensus as to how that should be implemented. Yes, more thought work needed. And being the guy behind current implementation, I'm curious what's your use case and how to best fit it in general API. -- Dmitry Olshansky
Re: delegate as memeber
A possible workaround is to initialize the delegate in the object's constructor.
Re: delegate as memeber
Le 21/02/2012 16:48, Adam D. Ruppe a écrit : A possible workaround is to initialize the delegate in the object's constructor. It is a struct. And struct don't have default constructor. It lead to very segfault prone code (I did try that).
Re: delegate as memeber
21.02.2012 17:24, deadalnix пишет: struct stuff { private Exception delegate() exceptionBuilder = delegate Exception() { return new Exception(foobar); }; } The following piece of code trigger a compiler error : delegate module.stuff.__dgliteral1 function literals cannot be class members Why is that ? Is it a bug or a feature ? The compiler expects member initializers to be known at compile-time. Since delegate carries closure, and closure is a run-time phenomena, you cannot put it there. That's how I understand it, and I might be wrong. Anyway, something like this is possible as a workaround: struct Foo { private Exception dg() { if( m_Dg ) return m_Dg(); return new Exception( foobar ); } private Exception delegate() m_Dg = null; }
Re: Examples of Windows services in D?
N, it wasn't me. I keep having to tell this to people, it was taken from http://www.dsource.org/projects/bindings/wiki/WindowsApi but it often doesn't compile with the latest compiler version so I keep it updated inside my project.
Re: Examples of Windows services in D?
On Tue, 21 Feb 2012 17:35:34 +0100, Andrej Mitrovic wrote: N, it wasn't me. I keep having to tell this to people, it was taken from http://www.dsource.org/projects/bindings/wiki/WindowsApi but it often doesn't compile with the latest compiler version so I keep it updated inside my project. Ah, sorry to spread misinformation, Andrej. :) Graham
Re: Compress spaces to one space
On 2/21/12, bearophile bearophileh...@lycos.com wrote: Andrej Mitrovic: Is there a Phobos function to compress all spaces to just one space in a string? E.g. foo bar becomes: foo bar import std.string; void main() { assert( foo bar .squeeze() == fo bar ); } Yikes! I didn't even notice it squeezes *all* duplicates. You see in my original code I just wanted extra spaces removed, not the chars themselves. So the right call is: squeeze( )
Re: Executable size when compiling with GDC
Lots of symbols and stuff. You can get it down with -ffunction-sections -fdata-sections -Wl,-s,--gc-sections Phobos should also be compiled with -ffunction-sections -fdata-sections to get the whole effect though.
Re: interface final members
On 2012-02-21 14:15, Mantis wrote: 21.02.2012 14:46, Joshua Reusch пишет: interface I { final int foo(I other, int a, int b) { return other.foo(a,b) + a*b; } int foo(int a, int b); } class A : I { int foo(int a, int b) { return a*b; } } void main() { A a = new A; a.foo(5,5); a.I.foo(a, 5,5); a.foo(a, 5,5); //line 22 } - $ rdmd interface_final_test interface_final_test.d(22): Error: function interface_final_test.A.foo (int a, int b) is not callable using argument types (A,int,int) interface_final_test.d(22): Error: expected 2 arguments, not 3 for non-variadic function type int(int a, int b) - Why do I need to write a.I.foo instead of a.foo to call the final method of the interface ? Thank you, Joshua I can't comment on the behaviour, but you may find this workaround useful: class A : I { alias I.foo foo; int foo(int a, int b) { return a*b; } } It's because the base class and the subclass use different overload sets, or something like that. -- /Jacob Carlborg
Re: delegate as memeber
On 2012-02-21 16:55, deadalnix wrote: Le 21/02/2012 16:48, Adam D. Ruppe a écrit : A possible workaround is to initialize the delegate in the object's constructor. It is a struct. And struct don't have default constructor. It lead to very segfault prone code (I did try that). You can implement a static opCall and use that instead of the constructor. -- /Jacob Carlborg
Re: Naming methods from strings using mixin
Awesome. Thanks! Adam D. Ruppe wrote: On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote: Using a mixin, is it possible to have it define a method based on a string passed into the mixin? Yeah, though you'll have to build a string of the method. Something like this: string make_method_string(string name) { string code = void ; // return type code ~= name; code ~= () {; // arglist code ~= q{ // body (q{ } is just another string literal but prettier for this imo writeln(hello); }; code ~= }; return code; } mixin template make_method(string name) { mixin(make_method_string(name)); // string mixin runs the above function at compile time, and then pastes the resulting code in here to be compiled } // and now to use it struct Test { mixin make_method(bark); } void main() { Test foo; foo.bark(); // works! } The string mixin and string builder helper function pattern can do pretty much anything you can think up, though it can get pretty ugly as it gets bigger just due to being strings.
Re: interface final members
On 02/21/2012 09:58 AM, Ali Çehreli wrote: The reason that I think so is that when the 'I other' is moved to a parameter location other than the first one, it works: No, it doesn't work. Sorry for the noise. Ali
Re: Naming methods from strings using mixin
Hello again, Both methods work as long as the object I call the mixin within is a struct struct Test { mixin MakeMethod!(bark); } If I switch struct to class class Test { mixin MakeMethod!(bark); } it segfaults. What am I missing? On Tuesday, 21 February 2012 at 15:29:49 UTC, Vladimir Panteleev wrote: On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote: Using a mixin, is it possible to have it define a method based on a string passed into the mixin? A simpler way: mixin template MakeMethod(string name) { void _MakeMethod_method() { /* ... */ } mixin(alias _MakeMethod_method ~ name ~ ;); }
Re: Naming methods from strings using mixin
On Tuesday, 21 February 2012 at 18:07:34 UTC, Robert Rouse wrote: What am I missing? Did you remember to new the class? class MyClass {} MyClass a; // a is null right now a = new MyClass(); // gotta remember this That's different than structs (or classes in C++) which work without being new'd.
Re: Naming methods from strings using mixin
I did not. Trying to new it gives me a compile error since MyClass a is not a pointer. If I define another method without mixin and call it before the mixin one, it works. On Tuesday, 21 February 2012 at 18:13:30 UTC, Adam D. Ruppe wrote: On Tuesday, 21 February 2012 at 18:07:34 UTC, Robert Rouse wrote: What am I missing? Did you remember to new the class? class MyClass {} MyClass a; // a is null right now a = new MyClass(); // gotta remember this That's different than structs (or classes in C++) which work without being new'd.
Re: Naming methods from strings using mixin
Nevermind.. I had it as struct playing around and didn't change it back On Tuesday, 21 February 2012 at 18:37:02 UTC, Robert Rouse wrote: I did not. Trying to new it gives me a compile error since MyClass a is not a pointer. If I define another method without mixin and call it before the mixin one, it works. On Tuesday, 21 February 2012 at 18:13:30 UTC, Adam D. Ruppe wrote: On Tuesday, 21 February 2012 at 18:07:34 UTC, Robert Rouse wrote: What am I missing? Did you remember to new the class? class MyClass {} MyClass a; // a is null right now a = new MyClass(); // gotta remember this That's different than structs (or classes in C++) which work without being new'd.
Re: Problems linking libdl?
On 02/20/2012 10:33 PM, simendsjo wrote: On Mon, 20 Feb 2012 22:26:58 +0100, Mike Wey mike-...@example.com wrote: On 02/20/2012 09:49 PM, simendsjo wrote: On Mon, 20 Feb 2012 21:41:45 +0100, simendsjo simend...@gmail.com wrote: I've tried the following using dmd 58 and trunk - both -m64 on kubuntu. Any idea what I'm doing wrong? import std.loader; void main(string[] args) { auto res = ExeModule_Init(); assert(res == 0); scope(exit) ExeModule_Uninit(); auto mod = ExeModule_Load(./libtcod.so); } $ dmd-trunk -v -L-ldl so.d gcc so.o -o so -m64 -ldl -Xlinker -L/home/simendsjo/code/dmd-trunk/build/lib64 -Xlinker -L/home/simendsjo/code/dmd-trunk/build/lib -Xlinker --no-warn-search-mismatch -Xlinker --export-dynamic -lphobos2 -lpthread -lm -lrt I get the same error using gdc-4.6 The problem is that -ldl should appear after -lphobos2 in the arguments passed to gcc. Ok, that removed the error (although I got another). But how can I specify this when I run dmd or gdc? dmd and gdc adds -L options before phobos... The last time this problem came up in the newsgroup, with librt, it was moved from the configuration file into the compiler, so now it's hardcoded. You could try passing -L--start-group before -L-ldl it should cause ld to recursively search for the symbols. Unfortunately i can't test this on my system. -- Mike Wey
mixin template FAIL
I decided to try using template mixin, but even the simplest program fails. What's wrong with this code? Error list follows. DMD64 D Compiler v2.057 OSX 10.6 import std.stdio; mixin template helpMe() { writeln(Satisfying!); } void main() { mixin helpMe(); } test.d(5): unexpected ( in declarator test.d(5): basic type expected, not Satisfying! test.d(5): found 'Satisfying!' when expecting ')' test.d(5): no identifier for declarator writeln(int) test.d(5): semicolon expected following function declaration test.d(5): Declaration expected, not ')' test.d(10): ';' expected after mixin test.d(10): found ')' instead of statement
Re: delegate as memeber
Le 21/02/2012 17:30, Mantis a écrit : 21.02.2012 17:24, deadalnix пишет: struct stuff { private Exception delegate() exceptionBuilder = delegate Exception() { return new Exception(foobar); }; } The following piece of code trigger a compiler error : delegate module.stuff.__dgliteral1 function literals cannot be class members Why is that ? Is it a bug or a feature ? The compiler expects member initializers to be known at compile-time. Since delegate carries closure, and closure is a run-time phenomena, you cannot put it there. That's how I understand it, and I might be wrong. Anyway, something like this is possible as a workaround: struct Foo { private Exception dg() { if( m_Dg ) return m_Dg(); return new Exception( foobar ); } private Exception delegate() m_Dg = null; } I think this the best solution after all. But still I think the original code should be an error only if it use data out of the delegate scope. If it doesn't, frame pointer doesn't matter and null can be passed.
Mixins: Using the type name to generate a method name
Piggy backing on my other question. I want to be able to make the name of the method optional in the argument list. If it doesn't exist, it should get the type name of the passed in type and lower case it and use it instead. I tried the following import std.stdio, std.string; mixin template make_method(T, string name = null) { void _method() { writeln(I am a banana); } static if(name) { mixin(alias _method ~ name ~ ; ); } else { mixin(alias _method ~ toLower(typeid(T)) ~ ; ); } } class Test { mixin make_method!(Test); } void main(string[] args) { Test test; test = new Test(); test.test(); } The compiler throws mixtest.d(14): Error: template std.string.toLower(S) if (isSomeString!(S)) does not match any function template declaration mixtest.d(14): Error: template std.string.toLower(S) if (isSomeString!(S)) cannot deduce template function from argument types !()(TypeInfo_Class) mixtest.d(14): Error: argument to mixin must be a string, not (alias _method ~ (__error) ~ ;) mixtest.d(26): Error: mixin mixtest.Test.make_method!(Test) error instantiating Am I just SOL on this one and I have to pass the name all the time or is there a way to make this work? Thanks
Re: Mixins: Using the type name to generate a method name
On Tuesday, 21 February 2012 at 19:42:42 UTC, Robert Rouse wrote: mixin(alias _method ~ toLower(typeid(T)) ~ ; ); Try using T.stringof instead of typeid(T). typeid does a runtime lookup. T.stringof does magic to get a string representation of the thing at compile time. Since, in the template, T here is a type, you get a string of that type. .stringof is a bit of magic that can work in a lot of places. last time I checked though, it is pretty poorly documented, so might take some guess and check to make it work for you.
Re: Mixins: Using the type name to generate a method name
21.02.2012 21:42, Robert Rouse пишет: ... mixin(alias _method ~ toLower(typeid(T)) ~ ; ); ... Try typeid(T).toString(); or typeof(T).stringof; typeid does not return a string type.
Re: mixin template FAIL
On 02/21/2012 10:47 AM, Zach the Mystic wrote: I decided to try using template mixin, but even the simplest program fails. What's wrong with this code? Error list follows. DMD64 D Compiler v2.057 OSX 10.6 import std.stdio; mixin template helpMe() { writeln(Satisfying!); } void main() { mixin helpMe(); } test.d(5): unexpected ( in declarator test.d(5): basic type expected, not Satisfying! test.d(5): found 'Satisfying!' when expecting ')' test.d(5): no identifier for declarator writeln(int) test.d(5): semicolon expected following function declaration test.d(5): Declaration expected, not ')' test.d(10): ';' expected after mixin test.d(10): found ')' instead of statement According to the docs, template mixins can have only declarations but helpMe above has a statement. http://dlang.org/template-mixin.html Ali
Re: Mixins: Using the type name to generate a method name
stringof did it. I'm still reading through the D programming book, so I guess I hadn't gotten there yet. I did a search in the book and found a reference. I'll read more. Thanks :) On Tuesday, 21 February 2012 at 19:48:18 UTC, Adam D. Ruppe wrote: On Tuesday, 21 February 2012 at 19:42:42 UTC, Robert Rouse wrote: mixin(alias _method ~ toLower(typeid(T)) ~ ; ); Try using T.stringof instead of typeid(T). typeid does a runtime lookup. T.stringof does magic to get a string representation of the thing at compile time. Since, in the template, T here is a type, you get a string of that type. .stringof is a bit of magic that can work in a lot of places. last time I checked though, it is pretty poorly documented, so might take some guess and check to make it work for you.
Re: delegate as memeber
On Tue, Feb 21, 2012 at 08:01:18PM +0100, deadalnix wrote: [...] But still I think the original code should be an error only if it use data out of the delegate scope. If it doesn't, frame pointer doesn't matter and null can be passed. You could file an enhancement request, if one hasn't already been filed. T -- I'm still trying to find a pun for punishment...
Re: mixin template FAIL
On 2012-02-21 20:53, Ali Çehreli wrote: On 02/21/2012 10:47 AM, Zach the Mystic wrote: I decided to try using template mixin, but even the simplest program fails. What's wrong with this code? Error list follows. DMD64 D Compiler v2.057 OSX 10.6 import std.stdio; mixin template helpMe() { writeln(Satisfying!); } void main() { mixin helpMe(); } test.d(5): unexpected ( in declarator test.d(5): basic type expected, not Satisfying! test.d(5): found 'Satisfying!' when expecting ')' test.d(5): no identifier for declarator writeln(int) test.d(5): semicolon expected following function declaration test.d(5): Declaration expected, not ')' test.d(10): ';' expected after mixin test.d(10): found ')' instead of statement According to the docs, template mixins can have only declarations but helpMe above has a statement. http://dlang.org/template-mixin.html Ali And the correct syntax for mixing in the template would be: mixin helpMe!(); Or mixin helpMe; // works if the template doesn't take any arguments -- /Jacob Carlborg
Re: mixin template FAIL
On 02/21/2012 01:53 PM, Ali Çehreli wrote: According to the docs, template mixins can have only declarations but helpMe above has a statement. http://dlang.org/template-mixin.html Ali come to think of it, I've occasionally wished for statement mixins. This would make a good enhancement request.
Re: Template Inheritance
That last one looks a lot better than my solution. It's certainly a lot clearer. One problem I discovered with using templates was that I ended up needing virtual functions, which means that I had to convert the template functions to mixins and just instantiate them for each type (at least there were only two types to handle!) in the base class. The problem I've got now is that if I create versions of get() that take different types in subclasses, I lose access to the superclass's overload set. If I try to use alias Base.get get, DMD complains that the alias and the functions conflict. It looks like I can override existing overloads but not create new ones. I guess I might have to put a hold on the project until the language gets modified (assuming that actually happens). How would I go about filing an enhancement request?
Avoiding const?
I apologize for what I'm sure is a very basic question. How should I do this elegantly? bool set[char[]]; //Stuff char[][] words = set.keys; It gives the error: Error: cannot implicitly convert expression (set.keys()) of type const(char)[][] to char[][] and I'm not sure why I can't copy const data to normal data.
Re: std.regex named matches
On 22 February 2012 04:45, Dmitry Olshansky dmitry.o...@gmail.com wrote: On 21.02.2012 7:34, James Miller wrote: On 20 February 2012 21:34, Dmitry Olshanskydmitry.o...@gmail.com wrote: 08.02.2012 13:07, James Miller пишет: Hi, I am using std.regex and using the named matches. I would like to be able to get at the names that have matched, since this is library code. e.g. auto m = match(test/2, regex(r(?Pword\w+)/(?Pnum\d))); //either auto names = m.names; //or auto names = m.captures.names; or something similar. I've looked at the library and I can't find anything of the sort, and you can't even use `foreach` to get at them that way, I'm guessing because you can have both integer and string indexes for the matches. I know this is two weeks old, but you can do foreach on them: foreach(c; m.captures){ //c is each captured group in turn, the first one is the whole match } Thanks James Miller Yeah, the problem with that is that I want the /names/ of the matches, that only returns the match. This was for library code, so the developer passes the regex. There are workarounds, but I would have liked to be able to do something more like auto names = m.captures.names; foreach (name; names) { writeln(name,: , m.captures[name]); } or even a straight AA-style foreach like this: foreach (name, match; m.captures) { writeln(name,: , match); } Names work as aliases for numbers, so that not every captured group has name. But something along the lines of : foreach(num, match; m.captures) writeln(m.nameOf(num),: ,match); where nameOf(x) should return mm.. empty string for groups with no name? it was decided that more data was needed in regex anyway, but there was no consensus as to how that should be implemented. Yes, more thought work needed. And being the guy behind current implementation, I'm curious what's your use case and how to best fit it in general API. -- Dmitry Olshansky Ah, right, nameOf would work ok. I know that the issue stems from there not really being a best-solution in this case because of the fact that you can have named /and/ unnamed matches. I don't /require/ it, it just would make my life easier. My use case, expanding on what I said before, is that I want to be able to present debugging information, being able to enumerate the names in the match goes a long way to that. Also it means I can do more flexible dispatching of data, otherwise I need hardcoded rules for the names, which is unfortunate. Like I said, nothing wrong with what is there, I just think that it can be improved. nameOf would work well, if it returns null, or empty string, then there is no name for that match. Since you can already grab specific names out of the regex anyway, this just fills in the gap in the other direction, going from match to name, rather than name to match. Thanks -- James Miller
Re: Avoiding const?
If you have a const array, you can create a non-const copy of the array using the .dup property of the array. The reason that you need this is that dynamic-length arrays share data when you assign them between variables, and you can't have a non-const variable using something else's const data without running into some really nasty problems. In your specific case, though, the .dup property might not convert the inner levels of the nested array. If it doesn't work, you could try something like this: char[][] words; words.length = set.keys.length; foreach(size_t i, const char[] text; set.keys) { words[i] = text.dup; } If you don't really need to modify the individual characters in the array, you might just want to stick with const; it will be more efficient. You might also want to define the set as bool[string] because associative arrays prefer const/immutable keys for some reason.
Re: Avoiding const?
BLM: const(char)[][] words = set.keys.sort; Converting the function's return type to const and doing this did what I wanted elegantly, I didn't realise I could apply sort to a const like this. Trying to use .dup like this: char[][] words = set.keys.dup; gives this error message: Error: cannot implicitly convert expression (_adSort(_adDupT( D13TypeInfo_AAxa6__initZ,set.keys()), D11TypeInfo_Aa6__initZ)) of type const(char)[][] to char[][] Isn't there any sort of cast(nonconst) equivalent? char[][] words; words.length = set.keys.length; foreach(size_t i, const char[] text; set.keys) { words[i] = text.dup; } This also worked, thank you for the suggestion. Jonathan M Davies: bool[char[]] set; doesn't work, because the key isn't immutable. When he tries to use it the compiler will scream at him (though ideally, it wouldn't even let him declare it - there's a bug report on that). When I use a key with it I use: set[cast(immutable) key] = true; This doesn't generate any compiler errors. auto words2 = set.keys.sort; auto words2 = set.keys.dup.sort; both did what I wanted using string. Thank you, I'll convert everything to strings. I guess I created my own difficulties by using char arrays.
Adding overloaded methods
I'm working on a project where I'm using overloaded virtual methods, and I've run into a challenge with overload sets. My code looks something like this: class Base { void get(ubyte b) {}; } class Derived: Base { //alias Base.get get; void get(string s) {}; } I've tried using an alias declaration to combine the two classes' overload sets in the derived class, but DMD complains that the alias conflicts with get(string). Is there some reasonably elegant way around this, or is it a limitation of the language?
Re: Avoiding const?
On Wednesday, February 22, 2012 03:07:38 ixid wrote: BLM: const(char)[][] words = set.keys.sort; Converting the function's return type to const and doing this did what I wanted elegantly, I didn't realise I could apply sort to a const like this. Trying to use .dup like this: char[][] words = set.keys.dup; gives this error message: Error: cannot implicitly convert expression (_adSort(_adDupT( D13TypeInfo_AAxa6__initZ,set.keys()), D11TypeInfo_Aa6__initZ)) of type const(char)[][] to char[][] Isn't there any sort of cast(nonconst) equivalent? 1. Don't use the built-in sort. It's going to be deprecated. Use std.algorithm.sort. 2. You should pretty much _never_ cast away const or immutable in D unless you really know what you're doing. Casting away const or immutable and then modifying a variable is undefined (unlike in C++). It violates the compiler's guarantees and risks segfaulting and the like. char[][] words; words.length = set.keys.length; foreach(size_t i, const char[] text; set.keys) { words[i] = text.dup; } This also worked, thank you for the suggestion. Jonathan M Davies: bool[char[]] set; doesn't work, because the key isn't immutable. When he tries to use it the compiler will scream at him (though ideally, it wouldn't even let him declare it - there's a bug report on that). When I use a key with it I use: set[cast(immutable) key] = true; This doesn't generate any compiler errors. auto words2 = set.keys.sort; auto words2 = set.keys.dup.sort; _Don't_ cast to immutable unless you can _guarantee_ that there are no other references to the variable being cast. You're going to get bugs otherwise. In general, if you're doing any casts to or from const or immutable, you're doing something wrong (there are exceptions - primarily involving passing stuff across threads - but again, you have to know what you're doing). If the key is not already immutable (or has immutable elements in the case of an array), then you need to actually get an immutable version, not cast it. In the case of an array, that would mean using idup. However, even better would be to use std.conv.to. That way, if the array or its elements are already immutable, you don't end up needlessly copying the array. For instance, bool[string] set; set[to!string(key)] = value; both did what I wanted using string. Thank you, I'll convert everything to strings. I guess I created my own difficulties by using char arrays. Yes. In general, you should be using string (which is immutable(char)[]) rather than char[]. In general, modifying an array of char just doesn't make sense (particularly in light of unicode), and you'll generally run into fewer difficulties. It also helps avoid duplication, because you never need to copy arrays of immutable elements unless you need a mutable copy, whereas you tend to have to copy arrays of mutable elements to avoid having stuff modify them. Also, more functions in the standard library support string than char[]. This question on stackoverflow would be good to look at for a more detailed explanation with regards to AAs and immutability: http://stackoverflow.com/questions/4611477/why-cant-i-store-string-keys-in-an- associative-array Also, if you haven't read it yet, you should read this article on arrays: http://www.dsource.org/projects/dcollections/wiki/ArrayArticle It should help you understand how they work, which will hopefully help you avoid some headaches. - Jonathan M Davis
Re: Adding overloaded methods
On Wednesday, February 22, 2012 02:21:43 BLM wrote: I'm working on a project where I'm using overloaded virtual methods, and I've run into a challenge with overload sets. My code looks something like this: class Base { void get(ubyte b) {}; } class Derived: Base { //alias Base.get get; void get(string s) {}; } I've tried using an alias declaration to combine the two classes' overload sets in the derived class, but DMD complains that the alias conflicts with get(string). Is there some reasonably elegant way around this, or is it a limitation of the language? Hmm. That's how you're _supposed_ to do it. Sounds like a bug. http://dlang.org/function.html It may be related to the fact that you don't have override on the derived class's get though. You're really supposed to, but it hasn't been promoted to an error yet (it's enabled with -w until it is). Try that and see if it fixes it. - Jonathan M Davis
Re: Adding overloaded methods
I tried using override and it complained that the functions weren't overriding anything. I think that the main problem is that the alias solution was designed to allow derived classes to use overloads that had already been defined in the base class, not for the derived classes to add _new_ overloads. This might be good material for an enhancement request.
Re: delegate as memeber
On Tuesday, 21 February 2012 at 15:41:58 UTC, deadalnix wrote: Le 21/02/2012 16:32, Vladimir Panteleev a écrit : On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote: struct stuff { private Exception delegate() exceptionBuilder = delegate Exception() { return new Exception(foobar); }; } The following piece of code trigger a compiler error : delegate module.stuff.__dgliteral1 function literals cannot be class members Why is that ? Is it a bug or a feature ? Delegates contain a context pointer. Your delegate literal has no context. You can't initialize it with the address of a method, either. For struct methods, the context pointer is a pointer to the structure. You can't have a .init that contains a pointer to an instance. You probably want to use a function literal. It doesn't work with function either. But I need delegate here. The default one doesn't require a context, but isn't it possible to pass null as a context, as none is needed ? This value can be changer later, and definitively require to be a delegate. struct stuff { private Exception function() exceptionBuilder = defaultExceptionBuilder; private static Exception defaultExceptionBuilder() { return new Exception(foobar); }; }
Re: Adding overloaded methods
On Wednesday, February 22, 2012 02:50:41 BLM wrote: I tried using override and it complained that the functions weren't overriding anything. I think that the main problem is that the alias solution was designed to allow derived classes to use overloads that had already been defined in the base class, not for the derived classes to add _new_ overloads. This might be good material for an enhancement request. I'd advise reporting it as a bug rather than an enhancement request. The whole point of using the alias is to bring all of the base class' overloads into the derived class' overload set. It shouldn't matter whether the derived class is adding overloads or just overriding a subset of the base class' overloads. If the compiler devs really think that it's an enhancement request, then they can change it, but it definitely looks like a bug to me. - Jonathan M Davis
Re: Adding overloaded methods
On 02/21/2012 06:21 PM, BLM wrote: I'm working on a project where I'm using overloaded virtual methods, and I've run into a challenge with overload sets. My code looks something like this: class Base { void get(ubyte b) {}; } class Derived: Base { //alias Base.get get; void get(string s) {}; } I've tried using an alias declaration to combine the two classes' overload sets in the derived class, but DMD complains that the alias conflicts with get(string). Is there some reasonably elegant way around this, or is it a limitation of the language? Your code actually works with dmd 2.058: import std.stdio; class Base { void get(ubyte b) { writeln(get(ubyte)); } } class Derived: Base { alias Base.get get; void get(string s) { writeln(get(string)); } } void main() { ubyte b; string s; auto o = new Derived(); o.get(b); o.get(s); } Outputs: get(ubyte) get(string) I have also corrected the indentation ;) and two extraneous semicolons. Ali
Re: Adding overloaded methods
I've submitted it to the DMD developers. Hopefully it won't take too long to get fixed; it looks like it would be a _fairly_ simple fix to make. (Since when is a compiler fix simple?)
Re: Avoiding const?
Thank you, I'll read those articles. Is there a more elegant way than this to get the string[] out of a range after using the algorithms sort? Ranges are a bit of a mystery. string[] temp; foreach(i;sort(set.keys)) temp ~= to!string(i); I'm a little worried that the very basic level of my posts is spamming the forum, is there a D community forum for absolute beginners?
inout problems
class Foo { this(int) inout { } Foo makeFoo() { return new Foo(1); } } void main() { } test.d(8): Error: cannot implicitly convert expression (new Foo(1)) of type inout(Foo) to test.Foo Is this a bug?
Re: Adding overloaded methods
Hmm... I guess I'll have to figure out why my code is behaving differently and put a test case together. Strange... Thanks for fixing the semicolons. Old C++ habits die hard, even if one has written very little C++ :)
Re: Avoiding const?
On Wednesday, February 22, 2012 04:42:05 ixid wrote: Thank you, I'll read those articles. Is there a more elegant way than this to get the string[] out of a range after using the algorithms sort? Ranges are a bit of a mystery. string[] temp; foreach(i;sort(set.keys)) temp ~= to!string(i); Sort returns a SortedRange, so if you passed it to a function which could take advantage of that (such as find), it would be more efficient to use the result of sort, but sort sorts in place. So, if you want a new array, what you should probably do is simply auto temp = set.keys.dup; sort(temp); However, I think that .keys returns a newly allocated array such that you don't need to dup it at all if you don't want to, which means that you'd do something more like auto temp = set.keys; sort(temp); I'm a little worried that the very basic level of my posts is spamming the forum, is there a D community forum for absolute beginners? This pretty much _is_ the forum for absolute beginners. The whole point of this forum is to answer questions for those learning D. It's digitalmars.D which is for general discussion on D. You're in the right place. - Jonathan M Davis
Re: inout problems
On 22 February 2012 17:01, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: class Foo { this(int) inout { } Foo makeFoo() { return new Foo(1); } } void main() { } test.d(8): Error: cannot implicitly convert expression (new Foo(1)) of type inout(Foo) to test.Foo Is this a bug? I have no idea if it is a bug or not, but can I ask why you're inout-ing the constructor? Seems odd to me thats all.
Re: Avoiding const?
On 02/21/2012 07:42 PM, ixid wrote: Ranges are a bit of a mystery. May I shamelessly recommend the Ranges chapter of my about-30%-translated book: http://ddili.org/ders/d.en/ranges.html I'm a little worried that the very basic level of my posts is spamming the forum Not at all! We are all learning from all sorts of questions and answers here. :) Ali
Re: inout problems
Hmm nevermind. The param type had to be inout, but to do that the ctor itself has to be inout. Somehow I managed to put the inout specifier in the wrong place when testing, I did this: this(inout(void*) obj) { } inout which is not the same as this: this(inout(void*) obj) inout { } Damn specs. Anyway it's working ok now.
Re: Adding overloaded methods
On 2012-02-22 03:39, Jonathan M Davis wrote: On Wednesday, February 22, 2012 02:21:43 BLM wrote: I'm working on a project where I'm using overloaded virtual methods, and I've run into a challenge with overload sets. My code looks something like this: class Base { void get(ubyte b) {}; } class Derived: Base { //alias Base.get get; void get(string s) {}; } I've tried using an alias declaration to combine the two classes' overload sets in the derived class, but DMD complains that the alias conflicts with get(string). Is there some reasonably elegant way around this, or is it a limitation of the language? Hmm. That's how you're _supposed_ to do it. Sounds like a bug. http://dlang.org/function.html It may be related to the fact that you don't have override on the derived class's get though. You're really supposed to, but it hasn't been promoted to an error yet (it's enabled with -w until it is). Try that and see if it fixes it. - Jonathan M Davis He is overloading, not overriding. You have to start notice the difference when reading these posts :) -- /Jacob Carlborg
Re: Adding overloaded methods
On Wednesday, February 22, 2012 08:19:09 Jacob Carlborg wrote: He is overloading, not overriding. You have to start notice the difference when reading these posts :) Well, it's both. He's overriding a base class function with a different signature. So, depending on how the compiler treats that, it could be considered either both an override and an overload or just an overload. And apparently the override attribute only applies to exact overloads. - Jonathan M Davis