Re: Merging two arrays in a uniform order
On Friday, 13 January 2017 at 06:32:02 UTC, aberba wrote: Unlike array1 + array2, how can i merge arrays such that: [a1, a1, a2, a1, a1, a2, a1] //uniform order where a1 = child of array1, a2 = child of array2 using a built-in function/algorithm (is/are there anything(s) in Phobos for this?). No manual approach. void main() { import std.stdio : writeln; import std.range : refRange, roundRobin; auto array1 = [1, 2, 3, 4, 5]; auto array2 = [11, 12, 13, 14, 15]; auto array1Ref = refRange(); roundRobin(array1Ref, array1Ref, array2) .writeln(); } elements: [ 1, 2, 11, 3, 4, 12, 5, 13, 14, 15 ] indexes: a11 a12 a21 a13 a14 a22 a15 a23 a24 a25
Re: code.dlang.org package readme.md
On Tuesday, 3 January 2017 at 11:51:56 UTC, Alexandru Ermicioi wrote: Hi all. How it is possible to show readme.md from github repository in code.dlang.org for a particular project? Thanks. Yes, code.dlang.org will display the readme file of the package if and only if it is named "README.md". For reference: https://github.com/dlang/dub-registry/blob/v2.0.0/views/view_package.dt#L128 https://github.com/dlang/dub-registry/blob/v2.0.0/source/dubregistry/registry.d#L351 The naming scheme is probably not set in stone (it just seemed to work ok in practice), so if you want you can open a pull request to make it more flexible.
Re: the best language I have ever met(?)
On Monday, 21 November 2016 at 12:08:30 UTC, Patric Dexheimer wrote: On Saturday, 19 November 2016 at 00:47:00 UTC, ketmar wrote: On Saturday, 19 November 2016 at 00:28:36 UTC, Stefan Koch wrote: Please don't post non-d. it slipped accidentally, sorry. ;-) for OP: `uint[2] a = [42, 69];` is the correct syntax. "uint[$] a = [42, 69];" haha for a moment I thought that this was the way of D to create a fixed-size array without explicit setting the size (like what u can do in c++ :)) That was a proposal for D that was rejected in the last moment by Andrei. My guess is that ketmar's modified dmd has that feature implemented.
Re: Static Length Propagation of Ranges
On Thursday, 20 October 2016 at 12:38:40 UTC, Nordlöw wrote: On Wednesday, 19 October 2016 at 19:39:46 UTC, Nordlöw wrote: On Wednesday, 19 October 2016 at 19:01:50 UTC, Meta wrote: https://goo.gl/t9m3YK I'm actually pretty impressed that this kind of code can be written in D. Thanks! Add at https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2234 Made it even modular by factoring out arrayN at https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2200 and used at https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2215 Code: ElementType!R[n] arrayN(size_t n, R)(R r) { assert(r.length == n); typeof(return) dst; import std.algorithm.mutation : copy; r.copy(dst[]); return dst; } typeof(fun(E.init))[n] map(alias fun, E, size_t n)(const E[n] src) { import std.algorithm.iteration : map; return src[].map!fun.arrayN!n; } @safe pure nothrow unittest { import std.meta : AliasSeq; foreach (E; AliasSeq!(int, double)) { enum n = 42; E[n] c; const result = map!(_ => _^^2)(c); static assert(c.length == result.length); static assert(is(typeof(result) == const(E)[n])); } } Here's my variation on the theme. The main difference being that instead of eagerly evaluating the range I wrap it with additional static information. Unfortunately, (AFAIK) Phobos does not take advantage of ranges with statically known length, similarly to how it handles ranges with `enum bool empty = false`. void main() { import std.stdio; int[3] sarr = [1, 2, 3]; auto r1 = sarr.staticLengthRange; static assert (isInputRange!(typeof(r1))); static assert (r1.length == 3); writeln(r1); auto arr = [1, 2, 3, 4]; auto r2 = arr.map!(a => a * 2).staticLengthRange!4; static assert (r2.length == 4); writeln(r2); } import std.algorithm.iteration : map; import std.range.primitives : hasLength, isInputRange; // Note: this overload has questionable memory safety :( // Would be quite cool if DIP1000 could support this use case auto staticLengthRange(T, size_t n)(ref T[n] arr) { return .staticLengthRange!(n, T[])(arr[]); } auto staticLengthRange(size_t n, R)(R range) if (isInputRange!R && hasLength!R) { struct Result { enum size_t length = n; R _range; alias _range this; } assert (range.length == n); return Result(range); } auto staticLengthRange(size_t n, R)(R range) if (isInputRange!R && hasLength!R) { struct Result { enum size_t length = n; R _range; alias _range this; } assert (range.length == n); return Result(range); }
Re: Static Length Propagation of Ranges
On Thursday, 20 October 2016 at 16:25:53 UTC, Meta wrote: On Thursday, 20 October 2016 at 13:05:05 UTC, Nordlöw wrote: On Thursday, 20 October 2016 at 12:38:40 UTC, Nordlöw wrote: ElementType!R[n] arrayN(size_t n, R)(R r) { assert(r.length == n); typeof(return) dst; import std.algorithm.mutation : copy; r.copy(dst[]); return dst; } Is there a place for part of this logic in Phobos? I'm thinking perhaps array{N,Exactly} should be added to std.array. The idea came to me after learning about dependent types in Idris: http://www.idris-lang.org/ There was a pull request awhile back for a small function that creates fixed-length arrays, but I think it was only intended to create them from dynamic arrays (such as `auto sarr = [1, 2, 3].staticArray`). Personally I think it would be nice to have a version of `array` that creates a static array, but I don't know how often it would be used or what the pitfalls are, if any. I think you're talking about this PR: https://github.com/dlang/phobos/pull/4090. It handles range iteration, as well as opApply iteration. I also think that the addition is worth having, though Andrei seemed to disagree. The (other?) major obstacle is safe usage, which currently is not enforced by the compiler, see: https://issues.dlang.org/show_bug.cgi?id=8838 https://issues.dlang.org/show_bug.cgi?id=12625 On the bright side, it looks like one of Walter's PRs for DIP1000 should address those issues: https://github.com/dlang/dmd/pull/5972/files?diff=unified#diff-33b3e2fefc5298c0b9de67897929e7ceR89
Re: how to access struct member using [] operator?
On Sunday, 25 September 2016 at 04:54:31 UTC, grampus wrote: Dear all For example, I have a struct struct point{int x;int y} point a; Is there an easy way to access x and y by using a["x"] and a["y"] I guess I need to overload [], but can't figure out how. Someone can help? Thank you very much Here's my solution. It's very similar to Namespace's solution, the main difference being that it doesn't coerce the result to the common type of all the fields which may not be always possible and is also looses information. It also uses this.tupleof and foreach, so you don't have to write the switch cases by hand. ``` struct Something { int x, y; float z; string w; auto opIndex(string member) { import std.variant : Algebraic; import std.traits : Fields; alias FieldTypes = Fields!(typeof(this)); alias CommonType = Algebraic!(FieldTypes, typeof(null)); switch (member) { foreach (idx, field; this.tupleof) { case this.tupleof[idx].stringof[5 .. $]: return CommonType(this.tupleof[idx]); } default: assert (0, "Type `" ~ typeof(this).stringof ~ "` doesn't contain any member named `" ~ member ~ "`!"); // or return CommonType(null); } } } void main() { import std.stdio; auto s = Something(3, 4, 4.5, "asd"); writeln(s["x"]); writeln(s["y"]); writeln(s["z"]); writeln(s["w"]); writeln(s["missing_field"]); } ``` Application output: 3 4 4.5 asd Application error: core.exception.AssertError@/home/d623/f162.d(26): Type `Something` doesn't contain any member named `missing_field`! The [5 .. $] trick is needed, because for e.g. idx = 0, this.tupleof[0].stringof returns "this.x" and we want to skip the "this." part (because otherwise the user would need to type s["this.x"]).
Re: ndslice and RC containers
On Thursday, 22 September 2016 at 12:38:57 UTC, Nordlöw wrote: Is ndslice' Slice() prepared for integration with containers with reference counting semantics? I wonder because according to the docs they internally store a pointer and an offset. What is that pointer supposed to point to except from obviously currently a GC-allocated array? See: https://dlang.org/phobos/std_experimental_ndslice_slice.html#.Slice ndslice (i.e. Slice(size_t N, Range) ) is a generalization of D's built-in slices (i.e. T[]) to N dimensions. Just like them, it doesn't handle memory ownership - it just provides a view over existing data. Usually, there are two use cases: 1) Wrapping an existing array: 1.1) You allocate an array however you want (GC, RC, plain malloc) or just use a slice to an array returned from a third-party library 1.2) Wrap it via sliced [1] 1.3) Use it 1.4) Free it: 1.4.a) Let the GC reclaim it 1.4.b) Let the RC reclaim it 1.4.c) Free it manually. 2) Making a new array 2.1.a) Using the GC via slice [2] 2.1.b) Using std.experimental.allcator via makeSlice [3] 2.2) Use it 2.3) Free it: 2.3.a) Let the GC reclaim it automatically 2.3.b) Manually dispose [4] it from the allocator it was allocated from (look for the allocator.dispose(tuple.array) pattern in the examples of makeSlice). Please note that the support for creating ndslices via custom memory allocators (i.e. makeSlice) was added after dmd-2.071 was branched, so you either have to wait for dmd-2.072, or use a nightly build (which I recommend). [1]: http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.sliced [2]: http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.slice [3]: http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.makeSlice [4]: http://dlang.org/phobos-prerelease/std_experimental_allocator.html#.dispose
Re: Template-style polymorphism in table structure
On Sunday, 4 September 2016 at 09:55:53 UTC, data pulverizer wrote: I am trying to build a data table object with unrestricted column types. The approach I am taking is to build a generic interface BaseVector class and then a subtype GenericVector(T) which inherits from the BaseVector. I then to build a Table class which contains columns that is a BaseVector array to represent the columns in the table. My main question is how to return GenericVector!(T) from the getCol() method in the Table class instead of BaseVector. Perhaps my Table implementation somehow needs to be linked to GenericVector(T) or maybe I have written BaseTable instead and I need to do something like a GenericTable(T...). However, my previous approach created a tuple type data object but once created, the type structure (column type configuration) could not be changed so no addition/removal of columns. import std.stdio : writeln, write, writefln; import std.format : format; interface BaseVector{ BaseVector get(size_t); } class GenericVector(T) : BaseVector{ T[] data; alias data this; GenericVector get(size_t i){ return new GenericVector!(T)(data[i]); } this(T[] arr){ this.data = arr; } this(T elem){ this.data ~= elem; } void append(T[] arr){ this.data ~= arr; } override string toString() const { return format("%s", data); } } class Table{ private: BaseVector[] data; public: // How to return GenericVector!(T) here instead of BaseVector BaseVector getCol(size_t i){ return data[i]; } this(BaseVector[] x ...){ foreach(col; x) this.data ~= col; } this(BaseVector[] x){ this.data ~= x; } this(Table x, BaseVector[] y ...){ this.data = x.data; foreach(col; y){ this.data ~= col; } } void append(BaseVector[] x ...){ foreach(col; x) this.data ~= x; } } void main(){ auto index = new GenericVector!(int)([1, 2, 3, 4, 5]); auto numbers = new GenericVector!(double)([1.1, 2.2, 3.3, 4.4, 5.5]); auto names = new GenericVector!(string)(["one", "two", "three", "four", "five"]); Table df = new Table(index, numbers, names); // I'd like this to be GenericVector!(T) writeln(typeid(df.getCol(0))); } Since BaseVector is a polymorphic type you can't know in advance (at compile-time) the type of the object at a particular index. The only way to get a typed result is to specify the type that you expect, by providing a type parameter to the function: The cast operator will perform a dynamic cast at runtime which will return an object of the requested type, or null, if object is of some other type. GenericVector!ExpectedType getTypedCol(ExpectedType)(size_t i){ assert (cast(GenericVector!ExpectedType)data[i], format("The vector at col %s is not of type %s, but %s", i, ExpectedType.stringof, typeof(data[i]))); return cast(GenericVector!ExpectedType)data[i]; } void main(){ auto index = new GenericVector!(int)([1, 2, 3, 4, 5]); auto numbers = new GenericVector!(double)([1.1, 2.2, 3.3, 4.4, 5.5]); auto names = new GenericVector!(string)(["one", "two", "three", "four", "five"]); Table df = new Table(index, numbers, names); if (typeid(df.getCol(0) == typeid(string)) writeln(df.getTypedCol!string(0).data); else if (typeid(df.getCol(0) == typeid(int)) writeln(df.getTypedCol!int(0).data); // and so on... } Another way to approach the problem is to keep your data in an Algebraic. (https://dpaste.dzfl.pl/7a4e9bf408d1): import std.meta : AliasSeq; import std.variant : Algebraic, visit; import std.stdio : writefln; alias AllowedTypes = AliasSeq!(int[], double[], string[]); alias Vector = Algebraic!AllowedTypes; alias Table = Vector[]; void main() { Vector indexes = [1, 2, 3, 4, 5]; Vector numbers = [1.1, 2.2, 3.3, 4.4, 5.5]; Vector names = ["one", "two", "three", "four", "five"]; Table table = [indexes, numbers, names]; foreach (idx, col; table) col.visit!( (int[] indexColumn) => writefln("An index column at %s. Contents: %s", idx, indexColumn), (double[] numberColumn) => writefln("A number column at %s. Contents: %s", idx, numberColumn), (string[] namesColumn) => writefln("A string column at %s. Contents: %s", idx, namesColumn) ); } Application output: An index column at 0. Contents: [1, 2, 3, 4, 5] A number column at 1. Contents: [1.1, 2.2, 3.3, 4.4, 5.5] A string column at 2. Contents: ["one", "two", "three", "four", "five"]
Re: std.functional.compose compilation error
On Thursday, 25 August 2016 at 21:01:29 UTC, Antonio Corbi wrote: On Thursday, 25 August 2016 at 14:30:00 UTC, Meta wrote: On Thursday, 25 August 2016 at 14:06:32 UTC, Antonio Corbi wrote: Hello, Trying to compile this example from Chuck Allison: --- import std.stdio; import std.functional; void main() { auto div3 = (double x) => x/3.0; auto sq = (double x) => x*x; auto pls1 = (double x) => x+1.0; alias compose!(div3,sq,pls1) comp; writeln(comp(2.0)); // 3 == (2.0+1.0)^^2 / 3.0 alias pipe!(div3,sq,pls1) pip; writeln(pip(2.0)); // 1.4 == (2.0/3.0)^^2 + 1.0 } I get this error (with DMD64 D Compiler v2.071.1 in linux): compose.d(8): Error: template instance compose!(div3, sq, pls1) compose is not a template declaration, it is a module But the error disappears if I use this import: import std.functional:compose,pipe; Is this a bug or is it the expected behaviour under the recent 'import' changes? Thanks! Try renaming your source file to something other than compose.d, I think that's confusing the compiler. Yep, that did the trick! I also noticed that 'old' compilers like: - gdc: gdc (GCC) 6.1.1 20160501 - ldc: LDC - the LLVM D compiler (1.0.0): based on DMD v2.070.2 and LLVM 3.8.0 *do* compile the original code posted without error. Thank's to all of you for your answers. Since DMD 2.071 the compiler has become more strict about the use of imports. See the changelog for more info: http://dlang.org/changelog/2.071.0.html
Re: Proper concurrent nearly lock free efficient nogc storage structures?
On Friday, 26 August 2016 at 23:38:02 UTC, Illuminati wrote: Does D have any such thing? I'm having to recreate the wheel here and it isn't fun ;/ Getting in the way of real work ;/ Surely you would think that with the power D has such things would exist by now? Here's two popular libraries that implement @nogc containers: http://code.dlang.org/packages/emsi_containers http://code.dlang.org/packages/memutils I don't know if in they have containers supporting concurrent lock-free operations, but still, it may be worth having a look.
Re: Windows 10 Linux Bash Shell: Compiling linux app on windows
On Saturday, 6 August 2016 at 17:18:51 UTC, Andre Pany wrote: Hi, I play around with the new windows 10 feature to run a linux sub system on windows. -> Installing dmd is working fine with the command curl -fsS https://dlang.org/install.sh | bash -s dmd -> Activating dmd is also working source ~/dlang/dmd-2.071.1/activate -> dmd can be started and shows correct version dmd --version. -> Compiling a hello world works, linking fails "dmd test -c" creates a test.o file but "dmd test" fails with error: cc: no such file or directory --- errorlevel 255 Do you have an idea how to fix the linker issue? Kind regards André Just like on a regular linux distro, you need to have installed standard development tools such as a C compiler toolchain. Since the install script on dlang's homepage is not a deb package it doesn't verify if those dependencies are fulfilled. I think running "sudo apt-get install build-essential" in bash.exe should do it (install C compiler and a "cc" alias to it). The other option is to download the Ubuntu/Debian x86_64 .deb package and do "sudo dpkg -i" on it: http://downloads.dlang.org/releases/2.x/2.071.1/dmd_2.071.1-0_amd64.deb and it will find the missing dependencies, so you can later install them, like described here: http://superuser.com/questions/196864/how-to-install-local-deb-packages-with-apt-get
Re: Verifying the arguments of a function with ref parameters?
On Thursday, 28 July 2016 at 21:49:00 UTC, pineapple wrote: On Thursday, 28 July 2016 at 20:28:39 UTC, jdfgjdf wrote: "Parameters!dgref.init" does not yield a reference. The real error is not displayed. In a normal context it would be "stuff is not callable with" What would be a better way to check whether some callable can be called using a parameters tuple? http://dlang.org/phobos/std_traits#.lvalueOf
Re: Is there a way to "see" source code generated by templates after a compile?
On Tuesday, 19 July 2016 at 20:19:53 UTC, WhatMeWorry wrote: On Sunday, 17 July 2016 at 05:57:52 UTC, WhatMeWorry wrote: I don't suppose there's a way to "see" source code generated by templates after a compile but before execution? Or does the compiler generate it to a lower level on the fly; thus losing the source code? I'm assuming no because if there were a way, I'd of come across it by now :) I've just stumbled across this on dmd documentation. Haven't had time to play with it yet. -allinst generate code for all template instantiations This is not what you are looking for. This option makes dmd put seemingly unused code in the binary. It does not output human-readable template instantations. It was meant to help workaround linking errors at the time when the lazy template instantiation mechanism was not so robust as nowadays.
Re: Second class pointers
On Friday, 8 July 2016 at 06:17:43 UTC, Nicholas Wilson wrote: On Friday, 8 July 2016 at 05:53:21 UTC, Nicholas Wilson wrote: So as part of my effort to get D running on GPUs I need to make a "second class" pointer type that I can alter in the backend of LDC to the correct address space. to that end I have made the following module dcompute.types.pointer; enum Private = 0; enum Global = 1; enum Shared = 2; enum Constant = 3; enum Generic = 4; pure @trusted nothrow @nogc struct Pointer(uint p, T) if(p <= Generic) { T* ptr; ref T opUnary(string op)() if(op=="*") { return *ptr; } ref T opIndex(size_t i) { return *(ptr+i); } auto opBinary(string op)(ptrdiff_t i) if(op=="+" || op == "-") { return Pointer!(p, T) (ptr + i); } } ... That should be mixin("ptr"~op~"i") I need compound add and compound subtract as well. Why not make the address (memory) space a strongly-typed enum, e.g.: enum AddressSpace { threadLocal = 0, groupLocal = 1, global = 2, constant = 3, texture = 4 generic = 5 } struct Pointer(T, AddressSpace type = AddressSpace.Generic) // ... ? is there anything else that I'm missing that you can do with a raw pointer? Slicing: // Pseudo OpenCL-D groupLocal T* ptr1; groupLocal T[] slice1 = ptr1[2 .. 10]; global T* ptr2; groupLocal T[] slice2 = ptr2[0 .. 2]; // Error
Re: Initializing static array with contents of (static and dynamic) arrays
On Monday, 4 July 2016 at 14:31:41 UTC, Johannes Loher wrote: In a project I am currently working on, I have lot's of code of the following form: static immutable ubyte[4] sigma0 = [101, 120, 112, 97]; static immutable ubyte[4] sigma1 = [110, 100, 32, 51]; static immutable ubyte[4] sigma2 = [ 50, 45, 98, 121]; static immutable ubyte[4] sigma3 = [116, 101, 32, 107]; void func(in ubyte[32] key, in ubyte[16] n) { ubyte[64] buf; buf[0..4] = sigma0; buf[4..20] = key[0..16]; buf[20..24] = sigma1; buf[24..40] = n; buf[40..44] = sigma2; buf[44..60] = key[16..$]; buf[60..64] = sigma3; /* do something with buf */ } This looks really bad to me. I would like to initialize buf with the corresponding values (the way it's done now, it is impossible to make buf immutable...). One option for this would be to use ~ to concatenate the arrays. But this obviously results in GC allocations, which I want to avoid here, because the functions get called very often. Another option would be to to manually expand the arrays and initialize buf with that: ubyte[64] buf = [sigma0[0], sigma0[1], /* ... */, sigma3[3]]; This is obviously very annoying and error prone. Whe searching for a solution, I found this thread about automatic expanding of arrays: http://forum.dlang.org/thread/hwellpcaomwbpnpof...@forum.dlang.org?page=1 This would result in the following code for me: ubyte[64] buf = [ expand!sigma0, expand!key[0..16], expand!sigma1, expand!n, expand!sigma2, expand!key[16..$], expand!sigma3 ]; Is this the suggested solution (is it robust)? Is there anything like this in Phobos? Thanks for your help! You should be able to use http://dlang.org/phobos-prerelease/std_meta#aliasSeqOf for this. I think it should work with the same syntax as expand, but with added bonus that it also handles ranges like those in std.range and std.algorithm.
Re: Creating a reference counted type?
On Sunday, 12 June 2016 at 14:49:18 UTC, Gary Willoughby wrote: On Sunday, 12 June 2016 at 14:45:12 UTC, ketmar wrote: ahem... wut?! we have one copy of our struct freed half the way, and another copy has refcount of 2, so it won't be freed at all. it doesn't so innocent as it looks: we may try to use `f` in `main`... just to find out that resources was mysteriously freed, and refcount is total garbage. Hmmm. I thought it looked *too* simple. Have you any idea if there is a simple solution to this? You need to allocate the ref count on the heap so it is actually shared between all copies of the struct. Also if you want to share the reference between multiple threads, you need to use core.atomic.atomicOp for incrementing and decrementing. See std.typecons.RefCounteed's implementation for reference https://github.com/dlang/phobos/blob/v2.071.0/std/typecons.d#L4712 You can use AffixAllocator http://dlang.org/phobos-prerelease/std_experimental_allocator_building_blocks_affix_allocator.html, so that ref count is automatically placed before or after the actual objected that is being ref counted. Just note that AffixAllocator is safe to use only by a single thread.
Re: asm woes...
On Saturday, 28 May 2016 at 08:10:50 UTC, Era Scarecrow wrote: On Friday, 27 May 2016 at 09:22:49 UTC, Guillaume Piolat wrote: You have to write your code three times, one for version(D_InlineAsm_X86) version (D_InlineAsm_X86_64) and a version without assembly. Rather than make a new thread I wonder if struct inheritance wouldn't solve this, as trying to manage specific versions, lack of versions, checks for CTFE all became a headache. and bloated a 4 line function (2 of which were the opening/declaration) to something like 20 lines and looks like a huge mess. So... Let's assume structs as they are don't (otherwise) change. Let's assume structs can be inherited. Let's assume inherited structs change _behavior_ only (overridden functions as final), but don't add/expand any new data (non-polymorphic, no vtables). Then I could do something like this! //contains plain portable version struct base {} version(X86) { struct inherited : base { //only adds or replaces functions, no data changes //all asm injection is known to be 32bit x86 } } version(X86_64) { ... } Truthfully going with my example, only a couple functions would be considered, namely multiply and divide as they would be the slowest ones, while everything else has very little to improve on, at least based on how wideint.d was implemented. The great thing about D's UFCS is that it allows exactly that: void main() { WideInt myInt; myInt.inc(); // looks like a member function myInt++; // can be hidden behind operator overloading } struct WideInt { ulong[2] data; int opUnary(string s)() { static if (s == "++") this.inc(); } } version(D_InlineAsm_X86_64) { void inc(ref WideInt w) { /* 32-bit increment implementation */ } } else version(D_InlineAsm_X86) { void inc(ref WideInt w) { /* 64-bit increment implementation */ } } else { void inc(ref WideInt w) { /* generic increment implementation */ } } Also, you can implement inc() in terms of ulong[2] - void inc(ref ulong[2] w), which makes it applicable for other types, with the same memory representation. E.g. cent - (cast(ulong[2]*)).inc(), arrays - ulong[] arr; arr[0..2].inc(), and so on.
Re: Is there an easy way to convert a pointer to malloc'd memory to an array?
On Tuesday, 24 May 2016 at 18:42:41 UTC, Gary Willoughby wrote: I have a T* pointer to the start of a malloc'd chunk of memory, the type T and the number of T's stored in the chunk. Is there an efficient way of converting this information to a D array of type T[] or even T[n]? BTW, the simplest way to use C malloc to allocate and initialize a D array is with http://dlang.org/phobos/std_experimental_allocator#makeArray: struct MyObj { /* ... */ } { MyObj[] arr = Mallocator.instance .makeArray!MyObj(10, ctorArgs); scope (exit) Mallocator.instance.dispose(arr); // use arr... } // arr is freed at the end of the scope Which is rougly equivalent to: void* p = malloc(10 * MyObj.sizeof); T[] arr = (cast(T*)p)[0 .. 10]; foreach (ref elem; arr) emplace(elem, ctorArgs); The benfit of using make* and dispose is that they allow you to change the allocator if you so need. You can also use the GC: int[] arr = GCAllocator.instance.makeArray!int(128); // no need to free arr The common idiom is that the user of a function that produces an array should supply the allocator as a parameter through which the function will make allocations. This useful when you know for example that the allocation would be small and short-lived in which case it would better to use a stack allocator, rather than a heap allocator.
Re: Newbie to D, first impressions and feedback on the 5 (and more) first minutes.
On Tuesday, 24 May 2016 at 15:27:45 UTC, llaine wrote: Hi everybody, As written in the description I'm really new to D, I discovered it a few weeks ago thanks to the D Conf in Berlin. After playing around for couple of days with it, I wanted to share my journey with you guys on several points. 1 - Installation (DMD and DUB) I'm running Fedora 23 on a daily basis and the installation was OK. Not as easy as on mac but still. I can't say that that it was easy, because I had to curl dub.rpm package and compile it from source. But it doesn't matter because for a linux user thoses things a pretty usual. 2 - Play-around That is the good part, after setting up my evt creating a Hello World project and something a bit more complicated was really easy. Thank's to DUB which take care of everything for me I was able to create a website using Vibe.d project. Congratulations on this point to all the people who made dub. Programming in 2016 should be like this. The only bad point I can see here is that it looks like it's more easy easy to get ready on a mac than on a linux machine. (I tried all this with a friend who is running the latest version of mac). 3 - Library That part was also good. Clicking on the packages menu on the website and searching for the things I need was indeed super easy. Everything in a big registery that's cool. I have a to say that I'm fucking amazed by the dlang.org website which is super fast (WOW). 4 - Documentation (For a newbie) This part was a bit different. By being a total newbie to the D language I don't really know where to begins. Of course I went to the getstarted.html page but as a newbie with no system programming background I feel there are too many choices for me. IMHO the best solution here would some kind of step by step tutorial that go through all thoses points with very basic explanation. After trying every of thoses pages, I finally try the "D Web Development Kai Nacke" book which is pretty interesting. The only bad point here is that I can't find a "Effective D" page. A document that gives tips for writing clear, idiomatic D code. A must read for any new D programmer. It augments the tour and the language specification, both of which should be read first. (Like in golang for example) 5 - Tools Well in one word. It sucks. I've tried to setup an editor with all the features that we can see in the wiki matrix. The only one which take them all is vscode. But for setup the plugin I had to compile the workspace-d package (which at the end didn't worked https://github.com/Pure-D/workspace-d/issues/16#issuecomment-221274965). So I folded over Sublime Text to have autocompletion but it's only available for the standard library (and not for Vibe.d, the things that i'm looking to use). However I had to say that I was amazed by the rapidity of speed answer over my github issue, WebFreak001 is doing really great job here!! So, my plan here is to get more knowledge about the dlang in near future. I'll be active on forum to annoy you guys. Ps : I'm looking for up to date benchmark such as Dlang vs Go vs Nodejs vs Swift vs TurboPascal ;) (Actually without pascal). Cheers Thanks for the detailed experience report! Just one question about the installation - have you tried the install.sh script on http://dlang.org/download? I really like it because it is simple, allows you to manage several versions of the language and even provides easy access to the nightly builds. About the benchmarks - you should know that any benchmark actually measures the speed of the generated code by a particular implementation of the language and also particular library functions, so you can't objectively compare languages that way, because all languages allow you to solve the same problem in different ways and also becuase different compilers can generate different code from the same D source file. Of the languages you have listed, D gives you the most unrestricted access to the hardware, which would allow you to squeeze every bit of performance. However, unlike other systems programming languages, it allows you to write your code almost as easily as with scripting languages, which allows you to get a working prototype quickly and later (if you so desire) you can optimize it. My general advice is to use DMD for its quick edit-compile-debug cycle, and then use LDC or GDC for measuring perfomance. Currently I would recommend LDC as it is more up-to-date with DMD at the moment, than GDC.
Re: foreach(i,ref val; ndim_arr)??
On Tuesday, 10 May 2016 at 10:21:30 UTC, ZombineDev wrote: On Monday, 9 May 2016 at 18:50:32 UTC, Jay Norwood wrote: I noticed some discussion of Cartesian indexes in Julia, where the index is a tuple, along with some discussion of optimizing the index created for cache efficiency. I could find foreach(ref val, m.byElement()), but didn't find an example that returned a tuple index. Is that supported? http://julialang.org/blog/2016/02/iteration http://julialang.org/blog/2016/03/arrays-iteration I guess you are talking about ndslice (http://dlang.org/phobos/std_experimental_ndslice). There are various functions that can take static arrays, as well as tuples as parameters that are both cache-efficient. For example: http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.makeSlice and http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.Slice.opIndex I also found the need for a byElement function that also provides the index. I guess it is a good idea for a pull request. In the mean time, you can use the following: auto indexed_range = lockstep( ndslice.byElement, ndslice.shape.indexSlice ); foreach (ref elem; indexes; indexed_range) writefln("Element at %s = %s", indexes, elem); Oops, this is not entirely correct. Sorry, I was on the phone and I couldn't verify it. Here's a working example: (You can try it at: https://dpaste.dzfl.pl/c0327f067fca) import std.array : array; import std.experimental.ndslice : byElement, indexSlice, sliced; import std.range : iota, lockstep, zip; import std.stdio : writefln; void main() { // needs .array for ref (lvalue) access // (iota offers only rvalues) auto slice = iota(2 * 3 * 4).array.sliced(2, 3, 4); auto indexed_range = lockstep( slice.shape.indexSlice.byElement(), slice.byElement() ); writefln("%s", slice); foreach (idx, ref elem; indexed_range) writefln("Element at %s = %s", idx, ++elem); } [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]] Element at [0, 0, 0] = 1 Element at [0, 0, 1] = 2 Element at [0, 0, 2] = 3 Element at [0, 0, 3] = 4 Element at [0, 1, 0] = 5 Element at [0, 1, 1] = 6 Element at [0, 1, 2] = 7 Element at [0, 1, 3] = 8 Element at [0, 2, 0] = 9 Element at [0, 2, 1] = 10 Element at [0, 2, 2] = 11 Element at [0, 2, 3] = 12 Element at [1, 0, 0] = 13 Element at [1, 0, 1] = 14 Element at [1, 0, 2] = 15 Element at [1, 0, 3] = 16 Element at [1, 1, 0] = 17 Element at [1, 1, 1] = 18 Element at [1, 1, 2] = 19 Element at [1, 1, 3] = 20 Element at [1, 2, 0] = 21 Element at [1, 2, 1] = 22 Element at [1, 2, 2] = 23 Element at [1, 2, 3] = 24
Re: foreach(i,ref val; ndim_arr)??
On Tuesday, 10 May 2016 at 13:52:27 UTC, ag0aep6g wrote: Am 10.05.2016 um 12:21 schrieb ZombineDev: auto indexed_range = lockstep( Tiny nitpick: lockstep doesn't return a range. It uses opApply to support foreach. Yes I know and I chose it in purpose, because it allows ref access to individual elements (zip returns a tuple which doesn't provide ref access). Otherwise my translation of OP wouldn't be accurate.
Re: foreach(i,ref val; ndim_arr)??
On Monday, 9 May 2016 at 18:50:32 UTC, Jay Norwood wrote: I noticed some discussion of Cartesian indexes in Julia, where the index is a tuple, along with some discussion of optimizing the index created for cache efficiency. I could find foreach(ref val, m.byElement()), but didn't find an example that returned a tuple index. Is that supported? http://julialang.org/blog/2016/02/iteration http://julialang.org/blog/2016/03/arrays-iteration I guess you are talking about ndslice (http://dlang.org/phobos/std_experimental_ndslice). There are various functions that can take static arrays, as well as tuples as parameters that are both cache-efficient. For example: http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.makeSlice and http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.Slice.opIndex I also found the need for a byElement function that also provides the index. I guess it is a good idea for a pull request. In the mean time, you can use the following: auto indexed_range = lockstep( ndslice.byElement, ndslice.shape.indexSlice ); foreach (ref elem; indexes; indexed_range) writefln("Element at %s = %s", indexes, elem);
Re: Async or event library
On Tuesday, 10 May 2016 at 09:58:38 UTC, ZombineDev wrote: On Monday, 9 May 2016 at 09:14:31 UTC, chmike wrote: [...] Have you looked at http://vibed.org? It is the most successful D library for async IO and it has several backends (some C and some D). It also provides a high-level web framework functionality on top, but it is optional and you can freely use only the low-level stuff. See also: http://code.dlang.org/search?q=event http://code.dlang.org/search?q=async Also, AFAIR, the author intends to merge some of the low-level functionality to Phobos.
Re: Async or event library
On Monday, 9 May 2016 at 09:14:31 UTC, chmike wrote: It seam that the scope of the event loop we are talking should be clarified to avoid confusions. There is the GUI event loop which is generally single threaded for efficient access to the data structure representing the GUI content. Single thread also simplifies synchronization and make deadlocks impossible. GUI events incoming rates are generally slow because it is human driven. So a single threaded GUI event loop is a very reasonable choice. The other event loop is for IO and timers. In this case the event rate can be very high and the speed is critical. This is where multithreading can play a useful role and the topic I am interested with. On unix the OS provides a fast select (epoll, kevent) which tells the user on which fd an event occurred. epoll doesn't cover asynchronous file operations and timer events. On Windows the OS provides IOCP which support queued operations and the user is notified of the completion. The boost asio lib adopted the IOCP model. Users queue asynchronous tasks and a callback function that is executed when the task is completed. That is also the model of I/O or timer event loops (e.g. libev, libuv, libevent). Unfortunately it seam that we don't have much liberty degree if we want an API that can work on Windows and unix. But the unix model can be more efficient. Here is a blog post reporting that the author could implement a more efficient system than libuv by using epoll directly http://blog.kazuhooku.com/2014/09/the-reasons-why-i-stopped-using-libuv.html. Have you looked at http://vibed.org? It is the most successful D library for async IO and it has several backends (some C and some D). It also provides a high-level web framework functionality on top, but it is optional and you can freely use only the low-level stuff. See also: http://code.dlang.org/search?q=event http://code.dlang.org/search?q=async
Re: what's the right way to get char* from string?
On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote: Hello, When I need to call C function, often need to have char* pointer from string. "Interfacing to C++" page: https://dlang.org/spec/cpp_interface.html have following example. extern (C) int strcmp(char* string1, char* string2); import std.string; int myDfunction(char[] s) { return strcmp(std.string.toStringz(s), "foo"); } but this is incorrect because toStringz() returns immutable pointer. One way is to write mutable version of toStringz() char* toStringzMutable(string s) @trusted pure nothrow { auto copy = new char[s.length + 1]; copy[0..s.length] = s[]; copy[s.length] = 0; return copy.ptr; } But I think this is common needs, why it is not provided by Phobos? (or tell me if it has) Thanks, aki In this particular case, if you `import core.stdc.string : strcmp`, instead of providing your own extern declaration it should work, because in there the signature is correctly typed as `in char*` which is essentially the same as `const(char*)` which can accept both mutable, const and immutable arguments. Also it has the correct attributes so you can call it from `pure`, `nothrow` and `@nogc` code. As others have said, when you do need to convert a string slice to a pointer to a null terminated char/wchar/dchar string, `toUTFz` can be very useful. But where possible, you should prefer functions that take an explicit length parameter, so you can avoid memory allocation: ``` string s1, s2; import std.algorithm : min; import core.stdc.string : strncmp; strncmp(s1.ptr, s2.ptr, min(s1.length, s2.length)); // (`min` is used to prevent the C function from // accessing data beyond the smallest // of the two string slices). ``` Also string slices that point to a **whole** string literal are automatically null-terminated: ``` // lit is zero-terminated string lit = "asdf"; assert (lit.ptr[lit.length] == '\0'); assert (strlen(lit.ptr) == lit.length); ``` However you need to be very careful, because as soon as you make a sub-slice, this property disappears: ``` // slice is not zero-terminated. string slice = lit[0..2]; assert (slice.ptr[length] == 'd'); assert (strlen(slice.ptr) != slice.length); ``` This means that you can't be sure that a string slice is zero-termninated unless you can see it in your code that it points to a string literal and you're sure that it would never be changed to point to something else (like something returned from a function).
Re: Anonymous structure
On Tuesday, 19 April 2016 at 20:19:37 UTC, ZombineDev wrote: On Tuesday, 19 April 2016 at 20:18:07 UTC, ZombineDev wrote: On Tuesday, 19 April 2016 at 17:16:00 UTC, Tofu Ninja wrote: On Tuesday, 19 April 2016 at 16:16:39 UTC, ZombineDev wrote: On Monday, 18 April 2016 at 23:00:42 UTC, captaindet wrote: On 2016-04-18 14:12, Tofu Ninja wrote: Also is there a way to have a named substructure, not a nested structure but something to just add an additional name, maybe something like struct a{ struct{ int x; int y; int z; } b; } not sure what you mean by "named substructure, not a nested structure" but this works: struct Outer{ struct Inner{ int x; int y; int z; } Inner inner; int a; } Outer outer; outer.a = 7; outer.inner.y = 42; // outer.x = 13; //fails writeln(outer); There's another way: http://forum.dlang.org/post/n3q9vn$1l8g$1...@digitalmars.com How is that supposed to work here? struct A { template _b() { int x, y, z; } alias b = _b!(); } void main() { import std.stdio; auto a = A(); a.b.x = 5; writeln(a.b.x); // prints 5 //writeln(a.b); // Error: expression has no value } Also functions defined in _b can access members of A. And also: import std.traits; writeln(Fields!A.stringof); // prints () writeln(Fields!Outer.stringof); // prints (Inner, int)
Re: Anonymous structure
On Tuesday, 19 April 2016 at 20:18:07 UTC, ZombineDev wrote: On Tuesday, 19 April 2016 at 17:16:00 UTC, Tofu Ninja wrote: On Tuesday, 19 April 2016 at 16:16:39 UTC, ZombineDev wrote: On Monday, 18 April 2016 at 23:00:42 UTC, captaindet wrote: On 2016-04-18 14:12, Tofu Ninja wrote: Also is there a way to have a named substructure, not a nested structure but something to just add an additional name, maybe something like struct a{ struct{ int x; int y; int z; } b; } not sure what you mean by "named substructure, not a nested structure" but this works: struct Outer{ struct Inner{ int x; int y; int z; } Inner inner; int a; } Outer outer; outer.a = 7; outer.inner.y = 42; // outer.x = 13; //fails writeln(outer); There's another way: http://forum.dlang.org/post/n3q9vn$1l8g$1...@digitalmars.com How is that supposed to work here? struct A { template _b() { int x, y, z; } alias b = _b!(); } void main() { import std.stdio; auto a = A(); a.b.x = 5; writeln(a.b.x); // prints 5 //writeln(a.b); // Error: expression has no value } Also functions defined in _b can access members of A.
Re: Anonymous structure
On Tuesday, 19 April 2016 at 17:16:00 UTC, Tofu Ninja wrote: On Tuesday, 19 April 2016 at 16:16:39 UTC, ZombineDev wrote: On Monday, 18 April 2016 at 23:00:42 UTC, captaindet wrote: On 2016-04-18 14:12, Tofu Ninja wrote: Also is there a way to have a named substructure, not a nested structure but something to just add an additional name, maybe something like struct a{ struct{ int x; int y; int z; } b; } not sure what you mean by "named substructure, not a nested structure" but this works: struct Outer{ struct Inner{ int x; int y; int z; } Inner inner; int a; } Outer outer; outer.a = 7; outer.inner.y = 42; // outer.x = 13; //fails writeln(outer); There's another way: http://forum.dlang.org/post/n3q9vn$1l8g$1...@digitalmars.com How is that supposed to work here? struct A { template _b() { int x, y, z; } alias b = _b!(); } void main() { import std.stdio; auto a = A(); a.b.x = 5; writeln(a.b.x); // prints 5 //writeln(a.b); // Error: expression has no value }
Re: Anonymous structure
On Monday, 18 April 2016 at 23:00:42 UTC, captaindet wrote: On 2016-04-18 14:12, Tofu Ninja wrote: Also is there a way to have a named substructure, not a nested structure but something to just add an additional name, maybe something like struct a{ struct{ int x; int y; int z; } b; } not sure what you mean by "named substructure, not a nested structure" but this works: struct Outer{ struct Inner{ int x; int y; int z; } Inner inner; int a; } Outer outer; outer.a = 7; outer.inner.y = 42; // outer.x = 13; //fails writeln(outer); There's another way: http://forum.dlang.org/post/n3q9vn$1l8g$1...@digitalmars.com
Re: pass a struct by value/ref and size of the struct
On Saturday, 2 April 2016 at 09:28:58 UTC, ZombineDev wrote: On Wednesday, 23 March 2016 at 19:39:49 UTC, kinke wrote: On Tuesday, 22 March 2016 at 07:35:49 UTC, ZombineDev wrote: If the object is larger than the size of a register on the target machine, it is implicitly passed by ref That's incorrect. As Johan pointed out, this is somewhat true for the Win64 ABI (but it firstly copies the argument before passing a pointer to it!), but it's not for the 32-bit x86 and x86_64 System V (used on all non-Windows platforms) ABIs. System V is especially elaborate and may pass structs up to twice the size of a register in 2 registers. Bigger structs passed by value are blitted into the function arguments stack in memory. They are then accessed by the callee via a stack offset, that's correct, but I wouldn't call that implicit-by-ref-passing, as copying does take place, unless the optimizer decides it's unnecessary. So passing structs > 64-bit by value on Win64 never pays off (there's always an indirection); using `const ref(T)` where possible makes sure you at least elide the copy. But then again, you'll very soon find out that it's not really an option as rvalues cannot be passed byref in D, something a lot of people [including myself if not already obvious :)] hate about D. Thank you and Johan for the detailed explanation. You're efforts on improving LDC are much appreciated. My intentions were to say that taking structs by value shouldn't be as expensive as in C++, because of the way D handles copy construction, especially if there is no user-defined postblit (which is quite common), and also because separate compilation is used more rarely. But probably I shouldn't have said that about the size of registers as it depends very much on the ABI and it's not true in general (as you pointed out). BTW, how does LDC handle the `auto ref` and `in` parameter attributes for templated functions (that obviously have their source code available)? Can they be used to prevent indirection when the structure can be passed in registers and to prevent copying when passing by registers is not possible? I find that (at least from a usability standpoint) auto ref works quite well: // UniqueRef has disabled this(this) UniqueRef!Resource r; void use()(auto ref UniqueRef!Resource r); // borrows use(r); // passes ownership of rvalues use(UniqueRef!Resource()) // transfers ownership use(move(r)); // r == UniqueRef.init here //= auto ref add(V)(auto ref V v1, auto ref V v2); // default this(this) Vec3f vec1; // accepts both lvalues and rvalues auto res = add(vec1, Vec3f(1, 2, 3.14));
Re: pass a struct by value/ref and size of the struct
On Wednesday, 23 March 2016 at 19:39:49 UTC, kinke wrote: On Tuesday, 22 March 2016 at 07:35:49 UTC, ZombineDev wrote: If the object is larger than the size of a register on the target machine, it is implicitly passed by ref That's incorrect. As Johan pointed out, this is somewhat true for the Win64 ABI (but it firstly copies the argument before passing a pointer to it!), but it's not for the 32-bit x86 and x86_64 System V (used on all non-Windows platforms) ABIs. System V is especially elaborate and may pass structs up to twice the size of a register in 2 registers. Bigger structs passed by value are blitted into the function arguments stack in memory. They are then accessed by the callee via a stack offset, that's correct, but I wouldn't call that implicit-by-ref-passing, as copying does take place, unless the optimizer decides it's unnecessary. So passing structs > 64-bit by value on Win64 never pays off (there's always an indirection); using `const ref(T)` where possible makes sure you at least elide the copy. But then again, you'll very soon find out that it's not really an option as rvalues cannot be passed byref in D, something a lot of people [including myself if not already obvious :)] hate about D. Thank you and Johan for the detailed explanation. You're efforts on improving LDC are much appreciated. My intentions were to say that taking structs by value shouldn't be as expensive as in C++, because of the way D handles copy construction, especially if there is no user-defined postblit (which is quite common), and also because separate compilation is used more rarely. But probably I shouldn't have said that about the size of registers as it depends very much on the ABI and it's not true in general (as you pointed out). BTW, how does LDC handle the `auto ref` and `in` parameter attributes for templated functions (that obviously have their source code available)? Can they be used to prevent indirection when the structure can be passed in registers and to prevent copying when passing by registers is not possible?
Re: How can convert the folowing to D.
On Friday, 1 April 2016 at 00:34:49 UTC, learner wrote: Hi, I have the following code in C++. rectangles.erase(rectangles.begin() + index); where rectangles is: std::vector rectangles; how can I do something similar in D. Learner. Also, if you are using std.container.array (which similar to std::vector in C++), you can use its linearRemove method, by giving it a range to remove (a slice of itself), like this: import std.container.array; import std.range : iota, drop, take; import std.stdio : writeln; void main() { auto arr = Array!int(10.iota); // initialize with [0, 10) arr[].writeln(); // same as arr.linearRemove(arr[5 .. 7]); arr.linearRemove(arr[].drop(5).take(2)); arr[].writeln(); } [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 7, 8, 9] The arr[] syntax is just a shorthand of arr.opSlice() which returns a range iterating over the elements of the array. Given this range, you can use the algorithms from http://dlang.org/phobos/std_range to perform further manipulations.
Re: Solution to "statement is not reachable" depending on template variables?
On Friday, 1 April 2016 at 01:21:32 UTC, Walter Bright wrote: On 3/16/2016 4:18 AM, Johan Engelen wrote: I've found discussions, but not an actual "recommended" solution for the problem of "statement is not reachable" warnings in templates with early returns, e.g.: ``` bool nobool(T...)() { foreach (i, U; T) { static if (is(U == bool)) { return false; } } return true; // emits "Warning: statement is not reachable" } bool nobool(T...)() { bool result = true; foreach (i, U; T) { static if (is(U == bool)) { result = false; break; } else { ... } } return result; // emits "Warning: statement is not reachable" } Note that the optimizer will remove the dead loads. Actually, I would expect every call of this fuction to be replaced by a boolean constant, since the result depends only on compile-time information. What happened to "obvious code should be correct"? Can we try to find a solution that doesn't look like a hack? I don't think that we should ask users of the language to uglify their code just to workaround a deficiency in the compiler. Instead, we should improve the lowering of the static foreach construct so the information that it is syntactically a loop is preserved after loop unrolling.
Re: I need some help benchmarking SoA vs AoS
On Saturday, 26 March 2016 at 17:43:48 UTC, maik klein wrote: On Saturday, 26 March 2016 at 17:06:39 UTC, ag0aep6g wrote: On 26.03.2016 18:04, ag0aep6g wrote: https://gist.github.com/aG0aep6G/a1b87df1ac5930870ffe/revisions PS: Those enforces are for a size of 100_000 not 1_000_000, because I'm impatient. Thanks, okay that gives me more more reliable results. for 1_000_000 benchmarking complete access AoS: 1 sec, 87 ms, 266 μs, and 4 hnsecs SoA: 1 sec, 491 ms, 186 μs, and 6 hnsecs benchmarking partial access AoS: 7 secs, 167 ms, 635 μs, and 8 hnsecs SoA: 1 sec, 20 ms, 573 μs, and 1 hnsec This is sort of what I expected. I will do a few more benchmarks now. I probably also randomize the inputs. Can you benchmark my implementation (http://dpaste.dzfl.pl/3de1e18756f8) against yours? It should have roughly the same API, except that mine doesn't support pre-allocation (reserving capacity) - I wanted to keep it minimalistic. During access it should have the same performance, however the insertion behavior should be noticeably different. I'm interested to see if one larger allocation on insertion would be faster than a number of small ones (or vice-versa). Though, AoS should be the fastest in this regard (growth performance).
Re: Containers, Allocators and Purity
On Thursday, 24 March 2016 at 11:18:06 UTC, Nordlöw wrote: Could somebody briefly outline how the thread-locality (non-GC-locked) of allocators relates to the purity of the containers using them? This because I want to move forward with optimizations in my knowledge graph that requires GC-free array containers storing value typed elements (integers) which preferrably has pure API. Specifically, I want to use something like https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d that is `@safe pure` and uses lock-free allocations in a heavily multi-threaded application. If I want purity aswell which `std.experimental.allocators` are possible? After a quick glance at: https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d It looks like if `useGC == false`, all of the methods should be `pure`-ready, except for `remove(size_t)` and `~this()`. These two methods use `typeid.destroy`, which I don't think is `pure`.
Re: Containers, Allocators and Purity
On Thursday, 24 March 2016 at 11:18:06 UTC, Nordlöw wrote: Could somebody briefly outline how the thread-locality (non-GC-locked) of allocators relates to the purity of the containers using them? This because I want to move forward with optimizations in my knowledge graph that requires GC-free array containers storing value typed elements (integers) which preferrably has pure API. Specifically, I want to use something like https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d that is `@safe pure` and uses lock-free allocations in a heavily multi-threaded application. If I want purity aswell which `std.experimental.allocators` are possible? Currently almost nothing in `std.experimental.allocators` is explicitly marked as pure, except for some of the things in ./common.d (https://github.com/D-Programming-Language/phobos/pull/3957 *shameless plug*). Thankfully make, makeArray, dispose and some of the allocators are templates, so you can rely on attribute inference. The most important thing is that you need to have pure `allocate` and `deallocate` methods. After this `make` and friends will work like magic (at least for types with pure `this` and `~this`). `pure` statefull allocator essentially means that it has to be thread-local, so there are no global side-effects. Essentially, to achieve this you can make a large initial allocation in each thread (even from a non-pure allocator) and then you can make `pure` sub-allocations out of it. You can read more about my adventures with my `pure` smart pointer here: http://forum.dlang.org/post/eegjluaiwvdxfnbxk...@forum.dlang.org http://forum.dlang.org/post/bvgyrfvuqrqcyvhkq...@forum.dlang.org
Re: pass a struct by value/ref and size of the struct
On Monday, 21 March 2016 at 23:31:06 UTC, ref2401 wrote: I have got a plenty of structs in my project. Their size varies from 12 bytes to 128 bytes. Is there a rule of thumb that states which structs I pass by value and which I should pass by reference due to their size? Thanks. If the object is larger than the size of a register on the target machine, it is implicitly passed by ref (i.e. struct fields are accessed by offset from the stack pointer). So the question is: does the compiler need to create temporaries and is this an expensive operation? In C++ the problem is that there are lots of non-POD types which have expensive copy constructors (like std::vector) and that's why taking objects by const& is good guideline. In D structs are implicitly movable (can be memcpy-ed around without their postblit this(this) function called) and that's why I think that passing by value shouldn't be as large problem as in C++, especially if you are using a good optimizing compiler such as LDC or GDC. Anyway, modern hardware in combination with compiler optimizations can often suprise you, so I recommend profiling your code and doing microbenchmarks to figure out where you may have performance problems. In my experience, large amounts of small memory allocations is orders of magnitude larger problem than the copying of large value types. The next thing to look for is inefficient memory layout with lots of indirections.
Re: /usr/bin/ld: cannot find -lphobos2
On Monday, 21 March 2016 at 10:46:27 UTC, ag0aep6g wrote: On 21.03.2016 11:19, ZombineDev wrote: DFLAGS=-I~/dev/repos/dlang/druntime/import -I~/dev/repos/dlang/phobos -L-L/home/zombinedev/dev/repos/dlang/phobos/generated/*/release/64 [...] Linking... ... /usr/bin/ld {other stuff...} -L/home/zombinedev/dev/repos/dlang/phobos/generated/*/release/64 -lphobos2 /usr/bin/ld: cannot find -lphobos2 However $ ls /home/zombinedev/dev/repos/dlang/phobos/generated/*/release/64 etc libphobos2.a libphobos2.so libphobos2.so.0.70 libphobos2.so.0.70.0 libphobos2.so.0.70.o Any idea what I'm doing wrong? Asterisk expansion is a shell feature. dmd probably doesn't go through a shell when running ld. Even if it did, no expansion would be done there, because the word is looked at as a whole. With the leading "-L", the pattern doesn't match an actual path. For example, compare `echo /*` with `echo -L/*`. You have to spell the different paths out. Thanks a lot! I replaced "*" with the name of my OS and it all works! I thought that if it could replace $HOME, it ought to replace the asterisk. Probably I should add this caveat to http://wiki.dlang.org/Starting_as_a_Contributor#Running_Independent_Programs for future reference.
Re: Enabling Only Top-Level Unittests
On Monday, 21 March 2016 at 10:29:36 UTC, Nordlöw wrote: I want to enable unittests only at the top-level of a module compilation. If I have a module top.d that imports dep1.d dep2.d ... which all contain unittests, how do I compile top.d with only the unittests for top.d enabled? I think the easiest solution is to use http://dlang.org/spec/traits.html#getUnitTests and to run the tests you want manually.
/usr/bin/ld: cannot find -lphobos2
I'm manually building dmd, druntime and phobos like so: $ cd ~/dev/repos/dlang $ git clone https://github.com/D-Programming-Language/dmd $ git clone https://github.com/D-Programming-Language/druntime $ git clone https://github.com/D-Programming-Language/phobos $ cd dmd && make -f make -f posix.mak -j4 AUTO_BOOTSTRAP=1 $ cd ../druntime && make -f make -f posix.mak -j4 $ cd ../phobos && make -f make -f posix.mak -j4 $ cat << EOF > ~/dev/repos/dlang/dmd/src/dmd.conf [Environment] DFLAGS=-I~/dev/repos/dlang/druntime/import -I~/dev/repos/dlang/phobos -L-L/home/zombinedev/dev/repos/dlang/phobos/generated/*/release/64 EOF # required for dub $ sudo ln -s ~/dev/repos/dlang/dmd/src/dmd /bin/dmd When my I build my library with dub I can see that dmd.conf is detected correctly: $ cd $myproj (I added the following to my dub.sdl: dflags "-v" lflags "-v") $ dmd test --verbose ... Performing "unittest" build using dmd for x86_64. ... binarydmd version v2.070-devel-46cc1c6 config/home/zombinedev/dev/repos/dlang/dmd/src/dmd.conf ... Linking... ... /usr/bin/ld {other stuff...} -L/home/zombinedev/dev/repos/dlang/phobos/generated/*/release/64 -lphobos2 /usr/bin/ld: cannot find -lphobos2 However $ ls /home/zombinedev/dev/repos/dlang/phobos/generated/*/release/64 etc libphobos2.a libphobos2.so libphobos2.so.0.70 libphobos2.so.0.70.0 libphobos2.so.0.70.o Any idea what I'm doing wrong?
Re: is module ( std.experimental.logger) thread-safe.
On Sunday, 6 March 2016 at 09:54:49 UTC, Dsby wrote: I want to use the filelogger to my application. is the sharedLog() global and thread-safe. Yes, `FileLogger` internally uses `lockingTextWriter`, so it should be safe to call from multiple threads. Furthermore, the `sharedLog` property uses atomic load and store instructions, so it should be OK to concurrently change the shared logger.
Re: Assoc Array for Concurrency
On Monday, 29 February 2016 at 12:43:39 UTC, Chris wrote: What's the best way to make an assoc array fit for multi-threading? If this is not possible what would be the best alternative? Say, for example, `data` is used by a class that is globally accessible to all threads. E.g. like this: string[string] data; // defined somewhere public string getData(string key) { if (key in data) return data[key]; else return ""; } I'm almost sure that built-in AAs don't provide automatic synchronization (in my tests I hit a deadlock), but you can easily wrap the AA into a struct that does the necessary synchronization. However be aware that even then you are not going to be safe, because more than one thread can try to access the keys or the values of the AA. Also note that because the built-in AAs rely on the GC, you may get poor scaling because every memory allocation can potentially take the global GC lock, which will block all threads from doing any work. So do your own tests and if you find the need to improve the performance, I would suggest investigating replacing the built-in AA with (for example) the hashmap from https://github.com/economicmodeling/containers in combination with a thread-local allocator. Here's an example of how to wrap an AA into a moderately safe accessor. In the following example I create an additional thread which concurrently adds odd numbers into the AA, while the main threads add even nubmers: http://dpaste.dzfl.pl/06025e6374eb It segfaults on DPaste because you can't create threads there, however it works ok on my machine. The output look like this: "0" : 0.140450140112896 "1" : 1.140450129700608 "2" : 2.140450140112896 "3" : 3.140450129700608 "4" : 4.140450140112896 "5" : 5.140450129700608 "6" : 6.140450140112896 "7" : 7.140450129700608 ...
Re: Simple performance question from a newcomer
On Sunday, 21 February 2016 at 16:36:22 UTC, ZombineDev wrote: On Sunday, 21 February 2016 at 16:29:26 UTC, ZombineDev wrote: ... And if I use the Kahan algorithm: 106 ms 36 ms 31 ms The second two results are probably larger due to noise. I did some more testing and clearly the larger times for N=1000 were just noise: [LDC Kahan N=1000] 106 ms 36 ms 31 ms 59 ms 24 ms 22 ms ... Just for the record, with `DMD -release -O -inline`, Kahan, N=1000 I get: 325 ms 217 ms 165 ms 231 ms 117 ms 58 ms 131 ms 109 ms 58 ms 131 ms 109 ms 57 ms 131 ms 112 ms 57 ms 125 ms 106 ms 55 ms 125 ms 104 ms 55 ms 125 ms 105 ms 55 ms 125 ms 104 ms 55 ms 230 ms 115 ms 58 ms 131 ms 112 ms 58 ms 131 ms 109 ms 57 ms
Re: Simple performance question from a newcomer
On Sunday, 21 February 2016 at 16:29:26 UTC, ZombineDev wrote: ... And if I use the Kahan algorithm: 106 ms 36 ms 31 ms The second two results are probably larger due to noise. I did some more testing and clearly the larger times for N=1000 were just noise: [LDC Kahan N=1000] 106 ms 36 ms 31 ms 59 ms 24 ms 22 ms 46 ms 21 ms 20 ms 45 ms 21 ms 20 ms 45 ms 21 ms 20 ms 59 ms 24 ms 21 ms 102 ms 35 ms 30 ms 104 ms 37 ms 29 ms 107 ms 36 ms 31 ms 46 ms 21 ms 20 ms
Re: Simple performance question from a newcomer
On Sunday, 21 February 2016 at 14:32:15 UTC, dextorious wrote: I've been vaguely aware of D for many years, but the recent addition of std.experimental.ndslice finally inspired me to give it a try, since my main expertise lies in the domain of scientific computing and I primarily use Python/Julia/C++, where multidimensional arrays can be handled with a great deal of expressiveness and flexibility. Before writing anything serious, I wanted to get a sense for the kind of code I would have to write to get the best performance for numerical calculations, so I wrote a trivial summation benchmark. The following code gave me slightly surprising results: import std.stdio; import std.array : array; import std.algorithm; import std.datetime; import std.range; import std.experimental.ndslice; void main() { int N = 1000; int Q = 20; int times = 1_000; double[] res1 = uninitializedArray!(double[])(N); double[] res2 = uninitializedArray!(double[])(N); double[] res3 = uninitializedArray!(double[])(N); auto f = iota(0.0, 1.0, 1.0 / Q / N).sliced(N, Q); StopWatch sw; double t0, t1, t2; sw.start(); foreach (unused; 0..times) { for (int i=0; ia + b) instead of f.sum in sumtest1, but that yielded even worse performance. I did not try the GDC/LDC compilers yet, since they don't seem to be up to date on the standard library and don't include the ndslice package last I checked. Now, seeing as how my experience writing D is literally a few hours, is there anything I did blatantly wrong? Did I miss any optimizations? Most importantly, can the elegant operator chaining style be generally made as fast as the explicit loops we've all been writing for decades? The problem is not with ranges, but with the particualr algorithm used for summing. If you look at the docs (http://dlang.org/phobos-prerelease/std_algorithm_iteration.html#.sum) you'll see that if the range has random-access `sum` will use the pair-wise algorithm. About the second and third tests, the problem is with DMD which should not be used when measuring performance (but only for development, because it has fast compile-times). These are the results that I get with LDC: Pair-wise (sumtest1): 415 ms 21 ms 20 ms And if I use the Kahan algorithm: 106 ms 36 ms 31 ms The second two results are probably larger due to noise. And if I increase N to 100_000: Pair-wise (sumtest1): 29557 ms 2061 ms 1990 ms Kahan: 4566 ms 2067 ms 1990 ms According to `dub --verbose`, my command-line was roughly this: ldc2 -ofapp -release -O5 -singleobj -w source/app.d ../../../../.dub/packages/mir-0.10.1-alpha/source/mir/ndslice/internal.d ../../../../.dub/packages/mir-0.10.1-alpha/source/mir/ndslice/iteration.d ../../../../.dub/packages/mir-0.10.1-alpha/source/mir/ndslice/package.d ../../../../.dub/packages/mir-0.10.1-alpha/source/mir/ndslice/selection.d ../../../../.dub/packages/mir-0.10.1-alpha/source/mir/ndslice/slice.d
Re: vk.xml
On Sunday, 21 February 2016 at 12:52:33 UTC, Nicholas Wilson wrote: So I was going through the vulcan spec to try to create a better D bindings for it. (pointer /len pairs to arrays adhering to D naming conventions and prettying up the *Create functions functions like vkResult *Create( arg ,, retptr) to a fancy throw on misuse struct with constructors and that kind of stuff.) the structure of the registry is as follows. struct KHR_registry { } I'm glad to see more people looking to create a D binding from vk.xml! I was also working on this (http://forum.dlang.org/post/ygylvtuwwiwyqtcnl...@forum.dlang.org), unfortunately I won't be able to continue my work until early March, so I hope you'll do a good job in the mean time ;) Unfortunately the spec is written in a very C specific way so we need to have a bunch of special cases for parsing the C code that's interleaved with the XML tags. I haven't used std.xml yet, but I hope I may be able to help you. where "string content" is the string between the tags (does this have a name?) and thing with @Tag are always in the tag (although it is also inconsistent). I tried looking at the docs for std.xml but they were not very helpful. May be you can use http://dlang.org/phobos/std_xml#.Element.text in combination with http://dlang.org/phobos/std_xml#.Element.elements To further complicate things not all of the fields are present in all cases also I need to keep track of the number of '*' (see fields named indirections) after a tag has closed for pointer type declarations in function signatures and structs. You mean things like: void** ppData (from the vkMapMemory command) ? Yeah this is extremely ugly. One way to do it is to go to the "param" XML element and check if the size of it's elements matches it's text size. In the case above everything between and is 39 characters and the two tags are 17 and 19 character respectively (total 36) which leaves 3 chars for the indirections. If we make a pass to remove all whitespace between tags (between ">" and "<") we should get exactly 2 characters which is the number of indirection we're looking for. Another way is to just strip the tags and leave only their internal text. In the above example the result should be: void** ppData which is valid D code and we can leave it that way for now. Also is there a way to do sane cross referencing without having internal pointers everywhere. I am no XML expert (so there may be an easier way), but I think it would be easier if we use associative arrays, instead of plain arrays. That way we can check for example: if ("VkBuffer" in types && "VkDevice" in types) types["VkBuffer"].parent = types["VkDevice"]; I'm sure there should be a very elegant way to do this by recursing down through the sub-structs The simplest solution, IMO, is to insert all the types, commands, enums, etc. in associative arrays first and then do cross-referencing. E.g. Type[string] types; struct Type { // ... other members // Set to string first, and later change // to the proper Type, after the whole `types` table has been read. Algebraic(string, Type*) parent; // ... more members } Otherwise the only sane way to do forward reference resolution is to use D Fibers. I have used fibers in some of my projects, but the extra complications are not worth it for this task as the xml is only 5100 lines and the performance benefits probably would not be very large. Many thanks Nic BTW if you run into some other issues with std.xml, you can also check http://arsdnet.net/web.d/dom.html and https://github.com/burner/std.xml2 Also don't forget to use unittests extensively!
Re: Arrays of noncopyables/Invalid memory operation
On Thursday, 18 February 2016 at 01:19:16 UTC, Ali Çehreli wrote: On 02/17/2016 05:14 PM, ZombineDev wrote: > The "Invalid memory operation" error is thrown only by the GC (AFAIK) > when the user tries something unsupported like allocating or freeing in > a destructor, while a GC collection is being run. That. The problem is when the assert check fails (for value==60). The GC fails to create the exception object. Ali Hmm, why does the destructor of object 60 run in the middle of nowhere? I remember seeing it crash while my debugger was in _d_arraysetlengthT [1], though I don't know exactly where because I didn't have debug symbols for druntime. __doPostblit[2] checks if the type has disabled this(this) and if so it doesn't do anything. So the destructor should not have been run because of the array resize. Seems like there maybe some memory corruption or a bug in druntime. [1]: https://github.com/D-Programming-Language/druntime/blob/e47a00bff935c3f079bb567a6ec97663ba384487/src/rt/lifetime.d#L1265 [2]: https://github.com/D-Programming-Language/druntime/blob/e47a00bff935c3f079bb567a6ec97663ba384487/src/rt/lifetime.d#L566
Re: ndslice help
On Thursday, 18 February 2016 at 00:25:09 UTC, Zz wrote: Hi, I'm trying to generate the following sequences with ndslice. 0 0 0 1 1 1 1 1 1 0 0 0 0 1 2 0 1 2 2 1 0 2 1 0 It's okay with loops but was checking to see if it's possible with ndslice. Zz Here's my solution: http://dpaste.dzfl.pl/29676608fd88 The best part about ndslice is that you can use the ordinary slice operations with it like: http://dlang.org/spec/arrays.html#array-copying, http://dlang.org/spec/arrays.html#array-setting, http://dlang.org/spec/arrays.html#array-operations, etc. and also leverage the existing ranges, range transformations and algorithms from http://dlang.org/phobos/std_range and http://dlang.org/phobos/std_algorithm. In addition, I used nested array formatting with http://dlang.org/phobos/std_format.
Re: Arrays of noncopyables/Invalid memory operation
On Wednesday, 17 February 2016 at 22:20:00 UTC, Matt Elkins wrote: So in a different thread someone mentioned that when arrays are grown an implicit copy could be called on all the elements, as they might need to be copied over to a new, larger block of memory. This makes sense, and is expected. However, it got me concerned: what if the post-blit was disabled because it is illegal to copy the object? I am using a lot of objects exactly like this, and wanted to make sure my program wasn't working by coincidence since my dynamic arrays are still small for now. So I tested: [code] import std.stdio; @safe: bool scopeEnded; struct Foo { @disable this(this); this(int val) {writeln("Constructing: ", val, " (", , ")"); value = val;} ~this() {writeln("Destroying: ", value, " (", , ")"); assert(value == int.init || scopeEnded);} int value; } unittest { Foo[] foos; for (auto i = 0; i < 1; ++i) { ++foos.length; foos[$ - 1] = Foo(i); } writeln("Scope about to end"); scopeEnded = true; } [/code] [output] Constructing: 0 (18FDA8) Destroying: 0 (18FD6C) Constructing: 1 (18FDA8) Destroying: 0 (18FD6C) Constructing: 2 (18FDA8) Destroying: 0 (18FD6C) Constructing: 410 (18FDA8) Destroying: 0 (18FD6C) Constructing: 411 (18FDA8) Destroying: 0 (18FD6C) Constructing: 412 (18FDA8) Destroying: 0 (18FD6C) Constructing: 413 (18FDA8) Destroying: 0 (18FD6C) Constructing: 414 (18FDA8) Destroying: 0 (18FD6C) Constructing: 415 (18FDA8) Destroying: 0 (18FD6C) core.exception.InvalidMemoryOperationError@src\core\exception.d(679): Invalid memory operation Constructing: 416 (18FDA8) Destroying: 0 (18FD6C) Constructing: 417 (18FDA8) core.exception.InvalidMemoryOperationError@src\core\exception.d(679): Invalid memory operation Destroying: 0 (18FD6C) Constructing: 418 (18FDA8) Destroying: 0 (18FD6C) Constructing: 419 (18FDA8) Destroying: 0 (18FD6C) Constructing: 420 (18FDA8) Destroying: 0 (18FD6C) Constructing: 421 (18FDA8) Destroying: 0 (18FD6C) Constructing: 422 (18FDA8) Destroying: 0 (18FD6C) Constructing: 423 (18FDA8) Constructing: 506 (18FDA8) Destroying: 0 (18FD6C) Constructing: 507 (18FDA8) Destroying: 0 (18FD6C) Constructing: 508 (18FDA8) Destroying: 0 (18FD6C) Constructing: 509 (18FDA8) Destroying: 0 (18FD6C) Destroying: 29 (5201F4) Program exited with code 1 [/output] Note that the invalid memory operation lines change relative order in this output, I think maybe it is stderr instead of stdout. So now I'm wondering: * Is the fact that this compiles a bug? If copying can happen under the hood, shouldn't the @disable this(this) prevent Foo being used this way? Or should copying be happening at all (the compiler could instead choose to "move" the Foo by blitting it and NOT running the destructor...though I don't know whether that is a safe choice in the general case)? From looking at the addresses of the objects it seems like they're being constructed on the stack (as a temporary object), copied (blitted) to the array on the heap and then the temporary object has it's destructor being run. I think this is safe because you can't access the temporary (only the compiler can see it), so it's uniqueness is preserved. Unnecessarily running destructor is either an optimization opportunity or a manifestation of the bug that you reported here: https://issues.dlang.org/show_bug.cgi?id=15661. I suggest testing this code again with a newer compiler (see my answer in the other thread - http://forum.dlang.org/post/omfyqfulgyzbrxlzr...@forum.dlang.org). * What is the invalid memory operation? It doesn't occur if I remove the assert or make the assert never fail, so I'm guessing it has to do with failing an assert in the destructor? This points bothers me less than the previous one because I don't expect an assert-failing program to behave nicely anyway. The "Invalid memory operation" error is thrown only by the GC (AFAIK) when the user tries something unsupported like allocating or freeing in a destructor, while a GC collection is being run. I think that it's not possible to trigger it in @nogc code. From a short debug session, I managed to find out that it crashes on the `++foos.length` line, somewhere inside this function: https://github.com/D-Programming-Language/druntime/blob/e47a00bff935c3f079bb567a6ec97663ba384487/src/rt/lifetime.d#L1265. Unfortunately I currently don't have enough time to investigate further. Can you please file a bugzilla issue with this test case?
Re: Confusion regarding struct lifecycle
On Wednesday, 17 February 2016 at 16:36:35 UTC, Matt Elkins wrote: On Wednesday, 17 February 2016 at 07:10:15 UTC, ZombineDev wrote: The downside is that it really indicates that I didn't reduce my buggy program properly. I'll hold out for the live-object-destructor-call fix to see whether that corrects my problem; I can just leak resources until then :). So I've reduced it more properly now, and am 98% sure I've just got another manifestation of that same bug. BTW, you can try the nighly build which should include the bug fix: http://dlang.org/download.html I tried this, and got the same issue. Actually, I was still able to reproduce the original reported issue as well, which leads me to believe either the bug was not actually fixed or (and this is more likely) I screwed something up with my install. Do I need to do anything special to install a nightly build (I'm on Windows)? My "install" procedure was to move my dmd2 folder, verify that compilation now fails since there is no compiler installed, and then copy in the nightly build's dmd2 folder over the original path. Compilation then succeeds (but the bug still manifests). That was running through my IDE (IntelliJ with the D language plugin), and then in turn through DUB. To remove variables, I also tried running dmd directly on the test file: dmd.exe test.d -unittest -main. This compiled but also reproduced the bug. I guess the other possibility is that a patch was made and the issue marked resolved, but the patch hasn't been folded into the nightly build. I have no idea how dmd's patch/build/CI process works, so I don't know whether that is a real possibility. Sorry for the confusion. The bug was indeed fixed in the stable branch, however the stable branch is not yet merged into master, from which the nightly builds are packaged. You should be able to test it with a nightly build probably within 1 or 2 days after you get a "Commits pushed to master" notification on the bugzilla issue [1]. [1]: https://issues.dlang.org/show_bug.cgi?id=15661
Re: Confusion regarding struct lifecycle
On Wednesday, 17 February 2016 at 02:44:04 UTC, Matt Elkins wrote: On Wednesday, 17 February 2016 at 02:23:52 UTC, Ali Çehreli wrote: [...] Oof. This strikes me as a "gotcha", that this happens even with @disable this() as opposed to a compiler error. Is this only for static arrays, or are there other places @disable this() is silently ignored? [...] Ok, I think that pretty much explains the behavior I was seeing in the reduced case. Thanks -- that's helpful to know! The downside is that it really indicates that I didn't reduce my buggy program properly. I'll hold out for the live-object-destructor-call fix to see whether that corrects my problem; I can just leak resources until then :). BTW, you can try the nighly build which should include the bug fix: http://dlang.org/download.html
Re: static array of structs clarification questions
On Saturday, 13 February 2016 at 10:22:36 UTC, Marc Schütz wrote: On Friday, 12 February 2016 at 21:56:09 UTC, Steven Schveighoffer wrote: That's odd. I think anonymous probably has the answer (they are context pointers), but I'm also surprised they are null, they shouldn't be. In this example, `void foo()` doesn't access any outer variables, so there's no need for a context to be created. Yes, but the compiler will create a context regardless of this. See also this issue: https://issues.dlang.org/show_bug.cgi?id=15343
Re: Index file for ddoc
On Saturday, 13 February 2016 at 11:28:40 UTC, tcak wrote: Maybe I am missing, but I do not see any index file when html files are generated by ddoc. Is there any way to generate index file automatically, so, a tree like links will be listed all created documentation files? If the problem is about the possibility of having index.d and it would be confused with index.html, I can understand. I'm not sure if you can do this only using dmd. I recommend the ddox generator / server. Martin Nowak made a nice theme for it: https://github.com/MartinNowak/scod
Re: Things that keep D from evolving?
On Saturday, 6 February 2016 at 15:14:06 UTC, Kagamin wrote: On Saturday, 6 February 2016 at 08:07:42 UTC, NX wrote: What language semantics prevent precise Lack of resources. Precise GC needs to know which fields are pointers. Somebody must generate that map. AFAIK there was an experiment on that. That information has already been present for a couple of releases (http://dlang.org/spec/traits.html#getPointerBitmap), however currently the precise GC is slower than the conservative one, because of the overhead the the extra metadata has. For more info, you can read the comments on these two PRs: https://github.com/D-Programming-Language/druntime/pull/1022 https://github.com/D-Programming-Language/druntime/pull/1057
Re: foreach seems to work with opIndex()
On Saturday, 6 February 2016 at 15:02:16 UTC, H. S. Teoh wrote: On Sat, Feb 06, 2016 at 02:43:52PM +, Tofu Ninja via Digitalmars-d-learn wrote: Foreach seems to work if there is an opIndex() with no arguments that returns a range interface, is this documented? I can't seem to find anything that say this is supposed to happen. I am not really complaining, its nice, but I just didnt really expect it because I feel like I remember this being an error some time ago. Not really sure, but opIndex() with no arguments is supposed to be the current way of implement the [] slicing operator for user-defined types. I'm not sure when foreach started supporting that, but it's certainly a nice thing! T I thought that opSlice() was supposed to be that operator. At least this is what's used in std.container (e.g. http://dlang.org/phobos/std_container_array.html#.Array.opSlice).
Capturing a variable by value?
C++11 allows you to capture a local variable explicitly by value. What is the simplest way to make code below print "0 1 .. 9", like the C++ version does? D version: ``` import std.stdio; void main() { alias F = void delegate(); F[] arr; foreach (i; 0 .. 10) arr ~= { write(i, " "); }; foreach (f; arr) f(); } ``` Prints: 9 9 9 9 9 9 9 9 9 9 C++ version: ``` #include #include #include using namespace std; int main() { using F = function; vector arr; for (auto i = 0; i < 10; ++i) arr.push_back([=]() { cout << i << " "; }); for (auto f : arr) f(); } ``` Prints: 0 1 2 3 4 5 6 7 8 9 One stupid solution is to replace `0 .. 10` with staticIota!(0, 10), which would unroll the loop at CT, but I want something more general that would me allow me to capture the values of a range while iterating over it at run-time.
Re: Capturing a variable by value?
On Wednesday, 3 February 2016 at 18:03:24 UTC, ZombineDev wrote: C++11 allows you to capture a local variable explicitly by value. What is the simplest way to make code below print "0 1 .. 9", like the C++ version does? D version: ``` import std.stdio; void main() { alias F = void delegate(); F[] arr; foreach (i; 0 .. 10) arr ~= { write(i, " "); }; foreach (f; arr) f(); } ``` Prints: 9 9 9 9 9 9 9 9 9 9 C++ version: ``` #include #include #include using namespace std; int main() { using F = function; vector arr; for (auto i = 0; i < 10; ++i) arr.push_back([=]() { cout << i << " "; }); for (auto f : arr) f(); } ``` Prints: 0 1 2 3 4 5 6 7 8 9 One stupid solution is to replace `0 .. 10` with staticIota!(0, 10), which would unroll the loop at CT, but I want something more general that would me allow me to capture the values of a range while iterating over it at run-time. I think these two links, more or less, answer my question: http://stackoverflow.com/questions/29759419/closures-in-loops-capturing-by-reference https://issues.dlang.org/show_bug.cgi?id=2043
Re: d plugin for Intelij Idea debuging support
On Friday, 29 January 2016 at 12:00:25 UTC, Pavel wrote: Hello! Is there any debuging support for Intelij Idea's D plugin? Thanks! Currently only XamarinStudio/MonoDevelop and DlangIDE allow debugging on Linux through GDB. On Windows VisaulD provides debugging support for Visual Studio.
Re: Why is it a memory ERRO.
On Saturday, 30 January 2016 at 05:50:33 UTC, Dsby wrote: Ok.Thank you. and i want to know how to know when the GC start runing? See also http://dlang.org/phobos/core_memory
Re: traits getOverload of a template method
On Thursday, 6 February 2014 at 23:06:03 UTC, QAston wrote: How do i get aliases to overloads of a template method like Class A { int a(T)(T tq,T tw); int a(T)(T tq); } __traits(getOverloads, A, "a(int)")doesnt work Bump. I also have a similar problem. I have a module with two function templates that are overloaded (they have the same name, but different sets of parameters) and I need to select one of them so I can cast it to a function with the @nogc attribute, similar to this: http://p0nce.github.io/d-idioms/#Bypassing-@nogc. ``` // move has two overloads: `T move(T)(ref T)` and `void move(T)(ref T, ref T)` // and I need to select the second one here: cast(FT)(move!int)(arg1, arg2) ``` Otherwise I get "Error: template std.algorithm.mutation.move matches more than one template declaration".
Re: Dense multidimensional std.container.array?
On Tuesday, 26 January 2016 at 14:55:53 UTC, Wilson wrote: Just wondering how to create a dense multidimensional array with the GC free array container? I don't want to use an array of arrays but I do want the array[0][0] notation. I suggest using std.experimental.ndslice [1] for multidimensional arrays and std.experimental.allocator [2] for GC-free allocation. For an introduction to the design ideas behind [2], you can also check Andrei's talk at DConf [3]. Here's an example: import std.stdio : writeln; import std.experimental.allocator : makeArray, dispose; import std.experimental.allocator.mallocator : Mallocator; import std.experimental.ndslice : sliced; void main() { ulong[] arr = Mallocator.instance.makeArray!ulong(36); scope (exit) Mallocator.instance.dispose(arr); // All of the below matrices refer to the same array // that was allocated above. auto matrix4x9 = arr.sliced(4, 9); // 2D 4x9 matrix auto matrix6x6 = arr.sliced(6, 6); // 2D 6x6 matrix auto matrix2x3x6 = arr.sliced(2, 3, 6); // 3D 2x3x6 matrix // matrix.length!N - gets the number of elements in the Nth dimention foreach (rowIdx; 0 .. matrix6x6.length!0) foreach (columnIdx; 0 .. matrix6x6.length!1) matrix6x6[rowIdx, columnIdx] = (rowIdx + 1) * 10 + columnIdx + 1; writeln (matrix6x6); writeln (matrix4x9); writeln (matrix2x3x6); // The memory allocated by arr will be freed implicitly here. } Which prints: [[11, 12, 13, 14, 15, 16], [21, 22, 23, 24, 25, 26], [31, 32, 33, 34, 35, 36], [41, 42, 43, 44, 45, 46], [51, 52, 53, 54, 55, 56], [61, 62, 63, 64, 65, 66]] [[11, 12, 13, 14, 15, 16, 21, 22, 23], [24, 25, 26, 31, 32, 33, 34, 35, 36], [41, 42, 43, 44, 45, 46, 51, 52, 53], [54, 55, 56, 61, 62, 63, 64, 65, 66]] [[[11, 12, 13, 14, 15, 16], [21, 22, 23, 24, 25, 26], [31, 32, 33, 34, 35, 36]], [[41, 42, 43, 44, 45, 46], [51, 52, 53, 54, 55, 56], [61, 62, 63, 64, 65, 66]]] [1]: http://dlang.org/phobos-prerelease/std_experimental_ndslice [2]: http://dlang.org/phobos-prerelease/std_experimental_allocator [3]: http://dconf.org/2015/talks/alexandrescu.html
Re: free causes exception
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote: On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote: On 1/26/16 9:20 AM, Igor wrote: I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has ~this() // destructor for Foo { core.stdc.stdlib.free(); } auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)]; auto app = cast(App)emplace!App(buffer[]); I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues? So how am I suppose to free an object? Don't do it in the destructor. I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed). There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon. A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about. um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to. I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?! Why not simply: class Foo { this(Arg1, Arg2) { ... } ... } // Option A: import std.typecons : scoped; auto foo = scoped!Foo(arg1, arg2); // Option B: import std.experimental.allocator : make, dispose; import std.experimental.allocator.mallocator; auto foo = Mallocator.instance.make!Foo(arg1, arg2); scope(exit) Mallocator.instance.dispose(foo); http://dlang.org/phobos/std_typecons#.scoped http://dlang.org/phobos/std_experimental_allocator
Re: free causes exception
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote: On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote: On 1/26/16 9:20 AM, Igor wrote: [...] Don't do it in the destructor. I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed). There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon. A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about. um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to. I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?! Destructors are meant to destroy the members of the object, not the object itself. An object should be freed by the destructor of its owner and so on, transitively. A class should not have a hard coded dependency on malloc/free, or the GC. You should strive to design it in such a way that the clients of the class are free to decide how to manage its memory.
Re: nogc Array
On Tuesday, 26 January 2016 at 03:03:40 UTC, Igor wrote: Is there a GC-less array that we can use out of the box or do I have to create my own? If you want containers, use: http://code.dlang.org/packages/emsi_containers If you just need an array, use: http://dlang.org/phobos/std_experimental_allocator#.makeArray
Re: Get process
On Tuesday, 5 January 2016 at 18:10:28 UTC, Bauss wrote: Oh yeah I forgot to notice that by name would be preferred. Not title, but name. I have adapted the answer on Stackoverflow [1] for D: // These Windows headers require DMD >= v2.070 import core.sys.windows.winnt : PROCESS_QUERY_INFORMATION, PROCESS_VM_READ; import core.sys.windows.winbase : OpenProcess, GetCurrentProcess; import core.sys.windows.psapi : GetProcessImageFileNameW, GetModuleFileNameEx; import std.stdio : writeln; void main() { // 1) Get a handle to the process // 1.1) Example - get current process: auto processHandle = GetCurrentProcess(); // 1.2) Example - get process with id 8036: // auto processHandle = OpenProcess( // PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, // FALSE, // 8036 /* This is the PID, you can find one from windows task manager */ // ); // 2) Allocate a buffer for the name wchar[2048] name; // 3.1) Call GetProcessImageFileNameW uint bytesWritten = GetProcessImageFileNameW(processHandle, name.ptr, name.length); // 3.2) or call or GetModuleFileNameEx //uint bytesWritten = GetModuleFileNameEx(processHandle, null, name.ptr, name.length); assert (bytesWritten > 0, "Error: GetProcessImageFileName() wrote zero bytes!"); writeln(name); } Please note that this is Windows only and you need to use DMD 2.070 [2] or newer. I'm not on Windows so I can't test it now, but this should be the basic idea. [1]: http://stackoverflow.com/questions/4570174/how-to-get-the-process-name-in-c/4570225 [2]: http://forum.dlang.org/thread/n6bsnt$iuc$1...@digitalmars.com
Re: How to config the GDC on linux target for ARM linux?
On Monday, 28 December 2015 at 04:52:44 UTC, FrankLike wrote: Now I build a project for ARM linux on ubuntu 15.04 ,but build error. I download the 'wiringPi' from http://wiringPi.com,convert the *.h to *.d.then build the 'aa.so' file: #! /bin/sh dfiles="max31855.d max5322.d mcp23008.d mcp23016.d mcp23016reg.d mcp23017.d mcp23s08.d mcp23s17.d mcp23x08.d mcp23x0817.d mcp3002.d mcp3004.d mcp3422.d mcp4802.d pcf8574.d pcf8591.d sn3218.d softPwm.d softServo.d softTone.d sr595.d wiringPi.d wiringPiI2C.d wiringPiSPI.d wiringSerial.d wiringShift.d wpiExtensions.d" ofiles="drcSerial.o max31855.o max5322.o mcp23008.o mcp23016.o mcp23017.o mcp23s08.o mcp23s17.o mcp3002.o mcp3004.o mcp3422.o mcp4802.o pcf8574.o pcf8591.o piHiPri.o piThead.o sn3218.o softPwm.o softServo.o softTone.o sr595.o wiringPi.o wiringPiI2C.o wiringPiSPI.o wiringSerial.o wiringShift.o wpiExtensions.o" /opt/arm-unknown-linux-gnueabihf/bin/arm-linux-gnueabihf-gdc -o aa.so $ofiels $dfiles -shared ---my.d import wiringPi; import std.stdio; void main() { writeln("start"); wiringPiSetup(); pinMode(0,OUTPUT); while(1) { digitalWrite(0,HIGH); delay(500); digitalWrite(0,LOW); delay(500); } return; } -build the my execute file /opt/arm-unknown-linux-gnueabihf/bin/arm-linux-gnueabihf-gdc -o my my.d aa.so -I./wiringPi/WiringPi/ -now get the error: my.d:1:8: error: module wiringPi is in file 'wiringPi.d' which cannot be read import wiringPi; ^ import path[0] = /opt/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/5.2.0/include/d -I copy the *.d to /opt/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/5.2.0/include/d it's ok ,but where is the file for config? -get another error: /tmp/cc7M1B9I.o: In function `_Dmain': my.d:(.text+0x60): undefined reference to `wiringPiSetup' my.d:(.text+0x6c): undefined reference to `pinMode' my.d:(.text+0x84): undefined reference to `digitalWrite' my.d:(.text+0x8c): undefined reference to `delay' my.d:(.text+0x98): undefined reference to `digitalWrite' my.d:(.text+0xa0): undefined reference to `delay' collect2: error: ld returned 1 exit status -end I'm not known the GDC config file ,and maybe I use the error build . Who can help me? thank you. About the first error ("...module wiringPi is in file 'wiringPi.d' which cannot be read...") - are you sure that the dfiles are in "./wiringPi/WiringPi/"? The compiler reports that it can't find them there. You can try copying the WiringPi dfiles in the same folder as "my.d". About the second error - you need to verify that aa.so actually has those symbols that the linker reports as "undefined reference". You can do this with readlelf or nm. For more info see here:http://stackoverflow.com/questions/1237575/how-do-i-find-out-what-all-symbols-are-exported-from-a-shared-object
Re: Multiple selective imports on one line
On Wednesday, 23 December 2015 at 19:27:31 UTC, earthfront wrote: On Wednesday, 23 December 2015 at 11:12:22 UTC, ZombineDev wrote: Actually array() is from sts.array and correct way to use selective imports is: import std.exception : enforce; import std.array : array; import std.algorithm.iteration : filter; import std.functional : memoize; If you want to import several symbols from one module, you can list them after the column like so: import std.algorithm : any, find, sort /*, etc... */; I hadn't compiled yet, so the array thing is indeed an error. So there's no way to combine these _selective_ imports on a single line, like I can with regular _module_ imports: import std.exception, std.array, std.functional; Correct? Yes, it is not allowed by the grammar. I think the reason is that the list items would become ambiguous (the difference between selected symbols and module names could only be revealed after semantic analysis). See for example: import abc : cba, dcb, bca : acb, dbc; // What is dbc? A module or a member of bca?
Re: Multiple selective imports on one line
On Wednesday, 23 December 2015 at 10:51:52 UTC, earthfront wrote: I'm using hackerpilot's excellent textadept plugin + DCD, Dfmt, and Dscanner. Upon saving files, it produces suggestions, much like warnings from the compiler. One suggestion is to use selective imports in local scopes. OK, I'll do that. Now I'm left with a smattering of lines which are just selective imports from a single module: void foo() { import std.exception:enforce; import std.algorithm:array; import std.algorithm.iteration:filter; import std.functional:memoize; //..Work.. } What is the proper way to combine these into one line? Actually array() is from sts.array and correct way to use selective imports is: import std.exception : enforce; import std.array : array; import std.algorithm.iteration : filter; import std.functional : memoize; If you want to import several symbols from one module, you can list them after the column like so: import std.algorithm : any, find, sort /*, etc... */;
Re: How is D doing?
On Tuesday, 22 December 2015 at 17:49:34 UTC, Jakob Jenkov wrote: On Tuesday, 22 December 2015 at 03:30:32 UTC, ShinraTensei wrote: I recently noticed massive increase in new languages for a person to jump into(Nim, Rust, Go...etc) but my question is weather the D is actually used anywhere or are there chances of it dying anytime soon. Check out Google Trends. Searches for D Tutorial still beats searches for Scala Tutorial by a big margin: https://google.com/trends/explore#q=d%20tutorial%2C%20scala%20tutorial Google Trends shows something interesting: https://google.com/trends/explore#q=%2Fm%2F01kbt7%2C%20%2Fm%2F0dsbpg6%2C%20%2Fm%2F091hdj%2C%20%2Fm%2F03j_q%2C%20C%2B%2B=q=Etc%2FGMT-2
Re: alias butAtLeast = max; 5.butAtLeast(6);
On Saturday, 12 December 2015 at 12:43:36 UTC, SimonN wrote: DMD v2.069.2-b1 on Linux. import std.algorithm; int a = max(5, 6);// works, a == 6 int b = max!(int, int)(5, 6); // works, manual instantiation int c = 5.max(6); // works, UFCS call I would like to use the last syntax, but with an alias. alias butAtLeast = max; // works int d = butAtLeast(5, 6); // works int e = 5.butAtLeast(6); // error: no property 'butAtLeast' for type 'int' Aliasing the instantiated function 'max!(int, int)' instead of aliasing 'max' doesn't help: The 'int e' line will fail with the exact same error. Can I get the alias to work somehow in an UFCS chain? -- Simon This is due to limitation of function-local aliases. If you put the alias outside it will work: http://dpaste.dzfl.pl/4fb06cbbfad2. Perhaps a simpler way achieve this is to use renamed imports: http://dpaste.dzfl.pl/08774a538fe9 The Identity template can also helpful in some situations: http://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
Re: How to add third party libraries to the project. (Xamarin)
On Friday, 4 December 2015 at 18:15:47 UTC, Neomex wrote: How do I add third party libraries to the project? I am using Xamarin. I have built Derelict-SDL2 with dub and got the lib file but I don't know what to do with it. In xamarins references folder theres only option to refresh not to add anything. The MonoD plugin for Xamarin/Monodevelop supports DUB, so you don't need to manually add references and/or build the dependencies yourself. Here's how you can create a new DUB project the depends on Derelict-SDL2 inside a folder named myproj: mkdir myproj dub init ./myproj derelict-sdl2 -fjson The last command will create the following directory structure: myproj/.gitignore <- useful, if you use git version control myproj/source <- here you should put your source code myproj/source/app.d myproj/dub.json <- this file describes your project and its dependencies The myproj/dub.json file contains: { "name": "myproj", "description": "A minimal D application.", "copyright": "Copyright © 2015, ubuntu", "authors": ["ubuntu"], "dependencies": { "derelict-sdl2": "1.9.7" } } To build this sample application with DUB you need to run only the following command: dub To open the created project under XamrinStudio / Monodevelop 1) Open XamrinStudio / Monodevelop 2) Make sure you have MonoD installed. You can do it from Tools -> Add-in Manager -> Gallery -> Language Bindings -> D Language Binding. 3) File -> Open -> navigate into the myproj folder and select the dub.json file. That's it. Xamarin Studio / Monodevelop will now open the DUB project in the Solution Pad. You can even browse through the source code of the dependencies, by clicking on the External Dependencies folder in the Solution Pad, which should be populated after the first time you build you project through Xamarin Studio / MonoDevelop. Here you can find more information about MonoD: http://wiki.dlang.org/Mono-D https://github.com/aBothe/Mono-D Mike Parker who is the main developer behind Derelict has a nice blog here: http://dblog.aldacron.net/ Good luck!
Re: How to add third party libraries to the project. (Xamarin)
On Friday, 4 December 2015 at 19:15:57 UTC, ZombineDev wrote: The myproj/dub.json file contains: { "name": "myproj", "description": "A minimal D application.", "copyright": "Copyright © 2015, ubuntu", "authors": ["ubuntu"], "dependencies": { "derelict-sdl2": "1.9.7" } } Instead of ubuntu, it will probable display the username of your machine. To build this sample application with DUB you need to run only the following command: dub Assuming that you're inside the folder myproj. Otherwise you'll need to run: dub --root=./myproj
Re: Thread in detached state?
On Friday, 13 November 2015 at 15:35:11 UTC, Ish wrote: I was directed here from General list, so be patient with me. I am looking for syntax for creating a detached-state thread in the spirit of POSIX thread attribute PTHREAD_CREATE_DETACHED (the thread resources are released on termination and not when the main thread terminates - allows for a very large number of threads). Sample code with call will be helpful. If you're more familiar with pthreads, you can just use them from core.sys.posix.pthread [1]. After all this what core.thread uses on Posix [2]. In general you can use any OS functionality by importing the declarations you need from core.sys.[OS].[header] [3]. However you need to make sure to register your thread if you are going to use features of D that need runtime support (such as the GC). I don't know if there's a good D tutorial specifically for pthreads, but you should be able to easily translate a C tutorial to D. (Because the D API is a one-to-one mapping of the C one). For example, these two sites provide plenty of information on using pthreads: [4], [5]. Probably because these are targeted at C programmers, they wouldn't teach you the best way to use this functionality from D, but as you learn more about the D's features, you will be able to gradually develop better techniques for using them. On the other hand, if you don't need to interact directly with Posix threads, it is recommended to use std.parallelism [6] or std.concurrency [7] for a more structured approach to parallelism and concurrency or a framework like vibe.d [8], which provides a well integrated approach to building scalable networking/web applications. [1]: https://github.com/D-Programming-Language/druntime/blob/master/src/core/sys/posix/pthread.d [2]: https://github.com/D-Programming-Language/druntime/blob/master/src/core/thread.d#L231 [3]: https://github.com/D-Programming-Language/druntime/tree/master/src/core/sys [4]: https://computing.llnl.gov/tutorials/pthreads/ [5]: https://www.cs.cf.ac.uk/Dave/C/ [6]: http://dlang.org/phobos/std_parallelism [7]: http://dlang.org/phobos/std_concurrency [8]: http://vibed.org/
Re: dataframe implementations
On Thursday, 19 November 2015 at 06:33:06 UTC, Jay Norwood wrote: On Wednesday, 18 November 2015 at 22:46:01 UTC, jmh530 wrote: My sense is that any data frame implementation should try to build on the work that's being done with n-dimensional slices. I've been watching that development, but I don't have a feel for where it could be applied in this case, since it appears to be focused on multi-dimensional slices of the same data type, slicing up a single range. The dataframes often consist of different data types by column. How did you see the nd slices being used? Maybe the nd slices could be applied if you considered each row to be the same structure, and slice by rows rather than operating on columns. Pandas supports a multi-dimension panel. Maybe this would be the application for nd slices by row. How about using a nd slice of Variant(s), or a more specialized type Algebraic type? [1]: http://dlang.org/phobos/std_variant
Re: Parse d source file by using compiler
On Monday, 9 November 2015 at 05:49:25 UTC, tcak wrote: I checked for a flag in this page http://dlang.org/dmd-linux.html , but couldn't have found any for this purpose. Is there a way to parse a d source file so it generates a tree in JSON, XML, or something-that-can-be-processed-easily file format? --- My real purpose: I need to generate hash code (e.g. MD5) for a part of source code (let's say a class, struct, or a function). So whether the codes are changed or not can be detected. As you will guess, comments, text formatting etc. shouldn't affect the hash result. Use-Case: I am writing a code generator/back up system. It will check the last available code file. If important changes are done in a specific part of code, it will increase version number by 1. You're use case is really interesting! AFAIK, currently, the lexer part of the DMD frontend is the only part that can be easily used standalone. Daniel Murphy (who drove a lot of the work towards DDMD) published the lexer on DUB: http://code.dlang.org/packages/ddmd. However the package is outdated, because it is based on DMD v2.067. As the whole frontend is now in D, you should be able to import any of the D modules and work with them, but it may not be as easy, as their API is geared only towards the DMD driver. I personally want to help refactor DDMD to be usable as a library, so you can use for all sorts of cool things (like runtime JIT, IDE support, REPL, and so on), but I'm quite busy at the moment :(
Re: ORM libraries for D
On Thursday, 24 September 2015 at 13:18:58 UTC, David Nadlinger wrote: Hi all, I'm having a look at ORM libraries in D right now. So far, I've come across hibernated and dvorm. Are there any other libraries that I should have a look at, particularly actively maintained ones? dvorm and hibernated seem to have received no work during the last couple of months. — David You can checkout dotter [1]. Also in this thread [2] Sebastiaan mentioned that he used at his work a custom built ORM solution. You can probably ask him for more details. [1]: https://github.com/rejectedsoftware/dotter [2]: http://forum.dlang.org/post/eixkzndqlqxxyjejb...@forum.dlang.org
Re: RAII and Deterministic Destruction
On Tuesday, 25 August 2015 at 22:35:57 UTC, Jim Hewes wrote: Although C++ can be ugly, one reason I keep going back to it rather then commit more time to reference-based languages like C# is because I like deterministic destruction so much. My question is whether D can REALLY handle this or not. I've not been sure about this for some time so now I'm just going to come out and finally ask. I know about this RAII section in the documentation: http://dlang.org/cpptod.html#raii But I don't believe that handles all cases, such as having classes as member variables of other classes. (Do the members get destructors called too?) Then there is std.typecons.Unique and std.typecons.RefCounted. With these, can I really get deterministic destruction for all cases like I would in C++? If so, it might be a good idea to emphasize this more in the documentation because I'd think people coming from C++ would be looking for this. Jim Structs in D behave like in C++ - they are created on the stack (unless you use new or malloc), passed by value and are automatically destroyed at the end of the scope. All their members are destroyed recursively after the user defined destructor is called. Just try it out in a toy program and see if it works as you expect.
Re: RAII and Deterministic Destruction
On Wednesday, 26 August 2015 at 01:09:15 UTC, ZombineDev wrote: On Tuesday, 25 August 2015 at 22:35:57 UTC, Jim Hewes wrote: Although C++ can be ugly, one reason I keep going back to it rather then commit more time to reference-based languages like C# is because I like deterministic destruction so much. My question is whether D can REALLY handle this or not. I've not been sure about this for some time so now I'm just going to come out and finally ask. I know about this RAII section in the documentation: http://dlang.org/cpptod.html#raii But I don't believe that handles all cases, such as having classes as member variables of other classes. (Do the members get destructors called too?) Then there is std.typecons.Unique and std.typecons.RefCounted. With these, can I really get deterministic destruction for all cases like I would in C++? If so, it might be a good idea to emphasize this more in the documentation because I'd think people coming from C++ would be looking for this. Jim Structs in D behave like in C++ - they are created on the stack (unless you use new or malloc), passed by value and are automatically destroyed at the end of the scope. All their members are destroyed recursively after the user defined destructor is called. Just try it out in a toy program and see if it works as you expect. Classes on the other hand are reference types and are created on the garbage-collected heap by default (though you can do your own memory management). Similarly, structs created by new are also allocated on the GC heap. During collections the GC will call destructors, but it is not guaranteed and you should not rely on it. For example (depending on your GC usage and configuration) only a single collection may occur at the end of the program.
Re: RAII and Deterministic Destruction
On Wednesday, 26 August 2015 at 01:18:43 UTC, ZombineDev wrote: On Wednesday, 26 August 2015 at 01:09:15 UTC, ZombineDev wrote: On Tuesday, 25 August 2015 at 22:35:57 UTC, Jim Hewes wrote: Although C++ can be ugly, one reason I keep going back to it rather then commit more time to reference-based languages like C# is because I like deterministic destruction so much. My question is whether D can REALLY handle this or not. I've not been sure about this for some time so now I'm just going to come out and finally ask. I know about this RAII section in the documentation: http://dlang.org/cpptod.html#raii But I don't believe that handles all cases, such as having classes as member variables of other classes. (Do the members get destructors called too?) Then there is std.typecons.Unique and std.typecons.RefCounted. With these, can I really get deterministic destruction for all cases like I would in C++? If so, it might be a good idea to emphasize this more in the documentation because I'd think people coming from C++ would be looking for this. Jim Structs in D behave like in C++ - they are created on the stack (unless you use new or malloc), passed by value and are automatically destroyed at the end of the scope. All their members are destroyed recursively after the user defined destructor is called. Just try it out in a toy program and see if it works as you expect. Classes on the other hand are reference types and are created on the garbage-collected heap by default (though you can do your own memory management). Similarly, structs created by new are also allocated on the GC heap. During collections the GC will call destructors, but it is not guaranteed and you should not rely on it. For example (depending on your GC usage and configuration) only a single collection may occur at the end of the program. Generally a very tutorial and reference is Ali's book [1], which is listed under Books and Articles in the sidebar of dlang.org. You should check the chapters Constructor and Other Special Functions [2] and Memory Management [3] (even though it covers mostly the GC). If you wish to avoid the GC, you can annotate your functions with the @nogc attribute [4] which enforces at compile-time that the annotated function won't use the GC. It is transitive which means that if you annotate your main() function with it, you shouldn't be allowed to use anything that allocates memory from the GC in your whole program. Since this feature was added there is an ongoing effort to minimize GC usage in the standard library, but there's still stuff that require it. That said the recommended approach is to build your data processing on ranges [5] (see the linked article by Andrei Alexandrescu) because it allows you to encapsulate memory usage more strategically. This is enabled by the lazy nature of ranges - they process data only when needed and so they don't need to allocate memory. Probably the best introduction to this technique is Walter Bright's keynote at DConf 2015 [6]: https://www.youtube.com/watch?v=znjesAXEEqw Be sure to check the DConf website as there's lots of great content from 2013 [7], 2014 [8] and 2015 [9]. [1]: http://ddili.org/ders/d.en/index.html [2]: http://ddili.org/ders/d.en/special_functions.html [3]: http://ddili.org/ders/d.en/memory.html [4]: http://dlang.org/attribute.html#nogc [5]: http://dlang.org/phobos/std_range.html [6]: https://www.youtube.com/watch?v=znjesAXEEqw [7]: http://dconf.org/2013/ [8]: http://dconf.org/2014/ [9]: http://dconf.org/2015/
Re: How to use ranges?
On Sunday, 23 August 2015 at 17:58:44 UTC, Doolan wrote: ... Ali's book has a very nice chapter about ranges: http://ddili.org/ders/d.en/ranges.html
Re: exclude current directory from search path in dmd ?
On Monday, 20 July 2015 at 03:33:08 UTC, Timothee Cour wrote: I've attached a reduced use case showing that the solutions proposed in this thread do not work, and wrote a local modification to dmd to allow a flag -exclude_cwd_from_imports that does work. Would that be acceptable to have this in official dmd? The best way to find out is to make a Pull Request. If it's hard to workaround than it's a good candidate for enhancement.
Re: Working functionally with third party libraries
On Friday, 17 July 2015 at 09:07:29 UTC, Jarl André Hübenthal wrote: Thanks. Its a lot more cleaner and syntactically readable having .array at the end. But about laziness the same applies to clojure and scala. In clojure you must force evaluate the list, in scala you must to mostly the same as in D, put a toList or something at the end. Or loop it. But its pretty nice to know that there is laziness in D, but when I query mongo I expect all docs to be retrieved, since there are no paging in the underlying queries? Thus, having a lazy functionality on top of non lazy db queries seem a bit off dont you think? I'm almost certain that the D database driver returns eagerly all the results that you've requested. The lazy stuff should happen when you start doing range operations after the results are returned from the database. It's not impossible to lazily query the database, but I think that the developers have chosen the eager approach, since it's more straightforward. Currently, in D most of the laziness is a convention, rather than something directly built into the language. There are many features that enable (indirectly) effective and easy to use lazy algorithms, but these features are have many other uses (templates, auto type deduction, compile-time reflection, etc.). The only two direct features are: 1) foreach can iterate over ranges (objects of structs or classes for which isInputRange is true. Here's an example: import std.algorithm.iteration : map, filter; foreach (name; persons.filter!(p = p.age 18).map!(p = p.name)) writeln(name); import std.range.primitives : isInputRange; static assert ( isInputRange!( typeof( persons.filter!(p = p.age 18).map!(p = p.name) ) ) == true ); See http://dlang.org/phobos/std_range_primitives.html#isInputRange 2) The lazy keyword - when you annotate function parameters with lazy they are evaluated not at the caller site, but only when needed like in other more traditional functional languages. For example: void calculate(int[] numbers) { import std.format : format; // ... logErrorIf(numbers[3] 5, format(Expected value 5, but got %s !, numbers[3])); // ^~~~ this is only evaluated // ... } void logErrorIf(bool condition, lazy string error_message) { if (condition) writeln(message); // ^~~~ here, if the condition is true } ( In D string is just an alias to immutable(char)[], so the above signature is identical to this: void logErrorIf(bool condition, lazy immutable(char)[] error_message) ) You can think of lazy parameters as implicit lambdas that return the expression passed as argument only when called. Here you can learn more about the lazy keyword http://dlang.org/lazy-evaluation.html Even though we have 'lazy' built into the language, most of the lazy algorithms do not use it. I just made a quick search through druntime and phobos for 'lazy' and 'range' (don't how correct it was - I admit I'm a unix noob) and here's what I got: // (I have DMD v2.067.1 installed) // lazy at the head of the function parameter list or in the tail $ find /usr/include/dmd/ -name '*.d' -exec cat {} \; | grep -c '(lazy \|, lazy ' 74 // just containing lazy $ find /usr/include/dmd/ -name '*.d' -exec cat {} \; | grep -c 'lazy' 138 // just containing range $ find /usr/include/dmd/ -name '*.d' -exec cat {} \; | grep -c 'range' 3548 I think that this because ranges are a more generic, flexible and powerful abstraction, and are more efficient maybe because they're easier to optimize to simple loops (eg. I've seen that the ldc compiler handles them very well). 'lazy' is still useful but generally I have seen it used for more simpler stuff (like the above 'lazy' example), and not for propagating state through range pipelines (or more simply - function chaining). So you'll see both functions that are lazy and functions that are not throughout Phobos (and most use ranges, as you can see from the results). Generally you can distinguish range functions from others by their signatures. Since most ranges in D are templated structs and not classes inheriting some interface (though there some, see http://dlang.org/phobos/std_range_interfaces#InputRange), functions that operate on ranges are templated at least on one range type: // Check if the function 'fun' is really a predicate enum isUnaryPredicate(alias fun, T) = is( typeof( fun(T.init) ) : bool); import std.range.primitives: isInputRange, ElementType; // templated on predicate and range type //v ~~v~~ auto filter1(alias predicate, Range)(Range range) if (isInputRange!Range// - some template isUnaryPredicate!(predicate, ElementType!Range)) // ^~ constraints { return ... } // Even if you can't look at the function body, you // can guess that it can't be lazy because, it must
Re: Working functionally with third party libraries
On Friday, 17 July 2015 at 15:41:22 UTC, ZombineDev wrote: I'm almost certain that the D database driver returns eagerly all the results that you've requested. The lazy stuff should happen when you start doing range operations after the results are returned from the database. It's not impossible to lazily query the database, but I think that the developers have chosen the eager approach, since it's more straightforward. Discard this. I didn't read the previous comments.
Re: Virtual value types during compile-time for static type safety, static optimizations and function overloading.
On Friday, 17 July 2015 at 21:20:41 UTC, Tamas wrote: Is there a solution that results the same static optimizations, but has no runtime penalty, i.e. the functions just operates with ints? (At least when compiled) Did you try looking at assembly generated by GDC or LDC with full optimizations? For example GDC does quite better than DMD for the proposed SafeInt type: https://github.com/D-Programming-Language/phobos/pull/3389#issuecomment-119005595
Re: Virtual value types during compile-time for static type safety, static optimizations and function overloading.
On Friday, 17 July 2015 at 23:15:31 UTC, ZombineDev wrote: On Friday, 17 July 2015 at 21:20:41 UTC, Tamas wrote: Is there a solution that results the same static optimizations, but has no runtime penalty, i.e. the functions just operates with ints? (At least when compiled) Did you try looking at assembly generated by GDC or LDC with full optimizations? For example GDC does quite better than DMD for the proposed SafeInt type: https://github.com/D-Programming-Language/phobos/pull/3389#issuecomment-119005595 Also, see the table at the bottom of this comment: https://github.com/D-Programming-Language/phobos/pull/3389#issuecomment-117450524
Re: Using executeShell in multiple thread causes access violation error
On Monday, 13 July 2015 at 09:46:26 UTC, Minas Mina wrote: I have written a script that visits all directories in the current directory and executes a command. In my case, git pull. When running the script serially, everything is fine. All git repositories are pulled. But I'd like to pull multiple repositories in parallel to speed things up. So I've changed my loop from foreach(entry; dirs) to foreach(entry; parallel(dirs)) After a while that the program is running I get: std.exception.ErrnoException@std\stdio.d(638): Could not close file `HANDLE(C0)' (No error) 0x00411E5C 0x0040B8AB 0x0040A146 0x00402288 0x00403A99 0x00413B95 0x004095FC 0x00439AA0 0x770992B2 in RtlInitializeExceptionChain 0x77099285 in RtlInitializeExceptionChain object.Error@(0): Access Violation 0x00439429 0x0043A277 0x00411ECD 0x763A9B2C in GetFileAttributesW Here is the code: http://pastebin.com/Tk0TBGxs Probably this is a Windows only problem. I tried the following code on my Linux machine and I didn't get any exception like yours: https://gist.github.com/ZombineDev/e1e48a18a22d4fc85e8d Can you run my code just so we can confirm that the problem is in the Windows implementation and not in your code? Also what compiler version are you using? If you don't get exception while using your code, it would be better if you could show me a complete code snippet so the issue can be reproduced.
Re: Working functionally with third party libraries
On Friday, 17 July 2015 at 17:56:51 UTC, sigod wrote: On Friday, 17 July 2015 at 15:41:22 UTC, ZombineDev wrote: eager approach, since it's more straightforward. What makes you think it's always more straightforward? Sometimes (like in this case with MongoDB) you cannot write eager approach without first writing lazy one. Well I just wrote without properly looking up what MongoDB does. I thought collection.find() returned the first n elements, not a iterator (cursor in MongoDB's terms) and that it would be additional work split those n elements. Anyway, thanks for the correction, now I am bit more educated ;)
Re: Working functionally with third party libraries
On Thursday, 16 July 2015 at 20:17:54 UTC, Jarl André Hübenthal wrote: On Thursday, 16 July 2015 at 20:00:38 UTC, Ali Çehreli wrote: On 07/16/2015 12:35 PM, Jarl =?UTF-8?B?QW5kcsOpIEjDvGJlbnRoYWwi?= jarl.an...@gmail.com wrote: Hi using mongo with vibe.d is easy. But I would like to skip the foreach on MongoCursor? I mean, I want to use map!, filter! and reduce! on the resulting docs. Is there a fast way to convert MongoCursor to an array without resolving to ugly for loops with appender! ? I've never used MongoCursor but judging from the fact that it has empty, front, and popFront(), it is an InputRange: http://vibed.org/api/vibe.db.mongo.cursor/MongoCursor Have you tried using it with map and others? What errors do you get? Ali Ah well I got another error now. Using the following code: Resource[] getResource() { auto coll = client.getCollection(app.resource); return coll.find().map!(doc = deserialize!(BsonSerializer, Resource)(doc)); } I get this error: src/app.d(51,21): Error: cannot implicitly convert expression (map(coll.find())) of type MapResult!(__lambda1, MongoCursor!(Bson, Bson, typeof(null))) to Resource[] Most of the functions from std.algorithm and std.range return a lazy range which you need to iterate over go get its elements. To turn those ranges to an array you need add a .array at the end (http://dlang.org/phobos/std_array#array). Here's a larger example: http://d.readthedocs.org/en/latest/introduction.html. Another option is to return the elements as a range (by making return type of your function auto), instead of putting them into a newly allocated array (with .array). This way may be a bit more work (delaying the call to .array), but it can be quite efficient because it removes the need to allocate memory.
Re: Return types of the methods of a struct
On Friday, 19 June 2015 at 14:13:46 UTC, Quentin Ladeveze wrote: [..] These are interesting and can be useful, but allMembers returns strings and not functions, so I can't apply ReturnType. Here's my solution: http://dpaste.dzfl.pl/c69de3c16d75
Re: What is the exact meaning of 'nothrow'?
On Thursday, 11 June 2015 at 00:32:45 UTC, ZombineDev wrote: Environment exceptions are stuff like user input and network and file access. This are problems that you generally want to ... These* are ... handle and that's why they're considered recoverable. So 'Exception's propagate through function calls and 'Error's terminate the program immediately. A function 'f' marked as nothrow indicates that no exceptions shall escape from it (if a function that 'f' calls can throw, 'f' must written, so that it catches the exception), but since ... catches *all possible exceptions*), ... 'Error's terminate the program immediately the callers of 'f' should not care about them and that's why 'Error's don't brake ... don't break* ...
Re: What is the exact meaning of 'nothrow'?
On Thursday, 11 June 2015 at 00:06:24 UTC, Yuxuan Shui wrote: I want to know exactly what is considered to be 'throw'. I'm able to use dynamic arrays (which can throw 'Range violation') and asserts in a nothrow function. Shouldn't those be considered 'throw'? In D there are two types of exceptions: logic errors (derived from 'Error') and environment exceptions (derived from 'Exception'). Logic errors are considered to be irrecoverable (eg. your program should be terminated because people generally don't write code to handle them - no one wraps their array accesses in try {...} catch {...}) Environment exceptions are stuff like user input and network and file access. This are problems that you generally want to handle and that's why they're considered recoverable. So 'Exception's propagate through function calls and 'Error's terminate the program immediately. A function 'f' marked as nothrow indicates that no exceptions shall escape from it (if a function that 'f' calls can throw, 'f' must written, so that it catches the exception), but since 'Error's terminate the program immediately the callers of 'f' should not care about them and that's why 'Error's don't brake the 'nothrow' promise of 'f'.
Re: What is D's minimum requirements on Mac?
On Wednesday, 10 June 2015 at 20:18:06 UTC, Laeeth Isharc wrote: On Wednesday, 10 June 2015 at 18:55:27 UTC, Adam D. Ruppe wrote: I'm still tempted to grab a used Mac so I can port my display stuff to Cocoa and test it, but Macs are outrageously expensive and I hate them, so want to spend as little as possible. What does dmd minimally require on a mac? If I got like a 10.5 would that work? i'm considering something like http://www.amazon.com/Apple-MB138LL-Intel-Drive-Combo/dp/B0006HU49Y/ref=sr_1_5?ie=UTF8qid=1433962021sr=8-5keywords=used+mac+mini I don't know what the robustness and intellectual property aspects are these days. But would a hackintosh do the trick ? http://lifehacker.com/5938332/how-to-run-mac-os-x-on-any-windows-pc-using-virtualbox A couple of weeks ago I tried this (but I used VMware player, instead of virtualbox) and it seemed to work well on OSX 10.10
Re: Windows Universal/Store apps support
On Thursday, 28 May 2015 at 15:57:42 UTC, Olivier Prince wrote: [snip] There isn't yet a polished alternative to MS VS Windows Store toolchain, but probably you don't need most of it (e.g. you can have a C++/XAML app that calls you D code). I noticed that Vibe.d has some WinRT support. Here's their WinRT driver, which uses calls some parts of WinRT API: https://github.com/rejectedsoftware/vibe.d/blob/master/source/vibe/core/drivers/winrt.d
Re: Idiomatic way to call base method in generic code
On Monday, 25 May 2015 at 07:57:49 UTC, ketmar wrote: i don't know why you want that, but something like this may do: auto callBaseMethod(string MTN, C, Args...) (inout C self, Args args) { alias FSC = BaseClassesTuple!(C)[0]; return mixin(`self.`~FSC.stringof~`.`~MTN~(args)); } writeln(d.callBaseMethod!toString); Thanks! [1]: https://github.com/ZombineDev/Chess2RT/blob/c36ba3e73744cf3912c25abccedbbd742f7f5be3/source/util/prettyprint.d#L7 [2]: https://github.com/ZombineDev/Chess2RT/blob/master/source/util/prettyprint.d#L14 I initially had [1] a string mixin which goes through all the members of a class and prints them and also prints its base class' members, but then it seemed that it would be more cleaner if I could use a function template [2] (which also improved my debug experience) so I started exploring alias, but they turned out to be less powerful then I thought: alias can't refer to a nested member: - struct Point2 { float x; float y; } struct Line2 { Point2 start; Point2 end; mixin Access; // alias x1 = this.start.x; - this doesn't work :( alias x1 = get!start.x; alias y1 = get!start.y; alias x2 = get!end.x; alias y2 = get!end.y; } // I need to use a mixin to flatten the access :( private mixin template Access() { ref auto get(string accessPattern)() inout { return mixin(accessPattern); } } - So I wondered if I'm missing something and decided to ask here. no. and again, why do you want that? why do you people are so afraid of string mixins? ;-) Well I'm not afraid of string mixins, but the `alias` keyword seemed to possess some mysterious power (I was also under the influence of this [3] blog post) which I wanted to explore. Also they're a bit more elegant. [3]: http://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
Re: is expression with static if matches wrong type
On Saturday, 23 May 2015 at 04:40:28 UTC, tcak wrote: [snip] Yup, you need to use == to match the exact type. Btw, you can use enum templates from std.traits, to accomplish the same with less code: public void setMarker(M)( size_t markerIndex, M markerValue ) if(isScalarType!M) { //... } http://dlang.org/phobos/std_traits.html#isScalarType
Re: is expression with static if matches wrong type
On Sunday, 24 May 2015 at 14:46:52 UTC, ZombineDev wrote: [snip] Correction: not exactly the same, because isScalar also allows wchar, dchar and const and immutable versions of those 'scalar' types.
Re: Idiomatic way to call base method in generic code
On Sunday, 24 May 2015 at 23:32:52 UTC, ZombineDev wrote: ... Small correction for clarity: void main() { Derived d = new Derived(); d.x = 13; d.y = 15; // 1) writeln(callMethod!(Derived, Derived.toString)(d)); - Should print 15 // 2) writeln(callBaseMethod!(Derived, Derived.toString)(d)); - Should print 13 // 3) writeln(d.Base.toString()); - Prints 13 }
Idiomatic way to call base method in generic code
import std.stdio, std.conv, std.traits; class Base { int x; override string toString() const { return x.to!string; } } class Derived : Base { int y; override string toString() const { return y.to!string; } } void callMethod(T, alias Method)(const T thiz) { thiz.fun(); } void callBaseMethod(SubClass, alias Method)(const SubClass thiz) { alias FirstSuperClass = BaseClassesTuple!(SubClass)[0]; thiz.FirstSuperClass.Method(); } void main() { Derived d = new Derived(); d.y = 15; d.x = 13; // 1) callMethod!(Derived, Derived.toString)(d); // 2) callBaseMethod!(Derived, Derived.toString)(d); // 3) writeln(d.Base.toString()); } I know I can call a base implementation of a method like in 3), but I need to do it generically like in 2). Does anybody now how I can achieve this? Additionally is there a way to make 1) work without using string mixins?
Calling to!string with null std.typecons.Rebindable results in segfault
Hi guys! I'm implementing a mixin for sinking the values of all class members which can be used like this: class MyFancyClassWithAlotOfMembers { // Many members here... void toString(scope void delegate(const(char)[]) sink) const { import utils.prettyPrint; mixin(toStrBody); // - Magic happens here } } Here is how I have implemented it: https://github.com/ZombineDev/Chess2RT/blob/master/source/util/prettyprint.d While doing so I stumbled on this bug: http://dpaste.dzfl.pl/875844035550 My questions are: 1) Is this a Phobos bug indeed? If so I will file a bug report. 2) Is there a better way to workaround the bug (without the compiles __trait)?