Re: What's up with GDC?
Real professionals won't have difficulties to find binaries for ldc: https://github.com/ldc-developers/ldc/releases -- Bien cordialement, Ch.Meessen > Le 10 juin 2016 à 22:30, Joerg Joergonson via Digitalmars-d-learn >a écrit : > >> On Friday, 10 June 2016 at 19:51:19 UTC, Johan Engelen wrote: >>> On Friday, 10 June 2016 at 19:37:13 UTC, Joerg Joergonson wrote: >>> arm-linux-genuabi? arm-linux-gnueableihfqueridsofeyfh? >>> aifh-fkeif-f-fdsskjhfkjfafaa? >> >> Rofl! >> >>> and ldc requires building from sources(actually I didn't have too much >>> trouble with installing it but it doesn't work with my libs because of the >>> crappy coff issues that D has had since birth(it's like a tumor)). >> >> Why do you have to build from sources? Any details about the problems you >> see? >> >> Thanks, >> Johan > > Well, the post was a bit incoherent because getting all this stuff working > is. I was searching for ldc and ran across some web site that had only the > sources(same for gdc). > > The point of it all is that things seem to be a bit discombobulated and make > D look bad. Professions won't use D if it can't be used professionally(not > that I'm a pro, just saying). > > Why isn't there a proper binaries for ldc and gdc that work out of the box > like dmd? There used to be. What's up with all this arm-linux-genuabi crap? > When one opens up the archive all the files are named that way too. There is > no explanation of what that means. Did some kid write this stuff in his > basement or is this suppose to be serious? Do people think about the end user > when creating this stuff or is it just a eureka moment "Lightbulb: Lets > create some spaghetti!". > > I would have thought things would have gotten easier and more logical but > that doesn't seem to be the case. > >
Re: String compare in words?
I didn't check assembly for '=='. What I have seen is that struct comparison in dmd is implemented as byte per byte compare even if the struct is 64bit long (e.g. Rebindable). I suppose dmd uses this strategy because struct/array may not be 64bit aligned, or they could have different alignment. In order to use the suggested optimization we need a good planet alignment. The effort to check that, or enforce it, is not worth the benefit on average. There could be a benefit in specific use cases where the alignment is ensured. I would be interested in such optimization with Rebindable. Can the 'is' operator be overloaded ? Le 30/05/2016 11:28, ag0aep6g via Digitalmars-d-learn a écrit : On 05/29/2016 10:40 PM, qznc wrote: bool string_cmp_opt(immutable(ubyte)[] x, immutable(ubyte)[] y) { Having "string" in the function name may be a bit misleading. This doesn't have any special functionality for text/characters/Unicode, does it? Should have const parameters, not immutable. pragma(inline, false); I think you have to put this pragma on the function signature, not in the body. Also, why prevent inlining of the function? if (x.length != y.length) return false; int i=0; int isn't large enough for array lengths. // word-wise compare is faster than byte-wise if (x.length > size_t.sizeof) for (; i < x.length - size_t.sizeof; i+=size_t.sizeof) { size_t* xw = cast(size_t*) [i]; size_t* yw = cast(size_t*) [i]; Typo: Should be `[i]` here. if (*xw != *yw) return false; } // last sub-word part for (; i < x.length; i+=1) { if (x[i] != y[i]) // byte compare return false; } return true; } Any comments or recommendations? Did you benchmark this against the built-in `==`, with ldc or gdc? If this is correct and faster than the built-in `==`, why isn't it the built-in `==`? -- Bien cordialement, Ch.Meessen
Maximum size of an string ?
Hi :) Has someone tested the maximum size of a D string variable for both 32 and 64 bits platforms ? Is it different from the maximum size of a char[] ? Oo` -- JC
Re: Maximum size of an string ?
Than you Ali :0 I assume it is for UTF8 encoding. That's quite large enough. JC On Thursday, 14 November 2013 at 11:50:28 UTC, Ali Çehreli wrote: On 11/14/2013 02:10 AM, Jean Christophe wrote: Has someone tested the maximum size of a D string variable for both 32 and 64 bits platforms ? Is it different from the maximum size of a char[] ? Both string and char[] are implemented in the same way: a size_t for length and a pointer to data. (D arrays know their sizes.) So, the theoretical limit for both are size_t, which is the equivalent of uint or ulong dependending on 32-bit versus 64-bit. Ali
Re: std.json
On Thursday, 17 May 2012 at 18:55:57 UTC, Jarl André wrote: On Thursday, 17 May 2012 at 18:36:22 UTC, Jarl André wrote: On Thursday, 17 May 2012 at 14:08:27 UTC, Vincent wrote: On Sunday, 25 March 2012 at 17:50:45 UTC, Andrea Fontana wrote: Hope it's clear... Nope, it's something like chess and have nothing common with simplicity of the real JSON usage! This is example from C#: var p = JsonConvert.DeserializeObjectPerson({some real JSON, not crapy EOS}); var str = JsonConvert.SerializeObject(p); That's it! And this is how it SHOULD be implemented. Cannot catch why this stupid realization came to standard library... :(( I'm pretty new to D, but I am an expert Java developer, self claimed. I am fluent in many other languages as well. In all languages there is a basis documentation. Read the documentation for parseJSON and you'll see that it should be possible to send in a straight JSON string. I think the complex example is a bit stupid. It scares developers away from the lang. Feel free to correct me of course. The final proof of exisiting simplicity :) JSONValue[string] value = parseJSON({ \test\: \1\ }).object; writeln(value[test].str); This outputs 1 +1
Re: fedora libcurl-gnutls issue
On Friday, 27 September 2013 at 19:44:18 UTC, Joshua Niehus wrote: On Friday, 27 September 2013 at 16:52:49 UTC, Dicebot wrote: Simply building dmd/phobos from git tag should result in proper linkage. Nothing is ever simple with me :) Thanks Dejan and Dicebot +1, build phobos from sources on your Fedora platform. Anyway in my case after doing that, which was ok, I finally moved to Debian which has much less stupid bugs than Fedora 19 and provides me a far more stable D programming environment.
Re: Range of random numbers
bearophile , dans le message (digitalmars.D.learn:35148), a écrit : Why don't you write a little benchmark to compare the performance of the two versions? Because I'm interested in the code's meaning for the human reader, not the performance. I actually think : map!(_= uniform(a, b))(repeat(0)) is better, because it puts the call to uniform first, and the _ indicates that the rest is unimportant. For you curiosity, this is the benchmark using: gdc (GCC) 4.7.0 20120322 (gdc 0.31 - r805:0414cec152c7, using dmd 2.057) and gdc -O3 testRNG.d ./a.out import std.array, std.range, std.algorithm, std.random, std.stdio, std.datetime; auto uniformRange1(T1, T2, T3)(T1 a, T2 b, T3 gen) { return map!((x) {return x();} ) (repeat((){return uniform(a, b, gen);})); } auto uniformRange2(T1, T2, T3)(T1 a, T2 b, T3 gen) { return map!((x) { return uniform(a, b, gen); })(repeat(0)); } auto uniformRange3(T1, T2, T3)(T1 a, T2 b, T3 gen) { return map!((x) { return uniform(a, b, gen); })(cycle([0])); } void f1() { auto ur = array(take(uniformRange1(0, 10, Xorshift(1)), 1000)); } void f2() { auto ur = array(take(uniformRange2(0, 10, Xorshift(1)), 1000)); } void f3() { auto ur = array(take(uniformRange3(0, 10, Xorshift(1)), 1000)); } void main() { auto b=benchmark!(f1, f2, f3)(1000); writeln(b[0].to!(seconds,double),s, , b[1].to!(seconds,double), s, , b[2].to!(seconds,double),s. ); // outputs : // 0.040437s, 0.0393537s, 0.0486439s } f2 performs 23% better than f3, and 3% better than f1. -- Christophe
Re: Range of random numbers
bearophile , dans le message (digitalmars.D.learn:35108), a écrit : What about (untested): auto uniformRange(T1 lower, T2 upper) { return count().map!(_ = uniform(lower, upper))(); } That looks like a workarround, not meaningful code. How about return repeat(_ =uniform(lower, upper)).map!(x = x())(); ? We could also use a template to make a range out of a delegate and avoid this workarround... struct RepeatDg(T) { T delegate() dg; this(T delegate() dg_) { dg = dg_; } @property enum bool empty = false; @property T front() { return dg(); } @property void popFront() {} }
Re: Allow empty field function arguments for default?
Jakob Ovrum , dans le message (digitalmars.D.learn:34948), a écrit : On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote: Named arguments would probably be better for this. fun(c = 5); Maybe so, but `fun(c = 5);` is not an additive change, while the OP's suggestion actually is. How about int c; fun(c = 5); ? -- Christophe
Re: Access violation using chain()
Brad Anderson , dans le message (digitalmars.D.learn:34902), a écrit : Perhaps I'm just misunderstanding something about closures but the following code seems to behave oddly: import std.stdio, std.range, std.algorithm, std.string; void main() { auto lst = [a, b]; auto rng = range_gen(lst); writeln(rng.take(5)); } auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); return chain(lst, a); // access violation //return a; // works } My guess is that chain takes lst by reference, just like the delegates for map, wo both are working on the same slice instance. The chain first pops elements from lst, and then calls the mapped sequence. At that time, lst is empty. You can just copy lst before you give it to chain (or to map's delegate) to solve this bug: auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); string[] lst2 = lst; return chain(lst2, a); // access violation }
Re: Static Associative Arrays
Jonathan M Davis , dans le message (digitalmars.D.learn:34332), a écrit : On Sunday, April 08, 2012 01:24:02 Caligo wrote: On Sat, Apr 7, 2012 at 11:01 PM, Jonathan M Davis jmdavisp...@gmx.com wrote: What do you mean my static associative arrays? Are you asking why you can't initialize a static variable which is an AA at compile time? e.g. - Jonathan M Davis The same way I can create a static array: int[4] = [1, 3, 4, 8]; // has value semantics and dynamic arrays: int[] = [1, 4, 2, 4]; // has reference semantics I want an associative array that has value semantics and it's size doesn't change, just like static arrays. Associative arrays are always on the heap. They always have reference semantics. It would be very expensive to have an AA with value semantics. They contains pointers all over the place. It would be equivalent to calling dup on them every time that you pass them to anything. And trying to put one on the stack would get very messy because all of the pointers involved. AAs are _completely_ different from dynamic and static arrays. Aside from the fact that they both have array in their name and both allow indexing of a sort, there's really no relation between them at all. Yet, one could imagine an associative array with a fixed size and fixed indexes, with no pointers. We could define a simple structure with a static array to store the data and methods to find the element associated with a key. But we could not use this structure in place of a classic associative array (for that we would need pointers obviously).
Re: Questions about the slice operator
Jonathan M Davis , dans le message (digitalmars.D.learn:34243), a Except that opSlice already works with ... What would this buy you? Having a specific range for a .. operator allows you to have them as parameters of any function. For example, this could be nice for multidimensional slicing: Matrix!(double, 6, 6) A; auto partOfA = A[1..3, 4..6]; Operations on several items of a container: Container B; B.remove(4..9); // remove 5 contiguous elements. etc.
Re: newbie question: Can D do this?
Timon Gehr , dans le message (digitalmars.D.learn:31142), a écrit : On 12/20/2011 03:18 PM, clk wrote: Thank you for your quick replies. I'm impressed by the helpfulness and dedication of the D community! Here's another one. Is there a way to pass arguments to functions by keyword as in the calls to f and g below? void f(int a = 0, int b = 1) {} void g(int a) {} void main() { f(b = 1, a = 0); // compile error g(a = 0); // also compile error } No, there are no named arguments in D. Having them would sometimes be useful, but the drawback is that the parameter names become part of the public interface. Well, that's precisely the point. And it is a drawback if parameters are systematically names, but not if it is triggered only on demand. Example : void foo(int a, int b:, int c:); void main() { foo(1, 2, 3); foo(1, c: 3, b: 2; foo(a: 1, b: 2, c: 3); // error : a is not a named parameter. } In the example, : is used to make a named parameter to recall the use when you call the function.
Re: writing iterators without code duplication. inout?
pompei2 , dans le message (digitalmars.D.learn:31164), a écrit : This is what I have, which works but has severe code duplication. I hoped inout would help me here, but I just can't figure it out. I also gave a try to ranges, but same thing again: I can only get it to work if I define my things twice. It's not optimal, and there is an ugly cast, but maybe this is a suitable workarrond for you : int delegate(int delegate(ref int)) doIter() const { return (int delegate(ref int) dg) { cast(typeof(this))(this).doIter()((ref int i) { int copy = i; dg(copy); }); } } Until int delegate(ref inout int) opApply() inout; and int delegate(int delegate(ref inout int)) doIter() inout; are made to work. (I actually don't know if there is any obstacles to do this).
Re: Abstract functions in child classes
FWIW, I agree with Addam. One of the things I like in D is that the langage is designed so that interpretations are made based on what you intend, and what you intend to do is checked. That is exactly what is done by using overwrite keyword. If you intend to make a non-abstract class, the compiler should check it is non-abstract and complain if it is not. This way, the error message pops where it belongs, i.e. at the class definition, not somewhere in another file where it is instanciated. It is not hard to add a specific unittest close to the class definition to test instanciation, but this is still much harder than writing 'abstract' at the beginning of the class definition when you intend to make it abstract (which is also much shorter than writing a sentence to indicate that the class is abstract in the documentation). For special use-cases, when you don't know if the class is abstract or not because it is a template, you should just be allowed to write something like 'auto abstract' and the problem is solved. Is is a really a larger pain to make this correction early to the langage, than to keep this little misfeature for years ? With an appropriate (and optional) warning to tell abstract class will soon have to be declared such for several years before there is an (optional) error, and maybe even a patch to make the correction automatically, that should not be such a pain. -- Christophe
Re: Stop TypeTuple as template parameter from expanding
bearophile , dans le message (digitalmars.D.learn:30429), a écrit : Tobias Pankrath: How would you do this? Do I need an extra template TypeList? It's the design of typetuples, they are auto-flattening. I have never appreciated this design. Maybe Walter likes them this way, or they can't be designed in another way, I don't know. You could always make them non-flattening by default, and create an operator to flatten them.
Re: std.container ranges
Steven Schveighoffer , dans le message (digitalmars.D.learn:30402), a The primitive for a container is remove(range). Ranges are essential to containers, and should be the major interface to them. Programmers have to learn ranges to use containers. Hiding ranges is not helping them. But here, it is more complicated than that, because range may be more powerful than iterators, they are less friendly to use when a single element reference has to be used. c.remove(find(c.all, E)); will not remove the first occurence of E, but all elements beyond E. so instead we have to write: c.remove(take(find(c[], E), 1)); Then it's too much. The problem is that range are not practical to refer to a single element in the container. We need to have single-element reference to manipulate the range. Then a function should be used to find such one-element reference. std.find is already taken, and can hardly be changed (although it should be name popUntil), but we can still use a find method of the container. auto r = take(find(c[], E), 1); should just be written: auto r = c.find(E); Then the syntax to remove a single element from c is acceptable: c.remove(c.find(E)). Now let us remove several consecutive elements from c, let us say, all elements between the value E and the next value F: | auto r = find(c[], E); | int i=0; | foreach(e, r) | if (e == F) break; | else ++i; | c.remove(take(r, i+1)); That is not practical at all, and in addition, it is not efficient, since r is walked again from E to F. If we add little methods to single element reference to make them behave a little like iterators, we can recreate ranges from two single element references, and regain all the power of iterators. To remove all elements from E to the next F included: auto r = c.find( E); c.remove(r, r.find(F)++); // or c.remove(range(r, r.find(F)++)); (I use the find method a bit like a joker in this exemple, it is just to get the idea). In conclusion, to refer to a single element of a container for simple operations, range looses against iterator. Ranges even loose to refer to a range of consecutive elements... Many alternatives are possible, but a simple iterator structure to refer to a single element, and that you can combine to recreate a range (and use all range algorithms) would be enough, and would complete the range interface to make them have no drawback against iterators.
Re: std.container ranges
Kagamin , dans le message (digitalmars.D.learn:30362), a écrit : Steven Schveighoffer Wrote: ahem, using dcollections: foreach(ref doRemove, cell; organism.purge) doRemove = cell.x == x cell.y == y; complexity: O(n) may be a generic iteration handler would be more useful? foreach(ref handler, cell; organism.each) if(cell.x == x cell.y == y) handler.removeCurrent(); it could provide a whole api, say, you may want to have lookahead foreach(ref handler, cell; organism.each) if(cell.x == x cell.y == y handler.next.x==0) handler.removeCurrent(); That's not easier than using Tobias' improved foreach: foreach(cell, cellRange; organism[]) if (cell.x == x cell.y == y) organism.remove(cellRange); If you want to use algorithm specialized and optimized for the container, I would prefer to use purge than each + handler. purge seems better to me, because it can be specialized for the container and for the action, and do not require to learn a new handler structure. each do not seem to add a lot to foreach(cell, cellRange; range), since it must be able to cope with any operation provided by handler, and any operation combinaisons...
Re: An issue with setting delegates via templates
Andrej Mitrovic , dans le message (digitalmars.D.learn:30315), a écrit : The new one: https://gist.github.com/1194497 I'll investigate this further then. OK, so there is indeed a filter to find a suitable delegate to load: @trusted T connect(T)(T handler) if(isHandler!(T, Types)); But only the first Bar.x function is picked and given to isHandler!(T, int) to check it can be called. Bar.x(double) do not pass this filter. I guess if the signature were: T connect(void handler(Types)); T connect(bool handler(Types)); etc... or maybe T connect(T : void handler(Types)) (T handler); T connect(T : bool handler(Types)) (T handler); etc... Then the compiler should be able to select the right Bar.x method. But with the isHandler filter,it is not able to find it. I don't see a way to improve isHandler to make it able to find the right Bar.x method, without modification of the compiler*, but I am not an expert here. * the compiler should allow all overloads of a function given as a template argument to be tested against the filter to choose the right one, and complain if several overloads match the filter. -- Christophe
Re: FIFO stack
Nick Sabalausky , dans le message (digitalmars.D.learn:30309), a écrit : Dominic Jones dominic.jo...@qmul.ac.uk wrote in message news:j89arh$2ua3$1...@digitalmars.com... Also an plain array is a good stack. :) I'd rather not use a plain array because (I assume) that when I push or pop using arrays, a swap array is created to resize the original. If this is not the case, then an array will certainly do. -Dominic The matter of using D's arrays as a LIFO is discussed the other branch of this thread (ie, you can do it, but it's slow because a pop then push will reallocate and copy), but as far as a FIFO: That may actually be reasonable to do as an array: Decreasing the length of an array (from either end) is a trivial matter that never allocates or copies. Appending to the end *usually* doesn't involve allocating. So the only issue I see it that the FIFO will march across memory. I guess that's probably not a problem as long as the GC knows it can reclaim the stuff you've popped off (Does it do that? Ie, if you do x = x[10..$]; and there's no other references, is the GC smart enough to reclaim those first ten spots? I guess I would assume so.) As far as I understand, if there is a pointer to an allocated memory block, the GC keeps the whole memory block. So the data at the beginning of x will be kept as long as x is not reallocated (but x will be reallocated at some point, because it can't walk across memory indefinitely, unless the GC is particularly efficient at avoiding reallocation). AFAIC, if I had to design a FIFO, I would use a circular array to avoid constant growing and reallocation of the array.
Re: Implicit cast to immutable
Steven Schveighoffer , dans le message (digitalmars.D.learn:30255), a écrit : On Fri, 21 Oct 2011 11:20:01 -0400, Christophe trav...@phare.normalesup.org wrote: Daniel Murphy , dans le message (digitalmars.D.learn:30139), a écrit : bearophile bearophileh...@lycos.com wrote in message news:j7jepi$prp$1...@digitalmars.com... Daniel Murphy: 2) immutable(int[]) fun() { return new int[]; } // conversion happens here immutable x = fun(); Bearophile's example is of the second, where it definately matters what the purity of the function is. This is the enhancement request I have written days ago: http://d.puremagic.com/issues/show_bug.cgi?id=6783 Bye, bearophile Yes, and the problem in that report is that the function is const-pure, not strong-pure. Without checking if the return type can contain a non-immutable reference from the arguments, it is not safe to implicitly convert the result to immutable. eg. immutable(int[]) foo(in int[] x) { return x; } auto g = [1, 2, 3]; auto a = foo(g.idup); //safe auto b = foo(g); // unsafe Checking at the call site is possible, but not from inside the function. int[] foo(in int[] x) { return new int[](3); } auto g = [1, 2, 3]; immutable a = foo(g.idup); // safe immutable b = foo(g); // unsafe, and easily rejected In your example, it is safe as the argument is not returned. Allowing this in the general case requires checking (recursively) that the return type does not contain any types that any of the arguments can implicitly convert to that are non-immutable. What is the rule ? The theoretical rule should be, if it can be proven (except for the case where a cast is used) the result is not a subset of the input, then the result can be implicitly cast to immutable. The actual rule may be more conservative, since it may be difficult to prove it. OK, it must be proven from the signature of the function alone, and not from the function body. The result of pure int[] foo(in int[] x); is castable to immutable, since elements of x are not supposed to escape the function. The result of pure int[] foo(const int[] x); is not, because the value return by foo may be elements of x. Only via cast. How does foo legally change const int[] data to int[] data without a cast? Note that the two functions you wrote are equivalent, since in translates to const scope and scope does nothing to array parameters. I meant: pure const(int)[] foo(const/in int[] x); But I thought scope was transitive like const, so it had effect on arrays. I find it pretty useless like that. A transitive scope could be very useful for purity checking and memory management optimisations. It would be useful for implicit casting to immutable too, even in no pure function. I may write about that later in another thread.
Re: scope struct?
Steve Teale , dans le message (digitalmars.D.learn:30117), a écrit : Is not needed because structs are inherently scope. I'm sure experienced D programmers do this all the time when they want something done on exit from a scope, but I never had, and maybe there are others who haven't, particularly if coming from a C++ 'use classes for everything' background. import std.stdio; bool glob; struct Sentinel { void function() doit; bool already; this(void function() f) { doit = f; already = false; } ~this() { if (!already) { writeln(Doing it now); doit(); } else writeln(Won't bother); } void dontBother() { already = true; } } void reset() { glob = false; } void main(string[] args) { glob = true; { Sentinel s = Sentinel(reset); writeln(Doing stuff in the scope); if (args.length = 2 args[1] == db) s.dontBother(); } writeln(glob); } void main(string[] args) { glob = true; { dontBother=false; scope(exit) { if (!dontBother) { writeln(Doing it now); glob = false; } else { writeln(Don't bother); } } writeln(Doing stuff in the scope); if (args.length = 2 args[1] == db) dontBother() = true; } writeln(glob); } If you're not running a test with a lot of writing, the scope clause is just: scope(exit) if (!dontBother) glob() = false; The scope exit clause will be run even if you exit via an exception (just like the sentinel's dstructor). As you can see, D as its own syntax to make things when the scope exits, so you don't need to build a sentinel struct. http://d-programming-language.org/exception-safe.html
Re: Implicit cast to immutable
Daniel Murphy , dans le message (digitalmars.D.learn:30139), a écrit : bearophile bearophileh...@lycos.com wrote in message news:j7jepi$prp$1...@digitalmars.com... Daniel Murphy: 2) immutable(int[]) fun() { return new int[]; } // conversion happens here immutable x = fun(); Bearophile's example is of the second, where it definately matters what the purity of the function is. This is the enhancement request I have written days ago: http://d.puremagic.com/issues/show_bug.cgi?id=6783 Bye, bearophile Yes, and the problem in that report is that the function is const-pure, not strong-pure. Without checking if the return type can contain a non-immutable reference from the arguments, it is not safe to implicitly convert the result to immutable. eg. immutable(int[]) foo(in int[] x) { return x; } auto g = [1, 2, 3]; auto a = foo(g.idup); //safe auto b = foo(g); // unsafe Checking at the call site is possible, but not from inside the function. int[] foo(in int[] x) { return new int[](3); } auto g = [1, 2, 3]; immutable a = foo(g.idup); // safe immutable b = foo(g); // unsafe, and easily rejected In your example, it is safe as the argument is not returned. Allowing this in the general case requires checking (recursively) that the return type does not contain any types that any of the arguments can implicitly convert to that are non-immutable. What is the rule ? The result of a pure function can be cast to immutable if the arguments are immutable. That requires specific checking by the compiler. The real type of the argument prior to the conversion to the argument type has to be checked. in, scope, or inout arguments are supposed to solve the problem with function site checking: without call-site checking, which are IMO a rather bad idea. The result of pure int[] foo(in int[] x); is castable to immutable, since elements of x are not supposed to escape the function. The result of pure int[] foo(const int[] x); is not, because the value return by foo may be elements of x.
Re: Ranges help
Xinok , dans le message (digitalmars.D.learn:30054), a écrit : This is in relation to my sorting algorithm. This is what I need to accomplish with ranges in the most efficient way possible: 1. Merge sort - This involves copying elements to a temporary buffer, which can simply be an array, then merging the two lists together. The important thing is that it may merge left to right, or right to left, which requires a bidirectional range. c[] = a[0..$/2]; foreach(a; arr) if(!b.empty !c.empty) if(b.front = c.front){ a = b.front; b.popFront(); } else{ a = c.front; c.popFront(); } 2. Range swap - First, I need to do a binary search, which requires a random access range. Then I need to swap two ranges of elements. while(!a.empty !b.empty){ swap(a.front, b.front); a.popFront(); b.popFront(); } That's the best I can come up with. I'm wondering if there's a more efficient way to accomplish what I have above. I also need to figure out the template constraints. Would this be correct? Or would this be too much? isRandomAccessRange !isFiniteRange isBidirectionalRange hasSlicing You should look at: std.algorithm.SetUnion std.algorithm.swapRanges -- Christophe
Re: contrary of std.utf.toUTFz!(const(wchar)*)
Trass3r , dans le message (digitalmars.D.learn:29978), a écrit : I feel a little stupid, but how to convert a wchar* zero terminated string into a wstring (DMD 2.055)? wstring w = cstr[0 .. strlenw(cstr)]; if cstr comes from c code, you cannot guarantee it is immutable. Moreover, cstr might point to 0.
Re: Implicit cast to immutable
bearophile , dans le message (digitalmars.D.learn:29961), a écrit : Andrej Mitrovic: Maybe: immutable(int[]) foo(in int[] x) pure { return new immutable(int[1]); } void main() {} I'd like to know why the code in my original post doesn't compile. I suspect it's a DMD bug, but I am not sure. The error message tells you why. new int[1] is not castable to immutable int[] (in a pure function). The solution is to change new int[1] to make it immutable directly. That is very consistent, so I don't think this should be considered as a bug. There may be an improvement to ask to make the compiler able to check when the cast to immutable is safe, but I don't think there is a bug. Or does this have something to do with implicit casts to immutable for pure functions? Right. I'm only vaguely familiar with pure.. I suggest you to use purity more and more in D, because it helps and with the recent bug fixes it is also becoming usable in D (but there are some significant problems left, example: map/filter are not pure yet). You would need to have pure delegates to have a real effect, wouldn't you ? -- Christophe
Re: Why an abstract pointer cannot be used as value in an associate array?
Cheng Wei , dans le message (digitalmars.D.learn:29865), a écrit : Thanks a lot. This solves the problem. However, it breaks the abstractness. Now in D side, we can call auto v = ab(). This does not make sense, because then v cannot be used in the C library. I don't understand why when we manipulate AB*, D compiler needs to know the size of struct ab. Moreover, when we use AB*[int], the D compiler complains about there's no opHash defined for AB. I don't think they are necessary at all. I guess D is not designed to use abstract classes because they are not needed in the language: the compiler reads all the symbols in the file before doing the real compilation, but there may be no real issue for the compiler, as long as you do not use the ab* for anything else than passing it to C code. You could file an enhancement request to support abstract pointer for the sake of interoperability with C. -- Christophe
Re: Multithreaded file IO?
Jerry , dans le message (digitalmars.D.learn:29830), a écrit : trav...@phare.normalesup.org (Christophe) writes: Jerry Quinn , dans le message (digitalmars.D.learn:29763), a écrit : What I really want is a shared fifo where the input is lines from a file, and many workers grab something from the fifo. They then push their results into a shared reordering output queue. My 2 cent advice: Does the queue really has to be a file ? You could read it completely before starting, and then just share your instructions as strings for example. Yes, these files could be large enough that the memory cost of loading is an issue. Also, I should be able to do this with input from stdin. At this point, I'm trying to figure out how to implement a shared fifo in D as much as solve my original problem :-) Ok, an idea then could be to make a separate thread that deal with the File object, or a big shared object well protected with a mutex, to ditribute instructions that are as much immutable as possible. Good luck.
Re: Why an abstract pointer cannot be used as value in an associate array?
what is the error message ?
Re: Using allSatisfy with template that takes multiple type arguments
Andrej Mitrovic , dans le message (digitalmars.D.learn:29825), a écrit : Thanks for the tips guys. I have another similar issue now, I want to check whether a type passes any of the predicates I list. This would be similar to anySatisfy, however anySatisfy takes one predicate and multiple types, and what I need is one type and multiple predicates, e.g.: anyPredicateSatisfy!(int, isNumeric, isIntegral); I've tried copying anySatisfy's code and modifying it to work: template anyPredicateSatisfy(T, F...) { static if (F.length == 0) { enum bool anySatisfy = false; } else static if (F.length == 1) { enum bool anySatisfy = (F[0])!T; } else { enum bool anySatisfy = (F[0])!T) || anySatisfy!(T, F[1 .. $]); ^ you mean anyPredicateSatisfy } } But the compiler thinks I'm doing C-style casts so this doesn't work. Any clues?
Re: Why is std.string.format a c-style variadic function?
Ellery Newcomer , dans le message (digitalmars.D.learn:29819), a écrit : On 09/26/2011 11:15 AM, Andrej Mitrovic wrote: On 9/26/11, Ellery Newcomer ellery-newco...@utulsa.edu wrote: std.metastrings.Format wouldn't be what you want, would it? Yep it is, Jonathan mentioned it above. thunderbird hates me. second time I give an answer made redundant by orphaned subthread. I've got the same problem with most of Jonathan's posts. I use flrn, an obsure news reader that nobody here probably knows about, so I thought it was just me. It seems that the Reference field in Jonathan's posts are unusual and break threads in some news reader. Would anyone know a solution (either for Elley and me, or for Jonathan)? -- Christophe
Re: How to check all values in a range are equal to some predicate?
Andrej Mitrovic , dans le message (digitalmars.D.learn:29755), a écrit : I want to use this in my unittests: assert(allEqual(Foo(1), obj1, obj2, obj3)); How would you implement a function like allEqual(needle, objects...) ? Maybe via reduce? I would use find. (the code was not compiled/tested at all) bool allEqual(R)(R r) if (isInputRange!R) { auto a = r.front; r.popFront(); return find!(b){return a!=b;}(r).empty; } and direct '==' operator for tuples: bool allEqual(T...)(T t) { return t[0] == t[1] allEqual(t[0], t[2..$]); } with an appropriate filter if I want to make something nice. -- Christophe
Re: Wrong const attribute?
Paolo Invernizzi , dans le message (digitalmars.D.learn:29680), a écrit : --Apple-Mail-7--919646864 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Hi all,=20 I've found nothing on bugzilla for that, what I'm missing? Or it's a = bug? (DMD 2.055) struct Bar { immutable int i; this(int j){ i =3D j; } } struct Foo { Bar bar; } void main(){ =20 auto b =3D Bar(1); =20 auto f =3D Foo(); f.bar =3D Bar(2); // Error: can only initialize const member bar = inside constructor =20 } Since your Bar has am immutable member, you cannot assign a Bar instance, which is what you do in the line where there is an error. If you want to perform an assignment, Bar.i cannot be immutable. If you really want Bar.i to be immutable, Foo must hold a pointer to Bar, so you can change this pointer, or Bar can be a class instead of a struct (which means Foo does contain a pointer to Bar, but you don't have to notice it). -- Christophe Travert
Re: toUTFz and WinAPI GetTextExtentPoint32W
Actually, I don't buy it. I guess the reason it's faster is that it doesn't check if the codepoint is valid. Why should it ? The documentation of std.utf.count says the string must be validly encoded, not that it will enforce that it is. Checking a string is valid everytime you use it would be very expensive. Actually, std.range.walkLength does not check the sequence is valid. See this test: void main() { string text = aléluyah; char[] text2 = text.dup; text2[3] = 'a'; writeln(walkLength(text2)); // outputs: 8 writeln(text2); // outputs: al\303aluyah } There is probably a way to check an utf sequence is valid with an unrollable loop. In fact you can easily get ridiculous overflowed negative lengths. Maybe we can put it here as unsafe and fast version though. Unless I am mistaken, the minimum length myCount can return is 0 even if the string is invalid. Also check std.utf.stride to see if you can get it better, it's the beast behind narrow string popFront. stride does not make much checking. It can even return 5 or 6, which is not possible for a valid utf-8 string ! The equivalent of myCount to stride would be: size_t myStride(char c) { // optional: // if ( (((c7)+1)1) - (((c6)+1)2) + (((c3)+1)5)) // throw new UtfException(Not the start of the UTF-8 sequence); return 1 + (((c6)+1)2) + (((c5)+1)3) + (((c4)+1)4); } That I compared to: size_t utfLikeStride(char c) { // optional: // immutable result = UTF8stride[c]; // if (result == 0xFF) // throw new UtfException(Not the start of the UTF-8 sequence); // return result; return UTF8stride[c]; } One table lookup is replaced by byte some arythmetic in myStride. I also took only one char as input, since stride only looked at the i-th character. Actually, if stride signature is kept to uint stride(char[] s, int i), I did not find any change with -O3. Average times for a lot of calls: (compiled with gcc, tested with -O3 and a homogenous distribution of valid characters from '\x00'..'\x7F' and '\xC2'..'\xF4') myStride no throws: 1112ms. utfLikeStride no throws: 1433ms. utfLikeStride throws:1868ms. (the current implementation). myStride throws: 8269ms. Removing throws from utfLikeStride makes it about 25% faster. Removing throws from myStride makes it about 7 times faster. With -O0, myStride gets less 10% slower than utfLikeStride (no throws). In conclusion, the fastest implementation is myStride without throws, and it beats the current implementation by about 40%. Changing std.utf.stride may be desirable. As I said earlier, the throws do not enforce the validity of the string. Really checking the validity of the string would cost much more, which may not be desirable, so why bother checking at all? A more serious benchmark could justify to change std.utf.stride. The improvement could be even better in real situation, because the lookup table of utfLikeStride may not be always at hand - this actually really depends on what the compiler does. In any case, this may not improve walkLength by more than a few percents. -- Christophe now I'll go back to my real work...
Re: const-immutable array argument?
bearophile , dans le message (digitalmars.D.learn:29609), a écrit : what's wrong in this code? void foo(const ref int[5] a) {} void main() { immutable int[5] arr; foo(arr); // Error? } I don't think it is wrong. Did you try changind the order of const and ref, or adding parenthesis ?
Re: Dynamic Array Question
To avoid having to change your other code, I'd do this: wchar[] t = ...; scope(exit) delete t; // add this line to the end of the function (after returning) There is another way, but it's not as easy: // put this at the top of file import core.memory; ... scope(exit) GC.free(t.ptr); does scope wchar[] t = ...; work too ?
Re: toUTFz and WinAPI GetTextExtentPoint32W
Jonathan M Davis , dans le message (digitalmars.D.learn:29637), a écrit : On Tuesday, September 20, 2011 14:43 Andrej Mitrovic wrote: On 9/20/11, Jonathan M Davis jmdavisp...@gmx.com wrote: Or std.range.walkLength. I don't know why we really have std.utf.count. I just calls walkLength anyway. I suspect that it's a function that predates walkLength and was made to use walkLength after walkLength was introduced. But it's kind of pointless now. - Jonathan M Davis I don't think having better-named aliases is a bad thing. Although now I'm seeing it's not just an alias but a function. std.utf.count has on advantage: someone looking for the function will find it. The programmer might not look in std.range to find a function about UFT strings, and even if he did, it is not indicated in walkLength that it works with (narrow) strings the way it does. To know you can use walklength, you must know that: -popFront works differently in string. -hasLength is not true for strings. -what is walkLength. So yes, you experienced programmer don't need std.utf.count, but newbies do. Last point: WalkLength is not optimized for strings. std.utf.count should be. This short implementation of count was 3 to 8 times faster than walkLength is a simple benchmark: size_t myCount(string text) { size_t n = text.length; for (uint i=0; itext.length; ++i) { auto s = text[i]6; n -= (s1) - ((s+1)2); } return n; } (compiled with gdc on 64 bits, the sample text was the introduction of french wikipedia UTF-8 article down to the sommaire - http://fr.wikipedia.org/wiki/UTF-8 ). The reason is that the loop can be unrolled by the compiler.
Re: toUTFz and WinAPI GetTextExtentPoint32W
Timon Gehr , dans le message (digitalmars.D.learn:29641), a écrit : Last point: WalkLength is not optimized for strings. std.utf.count should be. This short implementation of count was 3 to 8 times faster than walkLength is a simple benchmark: size_t myCount(string text) { size_t n = text.length; for (uint i=0; itext.length; ++i) { auto s = text[i]6; n -= (s1) - ((s+1)2); } return n; } (compiled with gdc on 64 bits, the sample text was the introduction of french wikipedia UTF-8 article down to the sommaire - http://fr.wikipedia.org/wiki/UTF-8 ). The reason is that the loop can be unrolled by the compiler. Very good point, you might want to file an enhancement request. It would make the functionality different enough to prevent count from being removed: walkLength throws on an invalid UTF sequence. I would be glad to do so, but I am quite new here, so I don't know how to. A little pointer could help. -- Christophe
Re: Should the 2.054 feature about warning on implicit fallthrough
bearophile , dans le message (digitalmars.D.learn:29532), a écrit : Well, I don't understand the error it gives :-) Are you able to explain it to me? import std.stdio; void main() { int i = 1; switch(i) { case 0: writeln(case 0); goto default; // needed here aLabel: writeln(a label); default: writeln(default); // But always falls through here } } test.d(10): Error: switch case fallthrough - use 'goto default;' if intended If there is a goto aLabel somewhere, the program could go to line 9. Then it should fall to the default statement, but the compiler asks for an explicit fallthrough, since default is not a simple label, but something like a case statement. -- Christophe
Re: Why can't templates with default arguments be instantiated without the bang syntax?
Simen Kjaeraas , dans le message (digitalmars.D.learn:29539), a écrit : On Thu, 15 Sep 2011 16:46:24 +0200, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: struct Foo(T = int) {} void main() { Foo foo; // fail Foo!() bar; // ok } It would be very convenient to be able to default to one type like this. For example, in CairoD there's a Point structure which takes doubles as its storage type, and then there's PointInt that takes ints. The reason they're not both a template Point() that takes a type argument is because in most cases the user will use the Point structure with doubles, and only in rare cases Point with ints. So to simplify code one doesn't have to write Point!double in all of their code, but simply Point. If the bang syntax wasn't required in presence of default arguments then these workarounds wouldn't be needed. How would you then pass a single-argument template as a template alias parameter? Example: template Foo( ) { template Bar( ) { } } template Baz(alias A) { mixin A!(); } void main( ) { mixin Baz!Foo; } Does this mixin Foo or Bar to main's scope? I don't get the problem. Maybe I am not used to mixin enough. Can you mixin normal templates, and not only mixin templates ? Anyway, why would this mixin Bar ? As I understand the proposition, only mixin Baz!(Foo.Bar); and of course mixin Baz!(Foo!().Bar) should mixin Bar. -- Christophe
Re: A question about purity
bearophile , dans le message (digitalmars.D.learn:29490), a écrit : Jonathan M Davis: However, Foo.y is not encapsulated by a strongly pure function at all. Other functions can alter alter it. So, it breaks purity. Thank you for your explanation :-) So, let's change the situation a bit. If the struct Foo is the only thing present in a module (to avoid someone to touch its private members), and the y field is private static only foo2 is able to touch it. In this case isn't foo2 weakly pure? No, because you change a variable that is global, even if it is private. In foo.foo1(), foo is changed, but it can be considered as an argument and a part of the result of foo1(). You cannot say this for Foo.y. Here is an example to illustrate what was meant with encapsulating with a pure function : struct Foo { int x; pure int foo1() { return x++; } private static int y; static pure int foo2() { return Foo.y++; // not pure: a global variable changes } } pure int test1(Foo foo) { auto a = foo.foo1(); // nothing changes outside test1: only the local // copy of foo changes. return a; } pure int test2() { auto b = Foo.foo2(); // error: Foo.y changes return b; } void main() { Foo foo; auto a = test1(foo); // only a copy of foo is changed. auto b = test1(foo); assert(a==b); // ok auto c = test2(); // error: Foo.y changes auto d = test2(); assert(c==d); // fails if test2 was indeed run twice. }
Re: package access specifier not usable within a class
Andrej Mitrovic , dans le message (digitalmars.D.learn:29388), a écrit : abstract class Foo { package void test(); } class Bar : Foo { override package void test() { } } function test.Bar.test cannot override a non-virtual function TDPL says package can only be used at class-level (i.e. package class Bar : Foo), outside classes or inside a struct. I want to hide a virtual method from client code, but another free function in a different module but in the same package as these classes needs access to that method. Are there any technical reasons why package is not allowed for virtual methods? private function are not virtual. All non-static non-private non-template member functions are virtual The spirit of this is that if a function is private, it should not be seen by its subclasses, which makes sens. However, this is a bit inconsistent with the fact that it can actually be seen by the whole file. It seems that package function inherited from the same behavior, enlarging this inconsistency. Your request seem to be reasonable, so I would say the langage should be improved in two ways: - private (and package) function can be specifically made virtual, but the problem is that virtual is not a keyword in d, and that would be weird to have to write final sometimes, and virtual some other times. - package function are virtual by default, which is the best solution IMO. It's not a huge problem if private methods cannot be virtual, if you can make them package virtual. In the meantime, I would make the method public, but prefix the name with an underscore to indicate it is morally private. I agree that it is relying on the client's good will. -- Christophe
Re: package access specifier not usable within a class
Christophe, dans le message (digitalmars.D.learn:29394), a écrit : Andrej Mitrovic , dans le message (digitalmars.D.learn:29388), a écrit : abstract class Foo { package void test(); } class Bar : Foo { override package void test() { } } function test.Bar.test cannot override a non-virtual function TDPL says package can only be used at class-level (i.e. package class Bar : Foo), outside classes or inside a struct. I want to hide a virtual method from client code, but another free function in a different module but in the same package as these classes needs access to that method. Are there any technical reasons why package is not allowed for virtual methods? private function are not virtual. All non-static non-private non-template member functions are virtual The spirit of this is that if a function is private, it should not be seen by its subclasses, which makes sens. However, this is a bit inconsistent with the fact that it can actually be seen by the whole file. It seems that package function inherited from the same behavior, enlarging this inconsistency. Your request seem to be reasonable, so I would say the langage should be improved in two ways: - private (and package) function can be specifically made virtual, but the problem is that virtual is not a keyword in d, and that would be weird to have to write final sometimes, and virtual some other times. - package function are virtual by default, which is the best solution IMO. It's not a huge problem if private methods cannot be virtual, if you can make them package virtual. In the meantime, I would make the method public, but prefix the name with an underscore to indicate it is morally private. I agree that it is relying on the client's good will. -- Christophe I forgot about protected. Making the function protected may be fine.
Re: About static variables
Nothing worth adding a confusing semantic to the langage. Just prefix your variable's name. Nobody will want to use myFunctionPrivateVariable outside of myFunction: class Foo { private size_t myFunctionPrivateCount; void myFunction() { alias myFunctionPrivateCount count; // .. count++; } }
Re: opDispatch shadowing toString - feature or bug?
Try to create the method: const void toString(void delegate(const(char)[]) sink, string formatString) { sink(toString()); }
Re: reading in text files
The default stdin doesn't have an end, and unless you type something in, there's no input at all. That's why the program just hangs. You can end keyboard stdin by typing ^D (Ctrl + D) under unix.