Re: i18n
xancorreu xancor...@gmail.com wrote: Hi, Is there any way for localizate and internationalizate messages? I were shocked if D has something like Fantom [http://fantom.org/doc/docLang/Localization.html]. Gettext is pretty ugly ;-) I use small D script to internationalize Delphi projects. It's not perfect, but it's simple and easy to modify for one's needs. https://gist.github.com/1728860
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/03/12 00:20, Jonathan M Davis wrote: in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. It's particularly problematic with arrays, since it's frequently desirable to return slices of them, and scope (and therefore in) would prevent that. It's useful in some instances (particularly with delegates), but I'd use in _very_ sparingly. It's almost always more trouble than it's worth IMHO. BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. If it isn't obvious why - GC. The compiler can optimize the cases where it knows a newly allocated object can't escape and reduce or omit the GC overhead. And yes, it can also do this automatically - but that requires analyzing the whole call chain, which is a) not always possible and b) much more expensive. artur
Re: Segment violation (was Re: Why I could not cast string to int?)
On 03-02-2012 11:08, Artur Skawina wrote: On 02/03/12 00:20, Jonathan M Davis wrote: in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. It's particularly problematic with arrays, since it's frequently desirable to return slices of them, and scope (and therefore in) would prevent that. It's useful in some instances (particularly with delegates), but I'd use in _very_ sparingly. It's almost always more trouble than it's worth IMHO. BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. If it isn't obvious why - GC. The compiler can optimize the cases where it knows a newly allocated object can't escape and reduce or omit the GC overhead. And yes, it can also do this automatically - but that requires analyzing the whole call chain, which is a) not always possible and b) much more expensive. artur It is not that simple. If the class's constructor passes 'this' off to some arbitrary code, this optimization breaks completely. You would need whole-program analysis to have the slightest hope of doing this optimization correctly. -- - Alex
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/03/12 11:41, Artur Skawina wrote: On 02/03/12 11:21, Alex Rønne Petersen wrote: On 03-02-2012 11:08, Artur Skawina wrote: On 02/03/12 00:20, Jonathan M Davis wrote: in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. It's particularly problematic with arrays, since it's frequently desirable to return slices of them, and scope (and therefore in) would prevent that. It's useful in some instances (particularly with delegates), but I'd use in _very_ sparingly. It's almost always more trouble than it's worth IMHO. BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. If it isn't obvious why - GC. The compiler can optimize the cases where it knows a newly allocated object can't escape and reduce or omit the GC overhead. And yes, it can also do this automatically - but that requires analyzing the whole call chain, which is a) not always possible and b) much more expensive. artur It is not that simple. If the class's constructor passes 'this' off to some arbitrary code, this optimization breaks completely. You would need whole-program analysis to have the slightest hope of doing this optimization correctly. It's about enabling the optimization for as much code as possible. And probably the most interesting cases are strings/arrays - the GC overhead can be huge if you do a lot of concatenation etc. Would marking the ctor as scope (similarly to const or pure) work for your case? (it is reasonable to expect that the compiler checks this by itself; it's per-type, so not nearly as expensive as analyzing the flow) Actually, passing 'this' to some some arbitrary code isn't a problem, unless the code in question has the esc annotation, in which case you need to mark the ctor (or any other method) as esq too; that will turn off the optimization, for this struct/class, obviously. That's why scope needs to be the default - mixing it with code that does not guarantee that the object does not escape does not really work - you cannot call anything not marked with scope with an already scoped object. Which means you need to mark practically every function argument as scope - this doesn't scale well. artur
why have protection attributes on/in interfaces abstract classes/methods no effect ouside a module?
why have protection attributes on/in interfaces and abstract classes/methods no effect outside a module? module types; private interface itest { private static void blub(); public void blub2(); private void blub3(); } private class test { protected abstract void blub4(); public abstract void blub5(); } --- module classes; import types; class A: itest { public static void blub(){} public void blub2(){} public void blub3(){} } class B: test { protected override void blub4(){} public override void blub5(){} } class C: test { public override void blub4(){} public override void blub5(){} } why is it allowed to use them in interface and abstract - and even check if there are no redundency like private private or something
Re: Segment violation (was Re: Why I could not cast string to int?)
On 03-02-2012 11:41, Artur Skawina wrote: On 02/03/12 11:21, Alex Rønne Petersen wrote: On 03-02-2012 11:08, Artur Skawina wrote: On 02/03/12 00:20, Jonathan M Davis wrote: in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. It's particularly problematic with arrays, since it's frequently desirable to return slices of them, and scope (and therefore in) would prevent that. It's useful in some instances (particularly with delegates), but I'd use in _very_ sparingly. It's almost always more trouble than it's worth IMHO. BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. If it isn't obvious why - GC. The compiler can optimize the cases where it knows a newly allocated object can't escape and reduce or omit the GC overhead. And yes, it can also do this automatically - but that requires analyzing the whole call chain, which is a) not always possible and b) much more expensive. artur It is not that simple. If the class's constructor passes 'this' off to some arbitrary code, this optimization breaks completely. You would need whole-program analysis to have the slightest hope of doing this optimization correctly. It's about enabling the optimization for as much code as possible. And probably the most interesting cases are strings/arrays - the GC overhead can be huge if you do a lot of concatenation etc. Would marking the ctor as scope (similarly to const or pure) work for your case? (it is reasonable to expect that the compiler checks this by itself; it's per-type, so not nearly as expensive as analyzing the flow) artur Well, you would have to mark methods as scope too, as they could be passing off 'this' as well. It's probably doable that way, but explicit annotations kind of suck. :( -- - Alex
Re: RPC module for D ?
I think that It not would show D awesomeness. The code of D thrift serverclient looks more long and complex that Python, Perl and Ruby examples with xml-rpc ... Why not are something more simple ? I think that D allow to something in the line of these xml-rpc implementations in Python or Ruby. El Mon, 30 Jan 2012 19:51:05 +, Zardoz escribió: I will try it. I only need to make a remote hello world , do a short description , and compare with other RPCs in other 3 languages (university homework...) . On Mon, 30 Jan 2012 17:30:59 +0100, David Nadlinger wrote: On 1/30/12 5:27 PM, luis wrote: There are any RPC module for D ?? I implemented support for Apache Thrift during last summer's GSoC, it's currently under review for inclusion into Thrift trunk: http://klickverbot.at/code/gsoc/thrift/ David
Re: Segment violation (was Re: Why I could not cast string to int?)
On Friday, February 03, 2012 11:08:54 Artur Skawina wrote: BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. That would destroy slicing. I'm firmly of the opinion that scope should be used sparingly. - Jonathan M Davis
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/03/12 13:06, Jonathan M Davis wrote: On Friday, February 03, 2012 11:08:54 Artur Skawina wrote: BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. That would destroy slicing. I'm firmly of the opinion that scope should be used sparingly. Well, not doing it destroys performance. [1] It's a trade-off. Also, i don't know if destroy slicing is accurate. Things like 'string f(string s) { return s[1..$]; }' needs to continue to work; the object does not really escape from the POV of f(), but the caller has to assume it's not dead after returning from the function. Doing this by default for any functions returning refs that could potentially hold on to the passed object would make things work. For the cases that where the called function knows that it will always return unique objects the signature could look like 'new string f(string s);', but that's only an optimization. Any other problematic slicing use, that i'm not thinking of right now? artur [1] I had a case, where turning on logging in some code made the program unusable, because instead of IIRC ~40s it took 40+ minutes, at which point i gave up and killed it... The profile looked like this: 37.62% uint gc.gcx.Gcx.fullcollect(void*) 20.47% uint gc.gcbits.GCBits.test(uint) 13.80% uint gc.gcbits.GCBits.testSet(uint) 10.15% pure nothrow @safe bool std.uni.isGraphical(dchar) 3.33% _D3std5array17__T8AppenderTAyaZ8Appender10__T3putTwZ3putMF 2.78% 0x11025a 2.13% _D3std6format65__T13formatElementTS3std5array17__T8Appende 1.64% _D3std6format56__T10formatCharTS3std5array17__T8AppenderTA 1.37% pure @safe uint std.utf.encode(ref char[4], dchar) 0.88% void* gc.gcx.GC.malloc(uint, uint, uint*) 0.50% pure nothrow @safe bool std.uni.binarySearch2(dchar, immutable(dchar[2][])) 0.45% void gc.gcbits.GCBits.set(uint) 0.37% void gc.gcbits.GCBits.clear(uint) 0.34% __divdi3 That shows several problems, but even after fixing the obvious ones (inlining GCBits, making std.uni.isGraphical sane (this, btw, reduced its cost to ~1%)) GC still takes up most of time (not remembering the details, but certainly 50%, it could have been 80%). Some slowdown from the IO and formatting is expected, but spending most cycles on GC is not reasonable, when most objects never leave the scope (in this case it was just strings passed to writeln etc IIRC).
Re: Segment violation (was Re: Why I could not cast string to int?)
Jonathan M Davis: in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Having const value types is useful because you can't change them later inside the method. This helps you avoid bugs like: void foo(int n) { // uses n here // modifies n here by mistake // uses n here again, assuming it's the 'real' n argument } When you program you think of arguments as the inputs of your algorithm, so if you mutate them by mistake, this sometimes causes bugs if later you think they are the real inputs of your algorithm still. Generally in D code all variables that can be const/immutable should be const/immutable, unless this causes problems or is impossible or it causes signficant performance troubles. This avoids some bugs, helps DMD optimize better (I have seen this), and helps the person that reads the code to understand the code better (because he/she/shi is free to focus on just the mutable variables). It's better to have const function arguments, unless this is not possible, or for not common situations where a mutable input helps you optimize your algorithm better (especially if the profiler has told you so). Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. Think of returning a part of a mutable input argument as an optimization, to be used when you know you need the extra speed. Otherwise where performance is not a problem it's often safer to return a const value or to return something new created inside the function/method. This programming style avoids many mistakes (it's useful in Java coding too). From what I've seen, in my D code only a small percentage of the program lines need to be optimized and use C-style coding. For most of the lines of code a more functional D style is enough, and safer. The idea is mutability where needed, and a bit more functional-style everywhere else :-) Bye, bearophile
Re: Segment violation (was Re: Why I could not cast string to int?)
Artur Skawina: Would marking the ctor as scope (similarly to const or pure) work for your case? (it is reasonable to expect that the compiler checks this by itself; it's per-type, so not nearly as expensive as analyzing the flow) Maybe this is a topic worth discussing in the main D newsgroup (and maybe later worth an enhancement request). Bye, bearophile
Re: Why I could not cast string to int?
Al 02/02/12 20:11, En/na Ali Çehreli ha escrit: On 02/02/2012 11:00 AM, xancorreu wrote: Al 02/02/12 19:18, En/na bearophile ha escrit: Can I say serialize the first, second and third arguments as Class Person? I mean, if you define a class Person like: class Person { string name uint age dead bool } could you serialize the input from console, like Std.in.serialize(Person, args(0), args(1), args(2))? I haven't used it but there is Orange: https://github.com/jacob-carlborg/orange I think it will be included in Phobos. You could do that manually checking each paramm, but it's a tedious task. If the input is exactly in the format that a library like Orange expects, then it's easy. To me, constructing an object from user input is conceptually outside of OO, because there is no object at that point yet. It makes sense to me to read the input and then make an object from the input. For my it could be put in a outside library, not in the class of the object. And if it's well designed, it could be informed of all exceptions Depending on the design, the input may be rejected by the function that reads the input, by the constructor of the type, or by both. Thanks, Xan. Ali
Re: Why I could not cast string to int?
Al 02/02/12 20:40, En/na Jonathan M Davis ha escrit: And whether that's the best way to handle it depends on what you're trying to do in terms of user input and error messages. How on earth is all of that going to be handled generically? It all depends on what the programmer is trying to do. Switching to use command-line switches and getopt would help some, but you still have to deal with the error messages yourself. Creating the Person is the easy part. - Jonathan M Davis I think it as a tool, not solve-everything-thing, it just a tool for easy your job. Yeah, you could manually do that (thanks for the code) but really you, maybe, want to do it _fastest_ and _easyest_. Thanks, Xan.
Re: Segment violation (was Re: Why I could not cast string to int?)
Al 03/02/12 00:14, En/na bearophile ha escrit: xancorreu: But you only put a in in recFactorial function argument. What this mean? **Why** this is more efficient than mine? It wasn't meant to improve performance. in turns a function argument to input only (and eventually scoped too). Generally when you program in D2 it's a good practice to use immutability where you can and where this doesn't cause other performance or typing problems. Immutability avoids bugs, allows a stronger purity (and I have seen DMD is often able to compiler a little more efficient program if you use immutability/constants everywhere they are a good fit). So 95% of the arguments of your program are better tagged with in. Mmm. Thanks. It remembers me val in scala ;-) I note it for optimizations. Bye, bearophile
Re: i18n
Al 02/02/12 20:40, En/na Stewart Gordon ha escrit: On 02/02/2012 18:48, xancorreu wrote: Hi, Is there any way for localizate and internationalizate messages? I were shocked if D has something like Fantom [http://fantom.org/doc/docLang/Localization.html]. Gettext is pretty ugly ;-) Is this just about supporting different human languages in your app? This is by displaying different messages depending of system locale of the user. Stewart.
Re: i18n
Al 03/02/12 09:09, En/na Alex_Dovhal ha escrit: xancorreuxancor...@gmail.com wrote: Hi, Is there any way for localizate and internationalizate messages? I were shocked if D has something like Fantom [http://fantom.org/doc/docLang/Localization.html]. Gettext is pretty ugly ;-) I use small D script to internationalize Delphi projects. It's not perfect, but it's simple and easy to modify for one's needs. https://gist.github.com/1728860 Thank you very much for your solution. I deduce so that there is no official support for that. If it's, it's a pain. Xan.
Re: i18n
I deduce so that there is no official support for that. If it's, it's a pain. Pain? Writing such a system can be done in a couple of lines.
char[] and wchar[] cannot be used as OutputRange
This I knew: Being UTF-8 and UTF-16 encodings, and because those encodings are variable-width, char[] and wchar[] cannot be RandomAccessRange ranges (dchar[] can be): import std.range; void main() { assert(!isRandomAccessRange!( char[])); assert(!isRandomAccessRange!(wchar[])); assert( isRandomAccessRange!(dchar[])); } What I've recently discovered is that for being variable-width encodings, char[] and wchar[] cannot be used as OutputRange ranges either. This is because strings are ranges of Unicode characters in D, so their .front must return a dchar, and that dchar must be an rvalue in the cases of char[] and wchar[], which cannot be assigned to. Only dchar[] has assignable elements: import std.range; void main() { assert(!hasAssignableElements!( char[])); assert(!hasAssignableElements!(wchar[])); assert( hasAssignableElements!(dchar[])); } For that reason, only dchar[] can be used as OutputRange: import std.range; void main() { assert(!isOutputRange!( char[], char)); assert(!isOutputRange!( char[], wchar)); assert(!isOutputRange!( char[], dchar)); assert(!isOutputRange!(wchar[], char)); assert(!isOutputRange!(wchar[], wchar)); assert(!isOutputRange!(wchar[], dchar)); assert( isOutputRange!(dchar[], char)); assert( isOutputRange!(dchar[], wchar)); assert( isOutputRange!(dchar[], dchar)); } Ali
Re: linker @ meaning and how to compile static libs
The main question is how do I either compile the library with the right version suffix (@12) Or get the linker to use the right version suffix (@8) That's no version suffix. It's the number of bytes of the arguments IIRC. Windows calling convention.
Re: char[] and wchar[] cannot be used as OutputRange
char[] and wchar[] could still define a put method, which would make them output ranges. This is worth a bug report. Ali Çehreli acehr...@yahoo.com wrote in message news:jgh4a1$1286$1...@digitalmars.com... This I knew: Being UTF-8 and UTF-16 encodings, and because those encodings are variable-width, char[] and wchar[] cannot be RandomAccessRange ranges (dchar[] can be): import std.range; void main() { assert(!isRandomAccessRange!( char[])); assert(!isRandomAccessRange!(wchar[])); assert( isRandomAccessRange!(dchar[])); } What I've recently discovered is that for being variable-width encodings, char[] and wchar[] cannot be used as OutputRange ranges either. This is because strings are ranges of Unicode characters in D, so their .front must return a dchar, and that dchar must be an rvalue in the cases of char[] and wchar[], which cannot be assigned to. Only dchar[] has assignable elements: import std.range; void main() { assert(!hasAssignableElements!( char[])); assert(!hasAssignableElements!(wchar[])); assert( hasAssignableElements!(dchar[])); } For that reason, only dchar[] can be used as OutputRange: import std.range; void main() { assert(!isOutputRange!( char[], char)); assert(!isOutputRange!( char[], wchar)); assert(!isOutputRange!( char[], dchar)); assert(!isOutputRange!(wchar[], char)); assert(!isOutputRange!(wchar[], wchar)); assert(!isOutputRange!(wchar[], dchar)); assert( isOutputRange!(dchar[], char)); assert( isOutputRange!(dchar[], wchar)); assert( isOutputRange!(dchar[], dchar)); } Ali
Re: Function signature constraint syntax
On Fri, Feb 03, 2012 at 06:51:56AM +0100, Philippe Sigaud wrote: Quick question: I have a function that takes an alias parameter: struct X { ... }; void func(alias G)(object O) { ... X x = ...; G(x); ... } How do I write a signature constraint that essentially specifies that G should take a parameter of type X and return void? if ( is(typeof(G(X.init ) ) == void)) For the expression to work, G must accept an X and return a void. Ah, I forgot about .init. Thanks, that's exactly what I was looking for. T -- Береги платье снову, а здоровье смолоду.
Re: i18n
On Fri, Feb 03, 2012 at 09:03:54PM +0100, xancorreu wrote: Al 03/02/12 18:07, En/na Trass3r ha escrit: I deduce so that there is no official support for that. If it's, it's a pain. Pain? Writing such a system can be done in a couple of lines. How? I don't know how to do that. How to read user current locale? An official version could simplify the things: people should not wrtite their own code [...] Write your own version and submit it for review/improvement. Then it'll become official. :) T -- For every argument for something, there is always an equal and opposite argument against it. Debates don't give answers, only wounded or inflated egos.
Re: i18n
Al 03/02/12 19:48, En/na DNewbie ha escrit: You can build multiple versions of you app: http://dsource.org/projects/tutorials/wiki/LocalesExample On Thu, Feb 2, 2012, at 07:48 PM, xancorreu wrote: Hi, Is there any way for localizate and internationalizate messages? I were shocked if D has something like Fantom [http://fantom.org/doc/docLang/Localization.html]. Gettext is pretty ugly ;-) If not, any plannings? Thanks, Xan. Thanks a lot, So I just need to detect user locale using How to do that? Xan.
Re: i18n
Thanks a lot, So I just need to detect user locale using How to do that? You can always use the functions you would use in C.
Re: i18n
03.02.2012 22:03, xancorreu пишет: Al 03/02/12 18:07, En/na Trass3r ha escrit: I deduce so that there is no official support for that. If it's, it's a pain. Pain? Writing such a system can be done in a couple of lines. How? I don't know how to do that. How to read user current locale? An official version could simplify the things: people should not wrtite their own code Xan. I doubt this is a good argument: I don't know it, so it should be done for me. Anyway, for windows you probably need to use this function, or related ones: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318136(v=vs.85).aspx I don't know how the thing is done on Unix family systems though, but as usual - Google is your best friend.
Re: i18n
On Fri, Feb 3, 2012, at 09:48 PM, Trass3r wrote: Thanks a lot, So I just need to detect user locale using How to do that? You can always use the functions you would use in C. You can see your language id in this page: http://msdn.microsoft.com/en-us/library/dd318693(v=vs.85).aspx Example - import std.stdio; import std.c.windows.windows; alias DWORD LCID; extern (Windows) LCID GetSystemDefaultLCID(); int main() { LCID lcid = GetSystemDefaultLCID(); printf(GetSystemDefaultLCID = 0x%04X\n, lcid); switch (lcid) { case 0x0409: writeln(United States (US)); break; case 0x040c: writeln(France (FR)); break; default: writeln(Unknown); break; } return 0; } -
Re: How far can CTFE go?
On 02/03/2012 04:26 AM, Manfred Nowak wrote: H. S. Teoh wrote: I don't think that should be grounds to get rid of CTFE, though. In contrast to your remark, I do not see the benefits of reducing two compiling phases to one. For me CTFE ist nothing else than running the executables of a first compilation in order to get some values needed for a second compilation. -manfred - needed for a third compilation, needed for a fourth compilation, needed for a fifth compilation ... - better syntax, can do complex things without obfuscating the code - no need to serialize and feed back the data into the compiler - more convenient! - faster - very cool You probably haven't made extensive use of the feature. For me it is the main reason to choose D for development.
Re: How far can CTFE go?
On 02/03/2012 12:22 AM, H. S. Teoh wrote: I'm experimenting with pluggable expression parser modules, and I'm wondering if I can use CTFE to build parser tables and such. What are the current limitations of CTFE? Are dynamic arrays of structs supported? Associative arrays? What about compile-time cross-module initialization? The idea is to have a library of modules that parse different kinds of expressions, and depending on which subset of modules are actually imported into the main program, the capability of the generated parser will vary. E.g., the basic parser understands only scalar expressions; import the vector module and it gets extended to handle vector expressions; import another module and it understands other kinds of expressions (matrices, etc.). The parser will be fully specified at compile-time (I'm not planning to support dynamically loading parsing modules), so ideally this should be possible to handle using CTFE. Or is this just a fool's errand? This should work just fine. There is at least one compile-time parser generator for D around, but I cannot find it. On another level, how far are we expecting CTFE to go eventually? In my mind, the ideal situation would be that CTFE can replace writing an arbitrarily complex helper program that generates D code (either functions or data, etc.) which then gets incorporated into the main program. T It can already do that! mixin(arbitrarily_complex_helper_function());
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/03/2012 11:08 AM, Artur Skawina wrote: On 02/03/12 00:20, Jonathan M Davis wrote: in is pointless on value types. All it does is make the function parameter const, which really doesn't do much for you, and in some instances, is really annoying. Personally, I see no point in using in unless the parameter is a reference type, and even then, it's often a bad idea with reference types, because in is really const scope, and the scope is problematic if you want to return anything from that variable. It's particularly problematic with arrays, since it's frequently desirable to return slices of them, and scope (and therefore in) would prevent that. It's useful in some instances (particularly with delegates), but I'd use in _very_ sparingly. It's almost always more trouble than it's worth IMHO. BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. I totally agree. Most function arguments are not escaped. However, it is nice that the shortest storage class, 'in', implies scope. If it isn't obvious why - GC. The compiler can optimize the cases where it knows a newly allocated object can't escape and reduce or omit the GC overhead. And yes, it can also do this automatically - but that requires analyzing the whole call chain, which is a) not always possible and b) much more expensive. artur Any optimization that relies on alias analysis potentially benefits from 'scope'.
Re: Segment violation (was Re: Why I could not cast string to int?)
On 02/03/2012 01:06 PM, Jonathan M Davis wrote: On Friday, February 03, 2012 11:08:54 Artur Skawina wrote: BTW, scope should have been the default for *all* reference type function arguments, with an explicit modifier, say esc, required to let the thing escape. It's an all-or-nothing thing, just like immutable strings - not using it everywhere is painful, but once you switch everything over you get the benefits. That would destroy slicing. I'm firmly of the opinion that scope should be used sparingly. - Jonathan M Davis It could be enabled on by type basis.
Re: How far can CTFE go?
On Sat, Feb 04, 2012 at 01:54:55AM +0100, Timon Gehr wrote: [...] On another level, how far are we expecting CTFE to go eventually? In my mind, the ideal situation would be that CTFE can replace writing an arbitrarily complex helper program that generates D code (either functions or data, etc.) which then gets incorporated into the main program. [...] It can already do that! mixin(arbitrarily_complex_helper_function()); [...] Yes, but how complete is the support for this? Last I checked, I couldn't call floating-point functions in the helper function 'cos std.math apparently uses asm to implement some of the math functions, and gdc refuses to evaluate that at compile-time. And IIRC, TDPL does mention that certain language constructs can't be used due to compiler limitations. (I'll have to look that up again when I get home.) But my original question pertains to cross-module initialization. Can the following can be achieved?: - The parser module (or parser generator module as the case may be) needs to collect info for all modules to be included in the final parser so that it can generate tables used by the parsing engine. - Ideally, the act of compiling one of these pluggable modules should automatically include itself into the parsing tables. - The tables should ideally be fully computed at compile-time. The main challenge is, how to have the pluggable module inform the parser module of its presence *at compile time*? Ideally, the parser module shouldn't need to keep a big list of potential modules; it should be the modules that register themselves with the parser. This is easily done with a static init method, obviously, but the challenge is how to achieve this at compile time. One way I can think of is for the module that contains main() decide which modules it wants to include, and call the parser module's setup function via CTFE with the list of modules it should lookup. So then the question becomes, given a list of modules represented as strings, is it possible for CTFE to do symbol lookups of that module at compile-time? This seems as far as I can go, at least from what I know. It would be nice if the main module doesn't even need to pass a list of modules to the parser generator, just link the relevant modules, and have the parser generator automatically detect what modules are present. But I suspect that won't work 'cos by the time we get to the linker it's too late to know which modules were included. T -- Don't throw out the baby with the bathwater. Use your hands...
Re: Segment violation (was Re: Why I could not cast string to int?)
Timon Gehr: However, it is nice that the shortest storage class, 'in', implies scope. I'd like to ask this to be valid, to shorten my code: alias immutable imm; Is this silly? Bye, bearophile
Re: How far can CTFE go?
Timon Gehr wrote: You probably haven't made extensive use of the feature. That is correct. - needed for a third compilation, needed for a fourth compilation, needed for a fifth compilation ... Provide an example please and I will change my opinion. - better syntax, can do complex things without obfuscating the code If the codes for more than one _needed_ phase are tangled into one code base, I call that an obfuscated base. -manfred
Re: Segment violation (was Re: Why I could not cast string to int?)
bearophile bearophileh...@lycos.com wrote in message news:jgi3jn$2o6p$1...@digitalmars.com... I'd like to ask this to be valid, to shorten my code: alias immutable imm; Is this silly? Yes =) immutable might be more characters than you want to type, but at this point it's extremely unlikely it will be changed or a synonym will be added. You can always define something like this: template imm(T) { alias immutable T imm; } imm!int cantchangethis = ...;
Re: How far can CTFE go?
On Sat, Feb 04, 2012 at 02:36:10AM +, Manfred Nowak wrote: [...] - better syntax, can do complex things without obfuscating the code If the codes for more than one _needed_ phase are tangled into one code base, I call that an obfuscated base. [...] One major advantage of CTFE that is covered in TDPL is compile-time validation of generated code. The example was generating a linear congruential engine for generating random numbers. The CTFE is used not only for generating the congruential engine code, but also to validate that its generating parameters do not lead to poor behaviour such as a very short period. If this was code generated by an external utility, you cannot easily validate the resulting code. Worse yet, the external utility generates correct code (e.g. a linear congruential generator with a maximal period) but the user goes and edits one of the parameters, it turns into a generator with a bad period. There's no easy way to prevent this. With CTFE, all generated linear congruential generators are *guaranteed* to have maximal periods, because the CTFE simply refuses to generate something with bad parameters. Also, functions used in CTFE can *also* be used at runtime. If you were forced to generate code by an external utility, there may not be a nice way of reusing code in this way, and there's the possibility that you will accidentally end up using two different versions of the function, leading to subtle hard-to-find bugs. With CTFE, it is guaranteed that the function used to generate the compile-time data is exactly the same as the one that is used at runtime to generate other data. T -- There are 10 kinds of people in the world: those who can count in binary, and those who can't.
Associative array literal is non-constant?
Why does the following code give a compiler error? static int[string] table = [abc:1, def:2, ghi:3]; Error message is: prog.d:3: Error: non-constant expression [abc:1,def:2,ghi:3] How is a literal non-constant? T -- GEEK = Gatherer of Extremely Enlightening Knowledge
Re: Associative array literal is non-constant?
A limitation of the current implementation. Associative arrays are built on the heap, and you can't currently build things on the heap and have them exist at runtime. The best current workaround is probably: static int[string] table; static this() { table = [abc:1, def:2, ghi:3]; } or if inside a function: static int[string] table; if (!table) table = [abc:1, def:2, ghi:3]; H. S. Teoh hst...@quickfur.ath.cx wrote in message news:mailman.356.1328336206.25230.digitalmars-d-le...@puremagic.com... Why does the following code give a compiler error? static int[string] table = [abc:1, def:2, ghi:3]; Error message is: prog.d:3: Error: non-constant expression [abc:1,def:2,ghi:3] How is a literal non-constant? T -- GEEK = Gatherer of Extremely Enlightening Knowledge
Re: Associative array literal is non-constant?
On Fri, Feb 03, 2012 at 10:18:18PM -0800, H. S. Teoh wrote: Why does the following code give a compiler error? static int[string] table = [abc:1, def:2, ghi:3]; Error message is: prog.d:3: Error: non-constant expression [abc:1,def:2,ghi:3] How is a literal non-constant? [...] Ugh. Just found this: http://d.puremagic.com/issues/show_bug.cgi?id=6238 Further testing shows that assoc array literals can't be used outside of function scope at all, for example: // (in package scope) auto hash = [ abc:1, def:2, ghi:3 ]; // Error: non-constant expression [abc:1,def:2,ghi:3] Seems like a pretty nasty bug to me. T -- If the comments and the code disagree, it's likely that *both* are wrong. -- Christopher