Re: Struct that destroys its original handle on copy-by-value
On Wednesday, 29 July 2015 at 19:10:36 UTC, Adam D. Ruppe wrote: On Sunday, 26 July 2015 at 12:16:30 UTC, Joseph Rushton Wakeling wrote: My aim by contrast is to _allow_ that kind of use, but render the original handle empty when it's done. I don't think D offers any way to do that. With the disabled postblit, you can force people into a method you write that returns a new copy and clears the original, but that won't just work with assignment. The ref assign might not be forbidden by the written doc but I'm guessing that is just an oversight - struct assignment in D never clears the original, it is always a simple copy (perhaps plus other code) Slightly OT, but this is something that would be possible with a copy constructor, I think?
Re: Template function that accept strings and array of strings
On Wednesday, 15 July 2015 at 21:57:50 UTC, badlink wrote: Hello, I can't figure how to write a template function that accept either strings or array of strings. This is my current code: bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char) || (isArray!T is(typeof(T[]) == char))) {...} I used const(T)[] because I'd like to accept immutable and mutable strings. But calling it with an immutable string generate this error: Error: template cache.MetadataCache.hasItemParent cannot deduce function from argument types !()(string, string), candidates are: cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(typeof(T) == char)) Any suggestions ? T is already a type, so typeof(T) is an error, which makes the constraint fail. Try hasItemParent(T)(const(char)[] itemId, const(T)[] parentId) if (is(T == char) || is (T == char[])) at least I think that's what you meant. typeof(anything[]) will never == char.
Re: turning an array of structs into a struct of arrays
On Sunday, 5 July 2015 at 00:07:59 UTC, Laeeth Isharc wrote: Posted short write-up here. Please make it better... http://wiki.dlang.org/Transforming_slice_of_structs_into_struct_of_slices In John Colvin's solution, should alias TransformMembers(alias TypeTransform, alias NameTransform, T) = Tuple!( RoundRobin!(Pack!(staticMap!(TypeTransform, FieldTypeTuple!PriceBar)), Pack!(staticMap!(NameTransform, FieldNameTuple!PriceBar; read alias TransformMembers(alias TypeTransform, alias NameTransform, T) = Tuple!( RoundRobin!(Pack!(staticMap!(TypeTransform, FieldTypeTuple!T)), Pack!(staticMap!(NameTransform, FieldNameTuple!T; ???
documenting compile-time constants
How do I ddoc an enum constant? Putting ddoc comments above functions and structs woorks fine but ddocing an enum constant doesn't generate any documentation.
Re: documenting compile-time constants
On Tuesday, 7 July 2015 at 03:30:40 UTC, Rikki Cattermole wrote: On 7/07/2015 1:05 p.m., Vlad Levenfeld wrote: How do I ddoc an enum constant? Putting ddoc comments above functions and structs woorks fine but ddocing an enum constant doesn't generate any documentation. If: /// enum MyValue = 8.2f; does not generate documentation upon its creation, please file a bug. If: /// enum MyEnum { /// MYValue = 8.2f } does not generate documentation upon its creation, please file a bug. If: /// enum MyEnum { MYValue = 8.2f } does not generate documentation upon its creation, please see the previous answer. Ok, done. https://issues.dlang.org/show_bug.cgi?id=14778
Re: std.parallelism and multidimensional arrays
On Friday, 22 May 2015 at 10:54:36 UTC, Stefan Frijters wrote: I have a code which does a lot of work on 2D/3D arrays, for which I use the 2.066 multidimensional slicing syntax through a fork of the Unstandard package [1]. Many times the order of operations doesn't matter and I thought I would give the parallelism module a try to try and get some easy speedups (I also use MPI, but that has some additional overhead). The way I currently have my foreach loops set up, p is a size_t[2], the payload of the array v is double[9] and the array is indexed directly with a size_t[2] array and all works fine: foreach(immutable p, ref v, arr) { double[9] stuff; arr[p] = stuff; } If I naively try foreach(immutable p, ref v, parallel(arr)) { ... } I first get errors of the type Error: foreach: cannot make v ref. I do not understand where that particular problem comes from, but I can possibly live without the ref, so I went for foreach(immutable p, v, parallel(arr)) { ... } Which gets me Error: no [] operator overload for type (complicated templated type of some wrapper struct I have for arr). I'm guessing it doesn't like that there is no such thing as a simple one-dimensional slicing operation for a multidimensional array? Should I define an opSlice function that takes the usual two size_t arguments for the upper and lower bounds and doesn't require a dimension template argument and somehow map this to my underlying two-dimensional array? Will it need an opIndex function that takes only takes a single size_t as well? Or is this just taking the simple parallel(...) too far and should I try to put something together myself using lower-level constructs? Any hints would be appreciated! [1] http://code.dlang.org/packages/unstandard I'd define a flatten range adaptor that presents n-dimensional ranges as 1d range that traverses the original array indices lexicographically, if that makes sense for your app.
Re: functors with template lambdas
On Saturday, 16 May 2015 at 02:08:09 UTC, weaselcat wrote: On Saturday, 16 May 2015 at 02:06:45 UTC, weaselcat wrote: very long standing compiler bug https://issues.dlang.org/show_bug.cgi?id=3051 see also https://issues.dlang.org/show_bug.cgi?id=5710 unsure if they're duplicate bugs, never really looked into it. Yeah it looks like the bugs come from the same root cause. http://wiki.dlang.org/DIP30 Also, this came up during the discussion of the latter bug. Its still in Draft status. Haven't read it carefully enough yet to tell whether or not it would be helpful. GDC rejects this code as well. I dunno about LDC. BUT!! I found a way to make this pattern, at least, work as intended. I expected a symbol resolution error from the following code but was very pleased to find that it compiles: module ffunc; struct F (T) { T a; } auto ref fmap (alias f, T)(auto ref F!T x) { return F!T (f(x.a)); } --- module gfunc; struct G (T) { T a; } auto ref fmap (alias f, T)(auto ref G!T x) { return G!T (f(x.a)); } --- import ffunc; import gfunc; auto ref identity (T)(auto ref T a) { return a; } void main () { F!int a; G!int b; a.fmap!identity; b.fmap!identity; static auto id (T)(T x) {return x;} a.fmap!id; b.fmap!id; a.fmap!((int x) = x); b.fmap!((int x) = x); a.fmap!(x = x); b.fmap!(x = x); } Frankly this is even better than the original code, because now fmap can be defined after the functor, as a UFCS extension. Awesome!!
functors with template lambdas
I think this code should be allowed, but it isn't: struct Functor (T) { T a; auto ref fmap (alias f)() { return Functor (f(a)); } } auto ref identity (T)(auto ref T a) { return a; } void main() { Functor!int a; static auto id (T)(T x) {return x;} a.fmap!identity; // ok a.fmap!id; // ok a.fmap!((int x) = x); // ok a.fmap!(x = x); // Error: template instance fmap!((x) = x) cannot use local '__lambda1' as parameter to non-global template fmap(alias f)() } This seems like one of those things that doesn't work because of some compiler implementation detail rather than a consequence of the language rules but I'm not sure. Opinion?
anonymous template predicates
I was wondering if there's a mechanism to make anonymous templates, e.g. given: enum Policy {A, B} alias List = TypeTuple!(...); instead of this: enum has_policy_A (T) = T.policy == Policy.A; alias Result = Filter!(has_policy_A, List); use something like this: Filter!(T = T.policy == Policy.A, List); I've tried templates that generate eponymous predicates from mixed-in strings but these have a number of caveats that limit their usability.
Re: Private alias escaping -- is this a bug?
On Saturday, 25 April 2015 at 23:51:05 UTC, rcorre wrote: I ran into this infuriatingly confusing situation just now: static assert(is(typeof(Parent.init.new Child) == Parent.Child)); // fine alias P = Parent; alias T = Parent.Child; static assert(is(typeof(P.init.new T) == T)); // nope! Wat??? After much confusion, I finally discovered this in my class: class Parent { class Child { } mixin MyMixin; } mixin Template MyMixin() { private alias T = ...; // the culprit! } Should the private alias be able to escape? Is this a bug or expected behavior? Also, is there a nice way to create template-level aliases in mixin templates that don't leak into the class? MyMixin generates multiple functions that all use T. You could namespace them in a sense by defining a nested struct that contains the aliases.
Re: how does isInputRange(T) actually work?
On Wednesday, 22 April 2015 at 21:22:43 UTC, Meta wrote: That makes sense. It seems to me that D has very... special but effective syntax. I'm having a hard time remembering all the keywords and expression forms (especially of IsExpression) but it's definitely a vast improvement over C++'s half baked pile of whatever. Thanks for the help, everyone. The `is` expression is complicated and has a bunch of different usage syntax, but it's like one of those little multitools. Complicated to figure out how to use, but extremely flexible and able to do a lot of cool things. Yeah, the `is` expression is one of my favorite D features. import std.container; template Substitute (T, U) { static if (is (T == F!V, alias F, V)) alias Substitute = F!U; } alias List = SList!int; static assert (is (Substitute!(List, char) == SList!char)); It's the little things.
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 07:01:27 UTC, Per Nordlöw wrote: On Tuesday, 21 April 2015 at 06:56:33 UTC, Per Nordlöw wrote: On Monday, 20 April 2015 at 13:49:41 UTC, John Colvin wrote: On Thursday, 16 April 2015 at 18:12:35 UTC, Nordlöw wrote: Is there a way to CT-query the arity of all opIndex and opSlice overloads? Further, this is slightly related to a way to query the dimensions of a data-type. If possible I would like to have a type trait for this. This type-trait could then be used both for this challenge but also for figuring out how to create randomized instances of multi-dimensional structures. This can be used for automatic generation of data instances of parameters in algorithm testing and benchmarking. template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else enum count_dim = i; } alias dimensionality = count_dim!(); } Then you throw in some more stuff to detect 1-dimensional cases.
Re: CT-String as a Symbol
As an aside, I've put a bit of work into the generic multidimensional containers problem lately and have an interface generating library as a result. https://github.com/evenex/autodata It's still in the nascent stages but contains a lot of tools for working with multidimensional structures. You can take a look at the definition in the spaces/ and topology/ folder (and the unittests in operators/) to get an idea of how it works - basically generates all the opIndex/opSlice stuff (with safety checks) under a unified system; end result being that you just write the business logic for your types, mixin the operators, and they will all interoperate with uniform semantics. The definitions for the types themselves tend to be very short and to-the-point as a result. I've taken old containers of mine whose defs were pushing 300 lines and reimplemented them in ~50 using the autodata operators. A full set of traits and multidim range compositions (map, zip, take, cycle, repeat) are present as well. A lot of them are full or partial reimplementations of Phobos stuff. It's pretty poorly documented (for now) but I'm happy to answer questions (and make documentation based on that) if you decide to check it out.
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 08:09:38 UTC, Per Nordlöw wrote: On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote: template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else enum count_dim = i; } alias dimensionality = count_dim!(); } Then you throw in some more stuff to detect 1-dimensional cases. Great! I guess a template restriction on opSlice would be in Place aswell. One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right? So, if the type is multidimensional, that means its using the new opIndex/opSlice syntax that was designed for multidimensional structures. So I know that, if dim 1, opSlice!i must be defined, and (assuming we are only working with integral indices here) I can instantiate it with opSlice!i (0,0). For other types, you would throw in a test for a length member, or for front, and know that you have a 1-dimensional type. Alternatively, if we're assuming only integral indices, a recursive attempt to get the typeof(opIndex (Repeat!(i, 0))) would probably handle all the opIndex-but-not-opSlice cases (but you still need to handle non-indexed ranges and D arrays specially).
Re: CT-String as a Symbol
template dimensionality (S) { template count_dim (uint i = 0) { static if (is (typeof(S.init.opSlice!i (0,0 enum count_dim = count_dim!(i+1); else static if (i == 0 (isInputRange!S || is (typeof(S.init[0]))) enum count_dim = 1; else enum count_dim = i; } alias dimensionality = count_dim!(); } Should work for any case I can think of (assuming integral indices).
Re: CT-String as a Symbol
On Tuesday, 21 April 2015 at 19:46:03 UTC, Nordlöw wrote: On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote: Then you throw in some more stuff to detect 1-dimensional cases. Could you please elaborate a bit? Well assuming the type is not multidimensional (does not define opSlice!i) then testing for input range primitives or opIndex(0) is probably enough to conclude that a type is 1d.
Re: About @ and UDA
On Wednesday, 15 April 2015 at 16:59:12 UTC, ketmar wrote: or make safe and company context keywords. along with body (oh, how i hate the unabilily to declare body member!) Ugh, yeah. Makes physics code awkward.
Re: alias this of non-public member
On Tuesday, 7 April 2015 at 19:17:41 UTC, Márcio Martins wrote: Proxy doesn't really help here :( Nothing will help you get around this. You have to expose a public member and alias to that. Try wrapping the access in a public zero-parameter member function.
Re: lambda code
On Thursday, 2 April 2015 at 19:27:21 UTC, John Colvin wrote: On Wednesday, 1 April 2015 at 23:29:00 UTC, Vlad Levenfeld wrote: On Tuesday, 31 March 2015 at 13:25:47 UTC, John Colvin wrote: On Tuesday, 31 March 2015 at 12:49:36 UTC, Vlad Levenfeld wrote: Is there any way (or could there be any way, in the future) of getting the code from lambda expressions as a string? I've noticed that if I have an error with a lambda that looks like, say x=x+a the error message will come up referring to it as (x) = x + a so some level of processing has already been done on the expression. Can I get at any of it during compilation? It would be useful for automatic program rewriting. Short answer: no. .codeof for functions is something I've wanted for ages, but no movement so far. :( On a more positive note, there's probably an OK way of achieving your particular goal without this. Do you have an example? Well I was just thinking of turning r[].map!(v = v.xy*2).zip (s[]).map!((v,t) = vec2(v.x*cos(t), v.y*sin(t))).to_vertex_shader (); or something like that, into a shader program. Right now I have to do it with strings: r[].vertex_shader!(`v`, q{ vec2 u = v.xy*2; gl_Position = vec2(v.x*cos(t), v.y*sin(t)); }); I just keep thinking that, if I have programs composed of individual processing stages, like auto aspect_ratio_correction (T,U)(T computation, U canvas) { return zip (computation, repeat (canvas.aspect_ratio, computation.length)) .map!((v, a_r) = v/a_r); } then it's so that I can put them in UFCS chains, so vec2[] vertices; float time; Display display; auto kernel = some_program (vertices[], time) .aspect_ratio_correction (display); is able to be run on the cpu or gpu and this decision must be made lazily: kernel[].array; // cpu kernel[].computed_on_gpu.array; // compute on gpu, read back to cpu So I'd like to turn place of execution into a lazily evaluated range adaptor, and maybe reduce the need to keep different cpu/gpu code for the same algorithms. This seems impossible without something like .codeof or, better yet, ASTs. I can already unwrap the type of a composed range to get at how its constructed, but I don't get any information on the functions that are involved with higher-order function adaptors. The idea of doing compile-time restructuring of these ufcs chains is interesting to me, but I feel like I only have half of what I need to give it a proper try.
Re: lambda code
On Tuesday, 31 March 2015 at 13:25:47 UTC, John Colvin wrote: On Tuesday, 31 March 2015 at 12:49:36 UTC, Vlad Levenfeld wrote: Is there any way (or could there be any way, in the future) of getting the code from lambda expressions as a string? I've noticed that if I have an error with a lambda that looks like, say x=x+a the error message will come up referring to it as (x) = x + a so some level of processing has already been done on the expression. Can I get at any of it during compilation? It would be useful for automatic program rewriting. Short answer: no. .codeof for functions is something I've wanted for ages, but no movement so far. :(
lambda code
Is there any way (or could there be any way, in the future) of getting the code from lambda expressions as a string? I've noticed that if I have an error with a lambda that looks like, say x=x+a the error message will come up referring to it as (x) = x + a so some level of processing has already been done on the expression. Can I get at any of it during compilation? It would be useful for automatic program rewriting.
reflect on this function
I'd like to do something like this: @reflexive @transitive bool relation (T)(T a, T b) out (result) { mixin(property_verification!result); } body { ... } which becomes out (result) { // generated from @reflexive assert (result == skip_contract!relation (b,a)); // generated from @transitive static typeof(result) c; if (result) assert (skip_contract!relation (b,c) == skip_contract!relation (a,c)); c = b; } or something like that. I don't see a way to get exactly this, but does anyone have any thoughts on something similar?
Re: reflect on this function
On Friday, 20 February 2015 at 22:44:35 UTC, ketmar wrote: can you go with `relationImpl` and mixin/template that generates `relation` with contract then? something like: @reflexive @transitive bool relationImpl (T)(T a, T b) { ... } alias relation = buildWithContracts!relationImpl; then you can simply call `relationImpl` in your out section. Yeah, this looks pretty good. As much as I hate the pimpl idiom, having a one-liner alias right next to the definition should minimize the eye-bleeding. Thanks!
Re: BigFloat?
On Tuesday, 17 February 2015 at 14:03:45 UTC, Kagamin wrote: On Tuesday, 17 February 2015 at 09:08:17 UTC, Vlad Levenfeld wrote: For my use case I'm less concerned with absolute resolution than with preserving the information in the smaller operand when dealing with large magnitude differences. What do you mean? As long as you don't change the operand, it will preserve its value. If you add or subtract two floating point numbers whose magnitudes differ, then the lower bits of the smaller operand will be lost in the result. If the magnitudes are different enough, then the result of the operation could even be equal to the larger operand. In vivo: http://dpaste.dzfl.pl/870c5e61d276
Re: BigFloat?
On Tuesday, 17 February 2015 at 08:05:49 UTC, Kagamin wrote: Periodic fractions. Or transcendental numbers, for that matter, but arbitrary != infinite. A max_expansion template parameter could be useful here. For my use case I'm less concerned with absolute resolution than with preserving the information in the smaller operand when dealing with large magnitude differences.
BigFloat?
We've got arbitrary precision integers, why not arbitrary precision floating point?
Re: function and variable
On Tuesday, 10 February 2015 at 03:59:22 UTC, Rikki Cattermole wrote: That's a bug. It should be using the function pointer. UFCS call should abide by the same scoping rules as anything else. https://issues.dlang.org/show_bug.cgi?id=14161 I thought that's how UFCS was explicitly designed? Global symbols only, yes?
Re: function and variable
On Tuesday, 10 February 2015 at 04:20:27 UTC, Fyodor Ustinov wrote: IMHO even if it is not a bug, it is a feature - it should not be compiled without notice. WBR, Fyodor. Agreed, should be a warning at least.
strange alias behavior
I'm expecting in this code http://dpaste.dzfl.pl/ee0d3cd31734 either line 8 should not compile, or lines 12 and 14 should have a totally different output. What's going on?
Re: Deducing a template retrun parameter type based on an assignment?
On Friday, 30 January 2015 at 06:35:31 UTC, Jeremy DeHaan wrote: I have a template fuction that looks like this: immutable(T)[] getString(T)() const if (is(T == dchar)||is(T == wchar)||is(T == char)) Basically, I was hoping that the type would be deduced based on the prameter that was being assigned to like so. string ret = thing.getString(); Apparently that does not work, though. I get informed that the type of the template is not able to be deduced. I'm curious as to why it was not able to deduce it on its own. Additionally, and I haven't run my code to try this yet, but giving T a default type compiled to my surprise. immutable(T)[] getString(T=char)() const if (is(T == dchar)||is(T == wchar)||is(T == char)) Is something like this supposed even to work? for template type deduction to work, you have to supply an argument. Your type signature would need to look like this: immutable(T)[] getString(T)(T arg) const and then T would be deduced from arg. But string ret = thing.getString(); won't compile because it is rewritten to getString(thing), but your getString function takes no runtime parameters. It looks like the signature I wrote earlier is what you actually want. As to your second example, it'll work fine. Basically your signature says only accept dchar, wchar or char, but if nothing's been specified, default to char. But if you rewrite getString to take one parameter, then the default template arg is redundant.
Re: Deducing a template retrun parameter type based on an assignment?
On Friday, 30 January 2015 at 07:13:09 UTC, Jeremy DeHaan wrote: That seems strange. I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to. It seems sensible to me, as changing string to auto would leave the type of the expression undefined. But maybe your expectation is a reasonable enhancement, I'll leave it for someone more knowledgeable than myself to judge. That is good to hear. It seemed like that was the way it would work, but I've never had to specify a default template parameter type. I'm hoping to avoid having to specify a template parameter, but it seems like it can't be helped if users want to get their string type as a wstring or dstring though. It doesn't seem too bad to me. I used a similar pattern quite recently to wrap glGetIntegeriv into gl.get!int. One way or another you'll have to specify the type, but if you want to cut down on redundant code then auto ret = thing.getString!wchar; is a good bet. And I'm fairly certain that since you're using a default param of char, auto ret = thing.getString; should compile and result in ret being a char string.
Re: using the full range of ubyte with iota
you can always write your own iota replacement, which will do [] and use ubytes, for example. writing that things is way easier than in C++. something like myIota!ubyte(0, 255), for example -- to make it visible that it emits ubytes. I think closedInterval!T (T left, T right) would be a nice name for it. What's this about !`[]` and std.range.uniform?? It's not in the documentation.
Re: Defining a static array with values in a range
On Thursday, 22 January 2015 at 05:56:40 UTC, tcak wrote: I want to define alphanumeric characters in an easy way. Something like that: char[] arr = ['a'..'z', 'A'..'Z', '0'..'9']; Though above example doesn't work. Is there any easy way to do this? I am trying to do something like EBNF definitions. So, I do not want to use loops, or define every single thing one by one by hand. This is interesting, I think this syntax would be pretty cool if it did work (I think it would work in foreach loops... at least it does with integers). Anyway, what you could do is define a static struct with slicing overloaded for chars, and have it return slices of a master char array or a generating function. Assume you called the struct C, then your char array declaration could looks something like join (C['a'..'z'], C['A'..'Z'], C['0'..'9']) It is a bit of up-front work, though it is maintainable. I'm also curious if there is indeed an easier way.
Re: import conflicts
I get this all the time with std.array.array (I use my own array implementations, but phobos' array seems to secretly creep in everywhere). I think its got to do with that private import visibility bug (https://issues.dlang.org/show_bug.cgi?id=314 or https://issues.dlang.org/show_bug.cgi?id=13096 I think) which, by the looks of it, should be getting a fix... soon? ish?
Re: Struggling with shared objects
That's real weird. In D:\D\dmd2\src\phobos\std\concurrency.d(13,13) 13,13 isn't a line number and static assertions should go off during compilation, not runtime.
Re: Example usage of the core.sync classes
On Saturday, 3 January 2015 at 15:44:16 UTC, Matt wrote: Right, I've been looking at core.atomic, but it has very little documentation, and it's territory I haven't explored, yet. Any chance of some pointers along the way? Could you be more specific about what you need help understanding? You can implement a very simple double buffer like so: synchronized final class DoubleBuffer (T) { T[][2] data; uint write_index; shared void swap () { atomicStore (write_index, (write_index + 1) % 2); (cast()this).buffer[write_index].clear; } shared @property write_buffer () { return (cast()this).buffer[write_index][]; } shared @property read_buffer () { return (cast()this).buffer[(write_index + 1) % 2][]; } } Just append to write_buffer, call swap, then read from read_buffer. Make sure you declare the instance shared. Benjamin's post links to a more robust and realistic implementation.
Re: Example usage of the core.sync classes
On Sunday, 4 January 2015 at 01:02:07 UTC, Matt wrote: What I mean is that I don't understand what atomicStore, atomicLoad, etc. actually DO, although in the case of the two mentioned, I can hazard a pretty good guess. The documentation doesn't exist to tell me how to use the functions found in the module. I've never used any atomic functions in any language before. Atomic operations are guaranteed to happen in one step. For example, x += 1 will load the value of x into a register, increment it by 1, then write the value back to memory, while atomicStore (x, x+1) will cause all three steps to be executed as if they were instantaneous. This prevents a thread writing to an address that another thread just read from, causing that thread's view of the data to be silently outdated (aka a race condition, because the final value of x depends on which thread writes first). However, thank you for the simple double buffered example, I do appreciate it. How would another thread gain access to the instance in use, though? Am I able to pass references to instances of this class via events? You can if they're shared. You can pass the reference via message, or have the reference exist at a location both threads have access to. The two @property functions in the example are meant to be used by the writing and reading thread, respectively. I go about the swap by letting the reader thread message the writer to inform it that it is ready for more data, at which point the writer thread is free to call .swap () once it is done writing (though you can do it the opposite way if you want). 'synchronized' is also something I'm clueless about, and again the D documentation doesn't help, as the section in the class documentation basically says synchronized classes are made of synchronized functions, without explaining what a synchronized function IS. The function section makes no mention of the synchronized keyword, either. A synchronized class has a hidden mutex, and any thread that calls a member method acquires the lock. The synchronized keyword isn't limited to classes, though - you can find a detailed description of synchronized's various uses here: http://ddili.org/ders/d.en/concurrency_shared.html Sorry, it feels like there's a load of stuff in the library and language to make multithreading easier, but with little to no explanation, so it feels like you're expected to already know it, unless I'm looking in the wrong places for my explanations. If I am, please do give me a kick, and point me in the right direction. Yeah, I think the docs are meant to be a reference if you already have in mind what you're looking for, and just need to know how to wire it up. I recommend Ali's book (linked in the previous paragraph) in general as its the most comprehensive and up-to-date explanation of the language as a whole that I've yet seen (and its free).
Re: Example usage of the core.sync classes
On Friday, 2 January 2015 at 17:39:19 UTC, Matt wrote: I'm trying to write a small 3D engine, and wanted to place the physics in a separate thread to the graphics, using events, possibly std.concurrency, to communicate between them. How, then, do I pass large amounts of data between threads? I'm thinking the physics world state (matrix for each object, object heirarchies, etc) being passed to the graphics thread for rendering. I'd assumed that I would use Mutex, or ReadWriteMutex, but I have no idea how to build code using these classes, if this is even the right way to go about this. I would really appreciate any pointers you can give. Many thanks My personal favorite method is to use the primitives in core.atomic with a double or triple buffer. To double buffer, keep two buffers in an array (data[][] or something) and an integer index that points to the active buffer, then use atomicStore to update active buffer index when you want to swap. Triple buffering can improve runtime performance at the cost of more memory, and in this case you will need two indices and two swap methods, one for the producer and another for the consumer. I use cas with a timed sleep to update the indices in this case. Take it with a grain of salt, I'm far from a pro, but this has worked well for me in the past. I can post some example code if you need it.
Re: Data Frames in D - let's not wait for linear algebra; useful today in finance and Internet of Things
Laeeth - I am not sure exactly what your needs are but I have a fairly complete solution for generic multidimensional interfaces (template-based, bounds checked, RAII-ready, non-integer indices, the whole shebang) that I have been building. Anyway I don't want to spam the forum if I've missed the point of this discussion, but perhaps we could speak about it further over email and you could give me your opinion? I'm at vlevenf...@gmail.com
Re: dub dustmite
No luck, unfortunately.
dub dustmite
I'm trying to reduce a bug with dub dustmite feature and I must be doing it wrong somehow, my regular dub output looks like this: source/experimental.d(2403): Error: struct experimental.Product!(int[], int[]).Product no size yet for forward reference ulong[2] source/experimental.d(2454): Error: template instance experimental.Product!(int[], int[]) error instantiating source/experimental.d(2462):instantiated from here: by!(int[], int[]) FAIL .dub/build/application-debug-linux.posix-x86_64-dmd_2067-44246AA2375AB6C7D895600135F734E4/ engine_vx executable Error executing command run: dmd failed with exit code 1. and then when I run this command dub dustmite ~/dubdust --compiler-regex=Product no size yet I get Executing dustmite... None = No object.Exception@dustmite.d(243): Initial test fails It seems like a pretty simple case, I'm not sure what's going on.
Re: windows linker error
On Tuesday, 25 November 2014 at 21:22:24 UTC, Vlad Levenfeld wrote: On Windows 7 I have built dmd (using the vcxproj), druntime (win64.mak) and phobos (win64.mak). I went into sc.ini and set the LINKCMD to point to Visual Studio 12.0's linker. When I try to compile anything with dmd, I get LINK : fatal error LNK1181: cannot open input file 'test,,nul,user32+kernel132/noi;.obj' I'm pretty sure else is ok as I didn't see any errors while I was building. What can I try next? Solved it by pointing to the dmc linker instead. Now I have LNK1104: cannot open file 'shell32.lib' I'm compiling with -m64... couldn't compile 32-bit phobos because of missing zlib.
Re: windows linker error
On Wednesday, 26 November 2014 at 01:35:20 UTC, Joakim wrote: On Tuesday, 25 November 2014 at 23:08:07 UTC, Vlad Levenfeld wrote: On Tuesday, 25 November 2014 at 21:22:24 UTC, Vlad Levenfeld wrote: On Windows 7 I have built dmd (using the vcxproj), druntime (win64.mak) and phobos (win64.mak). I went into sc.ini and set the LINKCMD to point to Visual Studio 12.0's linker. When I try to compile anything with dmd, I get LINK : fatal error LNK1181: cannot open input file 'test,,nul,user32+kernel132/noi;.obj' I'm pretty sure else is ok as I didn't see any errors while I was building. What can I try next? Solved it by pointing to the dmc linker instead. Now I have LNK1104: cannot open file 'shell32.lib' I'm compiling with -m64... couldn't compile 32-bit phobos because of missing zlib. Just so we're clear, you're trying to compile for Win64 COFF? It sounds like you don't have something about your environment set up right, as Win64 requires the MSVC toolchain and some configuration if you use the dmd zip. Did you install from the exe installer or are you using the zip? The dmc linker is not going to work, as it only does OMF. You may find this page helpful, though it may be a bit outdated: http://wiki.dlang.org/Installing_DMD_on_64-bit_Windows_7_%28COFF-compatible%29 I'm compiling the latest build from github. (I normally stay up to date with the current builds on 64bit Debian and everything works more or less without a hitch there, but now I need to get some of my tools working in a Windows environment) I'm not really sure what my options are regarding the COFF or what they mean, 64-bit is really the only requirement (mostly because I can't get the 32-bit stuff to compile). I've got Visual Studio Premium, I tried to install from the exe at one point and got Visual D in the process (and this did work, except that the code I need is built against the latest dmd/druntime/phobos builds). Installing it from the instructions, IIRC, also worked for me, but again, the version. So I used the dmd visual studio project to build dmd, then built druntime and phobos with Digital Mars make; I had previously tried to use dmc to build dmd but couldn't get it to work. Anyway, I manage to build successfully but then I get this linker error when I try to run dmd on some test.d consisting of void main (){}. I've gone into sc.ini and pulled out the ;VC2012 comments to expose the LIB instruction (to fix a different problem) and this is the point that I've gotten stuck at.
function not callable using argument types - i disagree
I'm trying to use the portaudio bindings and can't seem to call Pa_OpenStream, I get this error: source/pa_test.d(156): Error: function deimos.portaudio.Pa_OpenStream (void** stream, const(PaStreamParameters*) inputParameters, const(PaStreamParameters*) outputParameters, double sampleRate, uint framesPerBuffer, uint streamFlags, extern (C) int function(const(void)* input, void* output, uint frameCount, const(PaStreamCallbackTimeInfo)* timeInfo, uint statusFlags, void* userData) streamCallback, void* userData) is not callable using argument types (void**, PaStreamParameters*, PaStreamParameters*, double, uint, uint, extern (C) int function(const(void)* inputBuffer, void* outputBuffer, uint framesPerBuffer, const(PaStreamCallbackTimeInfo)* timeInfo, uint statusFlags, void* userData), void*) for clarity, here are the argument lists separated: what I need is up top, what I have is on the bottom: (void**, const(PaStreamParameters*), const(PaStreamParameters*), double, uint, uint, extern (C) int function(const(void)*, void*, uint, const(PaStreamCallbackTimeInfo)*, uint, void*), void*) (void**, PaStreamParameters*, PaStreamParameters*, double, uint, uint, extern (C) int function(const(void)*, void*, uint, const(PaStreamCallbackTimeInfo)*, uint, void*), void*) -- The only difference I see is in const(PaStreamParameters*) but I feel like every time I pass a non-const argument where a const is required, the conversion should be implicit. At least, that's the way I seem to recall it working. What am I doing wrong?
Re: function not callable using argument types - i disagree
Update: I just did a manual cast. Still getting there error. Here's the new argument lists: (void**, const(PaStreamParameters*), const(PaStreamParameters*), double, uint, uint, extern (C) int function(const(void)*, void*, uint, const(PaStreamCallbackTimeInfo)*, uint, void*), void*) (void**, const(PaStreamParameters*), const(PaStreamParameters*), double, uint, uint, extern (C) int function(const(void)*, void*, uint, const(PaStreamCallbackTimeInfo)*, uint, void*), void*) They're identical... unless I'm losing my mind. Yet still its not callable using argument types
Re: profiling issues
Awesome! These are exactly what I was looking for. Thanks!
profiling issues
I've got a library I've been building up over a few projects, and I've only ever run it under debug unittest and release (with dub buildOptions). Lately I've needed to control the performance more carefully, but unfortunately trying to compile with dub --profile gives me some strange errors: 1) A few lines in one of my modules are reported as unreachable by dmd. The data they operate on are defined entirely in code (i.e. not read as external input) so maybe they're getting CTFE'd into oblivion? All I know is they're apparently reachable in non-profiled code (and very essential to the business logic... but they're just math functions, nothing crazy, one of the unreachable lines computes the areas of some polygons, another sums the areas up). 2) The linker complains about undefined references to std.exception.enforce being called from std.stdio.rawRead. 3) If I try to compile with buildOptions:[profile] instead of dub --profile, then it compiles and links but then I segfault on launch at gc_malloc. I also recall (but can't seem to find) something about profiling not working with multithreaded code? Because almost every encapsulated service in this library runs on its own thread. And the code base (15k LOC) isn't easily reduced, as any remotely interesting main method I write pretty much pulls from the entire library. I don't want to have to turn this whole thing inside out. Its like 95% templates and inlining wreaks havoc on the logic as well, but that's another problem for another day... Does anyone else have these kinds of issues? Are there any alternative methods of coarse-grained profiling (i.e., not manually peppering timer calls into my code)? Whats with the unreachable statements? Any hints on what I can try next to get closer to a performance profile of my code?
Re: Intended behavior of std.range.cycle?
On Thursday, 4 September 2014 at 11:43:28 UTC, monarch_dodra wrote: *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... Can you elaborate on what the problem was? I'm curious as I've recently implemented a DSP module that uses ranges with floating-point slicing and, other than having to define a second kind of length (I call it measure so I can still have a discrete length when I need it), it seems to work well enough so far. It'd be bad if there were some unseen fiasco waiting for me...
Re: const-correctness in std.range
Thanks for the reply. And indeed, I recently found that ByLine.empty can't be const because it writes and removes a character from the stream or something... and when I compile with optimizations, const empty gets totally wrecked. I suppose that making empty const doesn't really gain me anything, as its generally used in conjunction with popFront which is obviously non-const.
const-correctness in std.range
I notice that some of the range adapters in std.range (iota, takeExactly) have a const empty property, while others (take, retro) don't. This makes maintaining const-correctness downstream (with my own range adapters atop phobos') more difficult. I'm wondering if there is a rationale for this, if there is some use for a non-const empty?
Re: @safe, pure and nothrow at the beginning of a module
On Friday, 15 August 2014 at 16:54:54 UTC, Philippe Sigaud wrote: So I'm trying to use @safe, pure and nothrow. If I understand correctly Adam Ruppe's Cookbook, by putting @safe: pure: nothrow: at the beginning of a module, I distribute it on all definitions, right? Even methods, inner classes, and so on? Because I did just that on half a dozen of modules and the compiler did not complain. Does that mean my code is clean(?) or that what I did has no effect? I've noticed the same thing. If I want pure and nothrow to propage to inner structs and classes I have to place another label inside the class definition. Otherwise only free functions are affected.
undefined references
I'm compiling with DMD 2.065 using dub, and I've gotten some undefined reference errors for symbols inside my own project. Trying to run dustmite doesn't help, it keeps reporting that its done in one iteration, and gives me an empty results folder. I've used it before, its pretty straightforward, not sure whats going wrong. I'm not sure what else to try. This is my first encounter with a linker error that didn't have to do with an external library.
Re: undefined references
Ok, I've gotten to the bottom of this issue but I'm not totally sure how to submit a bug report for this (no SSCCE: can't get dustmite to work on it, and the problem won't show itself when I use the offending module in isolation) so I will try to sum up the issue and maybe I can provide some useful information for the devs. I have a generic Vector struct that is constructed by helper functions that deduce the length and element type and forward the arguments to the appropriate constructor. Almost all of them had a constraint on them that required the length of the vector the be at least 2, but the Vector class itself had no such constraint, and one of the helper functions was missing it as well. When I added the constraint to either the Vector struct or the helper function (I've since added them to both) then everything links fine. It looks like what was happening was that a fill constructor helper function (intended use: vector!4 (x) = vector (x, x, x, x)) was routing to a variadic constructor helper function (vector (args) = vector!(args.length)(args)) that attempted to generate a 1-element vector and somewhere along the way - linker error. There are the mangled names that the linker could not resolve references to: `_D3evx7vectors16__T6VectorVm1TdZ6Vector6__initZ` `_D3evx7vectors16__T6VectorVm1TdZ6Vector6__ctorMFNaNbNcNfdZS3evx7vectors16__T6VectorVm1TdZ6Vector` the second of which demangles to this: pure nothrow ref @safe evx.vectors.Vector!(1uL, double).Vector evx.vectors.Vector!(1uL, double).Vector.__ctor(double) So, there's my one-element vector constructor, which is likely having a hard time with the following overloads: this (Elements...)(Elements elements) if (Elements.length == length) { foreach (i, element; elements) components[i] = element; } this (Element element) { components[] = element; } So, while the mistake was mine, this should be an ambiguous overload error at compile-time, instead of a linker error. I realize that everyone contributing to D has their hands more than full, and a bug this rare (assumption based on lack of search results) is gonna be low-priority, so I'm just making this post for posterity - maybe it'll help, and of course I'm happy to try anything and give additional information. If anyone has any suggestions on how I might go about making a useful bug report out of this, I'm all ears.
Re: opDispatch compiles fine, but still fails to resolve?
On Saturday, 9 August 2014 at 10:36:55 UTC, Artur Skawina via Digitalmars-d-learn wrote: On 08/09/14 03:20, Vlad Levenfeld via Digitalmars-d-learn wrote: More opDispatch woes. This feature keeps biting me, yet I keep trying to use it. This time I'm trying to access elements of a vector GLSL-style (without swizzling... for now). Here's the relevant code: struct Vector (uint length, Element = double) { ref @property component (string c)() { enum mat = q{xyzw}; enum col = q{rgba}; enum tex = q{uv}; static if (mat.canFind (c)) return components[mat.countUntil (c)]; else static if (col.canFind (c)) return components[col.countUntil (c)]; else static if (tex.canFind (c)) return components[tex.countUntil (c)]; else static assert (0); } ref @property opDispatch (string c)() if (c.length == 1) { auto v = component!c; pragma(msg, typeof(v)); // this outputs the expected result return v; // so everything is fine, right? wrong... } Element[length] components; } Calling vector.component!`x` or something works fine, but calling vector.x fails with Error: no property etc. Now, I'm used to opDispatch silently failing when it can't compile (very annoying btw), but in this case, I tested every line with a pragma (msg, __traits(compiles...)) and everything checks out. All expressions are verified CTFE-able. The compiler apparently makes it all the way through the method without a hitch, but then just fails symbol resolution anyway. Is this just a bug? Does anyone have any advice on what else to try? v.opDispatch!`x`; Your opDispatch is returning a reference to a local stack-allocated variable. D does not support real references; that 'auto v=...' declaration creates a copy. ref @property opDispatch (string c)() { return component!c; } [opDispatch works for every kind of symbol, there's no problem with @property] artur Yeah, sorry, I made that change last-minute to verify, with the pragma, that I was indeed getting the correct type. The problem must have been something else. I just made a complete oversight in the process of throwing everything but the kitchen sink into debugging it.
Re: opDispatch compiles fine, but still fails to resolve?
On Saturday, 9 August 2014 at 05:42:09 UTC, H. S. Teoh via Digitalmars-d-learn wrote: Why would having opDispatch actually generate compile errors cause problems for __traits(compiles,...)? __traits(compiles...) already works fine with a whole bunch of other non-compiling stuff (by gagging errors while it attempts them). The problem with opDispatch is that it gags too much, even when the resolution ultimately fails, so you're left with mysterious disappearances of opDispatch with no hint as to what went wrong. I'm not familiar with this part of DMD, but surely there's a way to make this behave better?? T You're right, between you and Artur and a night's rest I'm realizing what an utter mess my post was. At that point I had lost half a day debugging this and hadn't slept much so my thought process was not particularly coherent. The only thing I've ever really managed to get out of opDispatch in terms of errors is to litter the thing with pragma(msg, ...) and hope that, on visual inspection, something clicks and I can figure out where I went wrong. I think the real crux of my issue was misunderstanding auto ref. After I noticed that I could use const or @property or some other qualifier instead of auto, I assumed that it implied auto, so that ref @property = auto ref @property. Evidently not. I was looking inside the method body for the issue when it was on that first line the whole time.
tuple slicing operator
I may be misunderstanding the intended semantics of the [] operator but I've come to interpret x[] to mean give me x as a range and this is the meaning I intend when I overload it in my own structs. But - auto z = tuple (1,1,1); pragma (msg, typeof(z)); // Tuple!(int, int, int) pragma (msg, typeof(z[])); // (int, int, int) I'm surprised by what the last line outputs. In generic code I tend to use [] to make sure a variable is a range before I use it (like static arrays, or structs following my interpretation of []). So now whenever tuples might come into the mix I have to pass the argument through an overloaded convenience function that can tell a range or tuple type from one-element variadic argument. I've got a lot of difficulty with that last part so I am wondering, is there a better way to do this?
Re: tuple slicing operator
On Saturday, 9 August 2014 at 19:26:46 UTC, Meta wrote: (which is why z[] gives you a type of (int, int, int) instead of Tuple!(int, int, int)). That makes sense, and on second thought it wouldn't make sense to use a tuple as a range because it's not guaranteed to have only one element type. So, I can see how expanding the tuple is the reasonable thing to do. For one thing, any type can overload the [] operator, so x[] can mean anything. True, I just meant insofar as convention based on what I had (up until the tuples) thought to be the typical usage. Usually slices *are* ranges, but they don't have to be, and it's not a good assumption to make. Are there any specific cases where they're not? In generic code, you should always use template constraints and static if along with the appropriate traits to check facts about a type. Good advice, I think I will stick to this. My approach was sliding into 'programming by convention'.
opDispatch compiles fine, but still fails to resolve?
More opDispatch woes. This feature keeps biting me, yet I keep trying to use it. This time I'm trying to access elements of a vector GLSL-style (without swizzling... for now). Here's the relevant code: struct Vector (uint length, Element = double) { ref @property component (string c)() { enum mat = q{xyzw}; enum col = q{rgba}; enum tex = q{uv}; static if (mat.canFind (c)) return components[mat.countUntil (c)]; else static if (col.canFind (c)) return components[col.countUntil (c)]; else static if (tex.canFind (c)) return components[tex.countUntil (c)]; else static assert (0); } ref @property opDispatch (string c)() if (c.length == 1) { auto v = component!c; pragma(msg, typeof(v)); // this outputs the expected result return v; // so everything is fine, right? wrong... } Element[length] components; } Calling vector.component!`x` or something works fine, but calling vector.x fails with Error: no property etc. Now, I'm used to opDispatch silently failing when it can't compile (very annoying btw), but in this case, I tested every line with a pragma (msg, __traits(compiles...)) and everything checks out. All expressions are verified CTFE-able. The compiler apparently makes it all the way through the method without a hitch, but then just fails symbol resolution anyway. Is this just a bug? Does anyone have any advice on what else to try? I'm out of ideas (short of falling back on generating property methods by string mixin).
Re: opDispatch compiles fine, but still fails to resolve?
Yep, replacing @property with auto did the trick. The lack of error messages in opDispatch is frustrating. I realize that, due to tricks like __traits(compiles, Foo.testing_for_some_function), having opDispatch stop compilation if it fails is not going to work, but there's gotta be some way to expose what's going on with it when it fails. Maybe some kind of pragma to cause opDispatch to report its failures, I don't know.
Re: multidimensional indexing/slicing docs?
On Wednesday, 6 August 2014 at 08:48:25 UTC, John Colvin wrote: Is there anywhere that describes what Kenji (it was Kenji wasn't it?) recently implemented for this? I'm curious about this as well. I've just come across a case where I need to work with a 2D array of channels*samples from an analog-digital converter, and what I thought would be a straightforward design problem turned out to be pretty complicated. I have a C++ solution but its procedural/oop. Going functional and range-based would be a huge improvement, but I'm caught in analysis paralysis.
private selective imports
Is there any way to make selective imports private? I've got a name clash from importing an all module that has a bunch of public imports, one of which is circular, it goes sort of like this: module math.all; public: import geometry; import vectors; --- module vectors; struct Vector {} --- module geometry; import math.all: Vector; And then I get an error like: vectors.Vector conflicts with geometry.Vector Its the same Vector, though. What can I do?
Re: private selective imports
On Wednesday, 6 August 2014 at 18:33:23 UTC, Dicebot wrote: Most voted DMD bug : https://issues.dlang.org/show_bug.cgi?id=314 +1 from me as well. This is unfortunate. D otherwise has a very comfortable import system.
Re: private selective imports
Sure, but people keep using them at the module-level, which really shouldn't be done until the bug is fixed. IMHO, we'd be better off making it illegal to use selective imports at the module-level rather than keeping it as-is. - Jonathan M Davis I'm curious, what's the problem with it anyway? Judging by the posts in the bug report and the bug's own lifespan this must be a real tough one to crack.
auto ref function parameters in a free function
This doesn't work: bool less_than (T)(auto ref T a, auto ref T b) { return a b; } Error: auto can only be used for template function parameters What am I doing wrong? Is this not a template function?
Re: auto ref function parameters in a free function
This would make the function always take its argument by reference. I'm trying to use the feature here: http://dlang.org/template.html from the section Function Templates with Auto Ref Parameters
Re: auto ref function parameters in a free function
On Sunday, 3 August 2014 at 19:26:28 UTC, anonymous wrote: Works for me with dmd versions back to 2.060. What compiler are you using? dmd 2.065
Re: auto ref function parameters in a free function
On Sunday, 3 August 2014 at 19:43:53 UTC, anonymous wrote: If this exact code errors for you, it ... uhh ... could be platform specific? Are you on Windows? Debian, and your code works for me. I figured out the problem - I made less_than to serve as a default sorting predicate, so in a few places there is something like this: void sort (R, T = ElementType!R, alias compare = less_than!T)(R range, T item) {...} And since auto ref parameters need actual parameters to deduce whether they should be ref or not, less_than!T isn't an instantiated template - its still an alias, because it still must choose between having ref and value parameters. So, it looks like I can't use auto ref with less-than. Which is fine, if I need to quickly compare large structures I will just pass in a ref_less_than predicate or something.
Re: auto ref function parameters in a free function
On Sunday, 3 August 2014 at 20:10:39 UTC, Martijn Pot wrote: What is the benefit of 'auto ref' over 'in' as you are changing a nor b? Because less_than (T)(T a, T b) (or in, or const T) will copy a and b on their way into the function. Usually this is ok but certain data structures I use are not intended to be copied, or they are just very large or have very elaborate constructors that take up time and resources, or something. I don't know if inlining would solve this or not but as far as I know there is no way to rely on inlining currently.
Re: auto ref function parameters in a free function
On Sunday, 3 August 2014 at 21:24:03 UTC, Vlad Levenfeld wrote: certain data structures I use are not intended to be copied, . although these cases are probably better off being compared by some kind of key rather than directly... so, auto ref isn't necessary here, it was just something I had tried and was surprised at the error message I got.
Re: auto ref function parameters in a free function
On Sunday, 3 August 2014 at 21:47:06 UTC, Artur Skawina via Digitalmars-d-learn wrote: void sort (R, T = ElementType!R, alias compare = less_than)(R range, T item) [should work iff the sort implementation only calls the predicate] artur This works! Thanks!
why does isForwardRange work like this?
I've been having trouble propagating range traits for range-wrapper structs. Consider this sample code: struct Wrapper (R) { R range; static if (isInputRange!R) { /* input range stuff */ } static if (isForwardRange!R) { auto save () inout { return this; } static assert (isForwardRange!Wrapper); // -- this fails } } making save @property makes it compile. So I looked at the implementation of isForwardRange and now I am very confused about this condition: is(typeof((inout int = 0) { R r1 = void; static assert (is(typeof(r1.save) == R)); })); What's the rationale behind stating the condition this way as opposed to, say, is (typeof(R.init.save)) == R) || is ((typeof(R.init.save()) == R) so that member fields as well as @property and non-@property methods will match, and what is the purpose of (inout int = 0)?
Re: memory/array question
On Thursday, 31 July 2014 at 20:43:11 UTC, bearophile wrote: Take a look at the asm! Bye, bearophile I use DMD and Dub, how do I view the asm?
Re: why does isForwardRange work like this?
Yes, I see the problem now. I can't think of any reason why I'd want to make save anything but a function (especially since `save` is a verb) but I guess someone out there might have a good one. So, what is gained by (inout int = 0) over ()? I wasn't even aware that giving a default value for an unlabeled parameter would compile. What does it do?
pure delegates and opApply
I have some use cases where I am trying to iterate over a collection in a pure function. The collection doesn't change, but the foreach loop body updates a variable elsewhere in the function body. (I'm reimplementing reduce as pure nothrow, and the variable in question is the accumulator). Since opApply is implemented as a delegate, though, this prevents my function from being pure. The delegate isn't pure because it writes through its context pointer - but the context pointer shouldn't capture anything outside of the calling function's scope (I have no idea how to verify this). In other words, if I replaced the foreach with a for-loop, my function would be pure. I see 3 possible takes on this, please tell me if I'm hot or cold: 1) foreach is the idiomatic D way to iterate, but since I am insisting on purity, I have to accept that I might have to do things in a non-idiomatic way and go for the for-loop. 2) ranges are the other idiomatic D way to iterate, and if I want purity then I should be working with ranges anyway (as they have a more mathematical flavor to them than foreach or for) 3) opApply ought to be considered pure if the supplied delegate doesn't modify anything outside of the calling function's scope (bug/enhancement)
Re: Showing a user specified error message when no overloads match
On Tuesday, 29 July 2014 at 15:47:08 UTC, H. S. Teoh via Digitalmars-d-learn wrote: Maybe we should file an enhancement bug to improve error reporting for opDispatch. I found this https://issues.dlang.org/show_bug.cgi?id=8387 and cast a vote for it. I've cast a few votes in the bugtracker, don't know if that raises the visibility of the bugs or what. Maybe not since this bug had 4 votes to begin with and has been around since 2012... or maybe 4 is not that many.
clear works better than it ought to considered i never defined it
A weird thing happened: I was building a dictionary struct which contains a custom array of values and a differently-typed custom array of keys. Both of them implicitly define clear by aliasing a backing array. The dictionary type doesn't have clear, though. And it doesn't alias anything. Yet when I call clear on it, not only does it work, but it clears both of the private contained arrays. I can't find any free clear function in Phobos. Not that I'm complaining, but... what's going on here?
Re: clear works better than it ought to considered i never defined it
Yep, just checked in the debugger. So, that's actually a bad thing, then. Good thing its being deprecated!
Re: Showing a user specified error message when no overloads match
opDispatch behaves as though it has SFINAE. When something fails in the definition (like I am having now, some of the symbols I used in it hadn't been imported) there won't ever be an error message, I just get Error: no property 'bar' for type 'Foo' In one case I had to use static ifs and pragmas and static assert(0) to get error messages out of opDispatch because static assert messages were being suppressed. Its very frustrating.
Re: Map one tuple to another Tuple of different type
I'm just confused about how static while is supposed to work because static foreach, to my understanding, would have to work by making a new type for each iteration. I say this because, 1) runtime foreach works like that (with type = range), and 2) without ctfe foreach, the only way I know of to iterate a typelist is to make a new type with one less element, so I imagine static foreach lowers to that. I suppose its possible to make a struct with static immutable start and end iterators, and make new types out of advancing the start iterator until it was equal to the end. Seems like a step backward though. Anyway my actual question is: if all values are constant at compile time, how would a static while loop terminate?
Re: Map one tuple to another Tuple of different type
Yes, though the loop unrolling is news to me. I'll have to keep that in mind next time I'm trying to squeeze some extra performance out of a loop. btw, found a static switch enhancement request here: https://issues.dlang.org/show_bug.cgi?id=6921
Re: Compile-Time Interfaces (Concepts)
On Sunday, 20 July 2014 at 15:45:37 UTC, Atila Neves wrote: On Thursday, 17 July 2014 at 22:52:37 UTC, Justin Whear wrote: On Thu, 17 Jul 2014 22:49:30 +, Nordlöw wrote: AFAIK there is no compile-time variant of interfaces right? Why is that? Wouldn't it be nice to say something like struct SomeRange realize InputRange { /* implement members of InputRange */ } and then the compiler will statically check that that all members are implemented correctly. I guess this requires some new syntax to describe what an InputRange is. Kind of like C++ Concepts. What benefits would accrue from adding this? Static verification that a structure implements the specified concepts? If so, you can simply do this instead: static assert(isInputRange!SomeRange); This is sufficient, but not adequate. Just as the built-in unittest blocks with assertions, it's great when the assertion is true but good luck finding out where the bug is when it's not. The D Cookbook has an idiom to handle this by checking for __ctfe but it's super hacky and there should be a better way. I have lost count of how many times I wish the compiler would help me with compile time interfaces as it does with runtime code. static override and static interface? Yes please. Atila +1, failing template constraints just gives a vague couldn't match overload type of error, and sometimes static assertions get suppressed. I've noticed that opDispatch is particularly bad about this. Even syntactic errors won't trigger compiler messages, and instead seems to behave like SFINAE which I was assured doesn't exist in D. I have to use pragma (msg, ...) to get meaningful errors. Its so bad I generally avoid opDispatch despite its awesome potential and just generate template functions with mixins instead, because they are marginally easier to debug. I wind up doing things like this to get the functionality I want: static string assert_processing_stage_defined (string stage)() { static immutable error_msg = `Model must define processing stage: ` ~stage~ ` ()`; return q{ static assert (hasMember!(This, } ``~stage~`` q{), } ~error_msg~ q{); static assert (isSomeFunction!(__traits(getMember, This, } ``~stage~`` q{)), } ~error_msg~ q{); static assert (ParameterTypeTuple!(__traits(getMember, This, } ``~stage~`` q{)).length == 0, } ~error_msg~ q{); static assert (is (ReturnType!(__traits(getMember, This, } ``~stage~`` q{)) == void), } ~error_msg~ q{); }; } mixin(`` ~assert_processing_stage_defined!`initialize` ~assert_processing_stage_defined!`update` ); I'm sure theres worse ways to do it but I still find this ugly and overly specific. I would much rather use something like what Nordlöw suggested. Something that is standardized across the language and generates meaningful error messages.
Re: Map one tuple to another Tuple of different type
Thats real weird that it would reject your i variable, given that T.length is known at compile time. I think this is a bug. I can get your code to compile if I change your foreach loop to this: foreach(i, U; T) modTuple[i] = transTupleElem(argTuple[i]); // ok
Re: Map one tuple to another Tuple of different type
On Monday, 21 July 2014 at 01:29:40 UTC, Daniel Gibson wrote: Am 21.07.2014 03:05, schrieb Vlad Levenfeld: Thats real weird that it would reject your i variable, given that T.length is known at compile time. I think this is a bug. I can get your code to compile if I change your foreach loop to this: foreach(i, U; T) modTuple[i] = transTupleElem(argTuple[i]); // ok That works indeeed. I also tried foreach(int i, x; argTuple) which also with the same error as foreach(i ; 0 .. T.length). As a workaround I created a TupleIndices template, that would return a tuple with 0 .. len and did foreach(i; TupleIndices!(T.length) but that was kinda messy and reminded me of the loops I had to jump through in C++ to do anything useful with variadic templates.. I agree that this is a bug, but at least your workaround is much nicer, thanks a lot! :-) Cheers, Daniel (@Vlad: Originally I answered you directly because the Thunderbird developers thought it was a clever idea to put an answer button that answers to the author instead of to the newsgroup prominently into the GUI) You're very welcome. The reason foreach(int i, x; argTuple) failed is because argTuple is a value (of type T), and so known only at run-time. To get a foreach to run at compile-time, you have to give it something whose value is known to the compiler (so, T and typeof(argTuple) would suffice, and 0..T.length really should as well). A nice way to test is pragma(msg, Foo) where Foo is your argument... if its knowable at compile-time, then your compiler should output Foo (or the name of whatever its aliasing) to the console.
Re: Map one tuple to another Tuple of different type
On Monday, 21 July 2014 at 19:02:59 UTC, H. S. Teoh via Digitalmars-d-learn wrote: functionality is desirable. Maybe we should rouse a racket on the main D forum to either make staticIota public, or implement static foreach. ;-) static switch would be so sick. I frequently find myself doing some compile-time branching with more than 2 branches or with an enum (like for policies/strategies/whatever). Compile-time case labels would clean that code up, and final switch would be a maintenance improvement as well. static while sounds cool, but how would it work? (as in use case, not implementation). The condition would have to be immutable, wouldn't it?
Re: shared and nonshared dtor
On Sunday, 20 July 2014 at 08:29:55 UTC, Jonathan M Davis wrote: What you will probably need to do is to not try and use the same type as both shared and non-shared if it has a destructor. Unfortunately this option would require an unrealistic lot of refactoring for me. I'm basically using this thing as a drop-in replacement for arrays, so they go everywhere. I use array-based swap buffers to transfer data between threads. I have to declare the buffers shared, which makes the arrays shared. This problem only emerged when I decided I wanted them to free on destruction, so it looks like I'll be sticking with manual free for awhile longer. I would however suggest that you report this as a bug, since it really should be able to distinguish between shared and unshared destructors. Would it be considered a duplicate of https://issues.dlang.org/show_bug.cgi?id=12004 ? At least, all of my use cases agree with the bug filer's argument against having any shared dtors. shared is a great concept, but we are going to need a few adjustments to its design in order to make it properly, fully useable. Agreed. It's given me a few headaches in the past, but I do like the idea of a transitive qualifier that helps me identify potentially racy data.
shared and nonshared dtor
I have a Resource struct that is supposed to free some memory when it gets destroyed. Unfortunately, I can't define a destructor. If I do, the compiler complains that it can't destroy the shared versions. If I define a shared destructor, the compiler complains that it can't disambiguate between ~this() and shared ~this(). Is there a way around this or a better way to accomplish what I'm trying to do? I just want a lightweight handle to a manually-allocated dynamic array that I can append to and stuff, and frees itself on destruction (so I can keep them in various containers and know that freeing will automatically happen when I remove it).
Re: dependency graph
Thanks! Between the -deps flag and duml I think this is exactly what I need.
Re: break on assertion in GDB?
The reason it worked one time and not the other was because the other time was an exception, not an assertion. How do I break on exceptions? (ps. is there a guide anywhere to using GDB with D?)
Re: Trouble initializing a templated class
On Saturday, 5 July 2014 at 16:47:32 UTC, quakkels wrote: I'm going through Adam Wilson's talk 'C# to D' and I've gotten hung up by one of his examples regarding generic programming in D. Specifically, I'm trying to implement the code example found here: http://youtu.be/6_xdfSVRrKo?t=16m44s. I created a templateExp.d file that looks like this: public class BaseClass {} public class OtherClass : BaseClass {} class SomeClass(T : BaseClass) { public T[] values; public void add(T input) { values ~= input; } } void main() { auto sc = new SomeClass(); OtherClass oc1 = new OtherClass(); OtherClass oc2 = new OtherClass(); sc.add(oc1); sc.add(oc2); import std.stdio; writefln(value count, sc.values.length); } When I run the dmd compiler, I get this error: dmd templateExp.d teamplteExp.d(12): Error: class teamplteExp.SomeClass(T : BaseClass) is used as a type How can I initialize this class correctly? try SomeClass (T): BaseClass
Re: Trouble initializing a templated class
On Saturday, 5 July 2014 at 17:17:03 UTC, quakkels wrote: try SomeClass (T): BaseClass Not sure which line you want me to change. I don't want SomeClass to inherit from BaseClass. Rather, I want T to be restricted to classes that inherit from BaseClass. When I change `class SomeClass(T : BaseClass)` to `class SomeClass(T) : BaseClass` I still get the class templateExp.SomeClass(T) is used as a type error. ah, sorry, I misunderstood. It looks like you need to change the lin auto sc = new SomeClass (); to auto sc = new SomeClass!BaseClass (); The compiler complains because SomeClass is a template when you call SomeClass() without !() template parameters. It only becomes a type once instantiated with parameters.
overloading InExpression
Is this possible? The documentation for std.container lists in as an operator in the container API but only associative arrays actually seem to support it.
Re: overloading InExpression
On Wednesday, 2 July 2014 at 14:14:57 UTC, Dicebot wrote: struct S { int opIn_r(int key) { return key*2; } } void main() { assert((42 in S.init) == 84); } Thanks! I wonder, why the _r and lack of documentation?
Re: overloading InExpression
Ah yes I never noticed that in was in the binary op table. In my defense, searching for in usually yields too many results to be useful. Thanks to everyone for your help!
why does clearing an array set its capacity to 0?
I'm trying to implement some wrappers atop preallocated arrays, so I'm calling reserve in the constructor, have an invariant to ensure that the array.ptr never moves, and use in-contracts to make sure any insertion and appends don't put me over the array capacity. I find that I'm able to safely add and remove elements (I increment xor decrement the length when I do this) but when I call clear on the backing array or set its length to 0, my capacity also goes to 0. Why is this, and what do I do about it? --- As an aside, I remember seeing a Dconf2013 talk given by Don Clugston where he had mentioned that at Sociomantic Labs they operate within slices of larger, pinned arrays or something to minimize GC activity. (I'm very interested in seeing his Dconf2014 talk but can't seem to find a video). This is basically what I'm trying to do, specifically in the context of a custom allocator: allocating custom sliced range types that can do fast appends (as well as containers that don't call new). If anyone has any advice on this in general I would be grateful for it.
Re: why does clearing an array set its capacity to 0?
I was mistaken earlier, decrementing the length counter also sets the capacity to 0.
Re: why does clearing an array set its capacity to 0?
Thanks for your replies. The article was quite helpful in clarifying some questions I had. I decided to benchmark the different append methods (with [releaseMode, inline, noBoundsCheck, optimize]) by appending 10,000 elements to arrays with ~=, Appender, with and without first reserving, with and without assumeSafeAppend and with a custom array type that preallocated an array and kept its own length. The custom array was fastest, then the appender was over 2-3x slower, and the dynamic array 12-13x slower. What surprised me though, was that calling reserve didn't actually give much performance improvement. In fact, of all the ~= benchmarks, plain dynamic arrays had the best performance, followed by reserved and assumedSafe, followed by reserved. For the Appender, reserving was negligibly faster. I'm not sure if I'm doing something wrong but these seem pretty extreme to me, as the description of reserve gave me the impression that it was roughly the same thing as the custom array (i.e. slicing preallocated data).
Re: why does clearing an array set its capacity to 0?
How did you allocate your array? The GC has the APPENDABLE attribute special for memory blocks that are going to be used as slices: I allocated with new T[n]. I've tried allocating with both the APPENDABLE and NO_SCAN blocks but beyond a certain allocation size this doesn't work, I get a reported capacity of 0 and any append reallocates. (8000 does it for me, I haven't looked for the lower bound) Are you doing bounds checking for your array? Try the -boundscheck=off compiler flag. (That may be new in 2.066. Otherwise, try -noboundscheck.) I had it set through dub's buildOptions. Will there be a @nogc or @noheap flag in 2.066? I read some forum posts about it but can't seem to find whether it will be part of the next release.
break on assertion in GDB?
Is this possible? I find myself having to set breakpoints up the callchain and step through every invocation till I find the one that breaks. This is a really bad way to work, but when I fail an assertion in GDB, it just reports program terminated.
Re: break on assertion in GDB?
On Monday, 30 June 2014 at 12:08:31 UTC, Dicebot wrote: On Monday, 30 June 2014 at 11:56:27 UTC, Vlad Levenfeld wrote: Is this possible? I find myself having to set breakpoints up the callchain and step through every invocation till I find the one that breaks. This is a really bad way to work, but when I fail an assertion in GDB, it just reports program terminated. b _d_assert b _d_assert_msg (out of my memory) GDB recognizes both of these and sets the breakpoints, but never actually breaks.
Re: break on assertion in GDB?
I tried it again in a different context and it worked. Odd. Anyway, thanks for the information.