Re: Why D isn't the next "big thing" already
On Wednesday, 27 July 2016 at 10:17:57 UTC, NX wrote: On Wednesday, 27 July 2016 at 09:28:49 UTC, chmike wrote: 4. Web server && IO performance (see: https://www.techempower.com/benchmarks or https://github.com/nanoant/WebFrameworkBenchmark). Please, these are terribly outdated benchmarks. There was a recent bug causing Vibe.D to not scale to multiple cores at all which has been fixed. Yes, you are right. It's not easy to determine the version of vibe.d used for techempower. From this link it seam that version 0.7.19 of vibe.d was used Oo unless the Readme is simply outdated. https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/D/vibed For the other one it's vibe v0.7.26 which is more recent. The performance is still low.
Re: Check of point inside/outside polygon
On Wednesday, 27 July 2016 at 09:39:18 UTC, Suliman wrote: ... Big thanks! Ehm... Now I should add iteration on array of points in first and second polygon? If it's not hard for you could you show how it should look please. Sorry, I may have misunderstood the initial problem. You were asking how to test if a point is inside a polygon. Now you are referring to two polygons. This sound different. Iterating on segments of a polygon is not so difficult and is highly dependent of the data structure you use to represent points, segments and polygons. This really looks like an assignment or a D learning exercise. What do you need this for ? Do you have the data structures already defined ?
Re: Why D isn't the next "big thing" already
On Tuesday, 26 July 2016 at 15:11:00 UTC, llaine wrote: Hi guys, I'm using D since a few month now and I was wondering why people don't jump onto it that much and why it isn't the "big thing" already. Everybody is into javascript nowadays, but IMO even for doing web I found Vibe.d more interesting and efficient than node.js for example. I agree that you have to be pragmatic and choose the right tools for the right jobs but I would be interested to have other opinion on those questions. I've been testing D and love many features of the language. But I'm now to switching to Go for my alimentary project. But I prefer D's syntax, ranges and the easiness of generic coding. The reason I'm switching to Go is because 1. there is a much larger community and code base (it's easier to find code snippet, help or programmers) 2. go routines (fibers integrated into the language, plug & play) 3. GC performance (no stop the world hiccups) 4. Web server && IO performance (see: https://www.techempower.com/benchmarks or https://github.com/nanoant/WebFrameworkBenchmark). As a computer scientist I prefer D to Go and see a lot of potential in it. But as a software developer I feel that D still needs maturation to be competitive in a production environment. I guess this is the reason why D doesn't get much traction yet.
Re: Check of point inside/outside polygon
The algorithm is to draw a horizontal (or vertical) half line starting at your point and count the number of polygon edges crossed by the line. If that number is even, the point is outside the polygon, if it's odd, the point is inside. Let (x,y) be the point to test and (x1,y1)(x2,y2) the end points on each segment. Let n be the number of crossing that you initialize to 0. (x1,y1)(x2,y2) are also the corners of the rectangle enclosing the segment. You then have to examine each segment one after the other. The nice thing is that there are only two cases to consider. 1. When the point is on the left side of the rectangle enclosing the segment. 2. When the point is inside the rectangle enclosing if (y1 <= y2) { if ((y1 <= y) && (y2 >= y)) { if ((x1 < x) && (x2 < x)) { // case 1 : point on the left of the rectangle ++n; } else if (((x1 <= x) && (x2 >= x)) || ((x1 >= x) && (x2 <= x))) { // case 2 : point is inside of the rectangle if ((x2 - x1)*(y - y1) >= (y2 - y1)*(x - x1)) ++n; // Increment n because point is on the segment or on its left } } } else { if ((y1 >= y) && (y2 <= y)) { if ((x1 < x) && (x2 < x)) { // case 1 : point on the left of the rectangle ++n; } else if (((x1 <= x) && (x2 >= x)) || ((x1 => x) && (x2 <= x))) { // case 2 : point is inside of the rectangle if ((x2 - x1)*(y - y2) >= (y1 - y2)*(x - x1)) ++n; // Increment n because point is on the segment or on its left } } } This algorithm is very fast. I didn't tested the above code. You might have to massage it a bit for corner cases. It should give you a good push to start.
Go’s march to low-latency GC
In case you missed it https://blog.twitch.tv/gos-march-to-low-latency-gc-a6fa96f06eb7#.emwja62y1
Re: Asynchronous Programming and Eventhandling in D
On Wednesday, 6 July 2016 at 11:33:53 UTC, Eugene Wissner wrote: The only reason libev was choosen is that it is the simplest implementation I know about. A few C files. I had an educational purpose: I wanted to see how an event loop works on low level. Asyncio was for me no-go, since I've not written a lot in C++, and can only read the code a bit. So I'm not hanging on libev. The only another implementation would be the python event library. It is also pure C code and it was much more cleaner written than libev on the first sight. Your project and work is valuable on many aspects. I didn't mean to depreciate it. Now there are two problems with my work: 1) The first is something we all are tired to talk about: manual memory management. I make a proof of concept and am writing the code that is 100% marked as @nogc. It has side effects. For example I allocate exceptions and thay should be freed after catching - it is something, phobos doesn't do. As said it is an experiment; I would like to see how it works. 2) Performance. The main reason I started the writing at all is that the existing implementations seem to have only performance as criterium. Performance is super important, but not on the cost of design, usability and extensibility. For example in vibe.d (and libasync) everything possible is defined as structs, everything that would be interesting to extend is final; and after it you go to phobos and see a "workaround". For example Mallocator is a struct but you have to be sure, it is an allocator. How do you force the right interface? That is a valid point. I know it is hard to get the best performance and optimal API design at the same time. The reason the methods are final is to avoid the overhead of virtual method indirection. static if (hasMember!(Allocator, "deallocate")) { return impl.deallocate(b); } else { return false; } Somethinkg like this would be ok for C. But for a language with interfaces, it is ugly design independent of how it performs. Everything I say here is IMHO. This would mean we need a new design pattern that supports both. Except these two points I'm interested in some kind of collective work aswell. It is very difficult as one man job. I didn't know other people are also working on similar implementations. Nice to know. Are you aware of any benchmark tools in other languages that could be used? The benchmark tools available are mainly testing web servers. And the exact operation pattern is not very clear. One of such benchmark tool is wrk [https://github.com/wg/wrk] that measure HTTP request speed. The problem is that it measure the performance of the I/O and HTTP handling. Here are some benchmark results: * https://www.techempower.com/benchmarks/ * https://github.com/nanoant/WebFrameworkBenchmark How can D be worse than Java ? My strategy would be to split the problem. First get the async I/O optimal. Then get HTTP handling optimal, and finally get database interaction optimal (the optimal async I/O should help). An investigation on the methods used by Java/undertow to get these performances could help. I would suggest to implement a benchmark client doing some predefined patterns of I/O operations similar to web interactions or the most common types of interactions. And a server implemented in C using native system I/O operations. This server implementation would then be our reference. What would be measured is how much slower our different D implementations are relative to the C reference implementation. This will allow us to have a benchmarking test that doesn't depend that much of the hardware.
Re: Asynchronous Programming and Eventhandling in D
On Tuesday, 5 July 2016 at 20:38:53 UTC, Eugene Wissner wrote: On Tuesday, 5 July 2016 at 08:24:43 UTC, O/N/S wrote: Hi ("Grüss Gott") I like the asynchronous events in Javascript. Is something similar possible in D? Found Dragos Carp's asynchronous library (https://github.com/dcarp/asynchronous). Are there any more integrated (in Phobos/in D) ways to work asynchronously? An example: One server ask a second server to calculate something big. The first server continues with his work, until the answer come back from the second. And so on... Using threads or fibers would be a way, but has not the same elegancy like the Javascript way. (To avoid discussions: D is better ;-) Greetings from Munich, Ozan Servus, I'm currently rewriting the base skeleton of libev in D (only for linux for now) for web development aswell. And the next step would be data structures, basic server, futures and yo on... I was working with dcarp's asynchronous and i found it very very good. It is till now the best I've seen in D for async programming ( I mean its design and usability). Can you describe what would you like to see more concretly. I know js but how is it supposed to work for D? Maybe you can give some example, kind of pseudo code? It would help me much to build a concept and maybe we will see someday something usable in this area :) The problem I see with libev is that it isn't compatible with the CPIO API of windows. The C++ boost asio library, on the contrary, is compatible with the select/epoll/kqueue model and the Windows CPIO model. This is the reason I started on a D implementation of asio I called dasio [https://github.com/chmike/dasio]. Unfortunately my alimentary work didn't leave me any time to make progress on it. The only thing I manage to implement so far is asio's error code system. I'm glad to see other people see an interest to work on this. We definitely should find a way to combine our efforts. That is already a significant work made with the other libraries. My feeling is that providing support for very efficient IO in Phobos might have a strong impact on D's visibility and adoption for backend applications (e.g. servers). Performance is a very strong argument for adoption is such context. A list of requirements has been already published on the wiki. What I think is now missing is a benchmarking tool so that we can get numbers for each async lib implementation that we can also compare with a raw C implementation using the native functions.
Re: What's the secret to static class members
On Wednesday, 29 June 2016 at 17:00:49 UTC, Guido wrote: On Wednesday, 29 June 2016 at 15:40:57 UTC, Andrea Fontana wrote: On Wednesday, 29 June 2016 at 15:33:58 UTC, Guido wrote: The problem is actually much more profound. The classes need to be declared outside the main() scope. WTF?!?!?! I put them in main() so they would be in scope. This seems like a *MAJOR* design flaw with the language, not to mention the compiler not giving useful feedback. This decision, if it is a decision, makes no sense given all the attention to scoping rules. I'm not interested in trading one set of bad language decisions for another. Can someone fix this? I wonder which language you usually use in your programming experience. C++ I have all this business generally working in C++. I just wanted to try D for a production level quick project. So, the language is not ready. I'm really sad about this. I had hoped that I could get some useful work done. C++ is painfully slow to write & debug, but what can you do. As I said, why exchange one set of bad design decisions for another? On another topic, tuples seem to have a major problem as well. Tuple!(float, float, float) test; Tuple!(float, float, float) [] array_data; test[0] = 1.0; // works array_data[i][0] = 1.0; // doesn't work. Compile-time error, Why don't you give at least the compiler error and the full code ? If you don't want to publish your actual code, create a very small program reproducing the problem and show that to us. I understand your frustration, but understand that there are many people here that volunteer to help you. You have to provide them sufficient info for this to work. Tuple!(float, float, float) [] array_data; This declares a dynamic array that is initially empty (array_data.length == 0). Accessing the i'th item can't work. I'm a bit surprised the compiler would detect this problem because it is usually a run time error. So I suspect there are other problems with your code. You could also have written array_data ~= test; which appends the value test to the dynamic array that will then contain one element. You could then have written array_data[0][0] = 2.0; Or you could also have written Tuple!(float, float, float) [10] array_data; which would have declared array_data as a fixed sized array of 10 tuples. In this case writing array_data[1][0] = 1.0; would have worked. D is an excellent and mature language. Every language has its rules that needs to be learn. Claiming the problems you encountered are due to bad design of the language is unfair if you don't expose clearly the problem and verify the problem is not your side. There is a deeply thought rationale for every rule of the D language. If you don't understand the rationale or want to contest the choice of rules, then expose your point and arguments. People will helpfully answer you. I did it myself and was always impressed by the quality of the responses and positive and helpful attitude of people in this forum.
Re: Fibers, what for?
On Monday, 13 June 2016 at 00:57:11 UTC, Alex Parrill wrote: This is misleading. Any sort of cooperative system needs synchronization when two or more tasks try to access the same data, whether those "tasks" are OS threads, fibers, different machines on a network, etc. That is true. Sorry. What I meant is that with fibers the yield is performed in well defined locations it could be in blocking calls like read() or write() or when yield is called. For this reason it is simpler to synchronize access to shared ressources with fibers than with threads. It's thus POSSIBLE to write code that doesn't need synchronization even when shared ressources are used. Note also that the synchronization mechanism can be much simpler and efficient than the one needed with threads. With threads you MUST allways synchronize access to shared ressources and protect critical sections of your code, or use specially crafted none blocking data structures using atomic operations.
Re: Fibers, what for?
On Sunday, 12 June 2016 at 05:11:57 UTC, Ali Çehreli wrote: For convenience, here's the link: http://www.ustream.tv/recorded/86352137/highlight/699197 unfortunately iPads are not supported to view the video. :( I see two major benefits of fibers overs threads. Fibers don't need synchronization to access shared data. This removes the overhead of synchronization and simplifies "multitheaded" programming greatly. The second benefit is that fibers have a much lower time cost of context switching. When a fiber yields the processor to another fiber, the switch is immediate and the other fiber can immediatly resume its task. With threads, you have to wait that the OS give the processor back to your process. This can take some time when there are many other threads competing for the processor. The performance difference is the most notable when the amount of work to do between switches is small. Most popular and succesfull use for fibers is for asynchronous or event driven processing.
Re: template with enum arg ?
This is awesome! I added it to my D cookbook. Thank you very much.
template with enum arg ?
In a first implementation I defined a named enum in my class which I could use with my template function foo. final class Info { ... enum Value { info_1 = 1, ... } ... static bar(Value e) {...} } void foo(T)(T.Value e) { T.bar(e); } I could then write : foo(Info.Value.info_1); I would prefer to write : foo(Info.info_1); If I change the enum into an anonymous enum the template doesn't work anymore. How could I solve this ? Also, do I need a template argument filter if() ?
Passing a sting as 'in char[]' yields "immutable is not callable using argument types ()"
I have an immutable final class with methods with the following signature import std.typecons; immutable class Base{ ... @safe pure nothrow final Tuple!(int,"value",bool,"hasValue") value(const string name) { return nameImpl(value); } @safe pure nothrow protected abstract Tuple!(int,"value",bool,"hasValue") valueImpl(const string name); ... } final immutable class Info: Base{ ... @safe pure nothrow static Tuple!(int,"value",bool,"hasValue") value(const string name) { auto p = name in name2value_; // <-- Error in this line return (p) ? Tuple!(int,"value",bool,"hasValue")(*p,true) : Tuple!(int,"value",bool,"hasValue")(int.init,false); } @safe pure nothrow protected override Tuple!(int,"value",bool,"hasValue") valueImpl(const string name) { return value(name); } ... enum int[string] name2value_ = [ "info_1" : 1, ...]; } When trying to compile this I get the following error Error: function Info.value (const(string) name) immutable is not callable using argument types () What is the error ? Why is argument types () ?
Re: Passing a sting as 'in char[]' yields "immutable is not callable using argument types ()"
final Tuple!(int,"value",bool,"hasValue") value(const string name) { return nameImpl(value); } Sorry, this is the error. It should have been final Tuple!(int,"value",bool,"hasValue") value(const string name) { return valueImpl(name); }
Recommended coding convention for combining unix and windows code ?
Hello I'm writing some code that I want to be portable across Posix and Windows. What is the recommended code convention for such type of code ? 80% of the class implementation is the same for both OS. Should I write the following and copy past the 80% version( Windows ) { import core.sys.windows; class MyInfo {...} } else version( Posix ) { import core.sys.posix; class MyInfo {...} } else { static assert(false, "Unsupported platform"); } or should I do it the C way with multiple embedded static if... ? version( Windows ) { import core.sys.windows; } else { //Posix import core.sys.posix; } class MyInfo { ... static if(windows) { enum Value {...} } static else { //Posix enum Value {...} } ... }
Re: Implicit conversion of struct to bool for if (s) operation ?
On Monday, 6 June 2016 at 15:28:35 UTC, John wrote: Thank you John and Adam. That was a quick answer !
Re: Overriden method not detected ?
On Friday, 3 June 2016 at 21:04:41 UTC, ag0aep6g wrote: Thank you ag0aep6g, especially for the missing shared in my static this ! Since I'm implementing a (hopefully useful) library, it would be unpleasant for users to have to cast away shared to print the info. It works with immutable at the condition that I declare the toString() method like this string toString() immutable {...} There is also no missing opEqual. Is it possible to instantiate immutable objects by using emplace and modify the object in the toString() call ? This is to cache the resulting string to avoid creating a new string at each call. I would have to cast away the immutable attribute of 'this'. Is this possible ? Note that the objects would be instantiated by emplace in a void array at start up. So the memory is writable.
Re: Overriden method not detected ?
On Friday, 3 June 2016 at 15:23:16 UTC, Jonathan M Davis wrote: Thank you for your detailed explanation. If I have a static immutable object, I don't have to declare it as shared because it is implicit. Right ? Changing my __gshared into static shared raises some errors which I don't know how to address. Ali's chapter doesn't address shared classes. May I ask for your help ? 1. question --- I had a __gshared Info[N] infos_; that I fill in a static this() method. How should I declare this with shared ? Is it enough to write static shared Info[N] infos; ? Since shared is transitive, will the info objects be implicitly shared ? 2. question --- As I said above, I instantiate my Info objects in a private static this() method. The objects are emplaced in a static shared void array. Since emplace only accept a void[] as argument I had to cast away the shared as you did in your example. The compiler seams happy. However I didn't synchronized that code because I assume it is executed by the main thread before main starts. There is thus no risk of race conditions. Is this assumption correct ? 3. error A weird error is that there is apparently no overload for opEquals. Do I have to define one my self ? Is this so that users can synchronize themselves if needed ? source/app.d(9,13): Error: none of the overloads of 'opEquals' are callable using argument types (shared(Info), shared(Info)), candidates are: /usr/include/dmd/druntime/import/object.d(143,6): object.opEquals(Object lhs, Object rhs) /usr/include/dmd/druntime/import/object.d(168,6): object.opEquals(const(Object) lhs, const(Object) rhs) I guess I have to define my own opEqual. 4. error Another error is with writeln(info); where info is now a shared(Info). /usr/include/dmd/phobos/std/format.d(2904,5): Error: static assert "unable to format shared objects" /usr/include/dmd/phobos/std/format.d(3477,16): instantiated from here: formatValue!(LockingTextWriter, shared(Info), char) /usr/include/dmd/phobos/std/format.d(467,54):instantiated from here: formatGeneric!(LockingTextWriter, shared(Info), char) /usr/include/dmd/phobos/std/stdio.d(1316,31):instantiated from here: formattedWrite!(LockingTextWriter, char, shared(Info)) /usr/include/dmd/phobos/std/stdio.d(3114,28):instantiated from here: write!(shared(Info), char) source/app.d(12,12):instantiated from here: writeln!(shared(Info)) How can I solve that error ?
Re: Overriden method not detected ?
On Friday, 3 June 2016 at 12:41:39 UTC, Jonathan M Davis wrote: ... On a side note, be warned that you almost certainly shouldn't be using __gshared like this. It's intended for interacting with C code not for D objects to be marked with D. As far as the type system is concerned, __gshared isn't part of the type, and the variable will be treated as thread-local by all of the code that uses it, which can result in really nasty, subtle bugs when the compiler starts doing stuff like optimizations. If you want to be sharing D objects across threads, you really should be using shared so that the compiler knows that it's shared across threads and will treat it that way. Thanks to point this out. What does shared really do behind the scene ? Does it add synchronization instructions ? In my case I really don't want the compiler to add synchronization instructions because the objects are immutable from the user perspective. This is enforced by the interface. Tho objects are fully instantiated in a private static this() {} function which shouldn't be affected by multi-threading since it is executed at startup. The unpleasant side effect of shared is that I then have to use shared(Info) instead of the shorter type name Info. What are the subtle and nasty bugs you are referring to ?
Overriden method not detected ?
When trying to compile the following code I get a compilation error import std.stdio; class Info { final string name() { return nameImpl(); } protected abstract string nameImpl(); } final class MyInfo : Info { this() { assert(__ctfe); } private __gshared info_ = new MyInfo; // Line 12 static string name() { return "MyInfo"; } protected override string nameImpl() { return name(); } } void main() { writeln("Hello world!"); } source/app.d(12,31): Error: cannot create instance of abstract class MyInfo source/app.d(12,31):function 'string nameImpl()' is not implemented If I move the info_ static variable declaration after the nameImpl method declaration, there is no error anymore. Is this normal ? What rule is in play here ? Or is this a compiler bug ?
Re: Why simple code using Rebindable doesn't compile ?
On Tuesday, 31 May 2016 at 06:40:31 UTC, Era Scarecrow wrote: On Tuesday, 31 May 2016 at 05:31:59 UTC, chmike wrote: My conclusion is that rebindable is not a satisfying solution to have mutable references to immutable objects. I don't understand the rationale of these immutable references. It is too constraining. I still don't know why you're trying to use immutable. In the other thread you have listed you are trying to make a global singleton? You needed it mutable but marked immutable (for... some reason?) but all the methods won't change the contents or spirit of the object. I need to wrap my head around what you're trying to do before i can suggest anything else. Although making all members private and all functions as const would give you a mutable/unchanging object... The code I gave are just examples. The reason I used immutable is because I have two types of objects. I have many Info objects (~150) which are all singletons. These Info objects have a reference to a Category objects which is also a singleton. I can have mutable singleton objects. I have a public interface that doesn't allow to modify the object. This is not the problem. The problem is that I would like that all these objects are instantiated at compile time. This is to keep the start of the program fast. There is no problem to instantiate the Category object at compile time. The problem is to instantiate the different Info objects at compile time that have a reference to the Category object. Ctfe doesn't work when a global variable is referenced. I noticed that it worked when the Category is declared immutable. I can add a reference to that Category singleton instance to the new call of the Info objects. So the goal is to create and interconnect multiple objects at compile time. Ideally I would need to store a reference to each of the Info objects in an associative array so that I can retrieve a reference to it with some key.
Re: Why simple code using Rebindable doesn't compile ?
On Monday, 30 May 2016 at 21:32:46 UTC, Alex Parrill wrote: On Monday, 30 May 2016 at 10:09:19 UTC, chmike wrote: Why can't info() return a Rebindable!(immutable(InfoImpl)) ? What do you mean? `info` returns an `immutable(InfoImpl)`, not a `Rebindable!(immutable(InfoImpl))`. Rebindable doesn't apply itself to the return types of the methods of the return types (there's no reason to). I mean that if I change the return type of info() into Rebindable!(immutable(infoImpl)) like this Rebindable!(immutable(InfoImpl)) info() { ... return rebindable(x);} I get an error. I was explained privately that its because Rebindable... Is an lvalue and not a type. My conclusion is that rebindable is not a satisfying solution to have mutable references to immutable objects. I don't understand the rationale of these immutable references. It is too constraining.
Re: Why simple code using Rebindable doesn't compile ?
This code compile, but array appending doesn't work alias Rebindable!(immutable(InfoImpl)) Info; class InfoImpl { void foo() {} static immutable(InfoImpl) info() { __gshared immutable InfoImpl x = new immutable InfoImpl; return x; } } void main() { Info t = Info.info; Info[] a; //a ~= Info.info; <-- KO Compiler Error a ~= rebindable(Info.info); // Ok } - Why can't info() return a Rebindable!(immutable(InfoImpl)) ?
Re: Why simple code using Rebindable doesn't compile ?
Oops, the duplicate alias instruction and main are copy past error. It looks like the code was already too complex for me. ;) Here is the code I tested import std.typecons; Rebindable!(immutable TestImpl) Test; class TestImpl { void foo() {} Test test() { __gshared x = new immutable TestImpl; return rebindable(x); } } void main() { Test t = Test.test; }
Why simple code using Rebindable doesn't compile ?
Hello, here is a program stripped down to the minimum code that doesn't compile import std.typecons; Rebindable!(immutable TestImpl) Test; Rebindable!(immutable TestImpl) Test; class TestImpl { void foo() {} Test test() { __gshared x = new immutable TestImpl; return rebindable(x); } } void main() { Test t = Test.test; } void main() { Test t = Test.test; } source/app.d(32,10): Error: circular reference to 'app.Test' source/app.d(32,10): Error: Test is used as a type /usr/include/dmd/phobos/std/typecons.d(1616,20): Error: template instance std.traits.isDynamicArray!(immutable(TestImpl)) error instantiating source/app.d(27,1):instantiated from here: Rebindable!(immutable(TestImpl)) /usr/include/dmd/phobos/std/typecons.d(1625,17): Error: mixin std.typecons.RebindableCommon!(immutable(TestImpl), TestImpl, Rebindable) does not match template declaration RebindableCommon(T, U, alias This) if (is(T == class) || is(T == interface) || isAssociativeArray!T)
Re: String compare in words?
On average there would be less than 4 bytes remaining to compare. So a simple straightforward byte comparison should do the job efficiently.
Re: String compare in words?
On Sunday, 29 May 2016 at 20:40:52 UTC, qznc wrote: On Sunday, 29 May 2016 at 18:15:16 UTC, qznc wrote: On Sunday, 29 May 2016 at 17:38:17 UTC, Jonathan M Davis wrote: And if you're not simply comparing for equality, what are you looking to figure out? Without more information about what you're trying to do, it's kind of hard to help you. If I write the comparison naively, the assembly clearly shows a "movzbl" [0]. It loads a single byte! The other single byte load is encoded in the address mode of "cmp". Implementation: bool stringcmp(string x, string y) { foreach(i; 0..x.length) { if (x[i] != y[i]) // byte compare return false; } return true; } It makes no sense to load single bytes here. Since we only want to check for equality, we could load two full words and compare four or eight bytes in one go. Ok, to answer my own question, this looks good: bool string_cmp_opt(immutable(ubyte)[] x, immutable(ubyte)[] y) { pragma(inline, false); if (x.length != y.length) return false; int i=0; // word-wise compare is faster than byte-wise if (x.length > size_t.sizeof) for (; i < x.length - size_t.sizeof; i+=size_t.sizeof) { size_t* xw = cast(size_t*) [i]; size_t* yw = cast(size_t*) [i]; if (*xw != *yw) return false; } // last sub-word part for (; i < x.length; i+=1) { if (x[i] != y[i]) // byte compare return false; } return true; } Any comments or recommendations? I don't know if this would be faster, but here is my attempt. It assumes the arrays start at an address multiple of 8. if (x is y) return true; if (x.length != y.length) return false; size_t l = x.length; ubyte* a = x.ptr, b = y.ptr; for (size_t n = l>>3; n != 0; --n, a+=8, b+=8) if (*cast(long*)a ^ *cast(long*)b) return false; if (l & 4) { if (*cast(int*)a ^ *cast(int*)b) return false; a+= 4; b+= 4; } if (l & 2) { if (*cast(short*)a ^ *cast(short*)b) return false; a+=2; b+=2; } return (l & 1) && (*a ^ *b) ? false : true; If the pointers are not on an address multiple of 8, one has to inverse the trailing tests to consume the bytes in front of the array until the address becomes a multiple of 8. The trailing tests could eventually be replaced by a simple sequential byte compare. I don't know which is faster.
Re: is my code to get CTFE instantiated object valid D ?
On Sunday, 29 May 2016 at 06:49:42 UTC, chmike wrote: What is the right way to use it ? I answer to my self after testing so that people looking for that info can find it here. The right way would be immutable Category category_; Rebindable!(immutable Category) instance() { return rebindable(category_); } it is equivalent and shorter (for the lazy) to write auto instance() { return rebindable(category_); } The disadvantage of this form is that the reader of documentation generated automatically from the source file will only see this : auto instance() and he won't know what this instance method effectively returns. If we want a mutable reference that accept mutable and immutable Category objects, we should define this Rebindable!(const Category) x = Category.instance(); x = new Category; The concept of immutable and constness of D was the most difficult thing to learn because it is radically different from the const concept of C and C++. Now that I understood it and stopped getting hit with immutability and constness compiler errors, I start to like it. So the only problem I see with Rebindable is the inefficiency of reference comparison in the generated assembly code with DMD64 D Compiler v2.071.0. This will hopefully get fixed in next versions. Thank you very much to everybody who took the time to help me learn D and answer my so many questions.
Re: is my code to get CTFE instantiated object valid D ?
On Saturday, 28 May 2016 at 21:21:34 UTC, ag0aep6g wrote: On 05/28/2016 09:54 PM, chmike wrote: The only inconvenience left is that we can't have mutable references to immutable objects. There is std.typecons.Rebindable for that. That would be a good news. What is the right way to use it ? I had a hard time to understand how to use Rebindable. Rebindable!(immutable Category) instance( return Rebindable!(immutable Category)(instance_); } Or should, I do it like that ? Rebindable!(const Category) instance( return Rebindable!(const Category)(instance_); } The immutable and const concepts are really different from C and C++. A problem with rebindable is that its current assembly translation for 'is' test does a byte per byte comparison which is much less efficient than a direct 64bit comparison of the struct. I checked that with dmd. I don't know about gdc and ldc. This is something that will,be optimized soon I hope.
Re: is my code to get CTFE instantiated object valid D ?
On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote: I need to create an app wide singleton instance for my class. The singleton is immutable, but I want to allow mutable references to that singleton object so that I can do fast 'is' tests. I declared this class Category { protected static immutable Category instance_ = new Category; Category instance() { return cast(Category)instance_; } ... } It compiles and the instance should be instantiated at compile time. I couldn't check yet. The public interface of Category is designed so that the object's state can't be modified and thus remains immutable. Is this code valid D or is the behavior undefined due to the cast ? A variant implementation would have a method that modifies the object but only internally and in a very controlled way to store strings in a cache for faster access. Would it still be valid D code ? I answer to myself on this question because I finally found out. Creating an app wide singleton object is as simple as this class Category { this() { assert __ctfe); } // Just to make sure private __gshared instance_ = new Info; static Category instance() { return _instance; } } It works as long as the constructor doesn't reference other global or static variables. Unfortunately this is what I have in my use case. I had this final class Info { Info(Category category, string name) { category_ = category; name_ = name; assert(__ctfe); } private string name_; private Category category_; string name() { return name_; } Category category() { return category_; } } This class can't be instantiated as compile time because the constructor depends on the global variable Category.instance_. Category { ... __gshared Info a1 = new Info(Category.instance(), "I'm a1"); __gshared Info a2 = new Info(Category.instance(), "I'm a2"); ... } The problem is solved by changing Category into an immutable class and instance. It's Ok in my case because it is immutable. The only inconvenience left is that we can't have mutable references to immutable objects. But at least now I can write Info x1 = Cateqory.a1, x2 = Category.a2; Info x3 = x1, x4; assert(x3 is x1); assert(x3 !is x2); assert(x1.category is x2.category); assert(x4 is null); And of course we can also access all the properties of the Info values. Objects are identified by their unique address. Another problem left is that synchronization
Is it possible to forbid synchronization on an object ?
In my long quest to implement a flyweight pattern with objects instantiated at compile time, I was indirectly notified of the possible problem of synchronization. In a flyweight pattern the user has the impression there are distinct instances where in fact objects with the same state (member variable value) are the same instance. Since with play a trick with the users assumption, there is a high risk that user produces logically invalid code when using synchronization with such a flyweight object. In order to avoid this problem I would need a solution to make synchronization impossible on an object ? It is preferable if this could be enforced at compile time. Is this possible with D ?
Re: is my code to get CTFE instantiated object valid D ?
On Saturday, 28 May 2016 at 08:47:48 UTC, Kagamin wrote: For a trick of static mutable allocation see https://github.com/dlang/druntime/pull/1325 In the following instruction of the above commit, what effect has the [] after init ? _store[0 .. __traits(classInstanceSize, T)] = typeid(T).init[]; T is a template argument that is a class derived from Error. I couldn't find an explanation here https://dlang.org/spec/property.html#init. I saw that this is a concise implementation of what is being done in emplace().
Re: is my code to get CTFE instantiated object valid D ?
On Saturday, 28 May 2016 at 08:47:48 UTC, Kagamin wrote: For a trick of static mutable allocation see https://github.com/dlang/druntime/pull/1325 Thank you that looks promising. I'll study an experiment with the code. If I would like that the instances are not in TLS, can I use the following ? private __gshared void[...] store; I then need to be sure that the objects are instantiated at compile time. Will Emplace do the trick ?
Re: is my code to get CTFE instantiated object valid D ?
On Friday, 27 May 2016 at 21:41:02 UTC, Kagamin wrote: On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote: Is this code valid D or is the behavior undefined due to the cast ? A mutable object can be synchronized on: synchronized(Category.instance){} This will create and store a mutex in the object (sad but true, design taken from java). If the immutable object is in readonly memory, it will crash on write. That is a good argument. Thanks. It would indeed be a good idea to put immutable objects in a read only portion of the code. Would it be different if the object was declared const instead of immutable ? I want compile time instantiation and mutable references to the object. Apparently only immutable and const objects can be instantiated at compile time. I also want an app wide singleton (not stored in TLS). If I use _gshared I apparently wouldn't get a compile time instantitation. It's to implement the flyweight pattern. I don't want to use Rebindable because the assembly code generated by dmd is currently inefficient. Rebindable cast away the const but the non constant reference is not exposed. What is the difference between a const and immutable object ? would a const object be allowed to modify itself by using a hash table or caching results inside ? Is a static const Category c variable a TLS variable ? This is a bit frustrating because it is trivial to implement in C and C++.
is my code to get CTFE instantiated object valid D ?
I need to create an app wide singleton instance for my class. The singleton is immutable, but I want to allow mutable references to that singleton object so that I can do fast 'is' tests. I declared this class Category { protected static immutable Category instance_ = new Category; Category instance() { return cast(Category)instance_; } ... } It compiles and the instance should be instantiated at compile time. I couldn't check yet. The public interface of Category is designed so that the object's state can't be modified and thus remains immutable. Is this code valid D or is the behavior undefined due to the cast ? A variant implementation would have a method that modifies the object but only internally and in a very controlled way to store strings in a cache for faster access. Would it still be valid D code ?
Effect of declaring a class immutable ?
I couldn't find any information about this on the dlang web site. What is the effect adding the immutable attribute to a class like this immutable class MyClass { ... } The compiler doesn't complain. Will it add the immutable attribute to all members ?
Re: Problem with .debug info in program
After closer examination it seam that the second line with 9 is a bogus insertion. Removing it should fix the code line table. app.d 90x43aafb app.d 110x43aafe app.d 9 0x43ab08 <= to remove app.d 130x43ab10 app.d 150x43ab24
Problem with .debug info in program
Hello, I've notice that gdb was improperly displaying source lines with disassembled code. I looked at the assembly to check what is inlined and what not and the difference between the use of is and == in the machine code. I then tested with objdump with a simple program and saw the same problem. Here is the source code displayed with $ nl -da app.d and adding a white space in empty lines because it doesn't count empty lines even with option -ba. 1import std.stdio; 2 3void main() 4{ 5int a = 10; 6 7a += 3; 8 9++a; 10 11writefln("Value: %d", a); 12 13writeln("Helloworld!"); 14 15} This is the output of $ objdump --dwarf=decodedline app.o | less CU: app.d: Nom fichier Num ligne Adresse début ./app.d:[++] app.d3 0 app.d5 0x8 app.d7 0xf app.d9 0x13 app.d 11 0x16 app.d9 0x20 app.d 13 0x28 app.d 15 0x3c ... This is the output I get with $ objdump -d -S app > app.txt for the function _Dmain. 0043aae8 <_Dmain>: import std.stdio; void main() 43aae8: 55 push %rbp 43aae9: 48 8b ecmov%rsp,%rbp 43aaec: 48 83 ec 10 sub$0x10,%rsp { int a = 10; 43aaf0: c7 45 f8 0a 00 00 00movl $0xa,-0x8(%rbp) a += 3; 43aaf7: 83 45 f8 03 addl $0x3,-0x8(%rbp) ++a; 43aafb: ff 45 f8incl -0x8(%rbp) writefln("Value: %d", a); 43aafe: ba 60 e5 46 00 mov$0x46e560,%edx 43ab03: be 09 00 00 00 mov$0x9,%esi { int a = 10; a += 3; ++a; 43ab08: 8b 7d f8mov-0x8(%rbp),%edi 43ab0b: e8 18 00 00 00 callq 43ab28 <_D3std5stdio19__T8writeflnTAyaTiZ8writeflnFNfAyaiZv> writefln("Value: %d", a); writeln("Helloworld!"); 43ab10: ba 6a e5 46 00 mov$0x46e56a,%edx 43ab15: bf 0b 00 00 00 mov$0xb,%edi 43ab1a: 48 89 d6mov%rdx,%rsi 43ab1d: e8 e6 9b 00 00 callq 444708 <_D3std5stdio16__T7writelnTAyaZ7writelnFNfAyaZv> 43ab22: 31 c0 xor%eax,%eax } 43ab24: c9 leaveq 43ab25: c3 retq 43ab26: 66 90 xchg %ax,%ax 0043ab28 <_D3std5stdio19__T8writeflnTAyaTiZ8writeflnFNfAyaiZv>: } As you can see the source lines don't match the assembly after ++a. I have the impression the error is in the debug line number table. The jump from 11 back to 9 look suspect. This is also where the source line display with disassembled code start to get bogus. I get a similar output with gdb. I can't determine if the problem is in libdwarf or in the .debug info in the file because it's beyond my competence. Is this normal ? I guess it confuses debuggers and render them useless.
Re: Problem with .debug info in program
Here you have the object lines from app with the addresses. ./app.d:[++] app.d 30x43aae8 app.d 50x43aaf0 app.d 70x43aaf7 app.d 90x43aafb app.d 110x43aafe app.d 90x43ab08 app.d 130x43ab10 app.d 150x43ab24
Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?
On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote: (This effect could be simulated by making my_var into a function, but i don't want to do that.) May I ask why you don't want to do that ? In D you can call a function without args without (). So if you write private int my_var_ = 4; // where 4 is the default initialization value @property int my_var1() { return my_var_; } final int my_var2() { return my_var_; } int my_var3() { return my_var_; } int x = obj.my_var1; x = obj.my_var2; x = obj.my_var3; my_var3 is virtual so I guess you get the overhead of a virtual method call which is probably not what you want. my_var2 can't be overriden and if it doesn't itself override a method with a same name in a base class the compiler may optimize its call by inlining it. It's like a static method with 'this' passed as argument. I'm not fully sure about my_var1. I'm still a beginner, but I think the compiler will optimize it into inlined instruction if it can as for my_var2. Making the user accessing the member variables directly may look like it's more efficient, but it's bad API design because you can't change the class implementation affecting my_var_ without breaking the API. The D way enforces good programming and API design and optimizes as much as possible.
Re: mutable keyword
There is a benefit in not allowing to get pointers to class members. It allows to have movable object instances and this give access to some faster GC algorithms like generational garbage collection which is in use in Java. As an old C++ programmer and newbee in D programming, the D constness and immutability concepts are confusing. They are so strong that I hardly see any use for them with objects. There would be a much wider use to be able to tell user that he may assume the object is constant from the interface point of view. This is a huge help in code readability and program validity checking. I had the impression that this is the principle used for the pure keyword. I would vote against the introduction of the mutable keyword as it exist in C++ because it is a half backed solution. First it tells the compiler that this variable is modifiable at any time by any method of the class. This is way I always felt uncomfortable using mutable. It punches a big hole in the constness protection. The other problem is with inheritance (I know it's old school, but ok). If a derived class needs to modify a member variable of a base class that wasn't declared mutable, you're stuck. That is why C++ introduced the const_cast. This is much better in that the hole in the constness protection is very limited, but the code is also less pleasant to read. How could be the D way to solve this ? My feeling is that it could be by introducing a mutate{...} block. All instructions in that block would be allowed to modify the const object. The developer intent would be clear, the code readable and the hole limited. The difference with the C++ model is that in C++ we switch off the constness flag of member variables for a persistent or short time, in D we would switch off constness control in a block of instructions. I didn't thought of all the implications yet. I only talked about const objects. I still need to find a use case for immutable objects /S
Re: problems with Rebindable
On Saturday, 21 May 2016 at 13:17:11 UTC, ag0aep6g wrote: On 05/21/2016 12:42 PM, chmike wrote: Rebindable!Info x1, x2 = Infos.one; Rebindable!(immutable Info) x1, x2 = Infos.one; Indeed. Thanks. Reading the unit tests in the source code and the implementation of Rebindable helped. Note however that it doesn't work with immutable. It only works with constant. I guess this is because immutable is "stronger" than const. I determined that only const was supported by looking at Rebindable's code. Here is the code that finally works as I want. The flyweight pattern is thus well supported with the exception that switch can't be used. using static functions to get the Infos.one also allow to implement lazy object instantiation. import std.stdio; import std.typecons; interface IInfo { string toString() const; } // alias Rebindable!(immutable IInfo) Info; <-- Doesn't compile alias Rebindable!(const IInfo) Info; class Infos { static class Obj : IInfo { this(string msg) { this.msg = msg; } private string msg; override string toString() const { return msg; } } static Info one() { static auto x = Info(new Obj("I'm one")); return x; } static Info two() { static auto x = Info(new Obj("I'm two")); return x; } } void main() { Info x1; Info x2 = Infos.one; assert(x1 is null); assert(x2 !is null); assert(x2 is Infos.one); assert(x2 == Infos.one); x1 = x2; assert(x1 is x2); assert(x1 == x2); assert(x1 is Infos.one); assert(x1 == Infos.one); writeln(x1); Info x3 = Info(new Infos.Obj("I'm one")); assert(x1 !is x3); assert(x1 != x3); // Because there is no opEqual for deep equality test IInfo o1 = new Infos.Obj("I'm one"), o2 = new Infos.Obj("I'm one"); assert(o1 !is o2); assert(o1 != o2); // What I need for the flyweight pattern /* -- Doesn't compile : x1 is not a string or integral value switch(x1) { case Infos.one: writeln("case Infos.one"); break; default: writeln("default"); break; } */ } I wasn't indeed using Rebindable correctly and it support only const objects, not immutable objects. Thank you everybody for your help.
Re: problems with Rebindable
On Saturday, 21 May 2016 at 10:42:13 UTC, chmike wrote: source/app.d(23,27): Error: cannot implicitly convert expression (one) of type immutable(Obj) to app.Info Apparently Rebindable doesn't support polymorphism. This is hopefully fixable. source/app.d(43,5): Error: 'x1' must be of integral or string type, it is a app.Info source/app.d(45,10): Error: cannot implicitly convert expression (one) of type immutable(Obj) to app.Info A Rebindable variable can't be used as a switch argument. This would require a change to the language rules. However, the static immutable object Infos.one can be used as a case argument. The conclusion is that Rebindable doesn't cover the needs of a mutable object reference. In the flyweight pattern we only need to compare object addresses and we also want to use the lazy pattern to instantiate the immutable instances.
Re: Immutable objects and constructor ?
On Saturday, 21 May 2016 at 08:24:19 UTC, Ali Çehreli wrote: On 05/21/2016 01:07 AM, chmike wrote: > Unfortunately it is not possible to write this > > import std.typecons; > class Info{...} > rebindable!Info x; You have a capitalization typo. Rebindable is a type template, rebindable is a function template. import std.typecons; class Info{} void main() { auto x = rebindable(new immutable(Info)()); pragma(msg, typeof(x)); auto y = Rebindable!(immutable(Info))(new Info()); pragma(msg, typeof(y)); } Ali Thank you. I'll start a new thread with the subject "problems with Rebindable". See https://forum.dlang.org/post/bprfdptcvzzkfzxlh...@forum.dlang.org
problems with Rebindable
This thread is a followup of https://forum.dlang.org/post/vuljzyufphsywzevu...@forum.dlang.org with a refocused subject and question. I'm looking for a mutable reference to a none mutable object to implement the flyweight pattern. It is for a library and its user interface. So I'm not looking for hacks to get around the problem. Here is a toy example showing what I try to achieve and that fails to compile. The main shows what I expect users should be able to do. The aim is to allow the user to define another sets of constants of base type Info in his own class (e.g. MyInfos) and with a different implementation that the one provided in the example class Infos. import std.stdio; import std.typecons; interface Info { } class Infos { static class Obj : Info { this(string msg) immutable { this.msg = msg; } private string msg; string toString() immutable { return msg; } } static immutable one = new immutable Obj("I'm one"); } void main() { Rebindable!Info x1, x2 = Infos.one; assert(x1 is null); assert(x1 == null); assert(x2 !is null); assert(x2 != null); assert(x2 is Infos.one); assert(x2 == Infos.one); x1 = x2; assert(x1 is x2); assert(x1 == x2); assert(x1 is Infos.one); assert(x1 == Infos.one); writeln(x1); switch(x1) { case Infos.one: writeln("case Infos.one"); break; default: writeln("default"); break; } // That is enough for today } Compiling this code with dmd $ dmd --version DMD64 D Compiler v2.071.0 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright I get the following errors: $ dub build Performing "debug" build using dmd for x86_64. testrebindable ~master: building configuration "application"... source/app.d(23,27): Error: cannot implicitly convert expression (one) of type immutable(Obj) to app.Info source/app.d(26,12): Error: use 'is' instead of '==' when comparing with null source/app.d(29,12): Error: use '!is' instead of '!=' when comparing with null source/app.d(43,5): Error: 'x1' must be of integral or string type, it is a app.Info source/app.d(45,10): Error: cannot implicitly convert expression (one) of type immutable(Obj) to app.Info dmd failed with exit code 1.
Re: Immutable objects and constructor ?
Since I'm trying to implement a flyweight pattern, the opEqual need only comparision of reference in my case. By the way, what operation is the switch performing ? OpEqual or is ?
Re: Immutable objects and constructor ?
Unfortunately it is not possible to write this import std.typecons; class Info{...} rebindable!Info x; I get the following error message source/app.d(11,3): Error: template std.typecons.rebindable matches more than one template declaration: /usr/include/dmd/phobos/std/typecons.d(1675,14): rebindable(T)(T obj) if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T) and /usr/include/dmd/phobos/std/typecons.d(1694,14): rebindable(T)(Rebindable!T obj) This would have been equivalent to define a mutable reference to an object of type Info and allow me to write this alias rebindable!Info InfoR; InfoR x; Unfortunately I didn't manage to get something compiling with rebindable. I don't understand how I'm supposed to use it. Note that I'm designing a library that I would like intuitive to use. Hacking around the problem won't cut it. I need a type defining a mutable reference to an immutable object. Rebindable doesn't give me that apparently. I need something allowing me to write this interface Info {...} class MyInfos { static class Obj : Info {...} static immutable Obj one = new immutable Obj(...); } mutableObjectRef!Info x1, x2; assert(x1 is null); assert(x1 == null); x1 = MyInfos.one; assert(x1 is MyInfos.one); assert(x1 == MyInfos.one); x2 = x1; switch(x1){ case MyInfos.one: ... ; default:...; } x1 must have the semantic of an object reference, support polymorphism, allowing to down or up cast and of course access immutable members and methods. MyInfos.one is an object reference that I shouldn't be allowed to modify. I can't use a function because it needs the value semantic so I can use it as a case argument in a switch. It doesn't seam that this is what rebind provides. It looks like mutableObjectRef should be a templated struct. But I'm not experienced enough in D to implement it. I don't know if its only possible.
Re: Immutable objects and constructor ?
On Friday, 20 May 2016 at 17:35:01 UTC, Kagamin wrote: On Friday, 20 May 2016 at 16:09:54 UTC, chmike wrote: But I now met another error in my main(). I can't assign the immutable object to a mutable reference. Info x1 = MyInfos.one; Is it possible to define a mutable reference to an immutable instance ? Sort of possible with a library solution: import std.typecons; auto x1 = rebindable(MyInfos.one); I'm a bit surprized that the language doesn't support this. We have immutable strings that can be assigned to different variables. Why couldn't we do the same with objects ? This rebindable is not user friendly. I really wish the user could write this Info x = MyInfos.one; I may achieve this if Info is defined as a struct with a single member defined as rebindable.
Re: Immutable objects and constructor ?
On Friday, 20 May 2016 at 15:43:28 UTC, Marc Schütz wrote: It looks like your don't actually need `Obj` to be a real nested class. Try declaring it as `static Obj : Info { }`. This should work if `Obj`'s methods don't need access to `MyInfo`'s non-static members. That worked great. Thank you. The only problem left is how I can get mutable references to immutable objects.
Re: Immutable objects and constructor ?
I solved the problem by moving the class Obj definition out of the class MyInfo. I still don't understand why I had to do that. In C++ this would work without problem. I now have interface Info {. . .} class Obj : Info {. . .} class MyInfos { . . . static immutable Obj one = new immutable Obj(...); static immutable Obj two = new immutable Obj(...); . . . } This now compiles without a peep. But I now met another error in my main(). I can't assign the immutable object to a mutable reference. Info x1 = MyInfos.one; Is it possible to define a mutable reference to an immutable instance ? This is confusing and frustrating. In C++ we can write MyInfos { . . . // one is a constant pointer to a constant object of type Obj Obj const * const one; . . . } And in main() Info const * x1 = MyInfos.one; x1 i a modifiable pointer to a constant object of type Info. Is this possible in D ? I couldn't find how to do that.
Re: Immutable objects and constructor ?
The error message is gone, but I now have another compilation error message I don't understand. This is what I have in fact interface Info { . . . } class MyInfos { . . . protected: class Obj : Info { . . . } public: static immutable Obj one = new immutable Obj(...); static immutable Obj two = new immutable Obj(...); } I get a compiler error in the two assignments to the static Obj member variables: 'this' is only defined in non-static member functions, not MyInfos Is it related to the fact that the Obj class is encapsulated ? My goal is to be able to write things like this: void main() { Info x1 = MyInfos.one, x2 = MyInfo.two, x3; assert(x3 is null); x3 = x1; assert(x3 is x1); assert(x3 is MyInfo.one); // Use static immutable instance references as case arg in switch switch(x1) { case MyInfo.one: ...; } }
Immutable objects and constructor ?
I'm implementing the flyweight pattern. It means that I have a set of object instances representing all the possible values. This allows me to manipulate "values" by simply manipulating references to the instance. Testing "value" equality boils down to simply compare reference value. I hope I can use these immutable instances as case argument of a switch, but I'm not there yet. I have declared an immutable class. immutable interface SomeInfo { ... } immutable class Info : SomeInfo { @disable this(); this(int codeValue, string codeName) { codeValue_ = (codeValue * 10) - 113; // some random example computation codeName_ = "Info."~codeName_; } private: int codeValue_; string codeName_; } But when I try to instantiate the class I get an dramatic compilation error: "none of the overloads of '__ctor' are callable using a mutable object, candidates are: " Adding immutable to the constructor doesn't help. How can I initialize the immutable instances of a class ? I have seen it is possible to cast away the immutability. Does it also work for immutable classes ? Could I use an object factory ? How should I do if I would like to use the lazy pattern for initializing some member variables of the instance ? Something like : immutable class Info : SomeInfo { ... string toString() { if (!toString_) synchronize { // make it thread safe if (!toString_) toString_ = format("bla bla %s (%d)", codeName_, codeValue_); } return toString_; } ... private: string toString_; }
Re: static member and/or @property ?
On Thursday, 19 May 2016 at 15:33:21 UTC, ag0aep6g wrote: . . . interface AThing { final string name() { return nameImpl(); } string nameImpl(); } class OneThing : AThing { static string name() { return "OneThing"; } override string nameImpl() { return name(); } } class OtherThing : AThing { static string name() { return "OtherThing"; } override string nameImpl() { return name(); } } This is what I was looking fer. Thank you very much. The fact that I used the class name is just a coincidence for making the example clear.
static member and/or @property ?
Sorry for the confusing subject, I couldn't find a concise formulation of my question. I have a set of classes derived from the same interface so that I can use polymorphism. I would like to store the name of the class as a string so that it can be retrieved as a static member of the class or by using polymorphism. Here is the problem expressed as an exercise where you are invited to replace the ??? with the appropriate text, if it is possible. My blind and naive attempts failed. interface AThing { ??? string name ??? } class OneThing : AThing { ??? string name ??? "OneThing" ??? } class OtherThing : AThing { ??? string name ??? "OtherThing" ??? } void main() { // Accessing name as static information writeln(OneThing.name ??? ); // Accessing name through polymorphism AThing tbl; tbl ~= new OneThing; tbl ~= new OtherThing; tbl ~= new OneThing; foreach(a; tbl) writeln(a.name???); } The only viable solution I found so far is by using distinct member names. In the interface we define name as a property, and in the class we define the static member with another name. Is it possible to avoid the different names ?
ErrorException thrown when errno is modified ?
Hello, I'm planning to call some posix functions core.sys.posix that may set the errno value in case of error. e.g. read() or write(). Checking the std.exception documentation I see that ErrnoException may be thrown when errors setting errno may occur. Does this affect the posix calls ? From what I saw in the code, it doesn't seam the case. Just making sure I'm correct.
How to find the content of core.sys.* ?
Hello, The nice and handy documentation of dlang doesn't provide any info on the core.sys. How can I find out all the things that are in there ?
Re: D equivalent of C++ bind ?
On Monday, 16 May 2016 at 15:57:52 UTC, Dsby wrote: you can remove "auto ref". and I remove the "auto ref" in my use. if used the "alias T", It can not handle all while when the T is a delegate. in C++ std::bind, the arguments order you can sort by used. in D I do not find how to enablement. Yes this doesn't look easy. Maybe by using a mixin. Unfortunately this slows down compilation. I don't know the impact on optimization. I'm not sure if converting a function to a delegate is a good thing. It is good for your use case where the bind functions are used as callbacks. But sometime, users may really want to create a function. The user should then use ToDelegate! If he wants to convert the function to a delegate. But from the the documentation, ToDelegate doesn't work with functions with the @safe attribute.
Re: D equivalent of C++ bind ?
On Thursday, 12 May 2016 at 10:38:37 UTC, Dsby wrote: I write one, bind functon to a delegate. In here: https://github.com/putao-dev/collie/blob/master/source/collie/utils/functional.d this is the code: auto bind(T,Args...)(auto ref T fun,Args args) if (isCallable!(T)) { alias FUNTYPE = Parameters!(fun); static if(is(Args == void)) { static if(isDelegate!T) return fun; else return toDelegate(fun); } else static if(FUNTYPE.length > args.length) { alias DTYPE = FUNTYPE[args.length..$]; return delegate(DTYPE ars){ TypeTuple!(FUNTYPE) value; value[0..args.length] = args[]; value[args.length..$] = ars[]; return fun(value); }; } else { return delegate(){return fun(args);}; } } Thank you. Would you agree to help me understand it ? The only thing I don't understand is why the function template argument is defined as T and the argument as auto ref T fun. Why the auto ref and not alias T in the template argument list ? This bind is better than Partial!() from std.functional since it accepts any number of parameters. But the given parameters are passed as first arguments of fun. The std::bind of C++ allows to bind any parameter in any order and eventually multiple times. It's really as if a new function was defined with a total liberty degree on its signature. Anyway thank you very much.
Re: D equivalent of C++ bind ?
Thanks. This does the job but it's not as concise.
Re: Async or event library
vibed uses libevent, a C library. The discussion is regarding a possible pure D equivalent of libevent. libasync is an interesting proposal but it is apparently slower than libevent. I don't know the current status because vibed improved its performance in the last months. My initial question is if there is a working group I could join to work on this pure D async library. I'm interested in working on the subject.
D equivalent of C++ bind ?
Is there an equivalent in D of the C++11 std.bind template class [http://en.cppreference.com/w/cpp/utility/functional/bind] ? Here is a blog post showing different examples of its use https://oopscenities.net/2012/02/24/c11-stdfunction-and-stdbind/ A possible use case is for a callback function/delegate with the expected signature bool cb(int error). I would like to pass a function bool myCb(int error, ref int myArg) instead with the variable myArg being given as predefined argument. Here is an example. int count = 0; bool myCb(int error, ref int myArg) { if (myArg >= 6) return false; writeln(++myArg); return true; } void async_task(void function(int error) cb) { . . . while cb(0) . . . } void main() { . . . async_task( ??? myCb ??? count ??? ); . . . } In C++ we would write async_task(std::bind(myCb, std::placeholders::_1, count));
Re: Async or event library
It seam that the scope of the event loop we are talking should be clarified to avoid confusions. There is the GUI event loop which is generally single threaded for efficient access to the data structure representing the GUI content. Single thread also simplifies synchronization and make deadlocks impossible. GUI events incoming rates are generally slow because it is human driven. So a single threaded GUI event loop is a very reasonable choice. The other event loop is for IO and timers. In this case the event rate can be very high and the speed is critical. This is where multithreading can play a useful role and the topic I am interested with. On unix the OS provides a fast select (epoll, kevent) which tells the user on which fd an event occurred. epoll doesn't cover asynchronous file operations and timer events. On Windows the OS provides IOCP which support queued operations and the user is notified of the completion. The boost asio lib adopted the IOCP model. Users queue asynchronous tasks and a callback function that is executed when the task is completed. That is also the model of I/O or timer event loops (e.g. libev, libuv, libevent). Unfortunately it seam that we don't have much liberty degree if we want an API that can work on Windows and unix. But the unix model can be more efficient. Here is a blog post reporting that the author could implement a more efficient system than libuv by using epoll directly http://blog.kazuhooku.com/2014/09/the-reasons-why-i-stopped-using-libuv.html.
Re: Async or event library
Excuse the naive question rikki, why does the window event loop have to be single threaded ? The question is just to expose the rationale. Is it to avoid the synchronization overhead to access the window data ? In this case there is indeed a lot of data. Is there another reason ? In some applications and event types the synchronization overhead is small compared to the benefit of executing tasks in parallel on different cores. It is indeed none trivial and could be an interresting phd study subject.
Re: Async or event library
On Thursday, 5 May 2016 at 09:21:04 UTC, rikki cattermole wrote: Event loops needs to be thread local not per process. So many API's such as WinAPI for e.g. GUI's have this requirement in it that its just not worth fighting over. I don't understand. Do you mean that these event loops are single threaded and thus don't allow multi threaded use and parallel event handling ? Single threaded model avoids the overhead of synchronization. That would be another strong argument in favor of single threaded event loop. And another one is that single threaded application is much easier to get right than multi threaded applications. On the other side, WinAPI is old and the actual hardware evolution goes toward multi core computers and massive true parallelism. At CERN we use 16 core computers. Of course it's good to be backward compatible with existing APIs but D should be designed to best match the future of computing I think. So it seam the question boils down to determine if it's possible to have the best in both worlds. I agree that event loops working in isolation is the most simple API from the user perspective and is the most efficient since synchronization can be avoided. But worker thread pools has also its advantages when the app is running on a multicore computer.
Re: Async or event library
I would like to add that the switchable TLS is only a half backed solution. It would't work in a multi core context where threads are truly executing in parallel. Two such threads might get the same TLS context which would invalidate its implicit predicate. Another strategy would be to forbit use of TLS with threads using the event loop. But this might break existing code.
Async or event library
Hello I have seen the wiki page https://wiki.dlang.org/Event_system and would like to know the current status. Is there a working group for this subject ? This is a topic I'm interested in and did some modest work on some years ago. At the bottom of the wiki page there is an innocent question regarding TLS which is quite devastating. A worker thread pool system would not support affinity between threads and callback context. Unfortunately, D relies on Thread Local Storage for semi global data. This would be error prone. I saw such error case with people using TLS with Corba. One way out of this apparent deadlock is if D would provide its own TLS that can be switched between threads. This would allow to preserve affinity between threads and callback execution context. Unfortunately, it would introduce an overhead to access the data in the local storage due to the required indirection. It would also require that the compiler is adapted. When fibers and multithreading support is built in the language, as in Go, the compiler can do the magic. I would like to underline that the server side of software development is the easiset side to conquer because the client side as to many different GUIs and execution contexts. But it requieres that the performances are on par with other languages like C, C++, Go or Java.
Accepting function or delegate as function argument
I have implemented the following class (simplified ;) ) class Foo(K,T) { this(T delegate (K) factory) { m_factory = factory; } T delegate (K) m_factory; T bar(K key) { return m_factory(key); } } string dummyFactory(string key) { return "Hello "~key; } void main() { auto foo = new Foo!(string,string)(); writeln(foo.bar("world")); } The compiler complains that dummyFactory is a pointer to a function and not a delegate. How can I modify the class definition so that it accepts a function or a delegate transparently from the user perspective ? Two constructors, one accepting a function and the other one accepting a delegate would do the job for the API. Is there a simple method to convert a function pointer into a delegate pointer that is also efficient ?
Re: Code example for function/delegate as template argument ?
Thank you Basile and Teoh.
Re: Code example for function/delegate as template argument ?
I think you misunderstood the second question. Here is another attempt with an example. // function accepting a function as argument void foo(function void fg(int)) { fg(5); } // A class with a none static method with the same signature as the argument function of foo class Bar { void fizz(int a) { writefln("Arg: %s", a); } } // An instance of class Bar auto bar = new Bar; // Calling foo by passing bar and the method fizz so that bar.fizz() is called when foo calls fg foo( ??? ); Does the argument type need to be a delegate ?
Re: Code example for function/delegate as template argument ?
On Wednesday, 4 May 2016 at 06:59:00 UTC, Basile B. wrote: . . . void main(string[] args) { alias fun = (a) => a.writeln; auto foo = Foo!fun("hello"); } Is this equivalent to Foo!(a => a.writeln) or is it required to split this in two instructions as you did ? I also thought the parenthesis around the lambda arguments are not required. Is that right ?
Code example for function/delegate as template argument ?
Hello, I failed to find some code example for a template class/struct that accept a function/delegate as template argument. All examples I could find use simple value types like int or double. I piggy bag another question. Defining a function/delegate as function argument is shown in examples. What I could not find is how would I pass an object instance with a method to call ? In C++ we use std::bind. How do we do that in D ?
Re: struct cannot deduce function from argument types
Oops! Stupid of me. There were three bugs in the code. Correct code is as follow: import std.stdio; class Data { string m = "Hello world !"; } struct IdxElem(D) { bool inUse; D data; } IdxElem!(Data)[string] idx; void main() { idx["test1"] = IdxElem!Data(true, new Data); idx["test2"] = IdxElem!Data(false, new Data); writeln(idx["test2"].data.m); writeln("Hello world!"); }
struct cannot deduce function from argument types
The following code does not compile and I don't understand why. import std.stdio; class Data { string m = "Hello world !"; } struct IdxElem(D) { bool inUse; D data; } IdxElem!Data[string] idx; void main() { idx["test1"] = IdxElem(true, new Data); idx["test2"] = IdxElem(false, new Data); writeln(idx["test2"].data); writeln("Hello world!"); } This is the error message I get with DMD64 D Compiler v2.068.2 source/app.d(20,27): Error: struct app.IdxElem cannot deduce function from argument types !()(bool, Data), candidates are: source/app.d(9,1):app.IdxElem(D) source/app.d(21,27): Error: struct app.IdxElem cannot deduce function from argument types !()(bool, Data), candidates are: source/app.d(9,1):app.IdxElem(D) dmd failed with exit code 1. I get the same error even if I add a constructor to IdxElem that sets the member variables with its two arguments.
Re: Testing Return Value Optimization (RVO)
Oops found it my self. I had to use auto x = foo();
Re: Testing Return Value Optimization (RVO)
I tried your code as this and it doesn't work. #!/usr/bin/rdmd -O import std.stdio; struct S { int a; @disable this(this); }; S foo() { S v; v.a = 1; writeln(); return v; } void main() { S x; x = foo(); writeln(); } I even tried with dmd -O without success. What am I doing wrong ?
Testing Return Value Optimization (RVO)
Hello, Sorry if this question is a bit naive or shows a misunderstanding of RVO. I was trying to see if my C compiler was doing RVO with struct, but after testing it at is apparently not the case. Since I have heard that D supports RVO I wanted to give it a try in D. But apparently it doesn't do RVO as I expected it would do it. Here is the D code. It is very similar to the C code I tested with gcc and clang : --- #!/usr/bin/rdmd -O import std.stdio; struct S { int a, b; }; S foo(S* p) { S v = {1, 2}; writeln("foo: return value optimization: ", p == ); return v; } void main() { S x; x = foo(); } --- My assumption is the following. x is the target variable where to store the result of foo. I expected that with RVO foo() would receive the address where to store its result as hidden argument. Inside foo(), the optimizer would detect that v, its returned value, will be stored at the location given as hidden argument. It may then optimize out v so that foo() uses x as storage for v. My code is testing if this is the case and it is apparently not. Can someone please explain me why this doesn't work as I would expect RVO to work ?