function-local template specialization error
void main() { T input(T)() {} T input(T : string)() {} } Error message : isimsiz.d(6): found 'input' when expecting ';' following statement isimsiz.d(6): found ':' when expecting ')' isimsiz.d(6): found 'string' when expecting ';' following statement isimsiz.d(6): found ')' instead of statement isimsiz.d(8): unrecognized declaration Shouldn't that work? And void main() { void input(T)() {} void input(T : string)() {} } Again, Shouldn't that work? Error message: isimsiz.d(6): Error: declaration input(T : string) is already defined there is no problem when the templates are in the global namespace.
object.reserve() and array size
Is object.reserve() only useful for large arrays, or should I always use it if I intend to append to an array? Let's say I want to read some data, and I expect there to be ~100 bytes of data. Is there any point in using reserve() first, or will there always be that much memory available to an array? byte[] buffer; buffer.reserve(100); foreach(byte b; dataSource) buffer ~= b; -Lars
Re: function-local template specialization error
canalpay: > void main() > { > T input(T)() > {} > > T input(T : string)() > {} > } In D2 you can't define templates inside functions. Bye, bearophile
Re: object.reserve() and array size
On Wed, 14 Jul 2010 06:01:10 -0400, Lars T. Kyllingstad wrote: Is object.reserve() only useful for large arrays, or should I always use it if I intend to append to an array? Let's say I want to read some data, and I expect there to be ~100 bytes of data. Is there any point in using reserve() first, or will there always be that much memory available to an array? byte[] buffer; buffer.reserve(100); foreach(byte b; dataSource) buffer ~= b; Yes, you should always reserve if you know how much data is coming. If you do not here is what happens: Upon adding the first byte, a block of 16 bytes is allocated Upon adding the 16th byte (there is one byte for padding), a *new* block of 32 bytes is allocated, and the 15 previous bytes are copied to the 32-byte block. The original 16 byte block is left allocated because there could be other aliases to the data. Upon adding the 32nd byte, a block of 64 bytes is allocated, rinse and repeat. Upon adding the 64th byte, a block of 128 bytes is allocated, same deal. Then the block will hold 100 bytes. If you reserve 100 bytes, then a block of 128 bytes is allocated, and your data all goes in there. OT, I assume you realize that reading data in this way is horribly inefficient :) You should read a block at once if possible. -Steve
Re: function-local template specialization error
bearophile Wrote: > In D2 you can't define templates inside functions. > > Bye, > bearophile Thanks, But this example works: void main() { T input(T)() {} } Why ?
Re: object.reserve() and array size
On Wed, 14 Jul 2010 10:35:19 -0400, Steven Schveighoffer wrote: > On Wed, 14 Jul 2010 06:01:10 -0400, Lars T. Kyllingstad > wrote: > >> Is object.reserve() only useful for large arrays, or should I always >> use it if I intend to append to an array? >> >> Let's say I want to read some data, and I expect there to be ~100 bytes >> of data. Is there any point in using reserve() first, or will there >> always be that much memory available to an array? >> >> byte[] buffer; >> buffer.reserve(100); >> foreach(byte b; dataSource) buffer ~= b; > > Yes, you should always reserve if you know how much data is coming. If > you do not here is what happens: > > Upon adding the first byte, a block of 16 bytes is allocated Upon adding > the 16th byte (there is one byte for padding), a *new* block of 32 bytes > is allocated, and the 15 previous bytes are copied to the 32-byte block. > The original 16 byte block is left allocated because there could be > other aliases to the data. > Upon adding the 32nd byte, a block of 64 bytes is allocated, rinse and > repeat. > Upon adding the 64th byte, a block of 128 bytes is allocated, same deal. > > Then the block will hold 100 bytes. > > If you reserve 100 bytes, then a block of 128 bytes is allocated, and > your data all goes in there. > > OT, I assume you realize that reading data in this way is horribly > inefficient :) You should read a block at once if possible. Yeah, that was just an artificial example. :) The actual use case was building a string from substrings. Thanks! -Lars
Re: function-local template specialization error
canalpay: > Thanks, But this example works: > void main() > { > T input(T)() > {} > > } > > Why ? You are right. Beside allowing nested functions (this is well known), it seems D2 also accepts the definition (with template constraint too) and instantiation of simple templates inside functions, I didn't know this. But currently nested functions can't be overloaded. Probably for similar reasons inside a function you can't define more than one template with the same name. I presume this limit can be removed, so if you really need this you can ask for an enhancement request and if you can add a patch too to increase a bit the probability to see it fulfilled someday. Bye, bearophile
Some testing?
This small D2 program compiles with no errors: T foo(T)(T x) {} void main() {} But there is no way it can compile, regardless of the type T, because foo()() lacks a return statement. So is it possible for the D compiler to perform some sanity tests for the template functions too, to catch a bugs like this one? Bye, bearophile
Re: Some testing?
On Wednesday, July 14, 2010 11:55:57 bearophile wrote: > This small D2 program compiles with no errors: > > T foo(T)(T x) {} > void main() {} > > But there is no way it can compile, regardless of the type T, because > foo()() lacks a return statement. So is it possible for the D compiler to > perform some sanity tests for the template functions too, to catch a bugs > like this one? > > Bye, > bearophile You get an error if you use foo. My guess would be that foo effectively doesn't exist until you instantiate it, so there's not really a function to give you an error on. - Jonathan M Davis
Re: Some testing?
Am 14.07.2010 20:55, schrieb bearophile: This small D2 program compiles with no errors: T foo(T)(T x) {} void main() {} But there is no way it can compile, regardless of the type T, because foo()() lacks a return statement. So is it possible for the D compiler to perform some sanity tests for the template functions too, to catch a bugs like this one? Imagine T was void. Then no return was ok. It wouldn't (shouldn't) compile anyways because a parameter of type void is (should be) invalid. However to enforce the compiler to see that T can't be void is a bit to complicated, I think. Mafi
Re: function-local template specialization error
bearophile wrote: canalpay: Thanks, But this example works: void main() { T input(T)() {} } Why ? You are right. Beside allowing nested functions (this is well known), it seems D2 also accepts the definition (with template constraint too) and instantiation of simple templates inside functions, I didn't know this. But currently nested functions can't be overloaded. Probably for similar reasons inside a function you can't define more than one template with the same name. I presume this limit can be removed, so if you really need this you can ask for an enhancement request and if you can add a patch too to increase a bit the probability to see it fulfilled someday. Bye, bearophile The spec explicitly says: "Unlike module level declarations, declarations within function scope are processed in order. This means that two nested functions cannot mutually call each other: [snip] Future directions: This restriction may be removed." My guess is that it will become possible eventually.
Re: Some testing?
bearophile wrote: This small D2 program compiles with no errors: T foo(T)(T x) {} void main() {} But there is no way it can compile, regardless of the type T, because foo()() lacks a return statement. So is it possible for the D compiler to perform some sanity tests for the template functions too, to catch a bugs like this one? Bye, bearophile Yes, it'd be possible for such simple cases, but would it be worthwhile? Since an error message will occur for ANY instantiation of foo, the only errors that would catch are when there's absolutely no testing or use of foo. In which case you have much bigger problems. And unfortunately it doesn't scale to more complex situations where it might actually help.
Re: Some testing?
Mafi: > Imagine T was void. Then no return was ok. It wouldn't (shouldn't) > compile anyways because a parameter of type void is (should be) invalid. > However to enforce the compiler to see that T can't be void is a bit to > complicated, I think. You are right, this different version runs: T foo(T)() {} void main() { foo!void(); } Thanks for all the answers, to you, Don and Jonathan. A question like this was probably more at home in the IRC channel. Bye, bearophile
Re: Multi dimensional array question.
Lars T. Kyllingstad Wrote: > > But then arrays would be different from all other types! If you have an > array of 3 Ts, that is written T[3], regardless of what T is. Now > consider these two cases: > >A. T is an int. Then T[3] becomes int[3]. > >B. T is an int[string]. Then T[3] becomes int[string][3]. > > In case A, the first element of the array is accessed like this: > >int[3] a; >int firstA = a[0]; > > Since a is an array of int, firstA is of course an int. > > But then, since b is an array of int[string], we have > >int[string][3] b; >int[string] firstB = b[0]; > > If we again want to access element "foo" of the associative array which > is firstB, we write firstB["foo"]. And so we have the following three > ways to get to that element, which *must* be equivalent because that's > how the language is defined: > >// Using firstB as an intermediate step >int[string] firstB = b[0]; >int x = firstB["foo"]; > >// Drop the intermediate variable firstB >int x = (b[0])["foo"]; > >// Drop the redundant parentheses >int x = b[0]["foo"]; > > So you see, it can't be any other way than the way it is. :) > > -Lars Thank you for the elaborate answer! When you put it like that, it does make sense. But I'm sorry. I refuse. The reason I refuse is those examples are void of any higher semantic meaning. Once we add a semantic meaning, it simply becomes backwards: int[MAX_WIDTH][MAX_HEIGHT] map2d; map2d[x][y] = 9; // Wrong! At least in my head, this is cognitive dissonance. To me, the language acts as if it's low-level semantics outweighs my high-level semantics and I should correct my thinking for that. I refuse! Seems to me it could just as well work as: int[string][3] b; int[3] firstB = b["foo"]; int i = firstB[0]; int j = (b["foo"])[0]; int k = b["foo"][0]; But I feel like I'm the only one feeling this, so I'll just let it go and hope my dear C-style arrays stay in :) BR /HF PS. Never thought I'd find a reason to love C.. DS.
Re: Multi dimensional array question.
On Wednesday, July 14, 2010 13:57:13 Heywood Floyd wrote: > > Thank you for the elaborate answer! > > When you put it like that, it does make sense. But I'm sorry. I refuse. The > reason I refuse is those examples are void of any higher semantic meaning. > Once we add a semantic meaning, it simply becomes backwards: > > int[MAX_WIDTH][MAX_HEIGHT] map2d; > map2d[x][y] = 9; // Wrong! > > At least in my head, this is cognitive dissonance. To me, the language acts > as if it's low-level semantics outweighs my high-level semantics and I > should correct my thinking for that. I refuse! Seems to me it could just > as well work as: > > int[string][3] b; > int[3] firstB = b["foo"]; > int i = firstB[0]; > int j = (b["foo"])[0]; > int k = b["foo"][0]; > > But I feel like I'm the only one feeling this, so I'll just let it go and > hope my dear C-style arrays stay in :) > > BR > /HF > > PS. Never thought I'd find a reason to love C.. DS. Personally, I don't like it, but I also don't think that it necessarily makes sense to change it. From the point of view of how the compiler deduces types, it's exactly how it should work. The problem, of course, is that it doesn't match how we think. However, in order for us to be able to deduce complicated types, the compiler must be totally consistent in how it deduces the type. A prime example would be function pointers (particularly using the C syntax). To be able to pick it apart properly, you're going to have to understand how the compiler does it. The type is complicated enough that you're stuck. To read arrays in the reverse order that is done now, you'd have to read everything else in the reverse order to be consistent, which would really mean types like this: [5](int) const a; The whole thing is ugly. There's no question of that. But to "fix" it breaks other stuff. Types are read right to left. Being consistent with that makes it possible to understand more complicated types. The downside is that some simpler types become harder to understand. However, as long as you use dynamic arrays, this really isn't a problem. int[][] a = new int[][](MAX_WIDTH, MAX_HEIGHT); is totally clear and it works in the order that you think. The problem is when you use statically-allocated arrays. Personally, I'd advise you to just use dynamic arrays unless you do some profiling and find that a static array is better in a particular case. Doing things that way makes it so that the weird ordering in declarations isn't generally a problem. I agree that this particular syntactic faux pas is a problem, but I don't think that anyone has come up with an appropriate solution. Simply reversing how it works now would make reading more complex types much harder. A more complex solution would likely be required. As it stands, it's a problem, but it's only a problem if you're declaring statically-allocated arrays. It's unpleasant, but it should be manageable. - Jonathan M Davis
Best practice and module declarations
I was wondering what the general consesus was (if there is one) on whether it's valuable to always put module declarations in each module. Obviously, if you need the module to have a name other than the file name, then you need to have the module declaration. However, is it necessarily desirable to have it when the module name matches the file name? Or would there even be a reason for it to be desirable _not_ to have the module declaration? I can't think of any particularly strong reasons to have it or not to have it. My first reaction is to just always use it, but thinking about it, I'm not sure that there's really much point if the file name and the module name already match. Does anyone have reasons why it would matter other than personal preference? - Jonathan M Davis
Re: Best practice and module declarations
On 15.07.2010 00:22, Jonathan M Davis wrote: I was wondering what the general consesus was (if there is one) on whether it's valuable to always put module declarations in each module. Obviously, if you need the module to have a name other than the file name, then you need to have the module declaration. However, is it necessarily desirable to have it when the module name matches the file name? Or would there even be a reason for it to be desirable _not_ to have the module declaration? I can't think of any particularly strong reasons to have it or not to have it. My first reaction is to just always use it, but thinking about it, I'm not sure that there's really much point if the file name and the module name already match. Does anyone have reasons why it would matter other than personal preference? Some of the D build tools complain if you don't use module declarations. And IIRC, modules in subdirectories (packages) need to have them. So I end up adding them for anything but single-file test programs.
CT usage only in executable
Not that the memory is really significant compared to the rest of my program, but I have a few fairly large arrays I use only in compile time and I was wondering why dmd still includes those in the executable (simple text search dug them up).
Re: CT usage only in executable
strtr: > Not that the memory is really significant compared to the rest of my program, > but I have a few fairly large arrays I use only in compile time and I was > wondering why dmd still includes those in the executable (simple text search > dug them up). Are you able to create a smallish test case? Bye, bearophile
Re: CT usage only in executable
== Quote from bearophile (bearophileh...@lycos.com)'s article > strtr: > > Not that the memory is really significant compared to the rest of my > > program, > > but I have a few fairly large arrays I use only in compile time and I was > > wondering why dmd still includes those in the executable (simple text search > > dug them up). > Are you able to create a smallish test case? > Bye, > bearophile module main; const char[] CT_STRING = "int i=0;"; void main(){ mixin( CT_STRING ); } The string can be found in the executable.
Is synchronized(mutex) == mutex.lock()?
Hi! Breakfast toast: Is there any chance a) and b) below are identical in what they do? auto mutex = new Mutex(); auto cond = new Condition(mutex); // a) synchronized(mutex){ cond.wait(); } // b) mutex.lock(); cond.wait(); mutex.unlock(); I was sprinkling my code with mutex.lock/unlock (for fun) when suddenly I realized that, hey, maybe synchronized would work just as well, and be even more fun? (If that's even possible.) BR /HF