Re: @safe @nogc memory allocation
On Wednesday, 28 May 2014 at 23:57:40 UTC, Dicebot wrote: I believe within current language semantics even considering `new` pure is broken, there was a very recent thread discussing it in digitalmars.D group. If you can be sure that your code won't break basic sanity requirements (never comparing allocated immutable pointer identity, only pointed values) it should work fine. But I have never done it in my code and not aware of possible pitfalls. You also have to make sure your calls to malloc wont be considered strongly pure and memoized. e.g.: int* a = cast(int*)malloc(4); // 4 should be considered immutable int* b = cast(int*)malloc(4); // a == b if memoized // a != b otherwise (unless out of memory) Perhaps the wrapper function should take a pointer reference as a parameter (note: not immutable,) this also means that it can use type inference.
Re: @safe @nogc memory allocation
On Wednesday, 28 May 2014 at 21:31:41 UTC, Nordlöw wrote: It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`. Does this mean that I should write and use such a wrapper for malloc? /Per I don't know. I believe within current language semantics even considering `new` pure is broken, there was a very recent thread discussing it in digitalmars.D group. If you can be sure that your code won't break basic sanity requirements (never comparing allocated immutable pointer identity, only pointed values) it should work fine. But I have never done it in my code and not aware of possible pitfalls.
Re: Programming a Game in D? :D
On Wednesday, 28 May 2014 at 21:38:07 UTC, Francesco Cattoglio wrote: I'll be honest, perhaps I risk being misunderstood, but the questions you are asking denote a lack of even basic knowledge about the subject, so I really think you should do some good amount of research before even trying to write something on your own. Well, I really don't have a lot of knowledge but I don't know where to start. The Problem is just that there is sooo much stuff in the internet and it's kinda hard to get some knowledge. Have you tried at least some free tools that allow you to script stuff and have simple stuff displayed on screen? I'm talking about stuff like Construct 2, GameMaker, RPGMaker, zGameEditor... even map editors like the ones from Blizzard (WarCraft 3 : TFT or StarCraft 2)? So, i made a very little game with delphi Genesis3D and an Editor i don't remember about 2 years ago, but i don't know if i really knew what i was doing there :P
Re: Programming a Game in D? :D
On Wednesday, 28 May 2014 at 17:46:23 UTC, David wrote: Ok, now I just wonder wich Engine. (I know everybody hates the discussion about the "best" engine.) CryEngine, UDK, Unity or a less known Engine? I'll be honest, perhaps I risk being misunderstood, but the questions you are asking denote a lack of even basic knowledge about the subject, so I really think you should do some good amount of research before even trying to write something on your own. Have you tried at least some free tools that allow you to script stuff and have simple stuff displayed on screen? I'm talking about stuff like Construct 2, GameMaker, RPGMaker, zGameEditor... even map editors like the ones from Blizzard (WarCraft 3 : TFT or StarCraft 2)?
Re: @safe @nogc memory allocation
It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`. Does this mean that I should write and use such a wrapper for malloc? /Per
Re: @safe @nogc memory allocation
On Wednesday, 28 May 2014 at 21:09:26 UTC, bearophile wrote: Dicebot: It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`. One wrapper should have a template argument to specify the type of the items, to avoid the need of a cast. And instead of throwing an error it could also return a Nullable (the sizeof of such Nullable is the same as a pointer). Nullable!(Titem*, null) talloc(Titem)(in size_t nItems); Bye, bearophile I don't think wrapper with Nullable can be pure as it will possibly return two different object values (and not just different pointers) when called with same argument list. Throwing an Error is crucial here.
Re: @safe @nogc memory allocation
Dicebot: It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`. One wrapper should have a template argument to specify the type of the items, to avoid the need of a cast. And instead of throwing an error it could also return a Nullable (the sizeof of such Nullable is the same as a pointer). Nullable!(Titem*, null) talloc(Titem)(in size_t nItems); Bye, bearophile
Re: @safe @nogc memory allocation
On Wednesday, 28 May 2014 at 20:51:08 UTC, Nordlöw wrote: malloc? There's no wrapper around it though, like there is for uninitializedArray. Is the fact that malloc() can't be pure when new is a limitiation in the type system? Do we need a yet another code tag for this? /Per It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`.
Re: @safe @nogc memory allocation
malloc? There's no wrapper around it though, like there is for uninitializedArray. Is the fact that malloc() can't be pure when new is a limitiation in the type system? Do we need a yet another code tag for this? /Per
Re: Looping over all enum values
On Wednesday, 28 May 2014 at 20:20:37 UTC, Adam D. Ruppe wrote: On Wednesday, 28 May 2014 at 20:19:45 UTC, Mark Isaacson wrote: Is there a mechanism that allows you to loop over all of an enum's values? I've wanted to do so a couple times now for CTFE/mixin templates. __traits(allMembers) on the enum can do it or this can help too http://dlang.org/phobos/std_traits.html#EnumMembers Brilliant! Thanks Adam! I actually checked your book before any other sources for this :)
Re: Looping over all enum values
On Wednesday, 28 May 2014 at 20:19:45 UTC, Mark Isaacson wrote: Is there a mechanism that allows you to loop over all of an enum's values? I've wanted to do so a couple times now for CTFE/mixin templates. __traits(allMembers) on the enum can do it or this can help too http://dlang.org/phobos/std_traits.html#EnumMembers
Looping over all enum values
Is there a mechanism that allows you to loop over all of an enum's values? I've wanted to do so a couple times now for CTFE/mixin templates. I was able to loop over the underlying type when my enum was integer-based, but I can't do that if the values are strings (also that solution is quite hacky). Perhaps there's a pattern involving __traits?
Re: @safe @nogc memory allocation
On Wednesday, 28 May 2014 at 20:00:17 UTC, safety0ff wrote: I think malloc isn't @safe and alloca doesn't work if your function can throw. Yeah, uninitializedArray is also *only* trusted if the type in question has no indirections. I've heard of several bugs with alloca, but I don't know the exact list.
Re: @safe @nogc memory allocation
I think malloc isn't @safe and alloca doesn't work if your function can throw.
Re: @safe @nogc memory allocation
On Wednesday, 28 May 2014 at 19:43:53 UTC, Nordlöw wrote: I would like my radix sort function radixSortImpl() at https://github.com/nordlow/justd/blob/master/intsort.d to not use the GC. However, when I tag with @nogc I get the error: intsort.d(195,47): Error: @nogc function 'isort.radixSortImpl!(byte[], "a", false).radixSortImpl' cannot call non-@nogc function 'std.array.uninitializedArray!(byte[], immutable(ulong)).uninitializedArray' Is there an alternative to std.array: uninitializedArray Elem[] y = uninitializedArray!(Elem[])(n); that neither use the GC and nor preinitialize the data? malloc? There's no wrapper around it though, like there is for uninitializedArray. Keep in mind though that currently, you have to choose either of "pure" (GC) or "nogc" (malloc) if you need dynamic allocation :/ Could the recent DMD pull optimization to scope here https://github.com/D-Programming-Language/dmd/commit/abc7033bf9cf7f7224a47e45096efc48a21b5ab8 be used? /Per I don't think scope can be used to create a dynamic array on the stack. I think it requires the object's type be statically known. I could be wrong though. If you know "n" has a max size, you could you create a fixed size array, or attempt a "alloca" array?
@safe @nogc memory allocation
I would like my radix sort function radixSortImpl() at https://github.com/nordlow/justd/blob/master/intsort.d to not use the GC. However, when I tag with @nogc I get the error: intsort.d(195,47): Error: @nogc function 'isort.radixSortImpl!(byte[], "a", false).radixSortImpl' cannot call non-@nogc function 'std.array.uninitializedArray!(byte[], immutable(ulong)).uninitializedArray' Is there an alternative to std.array: uninitializedArray Elem[] y = uninitializedArray!(Elem[])(n); that neither use the GC and nor preinitialize the data? Could the recent DMD pull optimization to scope here https://github.com/D-Programming-Language/dmd/commit/abc7033bf9cf7f7224a47e45096efc48a21b5ab8 be used? /Per
Re: Programming a Game in D? :D
On Wednesday, 28 May 2014 at 17:46:23 UTC, David wrote: Ok, now I just wonder wich Engine. (I know everybody hates the discussion about the "best" engine.) CryEngine, UDK, Unity or a less known Engine? The best engine is the one you can get work done with. Unity seems to have a pretty good community around it lately and has a free version to play with. Having all of that documentation and community to fall back on is likely to be a benefit if you aren't hugely experienced yet.
Re: std.algorithm range violation
On Wednesday, 28 May 2014 at 17:39:15 UTC, monarch_dodra wrote: On Wednesday, 28 May 2014 at 11:40:05 UTC, Wanderer wrote: Sorry about typo, I meant providor_symbol_map.sort!((x,y)=>{x.value.length>y.value.length}) above. providor_symbol_map is an Associative Array, so you can't sort that. *Usually*, you want to do what the OP did, which is to get the keys, and sort them, but leave the AA unchanged. EG: Val[Key] myAA; Key[] mySortedKeys = myAA.keys.sort!((x, y)=> compare(myAA[x], myAA[y]))() //Print values in incremented order: foreach(key; mySortedKeys) writefln("%s: %s", key, myAA[key]); I case this was not clear "compare" is an function you should replace with your own. It should simply define strict ordering of x and y. "<" is one such function.
Re: Cost of .dup vs. instantiation
On Wednesday, 28 May 2014 at 14:36:25 UTC, Chris wrote: I use Appender to fill an array. The Appender is a class variable and is not instantiated with each function call to save instantiation. However, the return value or the function must be dup'ed, like so: Appender!(MyType[]) append; public auto doSomething() { scope (exit) { // clear append } // ... do something append ~= item; return (append.data).dup } My question is whether I save anything with Appender as a class variable here. I have to .dup the return value (+ clear the Appender). If I had a new Appender with each function call, it might be just as good. public auto doSomething() { Appender!(MyType[]) append; // return append.data. } Right or wrong? When it comes to optimizations it's hard to say. Benchmarking is better than relying advice/opinions on the internet in any case. That being said i doubt that the instantiation cost of the Appender is relevant. (Btw the appender is not a class variable! It is a struct with reference semantics). Reusing an appender is more for those cases where you want to reuse the underlying memory of the appender itself.
Re: Programming a Game in D? :D
On Tuesday, 27 May 2014 at 10:13:13 UTC, Szymon Gatner wrote: On Tuesday, 27 May 2014 at 10:03:36 UTC, David wrote: On Saturday, 24 May 2014 at 08:54:53 UTC, ponce wrote: Hi David, Learning programming, learning D and learning 3D are 3 significant endeavours. You might want to begin with http://www.basic4gl.net/ which will get you going with 3D, quite a topic in itself. Then learn D regardless :) So, I'v used Blender for a half year or sth. and I think I can make a little area :) As far as I know, I do now need a graphic and physics engines, 1 of the graphic APIs and for sure my programming stuff and here I'm stuck :D And I still can't install Mono-D :( if I try I just get a whole bunch of errors that any packages couldn't be found, don't know if I'm doing sth. wrong (I probably do :P) I would STRONGLY advise to go with a ready engine like Unity. You still have to learn a lot before you will have just building blocks to create a game like loading and rendering 3D models, a gameplay framework etc etc. Start with Unity, lean how to make a game there. Learn how to programm gameplay there and after that, when you see what is needed before even being able to make a game, only then try to make things from scratch. Use C# in Unity too as it is similar to D so you will have easier transition when necessary. Ok, now I just wonder wich Engine. (I know everybody hates the discussion about the "best" engine.) CryEngine, UDK, Unity or a less known Engine?
Re: std.algorithm range violation
On Wednesday, 28 May 2014 at 11:40:05 UTC, Wanderer wrote: Sorry about typo, I meant providor_symbol_map.sort!((x,y)=>{x.value.length>y.value.length}) above. providor_symbol_map is an Associative Array, so you can't sort that. *Usually*, you want to do what the OP did, which is to get the keys, and sort them, but leave the AA unchanged. EG: Val[Key] myAA; Key[] mySortedKeys = myAA.keys.sort!((x, y)=> compare(myAA[x], myAA[y]))() //Print values in incremented order: foreach(key; mySortedKeys) writefln("%s: %s", key, myAA[key]);
Re: Cost of .dup vs. instantiation
On Wednesday, 28 May 2014 at 14:36:25 UTC, Chris wrote: I use Appender to fill an array. The Appender is a class variable and is not instantiated with each function call to save instantiation. However, the return value or the function must be dup'ed, like so: Appender!(MyType[]) append; public auto doSomething() { scope (exit) { // clear append } // ... do something append ~= item; return (append.data).dup } My question is whether I save anything with Appender as a class variable here. I have to .dup the return value (+ clear the Appender). If I had a new Appender with each function call, it might be just as good. public auto doSomething() { Appender!(MyType[]) append; // return append.data. } Right or wrong? You might save a little because you avoid the cost of "growing" your appender repeatedly: Once the appender has come to "maturity", it will very likely stop growing. At that point, you only pay for *1* allocation per call to doSomething. Further advantages include: - dup has "APPENDABLE" info (whereas appender.data does not). - less wasted memory: dup uses no more memory than it has to, whereas Appender may over-allocate, depending on how you fill it. The "downside" to your approach is that you keep a handle on a buffer that can grow, but never shrink. If a at a certain point, you have to process some particularly large input, then you'll consume excessive amounts of memory.
Cost of .dup vs. instantiation
I use Appender to fill an array. The Appender is a class variable and is not instantiated with each function call to save instantiation. However, the return value or the function must be dup'ed, like so: Appender!(MyType[]) append; public auto doSomething() { scope (exit) { // clear append } // ... do something append ~= item; return (append.data).dup } My question is whether I save anything with Appender as a class variable here. I have to .dup the return value (+ clear the Appender). If I had a new Appender with each function call, it might be just as good. public auto doSomething() { Appender!(MyType[]) append; // return append.data. } Right or wrong?
Re: std.algorithm range violation
wow. senpai, teach me what I did wrong... 2014-05-28 13:21 GMT+02:00 bearophile via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com>: > maarten van damme: > > > writeln(providor_symbol_map.keys.sort!((x,y)=>providor_ >> symbol_map[x].length>=providor_symbol_map[y].length)); >> [/code] >> > > Try: > > ((x, y) => providor_symbol_map[x].length > providor_symbol_map[y].length) > > Bye, > bearophile >
Re: std.algorithm range violation
Aha, so you want to maintain "spam word" -> "set of senders" relationship, so it's actually "map of sets" and your declaration is correct. You only need to sort map's entries (key and value pairs together). If D supports that, it should be something like providor_symbol_map.sort!((x,y)=>{x.value.length=>y.value.length}), but I'm not sure it would work... But I'm just learning D (and very much like it so far!), hopefully someone more skilled will reply as well. :-)
Re: std.algorithm range violation
Wanderer: providor_symbol_map.sort!((x,y)=>{x.value.length=>y.value.length}), This lambda doesn't return a boolean. Also, add spaces around operators and after commas. Bye, bearophile
Re: std.algorithm range violation
Sorry about typo, I meant providor_symbol_map.sort!((x,y)=>{x.value.length>y.value.length}) above.
Re: std.algorithm range violation
maarten van damme: writeln(providor_symbol_map.keys.sort!((x,y)=>providor_symbol_map[x].length>=providor_symbol_map[y].length)); [/code] Try: ((x, y) => providor_symbol_map[x].length > providor_symbol_map[y].length) Bye, bearophile
Re: std.algorithm range violation
I'm trying to analyze the usage of certain words in a large number of spam emails, and I want for every interesting word a list of 'providors', that mentioned that word. with associative arrays I hoped to get it by using array["interestingworde]. And I have to refer outside from sort(x,y) as associative arrays have no order, I'll always have to sort a key-array according to values obtained through the associative array. It's supposed to be a delegate anyway, otherwise the least it could do is throw a compilation error. 2014-05-28 12:53 GMT+02:00 Wanderer via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com>: > On Wednesday, 28 May 2014 at 10:10:41 UTC, maarten van damme via > > Digitalmars-d-learn wrote: > >> an anyone explain me what I'm doing wrong here : >> >> [code] >> dstring[][dstring] providor_symbol_map; >> ... >> >> writeln(providor_symbol_map.keys.sort!((x,y)=>providor_ >> symbol_map[x].length>=providor_symbol_map[y].length)); >> [/code] >> >> output: >> core.exception.RangeError@std.algorithm(9429): Range violation >> > > "dstring[][dstring]" declaration looks a bit obscure to me... > what do you intent with it, "array of maps" or "map of arrays"? > > Also, it looks unnatural that inside sorting lambda, you refer > outside from it (back to providor_symbol_map variable). Ideally, > you should only use variables x and y. Does D support sorting by > map entries instead of by keys only or by values only? >
Re: std.algorithm range violation
On Wednesday, 28 May 2014 at 10:10:41 UTC, maarten van damme via Digitalmars-d-learn wrote: an anyone explain me what I'm doing wrong here : [code] dstring[][dstring] providor_symbol_map; ... writeln(providor_symbol_map.keys.sort!((x,y)=>providor_symbol_map[x].length>=providor_symbol_map[y].length)); [/code] output: core.exception.RangeError@std.algorithm(9429): Range violation "dstring[][dstring]" declaration looks a bit obscure to me... what do you intent with it, "array of maps" or "map of arrays"? Also, it looks unnatural that inside sorting lambda, you refer outside from it (back to providor_symbol_map variable). Ideally, you should only use variables x and y. Does D support sorting by map entries instead of by keys only or by values only?
std.algorithm range violation
an anyone explain me what I'm doing wrong here : [code] dstring[][dstring] providor_symbol_map; ... writeln(providor_symbol_map.keys.sort!((x,y)=>providor_symbol_map[x].length>=providor_symbol_map[y].length)); [/code] output: core.exception.RangeError@std.algorithm(9429): Range violation