Re: Intelligent Scope Hierarchy
On Thursday, 31 October 2013 at 22:03:18 UTC, Namespace wrote: The 'it' property is only some 'singleton' approach. You can write: void foo() { auto buffer = Mallocator.allocate(42); /// ... many code } And at the end of the scope buffer is cleared because Mallocator's destructor call deallocateAll (if I'm not wrong). That doesn't seem right? deallocateAll would deallocate all allocated objects? Even outside of foo's scope? Also, how would Mallocator.allocate know what to deallocate unless it kept a history? Why would the example code explicitly deallocate the object at the end of the scope if it were unnecessary?
Re: is this invalid code
On 10/31/2013 08:29 PM, Daniel Davidson wrote: The following crashes on writeln, but looks reasonable. Is some form of initializing ctor required for RateCurve? import std.datetime; import std.range; import std.stdio; struct DateRate { Date date; double value = 0.0; } struct RateCurve { private immutable(DateRate)[] _data; } struct CFS { double initialValue; RateCurve growth; } void main() { auto s = CFS(1.0); // auto s = CFS(1.0, RateCurve()); // crashes // auto s = CFS(1.0, RateCurve([])); // works writeln(s); } Thanks Dan You are not going to like my answer but this may be the 16-byte struct bug. Add something to RateCurve and your code works fine... :-/ struct RateCurve { private immutable(DateRate)[] _data; ubyte b; // <-- ADDED } Ali
is this invalid code
The following crashes on writeln, but looks reasonable. Is some form of initializing ctor required for RateCurve? import std.datetime; import std.range; import std.stdio; struct DateRate { Date date; double value = 0.0; } struct RateCurve { private immutable(DateRate)[] _data; } struct CFS { double initialValue; RateCurve growth; } void main() { auto s = CFS(1.0); // auto s = CFS(1.0, RateCurve()); // crashes // auto s = CFS(1.0, RateCurve([])); // works writeln(s); } Thanks Dan
Re: Dynamic load from another context
On Thursday, 31 October 2013 at 02:45:36 UTC, Wolftein wrote: so my question is, is it possible to build an associative array at compile-time? Yes, by using ctfe it's possible. like so: enum int[string] aa = createAA(); auto createAA() { int[string] aa; aa["hello"] = 1; aa["foo"] = 123; return aa; } unittest { static assert(aa["hello"] == 1); static assert(aa["foo"] == 123); } Then i could register some shared variables like events and when the plug-in is loaded, iterate over that array and set the correct values at runtime. This is not a good idea. The address values of functions/variables in a dll changes depending on where in memory the dll gets loaded. Since the addresses are determined at runtime compiletime calculations will not be correct. Also you could use the export keyword. This makes it possible to load the variables at runtime using the core.runtime module. However there seems to be problems with the export keyword see the DIP45 http://wiki.dlang.org/DIP45 I'm currently developing a reflection library for use across DLL's. In it i've done something simillar to what you want to do. I use annotations to indicate if a variable is sharable across dlls and then the code to handle the sharing is generated from those annotations via a mixin template. So bascialy i do something like this: (Simplified version) //Pluggin.d @DLLShared __gshared size_t foo; @DLLShared void bar(string a) { //Do something cool. } //Does not get shared over dll. void baz() { } mixin RegisterReflection; This would be expanded into something like this. __gshared void*[string] __reflectionData; export extern(C) void*[string] getReflectionTable() { return __reflectionData; } static this() { __reflectionData["foo"] = &foo; __reflectionData["bar"] = &bar; } //MainApp. alias extern(C) void function() reflection_pt; void main() { auto pluggin = loadPluggin("some_pluggin.dll"); auto data = pluggin.findFunc!(reflection_pt) ("getReflectionTable")(); auto fooPtr = cast(size_t*)(data["foo"]); //do something with the foo value. } I got a little sidetracked at the end. Hope this helped.
Re: new Type[count] takes too much?
On Thursday, 31 October 2013 at 23:48:19 UTC, Jonathan M Davis wrote: On Thursday, October 31, 2013 23:06:22 Namespace wrote: On Thursday, 31 October 2013 at 09:53:39 UTC, Jonathan M Davis wrote: > On Thursday, October 31, 2013 10:15:51 Namespace wrote: >> I'm sure we had already this conversation but I don't find >> the >> thread. >> >> T[] buffer = new T[N]; assumes more space than stated (in >> average >> 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). >> It >> behaves exactly like reserve and that is IMO wrong. If I >> reserve >> memory with buffer.reserve(N), I want to have at least N >> elements. That behaviour is correct. But if I use new T[N] I >> mostly want exactly N elements and no extra space. >> >> Thoughts? > > You're making the assumption that it would be normal to not > want to then > append to something you allocated with new T[N], and I don't > think that that's > a valid assumption. I disagree. If I want to append I use reserve and I think that is the most common approach. I would fully expect that most people don't bother with reserve or capacity and that they simply create the array at whatever size they create it at and then append to it without worrying about reserve. But we'd have to get real data on that to know for sure one way or the other. Certainly, most folks who are focusing on append performance seem to use Appender, and for the most part, I would suggest that anyone using reserve should be using Appender instead. - Jonathan M Davis Currently Appender isn't more performant than built-in arrays. ;)
Re: new Type[count] takes too much?
On Thursday, October 31, 2013 23:06:22 Namespace wrote: > On Thursday, 31 October 2013 at 09:53:39 UTC, Jonathan M Davis > > wrote: > > On Thursday, October 31, 2013 10:15:51 Namespace wrote: > >> I'm sure we had already this conversation but I don't find the > >> thread. > >> > >> T[] buffer = new T[N]; assumes more space than stated (in > >> average > >> 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It > >> behaves exactly like reserve and that is IMO wrong. If I > >> reserve > >> memory with buffer.reserve(N), I want to have at least N > >> elements. That behaviour is correct. But if I use new T[N] I > >> mostly want exactly N elements and no extra space. > >> > >> Thoughts? > > > > You're making the assumption that it would be normal to not > > want to then > > append to something you allocated with new T[N], and I don't > > think that that's > > a valid assumption. > > I disagree. If I want to append I use reserve and I think that is > the most common approach. I would fully expect that most people don't bother with reserve or capacity and that they simply create the array at whatever size they create it at and then append to it without worrying about reserve. But we'd have to get real data on that to know for sure one way or the other. Certainly, most folks who are focusing on append performance seem to use Appender, and for the most part, I would suggest that anyone using reserve should be using Appender instead. - Jonathan M Davis
Re: improving '$' to work with other functions (eg: indexed)
On Thursday, October 31, 2013 14:46:29 Timothee Cour wrote: > well it can be made to work with following rule: > > $ binds as follows, using the 1st pattern matched rule: > > very roughly: > > identifier [$] if typeof(a.length) => a[a.length] //likewise with s/[]/()/ > primary_expression . identifier if typeof(primary_expression.length) > => primary_expression . identifier [identifier.length] (recursively) > if no match is found, error. > > eg: > > [1,2,3].indexed([0,$-1] ) => indexed.length isn't valid, so it tries to > bind to [1,2,3]. > > intuitively I believe it makes sense. Well, I can see why you'd think that that makes sense, but it would have surprised me greatly if I had seen code like that compile. And given how little benefit it really provides, I don't think that it's worth the extra complication to the language. So, I'd be against it, but feel free to open an enhancement request. Maybe a compiler dev will take a shine to the idea. - Jonathan M Davis
Re: new Type[count] takes too much?
On Thursday, 31 October 2013 at 09:53:39 UTC, Jonathan M Davis wrote: On Thursday, October 31, 2013 10:15:51 Namespace wrote: I'm sure we had already this conversation but I don't find the thread. T[] buffer = new T[N]; assumes more space than stated (in average 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like reserve and that is IMO wrong. If I reserve memory with buffer.reserve(N), I want to have at least N elements. That behaviour is correct. But if I use new T[N] I mostly want exactly N elements and no extra space. Thoughts? You're making the assumption that it would be normal to not want to then append to something you allocated with new T[N], and I don't think that that's a valid assumption. I disagree. If I want to append I use reserve and I think that is the most common approach.
Re: improving '$' to work with other functions (eg: indexed)
well it can be made to work with following rule: $ binds as follows, using the 1st pattern matched rule: very roughly: identifier [$] if typeof(a.length) => a[a.length] //likewise with s/[]/()/ primary_expression . identifier if typeof(primary_expression.length) => primary_expression . identifier [identifier.length] (recursively) if no match is found, error. eg: [1,2,3].indexed([0,$-1] ) => indexed.length isn't valid, so it tries to bind to [1,2,3]. intuitively I believe it makes sense. On Thu, Oct 31, 2013 at 2:51 AM, Jonathan M Davis wrote: > On Thursday, October 31, 2013 02:46:32 Timothee Cour wrote: > > can we support this and similar use cases ? > > > > import std.range; > > void main(){ > > auto a=[1,2,3,4]; > > auto b1=a.indexed([0,a.length-1]);//OK > > auto b2=a.indexed([0,$-1]);//NG > > } > > Aren't you creating new arrays to pass to indexed here? If that's the > case, $ > isn't associated with any particular array, and I don't see how it could > work. > > Now, there's issue# 7177 > > http://d.puremagic.com/issues/show_bug.cgi?id=7177 > > which aims at getting opDollar to work with ranges which have length > (which it > generally doesn't at this point), so that might be related to what you're > looking for, but if what you're looking for is [0, $-1] to work on its > own, I > don't see how that could ever work, because $ only works when slicing or > indexing, and [0, $-1] in the context above is an array literal. > > - Jonathan M Davis >
Re: Intelligent Scope Hierarchy
The 'it' property is only some 'singleton' approach. You can write: void foo() { auto buffer = Mallocator.allocate(42); /// ... many code } And at the end of the scope buffer is cleared because Mallocator's destructor call deallocateAll (if I'm not wrong).
Re: [challenge] Lazy flatten/avoiding type forward reference with map
On 10/31/2013 02:19 PM, Ali Çehreli wrote: > Y Combinator? (No, I have not solved it yet. :) ) http://rosettacode.org/wiki/Y_combinator#D Ok, I was actually trying to find the following one: https://github.com/gecko0307/atrium/blob/master/dlib/functional/combinators.d Ali
Re: [challenge] Lazy flatten/avoiding type forward reference with map
On 10/31/2013 12:09 PM, David Nadlinger wrote: A while back, somebody raised the topic of implementing a lazy range for traversing/flattening a tree structure on #d. The obvious (in terms of Phobos primitives) solution would be something along the lines of this: --- struct Node(T) { T val; Node!T[] children; } auto flatten(T)(Node!T root) { import std.algorithm, std.range; return only(root.val).chain(map!flatten(root.children).joiner); } void main() { alias N = Node!int; auto a = N(1, [ N(2, [ N(3, [ N(4) ]) ]), N(5) ]); import std.stdio; writeln(a.flatten); // [1, 2, 3, 4, 5] } --- But of course, that piece of code does not compile with current DMD, as the return type of flatten() can't refer to the function itself (during name mangling). Now, one way around this would be to add an array() call at the end of the return statement, which hides the type of map!flatten, but at the cost of many unnecessary memory allocations. A second option would be to use inputRangeObject to convert the return value to ForwardRange!T (well, that is if it actually worked, due to an implementation bug it leads to a runtime crash). But can you think of a more simple/elegant workaround? (Note aside: Obviously, the fact that the code relies on recursion might be an issue, and a simple opApply-based solution with a worklist stack would likely perform better. Still, I think it's a simple, yet interesting problem.) David Y Combinator? (No, I have not solved it yet. :) ) http://rosettacode.org/wiki/Y_combinator#D Ali
Re: Assertion failure: '0' on line 1215 in file 'glue.c'
On Thursday, October 31, 2013 20:39:36 bearophile wrote: > Wolftein: > > Assertion failure: '0' on line 1215 in file 'glue.c' > > > > When trying to compile this: > > > > TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] > > _ownerList; > > > > Is that a compiler bug or i'm doing something that i don't > > suppose to do. > > It seems both a compiler bug fit for bugzilla, and a bug in your > code (TypeTuples are not meant for delegates, I think). Ah, yeah. TypeTuple won't work there (I missed that and thought that he was using a Tuple). TypeTuple is really only for metaprogramming, and it's a compile-time only entity, so it won't work in an AA. std.typecons.Tuple is what he'd have to use. - Jonathan M Davis
Re: D / GtkD for SQL Server
On 2013-10-31 14:47, ilya-stromberg wrote: John, It's interesting if you can connect to the MS SQL. Just use FreeTDS, nothing special about it. See: http://forum.dlang.org/thread/l403bf$139g$1...@digitalmars.com#post-l4089g:241723:241:40digitalmars.com -- /Jacob Carlborg
Re: new Type[count] takes too much?
On Thu, Oct 31, 2013 at 01:28:13PM -0700, Ali Çehreli wrote: > On 10/31/2013 01:10 PM, Marco Leise wrote: > >Am Thu, 31 Oct 2013 10:42:35 +0100 > >schrieb "Namespace" : > > > >>On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote: > >>>In Python if you append items to an array, it sovra-allocates, > >>Never heard of 'sovra'. What does it mean? > > > >That's bearophilian for 'over'. :p > > Apparently, a variation of Italian prefix sopra- :) > > http://en.wiktionary.org/wiki/sopra- [...] http://en.wiktionary.org/wiki/sovra :) T -- Nearly all men can stand adversity, but if you want to test a man's character, give him power. -- Abraham Lincoln
Re: new Type[count] takes too much?
On 10/31/2013 01:10 PM, Marco Leise wrote: Am Thu, 31 Oct 2013 10:42:35 +0100 schrieb "Namespace" : On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote: In Python if you append items to an array, it sovra-allocates, Never heard of 'sovra'. What does it mean? That's bearophilian for 'over'. :p Apparently, a variation of Italian prefix sopra- :) http://en.wiktionary.org/wiki/sopra- Ali
Re: new Type[count] takes too much?
Am Thu, 31 Oct 2013 10:42:35 +0100 schrieb "Namespace" : > On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote: > > In Python if you append items to an array, it sovra-allocates, > Never heard of 'sovra'. What does it mean? That's bearophilian for 'over'. :p -- Marco
Re: C/C++ struct interfacing
Below is a solution to get it to work as a C binding. - Your structure should not be enclosed in the `extern (C)` block; leave it as regular D code. - cppcall should be declared `extern (C)` in D and `extern "C"` in C++; - depending on your platform, you need to link to the C++ standard lib ; on my Ubuntu 12.04, I added the `-L-lstdc++` on the dmd command line. I already used that pattern in some binding for the RtMidi lib: https://github.com/remy-j-a-moueza/drtmidi dRtMidi.d defines a templated structure : struct answer (T) { int success; T value; const (char) * errMsg; } and so does cRtMidi.cpp : template struct answer { int success; T value; const char * errMsg; }; I declared a bunch of `extern (C)` and `extern "C"` function that pass that data arround. It works only if the T data type as the same size in both languages. You can check the size correspondance on this page : http://dlang.org/interfaceToC.html And for more tricky types, you can get some inspiration from Jacob Carlborg dstep project, especially : - translateType () in Type.d : https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Type.d - and the static constructor of the IncludeHandler class, to get to import the right D core module : https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/IncludeHandler.d On Sunday, 27 October 2013 at 12:20:49 UTC, Oleg B wrote: Hello. I want use one struct in two language. How to declare the same structure in different languages? D code: calling C++ function with my struct extern(C++) { struct vec(size_t N, T=float) { // << line 6 alias vec!(N,T) thistype; T[N] data; auto opBinary(string op)( in thistype rhs ) const { thistype ret; foreach( i; 0 .. N ) ret.data[i] = data[i] + rhs.data[i]; return ret; } } void cppcall( vec!(3,float) d ); } void main() { vec!3 a, b; a.data[0] = 10; a.data[1] = 7; a.data[2] = 3; b.data[0] = 13; b.data[1] = 9; b.data[2] = 4; cppcall( a + b ); } C++ code: use struct data #include struct vec { float data[3]; }; void cppcall( vec d ) { printf( "%f %f %f\n", d.data[0], d.data[1], d.data[2] ); } compilation failed with unclear error $ g++ -c ctypestest.cpp -o ctypestest.o $ dmd ctypestest.d ctypestest.o -ofctypestest ctypestest.d(6): Error: struct ctypestest.vec!(3, float).vec C++ static variables not supported
Re: new Type[count] takes too much?
Am Thu, 31 Oct 2013 02:52:49 -0700 schrieb Jonathan M Davis : > On Thursday, October 31, 2013 10:15:51 Namespace wrote: > > I'm sure we had already this conversation but I don't find the > > thread. > > > > T[] buffer = new T[N]; assumes more space than stated (in average > > 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It > > behaves exactly like reserve and that is IMO wrong. If I reserve > > memory with buffer.reserve(N), I want to have at least N > > elements. That behaviour is correct. But if I use new T[N] I > > mostly want exactly N elements and no extra space. > > > > Thoughts? Maybe run a comparison with another popular GC enabled language and check the memory use to find pathological cases. I'd assume that D's GC doesn't waste more memory than any other for dynamic arrays. > You're making the assumption that it would be normal to not want to then > append to something you allocated with new T[N], and I don't think that > that's > a valid assumption. That doesn't happen much in my programming practice. I'm with the OP on this. > Also, from what I understand of how allocators work, they > normally grab memory in sizes which are a multiple of 2, so I would expect it > to be highly abnormal to ever get exactly the amount of memory that you > requested. You're pretty much always going to get extra. > > - Jonathan M Davis That's true. Although now I wonder if you could gain anything from having memory pages split into chunks of T.sizeof from which you can allocate single objects or whole arrays of T with a compact layout... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |T|T|T[6] |T|T| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- Marco
Re: Using reduce() with tuples created by zip()
alias sum(T) = curry!(reduce!q{a + b}, cast(T)0); double euclidDistance(double[] xs, double[] ys) in { assert(xs.length == ys.length); } body { return zip(xs, ys) .map!(xy => (xy[0] - xy[1]) ^^ 2) .sum!double .sqrt; } void main() { auto xs = [0.0, 1.0, 0.1]; auto ys = [1.0, -1.0, 0.0]; euclidDistance(xs, ys).writeln; } In D functions are written in camelCase like euclidDistance, instead of euclid_distance. Function pre-conditions and post-conditions are generally better put in the pre and post part of functions. I have defined a sum because it's a generally useful function, but it's a toy because it assumes cast(T)0 as the identity element of the monoid with the plus operator. Bye, bearophile
Re: Assertion failure: '0' on line 1215 in file 'glue.c'
On Thursday, 31 October 2013 at 19:48:19 UTC, Wolftein wrote: On Thursday, 31 October 2013 at 19:39:37 UTC, bearophile wrote: Wolftein: Assertion failure: '0' on line 1215 in file 'glue.c' When trying to compile this: TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] _ownerList; Is that a compiler bug or i'm doing something that i don't suppose to do. It seems both a compiler bug fit for bugzilla, and a bug in your code (TypeTuples are not meant for delegates, I think). Create a minimal example for Bugzilla... Bye, bearophile TypeTuple!(uint, uint)[uint] -> won't work neither There seems to be a problem with TypeTuple and associative arrays in general. Reported :) http://d.puremagic.com/issues/show_bug.cgi?id=11404
Re: Using reduce() with tuples created by zip()
On Thursday, 31 October 2013 at 19:23:56 UTC, Philippe Sigaud wrote: I think reduce takes two arguments: the growing seed and the current front. You're trying to get (a[0]-b[0])^^2 + (a[1]-b[1])^^2 + ..., right? Yep. The (e[1]-e[0])*(e[1]-e[0]) bit was, I supposed was effectively calculating (a[0]-b[0])^^2 and so on. I forgot about the ^^2 in D. Try this: module euclid; import std.stdio; double euclid_dist( double[] pt1, double[] pt2 ) { assert( pt1.length == pt2.length ); import std.algorithm; import std.math; import std.range; return sqrt(0.0.reduce!( (sum,pair) => sum + (pair[0]-pair[1])^^2 )(zip(pt1, pt2))); } void main() { double[] arr1 = [0.0, 1.0, 0.1]; double[] arr2 = [1.0, -1.0, 0.0]; writeln(euclid_dist(arr1,arr2)); } On Thu, Oct 31, 2013 at 8:12 PM, Craig Dillabaugh < cdill...@cg.scs.carleton.ca> wrote: clip Cheers, Craig Thanks, I will try both your, and Bearophile's ideas and see if I can figure out how they work. Craig
Re: Using reduce() with tuples created by zip()
Craig Dillabaugh: I know I could use a simple foreach loop with my zip command, or even std.numeric.euclidean( ... ), but I am trying to be cute here! import std.stdio, std.algorithm, std.range, std.math, std.functional; alias sum(T) = curry!(reduce!q{a + b}, cast(T)0); double euclidDistance(double[] xs, double[] ys) in { assert(xs.length == ys.length); } body { return zip(xs, ys) .map!(xy => (xy[0] - xy[1]) ^^ 2) .sum!double .sqrt; } void main() { auto xs = [0.0, 1.0, 0.1]; auto ys = [1.0, -1.0, 0.0]; euclidDistance(xs, ys).writeln; } Bye, bearophile
Re: Assertion failure: '0' on line 1215 in file 'glue.c'
On Thursday, 31 October 2013 at 19:39:37 UTC, bearophile wrote: Wolftein: Assertion failure: '0' on line 1215 in file 'glue.c' When trying to compile this: TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] _ownerList; Is that a compiler bug or i'm doing something that i don't suppose to do. It seems both a compiler bug fit for bugzilla, and a bug in your code (TypeTuples are not meant for delegates, I think). Create a minimal example for Bugzilla... Bye, bearophile TypeTuple!(uint, uint)[uint] -> won't work neither There seems to be a problem with TypeTuple and associative arrays in general.
Re: Assertion failure: '0' on line 1215 in file 'glue.c'
On Thursday, October 31, 2013 20:30:25 Wolftein wrote: > Assertion failure: '0' on line 1215 in file 'glue.c' > > When trying to compile this: > > TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] > _ownerList; > > Is that a compiler bug or i'm doing something that i don't > suppose to do. Any and all assertions in the compiler which are triggered when compileng are a bug in the compiler. So, yes, this is a compiler bug - regardless of whether your code is valid or not (though I don't see anything obviously wrong with it). - Jonathan M Davis
Re: Assertion failure: '0' on line 1215 in file 'glue.c'
Wolftein: Assertion failure: '0' on line 1215 in file 'glue.c' When trying to compile this: TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] _ownerList; Is that a compiler bug or i'm doing something that i don't suppose to do. It seems both a compiler bug fit for bugzilla, and a bug in your code (TypeTuples are not meant for delegates, I think). Create a minimal example for Bugzilla... Bye, bearophile
Re: fieldPostBlit - what is wrong with this and workarounds
On Thursday, October 31, 2013 15:03:26 Daniel Davidson wrote: > Given this code: > > import plus.tvm.rate_curve; > struct T { > RateCurve m; > } > struct S { > const(T) rc; > } > > I get this error: Error: mutable method > plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not > callable using a const object > > Is this fundamentally incorrect? I abandoned immutable in hopes > that const would be more manageable and so far it has. But these > types of issues still crop up and stop me in my tracks. > > What are the requirements on RateCurve and T for this to work? const and postblit fundamentally don't mix, because for it to work, you have to violate the type system. With postblits, the struct gets memcpied and then the postblit constructor has the chance to mutate the resulting object to make the pieces different that need to be different. However, to do that mutation when the object is const would mean mutating a const object which violates the type system. What we really need is copy constructors, but they haven't been added yet. At one point, Andrei was saying that he and Walter had a solution, but he didn't elaborate on it. I assume that it involved introducing copy constructors, but I don't know, and this issue has not yet been resolved. Now, in your particular code example, you don't define postblit constructor, but my guess would be that RateCurve defines one, making it so that a postblit constructor is generated for T which uses the one for RateCurve, and the S gets one which uses T's. And because const doesn't work with postblit constructors, S becomes uncopyable, and if there's any code that requires that a copy be made, then it'll fail to compile (I'm not sure whether the fact that it's uncopyable will result in an error if no attempts to copy it are made, but you'll definitely get an error if an attempt to copy is made). Hopefully, this problem will be resolved, but regardless of that, I would advise against ever having a const member variable in a struct. Even if you don't have any postblit issues, such a struct can never be assigned to, and it becomes essentially unusuable in any situation where you would have to assign a value to it (e.g. if it were in an array). You can certainly make a struct's member variable const if you want to, but you're going to run into stuff that won't work as a result. It's far better to just provide a property for it which is const (probably returning the member by const ref if you want to avoid copying it when using the property) rather than making the member variable itself const. - Jonathan M Davis
Assertion failure: '0' on line 1215 in file 'glue.c'
Assertion failure: '0' on line 1215 in file 'glue.c' When trying to compile this: TypeTuple!(void delegate(Event), EventPriority, ulong)[uint] _ownerList; Is that a compiler bug or i'm doing something that i don't suppose to do.
Re: Using reduce() with tuples created by zip()
I think reduce takes two arguments: the growing seed and the current front. You're trying to get (a[0]-b[0])^^2 + (a[1]-b[1])^^2 + ..., right? Try this: module euclid; import std.stdio; double euclid_dist( double[] pt1, double[] pt2 ) { assert( pt1.length == pt2.length ); import std.algorithm; import std.math; import std.range; return sqrt(0.0.reduce!( (sum,pair) => sum + (pair[0]-pair[1])^^2 )(zip(pt1, pt2))); } void main() { double[] arr1 = [0.0, 1.0, 0.1]; double[] arr2 = [1.0, -1.0, 0.0]; writeln(euclid_dist(arr1,arr2)); } On Thu, Oct 31, 2013 at 8:12 PM, Craig Dillabaugh < cdill...@cg.scs.carleton.ca> wrote: > I am trying to calculate the Euclidean Distance between two > points. I currently have the following function (that doesn't > compile): > > double euclid_dist( double[] pt1, double[] pt2 ) { >assert( pt1.length == pt2.length ); > >return sqrt( > zip(pt1, pt2).reduce!(function(e) { return > (e[1]-e[0])*(e[1]-e[0]); })(0.0) >); > } > > Hopefully it is clear what I am trying to do. I want zip to > create a range that is a tuple of the point's coordinate pairs, > and then use reduce to sum the squared differences. I get the > following error but can't figure out how to fix my syntax: > > euclid.d(13): Error: template > euclid.euclid_dist.reduce!(__**funcliteral2).reduce does not match > any function template declaration. Candidates are: > /usr/include/dmd/phobos/std/**algorithm.d(688): > euclid.euclid_dist.reduce!(__**funcliteral2).reduce(Args...)(**Args > args) if (Args.length > 0 && Args.length <= 2 && > isIterable!(Args[__dollar - 1])) > euclid.d(13): Error: template > euclid.euclid_dist.reduce!(__**funcliteral2).reduce(Args...)(**Args > args) if (Args.length > 0 && Args.length <= 2 && > isIterable!(Args[__dollar - 1])) cannot deduce template function > from argument types !()(Zip!(double[], double[]), double) > Failed: 'dmd' '-v' '-o-' 'euclid.d' '-I.' > > > I know I could use a simple foreach loop with my zip command, or > even std.numeric.euclidean( ... ), but I am trying to be cute > here! > > Cheers, > Craig >
Using reduce() with tuples created by zip()
I am trying to calculate the Euclidean Distance between two points. I currently have the following function (that doesn't compile): double euclid_dist( double[] pt1, double[] pt2 ) { assert( pt1.length == pt2.length ); return sqrt( zip(pt1, pt2).reduce!(function(e) { return (e[1]-e[0])*(e[1]-e[0]); })(0.0) ); } Hopefully it is clear what I am trying to do. I want zip to create a range that is a tuple of the point's coordinate pairs, and then use reduce to sum the squared differences. I get the following error but can't figure out how to fix my syntax: euclid.d(13): Error: template euclid.euclid_dist.reduce!(__funcliteral2).reduce does not match any function template declaration. Candidates are: /usr/include/dmd/phobos/std/algorithm.d(688): euclid.euclid_dist.reduce!(__funcliteral2).reduce(Args...)(Args args) if (Args.length > 0 && Args.length <= 2 && isIterable!(Args[__dollar - 1])) euclid.d(13): Error: template euclid.euclid_dist.reduce!(__funcliteral2).reduce(Args...)(Args args) if (Args.length > 0 && Args.length <= 2 && isIterable!(Args[__dollar - 1])) cannot deduce template function from argument types !()(Zip!(double[], double[]), double) Failed: 'dmd' '-v' '-o-' 'euclid.d' '-I.' I know I could use a simple foreach loop with my zip command, or even std.numeric.euclidean( ... ), but I am trying to be cute here! Cheers, Craig
Re: structs holding on to reference data by pointer
On Thursday, 31 October 2013 at 18:51:46 UTC, bearophile wrote: Maxim Fomin: You can check whether data is on heap, stack, tls, or just global object by inspecting pointer at runtime. Ideally there would be such function in druntime. This seems like a nice enhancement request for Bugzilla :-) Are you going to open it? It seems useful for me too. You are expert in making enhacement request :) It is impossible to do this in CT (except if comiler support flow analysis and can prove in some scenarious that data is on stack or not, but due to separate compilation it is impossible to do in general case) (and probably shouldn't). You can do it even with separate compilation (at compile time) if your language has different kinds of pointers as Rust. Perhaps in D this can be done using Phobos-defined smart pointers. Bye, bearophile But I don't believe that D being system laguage will diverge from traidtional C/C++ pointer model. Right, in runtime smart pointers can probably do some job by guessing allocation kind looking at pointer.
[challenge] Lazy flatten/avoiding type forward reference with map
A while back, somebody raised the topic of implementing a lazy range for traversing/flattening a tree structure on #d. The obvious (in terms of Phobos primitives) solution would be something along the lines of this: --- struct Node(T) { T val; Node!T[] children; } auto flatten(T)(Node!T root) { import std.algorithm, std.range; return only(root.val).chain(map!flatten(root.children).joiner); } void main() { alias N = Node!int; auto a = N(1, [ N(2, [ N(3, [ N(4) ]) ]), N(5) ]); import std.stdio; writeln(a.flatten); // [1, 2, 3, 4, 5] } --- But of course, that piece of code does not compile with current DMD, as the return type of flatten() can't refer to the function itself (during name mangling). Now, one way around this would be to add an array() call at the end of the return statement, which hides the type of map!flatten, but at the cost of many unnecessary memory allocations. A second option would be to use inputRangeObject to convert the return value to ForwardRange!T (well, that is if it actually worked, due to an implementation bug it leads to a runtime crash). But can you think of a more simple/elegant workaround? (Note aside: Obviously, the fact that the code relies on recursion might be an issue, and a simple opApply-based solution with a worklist stack would likely perform better. Still, I think it's a simple, yet interesting problem.) David
Intelligent Scope Hierarchy
Hi, I'm new to D and stumbled on the new allocators thread. In the help there is code like auto buffer = Mallocator.it.allocate(1024 * 1024 * 4); scope(exit) Mallocator.it.deallocate(buffer); which seems redundant and error prone. Would it not be possible for allocate to automatically add itself to the parent scope by default? This way code like auto buffer = Mallocator.it.allocate(1024 * 1024 * 4); would automatically expand to auto buffer = Mallocator.it.allocate(1024 * 1024 * 4); scope(exit) Mallocator.it.deallocate(buffer); If, say, we needed to "raise" the scope(exit) of allocate to act on the parent of the parent scope then we could do something like auto MyAllocate(size) { return scope(raise) { Mallocator.it.allocate(size); }; auto scope(parent) { print("Happy times"); }; } auto buffer = MyAllocate(1024 * 1024 * 4); So that allocate inside MyAllocate won't release the buffer on the return of MyAllocate on use scope. with scope hierarchy the above would translate into auto buffer = MyAllocate(1024 * 1024 * 4); Mallocator.it.deallocate(buffer); print("Happy times"); This will allow wrapping automatic scope exits to behave properly. Of course with such a feature one would also need to prevent automatic scope assignment: auto buffer = scope(none) MyAllocate(1024 * 1024 * 4); would prevent any auto scope from My Allocate and subcalls from being called. This is just a rough suggestion that hopefully will lead to more potent scope control and less error prone allocators. I believe it should be somewhat easily implemented by having some type of vtable like control for each function that is called after each function to deal with the scope chaining.
Re: structs holding on to reference data by pointer
Maxim Fomin: You can check whether data is on heap, stack, tls, or just global object by inspecting pointer at runtime. Ideally there would be such function in druntime. This seems like a nice enhancement request for Bugzilla :-) Are you going to open it? It seems useful for me too. It is impossible to do this in CT (except if comiler support flow analysis and can prove in some scenarious that data is on stack or not, but due to separate compilation it is impossible to do in general case) (and probably shouldn't). You can do it even with separate compilation (at compile time) if your language has different kinds of pointers as Rust. Perhaps in D this can be done using Phobos-defined smart pointers. Bye, bearophile
Re: fieldPostBlit - what is wrong with this and workarounds
On Thursday, 31 October 2013 at 17:22:07 UTC, Daniel Davidson wrote: I'm think you may be correct... but what specifically is incorrect about the language? When I see __fieldPostBlit I get the feeling it is more an implementation issue than the language. __postblit also looks like implementation detail but it is same problem. Field postblit means that aggregate has some members which have postblits so they should be called. This is same problem which blows in higher level. If as you suggest, D language is fundamentally broken - is it possible we can just get a plan for fixing it? To me this seems like a huge design hole and I come back to the threads with questions again and again and I really don't know how others manage the use of const/immutable. This is probable tenth thread about const postblits which I do remember for all my (only) 2 years in D. D2 (version currently in use) dates back to 2004 AFAIK and Andrei (helping to design the language) is in D since 2006, also AFAIK. Draw your own conclusions. I've already given up on immutable. If I have to strip const as well then that is a huge pain and unfortunate since the concept seems sound and well argued in TDPL. Trying to mess with mutable/const/immutable on mostly working code is like playing whack a mole. One can do: 1) revise the design to challange whether consts are really necessary 2a) use workarounds like const pointer 2b) use cast to break const or another tricks (explicit casts are better because holes in type system may be fixed in some point in the feature)
Re: structs holding on to reference data by pointer
On Thursday, 31 October 2013 at 17:34:21 UTC, Daniel Davidson wrote: On Thursday, 31 October 2013 at 16:16:36 UTC, bearophile wrote: That's wrong code, you are escaping a reference to memory (of rc variable) allocated in the stack frame of foo(). The D compiler is not smart enough to recognize the bug. There are optimizations that patch and avoid this bug (like inlining, or allocating rc inside the stack frame of the main) but you can't rely on them. Ahh ok. Because of issues with const members (copying them when they are composed in other classes does not work well) I'm trying to get around the copy by storing reference data as const(T) *. This is why I'm asking. So here are some follow ups: - As I see it there is grave risk. Is the risk introduced by the fact that I am storing a member as const(T)*? Risk is that pointer to local variable is escaped, not because it is stored in const qualified pbject. - I assume that if I had created the RC instance on the heap there would be no problems. Is there a way in general to ensure that a const(T)* is referring to something on the heap as opposed to the stack (ideally at compile time). Yes, you can explicitly allocate on heap. You can check whether data is on heap, stack, tls, or just global object by inspecting pointer at runtime. Ideally there would be such function in druntime. It is impossible to do this in CT (except if comiler support flow analysis and can prove in some scenarious that data is on stack or not, but due to separate compilation it is impossible to do in general case) (and probably shouldn't). - What is the root problem - having a const(T)* member which then requires code to take address, or taking address? My first thought was, just never take address of local static variable - which is generally good advice. But once you are in a function that takes ref const(T) you can take the address of that as well - see modification below. This suffers the same problem but in a less obvious way. Any suggestions welcome. Thanks Dan import opmix.mix; import plus.tvm.rate_curve; import std.stdio; struct RC { this(this) { data = data.dup; } int[] data; } struct T { const(RC) *rc; void goo() { writeln("Data is ", rc.data); } } T goo(ref RC rc) { return T(&rc); } T foo() { RC rc = { [1,2,3] }; writeln("Address is ", &rc); return goo(rc); } void main() { T t = foo(); t.goo(); writeln("Address is ", t.rc); } Yes, this is known issue. There are lots of other tricks to break the language.
Re: structs holding on to reference data by pointer
On Thursday, 31 October 2013 at 16:16:36 UTC, bearophile wrote: That's wrong code, you are escaping a reference to memory (of rc variable) allocated in the stack frame of foo(). The D compiler is not smart enough to recognize the bug. There are optimizations that patch and avoid this bug (like inlining, or allocating rc inside the stack frame of the main) but you can't rely on them. Ahh ok. Because of issues with const members (copying them when they are composed in other classes does not work well) I'm trying to get around the copy by storing reference data as const(T) *. This is why I'm asking. So here are some follow ups: - As I see it there is grave risk. Is the risk introduced by the fact that I am storing a member as const(T)*? - I assume that if I had created the RC instance on the heap there would be no problems. Is there a way in general to ensure that a const(T)* is referring to something on the heap as opposed to the stack (ideally at compile time). - What is the root problem - having a const(T)* member which then requires code to take address, or taking address? My first thought was, just never take address of local static variable - which is generally good advice. But once you are in a function that takes ref const(T) you can take the address of that as well - see modification below. This suffers the same problem but in a less obvious way. Any suggestions welcome. Thanks Dan import opmix.mix; import plus.tvm.rate_curve; import std.stdio; struct RC { this(this) { data = data.dup; } int[] data; } struct T { const(RC) *rc; void goo() { writeln("Data is ", rc.data); } } T goo(ref RC rc) { return T(&rc); } T foo() { RC rc = { [1,2,3] }; writeln("Address is ", &rc); return goo(rc); } void main() { T t = foo(); t.goo(); writeln("Address is ", t.rc); }
Re: fieldPostBlit - what is wrong with this and workarounds
On Thursday, 31 October 2013 at 15:56:45 UTC, Maxim Fomin wrote: On Thursday, 31 October 2013 at 14:03:28 UTC, Daniel Davidson wrote: Given this code: import plus.tvm.rate_curve; struct T { RateCurve m; } struct S { const(T) rc; } I get this error: Error: mutable method plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not callable using a const object Is this fundamentally incorrect? I abandoned immutable in hopes that const would be more manageable and so far it has. But these types of issues still crop up and stop me in my tracks. What are the requirements on RateCurve and T for this to work? Thanks Dan D language is fundamentally incorrect here. There are sufficient issues in bugzilla (one which bearophile provided is actually relevant, it shows same problem from a little bit different aspect) and the problem tends to pop up quire regularly. It looks like nothing is done because it is design issue and although there were attempts to come up with, no idea is viewed as final solution. The easiest way to solve problem is to strip const. I'm think you may be correct... but what specifically is incorrect about the language? When I see __fieldPostBlit I get the feeling it is more an implementation issue than the language. If as you suggest, D language is fundamentally broken - is it possible we can just get a plan for fixing it? To me this seems like a huge design hole and I come back to the threads with questions again and again and I really don't know how others manage the use of const/immutable. I've already given up on immutable. If I have to strip const as well then that is a huge pain and unfortunate since the concept seems sound and well argued in TDPL. Trying to mess with mutable/const/immutable on mostly working code is like playing whack a mole.
Re: structs holding on to reference data by pointer
On Thursday, 31 October 2013 at 15:11:48 UTC, Daniel Davidson wrote: The following seems to work, but feels like luck. When foo returns rc should be taken off the stack. If I recall, in C++ something like this would crash, but why not here? This ineed runs by luck. In C++ it would not necessarily crash, but it is UB like in D. You can workaround issue by: import std.stdio; struct S { int[] data; const this(this) { S *s = cast(S*)&this; s.data = s.data.dup; } } struct SS { const S s; } void main() { S s1, s2; s1.data = s2.data = [0,1]; s1 = s2; s2.data[0] = 1; writeln(s1.data); } but this breaks constness and penalty is that function with casts cannot be run in safe code. (However in this case there is no logical mutation because 's' keeps its value. Probably self modifying const postblits should be allowed with restriction that it is programmer duty to ensure that const object is duplicated, but not mutated - at least judging by postblit definition it is reasonable assumption with some degree of confidence.)
Re: structs holding on to reference data by pointer
Daniel Davidson: import std.stdio; struct RC { this(this) { data = data.dup; } int[] data; } struct T { const(RC) *rc; void goo() { writeln("Data is ", rc.data); } } T foo() { RC rc = { [1,2,3] }; return T(&rc); } void main() { T t = foo(); t.goo(); } That's wrong code, you are escaping a reference to memory (of rc variable) allocated in the stack frame of foo(). The D compiler is not smart enough to recognize the bug. There are optimizations that patch and avoid this bug (like inlining, or allocating rc inside the stack frame of the main) but you can't rely on them. Bye, bearophile
Re: fieldPostBlit - what is wrong with this and workarounds
On Thursday, 31 October 2013 at 14:03:28 UTC, Daniel Davidson wrote: Given this code: import plus.tvm.rate_curve; struct T { RateCurve m; } struct S { const(T) rc; } I get this error: Error: mutable method plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not callable using a const object Is this fundamentally incorrect? I abandoned immutable in hopes that const would be more manageable and so far it has. But these types of issues still crop up and stop me in my tracks. What are the requirements on RateCurve and T for this to work? Thanks Dan D language is fundamentally incorrect here. There are sufficient issues in bugzilla (one which bearophile provided is actually relevant, it shows same problem from a little bit different aspect) and the problem tends to pop up quire regularly. It looks like nothing is done because it is design issue and although there were attempts to come up with, no idea is viewed as final solution. The easiest way to solve problem is to strip const.
Re: fieldPostBlit - what is wrong with this and workarounds
On Thursday, 31 October 2013 at 14:28:31 UTC, bearophile wrote: Daniel Davidson: I get this error: Error: mutable method plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not callable using a const object Related: http://d.puremagic.com/issues/show_bug.cgi?id=4867 Bye, bearophile Thanks but I don't see the relation.
structs holding on to reference data by pointer
The following seems to work, but feels like luck. When foo returns rc should be taken off the stack. If I recall, in C++ something like this would crash, but why not here? import std.stdio; struct RC { this(this) { data = data.dup; } int[] data; } struct T { const(RC) *rc; void goo() { writeln("Data is ", rc.data); } } T foo() { RC rc = { [1,2,3] }; return T(&rc); } void main() { T t = foo(); t.goo(); } I'm trying to get around issues with struct T { const(S) s; } by avoiding the postblit and having const(S) *s. I just want to know that it is always safe and if it is how? Thanks Dan
Re: fieldPostBlit - what is wrong with this and workarounds
Daniel Davidson: I get this error: Error: mutable method plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not callable using a const object Related: http://d.puremagic.com/issues/show_bug.cgi?id=4867 Bye, bearophile
fieldPostBlit - what is wrong with this and workarounds
Given this code: import plus.tvm.rate_curve; struct T { RateCurve m; } struct S { const(T) rc; } I get this error: Error: mutable method plus.models.dossier.__unittestL42_1.T.__fieldPostBlit is not callable using a const object Is this fundamentally incorrect? I abandoned immutable in hopes that const would be more manageable and so far it has. But these types of issues still crop up and stop me in my tracks. What are the requirements on RateCurve and T for this to work? Thanks Dan
Re: D / GtkD for SQL Server
On Sunday, 27 October 2013 at 00:06:35 UTC, John Joyus wrote: On 10/25/2013 04:04 AM, Gary Willoughby wrote: 1). Does D has any support for MSSQL? See here: http://forum.dlang.org/thread/qcxoafwuachwnnwqk...@forum.dlang.org Thanks for the link, but what I meant by MSSQL is Microsoft SQL Server. Not MySQL. John, It's interesting if you can connect to the MS SQL.
Re: Cast delegate and functions.
On Thursday, 31 October 2013 at 13:12:31 UTC, Wolftein wrote: void delegate(Event) void delegate(T) Where T is a class that inherits Event. I'm trying to cast (void delegate(T)) to (void delegate(Event)) to be able to store them in a map, but when i cast them i get null exeception. Same thing for cast things like this TemplateClass!Plugin TemplateClass!OtherTypeOfPlugin -> Being OtherTypeOfPlugin inherit Plugin Using C++ this is allowed. It is not safe to allow this. auto f = delegate(T x) { x.methodOfT(); } auto g = cast(void delegate(Event)) f; g(new Event()); This would call methodOfT on an Event object, which does not have that method. Co- and Contravariance for such stuff is tricky. Here is a discussion on how C# 4.0 approaches it: http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-sharp-4-0
Cast delegate and functions.
void delegate(Event) void delegate(T) Where T is a class that inherits Event. I'm trying to cast (void delegate(T)) to (void delegate(Event)) to be able to store them in a map, but when i cast them i get null exeception. Same thing for cast things like this TemplateClass!Plugin TemplateClass!OtherTypeOfPlugin -> Being OtherTypeOfPlugin inherit Plugin Using C++ this is allowed.
Re: Cast delegate and functions.
On Thursday, 31 October 2013 at 13:12:31 UTC, Wolftein wrote: void delegate(Event) void delegate(T) Where T is a class that inherits Event. I'm trying to cast (void delegate(T)) to (void delegate(Event)) to be able to store them in a map, but when i cast them i get null exeception. Same thing for cast things like this TemplateClass!Plugin TemplateClass!OtherTypeOfPlugin -> Being OtherTypeOfPlugin inherit Plugin Using C++ this is allowed. Well with the last verion delegate and function cast works fine, but not for TemplateClass.
Re: UFCS and error messages
Am Thu, 31 Oct 2013 11:58:18 +0100 schrieb "Andrea Fontana" : > Check this simple code: > > import std.stdio; > import std.conv; > > bool is_zero(T)(T i) { return to!int(i) == 0; } > > void main() { "0".is_zero.writeln; } > > This code print "true" of course. > > If you replace "to!int(i) == 0" with "i == 0" compiler gives this > error: > > "Error: no property 'is_zero' for type 'string'" > > But: > > is_zero("0") > > instead gives this: > > Error: incompatible types for ((i) == (0)): 'string' and 'int' > > Shoudn't "0".is_zero give this error too? If you see it as a universal function call, yes. But if you see it as an augmented property of string, then no. -- Marco
Re: UFCS and error messages
Andrea Fontana: Shoudn't "0".is_zero give this error too? Possibly yes. I put this enhancement request in Bugzilla few months ago, but I don't remember its number now. Bye, bearophile
UFCS and error messages
Check this simple code: import std.stdio; import std.conv; bool is_zero(T)(T i) { return to!int(i) == 0; } void main() { "0".is_zero.writeln; } This code print "true" of course. If you replace "to!int(i) == 0" with "i == 0" compiler gives this error: "Error: no property 'is_zero' for type 'string'" But: is_zero("0") instead gives this: Error: incompatible types for ((i) == (0)): 'string' and 'int' Shoudn't "0".is_zero give this error too?
Re: howto make a function get types form compile-time-parameters AND from arguments ?
by changeing T[] makeArray(T,U)(immutable U[] paramArray) into T[] makeArray(T,U)(const U paramArray) if (isAggregateType!(U) || is Array!(U)) everything works perfectly Thanks very much --- Uplink_Coder
Re: std.range.chunk without length
On Wednesday, 30 October 2013 at 20:43:54 UTC, qznc wrote: On Wednesday, 30 October 2013 at 00:20:12 UTC, Stephan Schiffels wrote: Hi, I'd like a version of std.range.chunk that does not require the range to have the "length" property. As an example, consider a file that you would like parse by lines and always lump together four lines, i.e. import std.stdio; void main() { auto range = File("test.txt", "r").byLine(); foreach(c; range.chunks(4)) { //doesn't compile writefln("%s %s", c[0], c[1]); } } Your wish was granted. Monarchdodra was sent back in time [0], so it is already fixed in HEAD. You could try the dmd beta [1]. [0] https://github.com/D-Programming-Language/phobos/pull/992 [1] http://forum.dlang.org/thread/526dd8c5.2040...@digitalmars.com Ah, awesome! Should have updated my github clone then. Thanks, Stephan
Re: howto make a function get types form compile-time-parameters AND from arguments ?
On Thursday, 31 October 2013 at 10:18:25 UTC, Uplink_Coder wrote: Maybe I shuold be more specific : for now It's: T[] arr = makeArray!(T,U)([some,instances,of,U]); but I would like it to be: auto arr = makeArray!(T)([some,instances,of,U]); void foo(T,U)(U arg){} int a; foo!(double)(a); //U is inferred as int void bar(T,U)(U[] arg){} long[] b; foo!(double)(b); //U is in inferred as long However, be aware that you can't pass mutable or const data as an immutable argument. Perhaps the signature that would work better for you would be T[] makeArray(T,U)(const U[] paramArray)
Re: new Type[count] takes too much?
On Thursday, October 31, 2013 11:16:35 Namespace wrote: > Hm, seems not very performant for a *system* language. But fine, > thanks for your explanation. :) I believe that C's malloc does the same thing. - Jonathan M Davis
Re: howto make a function get types form compile-time-parameters AND from arguments ?
Maybe I shuold be more specific : for now It's: T[] arr = makeArray!(T,U)([some,instances,of,U]); but I would like it to be: auto arr = makeArray!(T)([some,instances,of,U]);
Re: new Type[count] takes too much?
On Thursday, 31 October 2013 at 10:12:10 UTC, Jonathan M Davis wrote: On Thursday, October 31, 2013 10:59:48 Namespace wrote: On Thursday, 31 October 2013 at 09:48:23 UTC, safety0ff wrote: > On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace > wrote: >> I'm sure we had already this conversation but I don't find >> the >> thread. >> >> T[] buffer = new T[N]; assumes more space than stated (in >> average 2010 elements more. See: >> http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like >> reserve and that is IMO wrong. If I reserve memory with >> buffer.reserve(N), I want to have at least N elements. That >> behaviour is correct. But if I use new T[N] I mostly want >> exactly N elements and no extra space. >> >> Thoughts? > > To me it looks like it is derived directly from the way the > GC > allocates chunks: > Next power of two if less than 4096 otherwise some multiple > of > 4096. > > Unless you modify the GC, this behaviour is present whether > you > can see it or not (http://dpaste.dzfl.pl/5481ffc2 .) Maybe (and hopefully) I'm wrong, but it seems that the static array is on the heap? T[] buffer = new T[N]; is a dynamic array. Now, in the code in your dpaste link, you have a static array which is in a struct which is on the heap, so that's different, but now you're dealing with the amount of memory that gets allocated on the heap for the struct, and as the GC is going to allocate in multiples of 2, more than the size of the struct is going to be allocated. It might be that some of the memory beyond the end of the struct might actually be used for another object rather than the struct using the memory block by itself (I'm not sure what the GC does in that regard), but it's definitely going to allocate in multiples of 2, so if the GC has to go up another multiple of 2 to make the struct fit, it'll go up another multiple of 2. - Jonathan M Davis Hm, seems not very performant for a *system* language. But fine, thanks for your explanation. :)
Re: new Type[count] takes too much?
On Thursday, October 31, 2013 10:59:48 Namespace wrote: > On Thursday, 31 October 2013 at 09:48:23 UTC, safety0ff wrote: > > On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace wrote: > >> I'm sure we had already this conversation but I don't find the > >> thread. > >> > >> T[] buffer = new T[N]; assumes more space than stated (in > >> average 2010 elements more. See: > >> http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like > >> reserve and that is IMO wrong. If I reserve memory with > >> buffer.reserve(N), I want to have at least N elements. That > >> behaviour is correct. But if I use new T[N] I mostly want > >> exactly N elements and no extra space. > >> > >> Thoughts? > > > > To me it looks like it is derived directly from the way the GC > > allocates chunks: > > Next power of two if less than 4096 otherwise some multiple of > > 4096. > > > > Unless you modify the GC, this behaviour is present whether you > > can see it or not (http://dpaste.dzfl.pl/5481ffc2 .) > > Maybe (and hopefully) I'm wrong, but it seems that the static > array is on the heap? T[] buffer = new T[N]; is a dynamic array. Now, in the code in your dpaste link, you have a static array which is in a struct which is on the heap, so that's different, but now you're dealing with the amount of memory that gets allocated on the heap for the struct, and as the GC is going to allocate in multiples of 2, more than the size of the struct is going to be allocated. It might be that some of the memory beyond the end of the struct might actually be used for another object rather than the struct using the memory block by itself (I'm not sure what the GC does in that regard), but it's definitely going to allocate in multiples of 2, so if the GC has to go up another multiple of 2 to make the struct fit, it'll go up another multiple of 2. - Jonathan M Davis
Re: Error when trying to compile with --profile.
31-Oct-2013 13:28, bearophile пишет: Wolftein: Using --debug or --release works fine. But when i use --profile i get: c:\Program Files (x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2187): Error: balancedParens is not nothrow c:\Program Files (x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2188): Error: balancedParens is not nothrow Error: this.__invariant is not nothrow Error: this.__invariant is not nothrow Is this bug in Bugzilla? DMD 2.064 should not come out with this problem. It would unless the above is a regression. The release can't be stalled forever. Do you have a small test case? Bye, bearophile -- Dmitry Olshansky
Re: new Type[count] takes too much?
On Thursday, 31 October 2013 at 09:48:23 UTC, safety0ff wrote: On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace wrote: I'm sure we had already this conversation but I don't find the thread. T[] buffer = new T[N]; assumes more space than stated (in average 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like reserve and that is IMO wrong. If I reserve memory with buffer.reserve(N), I want to have at least N elements. That behaviour is correct. But if I use new T[N] I mostly want exactly N elements and no extra space. Thoughts? To me it looks like it is derived directly from the way the GC allocates chunks: Next power of two if less than 4096 otherwise some multiple of 4096. Unless you modify the GC, this behaviour is present whether you can see it or not (http://dpaste.dzfl.pl/5481ffc2 .) Maybe (and hopefully) I'm wrong, but it seems that the static array is on the heap?
Re: new Type[count] takes too much?
On Thursday, October 31, 2013 10:15:51 Namespace wrote: > I'm sure we had already this conversation but I don't find the > thread. > > T[] buffer = new T[N]; assumes more space than stated (in average > 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It > behaves exactly like reserve and that is IMO wrong. If I reserve > memory with buffer.reserve(N), I want to have at least N > elements. That behaviour is correct. But if I use new T[N] I > mostly want exactly N elements and no extra space. > > Thoughts? You're making the assumption that it would be normal to not want to then append to something you allocated with new T[N], and I don't think that that's a valid assumption. Also, from what I understand of how allocators work, they normally grab memory in sizes which are a multiple of 2, so I would expect it to be highly abnormal to ever get exactly the amount of memory that you requested. You're pretty much always going to get extra. - Jonathan M Davis
Re: improving '$' to work with other functions (eg: indexed)
On Thursday, October 31, 2013 02:46:32 Timothee Cour wrote: > can we support this and similar use cases ? > > import std.range; > void main(){ > auto a=[1,2,3,4]; > auto b1=a.indexed([0,a.length-1]);//OK > auto b2=a.indexed([0,$-1]);//NG > } Aren't you creating new arrays to pass to indexed here? If that's the case, $ isn't associated with any particular array, and I don't see how it could work. Now, there's issue# 7177 http://d.puremagic.com/issues/show_bug.cgi?id=7177 which aims at getting opDollar to work with ranges which have length (which it generally doesn't at this point), so that might be related to what you're looking for, but if what you're looking for is [0, $-1] to work on its own, I don't see how that could ever work, because $ only works when slicing or indexing, and [0, $-1] in the context above is an array literal. - Jonathan M Davis
Re: new Type[count] takes too much?
On Thursday, 31 October 2013 at 09:15:53 UTC, Namespace wrote: I'm sure we had already this conversation but I don't find the thread. T[] buffer = new T[N]; assumes more space than stated (in average 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like reserve and that is IMO wrong. If I reserve memory with buffer.reserve(N), I want to have at least N elements. That behaviour is correct. But if I use new T[N] I mostly want exactly N elements and no extra space. Thoughts? To me it looks like it is derived directly from the way the GC allocates chunks: Next power of two if less than 4096 otherwise some multiple of 4096. Unless you modify the GC, this behaviour is present whether you can see it or not (http://dpaste.dzfl.pl/5481ffc2 .)
howto make a function get a types form compilte-time-parameters AND from the arguments ?
(this is my first post so please alert me to any breaches of forum etiquette) Hello, I have a problem with a helper function I'm writeting. T[] makeArray(T,U)(immutable U[] paramArray) { T[] result; foreach (param;paramArray) { result ~= T(param); } return result; } and I would like not to take the compile-time-parameter U but insead infering it form the argumet. is it possible ? and if. how ? Uplink_Coder
improving '$' to work with other functions (eg: indexed)
can we support this and similar use cases ? import std.range; void main(){ auto a=[1,2,3,4]; auto b1=a.indexed([0,a.length-1]);//OK auto b2=a.indexed([0,$-1]);//NG }
Re: new Type[count] takes too much?
On Thursday, 31 October 2013 at 09:27:11 UTC, bearophile wrote: Namespace: T[] buffer = new T[N]; assumes more space than stated (in average 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like reserve and that is IMO wrong. If I reserve memory with buffer.reserve(N), I want to have at least N elements. That behaviour is correct. But if I use new T[N] I mostly want exactly N elements and no extra space. Thoughts? In Python if you append items to an array, it sovra-allocates, Never heard of 'sovra'. What does it mean? but if you create an array with the [x] * n syntax, then it creates a list (array) exactly of size n. Bye, bearophile So you agree with me.
Re: new Type[count] takes too much?
Namespace: T[] buffer = new T[N]; assumes more space than stated (in average 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like reserve and that is IMO wrong. If I reserve memory with buffer.reserve(N), I want to have at least N elements. That behaviour is correct. But if I use new T[N] I mostly want exactly N elements and no extra space. Thoughts? In Python if you append items to an array, it sovra-allocates, but if you create an array with the [x] * n syntax, then it creates a list (array) exactly of size n. Bye, bearophile
Re: Error when trying to compile with --profile.
Wolftein: Using --debug or --release works fine. But when i use --profile i get: c:\Program Files (x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2187): Error: balancedParens is not nothrow c:\Program Files (x86)\DLang\dmd2\windows\bin\..\..\src\phobos\std\path.d(2188): Error: balancedParens is not nothrow Error: this.__invariant is not nothrow Error: this.__invariant is not nothrow Is this bug in Bugzilla? DMD 2.064 should not come out with this problem. Do you have a small test case? Bye, bearophile
new Type[count] takes too much?
I'm sure we had already this conversation but I don't find the thread. T[] buffer = new T[N]; assumes more space than stated (in average 2010 elements more. See: http://dpaste.dzfl.pl/af92ad22c). It behaves exactly like reserve and that is IMO wrong. If I reserve memory with buffer.reserve(N), I want to have at least N elements. That behaviour is correct. But if I use new T[N] I mostly want exactly N elements and no extra space. Thoughts?