how to manage the list of immutable objects
I like to create immutable object which is identified by name as it's key. And also need get() to look up named object which is already created. class Foo { static immutable(Foo)[string] map; string name; // and other attributes here... this(string name) immutable { this.name = name; map[name] = this; } static immutable(Foo) get(string name) { return map[name]; } } But this code causes error: test.d(8): Error: cannot modify immutable expression map[name] How can I declare the map so that it contains immutable object Foo, but the reference to Foo is mutable? Anyway the goal is to provide get() function. Tell me how to implement get(). Aki.
Re: how to manage the list of immutable objects
On Tuesday, 14 July 2015 at 10:09:56 UTC, aki wrote: I like to create immutable object which is identified by name as it's key. And also need get() to look up named object which is already created. class Foo { static immutable(Foo)[string] map; string name; // and other attributes here... this(string name) immutable { this.name = name; map[name] = this; } static immutable(Foo) get(string name) { return map[name]; } } But this code causes error: test.d(8): Error: cannot modify immutable expression map[name] How can I declare the map so that it contains immutable object Foo, but the reference to Foo is mutable? Anyway the goal is to provide get() function. Tell me how to implement get(). Aki. Trying on http://dpaste.dzfl.pl/ I don't see that error. Maybe you mean const and not immutable ? Andrea
Re: Align object to vector using Dgame framework
On Tuesday, 14 July 2015 at 00:31:56 UTC, codenstuff wrote: On Monday, 13 July 2015 at 19:07:55 UTC, Márcio Martins wrote: On Monday, 13 July 2015 at 16:11:03 UTC, codenstuff wrote: [...] This is not really a game development forum but here you go: auto rads = atan2(object.velocity.y, object.velocity.x); // returns radians auto degs = angle * (180.0f / PI); // convert to degrees shape.rotate(degs); I suggest you store velocity as a Vector2f to avoid later confusion. It is really useful to learn basic linear algebra, and trigonometry as a game developer - you will be needing these tools on a daily basis. This does not work as expected. It keeps rotating object as long as vector is at angle. Any idea how to improve on this? I'm sorry. You should use setRotation() instead, rotate() just adds to the rotation.
Re: Wrapping a C-style Array (Pointer + Length) in a Range Interface
On Wednesday, 8 July 2015 at 05:14:48 UTC, ketmar wrote: so while there is nothing wrong in creating slices from pointers, programmer should be aware of some potential pitfalls. I believe there's a DIP (involving the scope keyword) related to this problem, right?
Re: Wrapping a C-style Array (Pointer + Length) in a Range Interface
On Tue, 14 Jul 2015 08:33:56 +, Nordlöw wrote: On Wednesday, 8 July 2015 at 05:14:48 UTC, ketmar wrote: so while there is nothing wrong in creating slices from pointers, programmer should be aware of some potential pitfalls. I believe there's a DIP (involving the scope keyword) related to this problem, right? yes, but i never get it. signature.asc Description: PGP signature
Re: how to manage the list of immutable objects
On Tuesday, 14 July 2015 at 10:46:42 UTC, Andrea Fontana wrote: Trying on http://dpaste.dzfl.pl/ I don't see that error. Maybe you mean const and not immutable ? Andrea I used: DMD32 D Compiler v2.067.1 on Windows8 I believe there are no typo because it is copy-pasted. I noticed I can use cast. cast()(map[name]) = cast()this; Are there any better solution? Aki.
Re: Linked variables
On Monday, 13 July 2015 at 22:07:11 UTC, Tanel Tagaväli wrote: Does the standard library have a way to create a forward link between two variables of the same type? One variable is the source and the other is the sink. When the source variable is changed, the sink variable is too. Changing the sink variable has no effect on the source variable. I have already implemented it using std.signals and class templates(https://github.com/TheBlu/lockd/blob/master/source/engine.d), but is there a better way, either in the standard library or a third party library? I have done a data binding system using properties in my D learning library. (https://github.com/BBasile/iz/blob/master/import/iz/properties.d#L610) The problem encountered with data binding is that there must be a signal. So the most obvious way to do that is always more or less based on the observer pattern. But there are other solutions: - check a list of pointer in a thread or in a timer. (foreach target in targets...if target != source... ; Thread.sleep();) - check a list of pointer when a particular message is found within a message queue. (if messages.peek == msg.synchronize_bindings then foreach target in targets...) - similarly, check the target on idle, for example on windows when no message is dispatched then an idleEvent can be defined. This solution works fine with GUI programs. A very D-ish way to do that would be to use UDA annotations to build the list of targets.
Re: how to manage the list of immutable objects
On 7/14/15 7:12 AM, aki wrote: On Tuesday, 14 July 2015 at 10:46:42 UTC, Andrea Fontana wrote: Trying on http://dpaste.dzfl.pl/ I don't see that error. Maybe you mean const and not immutable ? Wow, that needs updating. Latest version is 2.065 from February 2014, and the git version is from March 2013! I used: DMD32 D Compiler v2.067.1 on Windows8 I believe there are no typo because it is copy-pasted. I noticed I can use cast. cast()(map[name]) = cast()this; Are there any better solution? Cast is not a good idea. What you need is a rebindable class reference to an immutable class. For that, the official recommendation is to use std.typecons.Rebindable. Perhaps it works for you: static Rebindable!(immutable(Foo))[string] map -Steve
Re: Understanding Safety of Function Pointers vs. Addresses of Functions
On Tuesday, 14 July 2015 at 01:05:21 UTC, jmh530 wrote: Note: some of the above seemed to only work when I kept the std.math.cos, std.math.sin text in there. When I take it out, I get warnings about recursive aliases. Yeah, you can't do `alias cos = givemeabettername!cos;`. That would define the new cos in terms of itself. But, I can't seem to use a foreach loop. The recursive mixin template seems to be required. You can only use the implicitly static foreach where the normal, dynamic foreach is allowed, i.e. in function bodies. This is a syntactic restriction. If we had `static foreach` (like we have `static if`), that would presumably work everywhere. So this is the last thing I did (that didn't work). Adding foo back to the alias works. mixin template callThemAll(functions...) { mixin(alias ~__traits(identifier, functions[0]) ~ = givemeabettername!(std.math.~__traits(identifier, functions[0]) ~ );); static if(functions.length 1) mixin callThemAll!(functions[1..$]); } mixin callThemAll!(cos, sin); Works for me. Please show the complete code and the error message you get. Here's what works for me: import std.algorithm: map; import std.math; import std.array: array; template givemeabettername(alias fun) { T givemeabettername(T : U[], U)(T x) { return x.map!fun.array; } } mixin template callThemAll(functions...) { mixin(alias ~__traits(identifier, functions[0]) ~ = givemeabettername!(std.math.~__traits(identifier, functions[0]) ~ );); static if(functions.length 1) mixin callThemAll!(functions[1..$]); } mixin callThemAll!(cos, sin); void main() { real[] a = [1, 2, 3]; auto c = cos(a); auto s = sin(a); }
Re: Understanding Safety of Function Pointers vs. Addresses of Functions
On Tuesday, 14 July 2015 at 12:12:41 UTC, anonymous wrote: Works for me. Please show the complete code and the error message you get. Here's what works for me: Thanks for posting that. I figured out the issue. Before you had recommended that I use alias cos = std.math.cos; I had kept that text in. When I removed it, everything worked just fine. I'm still not sure I grasp the subtleties of alias when used with templates.
Profile Ouput
Perhaps my googlefu has failed me, but I can find anything describing the output of DMD's -profile switch. I get that trace.def is a list of all functions called and I understand the table at the bottom of trace.log. What I'm not sure about is everything above the table in trace.log, stuff like this: -- 4000 _Dmain _D4main6selectFZk 40002736471 4000 _D3std6random27__T7uniformVAyaa2_5b29TkTkZ7uniformFNfkkZk -- I get that it's telling me that the function main.select is called 4000 times and that it, in turn, calls std.random.uniform 4000 times. What I not clear about is the 2736 and the 471. They match none of the times int the table below, where main.select has a Tree Time of 823 and a Func Time of 141. I also don't understand the 4000 next to _Dmain, as it's only called once. If anyone could clarify, or point me somewhere that explains it, I'd appreciate it.
Re: Covariant callback functions, or assigning base class members through a subclass reference
Template Base on Derived: class Derived : Base!Derived { }
Re: Covariant callback functions, or assigning base class members through a subclass reference
On Tuesday, 14 July 2015 at 15:35:04 UTC, Kagamin wrote: Template Base on Derived: class Derived : Base!Derived { } Sure, but that would make Base!Derived and Base!AnotherSubClass different types. What I'd like to end up with is a Base[], being able to call foo() on the array members. Other parts of the code will add instances of derived types to this array, and have set the callback function to a delegate accepting said derived type. This is part of a library I'm working on. I don't mind if the library itself contains some nastiness to get this to work, as long as user code, which defines the derived types, is type safe and clean.
Covariant callback functions, or assigning base class members through a subclass reference
Given the following code: class Base { alias CallbackType = void delegate(Base); CallbackType callback; void foo() { callback(this); } } class Derived : Base { } void main() { auto d = new Derived(); d.callback = (Derived d) { /* Do something */ } } Obviously this won't compile, since the callback function needs to have Base as parameter, not Derived. But the given code is perfectly safe because in main d typed as Derived, not Base. Does anyone know a clean way to support the code given in main(), preferably by defining some smart CallbackType so Derived doesn't need to be modified? I understand this is unsafe in other scenarios, for example: class AnotherSubClass : Base { } void bar(Base b1, Base b2) { b1.callback = b2.callback; } void doom() { auto b1 = new Derived(); auto b2 = new AnotherSubClass(); b2.callback = (AnotherSubClass a) { }; bar(b1, b2); } But the CallbackType should be able to prevent such unsafe assignments.
Re: Understanding Safety of Function Pointers vs. Addresses of Functions
On Tuesday, 14 July 2015 at 17:24:41 UTC, anonymous wrote: This fails with Error: None of the overloads of 'cos' are callable using argument types (int[]). The problem is that template mixins cannot add to existing overload sets. The spec says: If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one [1]. That means, the `cos` from `alias cos = std.math.cos;` completely overrides the one from `mixin t!();`. I guess this is a measure against function hijacking again. I'm not sure if it's supposed to work like it does when the alias is removed, two implicitly imported/generated symbols forming an overload set. But I can't immediately see a problem with it either. [1] http://dlang.org/template-mixin.html - see Mixin Scope That's a great explanation. It doesn't seem like a bug or anything. It's just alias and template mixins are two areas of D that I'm less familiar with. Combining them together pushes my understanding a bit.
Re: how to manage the list of immutable objects
On Tuesday, 14 July 2015 at 11:44:34 UTC, Steven Schveighoffer wrote: static Rebindable!(immutable(Foo))[string] map -Steve It all works. And I learned something from the source code of Rebindable. Thank you. Aki.
Re: Covariant callback functions, or assigning base class members through a subclass reference
On 7/14/15 11:28 AM, Rene Zwanenburg wrote: Given the following code: class Base { alias CallbackType = void delegate(Base); CallbackType callback; void foo() { callback(this); } } class Derived : Base { } void main() { auto d = new Derived(); d.callback = (Derived d) { /* Do something */ } } Obviously this won't compile, since the callback function needs to have Base as parameter, not Derived. But the given code is perfectly safe because in main d typed as Derived, not Base. Does anyone know a clean way to support the code given in main(), preferably by defining some smart CallbackType so Derived doesn't need to be modified? No, this isn't possible. Only thing you can do is: d.callback = (Base b) { if(auto d = cast(Derived)b) { /* Do something */ } else assert(0); }; -Steve
Re: Covariant callback functions, or assigning base class members through a subclass reference
On Tuesday, 14 July 2015 at 17:26:32 UTC, Steven Schveighoffer wrote: On 7/14/15 11:28 AM, Rene Zwanenburg wrote: Given the following code: class Base { alias CallbackType = void delegate(Base); CallbackType callback; void foo() { callback(this); } } class Derived : Base { } void main() { auto d = new Derived(); d.callback = (Derived d) { /* Do something */ } } Obviously this won't compile, since the callback function needs to have Base as parameter, not Derived. But the given code is perfectly safe because in main d typed as Derived, not Base. Does anyone know a clean way to support the code given in main(), preferably by defining some smart CallbackType so Derived doesn't need to be modified? No, this isn't possible. Only thing you can do is: d.callback = (Base b) { if(auto d = cast(Derived)b) { /* Do something */ } else assert(0); }; -Steve Thanks, I'll have to think of something else then. At my day job I mostly work with C#, and I strongly dislike how event handler parameters there have to be broader-typed (is that even a valid term?) than they logically need to be, which is why I'm trying to avoid doing something similar here.
Re: Understanding Safety of Function Pointers vs. Addresses of Functions
On Tuesday, 14 July 2015 at 14:02:46 UTC, jmh530 wrote: Thanks for posting that. I figured out the issue. Before you had recommended that I use alias cos = std.math.cos; I had kept that text in. When I removed it, everything worked just fine. I'm still not sure I grasp the subtleties of alias when used with templates. Oh that's another goodie. So you had a situation like this: import std.math; alias cos = std.math.cos; mixin template t() { void cos(real[] arr) {/* ... */} } mixin t!(); void main() { cos([1, 2, 3]); } This fails with Error: None of the overloads of 'cos' are callable using argument types (int[]). The problem is that template mixins cannot add to existing overload sets. The spec says: If the name of a declaration in a mixin is the same as a declaration in the surrounding scope, the surrounding declaration overrides the mixin one [1]. That means, the `cos` from `alias cos = std.math.cos;` completely overrides the one from `mixin t!();`. I guess this is a measure against function hijacking again. I'm not sure if it's supposed to work like it does when the alias is removed, two implicitly imported/generated symbols forming an overload set. But I can't immediately see a problem with it either. [1] http://dlang.org/template-mixin.html - see Mixin Scope