Re: Using TreeSet and __gshared values
On Wednesday, 3 September 2014 at 20:10:51 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 03 Sep 2014 19:53:15 + nrgyzer via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: __gshared class members are effectively static, i.e. they are class members, not instance members. Hmm... would be nice if there were a warning/error when __gshared is used without static in a class.
Re: Using TreeSet and __gshared values
On Thu, 04 Sep 2014 08:38:50 + via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Hmm... would be nice if there were a warning/error when __gshared is used without static in a class. would you fill enhancement request in bugzilla? signature.asc Description: PGP signature
Re: basic question about adresses and values in structs
thanks! just what I needed, with some stumbling I managed to get everything working as intended: using a pointer variable to save an adres of a function, then dereferencing to use it. Now I am wondering when to use the ** ? for example I found this function over at https://github.com/d-gamedev-team/gfm/blob/master/core/gfm/core/memory.d void* storeRawPointerAndReturnAligned(void* raw, size_t alignment) nothrow { enum size_t pointerSize = size_t.sizeof; char* start = cast(char*)raw + pointerSize; void* aligned = nextAlignedPointer(start, alignment); void** rawLocation = cast(void**)(cast(char*)aligned - pointerSize); *rawLocation = raw; return aligned; } it's a little over my head yet..
Re: Using TreeSet and __gshared values
On Thursday, 4 September 2014 at 09:02:26 UTC, ketmar via Digitalmars-d-learn wrote: On Thu, 04 Sep 2014 08:38:50 + via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Hmm... would be nice if there were a warning/error when __gshared is used without static in a class. would you fill enhancement request in bugzilla? https://issues.dlang.org/show_bug.cgi?id=13421
Re: basic question about adresses and values in structs
On Thursday, 4 September 2014 at 09:54:57 UTC, nikki wrote: thanks! just what I needed, with some stumbling I managed to get everything working as intended: using a pointer variable to save an adres of a function, then dereferencing to use it. Now I am wondering when to use the ** ? for example I found this function over at https://github.com/d-gamedev-team/gfm/blob/master/core/gfm/core/memory.d void* storeRawPointerAndReturnAligned(void* raw, size_t alignment) nothrow { enum size_t pointerSize = size_t.sizeof; char* start = cast(char*)raw + pointerSize; void* aligned = nextAlignedPointer(start, alignment); void** rawLocation = cast(void**)(cast(char*)aligned - pointerSize); *rawLocation = raw; return aligned; } it's a little over my head yet.. void** (double ptr) is a pointer to array of pointers(just imagine a crossword where each horizontal letter is part of vertical word) there is little reason to use them in D, mostly to C/C++ interfacing
Intended behavior of std.range.cycle?
auto c = cycle([1,2,3]); foreach(i ; iota(-4,4)) { writeln(c[i]); } prints the sequence 1 2 3 1 1 - c[0] == c[-1] 2 3 I understand this is what would happen if I were to just use modulus on an index to access the original array, but should Cycle really mimic this behavior? I feel like most uses of Cycle would expect element -1 to be the last element of the original range, not the first. I could manually apply addition with modulus to ensure that the index is always positive, but then there's not much benefit to using cycle anyways -- I might as well be accessing the original range. Is this behavior intentional or an oversight?
Re: Intended behavior of std.range.cycle?
On Thursday, 4 September 2014 at 11:29:30 UTC, rcor wrote: auto c = cycle([1,2,3]); foreach(i ; iota(-4,4)) { writeln(c[i]); } prints the sequence 1 2 3 1 1 - c[0] == c[-1] 2 3 I understand this is what would happen if I were to just use modulus on an index to access the original array, but should Cycle really mimic this behavior? I feel like most uses of Cycle would expect element -1 to be the last element of the original range, not the first. I could manually apply addition with modulus to ensure that the index is always positive, but then there's not much benefit to using cycle anyways -- I might as well be accessing the original range. Is this behavior intentional or an oversight? Indexing is done with the unsigned size_t. You aren't indexing at -1, but rather, size_t.max. size_t.max % 3 probably doesn't result in 3 - 1 hence what you are observing. *Should* cycle be negatively index-able? Personally, I don't think so. And even if it could, it has been proven non-size_t indexing is not well supported at all. It was de-facto chosen after the iota-map fiasco that all ranges be indexed with size_t and nothing else...
Re: Intended behavior of std.range.cycle?
On Thursday, 4 September 2014 at 11:43:28 UTC, monarch_dodra wrote: Indexing is done with the unsigned size_t. I re-read your post, and I don't think I actually answered your question...? I don't know of any case where you'd want to index negativelly. That said, I'm sure it could be possible to wrap a cycle into a simple signed cycle adaptor. There's one issue with what you want to do though: Who is front, and where does your range start?
Re: literate programming in D
On Friday, 29 August 2014 at 23:41:00 UTC, bearophile wrote: nikki: I use it to change my d sourcefile slightly (into valid markdown) then I use a node module (ghmd) to make sortof sexy html from that. Are you going to add popups of the types as in the F# page I have linked? Bye, bearophile Slowly an idea is forming to try to write the whole thing using D and vibe.d instead of a tiny D script and alot of prewritten JS, I think I like the popups and I imagine the data that would go in those popups would be findable at the standard ddoc location for every function class and etc. So I guess I might eventually ;)
Re: literate programming in D
I should have read your post more carefully, the 'tagging' in the code is not really what I am after, I want the file including the documentation to just be a valid d file, does'nt mean however that there aren't ways of solving the issue without such precise tagging I guess
Re: basic question about adresses and values in structs
On 09/04/2014 02:54 AM, nikki wrote: a pointer variable to save an adres of a function, then dereferencing to use it. If possible, even in C, I would recommend using a 'function pointer' for that. However, there are cases where the signature of the function should be unknown to the code that is storing it so a void* is used. (Note that, as discussed on these forums in the past, void* has always been intended to be a data pointer. The fact that it works for function pointers is something we get as lucky accidents, which will most probably always supported by compilers and CPUs.) Here is how D does function pointers: http://dlang.org/expression.html#FunctionLiteral And a chapter that expands on those: http://ddili.org/ders/d.en/lambda.html Now I am wondering when to use the ** ? The simple answer is when dealing with the address of a type that is 'void*' itself. In other words, there is nothing special about **: It appears as the type that is a pointer to a pointer. Inserting spaces: int * p; // A pointer to an int void* * q;// A pointer to a void* // (untested) static assert (is (typeof(*p) == int)); static assert (is (typeof(*q) == void*)); int i; *p = i;// Can store an int void* v; *q = v;// Can store a void* Ali
Re: basic question about adresses and values in structs
On Thursday, 4 September 2014 at 14:00:14 UTC, Ali Çehreli wrote: On 09/04/2014 02:54 AM, nikki wrote: a pointer variable to save an adres of a function, then dereferencing to use it. If possible, even in C, I would recommend using a 'function pointer' for that. However, there are cases where the signature of the function should be unknown to the code that is storing it so a void* is used. (Note that, as discussed on these forums in the past, void* has always been intended to be a data pointer. The fact that it works for function pointers is something we get as lucky accidents, which will most probably always supported by compilers and CPUs.) ... Ali Ah right I was so busy with these * and ;) Thanks!
Re: writeln() assertion failed in hybrid x64
I'm having an error related to yours: when I call writeln function in a closed stdout I will get a segfault message. Example: import std.stdio; void main() { stdout.close(); write(hello\n); } The code above will crash with segfault buf the following code will raise an exception instead: import std.stdio; void main() { stdout.close(); stdout.write(hello\n); } In one of the specializations of the write function in the std.stdio (the call site that you showed in your post) no check for closed stdout (when stdout._p is null) is done. I can't say if this is a bug in the write function or the desired behaviour (I'm a novice here). On Wednesday, 3 September 2014 at 18:48:00 UTC, Szymon Gatner wrote: On Wednesday, 3 September 2014 at 09:55:55 UTC, Szymon Gatner wrote: Hey, I am trying to build hybrid (C++, D) application (more here: http://forum.dlang.org/thread/ugkpqprobonorbdun...@forum.dlang.org) but I am now getting assertion failure from within writeln(). writeln() is called from a D function that has C++ linkage: D definition: extern (C++) void printSomething() { writeln(hello from D); } usage from C++: extern C++ void printSomething(); int main() { DRuntime druntime; // rt_init(), rt_term() printSomething(); } this causes run-time assertion in fprintf() called from within writeln(): int __cdecl fprintf ( FILE *str, const char *format, ... ) /* * 'F'ile (stream) 'PRINT', 'F'ormatted */ { va_list(arglist); FILE *stream; int buffing; int retval=0; _VALIDATE_RETURN( (str != NULL), EINVAL, -1); === assetion here [...] } meaning that str arg passed is null. writelns()'s call site: enforce(fprintf(.stdout._p.handle, %.*s\n, cast(int) args[0].length, args[0].ptr) = 0); so for some reason .stdout._p.handle is null. Any ideas why this happens?
Re: writeln() assertion failed in hybrid x64
On Thu, 04 Sep 2014 15:10:21 + Jorge A. S. via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: In one of the specializations of the write function in the std.stdio (the call site that you showed in your post) no check for closed stdout (when stdout._p is null) is done. I can't say if this is a bug in the write function or the desired behaviour (I'm a novice here). it's definitely a bug. writeln() should throw, not segfaulting. signature.asc Description: PGP signature
Re: Intended behavior of std.range.cycle?
On Thursday, 4 September 2014 at 11:58:58 UTC, monarch_dodra wrote: On Thursday, 4 September 2014 at 11:43:28 UTC, monarch_dodra wrote: Indexing is done with the unsigned size_t. I re-read your post, and I don't think I actually answered your question...? I don't know of any case where you'd want to index negativelly. That said, I'm sure it could be possible to wrap a cycle into a simple signed cycle adaptor. There's one issue with what you want to do though: Who is front, and where does your range start? To give more detail: I've been working on a strategy game. The player has 'next' and 'previous' buttons they can use to cycle between units they haven't moved yet. I thought it would be cleaner to use a Cycle than to have the extra math necessary to wrap the index (its not that the math is terribly complicated, but it just makes things messier and less obvious). In this case, front is arbitrarily chosen based on the order in which the units were loaded. It doesn't really matter who is front as long as each press of 'next' or 'previous' jumps to a new unit. The negative index occurs when the player has unit 0 selected and presses 'previous'. Instead of jumping to the previous unit, the cursor sticks on the same unit (at least in the situation where size_t.max % numUnits == 0). It's not a huge deal to work around it in my own code, but I figured I should point it out in case this was unintentional.
dub github dependencies?
how i can specify github repo branch? i've already tried adding everything i have in mind but no luck so far. so in theory it should be like this: -- dub.json dependencies: { cairod: {version: ~ReworkWin32, path: https://github.com/evilrat666/cairoD.git} } but it says missing package description, while it obviuosly there... any suggestions? i know i could use local clone but what if someone else need to use it?
Re: Should formattedWrite take the outputrange by ref?
On Wednesday, 3 September 2014 at 07:43:20 UTC, Guillaume Chatelet wrote: +1 I've been bitten by this also. Same here, +1
Re: Should formattedWrite take the outputrange by ref?
On Thursday, 4 September 2014 at 17:06:00 UTC, Márcio Martins wrote: On Wednesday, 3 September 2014 at 07:43:20 UTC, Guillaume Chatelet wrote: +1 I've been bitten by this also. Same here, +1 It's still on my radar, but it's actually not that trivial of a change, especially if we want to avoid breaking code, and binary bloat...
Re: dub github dependencies?
On Thursday, 4 September 2014 at 16:43:13 UTC, evilrat wrote: how i can specify github repo branch? i've already tried adding everything i have in mind but no luck so far. so in theory it should be like this: -- dub.json dependencies: { cairod: {version: ~ReworkWin32, path: https://github.com/evilrat666/cairoD.git} } but it says missing package description, while it obviuosly there... any suggestions? i know i could use local clone but what if someone else need to use it? Packages have to exist on http://code.dlang.org/
Re: writeln() assertion failed in hybrid x64
On Thursday, 4 September 2014 at 15:25:59 UTC, ketmar via Digitalmars-d-learn wrote: On Thu, 04 Sep 2014 15:10:21 + Jorge A. S. via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: In one of the specializations of the write function in the std.stdio (the call site that you showed in your post) no check for closed stdout (when stdout._p is null) is done. I can't say if this is a bug in the write function or the desired behaviour (I'm a novice here). it's definitely a bug. writeln() should throw, not segfaulting. Shouldn't writeln() work tho instead of throwing or segfaulting?
Re: writeln() assertion failed in hybrid x64
On Thursday, 4 September 2014 at 17:57:47 UTC, Szymon Gatner wrote: On Thursday, 4 September 2014 at 15:25:59 UTC, ketmar via Digitalmars-d-learn wrote: On Thu, 04 Sep 2014 15:10:21 + Jorge A. S. via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: In one of the specializations of the write function in the std.stdio (the call site that you showed in your post) no check for closed stdout (when stdout._p is null) is done. I can't say if this is a bug in the write function or the desired behaviour (I'm a novice here). it's definitely a bug. writeln() should throw, not segfaulting. Shouldn't writeln() work tho instead of throwing or segfaulting? No, if stdout is closed, how should it work? Throwing is the correct behaviour.
Re: writeln() assertion failed in hybrid x64
On Thursday, 4 September 2014 at 18:22:55 UTC, Marc Schütz wrote: On Thursday, 4 September 2014 at 17:57:47 UTC, Szymon Gatner wrote: On Thursday, 4 September 2014 at 15:25:59 UTC, ketmar via Digitalmars-d-learn wrote: On Thu, 04 Sep 2014 15:10:21 + Jorge A. S. via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: In one of the specializations of the write function in the std.stdio (the call site that you showed in your post) no check for closed stdout (when stdout._p is null) is done. I can't say if this is a bug in the write function or the desired behaviour (I'm a novice here). it's definitely a bug. writeln() should throw, not segfaulting. Shouldn't writeln() work tho instead of throwing or segfaulting? No, if stdout is closed, how should it work? Throwing is the correct behaviour. Ah sorry, I totaly missed close() part. Any idea why it is null in my case tho?
Re: literate programming in D
Ah that sounds interesting too! Immediately I start thinking in terms like tidlywiki http://tiddlywiki.com/ or something similar, I guess the emacs way described earlier also would support this. I personally always enjoy reading the readthedocs stuff http://docs.readthedocs.org/en/latest/ is that the sort of stuff you mean? Tiddlywiki is interesting, but I'm really talking about the way LP was used by Knuth WEB/CWEB in his explanation of TeX and METAFONT. The Wikipedia article explains it pretty well (http://en.wikipedia.org/wiki/Literate_programming) You write a document combining documentation and code. Then two different programs (weave and ? for WEB) create the resulting documentation for one (HTML, pdf, whatever) and the code (a .d file) for another. I discovered LP through the incredible book Physically-based Ray-Tracing. The book is one program, explained and documented using literate progamming. It's an incredible achievement (1000+ pages of explanations!). See: www.pbrt.org and more precisely: http://www.pbrt.org/chapters/pbrt_chapter7.pdf The code begins at page 18 of the pdf. For example, at page 22: Sample Method Definitions ≡ Sample::Sample(SurfaceIntegrator *surf, VolumeIntegrator *vol, const Scene *scene) { surf-RequestSamples(this, scene); vol-RequestSamples(this, scene); Allocate storage for sample pointers 301 Compute total number of sample values needed 302 Allocate storage for sample values 302 } The snippet Sample Method Definitions introduces three new snippets, that will be explained elsewhere. Other snippets might also use the same references, if needed. It's not complicated to write a D tool for that, I did that some time ago. Once you define your begin/end token for snippet definitions, you can parse them to extract the way they are linked.
Re: Building a string from n chars
On Wednesday, 3 September 2014 at 20:46:40 UTC, monarch_dodra wrote: Is there a simpler way to way to s ~= repeat('*', n).array.to!string; if s has to be of type string? s ~= repeat('*', n).array(); Should be enough. Why the to!string? You're correct. The .to!string was unnecessary.
opSlice() or opIndex() for the entire slice?
The documentation says To overload a[], simply define opIndex with no parameters: http://dlang.org/operatoroverloading.html#Slice And it works with some uses of a[]. However, opSlice() seems to be needed to actually use the returned slice further. Note that opSlice() also seems to be for backward compatibility: For backward compatibility, a[] and a[i..j] can also be overloaded by implementing opSlice() with no arguments and opSlice(i, j) with two arguments, respectively. This only applies for one-dimensional slicing, and dates from when D did not have full support for multidimensional arrays. This usage of opSlice is discouraged. How can I achieve the last line in main() without needing opSlice()? I am trying to let the Slice type handle opAssign() and friends. import std.stdio; struct Collection { int[] elements; /* Handles the slice operations */ struct Slice { int[] slice; Slice opAssign(int value) { slice[] = value; return this; } } Slice opIndex() { writeln(opIndex); return Slice(elements); } Slice opSlice() { writeln(opSlice); return Slice(elements); } } void main() { auto c = Collection([ 0, 1, 2, 3]); // This works with either operator but opIndex is favored. (You can // comment out opSlice() and it will still work.) writeln(c[]); // This requires opSlice. c[] = 42; } Ali
Re: opSlice() or opIndex() for the entire slice?
On Thursday, 4 September 2014 at 19:12:27 UTC, Ali Çehreli wrote: The documentation says To overload a[], simply define opIndex with no parameters: http://dlang.org/operatoroverloading.html#Slice And it works with some uses of a[]. However, opSlice() seems to be needed to actually use the returned slice further. Note that opSlice() also seems to be for backward compatibility: For backward compatibility, a[] and a[i..j] can also be overloaded by implementing opSlice() with no arguments and opSlice(i, j) with two arguments, respectively. This only applies for one-dimensional slicing, and dates from when D did not have full support for multidimensional arrays. This usage of opSlice is discouraged. How can I achieve the last line in main() without needing opSlice()? I am trying to let the Slice type handle opAssign() and friends. --8-- snip --8-- // This requires opSlice. c[] = 42; } Have you tried opIndexAssign()?
Re: Building a string from n chars
On Wednesday, 3 September 2014 at 20:20:09 UTC, Meta wrote: Does this work? s ~= *.replicate(n); Yes, thanks. So what's best? type ~= '*'.repeat(pointerCount).array; or type ~= *.replicate(pointerCount); ? Further, -vgc says only ~= will allocate: t_repeat_replicate.d(12,19): vgc: operator ~= may cause GC allocation t_repeat_replicate.d(13,19): vgc: operator ~= may cause GC allocation Is DMD/Phobos already that clever!? :=)
Re: Building a string from n chars
On Thursday, 4 September 2014 at 19:22:42 UTC, Nordlöw wrote: Is DMD/Phobos already that clever!? Further -vgc has nothing to say about string t1; t1 ~= '*'.repeat(n).array; string t2; t2 ~= *.replicate(n); .
Allowing Expressions such as (low value high)
Are there any programming languages that extend the behaviour of comparison operators to allow expressions such as if (low value high) ? This syntax is currently disallowed by DMD. I'm aware of the risk of a programmer misinterpreting this as if ((low value) high) Is this the reason why no languages (including D allows it). I'm asking for in some cases, where value is a long expression, it would be a nice syntatic sugar to use.
Re: Allowing Expressions such as (low value high)
On Thursday, 4 September 2014 at 20:03:57 UTC, Nordlöw wrote: Are there any programming languages that extend the behaviour of comparison operators to allow expressions such as if (low value high) ? This syntax is currently disallowed by DMD. I'm aware of the risk of a programmer misinterpreting this as if ((low value) high) Is this the reason why no languages (including D allows it). I'm asking for in some cases, where value is a long expression, it would be a nice syntatic sugar to use. In the case of D, it's a C compatibility thing. Other languages I don't know.
Re: Allowing Expressions such as (low value high)
On Thursday, 4 September 2014 at 20:03:57 UTC, Nordlöw wrote: if (low value high) An alternative could be if (value in low..high) but then the problem would be to remember that this range is actually [low..high[ to be compliant with range indexing semantics. But it could still be a useful a quite self-explanatory syntax.
Re: Allowing Expressions such as (low value high)
On Thursday, 4 September 2014 at 20:25:52 UTC, monarch_dodra wrote: In the case of D, it's a C compatibility thing. Other languages I don't know. FYI, auto x = 1 2 3; as C++ is accepted (but warned about) by GCC as x.cpp:19:20: warning: comparisons like ‘X=Y=Z’ do not have their mathematical meaning [-Wparentheses] auto x = 1 2 3; Clang gives no warning.
Re: How to get nogc to work with manual memory allocation
On Sunday, 24 August 2014 at 13:27:01 UTC, Jacob Carlborg wrote: On 2014-08-24 14:18, Kagamin wrote: Shouldn't emplace and destroy infer their attributes instead of strictly annotating them as nogc. If they are templates, I guess they should. I don't know how good the compiler is at inferring attributes. I also haven't looked at the source code for these functions so I don't know if there's anything stopping them from begin @nogc. emplace calls constructor, and constructor can't be realistically required to be nogc. It depends on the constructor. Similar for destroy.
Re: writeln() assertion failed in hybrid x64
Maybe some module constructor wasn't run due to linking mess. So it remains uninitialized.
Re: Building a string from n chars
On Thursday, 4 September 2014 at 19:24:00 UTC, Nordlöw wrote: string t1; t1 ~= '*'.repeat(n).array; string t2; t2 ~= *.replicate(n); After having read http://dlang.org/phobos/std_array.html#.replicate I came to the conclusion that the lazy std.range:repeat is preferred. I'm still a bit confused about the fact that -vgc gives no warnings about GC-allocations, though.
Re: writeln() assertion failed in hybrid x64
On Thursday, 4 September 2014 at 20:38:38 UTC, Kagamin wrote: Maybe some module constructor wasn't run due to linking mess. So it remains uninitialized. Is there a way I can check if module c-tor run? rt_init() returned no error.
Re: Allowing Expressions such as (low value high)
On 9/4/14, 5:03 PM, Nordlöw wrote: Are there any programming languages that extend the behaviour of comparison operators to allow expressions such as if (low value high) ? This syntax is currently disallowed by DMD. I'm aware of the risk of a programmer misinterpreting this as if ((low value) high) Is this the reason why no languages (including D allows it). I'm asking for in some cases, where value is a long expression, it would be a nice syntatic sugar to use. Crystal has that syntax: ~~~ def foo puts Computing! a = 0 10.times do |i| a += i end a end if 0 foo = 45 puts Yes end ~~~ Prints: Computing! Yes That's because the middle expression in the comparison is first assigned to a temporary variable, so `foo` is only invoked once. This makes both the code more readable, efficient and saves the programmer from having to save that value to a temporary variable itself. I guess D doesn't have it because it has (...why?) to be compatible with C's semantic. Also, as you can see, it's not that trivial to implement because you need to assign that value first to a temporary variable.
Re: writeln() assertion failed in hybrid x64
https://github.com/D-Programming-Language/druntime/blob/master/src/core/stdc/stdio.d#L457 see? It's null. Hmm... where is it initialized?
Re: writeln() assertion failed in hybrid x64
https://github.com/D-Programming-Language/druntime/blob/master/src/rt/dmain2.d#L270 well, this sucks.
Re: Building a string from n chars
On Thursday, 4 September 2014 at 20:38:39 UTC, Nordlöw wrote: On Thursday, 4 September 2014 at 19:24:00 UTC, Nordlöw wrote: string t1; t1 ~= '*'.repeat(n).array; string t2; t2 ~= *.replicate(n); After having read http://dlang.org/phobos/std_array.html#.replicate I came to the conclusion that the lazy std.range:repeat is preferred. If lazy is good enough for you yes. AFAIK, replicate is *very* close in terms of implementation to what a.repeat(n).array() would do anyways. Heck, I'd be surprised if it did it differently, since (again, AFAIK) repeat.array() is optimal anyways. I'm still a bit confused about the fact that -vgc gives no warnings about GC-allocations, though. Strange indeed. Both solutions allocate a slice, and then append that slice. The s[]='*' Solution I gave you will not create a temporary allocation.
Re: Building a string from n chars
On Thursday, 4 September 2014 at 20:57:43 UTC, monarch_dodra wrote: On Thursday, 4 September 2014 at 20:38:39 UTC, Nordlöw wrote: On Thursday, 4 September 2014 at 19:24:00 UTC, Nordlöw wrote: string t1; t1 ~= '*'.repeat(n).array; string t2; t2 ~= *.replicate(n); After having read http://dlang.org/phobos/std_array.html#.replicate I came to the conclusion that the lazy std.range:repeat is preferred. If lazy is good enough for you yes. AFAIK, replicate is *very* close in terms of implementation to what a.repeat(n).array() would do anyways. Heck, I'd be surprised if it did it differently, since (again, AFAIK) repeat.array() is optimal anyways. I re-read the doc and implementation: replicate replicates a *range*. It is a bit optimized to detect the case where the range is a single element, but it still has to do the check, and even then (implementation detail), it is less efficient. I might create a pull to tweak that.
Re: opSlice() or opIndex() for the entire slice?
On Thursday, 4 September 2014 at 19:12:27 UTC, Ali Çehreli wrote: The documentation says To overload a[], simply define opIndex with no parameters: http://dlang.org/operatoroverloading.html#Slice And it works with some uses of a[]. However, opSlice() seems to be needed to actually use the returned slice further. This must be new, as I've read that page several times, and have never seen that before. Furthermore, I've done a *lot* pulls to improve ranges' slicing capabilities, and no reviewer has ever mentioned this before.
Re: opSlice() or opIndex() for the entire slice?
On 09/04/2014 12:19 PM, Marc Schütz schue...@gmx.net wrote: On Thursday, 4 September 2014 at 19:12:27 UTC, Ali Çehreli wrote: The documentation says To overload a[], simply define opIndex with no parameters: http://dlang.org/operatoroverloading.html#Slice And it works with some uses of a[]. However, opSlice() seems to be needed to actually use the returned slice further. Note that opSlice() also seems to be for backward compatibility: For backward compatibility, a[] and a[i..j] can also be overloaded by implementing opSlice() with no arguments and opSlice(i, j) with two arguments, respectively. This only applies for one-dimensional slicing, and dates from when D did not have full support for multidimensional arrays. This usage of opSlice is discouraged. How can I achieve the last line in main() without needing opSlice()? I am trying to let the Slice type handle opAssign() and friends. --8-- snip --8-- // This requires opSlice. c[] = 42; } Have you tried opIndexAssign()? That works and kind of makes sense. My main confusion stems from the fact that the new templated opSlice() does not have its own section on the documentation page, other than appearing in examples of other operators. What I did not like about opIndexAssign() at first is the fact that it puts the Collection in the middle and requires an explicit dispatch by the programmer to Slice. In contrast, the legacy way (which still works) bypasses Collection and goes directly to Slice. However, the legacy way supports only one dimension. Also, the new way is necessary as the same function (namely, opIndexAssign) takes care of both indexing and slicing. This is from the change log: void opIndexAssign(A...)(E val, A indices) { assert(A.length == payload.length); foreach (dim, x; indices) { static if (is(typeof(x) : size_t)) { // this[..., x, ...] payload[dim][x] = val; } else { // this[..., x[0] .. x[1], ...] payload[dim][x[0] .. x[1]] = val; } } } So, the following is my current solution. Note that opIndex() seems still be necessary. Is it possible to replace it with an opSlice overload? import std.stdio; struct Collection { int[] elements; /* Handles the slice operations */ struct Slice { int[] slice; Slice opAssign(int value) { writefln(Slice.opAssign(int)); slice[] = value; return this; } } size_t opDollar() const { writefln(opDollar()); return elements.length; } // CHALLENGE: Can you replace this with an opSlice overload? Slice opIndex() { writefln(opIndex()); return Slice(elements); } Slice opSlice(size_t dim, A...)(A args) { writefln(opSlice!%s(%(%s, %)), dim, [ args ]); return Slice(elements[args[0] .. args[1]]); } Collection opIndexAssign(A...)(int value, A indexes) { writefln(opIndexAssign(%s, %(%s, %)), value, [ indexes ]); foreach (dim, x; indexes) { static if (is(typeof(x) : size_t)) { elements[x] = value; } else static if (is(typeof(x) : Slice)) { x = value; } else { static assert(false); } } return this; } } void main() { auto c = Collection([ 0, 1, 2, 3]); writeln(\n--- c[] ---); c[]; writeln(\n--- c[1 .. $-1] = 42 ---); c[1 .. $-1] = 42; writeln(\n--- c[3] = 100 ---); c[3] = 100; assert(c.elements == [ 0, 42, 42, 100 ]); } The output: --- c[] --- opIndex() --- c[1 .. $-1] = 42 --- opDollar() opSlice!0(1, 3) opIndexAssign(42, Slice([1, 2])) Slice.opAssign(int) --- c[3] = 100 --- opIndexAssign(100, 3) Ali
Re: Allowing Expressions such as (low value high)
On Thursday, 4 September 2014 at 20:45:41 UTC, Ary Borenszweig wrote: That's because the middle expression in the comparison is first assigned to a temporary variable, so `foo` is only invoked once. This makes both the code more readable, efficient and saves the programmer from having to save that value to a temporary variable itself. I guess D doesn't have it because it has (...why?) to be compatible with C's semantic. Also, as you can see, it's not that trivial to implement because you need to assign that value first to a temporary variable. D can also, in this case, do (or will do) common sub-expression elimination because it has a strict memory model (const and immutability) and function purity (template inference).
Re: Allowing Expressions such as (low value high)
On Thursday, 4 September 2014 at 22:02:20 UTC, Nordlöw wrote: D can also, in this case, do (or will do) common sub-expression elimination because it has a strict memory model (const and immutability) and function purity (template inference). Correction: foo cannot be pure in this case. But I believe your example is misguiding in this case. The most common use case for this is when foo is pure.
Re: Allowing Expressions such as (low value high)
On 09/04/2014 04:03 PM, Nordlöw wrote: Are there any programming languages that extend the behaviour of comparison operators to allow expressions such as if (low value high) ? This syntax is currently disallowed by DMD. I'm aware of the risk of a programmer misinterpreting this as if ((low value) high) Is this the reason why no languages (including D allows it). I'm asking for in some cases, where value is a long expression, it would be a nice syntatic sugar to use. Python has this as well: ``` def foo(): print Called foo return 10 if 0 = foo() = 50: print Success! ``` I agree that it would be convenient, though I think that this would cause less breakage: ``` if(x in 0..50) {} ``` -- Matt Soucy http://msoucy.me/
Re: opSlice() or opIndex() for the entire slice?
On 09/04/2014 02:04 PM, monarch_dodra wrote: On Thursday, 4 September 2014 at 19:12:27 UTC, Ali Çehreli wrote: The documentation says To overload a[], simply define opIndex with no parameters: http://dlang.org/operatoroverloading.html#Slice And it works with some uses of a[]. However, opSlice() seems to be needed to actually use the returned slice further. This must be new, as I've read that page several times, and have never seen that before. Furthermore, I've done a *lot* pulls to improve ranges' slicing capabilities, and no reviewer has ever mentioned this before. Yeah, there is something fishy with these operators. Please see my other post. It seems like opIndex() is necessary or at least more convenient. Ali
Re: Allowing Expressions such as (low value high)
On 9/4/14, 7:03 PM, Nordlöw wrote: On Thursday, 4 September 2014 at 22:02:20 UTC, Nordlöw wrote: D can also, in this case, do (or will do) common sub-expression elimination because it has a strict memory model (const and immutability) and function purity (template inference). Correction: foo cannot be pure in this case. But I believe your example is misguiding in this case. The most common use case for this is when foo is pure. No, why? ~~~ min_alert_level = 5 max_alert_level = 10 if min_alert_level compute_current_alert_level max_alert_level send_email end ~~~ I don't see anything wrong with that code.
Re: Allowing Expressions such as (low value high)
On Thu, 04 Sep 2014 20:29:08 + Nordlöw via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: On Thursday, 4 September 2014 at 20:03:57 UTC, Nordlöw wrote: if (low value high) An alternative could be if (value in low..high) and then we need new overload for 'in' operator... signature.asc Description: PGP signature
Re: How to get nogc to work with manual memory allocation
On Sunday, 24 August 2014 at 08:03:11 UTC, Bienlein wrote: Hello, I was having a look at the new nogc annotation and therefore wrote some code that creates an instance on the heap bypassing the GC (code adapted from http://dpaste.dzfl.pl/2377217c7870). Problem is that calls to call the class' constructor, destructor and others can't be called anymore once nogc is used. So the question is how to get manual allocation and deallocation done with using nogc. Here is the experimental code: @nogc T nogcNew(T, Args...) (Args args) { import std.conv : emplace; import core.stdc.stdlib : malloc; // get class size of class object in bytes auto size = __traits(classInstanceSize, T); // allocate memory for the object auto memory = malloc(size)[0..size]; if(!memory) { import core.exception : onOutOfMemoryError; onOutOfMemoryError(); } // call T's constructor and emplace instance on // newly allocated memory return emplace!(T, Args)(memory, args); } @nogc void nogcDel(T)(T obj) { import core.stdc.stdlib : free; // calls obj's destructor destroy(obj); // free memory occupied by object free(cast(void*)obj); } @nogc void main() { TestClass test = nogcNew!TestClass(); test.x = 123; nogcDel(test); test.x = 456; // no protection violation ?! // remove @nogc to run this TestClass t = new TestClass(); t.x = 789; delete t; t.x = 678; // protection violation as expected } I have omitted the code for the TestClass class to save space. Problem is that the compiler outputs this: Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' cannot call non-@nogc function 'core.exception.onOutOfMemoryError' Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' cannot call non-@nogc function 'std.conv.emplace!(TestClass, ).emplace' Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' cannot call non-@nogc function 'object.destroy!(TestClass).destroy' Is there a way to get around this? Then the test.x = 456; did not cause a protection violation although the instance was deallocated before calling nogcDel. Something with the deallocation in nogcDel seems not to work. Some hint appreciated on this. When calling delete t the protection violation happens on the next line as expected. Thanks a lot, Bienlein @nogc is *no GC*, it has nothing to do with where you allocate from, no matter how some would choose to interpret it (I use it to mean 'no heap' pretty often in my own projects, though, can be useful). You can mark it @nogc by wrapping the non-@nogc stuff in a function and casting it, but you *absolutely* must be sure GC is not used in any called functions. You could possibly do that by requiring T's constructor to be @nogc, not sure if the other functions can use GC or not. Also, your function seems to be written only for classes, if this is intended, you should have an if(is(T == class)) template constraint there.
Mutable array with fixed length
How would you create a mutable array with a fixed(compile error when trying to change) length.
Re: dub github dependencies?
On Thursday, 4 September 2014 at 17:22:42 UTC, Gary Willoughby wrote: On Thursday, 4 September 2014 at 16:43:13 UTC, evilrat wrote: how i can specify github repo branch? i've already tried adding everything i have in mind but no luck so far. so in theory it should be like this: -- dub.json dependencies: { cairod: {version: ~ReworkWin32, path: https://github.com/evilrat666/cairoD.git} } but it says missing package description, while it obviuosly there... any suggestions? i know i could use local clone but what if someone else need to use it? Packages have to exist on http://code.dlang.org/ not really, first off, cairod already in dub registry, and second, you can set path to anywhere on local FS as long as it is dub package(how do you suppose subpackages work then?), but unfortunately it doesn't works with github that way.
Re: Mutable array with fixed length
On Fri, 05 Sep 2014 00:26:07 + Freddy via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: How would you create a mutable array with a fixed(compile error when trying to change) length. Static arrays have a fixed length and live on the stack. int[12] arr; Dynamic arrays have a mutable length and the memory that they refer to normally lives on the heap (though they can be slices of static arrays or any two pointers). int[] arr = new int[](12); If the array is fully const or immutable immutable(int[]) arr = new immutable(int[])(12); then its length can't be mutated, whereas if the elements are const or immutable but the array is not const(int)[] = new const(int)[](12); then the length can mutated but the elements cannot be. However, because const and immutable are transitive, there is no way to have an array whose elements are mutable but have the array itself (and thus its length) be const or immutable. So, to get what you want, you're probably going to have to create a wrapper struct that forwards all of the operations that you want and doesn't expose the ones you don't (e.g. length). - Jonathan M Davis