Re: Function template declaration mystery...
On Wednesday, 28 February 2018 at 17:47:22 UTC, Robert M. Münch wrote: Hi, I'm lost reading some code: A a; auto do(alias f, A)(auto ref A _a){ alias fun = unaryFun!f; return ... ... } How is this alias stuff working? I mean what's the type of f? Is it an anonymous function which then gets checked to be unary? How is it recognized in the code using the function template? This function can be called with code like this: a.do((myType) {...myCode...}); do(a, (myType) {...myCode...}); What's wondering me here is that the template function only has one paraemter (_a) but I somehow can get my myCode into it. But the code looks like a parameter to me. So why isn't it like: auto do(alias f, A)(auto ref A _a, ??? myCode){... I'm a bit confused. Testing this with: auto foo(alias f, A)(auto ref A a) { return f(a); } I can call foo either like this: foo!(x => x + x)(1); or 1.foo!(x => x + x); but these will give errors foo(1, x => x + x); //Error 1.foo(x => x + x); // Error I don't see how you can get that kind of behavior...
Re: Cast a 2d static array to a 1d static array. T[s][r] -> T[s*r]
On Tuesday, 27 February 2018 at 22:17:25 UTC, Jonathan wrote: On Tuesday, 27 February 2018 at 22:13:05 UTC, Jonathan wrote: Is it possible to cast a 2d static length array to a 1d static length array? E.g. int[2][2] a = [[1,2],[3,4]]; int[4]b = cast(int[4])a; Is not the byte data in memory exactly the same? *( [pos,size].ptr .cst!(void*) .cst!(int[4]*) ) (using dub `cst` library) or *( cast(int[4]*)(cast(void*)([pos,size].ptr)) ) Okay, this works but is this the best way?! This should work int[4] b = *(cast(int[4]*)a.ptr);
Re: Destructor called twice.
On Sunday, 25 February 2018 at 21:35:33 UTC, ketmar wrote: add postblit debug prints, and you will see. I get that it will call the postblit since it creates a temporary. What I expected though was that. auto s = S(0).foo(1); Would become something like: S s; s.__ctor(0).foo(1); But maybe this would not be consistent behavior? I'm wondering why it creates the temporary in the first place.
Re: Aliasing member's members
On Monday, 26 February 2018 at 20:50:35 UTC, Kayomn wrote: I've been experimenting with D's Better C mode, and I have a question regarding something that I started thinking about after watching one of Jonathon Blow's talks on data-oriented programming - more specifically the aspect of fake "inheritance" I have the following code. My question is if it's possible to use alias in a similar way to Jonathon's own language Jai and its using keyword, referencing the internal Vector2 as Player.pos instead of Player.entity.position: import core.stdc.stdio : printf; uint idCounter = 0; struct Vector2 { double x,y; } struct Entity { uint id; Vector2 position; } struct Player { Entity entity; alias pos = Entity.position; } Player createPlayer(Vector2 position) { Player player; player.entity.id = idCounter++; player.entity.position = position; return player; } int main(string[] args) { Player player = createPlayer(Vector2(50.0,50.0)); printf( "[Player]\nid: %d\nPosition: %lf x %lf\n", player.entity.id, player.pos.x, player.pos.y ); return 0; } Don't think you can alias member variables directly. You could do this though: struct Player { Entity entity; ref auto pos() inout { return entity.position; } } Which will give you most of what you want. Although if you want to take the address of pos you have to use auto addr = &player.pos();
Destructor called twice.
When writing some code to setup properties in a chain function manner I ran into some unexpected behavior with destructors. Example: struct S { int a, b; ref S foo(int b) { this.b = b; return this; } this(int ab) { this.a = this.b = ab; printf("ctor a=%d, b=%d\n", a, b); } ~this() { printf("dtor a=%d b=%d\n", a, b); } } void main() { auto s0 = S(0).foo(1); auto s1 = S(1).foo(2).foo(3).foo(4); auto s2 = S(2); s2.foo(5).foo(6).foo(7); } //Output is ctor 0 dtor 0 1 ctor 1 dtor 1 4 ctor a=2, b=2 dtor a=2 b=7 dtor 1 4 dtor 0 1 For s0,s1 the destructor is called twice but s2 works as I would expect. Taking a look with dmd -vcg-ast provided this: void main() { S s0 = ((S __slS3 = S(, );) , __slS3).this(0).foo(1); try { S s1 = ((S __slS4 = S(, );) , __slS4).this(1).foo(2).foo(3).foo(4); try { S s2 = s2 = S , s2.this(2); try { s2.foo(5).foo(6).foo(7); } finally s2.~this(); } finally s1.~this(); } finally s0.~this(); return 0; } The two extra dtor calls are not visible here but I guess they are caused by the temporary variables that are created and then go out of scope directly. Am I doing something wrong or is this a bug?
Re: Double link list
On Saturday, 24 February 2018 at 09:48:13 UTC, Joel wrote: I'm trying some code for practice, but it isn't working properly - it prints just one number when printing in reverse. I think the problem is here: void popFront() { head = head.next; if (head !is null) head.prev = null; } void popBack() { tail = tail.prev; if (tail !is null) tail.next = null; } Head and tail will point to the same nodes and you are setting the head.prev to null. Which would make the tail.prev null when iterating it backwards. Similarly if you started iterating it backwards and then iterating it forward it would not work.
Re: array/Array: "hard" bounds checking
On Thursday, 22 February 2018 at 12:50:43 UTC, ag0aep6g wrote: On 02/22/2018 10:39 AM, bauss wrote: On Thursday, 22 February 2018 at 05:22:19 UTC, TheFlyingFiddle wrote: Eg: uint a = 3; int b = -1; assert(a > b); //No idea what should happen here. This is what happens: assert(cast(int)a > b); Nope. It's `assert(a > cast(uint)b);`. These two posts kind of proved my point :D. And that is why you should never mix signed and unsigned integers. A good thing is that dscanner static analysis will warn you about this stuff (in simple cases at-least).
Re: array/Array: "hard" bounds checking
On Thursday, 22 February 2018 at 00:34:59 UTC, kdevel wrote: Is there a D equivalent of the C++ at method? I would like to reformulate repro2.d --- void main () { import std.stdio; import std.container; import std.range; auto z = Array!char(); z.reserve(0xC000_); z.capacity.writeln; z.length.writeln; for (uint u = 0; u < 0xC000_; ++u) z.insert = 'Y'; int i = -1073741825; i.writeln; z[i] = 'Q'; z[i].writeln; } --- $ dmd -O -m32 repro2.d $ ./repro2 3221225472 0 -1073741825 Q such that it fails like the 64 bit version: $ dmd -O -m64 repro2.d $ ./repro2 3221225472 0 -1073741825 core.exception.RangeError@.../dmd2/linux/bin64/../../src/phobos/std/container/array.d(650): Range violation ??:? _d_arrayboundsp [0x440d22] .../dmd2/linux/bin64/../../src/phobos/std/container/array.d:650 inout pure nothrow ref @nogc @safe inout(char) std.container.array.Array!(char).Array.opIndex(ulong) [0x43bb0f] repro2.d:14 _Dmain [0x43afff] Well in a 32bit program the value 0xBFFF_(-1073741825) is clearly inside the array. The Array class uses an size_t internaly for storing the length/capacity, that is uint in a 32bit program and ulong in a 64bit program. In the 64bit the value (0x__BFFF_)(-1073741825) is larger than 0xC000_000 so it will be out of bounds in this case. If you want any negative integer to be out of bounds the capacity cannot be larger than 0x7FFF_ in 32bit programs. But this behavior is strange. Well the really strange/bad part is that it's allowed by the compiler in the first place. I would be very happy if a user was forced to make an explicit cast for int <-> uint conversions. Like we have to do for long -> int conversions. Also signed/unsigned comparisons should be strictly outlawed by the compiler. Eg: uint a = 3; int b = -1; assert(a > b); //No idea what should happen here.
Re: Policy-based design in D
On Tuesday, 14 February 2017 at 06:48:33 UTC, TheGag96 wrote: Tonight I stumbled upon Andrei's concept of policy-based design (https://en.wikipedia.org/wiki/Policy-based_design) and tried to implement their example in D with the lack of multiple inheritance in mind. https://dpaste.dzfl.pl/adc05892344f (btw, any reason why certificate validation on dpaste fails right now?) The implementation isn't perfect, as I'm not sure how to check members of mixin templates so that you could verify whether print() and message() are actually where they should be. How would you do that? Is there any use for this kind of thing in D, and if so, what would it be? I've hardly dabbled in OOP patterns, but the abstraction seems kinda interesting. Something like this can be used to check if the mixin has a specific member: template hasMixinMember(alias mixin_, string member) { enum hasMixinMember = __traits(compiles, () { mixin mixin_ mix; static assert(__traits(hasMember, mix, member)); }); } struct HelloWorld(alias OutputPolicy, alias LanguagePolicy) if(hasMixinMember!(OutputPolicy, "print") && hasMixinMember!(LanguagePolicy, "message")) { mixin OutputPolicy; mixin LanguagePolicy; void run() { print(message()); } } Note: This method could fail if you do some compile-time reflection black magic inside the mixins. Could also do this: struct HelloWorld(alias OutputPolicy, alias LanguagePolicy) { mixin OutputPolicy output; mixin LanguagePolicy lang; void run() { output.print(lang.message()); } } If "output" / "lang" does not contain a particular member you will get a compile time error at the usage point (although it's not the best message).
Re: Yield from function?
On Monday, 30 January 2017 at 11:03:52 UTC, Profile Anaysis wrote: I need to yield from a complex recursive function too allow visualizing what it is doing. e.g., if it is a tree searching algorithm, I'd like to yield for each node so that the current state can be shown visually. I realize that there are several ways to do this but D a yield version without additional threads would be optimal. I don't need concurrency or speed, just simple. If you don't want to use fibers then an alternative to yeilds is to use callbacks during iteration. Example: struct Tree(T) { T value; Tree!(T)[] children; } void iterDepth(T)(Tree!(T) tree, void delegate(Tree!T) cb) { cb(tree); foreach(child; tree.children) { iterDepth(child, cb); } } unittest { auto tree = ... //Make the tree somehow iterDepth(tree, (node) { writeln(node.value); }); } Callbacks have their set of problems but it's one of the simpler ways to do this.
Re: Is it possible to "cache" results of compile-time executions between compiles?
On Tuesday, 24 January 2017 at 21:41:12 UTC, Profile Anaysis wrote: On Tuesday, 24 January 2017 at 21:36:50 UTC, Profile Anaysis wrote: ... Maybe with all this talk of the new CTFE engine being developed, a similar mechanism can be used optionally? This could help with debugging also. In debug mode, the cfte mixin's are written to disk with hash, if they are not a string themselves. (could be done with all cfte's, I suppose, but not sure about performance and consistency) Then debuggers can use the outputed cfte's for proper analysis, line breaking, etc... Would be nice to have something like this in dmd. Would be even better if it could work on templates as well. No more stepping though functions filled with static if :). I think it would be possible to make something like this work to: template Generator(T...) { string Generator() { //Complex ctfe with T... that generates strings and nothing else. } } If it's possible to quickly detect changes to all T arguments one could cache things on this form to. For example: mixin Cache!("some_file_name", Generator, size_t, int, 2, "hello", MyStruct(3), MyType); The problem would be detecting changes in the arguments. As long as one is able to get a unique hash from each input element it should work fine I think. I guess it would be required to reflect over the members of the structs/classes to lookup attributes and such. If the generation stage is time consuming this might be worth it... But it's not gonna be "almost free" like for DSLs. Basic types (not including functions/delegates don't see how this could work without writing mixin code targeted at caching) should be simple/trivial to detect changes to however.
Re: Is it possible to "cache" results of compile-time executions between compiles?
On Tuesday, 24 January 2017 at 21:36:50 UTC, Profile Anaysis wrote: On Tuesday, 24 January 2017 at 16:49:03 UTC, TheFlyingFiddle wrote: On Tuesday, 24 January 2017 at 16:41:13 UTC, TheFlyingFiddle wrote: Everything turned out s much better than expected :) Added bonus is that mixin output can be viewed in the generated files :D Could you post your solution? I suggest we get a real caching module like above that has the extra feature of hashing the mixin strings. This way the caching mechanism can validate if the mixin strings have changed. Put the hash in a comment in the output file that used to test if the input string has the same hash. If it does, simply use the output file, else, regenerate. Adds some overhead but keeps things consistent. (Since I'm not sure what Cache!() is, I'm assuming it doesn't do this) This is the solution I through together: // module mixin_cache.d mixin template Cache(alias GenSource, string from, string path) { import core.internal.hash; import std.conv : to; //Hash to keep track of changes enum h = hashOf(from); enum p = path ~ h.to!string ~ ".txt"; //Check if the file exists else suppress errors //The -J flag needs to be set on dmd else //this always fails static if(__traits(compiles, import(p))) { //Tell the wrapper that we loaded the file p //_importing is a magic string pragma(msg, "_importing"); pragma(msg, p); mixin(import(p)); } else { //We don't have a cached file so generate it private enum src = GenSource!(from); static if(__traits(compiles, () { mixin(src); })) { //_exporing_start_ tells the wrapper to begin //outputing the generated source into file p pragma(msg, "_exported_start_"); pragma(msg, p); pragma(msg, src); pragma(msg, "_exported_end_"); } mixin(src); } } To make this work I wrap dmd in a d script like this: (ignoring some details as what i've got is not really tested yet) // dmd_with_mixin_cache.d void main(string[] args) { auto dmdargs = ... //Fix args etc. auto dmd = pipeProcess(dmdargs, Redirect.stderr); foreach(line; dmd.stderr.byLine(KeepTerminator.yes)) { if(line.startsWith("_exported_start_")) { //Parse file and store source in a file //Keep going until _exported_end_ } else if(line.startsWith("_importing")) { //A user imported a file. (don't delete it!) } else { //Other output from dmd like errors / other pragma(msg, ...) } } //Files not imported / exported could be stale //delete them. Unless we got a compile error from dmd //Then don't delete anything. } The cache template and the small wrapper that wraps dmd was all that were needed. usage is somthing like this: template Generate(string source) { string Generate() { //Do some complex ctfe here //can't wait for the new ctfe engine! foreach(i; 0 .. 100_000) { } return source; } } mixin Cache!("Some interesting DSL or similar", __MODULE__); //some_filename is not really needed but can be nice when browsing the //mixin code to see where it came from. (approximately anwyays) This is it. If you want I can post a full solution sometime later this week but I want to clean up what I have first.
Re: Is it possible to "cache" results of compile-time executions between compiles?
On Tuesday, 24 January 2017 at 16:41:13 UTC, TheFlyingFiddle wrote: Everything turned out s much better than expected :) Added bonus is that mixin output can be viewed in the generated files :D
Re: Is it possible to "cache" results of compile-time executions between compiles?
On Tuesday, 24 January 2017 at 12:19:33 UTC, ketmar wrote: On Tuesday, 24 January 2017 at 12:14:05 UTC, TheFlyingFiddle wrote: unittest { enum s = import("myfile"); } Is there something similar to this for outputting files at compile-time? no. this is by design, so it won't be fixed. sorry. you may use build script that will create the code first, and you can dump `pragma(msg, …);` to file, but that's all. Thanks again. Wrapping dmd with a script worked wonders! Now i'm able to do this: From the old: (a) unittest { mixin Sql!(...); mixin Sql!(...); ... mixin Sql!(...); } To the new: (b) unittest { mixin Cache!(Sql, ...); mixin Cache!(Sql, ...); ... mixin Cache!(Sql, ...); } For (a) the build times are in the 10-30s always For (b) the build times are in the 10-30s the first time and subseconds later. Each query just adds a few ms to the build time now! Additionally even if dmd crashes with an out of memory exception (which still happens with the current ctfe engine) most of the queries will have already been built and dmd can be restarted. After the restart the built queries are loaded via caching and dmd can finish working on the leftovers. Everything turned out s much better than expected :)
Re: Is it possible to "cache" results of compile-time executions between compiles?
On Tuesday, 24 January 2017 at 12:19:33 UTC, ketmar wrote: On Tuesday, 24 January 2017 at 12:14:05 UTC, TheFlyingFiddle wrote: unittest { enum s = import("myfile"); } Is there something similar to this for outputting files at compile-time? no. this is by design, so it won't be fixed. sorry. you may use build script that will create the code first, and you can dump `pragma(msg, …);` to file, but that's all. Yeah, I guess allowing the compiler to produce arbitrary files would be problematic from a security standpoint. Thanks for the pragma idea! Wrapping the build in a script is a satisfactory solution for me.
Re: Is it possible to "cache" results of compile-time executions between compiles?
On Tuesday, 24 January 2017 at 11:19:58 UTC, TheFlyingFiddle wrote: Does D have any facilities that could make this possible? It seems that there is a feature I was unaware of/forgot called Import Expressions. unittest { enum s = import("myfile"); } Is there something similar to this for outputting files at compile-time? Or do I need to keep the source around and write it at run-time?
Re: Why is &array[0] @safer than array.ptr?
On Tuesday, 24 January 2017 at 11:28:17 UTC, Atila Neves wrote: void main() { foo; } void foo() @safe { int[] array; auto ptr = array.ptr; } foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe. Atila Just a speculative guess. unittest @safe { int[] array; auto ptr = array.ptr; //could be null auto ptr2 = &array[0]; //Does a bounds check? auto ptr3 = &array[5]; //Should do a bounds check. }
Is it possible to "cache" results of compile-time executions between compiles?
Context: I am currently writing a small library that compiles sql strings at compile-time and generates query objects. Something like this: unittest { mixin Sql!(q{ select feed.url, feed.title from users join user_feeds as feed on users.id = feed.user where user.id = {user} }, DBInterface) UserFeeds; UserFeeds.Query query; query.user = 1; //some user auto con = //Open db connection auto feeds = con.execute(query); foreach(f; feeds) { writef("Feed: %s\n\tTitle: %s\n", f.url, f.title); } } The parsing step does some amount work like validates the sql query, makes sure that tables "user" and "user_feed" exists in DBInterface and creates a query having "user" as input and a result type containing url, title with appropriate type. Now the compile times for parsing a small number of queries are marginal. However, as the queries become more numerous and complex compile-times starts to become a problem. Currently I "solve"tm long compile times by having the DBInterface and queries be compiled into a separate lib and linking to that lib from the main application. Having a dedicated db lib fixes compile times for the main application. But I am wondering if it's possible to work on a lower level of granularity. Somehow "cache" the queries between compiles, without resorting to each query being compiled into it's own lib/object file. Does D have any facilities that could make this possible?
Re: Problems with stored procedure using the mysql-native library.
On Wednesday, 18 January 2017 at 19:40:12 UTC, TheFlyingFiddle wrote: Hi I am having problems using stored procedures that return results. Update: I am using the SvrCapFlags.MULTI_RESULTS flag when initiating the connection and have also tried using the SvrCapFlags.MULTI_STATEMENTS flag. Unfortunately these flags do not solve the problem.
Problems with stored procedure using the mysql-native library.
Hi I am having problems using stored procedures that return results. Example procedure: CREATE PROCEDURE GetUsers() SELECT * FROM users; When I use this procedure from the MySQL command line everything works fine. However, when I use it from the mysql-native library i get into problems. int main() { auto con = new Connection(...); // auto cmd = Command(con); cmd.execProcedure("GetUsers"); } This returns the error: MySQL error: PROCEDURE db.getusers can't return a result set in the given context. Other SQL queries work fine over the connection and procedure calls that do not return anything also works. How would i go about solving this problem?
Re: test if the alias of a template is a literal
On Thursday, 27 October 2016 at 14:45:22 UTC, Gianni Pisetta wrote: On Thursday, 27 October 2016 at 14:34:38 UTC, TheFlyingFiddle wrote: On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote: Hi all, but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done? Thanks, Gianni Pisetta Not really understanding your problem. Could you include an example use that is problematic? Yea, sorry I missed that. A really stupid example would be string var; alias Sequence = Optimize!( "The", " ", "value", " ", "of", " ", "var is ", var ); static assert( is( Sequence == AliasSeq!( "The value of var is ", var ) ) ); writeln( Sequence ); given that you include the code snippet in the first post. Thanks, Gianni I think this fixes the problem: template isStringLiteral(T...) if (T.length == 1) { static if(is( typeof(T[0]) == string )) { enum bool isStringLiteral = !__traits(compiles, &T[0]); } else { enum bool isStringLiteral = false; } } Literals do not have an address but variables do. However note that: string var; static assert(!is(AliasSeq!(var) == AliasSeq!(var))); It still works at run-time though: string var = " hello "; alias Seq = Optimize!("This", " is", " a", " variable! ", var); //pragma(msg, Seq) //Fails to compile at var //static assert(is(Seq == AliasSeq!("This is a variable!", var))); //Also fails writeln(Seq); //Still works
Re: test if the alias of a template is a literal
On Thursday, 27 October 2016 at 14:04:23 UTC, Gianni Pisetta wrote: Hi all, but at the moment isStringLiteral will return true even with variables of type string. So i searched for a metod to check if an alias is a literal value, but found nothing. Anyone have any clue on how can be done? Thanks, Gianni Pisetta Not really understanding your problem. Could you include an example use that is problematic?
Re: Meta-programming detecting anonymous unions inside structs.
On Friday, 21 October 2016 at 08:18:58 UTC, rikki cattermole wrote: On 21/10/2016 9:13 PM, TheFlyingFiddle wrote: On Friday, 21 October 2016 at 07:56:27 UTC, rikki cattermole wrote: You're gonna have to use UDA's for that. Yes, to do the serialization you're right. But my usecase for this is for error reporting. Basically any struct that contains unions without serialization instructions cannot be serialized and I want to make such structures errors. So when I try to serialize the example struct Foo. It should assert with something along the lines of: "Don't know how to serialize overlapping fields: "Foo.integer", "Foo.floating" and "Foo.array". I suppose you could use .offsetof to determine this. This is what I was looking for. Thanks!
Re: Meta-programming detecting anonymous unions inside structs.
On Friday, 21 October 2016 at 07:56:27 UTC, rikki cattermole wrote: You're gonna have to use UDA's for that. Yes, to do the serialization you're right. But my usecase for this is for error reporting. Basically any struct that contains unions without serialization instructions cannot be serialized and I want to make such structures errors. So when I try to serialize the example struct Foo. It should assert with something along the lines of: "Don't know how to serialize overlapping fields: "Foo.integer", "Foo.floating" and "Foo.array".
Meta-programming detecting anonymous unions inside structs.
I am trying to port a serialization library I wrote in Lua some time ago. I've ran into a problem relating to types with anonymous unions inside. Given this code: enum Kind { none = 0, array, integer, floating, } struct Foo { Kind type; union { ulong integer; double floating; void[] array; } int nonUnionField; //... } How can I tell that "integer", "floating" and "array" are part the union while "nonUnionField" is not? Thanks in advance.
Re: How to do "inheritance" in D structs
On Wednesday, 12 October 2016 at 02:18:47 UTC, TheFlyingFiddle wrote: void foo(ref ABase base) { base.ival = 32; } This should be: void foo(ref Base1 base) { base.ival = 32; }
Re: How to do "inheritance" in D structs
On Wednesday, 12 October 2016 at 01:22:04 UTC, lobo wrote: Hi, I'm coming from C++ and wondered if the pattern below has an equivalent in D using structs. I could just use classes and leave it up to the caller to use scoped! as well but I'm not sure how that will play out when others start using my lib. Thanks, lobo module A; class Base1 { int ival = 42; } class Base2 { int ival = 84; } module B; class S(ABase) : ABase { string sval = "hello"; } module C; import A; import B; void main() { auto s= scoped!(S!Base1); // scoped!(S!Base2) } You could use "alias this" to simulate that type of inheritence. module A; struct Base1 { int ival = 42; } module B; struct Base2 { int ival = 84; } module C; import A, B; struct S(Base) if(is(Base == struct)) { Base base; alias base this; string sval = "Hello "; } void foo(ref ABase base) { base.ival = 32; } void main() { S!Base1 a; S!Base2 b; writeln(a.sval, a.ival); writeln(b.sval, b.ival); foo(a); writeln(a.sval, a.ival); }
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 15:46:20 UTC, orip wrote: On Tuesday, 11 October 2016 at 13:06:37 UTC, pineapple wrote: Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`. Of course it does! I would like the function to return an "input range of int", no matter which one specifically. Is this possible? It is, but you will have to use an interface / class to achieve this behavior (or use some sort of polymorphic struct). Something like this will do the trick: import std.range; import std.stdio; interface IInputRange(T) { bool empty(); T front(); void popFront(); } final class InputRange(Range) if(isInputRange!Range) : IInputRange!(ElementType!Range) { Range r; this(Range r) { this.r = r; } bool empty() { return r.empty; } ElementType!Range front() { return r.front; } void popFront() { r.popFront; } } auto inputRange(Range)(Range r) { return new InputRange!Range(r); } IInputRange!int foo(int[] ints) { import std.range; if(ints.length > 10) { return inputRange(chain(ints[0 .. 5], ints[8 .. $])); } else { return inputRange(ints); } } void main() { auto ir = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); auto ir2 = foo([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); writeln(ir); writeln(ir2); }
Re: bug, or is this also intended?
On Monday, 3 October 2016 at 11:40:00 UTC, deed wrote: Unexpected auto-concatenation of string elements: string[] arr = ["a", "b" "c"];// ["a", "bc"], length==2 int[] arr2 = [[1], [2] [3]];// Error: array index 3 is out of bounds [2][0 .. 1] // Error: array index 3 is out of bounds [0..1] dmd 2.071.2-b2 It comes from C. In C you can write stuff like: char* foo = "Foo is good but... " "... bar is better!"; Eg static string concatenation for multiline/macros etc. Think it was implemented this way to provide better support for converting c codebases.
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 16:45:11 UTC, Uranuz wrote: How to make rsplit (like in Python) in D without need for extra allocation using standard library? And why there is no algorithms (or parameter in existing algorithms) to process range from the back. Is `back` and `popBack` somehow worse than `front` and `popFront`. I've tried to write somethig that would work without allocation, but failed. I have searching in forum. Found this thread: https://forum.dlang.org/post/bug-1030...@http.d.puremagic.com%2Fissues%2F I tried to use `findSplitBefore` with `retro`, but it doesn't compile: import std.stdio; import std.algorithm; import std.range; import std.string; void main() { string str = "Human.Engineer.Programmer.DProgrammer"; writeln( findSplitBefore(retro(str), ".")[0].retro ); } Compilation output: /d153/f534.d(10): Error: template std.range.retro cannot deduce function from argument types !()(Result), candidates are: /opt/compilers/dmd2/include/std/range/package.d(198): std.range.retro(Range)(Range r) if (isBidirectionalRange!(Unqual!Range)) Why I have to write such strange things to do enough wide-spread operation. I using Python at the job and there is very much cases when I use rsplit. So it's very strange to me that D library has a lot of `advanced` algorithms that are not very commonly used, but there is no rsplit. Maybe I missing something, so please give me some advice) There are two reasons why this does not compile. The first has to do with how retro() (and indeed most function in std.range) work with utf-8 strings (eg the string type). When working on strings as ranges, the ranges internally change the type of ".front" from 'char' into 'dchar'. This is done to ensure that algorithms working on strings do not violate utf-8. See related thread: http://forum.dlang.org/post/mailman.384.1389668512.15871.digitalmars-d-le...@puremagic.com The second reason has to do with findSplitBefore called with bidirectional ranges. Now to why your code does not compile. retro takes as input parameter a bidirectional or random access range. Because of how strings are handled, the string type "string" is not characterized as a random access range but instead as a bidirectional range. So the output from retro is a bidirectional range. Calling findSplitBefore with a bidirectional range unfortunately does not return results that are also bidirectional ranges. Instead findSplitBefore returns forward ranges when bidirectional ranges are given as input. I am not entirely sure why. The chain of calls has the following types. string is (bidirectional range) -> retro(str) is (bidirectional range) -> findSplitBefore is (forward range) Now the last call to retro is called with a forward range and retro needs bidirectional or random access ranges as input. If you change the line: string str = "Human.Engineer.Programmer.DProgrammer"; into: dstring str = "Human.Engineer.Programmer.DProgrammer"; Then the code will compile. The reason for this is: dstring is (random access range) -> retro(str) is (random access range) -> findSplitBefore is (random access range) Now the last call to retro gets a random access range as input and everyone is happy.
What does the -betterC switch in dmd do?
The description in dmd help says: omit generating some runtime information and helper functions. What runtime information are we talking about here? My understanding is that it's basically an experimental feature but when (if) completed what subset of the language would still be usable?
Re: String interpolation
On Tuesday, 10 November 2015 at 10:41:52 UTC, tired_eyes wrote: On Tuesday, 10 November 2015 at 10:33:30 UTC, Tobias Pankrath wrote: Ruby: a = 1 b = 4 puts "The number #{a} is less than #{b}" PHP: $a = 1; $b = 4; echo "The number $a is less than $b"; D: ??? int a = 1, b = 4; writefln("The number %s is less than %s", a, b); You can't do it the ruby / perl / php way in D. It could be possible if we had AST macros in the language but as it stands now it's not possible to do that. the closest you could get is something like this: string s = aliasFormat!("The number $a is less than $b", a, b); or aliasWrite!("The number $a is less than $b", a, b); Not really recommended though as these would end up creating lots of template bloat.
Re: Associative arrays
On Monday, 9 November 2015 at 04:52:37 UTC, rsw0x wrote: On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole wrote: Fwiw, EMSI provides high quality containers backed by std.experimental.allocator. https://github.com/economicmodeling/containers I have a question regarding the implementation of the economicmodeling hashmap. Why must buckets be a power of two? Is it to be able to use the: hash & (buckets.length - 1) for index calculations or is there some other reason?
Re: Associative arrays
On Monday, 9 November 2015 at 04:52:37 UTC, rsw0x wrote: On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole wrote: On 09/11/15 4:57 PM, TheFlyingFiddle wrote: [...] Nope. [...] As far as I'm aware, you are stuck using e.g. structs to emulate AA behavior. I have a VERY basic implementation here: https://github.com/rikkimax/alphaPhobos/blob/master/source/std/experimental/internal/containers/map.d Feel free to steal. Fwiw, EMSI provides high quality containers backed by std.experimental.allocator. https://github.com/economicmodeling/containers Thanks for the suggestions. I also made a hashmap using allocators some time ago that I use in-place of the built in hashmap for most of my purposes. The syntax of a custom hash map is somewhat lacking in comparison to the built in one however and I was hoping that I could either make the built in work with allocators or replace it with my own implementation. In addition to this I am building a pointer patching binary serializer and I hoped that I could make it work with the built in aa without requiring to many gc allocations. The economicmodeling one seems interesting ill try it out and see if it's better then the one I am currently using.
Associative arrays
I have a few questions about the pseudo built in associative arrays. 1. Is it possible to have the built in associative array use a custom allocator from std.experimental.allocator to service it's allocation needs? 2. A while ago I read on the newsgroup a while back that there was a plan to make it possible for a user to swap out the standard associative array implementation by modifying druntime and or implementing some linker functions. Have this been done yet? And if so what must I do to swap the implementation?
Re: Preferred behavior of take() with ranges (value vs reference range)
On Monday, 9 November 2015 at 02:14:58 UTC, Jon D wrote: Here's an example of the behavior differences below. It uses refRange, but same behavior occurs if the range is created as a class rather than a struct. --Jon This is an artifact of struct based ranges being value types. When you use take the range get's copied into another structure that is also a range but limits the number of elements you take from that range. Basically: take looks something like this: (simplified) struct Take(Range) { size_t count; Range range; @property ElementType!Range front() { return range.front; } @property bool empty() { return count == 0 || range.empty; } void popFront() { count--; range.popFront; } } Code like this: auto fib1 = ... //Here fib1 get's copied into first5. auto first5 = Take(5, fib); So later when you perform actions on first5 you no longer take any action on fib1 but instead take action on the copied range inside of first5. Hence you don't see any consumption of fib1's elements. However when you use a refRange / a class the Take range will take a reference / pointer to the actual range. So now your no longer working a copy of the range but on the range itself. As you reuse the same range you will see that consumption has occured. If you want a more indepth explanation there were two talks at Dconf this year that (in part) discussed this topic. (https://www.youtube.com/watch?v=A8Btr8TPJ8c, https://www.youtube.com/watch?v=QdMdH7WX2ew&list=PLEDeq48KhndP-mlE-0Bfb_qPIMA4RrrKo&index=14)
Re: Align a variable on the stack.
On Friday, 6 November 2015 at 11:38:29 UTC, Marc Schütz wrote: On Friday, 6 November 2015 at 11:37:22 UTC, Marc Schütz wrote: Ok, benchA and benchB have the same assembler code generated. However, I _can_ reproduce the slowdown albeit on average only 20%-40%, not a factor of 10. Forgot to add that this is on Linux x86_64, so that probably explains the difference. It turns out that it's always the first tested function that's slower. You can test this by switching benchA and benchB in the call to benchmark(). I suspect the reason is that the OS is paging in the code the first time, and we're actually seeing the cost of the page fault. If you a second round of benchmarks after the first one, that one shows more or less the same performance for both functions. I tested swapping around the functions on windows x86 and I still get the same slowdown with the default initializer. Still basically the same running speed of both functions on windows x64. Interestingly enough the slowdown disappear if I add another float variable to the structs. This causes the assembly to change to using different instructions so I guess that is why. Also it only seems to affect small structs with floats in them. If I change the memebers to int both versions run at the same speed on x86 aswell.
Re: Unittest in a library
On Friday, 6 November 2015 at 03:59:07 UTC, Charles wrote: Is it possible to have unittest blocks if I'm compiling a library? I've tried having this: test.d: class Classy { unittest { assert(0, "failed test"); } } and then build it with `dmd test.d -lib -unittest` and it doesn't fail the unittest. You can test the unittests by using the -main switch. http://dlang.org/dmd-linux.html#switch-main
Re: Align a variable on the stack.
On Friday, 6 November 2015 at 00:43:49 UTC, rsw0x wrote: On Thursday, 5 November 2015 at 23:37:45 UTC, TheFlyingFiddle wrote: On Thursday, 5 November 2015 at 21:24:03 UTC, TheFlyingFiddle wrote: [...] I reduced it further: [...] these run at the exact same speed for me and produce identical assembly output from a quick glance dmd 2.069, -O -release -inline Are you running on windows? I tested on windows x64 and there I also get the exact same speed for both functions.
Re: Align a variable on the stack.
On Thursday, 5 November 2015 at 21:24:03 UTC, TheFlyingFiddle wrote: On Thursday, 5 November 2015 at 21:22:18 UTC, TheFlyingFiddle wrote: On Thursday, 5 November 2015 at 11:14:50 UTC, Marc Schütz wrote: ~10x slowdown... I forgot to mention this but I am using DMD 2.069.0-rc2 for x86 windows. I reduced it further: struct A { float x, y, z ,w; } struct B { float x=float.nan; float y=float.nan; float z=float.nan; float w=float.nan; } void initVal(T)(ref T t, ref float k) { pragma(inline, false); } void benchA() { foreach(float f; 0 .. 1000_000) { A val = A.init; initVal(val, f); } } void benchB() { foreach(float f; 0 .. 1000_000) { B val = B.init; initVal(val, f); } } int main(string[] argv) { import std.datetime; import std.stdio; auto res = benchmark!(benchA, benchB)(1); writeln("Default: ", res[0]); writeln("Explicit: ", res[1]); readln; return 0; } also i am using dmd -release -boundcheck=off -inline The pragma(inline, false) is there to prevent it from removing the assignment in the loop.
Re: Align a variable on the stack.
On Thursday, 5 November 2015 at 21:22:18 UTC, TheFlyingFiddle wrote: On Thursday, 5 November 2015 at 11:14:50 UTC, Marc Schütz wrote: ~10x slowdown... I forgot to mention this but I am using DMD 2.069.0-rc2 for x86 windows.
Re: Align a variable on the stack.
On Thursday, 5 November 2015 at 11:14:50 UTC, Marc Schütz wrote: On Thursday, 5 November 2015 at 03:52:47 UTC, TheFlyingFiddle wrote: Can you publish two compilable and runnable versions of the code that exhibit the difference? Then we can have a look at the generated assembly. If there's really different code being generated depending on whether the .init value is explicitly set to float.nan or not, then this suggests there is a bug in DMD. I created a simple example here: struct A { float x, y, z ,w; } struct B { float x=float.nan; float y=float.nan; float z=float.nan; float w=float.nan; } void initVal(T)(ref T t, ref float k) { pragma(inline, false); t.x = k; t.y = k * 2; t.z = k / 2; t.w = k^^3; } __gshared A[] a; void benchA() { A val; foreach(float f; 0 .. 1000_000) { val = A.init; initVal(val, f); a ~= val; } } __gshared B[] b; void benchB() { B val; foreach(float f; 0 .. 1000_000) { val = B.init; initVal(val, f); b ~= val; } } int main(string[] argv) { import std.datetime; import std.stdio; auto res = benchmark!(benchA, benchB)(1); writeln("Default: ", res[0]); writeln("Explicit: ", res[1]); return 0; } output: Default: TickDuration(1637842) Explicit: TickDuration(167088) ~10x slowdown...
Re: Align a variable on the stack.
On Wednesday, 4 November 2015 at 01:14:31 UTC, Nicholas Wilson wrote: Note that there are two different alignments: to control padding between instances on the stack (arrays) to control padding between members of a struct align(64) //arrays struct foo { align(16) short baz; //between members align (1) float quux; } your 2.5x speedup is due to aligned vs. unaligned loads and stores which for SIMD type stuff has a really big effect. Basically misaligned stuff is really slow. IIRC there was a (blog/paper?) of someone on a uC spending a vast amount of time in ONE misaligned integer assignment causing traps and getting the kernel involved. Not quite as bad on x86 but still with doing. As to a less jacky solution I'm not sure there is one. Thanks for the reply. I did some more checking around and I found that it was not really an alignment problem but was caused by using the default init value of my type. My starting type. align(64) struct Phys { float x, y, z, w; //More stuff. } //Was 64 bytes in size at the time. The above worked fine, it was fast and all. But after a while I wanted the data in a diffrent format. So I started decoding positions, and other variables in separate arrays. Something like this: align(16) struct Pos { float x, y, z, w; } This counter to my limited knowledge of how cpu's work was much slower. Doing the same thing lot's of times, touching less memory with less branches should in theory at-least be faster right? So after I ruled out bottlenecks in the parser I assumed there was some alignment problems so I did my Aligner hack. This caused to code to run faster so I assumed this was the cause... Naive! (there was a typo in the code I submitted to begin with I used a = Align!(T).init and not a.value = T.init) The performance was actually cased by the line : t = T.init no matter if it was aligned or not. I solved the problem by changing the struct to look like this. align(16) struct Pos { float x = float.nan; float y = float.nan; float z = float.nan; float w = float.nan; } Basically T.init get's explicit values. But... this should be the same Pos.init as the default Pos.init. So I really fail to understand how this could fix the problem. I guessed the compiler generates some slightly different code if I do it this way? And that this slightly different code fixes some bottleneck in the cpu. But when I took a look at the assembly of the function I could not find any difference in the generated code... I don't really know where to go from here to figure out the underlying cause. Does anyone have any suggestions?
Re: foreach loop
On Tuesday, 3 November 2015 at 15:29:31 UTC, Namal wrote: well I tried this that way, but my count stays 0, same as if I do it in an int function with a return though I clearly have some false elements in the arr. You could also use count: http://dlang.org/phobos/std_algorithm_searching.html#count return arr.count!(x => !x);
Re: Is it possible to filter variadics?
On Tuesday, 3 November 2015 at 23:41:10 UTC, maik klein wrote: Is it possible to filter variadics for example if I would call void printSumIntFloats(Ts...)(Ts ts){...} printSumIntFloats(1,1.0f,2,2.0f); I want to print the sum of all integers and the sum of all floats. //Pseudo code void printSumIntFloats(Ts...)(Ts ts){ auto sumOfInts = ts .filter!(isInteger) .reduce(a => a + b); writeln(sumOfInts); ... } Is something like this possible? It is possible: I don't think that reduce works on tuples but you could do something like this. import std.traits, std.meta; void printsumIntFloats(Ts...)(Ts ts) { alias integers = Filter!(isInteger, Ts); alias floats = Filter!(isFloatingPoint, Ts); alias int_t= CommonType!(integers); alias float_t = CommonType!(floats); int_t intres = 0; float_t floatres = 0; foreach(i, arg; ts) { static if(isInteger!(Ts[i])) intres += arg; else floatres += arg; } writeln(intres); writeln(floatres); }
Align a variable on the stack.
Is there a built in way to do this in dmd? Basically I want to do this: auto decode(T)(...) { while(...) { T t = T.init; //I want this aligned to 64 bytes. } } Currently I am using: align(64) struct Aligner(T) { T value; } auto decode(T)(...) { Aligner!T t = void; while(...) { t.value = T.init; } } But is there a less hacky way? From the documentation of align it seems i cannot use that for this kind of stuff. Also I don't want to have to use align(64) on my T struct type since for my usecase I am decoding arrays of T. The reason that I want to do this in the first place is that if the variable is aligned i get about a 2.5x speedup (i don't really know why... found it by accident)
Re: Unionize range types
On Tuesday, 3 November 2015 at 01:55:27 UTC, Freddy wrote: Is there any way I can Unionize range Types? --- auto primeFactors(T)(T t, T div = 2) { if (t % div == 0) { return t.only.chain(primeFactors(t / div, div)); } if (div > t) { return []; } else { return primeFactors(t, div + 1); } } --- Simplest way would be to go with a polymorphic approach. import std.range; interface IInputRange(T) { T front(); bool empty(); void popFront(); } class InputRange(Range) : IInputRange(ElementType!Range) { Range inner; T front() { return inner.front; } bool empty() { return inner.empty; } void popFront() { inner.popFront; } } Simply wrap the ranges in the InputRange!Range class template. And return an IInputRange!T. This will require allocation though and is not really the way I would tackle the problem. Or you could use Algebraic from std.variant which is probably more what you were looking for. But it's kind of awkward to use in the example you posted since it's not really clear what the specific range types are. I would suggest creating a new range for prime-factors instead of trying to mix several ranges together. Something like this should do the trick. (if i am understanding the problem correctly) auto primeFactors(T)(T t) if(isIntegral!T) { struct Factors { T value; T front; bool empty() { return value == 1; } void popFront() { while(true) { if(value % front == 0) { value /= front; break; } if(front > value) { value = 1; break; } else { front = front + 1; } } } } auto f = Factors(t, 2); f.popFront(); return f; }
Re: Efficiency of immutable vs mutable
On Tuesday, 3 November 2015 at 03:16:07 UTC, Andrew wrote: I've written a short D program that involves many lookups into a static array. When I make the array immutable the program runs faster. This must mean that immutable is more than a restriction on access, it must affect the compiler output. But why and how? Thanks Andrew I'm going to speculate a bit here since you did not post any code. Say you have this code: static char[4] lookup = ['a', 't', 'g', 'c'] This lookup table will be in thread local storage (tls). TLS is a way to have global variables that are not shared between threads that is every thread has it's own copy of the variable. TLS variables are not as fast to access as true global variables however since the accessing code has to do some additional lookup based on the thread to gain access to the correct copy. If you change the above code to this: static immutable char[4] lookup = ['a', 't', 'g', 'c']; Then you get an immutable array. Since this array cannot change and is the same on all threads there is no reason to have separate storage for each thread. Thus the above code will create a true global variable that is shared between the threads. So what you are likely seeing is that a variable changed from being tls to being a shared global. Global accessing is faster then TLS accessing so this is probably what made your code run faster. If you want a shared global that is not immutable you can do this. __gshared char[4] lookup = ['a', 't', 'g', 'c]; Be warned though these kinds of globals are not thread safe so mutation and accessing should be synchronized if your using more then one thread.
Re: Static constructors in structs.
On Friday, 30 October 2015 at 21:29:22 UTC, BBasile wrote: __gshared is mostly usefull on fields (eg public uint a) because it prevents a data to be put on the TLS, which in certain case reduces the perfs up to 30%. The byte code using a global variable that's not __gshared can be incredibly slower ! I have gotten used to using __gshared on fields so much that I just naturally assumed that shared static this() { } would be equivalent to __gshared static this() { } :P. I find they can be very useful for data that initialized in static constructors and then never change again (I will have to fix my shared constructors now :S guess i have been lucky not running into race problems before).
Re: Static constructors in structs.
On Friday, 30 October 2015 at 20:58:37 UTC, anonymous wrote: On 30.10.2015 21:23, TheFlyingFiddle wrote: Is this intended to work? struct A { __gshared static this() { //Add some reflection info to some global stuff. addReflectionInfo!(typeof(this)); } } I just noticed this works in 2.069, is this intended? static constructors are supposed to work, yes. The description is on the class page: http://dlang.org/class.html#static-constructor __gshared doesn't do anything there, though. Use `shared static this` instead, if you want the constructor to run only once per process, and not once per thread. Was under the impression that __gshared did the same thing for static constructors. Thanks.
Re: Static constructors in structs.
On Friday, 30 October 2015 at 20:59:46 UTC, Adam D. Ruppe wrote: On Friday, 30 October 2015 at 20:23:45 UTC, TheFlyingFiddle wrote: But yeah, the struct feature table http://dlang.org/struct.html shows them as checked. I gotta say the language documentation is shaping up nicely.
Static constructors in structs.
Is this intended to work? struct A { __gshared static this() { //Add some reflection info to some global stuff. addReflectionInfo!(typeof(this)); } } I just noticed this works in 2.069, is this intended? I mean I love it! It makes it possible to do lot's of useful mixins for runtime reflection for example. Just wondering if I can start writing code this way or if it's a regression and is going away. I think this did not work a year ago when I tried doing something like this.
Re: How can I distinguish an enum constant from an actual enum at compile time?
On Friday, 30 October 2015 at 11:46:43 UTC, TheFlyingFiddle wrote: I want to be able to do something like this: enum a = 32 enum b = { q,w,e,r,t,y } CtType ctype = getCtType!(a); // -> Would become CtType.enumConstant CtType ctype1 = getCtType!(b); // -> Would become CtType.enum_ Never mind if found out how: pragma(msg, is(b == enum)); //True pragma(msg, is(a == enum)); //False.
How can I distinguish an enum constant from an actual enum at compile time?
I want to be able to do something like this: enum a = 32 enum b = { q,w,e,r,t,y } CtType ctype = getCtType!(a); // -> Would become CtType.enumConstant CtType ctype1 = getCtType!(b); // -> Would become CtType.enum_
Re: What's in a empty class?
On Tuesday, 27 October 2015 at 21:28:31 UTC, Adam D. Ruppe wrote: On Tuesday, 27 October 2015 at 21:23:45 UTC, TheFlyingFiddle wrote: I can account for the first thing a vtable. But that should only cover 4bytes. What's in the other 4bytes? The monitor used for `synchronized`. (yes, this is something a lot of people want to remove as it is rarely all that useful yet you pay the price in all D class objects) I see Thanks.
What's in a empty class?
With this code: class A { } pragma(msg, __traits(classInstanceSize, A)); I get the output 8 (32-bit). I can account for the first thing a vtable. But that should only cover 4bytes. What's in the other 4bytes?
Re: Array of templated classes or structs
On Saturday, 24 October 2015 at 19:00:57 UTC, TheFlyingFiddle wrote: One thing about variant is that if the struct you are trying to insert is larger then (void delegate()).sizeof it will allocate the wrapped type on the gc heap. This is not a concern if you want to have class templates as they are on the heap anyways and have a fixed size.
Re: Array of templated classes or structs
On Saturday, 24 October 2015 at 18:40:02 UTC, TheFlyingFiddle wrote: To complete TemplateStruct simply forward the remaing members of the variant. Or use something like proxy!T in std.typecons. Or use an alias this v. (I don't really recommend alias this it has all kinds of problems) One thing about variant is that if the struct you are trying to insert is larger then (void delegate()).sizeof it will allocate the wrapped type on the gc heap. This might be detrimental to performance. So to help with this you could add an extra element on the TemplateStruct to sort of handle this. struct TemplateStruct(alias template_, size_t size = (void delegate).sizeof) { VariantN!(size) v; //Rest is the same. } Pick a good size for the template you want to make arrays of and it will lessen the stress on the gc heap. For example: struct vec4(T) { T[4] data; //stuff } alias Vector4 = TemplateStruct!(template_, vec4!(double).sizeof); Vector4[] array; Additionaly you might want to look into the (http://forum.dlang.org/thread/jiucsrcvkfdzwinqp...@forum.dlang.org) if your interested in some cool stuff that can be done to call methods on such variant structs.
Re: Array of templated classes or structs
On Saturday, 24 October 2015 at 18:29:08 UTC, TheFlyingFiddle wrote: Variant[] array; array ~= S!int(...); array ~= S!double(...); array ~= S!long(...); array ~= "I am a string!"; And this is probably not what you want. You can do this if you want to ensure that items stored in the variant are of a specific template struct/class. import std.traits, std.variant; struct TemplateStruct(alias template_) { private Varint v; void opAssign(TemplateStruct!template_ other) { this.v = other.v; } void opAssing(T)(T t) if(isInstanceOf!(template_, T)) { this.v = t; } T* peek(T) { return v.peek!T; } auto visit(Handlers...) { return v.visit!handler; } //More variant stuff here. } This should work: (untested) TemplateStruct!(S)[] array; array ~= S!int(...); array ~= S!long(...); array ~= S!double(...); array ~= "I am a string!"; //This line should issue a compiler error. To complete TemplateStruct simply forward the remaing members of the variant. Or use something like proxy!T in std.typecons. Or use an alias this v. (I don't really recommend alias this it has all kinds of problems)
Re: Array of templated classes or structs
On Saturday, 24 October 2015 at 15:57:09 UTC, Dandyvica wrote: Hi guys, Apart from deriving from the same class and declaring an array of that root class, is there a way to create an array of templates? This seems not possible since template are compile-time generated, but just to be sure. For example, it seems logical to get an array of complex numbers but Complex needs to be declared with a type. Thanks for any hint. Structs or classes that are templated will create new types each time they are instantiated. struct S(T) { /*stuff*/ } static assert(!is(S!int == S!double)); So you can create arrays of: S!int[] a; or S!double[] b; But you can't really create arrays of S!(int or double)[]. However it can be sort of done by using a variant(taged union). import std.variant; alias SIntOrDouble = Algebraic!(S!int, S!double); SIntOrDouble[] array; array ~= S!int(...); array ~= S!double(...); Now the array holds two items an S!int for the first item and an S!double for the second. You can use it like this. foreach(ref elem; array) { if(auto p = elem.peek!(S!int)) { //Do stuff with an S!int item } else if(auto p = elem.peek!(S!double)) { //Do stuff with an S!double. } } Or like this: foreach(ref elem; array) { elem.visit!( (S!int i) => /*something with ints*/, (S!double d) => /*something with doubles*/ ); } Take a look at std.variant if you are interested. A drawback to the Algebraic is that you must know all the different template instantiations that you will be using. If you don't know this I suggest you use a variant instead. The line: SIntOrDouble[] array; changes to Variant[] array; With this you can hold anything in the array. This is both an advantage and a drawback, the advantage is that you can just add more templpate instantiations to the program as is evolves. But you lose static typing information so the compiler will not be able to help you anymore. For example this would be valid: Variant[] array; array ~= S!int(...); array ~= S!double(...); array ~= S!long(...); array ~= "I am a string!"; And this is probably not what you want.
Re: D serialization temporary fixup?
On Thursday, 22 October 2015 at 16:15:23 UTC, Shriramana Sharma wrote: I wanted a D equivalent to: http://doc.qt.io/qt-5/qdatastream.html https://docs.python.org/3/library/pickle.html and saw that one is under construction: http://wiki.dlang.org/Review/std.serialization But till it's finalized, I'd just like to have a quick but reliable way to store real and int data types into a binary data file and read therefrom. Is there such a solution? The size of the data is fixed, but especially since I have real values, I'd like to not write to limited fixed decimal text format. If your only interested in POD data something like this should do the trick. module pod_encoding; import std.traits; import std.stdio; void encode(T)(string s, T[] t) if(!hasIndirections!T && (is(T == struct) || isNumeric!T)) { File(s, "wb").rawWrite(t); } T[] decode(T)(string s) if(!hasIndirections!T && (is(T == struct) || isNumeric!T)) { File f = File(s, "rb"); assert(f.size % T.sizeof == 0, "File does not contain array of " ~ T.stringof ~ "."); auto size = f.size / U.sizeof; auto data = new T[size]; data = f.rawRead(data); return data; }
Re: Ternary if and ~ does not work quite well
On Monday, 12 October 2015 at 05:19:40 UTC, Andre wrote: Hi, writeln("foo "~ true ? "bar" : "baz"); André "foo" ~ true How does this compile? All i can see is a user trying to append a boolean to a string which is obvously a type error. Or are they converted to ints and then ~ would be a complement operator? In that case.. horror.
Re: Degenerate Regex Case
On Friday, 24 April 2015 at 18:28:16 UTC, Guillaume wrote: Hello, I'm trying to make a regex comparison with D, based off of this article: https://swtch.com/~rsc/regexp/regexp1.html I've written my code like so: import std.stdio, std.regex; void main(string argv[]) { string m = argv[1]; auto p = ctRegex!("a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaa"); if (match(m, p)) { writeln("match"); } else { writeln("no match"); } } And the compiler goes into swap. Doing it at runtime is no better. I was under the impression that this particular regex was used for showcasing the Thompson NFA which D claims to be using. The regex "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaa" can be simplified to "a{30,60}" (if i counted correctly). The regex "a{30,60}" works fine. [Speculation] I don't have a good understanding of how D's regex engine work but I am guessing that it does not do any simplification of the regex input causing it to generate larger engines for each additional ? symbol. Thus needing more memory. Eventually as in this case the compiler runs out of memory.
Re: How can I do that in @nogc?
On Wednesday, 25 February 2015 at 19:32:50 UTC, Namespace wrote: How can I specify that 'func' is @nogc? Or can define the function otherwise? An alternative solution would be to use function templated on an alias. import std.traits; void glCheck(alias func)(string file = __FILE__, size_t line = __LINE__) @nogc if(isCallable!func) { func(); glCheckError(file, line); } void foo() { new int(5); } //Uses GC void bar() @nogc { /* ... */ } //Does not use GC unittest { //Calling is a little different glCheck!foo; //Does not compile not @nogc glCheck!bar; //Works like a charm. } //If you wanted to take arguments to func //it can be done like this. void glCheck(alias func, string file = __FILE__, size_t line = __LINE__, Args...)(auto ref Args args) @nogc if(isCallable!func) { func(args); glCheckError(file, line); } void buz(string a, uint b, float c) @nogc { /* ... */ } unittest { //Calling looks like this. glCheck!buz("foobar", 0xBAADF00D, 42.0f); }
Re: Map one tuple to another Tuple of different type
On Monday, 21 July 2014 at 01:42:58 UTC, Daniel Gibson wrote: Am 21.07.2014 03:34, schrieb Vlad Levenfeld: To get a foreach to run at compile-time, you have to give it something whose value is known to the compiler (so, T and typeof(argTuple) would suffice, and 0..T.length really should as well). Yup I use this when i want a compile time foreach(from a constant number). It's slightly longer but has worked great for me thus far. template staticIota(size_t s, size_t e, size_t step = 1) { import std.typetuple : TypeTuple; static if(s < e) alias staticIota = TypeTuple!(s, staticIota!(s + step, e)); else alias staticIota = TypeTuple!(); } usage: unittest { foreach(i; staticIota!(0, 10)) { pragma(msg, i); } } //Outputs 1 to 10 at compile-time.
Re: Map one tuple to another Tuple of different type
On Monday, 21 July 2014 at 15:04:14 UTC, TheFlyingFiddle wrote: //Outputs 1 to 10 at compile-time. Edit: 0 to 9
Re: Map one tuple to another Tuple of different type
On Monday, 21 July 2014 at 15:04:14 UTC, TheFlyingFiddle wrote: template staticIota(size_t s, size_t e, size_t step = 1) { import std.typetuple : TypeTuple; static if(s < e) alias staticIota = TypeTuple!(s, staticIota!(s + step, e, step)); else alias staticIota = TypeTuple!(); } Edit: Missed the second step.
Re: How to define and use a custom comparison function
On Tuesday, 17 June 2014 at 07:53:51 UTC, monarch_dodra wrote: On Tuesday, 17 June 2014 at 04:32:20 UTC, Jakob Ovrum wrote: On Monday, 16 June 2014 at 20:49:29 UTC, monarch_dodra wrote: MyCompare cmp(SortOrder.ASC, 10); This syntax is not valid D. It should be: auto cmp = MyCompare(SortOrder,ASC, 10); Well, techincally, the *syntax* is valid. If "MyCompare" contains a constructor, it's legit code to boot. It's part of the uniform initialization syntax, and it's what allows things like: BigInt b = 5; or BigInt b(5); THAT said, yeah, the MyCompare I posted did not contain a constructor. SO my code was wrong, guilty as charged. Since when is that syntax valid? Is there somewhere it is documented?
Re: Library design
On Friday, 13 June 2014 at 04:11:38 UTC, Rutger wrote: I'm trying to create a minimal tweening library in D based on the commonly used easing equations by Robert Penner (http://www.robertpenner.com/easing/). One of the goals with the design of the library is that any numeric type should be tweenable.(The user of the library shouldn't have to do any casting of their own etc) Now how do I go about and design a data structure that can take either floats, ints or doubles, store them and modify them? This is what I hacked together earlier today: abstract class TweenWrapper{ } class Tween(T) : TweenWrapper{ T owner; string[] members; /** Duration in milliseconds */ int duration; /** Elapsed time in milliseconds */ int elapsedTime; bool isComplete; /** Type of easing */ EasingType easingType; } TweenWrapper is just what it sounds like, a wrapper so I don't have to specify any type for the container holding the Tween objects(DList!TweenWrapper). __traits(getMember, owner, members[0]) = valueReturnedFromEasingFunction; Was How I planned to use this class.. but you know, compile time only. Let me know if this isn't enough to go on. Is what I'm asking even possible(the easy way) in D? TL;DR Help me make D Dynamic! From what i can tell you want something similar to this. interface ITween { void update(int elapsedTime); } class Tween(T, string member) : ITween { //Expands to //|alias memberType = typeof(T.memberName);| mixin("alias memberType = typeof(" ~ T.stringof ~ "." ~ member ~ ");"); memberType from; memberType to; EasingType type; int duration; int elapsedTime; T owner; @property bool isComplete() { return elapsedTime >= duration; } void update(int time) { elapsedTime = min(elapsedTime + time, duration); double amount = elapsedTime / cast(double)duration; auto tweened = ease(type, from, to, amount); __traits(getMember, owner, member) = tweened; } } Where ease is a method that will look something like this: T ease(T)(EasingType type, T from, T to, double amount) if(isNumeric!T) { double result; if(type == EasingType.linear) result = linearEase(amount); else assert(0, "Not yet implemented"); return cast(T)((to - from) * result + from)); } double linearEase(double amount) { return amount; } This will work for all number types. Hope this was helpful.
Re: Cost of .dup vs. instantiation
On Wednesday, 28 May 2014 at 14:36:25 UTC, Chris wrote: I use Appender to fill an array. The Appender is a class variable and is not instantiated with each function call to save instantiation. However, the return value or the function must be dup'ed, like so: Appender!(MyType[]) append; public auto doSomething() { scope (exit) { // clear append } // ... do something append ~= item; return (append.data).dup } My question is whether I save anything with Appender as a class variable here. I have to .dup the return value (+ clear the Appender). If I had a new Appender with each function call, it might be just as good. public auto doSomething() { Appender!(MyType[]) append; // return append.data. } Right or wrong? When it comes to optimizations it's hard to say. Benchmarking is better than relying advice/opinions on the internet in any case. That being said i doubt that the instantiation cost of the Appender is relevant. (Btw the appender is not a class variable! It is a struct with reference semantics). Reusing an appender is more for those cases where you want to reuse the underlying memory of the appender itself.
Re: core.sync.rwmutex example
On Friday, 9 May 2014 at 23:12:44 UTC, Charles Hixson via Digitalmars-d-learn wrote: But I'm worried about the receiving end. It needs, somehow, to ensure that the message it receives is the appropriate message, and that other messages don't get dropped while it's waiting for the answer...or, perhaps worse, substituted for the expected answer. If I can depend on msg[0] of "auto msg = receiveOnly!(Tid, bool)" that will allow me to check that the message was received from the proper source If you are worried that other messages having the same signature will be sent from other sources than the expected source you could make use of message tagging. Simply wrap the boolean result in a struct with a descriptive name. struct SharedHashMapSetCB { bool flag; } void set (string s, uint64_t id) { tbl[s] = id; send (SharedHashMapSetCB(true)); } //On the receiving end auto msg = receiveOnly!SharedHashMapSetCB(); But doesn't this design lock the entire hash-table while the update is in progress? Is there a better way? I think a shared memory hash-map is better for your use case. Working with message passing is preferable done asynchronously. Blocking calls (send followed by receive) is likely to be slower then simply waiting on a semaphore.
Re: string mixin only works once per block?
On Friday, 11 April 2014 at 18:46:12 UTC, Vlad Levenfeld wrote: Corrections and suggestions welcome! I would not recommend using string attributes since it's easy to misspell them, it would be better to use a struct tag or simply make a uniform type since the compiler will help you out if you miss something. //Struct tag struct Uniform { } @Uniform GLint start_color; instead of @("uniform") GLint start_color; // Even better using uniform as a type struct Uniform(T) { T value; GLint location; } Uniform!vec4 start_color; For a next step i would recommend that you do some validation as part of the linking process. After you have found the location of the uniform simply use the opengl query functions to get the type of the uniform and do type-checking agains the client uniform type. If you want to take it even further you could automate the opengl setup step. (Templates are freeking awesome) //U == Uniform Type V == vertex type (used for validation). struct ShaderProgram(U,V) { GLint[U.tupleof.length] uniformLocations; //Locations of all the uniforms in the same order as they appear in the U struct. U uniforms; //All the uniforms that exists in the shader. GLint glName; //gl id this(string geometrySource, string vertSource, string fragSource) { //Compile shaders link program. //Find uniforms locations by looking at fileds in U and do some validation //on these. //Find all vertex input attributes and do validation against fields in V } void use() { //Call glUseProgram(glName); //Go through all the fields in //uniformValues and set them with //glUniform* //Locations are stored in locations array. } //More methods for validation or other convinience things. } An example useage of this system. (I assume some sort of particle system) struct Particle { vec2 velocity; vec2 position; float spawnTime; } struct ParticleUniforms { mat4 projection; Color startColor; Color endColor; vec2 startSize; vec2 endSize; float particleLifeTime; float currentTime; } ShaderProgram!(Particle, ParticleUniforms) program; void setup() { //Initialize the program with the given shaders //If we get passed this line we can be sure that the //program is actually functional! program = ShaderProgram!(Particle, ParticleUniforms) (gShader, vShader, fShader); //Set initial values for all the uniforms in the program. program.uniforms.startColor = Color.red; program.uniforms.endColor = Color.green; etc... } void render(Time time) { //Update interesting uniforms program.uniform.currentTime += time.delta; program.use(); //glUseProgram //Now we have a program that is usable and ensured to be valid. //(If it works like intended is subject to the shaders ^^) } I am currently using something similar to this and it has made compability debugging virtually nonexistant. It also leaves the amount of boilerplate to a minimum. (It can be extended even further to validate correct setup of various buffers, vertex array objects and most other opengl related stuff) One last thing: The following will make debugging opengl easier. struct gl { static auto ref opDispatch(string name, Args...)(Args args) { enum glName = "gl" ~ name[0].toUpper.to!string ~ name[1 .. $]; debug scope(exit) checkGLError(name, args) mixin("return " ~ glName ~ "(args);"); } } Now instead of calling opengl methods like this: glUniform* glBindTexture* etc Call them like this. gl.uniform* gl.bindTexture* etc This will automagically add a glGetError() after every call in debugmode. No more adding glGetError manually! I feel i went of topic. I hope this was usefull to you.
Re: Non-Initialized Dynamic Arrays Construction
On Monday, 24 February 2014 at 13:08:52 UTC, Mengu wrote: On Monday, 24 February 2014 at 11:29:39 UTC, bearophile wrote: TheFlyingFiddle: http://dlang.org/phobos/std_array.html#.uninitializedArray is what you want. The OP wants minimallyInitializedArray. uninitializedArray is only for special situations. Perhaps we have to fix the online docs to underline this. Bye, bearophile what's the difference? Well for anything that does not have indirections eg numbers / chars and structs without classes/arrays/pointers in them. Then the two functions are equivalent. So: int[] first = uninitializedArray!(int[])(n); int[] second = minimallyInitializedArray!(int[])(n); Both first and second contain garbaged values. int*[] third = uninitializedArray!(int*[])(n); int*[] forth = minimallyInitializedArray!(int*[])(n); The third array contains garbage but all elements in forth are initialized to null. I assume this behavior is this way since an int with a garbage value is not as bad as a garbage pointer dereference into memory. The OP wants minimallyInitializedArray. uninitializedArray is only for special situations. True but uninitializedArray corresponds to = void semantics for all arrays. minimallyInitializedArray is safer though so i guess it should be used. Wouldn't it be nice to have some kind of syntactic sugar for this similar to what we have for static arrays? BTW: Why isn't simply the following allowed? int n = 3; int[n] = void; Is it too easy to confuse with static array syntax? I don't like this, since it would be wierd from an allocation view point. How is int[n] allocated? Is it the GC? Is it alloca? Can i overide the allocation mechanism? Does the allocated array behave the same as a static array? (it gets destroyed if it goes out of scope) I think it gets a little confusing and also personally i don't want more hidden memory allocations. We already have alot of those.
Re: Non-Initialized Dynamic Arrays Construction
On Monday, 24 February 2014 at 11:11:44 UTC, Nordlöw wrote: Is it possible void construct a dynamic array such as b in int n = 3; auto b = new float[n]; similar to what we do with static arrays as in int[3] c = void; http://dlang.org/phobos/std_array.html#.uninitializedArray is what you want.
Re: loop over all parameters of all overloads of all members
On Sunday, 23 February 2014 at 21:08:48 UTC, Frustrated wrote: The following code craps out on the inner for each foreach (am; __traits(derivedMembers, B)) foreach (m; [__traits(getOverloads, B, am)]) { } So how can I loop over all the parameters of all the overloads of all the members of a class? Create some weird mapping tuple? Here's an example of how to loop over all paremters of all the methods in a class T and print the functions with arguments. import std.typetuple, std.traits; class B { void b() { } void b(int i) { } void b(int i, long l) { } } string signatureString(alias func)() { alias pt = ParameterTypeTuple!func; alias pi = ParameterIdentifierTuple!func; alias rt = ReturnType!func; enum name = __traits(identifier, func); enum stat = __traits(isStaticFunction, func) ? "static " : ""; string s = stat ~ rt.stringof ~ " " ~ name ~ "("; foreach(i, dummy; pt) { s ~= pt[i].stringof ~ " " ~ pi[i]; static if(i != pt.length - 1) s ~= ","; } s ~= ")"; return s; } void ctPrintClassFunctions(T)() { foreach(member; __traits(allMembers, T)) { static if(__traits(compiles, __traits(getOverloads, T.init, member))) { alias Overloads = TypeTuple!(__traits(getOverloads, T.init, member)); foreach(overload; Overloads) { pragma(msg, signatureString!overload); } } } } void main() { ctPrintClassFunctions!B; } I guess we are not going to get a static foreach any time soon? Every foreach in the example is a "static" foreach in the sense that it unrolls the loops and evaluates them at compiletime.
Re: How can i find my LAN IP Address using std.socket?
On Tuesday, 4 February 2014 at 13:24:59 UTC, Dicebot wrote: On Tuesday, 4 February 2014 at 13:21:54 UTC, Stanislav Blinov wrote: Worth noting that this solution is not reliable in general either because your server can possibly have complicated routing configurations that will make, for example, LAN destination packets go via different network interface than WAN destination ones. It is probably better to tell what high-level problem you are trying to solve to find most useful compromise. I'm setting up a simple local network enabling me to connect phones to the computer through the local wi-fi. The simplest way i could think of to make this work without relying on an external server was to simply broadcast the ip and port to all machines in the network.(Btw by server i mean my / my project groups windows boxes). So well the problem is that i need a way for the phones to find running servers on the LAN.
Re: How can i find my LAN IP Address using std.socket?
On Tuesday, 4 February 2014 at 13:21:54 UTC, Stanislav Blinov wrote: On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle wrote: I'm trying to find my own ip address using std.socket with little success. How would i go about doing this? (It should be a AddressFamily.INET socket) Create a connection to another LAN machine with a known address (e.g. gateway or router), then use Socket's localAddress property to get your IP. You cannot really do that before establishing a connection, as Dicebot already mentioned. Problem is that i don't know in what local network the server will be running, so this is unfortunatly not an option for me.
Re: How can i find my LAN IP Address using std.socket?
On Tuesday, 4 February 2014 at 13:13:07 UTC, Dicebot wrote: On Tuesday, 4 February 2014 at 13:02:26 UTC, TheFlyingFiddle wrote: I'm trying to find my own ip address using std.socket with little success. How would i go about doing this? (It should be a AddressFamily.INET socket) You can have lot of different local IP addresses on a single machine so question can't be answered properly. However you may use in `Socket.hostName` and resolve it via DNS to find IP machine itself currently consuders as its main pulbic IP. This works great thanks. I just need any (working) local IP address so getting more then one is not an issue for me.
How can i find my LAN IP Address using std.socket?
I'm trying to find my own ip address using std.socket with little success. How would i go about doing this? (It should be a AddressFamily.INET socket)
Re: Templates: generic "return null;"
On Monday, 3 February 2014 at 10:25:19 UTC, Chris wrote: Is there a way I can make the return type in getAttribute generic? null does not work with numbers. MyStruct(T) { T[T] attributes; // public auto getAttribute(T attr) { if (!(attr in attributes)) { return null; // Doesn't work for numbers! } return attributes[attr]; } } void main() { auto myStr = MyStruct!int(0); // Error } Whenever i am faced with this situation i do one (or more then one) of the following things. struct MyStruct(T) { T[T] attributes; //(1) Forward the underlying access method Eg: auto opBinaryRight(string s : "in")(T attrib) { return attrib in attributes; } //(2) make a try method. bool tryAttrib(T attrib, out T outAttrib) { auto p = attrib in attributes; if(p) outAttrib = *p; return p !is null; } //(3) Give user option to set default value. T attribOrDefault(T attrib, T default) { auto p = attrib im attributes; return p is null ? default : attrib; } //(4) Use Nullable!T (I prefer #5 over this one) Nullable!T attribOrNull(T attrib) { Nullable!T result; auto p = attrib ib attributes; if(p) result = *p; return result; } //(5) Use a pointer but not forward in operator. T* attribPtr(T attrib) { return attrib in attributes; } //(6) Throw exception (I only do this in combination with one of the above) T attribEx(T attrib) { return *enforce!AttribNotFoundEx(attrib in attributes); } } My personal preference using #2 and #3 in combination. #2 covers the basic case "Is this thing avalible?" and #3 covers the case "Give it to me if it is avalible or use this default value" I think it gives a clear image of what your code is doing at the callsite. Only using #2 or #3 limits you in this sence. For #1, #4 and #5 i personally stay away from them. They force the caller to either use an if or potentially trigger a null pointer derecerence. (Btw what is the benefit of #4? I have never used it since it seems pointless) I very rarly use attribEx. I don't think code shuld just spew exceptions all over the place. They should be reserved for really bad stuff, like bounds checks. One exception i make to this rule is if i'm dealing with ranges. Since the other methods don't lend themselfs for UFCS-chaing.
@trusted delegates all over std.array
Why is std.array litered with @trusted delegates? Ex: in the clear method in Appender. void clear() @safe pure nothrow { if(_data) { _data.arr = ()@trusted { return _data.arr.ptr[0 .. 0]; }(); } } Is it to enable @safe? And should it be allowed i mean the code does deal with pointers so it really should be made @trusted? Or is the reasoning that as much of the standard library should be @safe as possible so some small hacks are ok?
Re: std.typecons wrap interface with NVI
On Sunday, 2 February 2014 at 01:19:22 UTC, Matthew Dudley wrote: This is the general outline of what I'm trying to do: import std.typecons; //wrap import std.stdio; interface FooBar { public: void foo(); void bar(); final void both() // NVI { foo(); bar(); } } class Baz { public: void foo() { writeln("foo"); } void bar() { writeln("bar"); } } void main() { auto baz = new Baz(); auto foobar = baz.wrap!(FooBar)(); // causes this wall-o-text error -- http://pastebin.com/Pa5dHQtN // Which at the end says: // /usr/local/Cellar/dmd/2.064.2/import/std/typecons.d(2779): Error: static assert "Source Baz does not have structural conformance to (FooBar)" } I'm still learning D, but this seems like it should work. If I explicitly implement FooBar in Baz, everything's groovy, but this isn't. Is this a bug in wrap or am I misunderstanding the intention of wrap or NVI? You are getting the point of NVI i think, that part is correct. I don't know why NVI dosn't work together with wrapping but i would assume it is a bug. Conseptually NVI does not change the behavior of the wrapped object so it shouldn't be a problem. (Abstract classes are a problem here though see below). As far as wrap goes i am not sure what the intention behind it is. It would be a cool feature if it allowed wrapping of structs but... it dosn't. It could have some use in avoiding the need of writing adapter classes for code you can't change but other then that it should imho be avoided. Templates and interface inheritance in general makes the feature unessasary. Also as a side note, if I use an abstract class instead of an interface, things explode in similarly large wall-o-text fashion. Is there a reason for abstract classes aren't or can't be used for wrap? class FooBar { abstract void foo(); void bar() { writeln("Hello from FooBar.bar"); } } class Baz { void foo() { writeln("Hello from Baz.foo"); } voir bar() { writeln("Hello from Baz.bar"); } } void main() { auto baz = new Baz(); baz.bar(); auto wrapped = baz.wrap!(FooBar); wrapped.bar(); //Which bar should be called? } Wrapping a type into an interface should not change the behaviour of the wrapped types operations. In the example above what would the wrapped.bar() call do? Would it call bar in FooBar? or bar in Baz? maby both? There is no clear defined rule of what to do here. I'm guessing this is why they decided to not support implementation wrapping. (Note it could have been defined but it's not.) Also wrapping does try to simulate how Go does duck typing and there is no inheritance there so i'm guessing that was a factor in the design.
Re: Implicit conversion from a base/array type
On Saturday, 1 February 2014 at 20:26:27 UTC, alexhairyman wrote: Is there a way to implicitly convert *FROM* a base type? I have an implicit conversion to a base type (float[2]) in a struct, but now I'd like to be able to implicitly convert from a base type (in this case a float[2]) to a struct. Is this even allowed? Is it incorrect or unsafe? I'm still pretty new so there could be a major reason to not want to do this. I also did a lot of searching of the site, I hope I didn't miss something major, but I might have. example : struct Coord {...} // X,Y wrapper-like type, implicitly converts to/from float void DoCoord(Coordinate c) {... do stuff...} void main() { DoCoord ([0.0f, 5.0f]); // Is it possible to set this up? } D currencly has no implicit casting operator overloading. It has been proposed before in http://wiki.dlang.org/DIP52 but i am not sure what the state of that is as of now.
Re: Parallel thread safety (fun fun)
On Friday, 31 January 2014 at 21:33:50 UTC, Mineko wrote: So, I'm implementing some parallelism in my engine (maybe some concurrency where appropriate later), and I'm having some issues with thread safety, and synchronize ain't cutting it. What I figure is that if I can get the IO class working within a parallel thread then everything else should fall in place, so, I need some help making the IO class thread-safe. (I'm new to thread safety btw, like, yesterday new >_>) Relevent file here: https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/utility/io.d Feel free to drop any other suggestions on what to do with that class if you want, always appreciated. :) First of all you are using the synchronized statement incorrecly. synchronized bool addTime; <-- This does absolutely nothing. I am supprised this code is allowed. You can only use synchronized on class methods http://dlang.org/class.html#synchronized-functions or on an abitrary block of code http://dlang.org/statement.html#SynchronizedStatement If you want to synchronize access to data you will have to either make them shared and use synchronized/atomic operations on them or synchronize the use yourself. This is a quite complex and bugprone activity and if your just getting started i would not reccomend it. There is a simpler / better way that i will describe later. Secondly the only use of concurency that i see in the IO class is the attempt to write to a file from multiple threads. In the write() method. This is not a good idea. Firstly you will not be able to write any faster to the file since it's IO bound in any case. The only effect if any is that you will use more resources and that the output will appear in the file in random order. (Probably not what you want) I would reccomend using message passing instead of even attempting to synchronize things. This is ALOT simpler and if your goal is to offload IO to another thread it's the way to go IMHO. Here is a very simple logging application that writes to a file using std.concurrency through message passing. To make things simple it can only log messages from the thread that started it. This would probably be the main thread in a game. module main; import logger; void main() { startLoggerThread("log.txt"); log("Hello"); log("World"); stopLoggerThread(); } //logger.d module logger; import std.concurrency; import std.file; //This is a unique identifier for a thread. Tid loggerTid; //Starts the logger thread. //(This must be done before any logging can take place.) void startLoggerThread(string logFile) { loggerTid = spawn(&loggerEntry, logFile); } //Stops the logger thread. void stopLoggerThread() { send(loggerTid, Shutdown()); } //Called by the thread that started the logger. void log(string msg) { //Send the message to log to the logger thread //identified by the loggerTid. send(loggerTid, msg); } //A tag struct symbolising the message shutdown. struct Shutdown { } void loggerEntry(string logFile) { bool running = true; //Recevie logging requests until stopLoggerThread is called. while(running) { receive( //We get a message here when log is called. (string msg) { //Create file if it does not already exists //otherwise append to it. if(!exists(logFile)) write(logFile, msg ~ "\n"); else append(logFile, msg ~ "\n"); }, //If we get this message we stop the logger thread. (Shutdown _) { running = false; }); } } The example works by first creating a logging thread. This thread then listens to logging requests from the main thread. And logs all messages it receives. I would reccomend reading the TDPL chapter on concurrency if you want to learn more. //Hope this was all helpful
Re: Interfaces allow member definitions?
On Thursday, 30 January 2014 at 13:43:49 UTC, Casper Færgemand wrote: Compiling with DMD 2.064, I am NOT able to get any function in interfaces accepted unless they are final. This means you cannot provide default behavior in the interface, at least not in the ways shown above. Yes the void baz() method is incorrect. The rest should be fine though.
Re: Interfaces allow member definitions?
On Thursday, 30 January 2014 at 11:19:58 UTC, Frustrated wrote: I was, I think, able to call an interface's method. I had the code like the following interface A { void foo(); } class B : A { void foo() { writeln("Hey"); } } class C : A { void foo() { writeln("You"); } } yet, when I called a.foo(); I did not get any output. (A being of type A) Now, I was doing some weird stuff but either in the vtable for A, there are empty functions that do nothing or I just happen to call bogus memory that did not throw an exception. The real question is, do interface methods actually support function definitions? Is there anything that stops us from actually doing interface A { void foo() { writeln("What up!!"); } } internally? I know member functions require a this but in this case foo does not require this so it any this would work. Basically, does the vtable contain storage for the interface's members but blocks us from using them due to the issue with this? If so, then shouldn't we be able to create functions in an interface as long as they do not reference this? (basically static functions that can be overriden as dynamic functions in the class) e.g., interface A { // default behavior for foo and bar void foo() { writeln("asdasdfasdfasdf"); } void bar() { writeln("1234"); } } class B : A { void foo() { writeln("help"); } } void main() { A a = new B; a.foo(); // prints help a.bar(); // prints 1234 B b = new B; b.foo(); // prints help b.bar(); // prints 1234 } This would allow one to sort of add default behavior to an interface(limited since no fields could be used but properties help with it). basically the vtable just needs an extra spot for the interface methods and calls them with null or the object it contains for this... which doesn't matter since this is never used in the body of the function. You can already do this using the Non-virtual interface ideom interface Foo { final void bar() { writeln("Something"); } void baz() { writeln("Something Else"); } } Note the final keyword it is imortant here. This will make bar simply be a non-virutal method in Foo. If you want to provide some basic implementation but still forward to a base class you can do something like this. interface Foo2 { final void bar(uint i) { // Does some basic stuff here. bar_impl(i); } protected void bar_impl(uint i); } class A : Foo2 { protected void bar_impl(uint i) { //Do some specific stuff here. } } This pattern allows you to do some basic stuff in bar and more specialized stuff in bar_impl. It does require that you overload bar_impl though which may not be what you want.
Re: Good ol' OpenGL D-C interfacing. :(
On Saturday, 25 January 2014 at 23:28:07 UTC, Mineko wrote: Alright.. For the record, I've been searching on how to fix this for 2 hours now, so yeah. Anyway, here's the issue, and it's probably half OpenGL being well.. OpenGL, and the other half being D-C interfacing. Point is, I'm trying to draw a triangle with a custom Triangle class I made, and I'm having issues, relevant code is here: https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/scene.d https://github.com/MinekoRox/Breaker-Engine/blob/master/src/breaker/utility/graphics/primitives.d https://github.com/MinekoRox/Breaker-Engine/blob/master/res/shaders/testShader.glsl I assume this is probably me messing up with arrays and sizing, but I've done what I can as far as that goes so.. Maybe one of you know what to do. Your init and finalize methods in primitives.d does not work. You need to send the vao, points_vbo and colors_vbo by ref.
Re: [Windows & DMD] No callstack when crash with Access violation reading location 0x00000000
On Saturday, 18 January 2014 at 19:40:38 UTC, Xavier Bigand wrote: I am not sure the issue come really from my code, cause it just works fine on ATI cards, I do something Nvidia drivers dislike. I tried to replace GL_LINE_LOOP by triangles, increase buffer size, put the GL_ELEMENT_ARRAY_BUFFER buffer type bind right before glDrawElements without success. Crash only append when I fill text mesh before those ones. So I need dig more. From what i saw in your code you are not using Vertex Array Objects. I have had similar problems that code ran fine on ATI but crashed on nvidia. The problem went away for me when i just created and bound a global VAO just after context creation. Also i would recommend calling glGetError after every call, it helps finding errors. Here is a simple trick to do this automatically. static gl { static ref auto opDispatch(string name, Args...)(Args args) { enum glName = "gl" ~ name[0].toUpper.to!string ~ name[1 .. $]; debug scope(exit) checkGLError(); //Do glGetError and log it or something. mixin("return " ~ glName ~ "(args);"); } } After this simply change all glFunctionName(args) to gl.functionName or gl.functionName.
Re: std.algorithm for changing array values
On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote: Hi, I checked std.algorithm but have no glue which functions I can use to rewrite following code with some nice algorithm functions. I have an array of structs. I want to check for a specific key and if found I change the value. If it is not found I add the entry. Kind regards André struct Data{ int key; int value; } void main(){ Data[] entries = [Data(1,1),Data(2,2)]; bool found; foreach(entry;entries){ if (entry.key == 3){ entry.value = 42; found = true; } } if (found == false){ entries ~= Data(3,42); } } You can use canFind. import std.algorithm; struct Data{ int key; int value; } void main() { auto entries = [Data(1,1),Data(2,2)]; if(!entries.canFind!(x => x.key == 3)) entries ~= Data(3, 42); }
Re: Why is string.front dchar?
On Tuesday, 14 January 2014 at 01:12:40 UTC, bearophile wrote: TheFlyingFiddle: But for backwards compatibility reasons in this code: foreach (c; "somestring") c is a char, not a dchar. You have to type it explicitly to handle the UTF safely: foreach (dchar c; "somestring") This is why i was confused really since the normal foreach is char it's weird that string.front is not a char. But if foreach being a char is only the way it is for legacy reasons it all makes sense.
Re: Shared library string safety?
On Tuesday, 14 January 2014 at 07:44:21 UTC, Mineko wrote: I see, I'll have to look more into that, on a slightly unrelated note, any idea what's going on with glfwCreateWindow, it keeps wanting to be null while it's supposed to be an adddress. this.get = glfwCreateWindow(settings.width, settings.height, toStringz(settings.title), this.monitor, this.share); writeln(this.get); glfwCreateWindow returns a null ptr if something is wrong with it's parameters or os driver or anything it can detect really. To get error information you can use glfwSetErrorCallback with a custom function and handle the errors with it. Something like this: extern(C) void errorFunc(int error_code, const(char)* errorMessage) { //Do something here like wrilteln. } void main() { //Load libs and setup stuff. glfwSetErrorCallback(&errorFunc); //Now anything that gives an error will forward it to //errorFunc. } That writeln will give me null, is it related to all this stuff? I doubt it.
Why is string.front dchar?
I'm curious, why is the .front property of narrow strings of type dchar? And not the underlying character type for the string.
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? Well something like this. struct MyString { string value; alias value this; auto opBinary(string op)(string rhs) if( op == "^" ) { string result; foreach(i; 0 .. min(value.length, rhs.length)) result ~= value[i] ^ rhs[i]; return MyString(result); } } auto mstr(string s) { return MyString(s); } auto s = "Hello"; auto s2 = "World"; auto res = s.mstr ^ s2; or string res = s.mstr ^ s2; //If you want the result to be a string. While this works it's not that much better then the simple: auto s = "Hello"; auto s2 = "World"; auto res = s.xor(s2); It seems I can't even inherit from string. In D a string is not a class its just an immutable array (slice) of char. alias string = immutable(char[]);
Re: How do I choose the correct primative?
On Monday, 6 January 2014 at 20:08:27 UTC, Jake Thomas wrote: Things like Object.factory also pulls in it's fair share due to not being able to remove classes. So we get alot of fluff in small programs. What do you mean by not being able to remove classes? Isn't the whole point of offering a language that has both structs, which can have functions, and classes to do away with classes when inheritence isn't needed? Well since you could potentially create classes through Object.factory at runtime the code for unused classes will be compiled into the binary anyways this is even if you never use Object.factory directly in the code. I am not 100% sure but i think the main problem is ModuleInfo that keeps everything alive. And it keeps classes alive since they could be used by object factory. It also keeps other information like unittests locations and static constructors. What tools and parameters did you use to obtain that dissassembly? I used the visual studio dissassembly window. Can you tell whether a 32-bit load was used? _Dmain: pushRBP mov RBP,RSP mov EAX,0Ah pop RBP ret mov EAX,0AH This is a 32-bit instruction. 64-bit instructions use the RAX register. It's actually the same register but it's just named diffrently depending if you use the full 64-bits or just the lower 32-bits. It will automatically zero extend it. See https://github.com/yasm/yasm/wiki/AMD64 for a simple intro into x64.
Re: Shared library extern (C) variables
On Monday, 6 January 2014 at 09:27:26 UTC, Jacob Carlborg wrote: To be able to load symbols from libraries at runtime they have to be declared with extern. "export", not "extern". Yeah typo sry.
Re: Shared library extern (C) variables
On Sunday, 5 January 2014 at 19:55:50 UTC, Mineko wrote: Ahh I appreciate it, but I already have that part down and good. :) I was wondering about how to use export correctly, I apologize for not being clear. Also I'll keep in mind the __gshared, never even knew about it. Export is currently somewhat broken see DIP45 for an indepth explanation (link) To be able to load symbols from libraries at runtime they have to be declared with extern. This rule does not hold on linux though since it simply makes all the symbols avalible but for other systems it is important. So for instance: void foo() { ... } //This will NOT be avalible for loading under windows. export void foo() { ... } //This is avalible for loading under windows. extern(C) void foo() { ... } //This will also not be avalible for loading. extern is a whole diffrent creature. extern deals with name mangling and calling conventions. extern(C) void foo() { ... } Uses C name mangling and calling convention: C name mangling is no name mangling so the symbol for foo() will simply be foo All symbols not annotated with an extern will automatically be extern(D) and wil use the standard D name mangling and calling convetion. D name mangling makes this: module main; void foo() { ... } into _D4main3fooFZv This is probably why you did not succeed in loading your test function. So to sum up: export deals with DLL/shared library symbol visibility. extern(C/D/Windows/C++/Pascal) deals with name mangling and calling convention.
Re: Is it possible to handle 'magic' property assignments a'la PHP?
On Sunday, 5 January 2014 at 17:17:27 UTC, Artur Skawina wrote: While 'void' is not a first class type in D, there /is/ a special case for returning 'void' from functions - so all of the above can simply be written as: struct gl { static auto ref opDispatch(string name, Args...)(Args args) { scope (exit) checkGLError(); return mixin("gl"~name~"(args)"); } } artur That's awesome! Thanks for enlightening me!
Re: Is it possible to handle 'magic' property assignments a'la PHP?
Another simple example that have helped me tremendously when debugging OpenGL calls. A simple dispatcher that checks glGetError after every call. struct GL { auto opDispatch(string name, Args...)(Args args) { enum glName = "gl" ~ name; mixin(format(" static if(is(ReturnType!%1$s == void)) { %1$s(args); checkGLError(); } else { auto r = %1$s(args); checkGLError(); return r; }", glName)); } } GL gl; I simply use gl.funcName instead of glFuncName. opDispatch rules!.
Re: How do I choose the correct primative?
On Sunday, 5 January 2014 at 06:31:38 UTC, Jake Thomas wrote: And got 86,421 lines of assembly!! I expected a load instruction to load whatever was at loadMe's location into r0 (the return register) and not much else. Maybe 10 lines - tops - due to compiler fluffiness. I got about 8,641 times that - over 3 more orders of magnatude. What is going on here? Well the compiler pulls in at minimum the entire D runtime if i'm not mistaken which make the standard .exe about 350kb. Things like Object.factory also pulls in it's fair share due to not being able to remove classes. So we get alot of fluff in small programs. The module layout of the standard library is also a problem, there is a lot of interconnections between the different modules in Phobos. (will hopefully be better when the modules are broken down into submodules) I tested your test program on windows x64 and got the following result: mov ebp,esp sub rsp,10h mov eax,dword ptr [rbp-8] lea rsp,[rbp] pop rbp ret //This does a 32 bit load into the eax register (return register) from the //stack. mov eax,dword ptr [rbp-8] //I also ran this to see if there was any difference int main() { int loadMe = 10; return loadMe; } --Resulting main functtion mov ebp,esp sub rsp,10h mov eax,0Ah mov dword ptr [rbp-8],eax lea rsp,[rbp] pop rbp ret //Loads 10 the value to be returned and //Then stores that value on the stack. //While this is not rly necessary i ran //the code in debug mode so it does not //remove most useless instructions. mov eax,0Ah mov dword ptr [rbp-8],eax //In optimized mode it is gone pushrbp mov rbp,rsp mov eax,0Ah pop rbp ret So it looks like dmd does 32-bit loads at least on windows x64.
Re: How do I choose the correct primative?
On Saturday, 4 January 2014 at 03:14:35 UTC, Jake Thomas wrote: So, short-term, it seems like one would want to use my "native/unative" technique. But long-term, hopefully not only does this get fixed, but the default behavior for the compiler be to pad things out to the native word size without having to specify alignment. According to this (http://msdn.microsoft.com/en-us/library/windows/hardware/ff561499(v=vs.85).aspx) 32-bit registers are automatically zero extended on x64 architecture while 16-bit and 8-bit registers are not. So 32-bit integers are fast. And since they are smaller then 64-bits they should benefit from higher cache-locality. So you might actually slow things down by using your (u)native sizes. Andrei has a nice talk about optimizations that talks about this a bit (http://shelby.tv/video/vimeo/55639112/facebook-nyc-tech-talk-andrei-alexandrescu-three-optimization-tips-for-c) How do you folks decide if a number should be an int, long, or even short? It depends what the number is for. In general i stick to (u)int or size_t but when types have some special significance for example the red color channel or a network port i use the corresponding types to signal bound ranges on the values. That being said i try to minimize the size of my structs as much as possible. (Keep in mind that when doing this you order the fields by alignment size) I tend to use ushorts as indices when i know that an array will never be larger then ushort.max. But this is only if i use 2 of em. There is no point in having 1 short if the struct alignment is 4 since that will only be wasted space anyways. I guess the exact type of variables should remain up in the air until the whole thing is implemented and tested using different types? Yes very much so.