Re: Can D interface with Free Pascal?
FreeSlave: On Thursday, 28 January 2016 at 08:15:38 UTC, FreeSlave wrote: Not directly. You can declare cdecl function on Free Pascal side and call it as extern(C). What about extern(Pascal)? https://dlang.org/spec/attribute.html#linkage Bye, bearophile
Re: How to represent struct with trailing array member
Dibyendu Majumdar: On Thursday, 21 January 2016 at 21:52:06 UTC, Dibyendu Majumdar wrote: How should this be translated to D? Will D's array access allow data elements to be accessed beyond the size declared? Take a look at the code I've written here: http://rosettacode.org/wiki/Sokoban#Faster_Version You can also add a constructor to such struct, for safety and disallow default construction. Bye, bearophile
Re: Convert some ints into a byte array without allocations?
Yazan D: On Saturday, 16 January 2016 at 14:42:27 UTC, Yazan D wrote: ubyte[] b = (cast(ubyte*) )[0 .. int.sizeof]; Better to use the actual size: ubyte[] b = (cast(ubyte*) )[0 .. a.sizeof]; Bye, bearophile
Re: conver BigInt to string
Namal: Hello I am trying to convert BigInt to string like that while trying to sort it: void main() { import std.stdio, std.algorithm, std.conv, std.bigint, std.string; auto n = 17.BigInt ^^ 179; n.text.dup.representation.sort().release.assumeUTF.writeln; } Bye, bearophile
Re: conver BigInt to string
void main() { import std.stdio, std.algorithm, std.conv, std.bigint, std.string; auto n = 17.BigInt ^^ 179; n.text.dup.representation.sort().release.assumeUTF.writeln; } Better: n.to!(char[]).representation.sort().release.assumeUTF.writeln; Bye, bearophile
Re: array function
Namal: std::vector foo(int N){ std::vector V(N); int some_array[N]; VLAs are not present in D. Bye, bearophile
[Rosettacode] sum of powers conjecture
I've translated the C++ entry to D as third D entry, but it's not a good translation, I've just converted iterators to pointers instead of using ranges (the resulting speed is acceptable). You're welcome to improve it: http://rosettacode.org/wiki/Euler%27s_sum_of_powers_conjecture#Third_version Bye, bearophile
Re: Ada to D - an array for storing values of each of the six bits which are sufficient
Dennis Ritchie: Anybody can write a packed array on the D? I once badly represent the means by which we can write a packed array. Maybe for this you should use core.simd or unions? SIMD could be useful for some fancy bulk operations. But you should be able to write a good basic packed array without SIMD, perhaps about as nice as the Ada ones (D sometimes offers good enough tools to build what you need). Posible use: PackedDynamicArray!6 pa; // On heap. PackedFixedArray!(6, 300) pfa; // On stack. Bye, bearophile
Re: Ada to D - an array for storing values of each of the six bits which are sufficient
Dennis Ritchie: There is an array of values to store each of which sufficiently 6 bits. As it is written down on the D? You can't do it directly in D. Someone has to write a packed array data structure to do it. Bye, bearophile
Re: Implicit conversion error
Paul: When compiled on a 64 bit machine, this line int r = uniform(0, mobs.length); .length returns a size_t, and 0 is an int. uniform() probably decides to unify those types to a size_t. A size_t is 32 bit on 32 bit machines and 64 bits on 64 bit machines. But D int is always a 32 bit signed integer. D allows implicit assignment of a 32 bit size_t to int but not a 64 bit size_t to an int. I agree that it's a bit of a mess. Bye, bearophile
Re: Possible to write a classic fizzbuzz example using a UFCS chain?
Gary Willoughby: I wondered if it was possible to write a classic fizzbuzz[1] example using a UFCS chain? I've tried and failed. Is this OK? void main() { import std.stdio, std.algorithm, std.range, std.conv, std.functional; 100 .iota .map!(i = ((i + 1) % 15).predSwitch( 0, FizzBuzz, 3, Fizz, 5, Buzz, 6, Fizz, 9, Fizz, 10, Buzz, 12, Fizz, /*else*/ i.text)) .reverseArgs!writefln(%-(%s\n%)); } Bye, bearophile
Re: function ref param vs pointer param
On Friday, 24 April 2015 at 13:39:35 UTC, ref2401 wrote: processPointer(ms); I think doing this way is more descriptive. Now all readers know that ms might be changed inside the function. C# avoids that problem requiring (in most cases) the usage of ref at the calling point too. But this idea was refused for D (also because it goes against UFCS chains). Bye, bearophile
Re: function ref param vs pointer param
ref2401: void processRef(ref MyStruct ms) { writeln(processRef: , ms); } void processPointer(MyStruct* ms) { writeln(processPointer: , *ms); ref params don't need the * every time you use them inside the function, and don't need the when you call the function. Bye, bearophile
Re: multiSort for sorting AA by value
Chris: I'm happy with it, but maybe there is a more concise implementation? This is a bit shorter and a bit better (writefln is not yet able to format tuples nicely): void main() { import std.stdio: writeln; import std.algorithm.sorting: multiSort; import std.array: array; const size_t[string] wCount = [ hamster: 5, zorro: 80, troll: 90, algorithm: 80, beer: 80 ]; auto pairs = wCount.byKeyValue.array; assert(wCount.length == pairs.length); pairs.multiSort!(q{a.value b.value}, q{a.key b.key}); assert(pairs[2].key == beer); foreach (const ref it; pairs) writeln(it.key, : , it.value); } Bye, bearophile
Re: Structural exhaustive matching
Jadbox: I'm curious on what the best way to do ADTs in D. Sometimes there's no best way, there are several alternative ways with different tradeoffs. D isn't a functional language and there's no really good way to do ADTs in D. You can use plus a final switch. Or you can use Algebraic from Phobos. Sometimes you can use another Phobos function that simulates an improved switch. Or often you can just give up at using ADTs in D and use what other solutions D offers you (like OOP). Bye, bearophile
Re: Converting Java code to D
John Colvin: struct LineStyle { enum NONE = None; enum SOLID = Solid; enum DASH = Dash; enum DOT = Dot; enum DASHDOT = Dash Dot; enum DASHDOTDOT = Dash Dot Dot; string label; private this(string label) { this.label = label; } } The constructor doesn't look very useful. Perhaps a named enum is safer. Bye, bearophile
Re: Function name from function pointer
Paul D Anderson: Is there a way to return the name of a function (a string) from a pointer to that function? Perhaps creating a string[void*] AA and initializing with all the function pointers you care about. Bye, bearophile
Re: Generating all combinations of length X in an array
wobbles: Have just tested, it is! But with the current D front-end it's not a good idea to generate too many combinations at compile-time. Efficient code doesn't save you from bad usages. Bye, bearophile
Re: return the other functions of the void main()
Jack Applegame: writeln(a.find(4).empty ? No : Yes); canFind? Bye, bearophile
Re: Generating all combinations of length X in an array
wobbles: While trying to generate all combinations of length X in an array, I came across the question on stackoverflow. [1] Theres a couple good answers there, but one that caught my eye shows a C# code snippet that is quite nice and short: Often short code is not the best code. Take a look at the versions here, the usable one is the third: http://rosettacode.org/wiki/Combinations#D Bye, bearophile
Re: Implementing Iterator to support foreach
tcak: I am planning to implement Iterator class. But looking at foreach statement, it takes a range only. Unless you are just experimenting, it's better to not go against a language and its std lib. Bye, bearophile
Re: function shadowed
ddos: same behavior when overriding methods of base classes This is by design. Bye, bearophile
Re: Shall I use immutable or const while passing parameters to functions
tcak: void dataProcessor( string giveMeAllYourData ){} dataProcessor( cast( immutable )( importantData[5 .. 14] ) ); With Const, void dataProcessor( in char[] giveMeAllYourData ){} dataProcessor( cast( const )( importantData[5 .. 14] ) ); Don't cast to const/immutable unless you have a good reason to do it, and you know what you are doing (and most times you don't know it). More generally, minimize the number of cast() in your D programs. You can use a search to count how many cast( there are in your whole D codebase, and you can try to reduce that number. Bye, bearophile
Re: Issue with free() for linked list implementation
Namespace: I've written a straight forward linked list implementation here: https://github.com/nomad-software/etcetera/blob/master/source/etcetera/collection/linkedlist.d Even though I'm using the GC to manage memory, maybe it will help you. Good idea to link to some existing code. Here is mine: https://github.com/Dgame/m3/blob/master/source/m3/List.d In 99%+ of cases it's a bad idea to use a linked list. Bye, bearophile
Re: Speed of horizontal flip
tchaloupka: Am I doing something utterly wrong? If you have to perform performance benchmarks then use ldc or gdc. Also disable bound tests with your compilation switches. Sometimes reverse() is not efficient, I think, it should be improved. Try to replace it with a little function written by you. Add the usual pure/nothrow/@nogc/@safe annotations where you can (they don't increase speed much, usually). And you refer to flip as method, so if you are using classes don't forget to make the method final. Profile the code and look for the performance bottlenecks. You can even replace the *w multiplications with an increment of an index each loop, but this time saving is dwarfed by the reverse(). Bye, bearophile
Re: What ?
Brian Schott: Do this instead: ulong u = 1L 63; I suggest a more explicit: ulong u = 1UL 63; Alternative: ulong u = 2UL ^^ 63; Bye, bearophile
Re: Associative Array of Const Objects?
bitwise: I'm a little confused at this point why this doesn't work either: const and immutable are rather different between C++ and D, I suggest you to take a look at the documentation: http://dlang.org/const-faq.html Bye, bearophile
Re: Associative Array of Const Objects?
bitwise: class Test{} void main() { const(Test)[string] tests; tests[test] = new Test(); } This code used to work, but after upgrading to dmd 2.067, it no longer does. --Error: cannot modify const expression tests[test] How do I insert an item into an associative array of const objects? You meant to say associative array with const objects as values. I think the short answer is that you can't. This is a breaking change, I think, it broke some of my code too. But perhaps something like Rebindable could be used. Bye, bearophile
Re: D's type classes pattern ?
matovitch: I am curious to know how isInputRange is implemented since I wanted to do kind of the same but I am afraid it's full of (ugly) traits and template trickeries where haskell type classes are quite neat and essentially a declaration of an interface. Take a look at the sources and learn. They are sometimes tricky to get right, but it's not a problem of ugly syntax. I wondered if you could check statically that the type could implement an interface *if it wanted to* that is, without inheriting it... Template constraints don't require inheritance. Bye, bearophile
Re: Keep Track of the Best N Nodes in a Graph Traversal Algorithm
Nordlöw: I have graph traversal algorithm that needs to keep track of the N best node visit. std.algorithm.topNCopy? Bye, bearophile
Re: C# to D
Dennis Ritchie: int[] arr = { 7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8 }; Console.WriteLine(string.Join( , arr.OrderByDescending(x = arr.Count(y = y == x)).ThenBy(x = x))); // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0 One solution: void main() { import std.stdio, std.algorithm, std.typecons; auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]; arr .schwartzSort!(x = tuple(-arr.count!(y = y == x), x)) .writeln; } Bye, bearophile
Re: C# to D
.schwartzSort!(x = tuple(-arr.count!(y = y == x), x)) But calling count for each item is not efficient (in both C# and D). If your array is largish, then you need a more efficient solution. Bye, bearophile
Re: C# to D
Ali Çehreli: Do you know the story about groupBy? It's a long messy story. Look for it with another name, like chunkBy or something like that. Bye, bearophile
Re: C# to D
Ivan Kazmenko: (1) For me, the name of the function is obscure. Something like sortBy would be a lot easier to find than schwartzSort. I've asked to change the name of that function for years. But Andrei Alexandrescu is a adamantly against changing that pet name he has chosen. This is irrational behavour: https://issues.dlang.org/show_bug.cgi?id=4909 There's lot of way to go for Phobos. And the only want to find holes, missed opportunities, sub-optimal performance spots, missing functions and features, and bad APIs and bad names is to actually try to use Phobos, like we are doing in this thread. Bye, bearophile
Re: C# to D
Dennis Ritchie: A more effective solution for C ++: #include iostream #include vector #include range/v3/all.hpp int main() { using namespace ranges; auto rng = istreamint( std::cin ) | to_vector | action::sort | view::group_by( std::equal_toint() ) | copy | action::stable_sort( []( const auto e1, const auto e2 ) { return distance( e1 ) distance( e2 ); } ); std::cout ( rng ); } This is still not very efficient (perhaps the last sorting has to be stable): void main() { import std.stdio, std.algorithm, std.typecons, std.array; [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8] .sort() .groupBy!((a, b) = a == b) .map!array .array .sort!q{a.length b.length} .joiner .writeln; } Bye, bearophile
Re: C# to D
Ivan Kazmenko: arr.map !(to !(string)) .join ( ) .writeln; I suggest to not put a space before the bang (!), because it's confusing for me. Also, arr.map !(to !(string)) is better written arr.map!text. But even better is to use the range formatting of writefln, avoiding the map, to, and join, something like: writefln(%(%d %), arr); Bye, bearophile
Re: Keep Track of the Best N Nodes in a Graph Traversal Algorithm
Nordlöw: Ahh, a Binary Heap perfectly matches my needs. https://en.wikipedia.org/wiki/Binary_heap http://dlang.org/phobos/std_container_binaryheap.html But isn't topNCopy using a heap? Bye, bearophile
Re: Do strings with enum allocate at usage point?
岩倉 澪: However, if enum implies allocation at the usage point for strings, There are two ways to see if something allocates: there is a compiler switch, and an annotation: void foo() @nogc { // Your code here } If the compiler doesn't have a bug it will complain if you put something that allocates inside that function. Bye, bearophile
Re: How to generate a random string ...
Robert burner Schadek: ... from all Unicode characters in an idiomatic D way? Perhaps by rejection? I mean, generating a uint, test if it's a character and repeat until the result is true. Bye, bearophile
Re: get from tuple by type
Charles Cooper: Yes, I could say external_api1_react_to_event(event_t[1], event_t[0]) .. but that is barbaric. It's a productivity sink because I have to go back to the original definition, align the arguments, and then context switch back to whatever I was working on before. If you are experiencing those problems it's probably the way D/Phobos to tell you to not use basic tuples for your purpose. Use tuples with named fields (or even structs). Take also a look at Algebraic in std.variant. Bye, bearophile
Re: Dlang seems like java now,but why not let d more like C# Style?
dnewer: but,C# cant compiled to native code. Soon you will be able to compile C# natively. Bye, bearophile
Re: Compilation changes
Ali Çehreli: That may be related to the recent changes in the build system. Right. Have you been following the following threads? (I haven't been; so, I am sure whether they apply.) I have not. [dmd-internals] DMD now requires a working D compiler to be build Proposal : aggregated dlang git repository dmd 2.066.1 cannot build phobos 2.066.1 I will try to get something out of those threads, thank you :-) Bye, bearophile
Compilation changes
Time ago Dmitry Olshansky gave me a nice script to compile dmd+Phobos from github, starting like this: My recipe on Windows, by Dmitry Olshansky: 0. Make sure there are no other DMD in the Windows path. 1. Get the latest DMD release zip you can find, unzip to some drive root(! otherwise get's trickier) 2. Delete all within src subfolder 3. Get a Git console in \dmd2\src, then the usual: ... Now I think it doesn't work any more, giving errors like this: make -fwin32.mak C=backend TK=tk ROOT=root HOST_DC= reldmd make -fwin32.mak C=backend TK=tk ROOT=root HOST_DC= OPT=-o DEBUG= LFLAGS=-L/delexe/la dmd.exe run idgen Error: 'run' not found --- errorlevel 1 --- errorlevel 1 So is Dmitry (or someone else) willing and able to tell me how to fix my compilation script and what to do? Thank you, bye, bearophile
Re: Int to float?
Ola Fosheim Grøstad: D claims to follow C, so using unions for type punning is ultimately implementation defined. I am not sure if D is the same as C regarding this. Bye, bearophile
Re: is expression and type tuples
Jack Applegame: On Tuesday, 3 March 2015 at 17:49:24 UTC, bearophile wrote: That's 1 + n-1 :-) Could you please explain what does '1 + n-1' mean? This is your code: template Is(ARGS...) if(ARGS.length % 2 == 0) { enum N = ARGS.length/2; static if(N == 1) enum Is = is(ARGS[0] : ARGS[1]); else enum Is = is(ARGS[0] : ARGS[N]) Is!(ARGS[1..N], ARGS[N+1..$]); } The recursion scheme you are using is working on a single item (a single pair of items), and then calling the recursion on all other items but the first. If you look in std.traits you see examples of a different recursion that reduces compilation time: template isExpressionTuple(T ...) { static if (T.length = 2) enum bool isExpressionTuple = isExpressionTuple!(T[0 .. $/2]) isExpressionTuple!(T[$/2 .. $]); else static if (T.length == 1) enum bool isExpressionTuple = !is(T[0]) __traits(compiles, { auto ex = T[0]; }); else enum bool isExpressionTuple = true; // default } Bye, bearophile
[rosettacode] std.container.DList problems
This code used to work in DMD 2.065: http://rosettacode.org/wiki/Strand_sort#D import std.stdio, std.container; DList!T strandSort(T)(DList!T list) { static DList!T merge(DList!T left, DList!T right) { DList!T result; while (!left.empty !right.empty) { if (left.front = right.front) { result.insertBack(left.front); left.removeFront(); } else { result.insertBack(right.front); right.removeFront(); } } result.insertBack(left[]); result.insertBack(right[]); return result; } DList!T result, sorted, leftover; while (!list.empty) { leftover.clear(); sorted.clear(); sorted.insertBack(list.front); list.removeFront(); foreach (item; list) { if (sorted.back = item) sorted.insertBack(item); else leftover.insertBack(item); } result = merge(sorted, result); list = leftover; } return result; } void main() { auto lst = DList!int([-2,0,-2,5,5,3,-1,-3,5,5,0,2,-4,4,2]); foreach (e; lst.strandSort) write(e, ); } Now it gives a runtime error like phobos\std\container\dlist.d(329): DList.front: List is empty. I think the cause is that list = leftover; has a different semantics. Is this a regression fit for Bugzilla? Bye, bearophile
Re: Implicit fall through not detected (Example from lex.html)
Andre: I am also not really happy with the actual behavor (w / wi switch needed) You shall always compile your D code with warnings active, unless you need them disabled for some real reason. Eventually the fall through warning will become a deprecation and then an error. It's meant to be an error, but in D we introduce errors slowly. Bye, bearophile
Re: is expression and type tuples
Jack Applegame: Seems like is expression doesn't support type tuples: pragma(msg, is(short : int)); // true enum Test(ARGS...) = is(ARGS[0..2] : ARGS[2..4]); pragma(msg, is(Test!(int, int, int, int))); // false pragma(msg, Test!(int, short, int, int)); // false Is it by design, or just not implemented? It's by design, perhaps because Walter didn't think of this case, or probably for compiler simplicity. But it should be not too much hard to implement it your code. Just use two is(), or use recursion (with splitting in two, and not 1 + n-1). Bye, bearophile
Re: is expression and type tuples
Jack Applegame: or use recursion (with splitting in two, and not 1 + n-1). Bye, bearophile I already have one: template Is(ARGS...) if(ARGS.length % 2 == 0) { enum N = ARGS.length/2; static if(N == 1) enum Is = is(ARGS[0] : ARGS[1]); else enum Is = is(ARGS[0] : ARGS[N]) Is!(ARGS[1..N], ARGS[N+1..$]); } That's 1 + n-1 :-) Bye, bearophile
Re: UFCS on template alias ?
Baz: Is this a normal behaviour ? Try to move the definition of poly to module-level scope. This is a design decision to avoid other troubles. Bye, bearophile
Re: D : dmd vs gdc : which one to choose?
Mayuresh Kathe: Should I choose DMD or go with GDC? It's a good idea to use all available compilers. LDC and DMD are both useful. Every one of them has advantages and disadvantages. Bye, bearophile
Re: Mimicking C++'s indexing behavior in D associative arrays
Rikki Cattermole: Foo*[string] bar; Foo v = *bar.grab(mykey); Is this the setdefault of Python dicts? If this need is strong a new function could be added to Phobos (or even druntime if you want to reduce the number of hash computations). Bye, bearophile
Re: what is the offical way to handle multiple list in map() ?
Baz: is this the official way ? It seems a way to perform nested mapping in D. --- auto fruits = [apple, banana, orange][]; auto vegies = [grass, salad][]; Those trailing [] are unneded. auto youreallygonna = map!( `map!(a = eat ~ a)(a)` )([fruits, vegies]); Better to use another lambda inside, instead of that string. Bye, bearophile
Re: ranges reading garbage
John Colvin: prints things like [0, 4, 5, 1, 1, 1459971595, 1459971596, 2, 2, 1459971596, 1459971597, 3, 4, 8, 9, 5, 5, 4441427819, 4441427820, 6, 6, 4441427820, 4441427821, 7] but the output isn't consistent, the big numbers change on each run. Try to replace the only() with: [y, y+ys.length, y+ys.length+1, y+1] Like this: import std.range, std.algorithm, std.stdio; void foo(in float[] data, in float[] xs, in float[] ys) @safe { iota(0, data.length, ys.length) .map!(xBase = iota(xBase, xBase + ys.length - 1) .map!(y = [y, y+ys.length, y+ys.length+1, y+1]) .joiner) .joiner .writeln; } void main() { foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]); } In Rust the compiler enforces that all stack-allocated data doesn't come from dead stack frames. In D you have to be careful to avoid doing it. In future this kind of bugs will be hopefully avoided by a better tracking of the memory. I am not sure if http://wiki.dlang.org/DIP69 is able to avoid this bug, if it can't, then DIP69 needs to be improved. Bye, bearophile
Re: ranges reading garbage
FG: Odd... Still something is wrong. It prints: [0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 5, 6, 6, 6, 6, 7, 7] instead of this: [0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 9, 10, 6, 6, 10, 11, 7] This is less lazy and gives another result: import std.range, std.algorithm, std.stdio; void foo(in float[] data, in float[] xs, in float[] ys) @safe { iota(0, data.length, ys.length) .map!(xBase = iota(xBase, xBase + ys.length - 1) .map!(y = [y, y+ys.length, y+ys.length+1, y+1]) .join) .join .writeln; } void main() { foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]); } What a fun program :-) Bye, bearophile
Re: Data-Flow (Escape) Analysis to Aid in Avoiding GC
Per Nordlöw: Then how does the GC know when to release when there are multiple references? The mark phase counts what's reachable and what can't be reached. If an object has one pointer to it, or one hundred pointers, it is not removed. If nothing points to it, it is removed. I suggest you to read how a marksweep GC works, or better to implement a bare-bones marksweep GC in C language yourself for Lisp-like cons cells, you only need 100 lines of code or so to do it. Bye, bearophile
Re: Number of Bits Needed to Represent a Zero-Offset Integer
H. S. Teoh: Maybe that could be the basis of a better name? Right. Bye, bearophile
Re: Number of Bits Needed to Represent a Zero-Offset Integer
H. S. Teoh: So it could be called ilog2? Perhaps floorIlog2? Isn't ilog2 a different function? Bye, bearophile
Re: What is the Correct way to Malloc in @nogc section?
Foo: I'm regret that I tried to help, I will delete this repo as far as possible. :) Language communities aren't perfect, but the success of a language comes from the help of many little hands :) Perhaps Rust will win over D in the end, but there's no reason to throw away your work just for a comment... be tolerant and be good. Bye, bearophile
Re: Number of Bits Needed to Represent a Zero-Offset Integer
Dominikus Dittes Scherkl: I would recommend to use something like this: /// returns the number of the highest set bit +1 in the given value or 0 if no bit is set size_t bitlen(T)(const(T) a) pure @safe @nogc nothrow if(isUnsigned!T) { static if(T.sizeof = size_t.sizeof) // doesn't work for ulong on 32bit sys { return x ? core.bitop.bsr(x)+1 : 0; } else static if(T.sizeof == 8) // ulong if size_t == uint { return x ? x32 ? core.bitop.bsr(x)+33 : core.bitop.bsr(x)+1 : 0; } } Is this good to be added to Phobos? Perhaps with a more descriptive name? Bye, bearophile
Re: Data-Flow (Escape) Analysis to Aid in Avoiding GC
Tobias Pankrath: Why should splitter.front allocate? I think that front was able to throw Unicode exceptions, that require the GC. But I think later they have become asserts, that don't require the GC. Bye, bearophile
Re: How to write similar code D?
FG: auto query = iota(2, 2 + 10) .map!(c = [Length: 2 * c, Height: c * c - 1, Hypotenuse: c * c + 1]) .map!(x = format(%4d%4d%4d, x[Height], Unlike other languages like JavaScript, the D front-end is very weak in optimizing well such kind of code... I think D compilers handle built-in associative arrays in a very straight way. Bye, bearophile
Re: cannot deduce function from argument types issue.
ted: Could someone enlighten me ? This works: import std.range: ElementType, isInputRange; ElementType!R testFunc(R, T)(R range, T foo) if (is(ElementType!R == T)) { static assert(isInputRange!R); typeof(return) retVal = foo ^^ 2; // More DRY. return retVal; } void main() { auto values = [0.0, 3.0, -1.0, 5.0]; auto result = testFunc(values, 8.8); } The D compiler seems unable to compute ElementType!R in the function signature. If I am right, then this seems worth an enhancement request. Bye, bearophile
Re: cannot deduce function from argument types issue.
Ali Çehreli: If think it is a little too much to ask from the template system of D. I remember hitting a similar problem with code like this bar() function: // OK void foo(size_t N1, size_t N2)(int[N1] a, int[N2] b) if (N2 == N1 ^^ 2) {} // Not OK void bar(size_t N)(int[N] a, int[N ^ 2] b) {} void main() { int[2] a = [1, 2]; int[4] b = [1, 2, 3, 4]; foo(a, b); bar(a, b); } So perhaps my suggestion to file an enhancement request is not a good idea... Bye, bearophile
Re: cannot deduce function from argument types issue.
void bar(size_t N)(int[N] a, int[N ^ 2] b) {} I meant: void bar(size_t N)(int[N] a, int[N ^^ 2] b) {}
Re: Classes and @disable this()
I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { @disable this(); this(int i) {} } void main() {} https://issues.dlang.org/show_bug.cgi?id=14163 Bye, bearophile
Re: cannot deduce function from argument types issue.
ted: ... where you say 'More DRY' above, are you referring to I was referring to both, but mostly to the typeof. It's more DRY (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself ). You are stating only once the type of the return variable. This is less bug-prone. Bye, bearophile
Re: To write such an expressive code D
Dennis Ritchie: Please help. This starts to look like homework :-) Bye, bearophile
Re: Compilation with dub + dmd: out of memory
Vlasov Roman: I have the quite computer with 2 GB RAM. At compilation with dub and dmd of small project this pair eating about 1.4~1.5 GB RAM. I solve this probleb by connecting swap partition, but it calls some freezes + it take ~10% of swap, and after compilation swap not released. At switching off swap as result we get ~200 MB of dead data in RAM, which can be released by rebooting. How i can resolve it? Look for CTFE code, perhaps some of it is excessive. You can convert some of it to run-time in a module-level static this(). Bye, bearophile
Re: To write such an expressive code D
Dennis Ritchie: Output: 0 xor 0 xor 0 = 0 0 xor 0 xor 1 = 1 0 xor 1 xor 0 = 1 0 xor 1 xor 1 = 0 1 xor 0 xor 0 = 1 1 xor 0 xor 1 = 0 1 xor 1 xor 0 = 0 1 xor 1 xor 1 = 1 This man again took advantage of the fact that in D there is no such operation - (analog switch). A natural solution in D: void main() { import std.stdio; foreach (immutable a; 0 .. 2) foreach (immutable b; 0 .. 2) foreach (immutable c; 0 .. 2) writefln(%d xor %d xor %d = %d, a, b, c, (a + b + c) % 2); } Alternative solution closer to the F# code: import std.stdio, std.algorithm, std.typecons; int f(T)(T t) if (isTuple!T) { return t.predSwitch( tuple(0, 0, 0), 0, tuple(0, 1, 1), 0, tuple(1, 0, 1), 0, tuple(1, 1, 0), 0, /*else*/ 1); } void main() { foreach (immutable a; 0 .. 2) foreach (immutable b; 0 .. 2) foreach (immutable c; 0 .. 2) writefln(%d xor %d xor %d = %d, a, b, c, tuple(a, b, c).f); } Bye, bearophile
Re: How to write similar code D?
Dennis Ritchie: Tell me, please, how to write similar С# code D: This is more or less exactly the same: void main() { import std.stdio, std.range, std.algorithm, std.typecons, std.format; auto query = iota(2, 12) .map!(c = Tuple!(int,length, int,height, int,hypotenuse) (2 * c, c ^^ 2 - 1, c ^^ 2 + 1)) .map!(x = %3d%4d%4d.format(x.height, x.hypotenuse, x.length)); foreach (immutable x; query) x.writeln; } But often you write something more like this in D using the latest version of the compiler: void main() { import std.stdio, std.range, std.algorithm, std.typecons; iota(2, 12) .map!(c = tuple(c ^^ 2 - 1, c ^^ 2 + 1, 2 * c)) .each!(x = writefln(%3d%4d%4d, x[])); } Bye, bearophile
Re: Classes and @disable this()
fra: However making it a compiler error would be far, far better I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { @disable this(); this(int i) {} } void main() {} Bye, bearophile
Re: Template constructor in a non-template struct.
ChrisG: I don't really understand how I'd differentiate a constructor template from a class/struct template. One solution is to use a template struct (struct/class names start with an upper case in D, while typed enum members usually start with a lower case): enum E { option1, option2 } struct Boring(E Opt = E.option1) { this(int arg1, int arg2) {} } void main() { auto a = Boring!(E.option2)(1, 2); } If you want to instantiate the constructor template without type inference, then this seems to work, but it's not idiomatic D: enum E { option1, option2 } struct Boring { this(E Opt = E.option1)(int arg1, int arg2) {} } void main() { auto a = Boring().__ctor!(E.option2)(1, 2); } Bye, bearophile
Re: primitive type variables not nullable ?
Tobias Pankrath: Check for null with (x is null) not via printing to stdout. In most cases instead of checking dynamic arrays for null, it's better to use std.array.empty. Bye, bearophile
Re: Do you have a better way to remove element from a array?
Tobias Pankrath: Works as designed: http://dlang.org/phobos/std_algorithm.html#.remove Unfortunately it's one of the worst designed functions of Phobos: https://issues.dlang.org/show_bug.cgi?id=10959 Bye, bearophile
Re: how can I get a reference of array?
zhmt: Will arr.ptr change in the future? As the array add more members , it need more memroy, then remalloc may be called, the pointer maybe change, then the stored pointer will be invalid. Will this happen? Yes, it can happen. Bye, bearophile
Re: Do you have a better way to remove element from a array?
bachmeier: It seems your argument is that remove is poorly designed because it's not destructive. Or am I missing your argument? It has to be a void function (or perhaps bettter it can return true/false if it has removed the item, so it becomes @nogc and nothrow). And it has to remove the first item equal to the given one. You can then add a second function that removes at a given index (like removeAt). Bye, bearophile
Re: Conway's game of life
Paul: Regarding the immutable loop variable, I've conditioned myself never to interfere with loop control values But adding immutable you don't risk modifying the variable by mistake. It's another design mistake of D. Variables (like foreach loop indexes) must be immutable by default because otherwise programmers often don't bother making them immutable. It's a lost war. Bye, bearophile
Re: Conway's game of life
Paul: enum WORLDSIZE = 20; enum INITIALPOP = 70; //experimental enum DEAD = 0; enum ALIVE = 1; D enums don't need to be ALL UPPERCASE :-) int world[WORLDSIZE][WORLDSIZE]; Don't forget to compile with warnings active (it's a design error of the D compiler to have them disabled by default). foreach(i; 0..INITIALPOP){ It's less bug-prone to make that index immutable: foreach(immutable i; 0 .. initialPop) { Bye, bearophile
Re: how convert the range to slice ?
Nordlöw: Is started digging a bit... The magic happens at line 103 in cast.c. How do I most conveniently figure out which members (functions) a type (e-type) has? I figured I could check for typical InputRange members and issue a hint about using .array if e-type has them. It's probably better to ask such questions on GitHub (and to open an enhancement request in Bugzilla). Bye, bearophile
Re: Conway's game of life
gedaiu: https://github.com/gedaiu/Game-Of-Life-D A bare-bones implementation: http://rosettacode.org/wiki/Conway%27s_Game_of_Life#Faster_Version The quality of the D GC is not important for a simple Life implementation, you just need two arrays. Bye, bearophile
Re: std.algorithm sort() and reverse() confusion
Jonathan M Davis: arr.reverse.map!sqrt Yes, but arguably, chaining calls in this case is bad, We have discussed this some time... and I'd like reverse() to return the original array (like the deprecated array .reverse property). It's not a perfect design, but allowing UFCS chains is quite important. Bye, bearophile
Re: Deducing a template retrun parameter type based on an assignment?
Jeremy DeHaan: I figured that it would be smart enough to deduce the parameter type based on the type that it was trying to be assigned to. For that you need languages like Haskell/Rust. D type inference doesn't work from the type something is assigned to. Bye, bearophile
Re: Check if type is from specific template?
Tofu Ninja: Basically what the title says, how do I check if a type T is an instantiation of a specific template? If you have an updated Phobos std.traits.isInstanceOf could be what you look for. Bye, bearophile
Re: how convert the range to slice ?
Chris Williams: Range is not castable to array. See std.array.array to generate an array from a Range. Currently this program: void main() { import std.range; int[] a = iota(10); } Gives an error like: test.d(3,19): Error: cannot implicitly convert expression (iota(10)) of type Result to int[] For the error message to be like yours, the compiler has to recognize a Range, this could be possible because foreach() already does that. I think you can try to open a diagnostic enhancement request. In D there are already examples of hardcoded error messages targeting newbies: void main() { int x; writeln(a); printf(%d\n, x); } Gives: test.d(3,5): Error: 'writeln' is not defined, perhaps you need to import std.stdio; ? test.d(4,5): Error: 'printf' is not defined, perhaps you need to import core.stdc.stdio; ? Bye, bearophile
Re: how convert the range to slice ?
Nordlöw: Is there any chance we could add logic to dmd+phobos that hints user about this? It's such a fundamental part of D+Phobos that newbies are forced to learn this quickly. On the other hand an informative error message could be useful... What error message do you suggest? Bye, bearophile
Re: I left my program open for 9 hours and it used up 700mb of ram, could someone review it?
Gan: Is there some special stuff I gotta do extra with structs? Do they need manually allocated and released? Most of your usages of tiny structs should be by value. So just keep in mind they are values. Even when you iterate with a foreach on a mutable array of them :-) On a second question, do I ever need to manually release objects I create with new? Usually not. How much advanced do you want to be? :-) Bye, bearophile
Re: Array List object?
Gan: //Initializing the array tiles = new SBTile[](0); This is often useless. //Clearing the array tiles = []; This doesn't clear the array, it rebinds it to a null pointer. Bye, bearophile
Re: Array List object?
And it's named dynamic array, instead of Array List object, it's not a class instance. Bye, bearophile
Re: Virtual functions and inheritance
Baz: doesn't work. And similarly to the the orginal post: I suggest to read some D documentation first, and program later. Bye, bearophile
Re: Classical bug
Vladimir Panteleev: But the check seems very simple, and is easily circumvented. This compiles: byte[] func() { byte[1024] buffer; auto p = buffer[0..3]; return p; } I guess such bugs will be detected (in safe code only!) after the implementation of: http://wiki.dlang.org/DIP69 Currently we are implementing a kind of pre-phase: http://wiki.dlang.org/DIP25 And here I have asked for @safe to become the default (Walter seems not against this idea): https://d.puremagic.com/issues/show_bug.cgi?id=13838 Bye, bearophile
Re: I left my program open for 9 hours and it used up 700mb of ram, could someone review it?
Gan: How can I make it use less CPU/RAM? Most tiny classes probably should be structs. More generally, use a struct every time you don't need a class. You can start with those two: struct SBRange { double left = 0.0, right = 0.0, top = 0.0, bottom = 0.0; } struct Point(T) { T x, y; } This probably isn't enough to solve your problems, but it's a start. Bye, bearophile
How to tell an identifier is a module?
__traits(allMembers, mixin(__MODULE__)) also yields a module name like object, but then how can you find out that object is a module? This doesn't work: void main() { pragma(msg, is(int == int)); pragma(msg, is(object == module)); } Bye, bearophile
Re: static class vs. static struct
On Monday, 26 January 2015 at 14:02:54 UTC, ref2401 wrote: What's the difference between static class and static struct? What should i use? Non-static structs/classes have an extra pointer. Static ones don't have it, so their differences are the usual ones: a class is used by reference and they are often on the heap, while a struct is handled by value (or pointer to value). A class has two extra hidden fields. Bye, bearophile
Re: using the full range of ubyte with iota
Vlad Levenfeld: What's this about !`[]` and std.range.uniform?? It's not in the documentation. It's an enhancement I have proposed. Bye, bearophile
Re: using the full range of ubyte with iota
Dominikus Dittes Scherkl: Because this is useful in more situations, Right, but it's still a cast. And in D you want to minimize the number of usages of casts. The proposed syntax iota![] is cast-safe. Bye, bearophile
Re: Difference between concatenation and appendation
Laeeth Isharc: I think concatenation and append are used as synonyms (the same meaning is meant). a~=b or a=a~b a=a~b always allocates a new array, while a~=b sometimes re-allocates in place. Bye, bearophile
Re: using the full range of ubyte with iota
Dominikus Dittes Scherkl: Has anyone any idea how to work around this? In Bugzilla I have proposed to solve this problem with this syntax taken from std.range.uniform: iota![](ubyte.min, ubyte.max) Bye, bearophile
Re: Initialization of structure field w/o default ctor
drug: Also can I avoid dummy non-default ctor for Bar? One solution: struct Foo { int foo; @disable this(); this(int foo_) pure nothrow @safe @nogc { this.foo = foo_; } } struct Bar { enum arraySize = 3; Foo[arraySize] foo = Foo(1); } void main() @safe { import std.stdio; Bar bar; bar.writeln; } Bye, bearophile
Re: Defining a static array with values in a range
tcak: Well, that's just disguising what we can't do. When the a..b syntax was added to foreach() someone criticized that syntax saing it's a one trick pony, and indeed I don't know why Walter didn't make it a little more first-class. But note that in D the a..b ranges are always open on the right, so 'a'..'z' can't include the 'z'. What do you think of this? import std.stdio, std.range, std.algorithm, std.array; auto charInterval(in char a, in char b) pure nothrow @safe @nogc { return iota(a, b + 1).map!(i = cast(char)i); } void main() @safe { char[] arr = chain(charInterval('a', 'z'), charInterval('A', 'Z'), charInterval('0', '9')).array; arr.writeln; } charInterval can of course become eager too, so you just need ~ to concatenate the results: import std.stdio, std.range, std.algorithm, std.array; char[] charInterval(in char a, in char b) pure nothrow @safe { return iota(a, b + 1).map!(i = cast(char)i).array; } void main() @safe { char[] arr = charInterval('a', 'z') ~ charInterval('A', 'Z') ~ charInterval('0', '9'); arr.writeln; } Bye, bearophile