Re: C++ Interop
On Saturday, 6 January 2018 at 11:20:01 UTC, Seb wrote: On Saturday, 6 January 2018 at 11:17:56 UTC, Seb wrote: On Friday, 5 January 2018 at 13:02:12 UTC, qznc wrote: I'm exploring [0] C++ interop after watching Walter's presentation [1]. [...] I know about this: https://github.com/Remedy-Entertainment/binderoo https://github.com/dlang/druntime/pull/1802 And: https://github.com/dlang/druntime/pull/1316 Also I think Ian (@ibuclaw) and @Razvan7 are currently working on a header generation tool from D sources to C++ headers. It would be great to have std::vector and std::string out of the box in D, but putting it into druntime? Druntime is supposed to be shared among all frontends, isn't it? GCC and Clang probably do not have equivalent vector/string classes that the same D code can be used.
C++ Interop
I'm exploring [0] C++ interop after watching Walter's presentation [1]. I hit a block with classes as template parameters. This means vector works, but vector does not. D seems to map vector!Foo to vector<Foo*>. Likewise shared_ptr is a problem. Any way to fix that on the D side? The ugly workaround is to adapt the C++ code. I understand that this mapping makes sense for function calls because bar(Foo f) in D maps to bar(Foo *f) in C++. And C++ bar(Foo f) has no equivalent in D because classes are reference types. On a related note, C++ interop requires to redeclare or even reimplement C++ code. Has anybody started a libcpp-in-d project? I'm looking for basics like vector and string. [0] https://github.com/qznc/d-cpptest [1] https://youtu.be/IkwaV6k6BmM
Re: Use of "T"
On Wednesday, 12 April 2017 at 13:17:42 UTC, solidstate1991 wrote: How can I make use of T? I've seen it being used many times for this application. What "T"? This letter is often used as a generic template parameter. Are you talking about templates? Maybe you can give some examples of the "many times" you have seen it used?
Dub and bindings
Are there any general tips or best practices for bindings in dub packages? For example, I love the d2sqlite3 package. It just works out of the box. No linker configuration or anything. However, that is probably a testament to sqlite's lack of dependencies. That cannot work for libraries, which rely on other libraries. Should the C code be included in the Github repo? Are submodules fine? Should the C build be invoked by dub via "preBuildCommands"? What about system libraries? Can that be made cross-platform? Should lflags be specified in the dub config or should they be passed via environment variable? There should be a general guide for this. Maybe there already is one?
Re: About spinlock implementation
On Thursday, 1 September 2016 at 10:30:12 UTC, Guillaume Piolat wrote: On Thursday, 1 September 2016 at 07:46:04 UTC, qznc wrote: I find the documentation on MemoryOrder lacking about the semantics of rel. :( [0] https://dlang.org/library/core/atomic/memory_order.html What helped me was to read std::memory_order documentation http://en.cppreference.com/w/cpp/atomic/memory_order Yes, but how do they map? Is D's rel = relaxed or release or acq_rel? Also, reading C++ documentation should not be required of course. ;)
Re: About spinlock implementation
On Thursday, 1 September 2016 at 06:44:13 UTC, mogu wrote: I found an implementation of spinlock in concurrency.d. ``` static shared struct SpinLock { void lock() { while (!cas(, false, true)) { Thread.yield(); } } void unlock() { atomicStore!(MemoryOrder.rel)(locked, false); } bool locked; } ``` Why atomicStore use MemoryOrder.rel instead of MemoryOrder.raw? I'm not sure I understand rel [0], but raw is too weak. Raw means no sequencing barrier, so local_var = protected_value; spinlock.unlock(); could be transformed (by compiler or CPU) to spinlock.unlock(); local_var = protected_value; This effectively makes the access to the protected value unprotected and nullifies the effect of the spinlock. I find the documentation on MemoryOrder lacking about the semantics of rel. :( [0] https://dlang.org/library/core/atomic/memory_order.html
Re: Implementing a cache
On Saturday, 2 July 2016 at 12:21:14 UTC, Lodovico Giaretta wrote: On Saturday, 2 July 2016 at 12:10:28 UTC, qznc wrote: Alternatively, any better idea to implement the cache? I guess there is no off-the-shelf/dub solution. For now, I settled for a sorted array of cache entries plus an AA to map urls to indices into this array. https://github.com/qznc/d-github/commit/46c013c650d2cf34911ad3e10308ee6a0b5e3690#diff-24abb1e4df591f2d28947bbde1a09220R79
Implementing a cache
I want to implement some caching for HTTP GET requests. Basically a map of URL to content. A cache needs some additional meta data (size, age, etc). There seem to be two basic data structures available: Associative array (AA) or red black tree (RBT). With AA cache eviction is inefficient. It requires to sort the keys of the AA with respect to a field in the value. Stack overflow says "use RBT instead" [0]. With RBT retrieving something is inefficient. To get an entry, we need to create an fake entry with the key and get a range of entries 'equal' to the fake one? Or can I exploit some "find on sorted range" algorithm somewhere? Alternatively, any better idea to implement the cache? I guess there is no off-the-shelf/dub solution. [0] https://stackoverflow.com/questions/10060625/how-to-sort-associative-arrays
Re: String compare in words?
On Sunday, 29 May 2016 at 17:42:48 UTC, Era Scarecrow wrote: Worse I'm not sure if the code generation already does that and possibly does a better job than what we could do by hand... Not with dmd v2.071.0 or ldc 0.17.1. At least not in all the variations I tried to trick them with, like copying into fixed-size array. Well, they did insert a memcmp and libc is probably optimized like that, but they copied data first, which is unnecessary.
Re: String compare in words?
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?
Re: String compare in words?
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. This example is simplified and far-fetched. Actually, this is about the find algorithm [1]. [0] http://goo.gl/ttybAB [1] http://forum.dlang.org/post/vdjraubhtoqtxeshj...@forum.dlang.org
String compare in words?
Given two string (or char[] or ubyte[]) objects, I want to compare them. The naive loop accesses the arrays byte-wise. How could I turn this into a word-wise compare for better performance? Is a cast into size_t[] ok? Some Phobos helper functions?
Re: Newbie to D, first impressions and feedback on the 5 (and more) first minutes.
On Wednesday, 25 May 2016 at 09:41:10 UTC, Russel Winder wrote: I do not really have the proper resources to host such a repository and because of this I have not built one. I know I should rather than just moan, but Debian is my main platform and that is covered. Yes, this is the core problem. There is no single person, which (a) cares enough about Fedora and (b) can fix it. Unless this champion appears, Fedora will continue to suck for newbies.
Re: Newbie to D, first impressions and feedback on the 5 (and more) first minutes.
On Tuesday, 24 May 2016 at 15:27:45 UTC, llaine wrote: As written in the description I'm really new to D, I discovered it a few weeks ago thanks to the D Conf in Berlin. After playing around for couple of days with it, I wanted to share my journey with you guys on several points. Thanks for writing this! The "First 5 Minutes" (or days) are an important aspect, which the D community tries to improve. Since active D users already forgot about their first contact with D, the only information on what to improve are newbies telling their experience.
Re: reading file byLine
On Wednesday, 2 September 2015 at 13:46:54 UTC, Namal wrote: On Wednesday, 2 September 2015 at 13:12:39 UTC, cym13 wrote: On Wednesday, 2 September 2015 at 13:01:31 UTC, Namal wrote: Hello, I want to read a file line by line and store each line in a string. I found this example with byLine and ranges. First of all, do I need the range lib at all to do this and if so what is the range of the end of the file? You don't need the range lib at all, std.range provides advanced functions to work with ranges but ranges are a general concept. You need std.stdio though as this is doing file operations. A way to do it is: void main() { auto f = File("myfile"); string buffer; foreach (line ; f.byLine) { buffer ~= line; } f.close(); writeln(buffer); } Note that by default byLine doesn't keep the line terminator. See http://dlang.org/phobos/std_stdio.html#.File.byLine for more informations. Thx, cym. I have a question about a D strings though. In c++ I would just reuse the string buffer with the "=" how can I clear the string after i store a line in the buffer and do something with it. Just like in C++: buffer = line; However, you can just use "line" instead of "buffer" then. The byLine does buffer internally, so it overwrites "line" on the next iteration of foreach. If you want to keep the line string, then make a copy "line.idup". I also tried to append a line to an array of strings but it failed because the line is a char? Here is how to get an array of lines: import std.stdio; void main() { auto f = File("myfile"); string buffer[]; foreach (line ; f.byLine) { buffer ~= line.idup; } f.close(); writeln(buffer); }
Profiling with LDC/GDC?
Is it possible to profile with LDC/GDC? At least LDC lists it as only an "idea". http://wiki.dlang.org/LDC_project_ideas
Re: linking external libs
On Thursday, 2 July 2015 at 12:10:52 UTC, Nicholas Wilson wrote: Also is there a binding to GMP somewhere? I just hacked one together. I could need the bindings to fix the pidigits benchmark. There is this 7y old code on dsource: http://www.dsource.org/projects/bindings/browser/trunk/gmp The readme says This is in alpha state. All functions that have been tried seem to work. (8 out of many), so not that confident.
Packing enums
I stumbled upon this interesting programming challenge [0], which imho should be possible to implement in D. Maybe someone here wants to try. Task: Given two enums with less than 256 states, pack them into one byte and provide convenient accessor functions. Something like this: enum X { A, B, C }; enum Y { foo, bar, baz }; alias both = TwoEnums!(X,Y); static assert(both.sizeof == 1); both z; z.X = B; z.Y = bar; Of course, you can generalize to n enums packed into a minimal number of bytes. [0] https://news.ycombinator.com/item?id=9800231
Re: std.container.Array deep-copy?
On Friday, 10 October 2014 at 06:27:35 UTC, yazd wrote: On Thursday, 9 October 2014 at 21:24:55 UTC, qznc wrote: On Thursday, 9 October 2014 at 21:14:46 UTC, qznc wrote: How can you deep-copy a std.container.Array instance? Ok, the deep-copy problem already got resolved on reddit: Use dup. However, the error is still open. You cannot give an Array!X argument to constructor/replace/insertBefore of Array!X instances? You will just need to slice it to provide a range. Like the following? That did not work. Array!Foo y = Array!Foo(x[]);
Re: std.container.Array deep-copy?
On Friday, 10 October 2014 at 10:59:59 UTC, Sag Academy wrote: On Friday, 10 October 2014 at 10:32:17 UTC, yazd wrote: Like the following? That did not work. Array!Foo y = Array!Foo(x[]); How does it not work? It compiles successfully: http://dpaste.dzfl.pl/583d20e426a0 yeah man. You are right. Sorry. I probably messed up my test file somehow.
std.container.Array deep-copy?
How can you deep-copy a std.container.Array instance? The actual array data is heap-allocated and reference-counted. Assignment and .dup only create additional references. Using a copy constructor yields an error: Array!Foo x; Array!Foo y = Array!Foo(x); Error: template std.container.Array!(Foo).Array.__ctor cannot deduce function from argument types !()(Array!(Foo)), candidates are: /opt/compilers/dmd2/include/std/container.d(2652): std.container.Array!(Foo).Array.__ctor(U)(U[] values...) if (isImplicitlyConvertible!(U, T)) /opt/compilers/dmd2/include/std/container.d(2670): std.container.Array!(Foo).Array.__ctor(Stuff)(Stuff stuff) if (isInputRange!Stuff isImplicitlyConvertible!(ElementType!Stuff, T) !is(Stuff == T[])) The question came up in a reddit discussion: http://www.reddit.com/r/programming/comments/2ipdpa/floss_weekly_311_the_d_language/cl4yv8w
Re: std.container.Array deep-copy?
On Thursday, 9 October 2014 at 21:14:46 UTC, qznc wrote: How can you deep-copy a std.container.Array instance? Ok, the deep-copy problem already got resolved on reddit: Use dup. However, the error is still open. You cannot give an Array!X argument to constructor/replace/insertBefore of Array!X instances?
Re: Idiomatic D?
On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote: On Thursday, 30 January 2014 at 20:10:01 UTC, Dicebot wrote: On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote: I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D? There is no official idiomatic style like, for example, in python. When I speak about idiomatic D I usually think about style Phobos is written in (omitting legacy modules) as it is the code that gets most attention from most experienced D developers. Got any tips? http://qznc.github.io/d-tut/idiomatic.html
Re: A little of coordination for Rosettacode
I just made some scripts [0] to download and compile all D examples from Rosettacode. From 186 of 716 examples fail to compile [1]. Some for trivial reasons like not wrapped into a main function or a missing import. Some require SDL or Tango or other third-party libraries. My ultimate goal was to use this for regression testing dmd. Anyways if people try code examples they should compile out of the box for good PR. If you are looking for a low-barrier way to support D a little, feel free to check out the fail list [1] and fix some. :) [0] https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master [1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694
Re: A little of coordination for Rosettacode
On Thursday, 16 January 2014 at 01:11:23 UTC, bearophile wrote: - To test the compiler betas to see if they have regressions if you try to use the new features. This sounds somewhat paradox to me. How can a new feature have a regression? A regression means it has worked before, but new feature did not exist before. Maybe the question is about before? In my understanding before is latest release, whereas current is beta release or git HEAD. Do you mean before as something like commit deadbeef~4 whereas current is commit deadbeef? I see nothing wrong with using code from Rosettacode to try out new features. It is weird though, if people want to test an example, you have to tell them to compile dmd from git. In practice the difference between the uses is not that important I think, because the sheer number of code snippets and release frequency means that most examples can be compiled with the latest release no matter what bearophile does. ;) Btw are your scripts public, bearophile?
Re: Why is string.front dchar?
And a short overview over Unicode in D: http://qznc.github.io/d-tut/unicode.html
Re: Value or Reference Semantics Trait
On Sunday, 12 January 2014 at 20:16:15 UTC, Nordlöw wrote: Is there a trait to check whether a type has value or reference semantics? I need this in a template struct that adaptively (using static if) represent histogram bins as either a dense static array or a sparse associative array. No, afaik. However, the question goes deeper than you might have though. You probably want to distuingish between structs+scalars vs classes. However, what about ref-arguments? Mutable arrays are struct values, but have reference semantics. Immutable-value arrays (e.g. string) have value semantics. You could use one version as default and define special cases via some stuff you find in std.traits.
stringpool / string interning
I would like to efficiently compare lots of strings. The usual approach is String-interning as Java calls it. After a string is interned they can be compared via just a single pointer comparison instead of comparing char by char. I have not found anything like that in Phobos. Somebody already implemented something like this?
Re: Learning D as main systems programming language
On Wednesday, 8 January 2014 at 23:38:31 UTC, Goran Petrevski wrote: I'm new in the programming, systems programming especially, but I want to learn D more as a systems programming language and by that I mean avoiding libraries at all. My goal is to write a simple operating system totaly in D (using Assembly wherever is needed) and by progressing in that project, learning this powerfull language as the main systems programming language. Any help/advice on this goal will be really helpful/appreciated. Thanks in advance. You might want to look into XOmB: https://github.com/xomboverlord/xomb
Re: Dub and GtkD
On Saturday, 21 December 2013 at 14:52:08 UTC, Russel Winder wrote: I just created a new vibe.d project using dub, all fine. Well once I had solved the libevent problem. Then, as the project is to be a GUI client, I added a gtk-d dependency. I tried building the empty project and the binary comes out at 42MB. Not only that there are two copies of it one in . and one in ./.dub/build. I was gobsmacked, this isn't Go, there should be dynamic linking by default. Is this something I have missed? There ought to be a clean target for dub as well as a build and run target for dub, or have I missed something? Re GtkD, when I run the Hello World vibe.d web server with GtkD doing nothing, I get: | dub Checking dependencies in '/home/users/russel/Repositories/Git/Masters/ArcamClient_D' Target is up to date. Skipping build. Running ./arcamclient Listening for HTTP requests on ::1:8080 Listening for HTTP requests on 127.0.0.1:8080 Please open http://127.0.0.1:8080/ in your browser. object.Exception@../../../../.dub/packages/gtk-d-master/src/gtkc/Loader.d(127): Library load failed: libgtkglext-3.0.so.0 Error: Program exited with code 1 In an earlier thread here, Mike Wey's response was download libgtkglext and build it yourself. I am not sure this is the right approach. Debian packages GNOME 3 quite well but they do not have this libgtkglext-3.0.so.0 and yet things work. I think mayhap GtkD should have this as an optional dependency rather than a mandatory one. Or am I missing something? For some reason GtkD uses some unreleased version of Gtk with some OpenGL features. You can use the normal/stable variant by adapting your dependency a little: dependencies: { gtk-d:gtkd: ~master } Not sure, why GtkD does this. There are also no versions, just ~master.
Re: Language Support - Read and Write
On Sunday, 15 December 2013 at 08:41:42 UTC, Siavash Babaei wrote: Is it not possible to read and write in non-latin languages like Hebrew, Arabic, Farsi, etc?! If so, how, and if not, why? D source files are UTF-8. You can name your variables and functions using the fullw wealth of Unicode. D provides the string type (and others) for Unicode data. D has no problem with Hebrew, Arabic, Farsi, etc. Does that answer your question?
Re: Ranges: is it ok if front is a data member?
On Thursday, 12 December 2013 at 21:55:20 UTC, Ali Çehreli wrote: The third condition that is checked to determine whether it is an OutputRange is indeed assignment to front. http://dlang.org/phobos/std_range.html#.put That condition is what makes a slice an OutputRange, which causes the super confusing state of output range losing elements after put'ting: :) import std.range; void main() { auto s = [ 1, 2, 3 ]; s.put(10); assert(s.length == 2); // PASSES! :p } Ouch. That surely is confusing. Why don't arrays provide .put which appends the element?
Re: Template resolution and interfaces
On Tuesday, 10 December 2013 at 17:50:45 UTC, Torje Digernes wrote: http://pastie.org/8542555 Compositing an class via curry fails when I try to use interfaces. Guessing that this is due to when classes are validated for interface implementation and when templates are instantiated. I thought this was a cool optional way to build/composite classes instead of wrappers. Don't think it has inherent advantages (except that trivial wrappers look silly), just another way to do it. Any chance I can do this anytime soon? Or already by writing somewhat smarter? Your code creates an alias, which only exists at compile-time but not at run-time. The compiler error interface function 'void mpriority()' is not implemented is correct. A naive implementation is straightforward: void mpriority() { priority(myData); } Why do you want to use curry?
Re: Stream-Based Processing of Range Chunks in D
On Tuesday, 10 December 2013 at 09:57:44 UTC, Nordlöw wrote: I'm looking for an elegant way to perform chunk-stream-based processing of arrays/ranges. I'm building a file indexing/search engine in D that calculates various kinds of statistics on files such as histograms and SHA1-digests. I want these calculations to be performed in a single pass with regards to data-access locality. Here is an excerpt from the engine /** Process File in Cache Friendly Chunks. */ void calculateCStatInChunks(immutable (ubyte[]) src, size_t chunkSize, bool doSHA1, bool doBHist8) { if (!_cstat.contentsDigest[].allZeros) { doSHA1 = false; } if (!_cstat.bhist8.allZeros) { doBHist8 = false; } import std.digest.sha; SHA1 sha1; if (doSHA1) { sha1.start(); } import std.range: chunks; foreach (chunk; src.chunks(chunkSize)) { if (doSHA1) { sha1.put(chunk); } if (doBHist8) { /*...*/ } } if (doSHA1) { _cstat.contentsDigest = sha1.finish(); } } Seemingly this is not a very elegant (functional) approach as I have to spread logic for each statistics (reducer) across three different places in the code, namely `start`, `put` and `finish`. Does anybody have suggestions/references on Haskell-monad-like stream based APIs that can make this code more D-style component-based? You could make a range step for each kind of statistic, which outputs the input range unchanged and does its job as a side effect. SHA1 sha1; src.chunks(chunkSize) .add_sha1(doSHA1, sha1) .add_bhist(doBHist8) .strict_consuming(); You could try to use constructor/destructor mechanisms for sha1.start and sha1.finish. Or at least scope guards: SHA1 sha1; if (doSHA1) { sha1.start(); } scope(exit) if (doSHA1) { _cstat.contentsDigest = sha1.finish(); }
Re: Only const or immutable class thread local variables are allowed
On Tuesday, 10 December 2013 at 09:50:56 UTC, Joseph Rushton Wakeling wrote: On 10/12/13 09:27, Jonathan M Davis wrote: A lot of dmd's error messages aren't great. Would this be better? Cannot initialize thread-local class variable %s with a mutable value. Only const or immutable initial values are allowed (e.g. null). That would be better. https://github.com/D-Programming-Language/dmd/pull/2943 I can also add a bugzilla issue if you like, but maybe seems overkill ... ? The changelog is partially generated from Bugzilla issues. That was the main reason to also add issues for pull request, afaik.
Re: Only const or immutable class thread local variables are allowed
On Tuesday, 10 December 2013 at 09:50:56 UTC, Joseph Rushton Wakeling wrote: On 10/12/13 09:27, Jonathan M Davis wrote: A lot of dmd's error messages aren't great. Would this be better? Cannot initialize thread-local class variable %s with a mutable value. Only const or immutable initial values are allowed (e.g. null). That would be better. https://github.com/D-Programming-Language/dmd/pull/2943 I can also add a bugzilla issue if you like, but maybe seems overkill ... ? The changelog is partially generated from Bugzilla issues. That was the main reason to also add issues for pull request, afaik.
Re: Simultaneous Assignment
On Monday, 9 December 2013 at 07:38:04 UTC, Dfr wrote: Does D has somtething similar ? http://code.google.com/p/go-wiki/wiki/SimultaneousAssignment No, not in general. There are a few special cases, though. The foreach loop can assign value and index simultaneously. foreach (int i, char c; a) { writefln(a[%d] = '%c', i, c); } Many things can be done in the library. For example, the variable swap from your link: swap(i,j); // more: http://www.dpaste.dzfl.pl/582f7ae2 For returning multiple values from a function in D, you use std.typecons.tuple. I tried this way, but it not worked out. if((int x = 10) 0) { writefln(x is %s, x); } Could you give more context for your specific example? What are you trying to do?
Re: Only const or immutable class thread local variables are allowed
On Monday, 9 December 2013 at 06:43:05 UTC, Joseph Rushton Wakeling wrote: On 09/12/13 01:24, Ali Çehreli wrote: On 12/08/2013 02:40 PM, qznc wrote: I understand you are talking about the Singleton design pattern. You might want to look how std.parallelism does it with the default global thread pool. https://github.com/D-Programming-Language/phobos/blob/master/std/parallelism.d#L3261 (ii) I still think it's not what I want. The static class instance doesn't need to be globally global, I want the default thread-local storage as per the existing std.random.rndGen. Hence the solution I arrived at, but which I'm sure could be improved. class Foo { private static Foo singleton = null; @property public static Foo global() { if (singleton is null) singleton = new Foo(); return singleton; } } Running example: http://www.dpaste.dzfl.pl/f65513fa
Re: Simultaneous Assignment
On Monday, 9 December 2013 at 09:32:26 UTC, Dfr wrote: What i trying to achieve in my current example is more succinct code. A coming from Perl and instead of writing: if(some_complex_statement.here 0) { writefln(x is %s, some_long_expression.here); } I got used not to repeat complex statement, but use 'x' as quick alias: if((int x = some_complex_statement.here) 0) { writefln(x is %s, x); } Afaik, D has no StatementExpression, which means no declarations inside expressions. However, there is an AssignExpression, so assignment works, but requires the declaration before. int x; if((x = some_long_expression.here) 0) { writefln(x is %s, x); } The bad news is that this means type inference cannot be used here (no auto) and the variables is declared in a wider scope than just the if-body.
Re: std.string inPattern() and UTF symbols
On Monday, 9 December 2013 at 14:44:23 UTC, Fra wrote: various (UTF) symbols seems to be ignored by inPattern, see http://dpaste.dzfl.pl/e8ff9002 for a quick example (munch() uses inPattern() internally) Is it me doing something in an improper way, or is the documentation lacking more specific limitation of the function? All I can read is In the future, the pattern syntax may be improved to be more like regular expression character classes. This doesn't sound like non-ascii symbols are not supported Looking at the implementation of inPattern [0], I'd say it is restricted to ASCII. The unittests only cover ASCII, for example. I also smell a unicode bug, due to the combination of foreach and length. [0] https://github.com/D-Programming-Language/phobos/blob/master/std/string.d#L2595
Re: std.string inPattern() and UTF symbols
On Monday, 9 December 2013 at 15:58:53 UTC, qznc wrote: I also smell a unicode bug, due to the combination of foreach and length. Bug reported. :) https://d.puremagic.com/issues/show_bug.cgi?id=11712 That is probably not the root of Fras problem, though.
Re: Only const or immutable class thread local variables are allowed
On Sunday, 8 December 2013 at 21:32:35 UTC, Joseph Rushton Wakeling wrote: On 08/12/13 21:12, Ali Çehreli wrote: In any case, I think class static this is the solution: I think I may have misled you by talking about properties, because I _don't_ mean a property of a class. I mean a public standalone function that is marked as a @property, which returns a persistent instance of some class. The actual motivation is reimplementing std.random.rndGen but with class-based RNGs instead of structs :-) A consequence of this is that I don't think a static class instance can work, because the returned class has to be non-const -- it's an RNG that will be updated! I understand you are talking about the Singleton design pattern. You might want to look how std.parallelism does it with the default global thread pool. https://github.com/D-Programming-Language/phobos/blob/master/std/parallelism.d#L3261
Re: Monads compared to InputRanges?
On Wednesday, 4 December 2013 at 01:53:39 UTC, Shammah Chancellor wrote: Or is D syntax not generic enough to define monads? I started to port monads to D [0]. You can do it, but it looks ugly. The trick is to implement (Haskell) type classes via template specialization. I came to the conclusion that it is not worth it. What D kind of lacks is a way to define a general type class aka the interface. Of course, you could use the interface keyword, but then you cannot apply it to structs. Haskell has no structs (value type records), so they do not have this problem. Look at how isInputRange is implemented [1]. The traits in Rust [2] provide this interface mechanisms as a language feature. D uses static-if instead. Not Haskell, not D, not Rust can check, if your monad actually follows the monad laws [3]. This would probably require a full theorem prover in your language. So Coq, Isabelle, and maybe ATS could do that. A similar challenge would be to check if a user-defined plus operator is commutative (a+b == b+a) like arithmetic plus operations. [0] https://bitbucket.org/qznc/d-monad/src/5b9d41c611093db74485b017a72473447f8d5595/generic.d?at=master [1] https://github.com/D-Programming-Language/phobos/blob/master/std/range.d#L519 [2] http://static.rust-lang.org/doc/0.8/tutorial.html#generics [3] http://www.haskell.org/haskellwiki/Monad_laws
Re: Thread affinity?
On Tuesday, 3 December 2013 at 17:10:07 UTC, Rob T wrote: In core.thread I don't see a portable way to pin a thread to a specific core, or at least pin the thread to whatever core it is currently running in. I found this solution, but it's for Windows only. http://www.gamedev.net/blog/1140/entry-2254424-setting-thread-affinity-on-windows-in-d/ I can find solutions for pthread coded in C/C++, but I'm not sure how to apply these solutions when using the D Thread class. I may be able hack something out, but I need to be sure it's safe and correct. http://stackoverflow.com/questions/1407786/how-to-set-cpu-affinity-of-a-particular-pthread Any help is appreciated. You should file an issue [0] as this should actually be in core.thread. [0] https://d.puremagic.com/issues/enter_bug.cgi
Re: Rest
On Sunday, 1 December 2013 at 18:37:25 UTC, guest wrote: just wanted to know if something in my code is really bad or could be solved in more elegant way. Basicly things which people with more experience in D see on their first view of my code. The line splitting in HttpRequest can be simplified with Phobos functions. Look into std.array.split. Not D specific, but you are nesting pretty deeply in my eyes. I would for example rewrite the run function: foreach(...) { if (foo) { bla } } into foreach(...) { if (!foo) continue; bla } In paramAssignment you could use scope(failure) instead of try-catch. Design-wise your approach cannot be extended with new HTTP methods. For example, Subversion uses PROPFIND and REPORT. You are using classes extensively, but I doubt that OO is the best paradigm here. It looks rather functional to me. Each request is mapped to a function call. Why grouping this into classes? For my taste there is too much magic (string mixins), but it seems necessary for this annotation approach.
Re: scoped chdir and similar patterns
On Thursday, 5 December 2013 at 01:07:19 UTC, Timothee Cour wrote: A1. Is there a (clever?) way to achieve the following using a single function call? You could (mis)use destructors. = struct chdir_scoped { string olddir; this(string newdir) { olddir = bar; writeln(chdir to ~newdir); } ~this() { writeln(chdir back to ~olddir); } } int main() { auto x = chdir_scoped(foo); writeln(doing work in foo); return 0; } = Output: chdir to foo doing work in foo chdir back to bar = Feels hacky to me, since x is not used anywhere.
Re: D game engine -- Any suggestions?
On Wednesday, 20 November 2013 at 16:40:59 UTC, Mineko wrote: On Wednesday, 20 November 2013 at 15:30:32 UTC, Geancarlo Rocha wrote: You should fix your LICENSE following these instructions http://www.gnu.org/licenses/gpl-howto.html. I hope you understand the virality of GPL and why most people won't touch your code for real work. Yeah I know, have any better ideas that is at least similar enough to the GPL? You could try my little wizard: http://beza1e1.tuxen.de/licences/
Re: Accessing mutable data that isn't
On Wednesday, 20 November 2013 at 22:49:42 UTC, Spott wrote: I've been screwing around with templates lately, and I'm attempting to figure out why the following won't compile: struct value { int a; const auto opBinary(string op, T)(in T rhs) const pure { static if (op == +) return intermediateValue!(value.plus,this,rhs)(); } ref value opAssign(T)( in T t ) { a = t.a; return this; } static int plus(T1, T2)(in T1 x, in T2 y) pure { return x.a + y.a; } } struct intermediateValue(alias Op, alias A, alias B) { auto opBinary(string op, T)(in T rhs) const pure { static if (op == +) return intermediateValue!(value.plus,this,rhs)(); } @property auto a() const pure { return Op(A, B); } } void main() { value a = value(2); value b = value(3); value c; c = a + b; } The error is: d_playground.d(34): Error: pure nested function 'a' cannot access mutable data 'this' d_playground.d(34): Error: pure nested function 'a' cannot access mutable data 'this' d_playground.d(10): Error: template instance d_playground.value.opBinary!(+, value).opBinary.intermediateValue!(plus, this, rhs) error instantiating d_playground.d(44):instantiated from here: opBinary!(+, value) d_playground.d(44): Error: template instance d_playground.value.opBinary!(+, value) error instantiating What is going on? Why is 'a' not allowed to access mutable data (even though it isn't modifying it)? How do I tell the compiler to pass this in a const fashion? No answer, but two notes. First, use dpaste for such code snippets: http://dpaste.dzfl.pl/f2f39b32 Second, what are you trying to do? intermediateValue is a struct without members. I am not sure what 'this' means in such a case.
Re: From D struct to C struct
On Monday, 18 November 2013 at 08:32:11 UTC, Namespace wrote: I found another approach. It avoids the GC and the Heap: A Circular Buffer: http://dpaste.dzfl.pl/cf1e7afb That should work. It is unsafe, but might work in your specific case. The problem is that future changes might exhibit memory corruption, if the limit of your buffer is too low. Would probably be a hell to debug.
Re: pure-ifying my code
On Monday, 18 November 2013 at 07:37:27 UTC, Jonathan M Davis wrote: This is middleend optimization stuff, though. I'm not quite sure what you mean by this. There is no middle-end. We have the front-end, which is shared by dmd, gdc, and ldc, and then each compiler has its own backend. Anything D-specific is done in the front-end. So, if there are any D-specific optimizations (such as optimizations related to pure), they need to be in the front-end. For me, middle-end is stuff, which is neither specific to input language nor to output OS/architecture/runtime. Effectively, all compiler optimizations which are useful everywhere. Maybe this view is a little outdated, since most people consider LLVM has simply a backend, while I would consider it middle- and backend of a compiler.
Re: D on learnxinyminutes.com
On Sunday, 17 November 2013 at 20:56:47 UTC, John J wrote: Can you please add the D language to the http://learnxinyminutes.com/ That's an interesting way of quickly introducing a language through a long and well commented code example. Writing this is probably a good learning experience for anybody who wants to learn D. Of course, you can ask for feedback here. ;)
Re: From D struct to C struct
On Sunday, 17 November 2013 at 22:11:02 UTC, Namespace wrote: Hello. I have some trouble with C interfacing. I have a C struct with an integer member and I want to wrap this into a D template. But if I want to access the C API, I have to convert the C struct with the type informations of the D struct. Example: http://dpaste.dzfl.pl/e3d10755 The question is: How can I write the ptr method? It is very probable, that these conversion is often used, so the ptr method should be fast and without many garbage. And If possible, I want to avoid the GC / Heap. My current approach doesn't avoid the GC complete, but it displace the problem: http://dpaste.dzfl.pl/449f663f Any further ideas how to solve that? You cannot use the stack due to your API requirements, so only heap or data segment remains. I assume you cannot use static variables, so heap it is. You should look into Andreis proposed std.allocator to optimize your memory management. http://forum.dlang.org/post/l4btsk$5u8$1...@digitalmars.com
Re: pure-ifying my code
On Sunday, 17 November 2013 at 21:00:16 UTC, Jonathan M Davis wrote: will definitely result in multiple calls to pure_func. It's not that it's impossible for the compiler to do it - it's perfectly possible. But doing so would require at least basic code flow analysis, and dmd almost never does any kind of code flow analysis. I remember Walter being against flow analysis in the frontend. This is middleend optimization stuff, though. Does dmd really use no data flow analysis anywhere?
Re: Best data structure for a particle system?
On Friday, 15 November 2013 at 14:01:36 UTC, Chris Cain wrote: On Friday, 15 November 2013 at 13:32:38 UTC, Mikko Ronkainen wrote: Ok, thanks! That linked list cache thrashing was just the thing I knew that I don't know :) Let's say I just use dynamic array and grow it when adding new particles to the system, and when particles die, just set their dead flag on. This means that, when adding a new particle, I need to scan the array first for possible dead particles that can be reused. Is there some trick that could be used here to reduce excessive searching/iteration? Instead of having a dead flag, you could swap ( http://dlang.org/phobos/std_algorithm.html#swap ) the dying particle with the last particle in the list and then decrement the list's length. This swapping might even speed up the normal particle processing, because with a mix of dead and alive particles the flag checking could confuse the branch predictor. http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array Ultimately, if flag or swap is faster must be measured. Profiling and bencharking are your friends, if you want to optimize your particle system. For a start use an array and either method.
Re: What is the closest to ConcurrentHashMap and NavigableMap in Java?
On Thursday, 14 November 2013 at 23:10:58 UTC, Jacek Furmankiewicz wrote: While looking a D, I am just trying to focus on the parts which I know would be a showstopper for us on day one...and this particular issue is it. Yes, I also think for long-running memory-hungry server-stuff the current conservative GC is a show stopper. Some people are working on a concurrent and a precise GC. Then parallel and concurrent and incremental and generational and whatnot GCs will be explored. The point where it gets interesting for these server-apps is not clear though. Regarding the GC, I've seen some slides on DConf about other garbage collectors available. Is there any resource/tutorial that shows how you can swap out the default GC for those alternative implementations? As far as I know those other GCs are not ready for prime time yet. For sure, there is no other GC shipped with the current D 2.064.2. Oh, and keep nagging! We need to hear about showstoppers, so we can fix them! ;)
Re: Efficient string concatenation?
On Friday, 15 November 2013 at 22:35:48 UTC, Jacek Furmankiewicz wrote: I am learning D by going through Ali Cehreli's otherwise excellent Programming in D PDF and he did not show this in his initial chapter on Strings. Well, Appender is not string specific. D feels like being in a different league in terms of generic programming. Many stdlib stuff is implemented more abstract and generic, which makes it harder to find. Looking for some string operations, you might find it in std.algorithm, std.array, std.range, or std.string. Maybe it is different to C++ programmer, who are used to this from the STL.
Re: Deimos rules?
On Wednesday, 13 November 2013 at 22:46:45 UTC, Jonathan M Davis wrote: On Wednesday, November 13, 2013 23:01:58 Xavier Bigand wrote: I work on XCB integration, so I think that I can add bindings in deimos. C headers are translated to d modules by using DStep or manually? If manually need I respect some syntactical rules? It's completely project-dependent. Deimos is for D bindings to C libraries. They need to be the extern(C) declarations which correspond to the C header declarations without any D wrappers. Beyond that, how the project is put together or how the bindings are generated is really up to whoever does the header translation. DStep is new enough that I expect that most of Deimos has been converted by hand. There's also htod on Windows, but it does a pretty poor job, because it's D1-compatible (e.g. it doesn't handle const right). So, you can translate the headers however you want, and there are no syntactic rules. I'd say that you should follow the same file layout as the actual C headers (a one-to-one translation of header.h - header.d), but how everything is formatted in those files doesn't really matter. It's up to you. Ah, that reminds that the tutorial needs some good advice about this. As far as I know, DStep is the current state of art.
Re: What does func!thing mean?
On Friday, 8 November 2013 at 05:46:29 UTC, ProgrammingGhost wrote: I'm a D noob. .map!(a = a.length) seems like the lambda is passed into the template. .map!split just confuses me. What is split? I thought only types can be after !. I would guess split is a standard function but then shouldn't it be map!(split)? const wordCount = file.byLine() // Read lines .map!split // Split into words .map!(a = a.length) // Count words per line .reduce!((a, b) = a + b); // Total word count Do you know C++ templates? C++ functhing == D func!(thing). You can pass anything into a template, not just types. So you are right, map!split gives the split function into the map template and map!(split) is the canonical form. D allows you to remove the parens for simple cases, hence map!split.
Re: UFCS with constructors
On Wednesday, 6 November 2013 at 11:04:05 UTC, bearophile wrote: import std.typecons: Typedef; alias Foo = Typedef!double; void main() { auto a1 = Foo(1); pragma(msg, typeof(a1)); auto a2 = 1.Foo; pragma(msg, typeof(a2)); auto a3 = Foo(-1); pragma(msg, typeof(a3)); auto a4 = -1.Foo; pragma(msg, typeof(a4)); } It prints: Typedef!(double, nan) Typedef!(double, nan) Typedef!(double, nan) double Is this expected/acceptable/good? Operator precedence of . is higher than unary minus. That should be the explanation, why the fourth output is different than the others. However, what is Typedef for?
Re: Cast delegate and functions.
On Thursday, 31 October 2013 at 13:12:31 UTC, Wolftein wrote: void delegate(Event) void delegate(T) Where T is a class that inherits Event. I'm trying to cast (void delegate(T)) to (void delegate(Event)) to be able to store them in a map, but when i cast them i get null exeception. Same thing for cast things like this TemplateClass!Plugin TemplateClass!OtherTypeOfPlugin - Being OtherTypeOfPlugin inherit Plugin Using C++ this is allowed. It is not safe to allow this. auto f = delegate(T x) { x.methodOfT(); } auto g = cast(void delegate(Event)) f; g(new Event()); This would call methodOfT on an Event object, which does not have that method. Co- and Contravariance for such stuff is tricky. Here is a discussion on how C# 4.0 approaches it: http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-sharp-4-0
Re: Looking for something similar to Python's bisect_right
On Wednesday, 30 October 2013 at 06:04:36 UTC, Zeke wrote: Hello, I'm on day 2 of learning D. I've learned C, C++, Java, Python, Ruby in University, but I wanted to broaden my palette by picking up D. This project is a basic implementation of Project Euler problem 10. I build an array of primes, and for each new test number I check if the test is divisible by any prime from 2 to sqrt(test) (which cuts down on number of iterations). Trouble is, I can't find a method that's in the libraries to calculate the index of where sqrt(test) would exist or would be inserted into a sorted array. I tried casting the primes array to a SortedRange using assumeSorted() but it didn't work for me. countUntil() returns -1 if the value doesn't exist. and I didn't find anything in the std.algorithm, std.array, or std.container. Here's my current working implementation of is_prime and the functions it uses: pure nothrow @safe bool is_prime(in ulong[] primes, ulong num) { // Need to find a more elegant way to find the index of where a number's // square root would be in a sorted array. auto upper = insind(primes, cast(ulong)sqrt(cast(double)num)) + 1; // Check each prime in the array up to the square root of our current test // number to see if it is prime. foreach(ulong prime; primes[0..upper]) { if (num % prime == 0) { return false; } } return true; } Why do you want to find the exact prime first? Just check against sqrt(num) in the loop. auto upper = cast(ulong)sqrt(cast(double)num)) + 1; foreach(ulong prime; primes) { if (prime upper) return true; if (num % prime == 0) return false; } assert (false); // should be unreachable?
Re: Looking for something similar to Python's bisect_right
On Wednesday, 30 October 2013 at 18:56:42 UTC, Zeke wrote: On Wednesday, 30 October 2013 at 14:17:22 UTC, qznc wrote: Why do you want to find the exact prime first? Just check against sqrt(num) in the loop. auto upper = cast(ulong)sqrt(cast(double)num)) + 1; foreach(ulong prime; primes) { if (prime upper) return true; if (num % prime == 0) return false; } assert (false); // should be unreachable? Because having a branch inside the foreach causes a branch prediction error when you've found a prime number. Simply iterating up to the sqrt and then terminating the loop has no branch prediction error. Try it for yourself. Interesting thought. In your code, there are two conditional branches in each iteration: The check for the end of foreach range and the prime check. Why is one more condition for the upper check so bad? I admit, my code includes the superfluous foreach range check. Hence this improved version: ulong prime; int i = 0; assert (primes[$] upper); do { prime = primes[i]; if (num % prime == 0) return false; i+=1; } while (prime upper); return true; In this version there is still an implicit bounds check for the array access. For dmd -noboundscheck disables that branching. Optimizing for branch prediction sounds premature, since you are using a slow algorithm anyways. ;)
Re: std.range.chunk without length
On Wednesday, 30 October 2013 at 00:20:12 UTC, Stephan Schiffels wrote: Hi, I'd like a version of std.range.chunk that does not require the range to have the length property. As an example, consider a file that you would like parse by lines and always lump together four lines, i.e. import std.stdio; void main() { auto range = File(test.txt, r).byLine(); foreach(c; range.chunks(4)) { //doesn't compile writefln(%s %s, c[0], c[1]); } } Your wish was granted. Monarchdodra was sent back in time [0], so it is already fixed in HEAD. You could try the dmd beta [1]. [0] https://github.com/D-Programming-Language/phobos/pull/992 [1] http://forum.dlang.org/thread/526dd8c5.2040...@digitalmars.com
Re: GhostDoc for VisualD?
On Wednesday, 23 October 2013 at 15:56:33 UTC, Namespace wrote: Is there anything like this for VisualD? As far as I understand the GhostDoc website it generates prose comments from the type information? The only reason I can think of are weird enterprise requirements like every method must have at least 5 lines of documentation. Maybe you want some specific part of GhostDoc, which is actually useful?
Re: Help with concurrency - traversing a DAG
On Tuesday, 22 October 2013 at 08:13:57 UTC, tbttfox wrote: On Friday, 18 October 2013 at 19:47:37 UTC, qznc wrote: Create a task for each node without a parent. Let the tasks create new tasks for their children. I was finally able to try this out, but I'm having a problem. My test case right now is a simple linked list, and what I think happens is that the queue empties and makes it past the pool.finish() before the worker thread can add another task to the queue. Here's the code: http://pastebin.com/LLfMyKVp Thanks again This pool.finish seems to be the wrong way to wait. I think you have to implement your own.
Re: Changing elements during foreach
On Monday, 21 October 2013 at 10:31:51 UTC, Krzysztof Ciebiera wrote: Is the following compiler behavior consistent with language specification? import std.stdio; void main() { int a[][] = [[1,2,3]]; foreach(x; a) { x[0] = 0; x ~= 4; } writeln(a); } I understand why thw program could output [1,2,3] (like in C++ without ) or [0,2,3,4] (python, C++ ref). But [0,2,3]? It was unpleasant surprise. The behavior of D's slices is often unintuitive. To understand them, read this article: http://dlang.org/d-array-article.html
Re: D and C++
On Saturday, 19 October 2013 at 13:20:28 UTC, develop32 wrote: Hi, Are there any recent improvements in how D interfaces with C++? I got the impression that some work has been done on that, in order to make DMD a self-hosting compiler. I do not know of any recent improvements. The current plan to make DMD self-hosting seems to be a conversion tool. The transition would one step then. The challenge is mostly on LDC then to use the C++ LLVM bindings.
Re: Changing elements during foreach
On Monday, 21 October 2013 at 20:14:09 UTC, ixid wrote: On Monday, 21 October 2013 at 19:37:47 UTC, Jonathan M Davis wrote: On Monday, October 21, 2013 21:16:00 qznc wrote: On Monday, 21 October 2013 at 16:22:29 UTC, Krzysztof Ciebiera wrote: I understand slices now and I don't find it consistent with no shoot in the foot by default statement. I agree. The pitfalls are well understood, yet everybody seems to love them. Ok, compared to C array they are an improvement due to bounds checking. If the elements are const or immutable (string) everything is fine, but write+append is basically implementation-defined behavior. Once there is a proper std.collections, I will probably adapt my tutorial to recommend a safe alternative (ArrayList?). Just don't use slices when appending. It's only an issue when you're appending and relying on slices continuing to refer to the same array, and that's not going to work. Slices are primarily for reading, not writing. Using a container doesn't change that. It just makes it so that you can't even attempt to append to a slice, because the slice is a different type than that container and won't support appending. What would be the issue/s with disallowing appending to slices? So you'd have to explicitly duplicate before you could append. Appending itself is not the problem. Append + write is indeterministic. int[] a = [1,2,3]; int[] b = a; a ~= [4,5]; // append a[0] = 42; // write assert (b[0] == 42) // indeterministic, implementation-specific It depends on the capacity during the append. If a reallocation happened, then b[0]==1. Otherwise b[0]==42. If you can forbid the write (e.g. immutable(char)[] aka string), you can append as much as you want. If you can disallow the append (convention, no type system support for this), you can write as much as you want. For something like Javas ArrayList, the behavior would be a deterministic b[0]==42, but also a.length==b.length.
Re: D and C++
On Monday, 21 October 2013 at 11:29:54 UTC, develop32 wrote: On Monday, 21 October 2013 at 11:08:15 UTC, qznc wrote: On Saturday, 19 October 2013 at 13:20:28 UTC, develop32 wrote: Hi, Are there any recent improvements in how D interfaces with C++? I got the impression that some work has been done on that, in order to make DMD a self-hosting compiler. I do not know of any recent improvements. The current plan to make DMD self-hosting seems to be a conversion tool. The transition would one step then. The challenge is mostly on LDC then to use the C++ LLVM bindings. I'm aware of the conversion tool, but it seems it will only apply to the frontend? The DMD backend will be left as is. The DM backend has some legal issues. Symantec owns part of it and does not relicence it. Converting it to D would not change that, since the D version is still derived work. Writing a whole new backend in D is not feasible. There are so many more important tasks. However, in the Open Source world, nobody can stop you from doing it. ;)
Re: Help with concurrency - traversing a DAG
On Friday, 18 October 2013 at 07:20:07 UTC, tbttfox wrote: So I've got a project in mind, and at the core of that project is a DAG with lots of nodes. This seems to be a great candidate for concurrent evaluation. The problem is that a node can only be evaluated after all of its parents have. I'm really new to D and static typing in general (coming from Python-it was way too slow for this), and I'm having trouble navigating the shared/const/immutables and keeping within the concurrency structure in D. The actual question: Will the following strategy work? I've tried coding this a couple times, and it just doesn't seem to be working. Is there something wrong with my logic? I make a shared list of linked nodes and pass that to each thread on spawn. Then the indexes of any node without a parent go into a queue. The main thread then passes list indexes to the worker threads from that queue. When a worker thread gets an index, it makes a local copy of that node, evaluates it, and stores the data it computes with the node. Then every child of that node is checked to see if its parents have all been processed. If so, that child is added to the queue and the thread requests another item from the queue. When the queue is empty, the job is done. I assume your goal is to exploit parallelism for a speedup? How expensive is the evaluates it step? Is the traversal or the evaluation dominating the run time in the single-threaded version? How scalable do you need to be (e.g. Desktop Multicore or Cluster or Cloud)? In terms of logic, I can see no error. Though it is not clear, if you use push or pull. The master might push to the workers or the workers might pull from the master.
Re: Help with concurrency - traversing a DAG
On Friday, 18 October 2013 at 16:31:13 UTC, tbttfox wrote: My not currently not working implementation has the workers make a pull request from the master. As far as I understand you just want something working right now? Then my suggestion would be to look into std.parallelism [0]. Create a task for each node without a parent. Let the tasks create new tasks for their children. This would implement your concept quite well. The queue is actually the task queue of a thread pool. The nice thing, is that all this queueing and synchronization stuff is already implemented for you in the standard library. You could try to make the DAG immutable and create a secondary data structure for the evaluation results. [0] http://dlang.org/phobos/std_parallelism.html
Re: mutable, const, immutable guidelines
On Wednesday, 16 October 2013 at 20:33:23 UTC, H. S. Teoh wrote: I'm of the view that code should only require the minimum of assumptions it needs to actually work. If your code can work with mutable types, then let it take a mutable (unqualified) type. If your code works without modifying input data, then let it take const. Only if your code absolutely will not work correctly unless the data is guaranteed to never change, ever, by anyone, should it take immutable. Sounds reasonable. Which one of the following would you prefer? foo1(const T t) { takes_immutable(t.idup); } foo2(immutable(T) t) { takes_immutable(t); } I'd say foo2, which puts the burden of the copy on the caller. However, if the caller already has an immutable value an unecessary copy is avoided.
Re: mutable, const, immutable guidelines
On Wednesday, 16 October 2013 at 20:33:23 UTC, H. S. Teoh wrote: I'm of the view that code should only require the minimum of assumptions it needs to actually work. If your code can work with mutable types, then let it take a mutable (unqualified) type. If your code works without modifying input data, then let it take const. Only if your code absolutely will not work correctly unless the data is guaranteed to never change, ever, by anyone, should it take immutable. What about functions, which are not thread-safe? auto percentageDistribution(const int[] percentages) { [...] assert (sum == 100); [...] } Not a realistic example, but it should do. This function checks that the sum of all percentages equals 100, but a concurrent modification might break this. You could require an immutable array to avoid that. Alternatively, the absence of shared could be considered enough to express this.
Re: mutable, const, immutable guidelines
On Wednesday, 16 October 2013 at 17:55:14 UTC, H. S. Teoh wrote: Maybe it's helpful to understand how D's const system works. The following diagram may help (please excuse the ASCII graphics): const / \ mutable immutable I think people in this thread know how const works, but some think it is broken. Scenario is this: Library code: struct Foo { int x; } User code: Foo f; immutable f2 = f; This works, even though the library writer might not have anticipated that someone makes Foo immutable. However, now the library writer obliviously releases a new version of the library, which extends it like this: struct Foo { int x; private int[] history; } Unfortunately, now the user code is broken due to the freshly introduced mutable aliasing. Personally, I think is fine. Upon compilation the user code gives a error message and user developer can adapt to the code to the new library version. Some think the library writer should have a possibility to make this work.
Re: Starting D with a project in mind.
On Thursday, 10 October 2013 at 19:49:15 UTC, Andrew wrote: Hi All, I've been writing a MUD for a little while, initially using Haskell but now using C. I develop on MacOS X but deploy to a Raspberry Pi. I loved using Haskell especially using the Parsec parser but unfortunately I couldn't build on the Pi because the resource requirements were just too heavy. Now I develop in C and the same Makefile builds on Mac and Debian equally well and of course I can use the lovely Xcode environment. However, as I start to add more advanced features it's getting rather tedious. The MUD has an embedded web server which supports web sockets for real time play and the back end is a Mongo DB. The C code to access DB is very repetitive and is slowing me down because of the lack of higher level constructs. Similarly the parser is very basic and ropey which needs attention. Hence my interest in D. I've spent a few hours trying to get GDC working on my Pi which is proving to be a bitch but I'm hoping that it will be worth it. Before I get too far down this path, would you recommend D for this task and will porting from Mac to Pi be seamless ? As Adam already said D on Pi is adventurous. For MongoDB and web stuff, you should look into Vibe.d [0]. For parsing I would suggest Pegged [1]. Welcome to D and Happy Hacking! :) [0] http://vibed.org/ [1] https://github.com/PhilippeSigaud/Pegged
Re: mutable, const, immutable guidelines
On Wednesday, 9 October 2013 at 04:31:55 UTC, Ali Çehreli wrote: On 10/08/2013 03:12 PM, qznc wrote: On Monday, 7 October 2013 at 17:57:11 UTC, Ali Çehreli wrote: To look at just one usage example, the following line carries two requirements: auto a = T(); immutable b = a; 1) b will be an immutable copy of a. 2) T will always be usable as in that fashion. If T appears on an API, it is the responibility of the user to ensure whether they are allowed to treat T in that way. Otherwise, they risk maintainability if the module decides to change T in any way that fits the module's needs. If they have not yet advertised that T can be used as immutable, it should not be. I do not agree with you, that the user has the responsibility. I have difficulty agreeing with myself as well. :) However, the power of immutable makes me think so. Interestingly, once a user creates an immutable variable of a type, that type must support that use. Rather I think the provider of T has the responsibility to maintain backwards compatibility. Agreed but I don't know how. Here is challenge: Let's start with the following program: // Library type struct MyInt { int i; } void main() { // User code auto a = MyInt(1); immutable b = a; } Let's assume that the library adds a private dynamic array of ints to that type: // Library type struct MyInt { int i; private int[] history;// -- Added } void main() { // User code auto a = MyInt(1); immutable b = a; // -- Existing code breaks } Error: cannot implicitly convert expression (a) of type MyInt to immutable(MyInt) Maybe the fact that D allows this implicit copy to immutable is the problem? If one could require the use of a specific function, this function could be overridden with working behavior. The following code works. import std.exception: assumeUnique; struct MyInt { int i; private int[] history;// -- Added } // idup for creating immutable MyInts immutable(MyInt) idup(const MyInt mi) pure nothrow @trusted { MyInt cpy = MyInt(mi.i); return cast(immutable) cpy; } // special version for performance immutable(MyInt) idup(immutable MyInt mi) pure nothrow @trusted { return mi; } unittest { auto a = MyInt(1); immutable b = a.idup; // -- Code does not break } D could either remove the implicit-copy-to-immutable or provide a special copy-constructor for immutable structs.
Re: mutable, const, immutable guidelines
On Thursday, 10 October 2013 at 18:39:32 UTC, Christian Köstlin wrote: On 10/10/13 1:05 , qznc wrote: Very interesting discussion! contract between caller and callee. If an argument is const, it means the callee says he can handle others changing the state concurrently. i think what the usual understanding of const for an argument to callee is, what is written at http://dlang.org/const3.html. that means for me, that callee promises not to change the data itself. perhaps a bettr description would be readonly. The linked page clearly says It may, however, be changed by another reference to that same data. usually you would think that no one else should change the data while callee runs. but at least with c++ i could imagine running callee in a thread with a reference to a const thing which changes underneath and while callee is running. A const argument gives information to both sides. For the caller it means callee does not modify the data. For the callee it means somebody else (another thread) may modify the data at any time. An immutable argument means the same for the caller, but gives an additional guarantee to the callee that nobody modifies the data.
Re: mutable, const, immutable guidelines
On Wednesday, 9 October 2013 at 04:41:35 UTC, Ali Çehreli wrote: 4. Data structures should not restrict themselves to be mutable, const, or immutable. What is the template of a struct that can be used as such? Providing simple values seems to be insufficient: struct MyInt { int i; private int[] history; } What else should the struct above have to make it usable as mutable, const, immutable? This is a noble goal, which in reality is probably either trivial or impossible. So I am not sure, if it is worthy to be called a guideline. We have to nail this down already. We have this great addition of immutable in the language but we either don't know how to use it or the language is lacking hopefully trivial things to make it work. For this case, there are basically two approaches: a) prevent the use as immutable in the first place or b) make it work as immutable by force. For version a) we could have a UDA like this: @NeverImmutable struct MyInt { int i; } auto x = immutable(MyInt)(42); // compile error immutable y = MyInt(42);// compile error However, the library writer would have to anticipate the private dynamic array, which probably does not happen. Defensive coding like putting @NeverImmutable on everything would defeat the purpose as well. For version b) we would relax the type system, which opens an ugly can of worms of unknown size. Basically, immutable data would be allowed to have mutable private data, if the author sufficiently asserts everything is correct. Since there are lots of interesting compiler optimizations with immutable things, I can imagine there will be lots of subtle errors until one can make something like this work. At this point, I cannot imagine that there is a solution which makes this case work, so I think we have to accept this breakage.
Re: mutable, const, immutable guidelines
On Wednesday, 9 October 2013 at 15:50:55 UTC, Daniel Davidson wrote: void foo(const(MutableType) mt); void foo(immutable(MutableType) mt); Naturally the inclination is to choose the second as it is a stronger guarantee that no threads are changing the data. Cool. But wait, the first one still probably requires the same guarantee, even if it does not state it. If in the const case another thread changes the state of mt during the function foo then it will fail. foo actually requires that mt not be change by other threads during its operation - that is the only sane way of using the data in the function. Why the first one still probably requires the same guarantee? Why would foo fail if in the const case another thread changes the state of mt? If foo is not thread-safe, then it should require immutable. Take, for example, LinearCongruentialEngine from random.d. It has a function: bool opEquals(ref const LinearCongruentialEngine rhs) const Why is it using const here instead of immutable? Does it not care about other threads? No - it just is not smart enough to deal with it. It assumes other threads won't be changing it or if they are caveat developer. So when do you use immutable as a signal that not only will this function not change it, no thread will change it either? Probably when you know you have to deal with threading. But that then would be coupling two maybe orthogonal decisions - the threading of a program and the signature of functions. Hm, that actually looks like a bug. If LinearCongruentialEngine is instantiated with a UIntType larger than size_t, it is not thread-safe, but this seems to be claimed in the section header. Why are those two decisions orthogonal? The signature of a function is a contract between caller and callee. If an argument is const, it means the callee says he can handle others changing the state concurrently.
Re: mutable, const, immutable guidelines
On Wednesday, 9 October 2013 at 15:50:55 UTC, Daniel Davidson wrote: I would rephrase the second guideline as: Never dup or idup an argument to make it mutable or immutable, but require the caller to do this (might be able to avoid it). Agreed. But it means you agree with me that immutable should indeed appear on function signatures as needed. I don't really agree. Naturally, if const were used all the way down there would be no need for copies. It is the introduction of immutable (via string in your example) that breaks the rule and causes the pain. But then if the rule were adopted globally - immutable is never used on parameters in a signature, only const is used, when would you start seeing any benefit to the immutable keyword? The benefit of immutable is that nobody else can change it. Functions that would be non-thread-safe with const arguments are thread-safe with immutable arguments. That relationship with thread-safety almost seems to be a good guideline. 5. If a function is not thread-safe due to const arguments, consider making it immutable. Otherwise you must explicitly document the lack of thread-safety. For more guidelines: 3. Return value, which are freshly created, should never be const. They should be mutable or immutable. Agreed. I say that it should be mutable if the function is pure, as such a return values is automatically convertible to immutable. Basically, I cannot come up with a case, where const would be preferable to mutable and immutable. Maybe someone is able to find a good example? I don't know if these are good examples, but they are examples: From zip.d: const(void)[] compress(const(void)[] buf) Looking it up (in zlib.d actually) it could just as well return an immutable array, since it is freshly allocated. From vibe: const(Json) opIndex(string key) const { Not sure where exactly this comes from. Seems to be some kind of map? In this case the value is not freshly created, so the guideline does not apply. I'm confused by the term usable as mutable, const, immutable? Isn't it true that types are not mutable, const, immutable in their definition but only in their context? MyInt is a type, probably mutable. immutable(MyInt) is also a type, but immutable. const(MyInt) is also a type, but const. These are example of immutable and const being used as type constructors. They create a new type from an existing one (MyInt).
Re: mutable, const, immutable guidelines
On Wednesday, 2 October 2013 at 13:09:34 UTC, Daniel Davidson wrote: 1. If a variable is never mutated, make it const, not immutable. 2. Make the parameter reference to immutable if that is how you will use it anyway. It is fine to ask a favor from the caller. ... I think guideline 1 should be about arguments not variables. Functions should take const arguments, so they can be called with mutable and immutable values. I would rephrase the second guideline as: Never dup or idup an argument to make it mutable or immutable, but require the caller to do this (might be able to avoid it). For more guidelines: 3. Return value, which are freshly created, should never be const. They should be mutable or immutable. Basically, I cannot come up with a case, where const would be preferable to mutable and immutable. Maybe someone is able to find a good example? Of course, this does not hold for returned values, which are retrieved from somewhere (array,container,etc). In this case, I have no general advice. 4. Data structures should not restrict themselves to be mutable, const, or immutable. This is a noble goal, which in reality is probably either trivial or impossible. So I am not sure, if it is worthy to be called a guideline.
Re: mutable, const, immutable guidelines
On Monday, 7 October 2013 at 17:57:11 UTC, Ali Çehreli wrote: To look at just one usage example, the following line carries two requirements: auto a = T(); immutable b = a; 1) b will be an immutable copy of a. 2) T will always be usable as in that fashion. If T appears on an API, it is the responibility of the user to ensure whether they are allowed to treat T in that way. Otherwise, they risk maintainability if the module decides to change T in any way that fits the module's needs. If they have not yet advertised that T can be used as immutable, it should not be. I do not agree with you, that the user has the responsibility. Rather I think the provider of T has the responsibility to maintain backwards compatibility. My principle is anything is allowed, unless explicitly forbidden. This includes immutable type constructing. It is great that we get a type error, if backwards compatibility is broken. Nevertheless, the question of responsibility seems to be subjective. Are there any clear technical reasons for either way? Unfortunately, there is no way for the provider to allow or disallow immutable(T). Maybe there should be a UDA or something for this?
Re: Learning D - first steps and best practices
On Wednesday, 2 October 2013 at 03:28:59 UTC, Jonathan M Davis wrote: On Wednesday, October 02, 2013 03:19:19 Jesse Phillips wrote: For me, if the program didn't format brackets on the same line I wouldn't use it. If you start making things configurable, may as well improve indent's support for D. Whereas I'd hate to have to write code that didn't have braces on their own line. It's far better for us both to be able to write code the way that we want than try and force standard formatting rules of some kind. IMHO, they add little to no value and definitely make coding less enjoyable. My vision: Jonathan checks out Jesses code to fix a bug. On opening the file his editor automatically reformats to braces-on-own-line. When committing the fix, a pre-commit hook reformats to the project-specific style braces-on-same-line. Everybody is happy. :) Of course, there are edge cases, where automatic formatting should be broken. However, I think we should let them be and adapt. I also add code sometimes, just to remove a compiler warning like unused argument. Likewise, I am fine with minor noise in exchange for consistent styling like described above.
Re: unsigned interger overflow
On Wednesday, 2 October 2013 at 05:41:50 UTC, Jonathan M Davis wrote: On Wednesday, October 02, 2013 12:32:24 Alexandr Druzhinin wrote: Is it safe to replace code: uint index; // do something index++; if(index == index.max) index = index.init; by the following code uint index; // do something index++; /// I use unsigned int so uint.max changed to 0 automagically Well, not quite. Your first one skips uint.max. It goes from uint.max - 1 to 0, whereas the second one goes from uint.max to 0. So, they're subtly different. But yes, incrementing the maximum value of an unsigned integral type is guaranteed to wrap around to 0. Signed integers are of course another matter entirely, but it's guaranteed to work with unsigned integers. For signed integers there seems to be no clear consensus [0], although personally I would read the spec [1] as wrapping happens for int as well: If both operands are of integral types and an overflow or underflow occurs in the computation, wrapping will happen. I also consider it reasonable, since every architecture uses 2s-complement. [0] http://forum.dlang.org/thread/jo2c0a$31hh$1...@digitalmars.com [1] http://dlang.org/expression.html
Re: 'pp' for D?
On Tuesday, 1 October 2013 at 09:21:44 UTC, John Colvin wrote: On Monday, 30 September 2013 at 21:24:28 UTC, linkrope wrote: But putting quotes around a string value is obviously not enough. What if the string contains a quote? hell\o would become `hello`! Would would you want it be become? I believe the basic idea of repr and friends is to output language literals. You could copypaste the output back into a source file and use it.
Re: Learning D - first steps and best practices
On Sunday, 29 September 2013 at 07:49:21 UTC, Jonathan M Davis wrote: I confess that I don't understand why so many people are fixated on having a standard style, particularly when it's very, very clear that most everyone disagrees on what counts as good style. What little we have in terms of official style guidlelines for D can be found here: http//:dlang.org/dstyle.html I think nowadays programmers expect their language to come with more opinion and best practices. In contrast, the C++ world is too fragmented for consistent advice. I believe, the best solution would be to include an auto-formatter (like go fmt), so people can simply reformat the code before and after editing.
Re: RosettaCode proposal: RFC diagram converter
On Monday, 30 September 2013 at 23:27:48 UTC, bearophile wrote: Inspired by a talk by Eden in the StrangeLoop 2013 conference, I'd like to create a new small Rosettacode Task. Perhaps someone here is able to review this task description a little, or even to implement the D solution: - - - - - - -TASK DESCRIPTION START- - - - - - - - - Task Title: ASCII art diagram converter Given the RFC 1035 message diagram from Section 4.1.1 (Header section format) as a string: http://www.ietf.org/rfc/rfc1035.txt +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z| RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QDCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ANCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |NSCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ARCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ Where: ID is 16 bits QR = Query (0) or Response (1) Opcode = Four bits defining kine of query: 0:a standard query (QUERY) 1:an inverse query (IQUERY) 2:a server status request (STATUS) 3-15: reserved for future use AA = Authoritative Answer bit TC = Truncation bit RD = Recursion Desired bit RA = Recursion Available bit Z = Reserved RCODE = Response code QC = Question Count ANC = Answer Count AUC = Authority Count ADC = Additional Count/pre Write a function, member function, class or template that accepts a similar multi-line string as input to define a data structure or something else able to decode or store a header with that specified bit structure. If your language has macros, introspection, code generation, or powerful enough templates, then accept such string at compile-time to define the header data structure statically. Such Header function or template should accept a table with 8, 16, 32, 64 columns and any number of rows. The only allowed symbols to define the table are + - | (plus, minus, pipe), and whitespace. Lines of the input string composed just of whitespace should be ignored. Leading and trailing whitespace in the input string should be ignored, as well as before and after each table row. The box for each bit of the diagram takes four chars +--+. The code should perform a little of validation of the input string, but for brevity a full validation is not required. - - - - - - -TASK DESCRIPTION END- - - - - - - - - I think such ASCII art inside the source code is easy to read, so in theory the D entry could be useful for more than just a Rosettacode Task. The usage syntax of the D entry: alias H1 = BitfieldsTable! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z| RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QDCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ANCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |NSCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ARCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+; Bye, bearophile Nice idea! :) I assume 1 column corresponds to 1 bit. This should probably be mentioned explicitly in the task description.
Re: Question about garbage collector
On Wednesday, 28 August 2013 at 21:28:11 UTC, bioinfornatics wrote: Hi everyone, yesterday i read an article into a french linux journal that in some years garbage collector will disapear. Why ? he explain in very very short as: -- - Moore's law will be not anymore true so only memory will continue to increase ( static and volatil ) - Garbage Collector are not efficient in big memory for some technical reason - Data to manage will continue to grow big data ant full memory stategy will the rule So Develloper will move to a language where they are no garbage collector. -- In bioinformatic we work with big data or full memory stategy often and that will not stop. So what think D garbage cllector's dev about this ? Yes, I got this gist from hardware researchers repeatedly. Buzz phrases like all computing is low power computing now get thrown around. You can google dark silicon for more details. However, your summary (or the article) is not quite correct. Garbage collection is not efficient in little-memory scenarios (embedded systems). Good, efficient garbage collection often requires a few times as much memory as manual memory management. This means if your application needs lots of RAM, you might be able tackle bigger tasks, if you get rid of the garbage collector. Also, be careful about the problem domain. There will be enough domains left in some years, where garbage collection is the better tradeoff. Just think about all the domains where Python,Ruby,etc are popular now. The interesting field is mobile, though. Android's Dalvik and Web Apps use garbage collection. iOS switched to compiler-supported reference counting a few years ago. Mobile means saving battery is important, so efficiency is important. However, battery life is not the biggest factor for consumers.
Re: improve concurrent queue
On Monday, 26 August 2013 at 19:35:28 UTC, luminousone wrote: I have been working on a project and needed a good concurrent queue What does good mean? Concurrent queues have so many design parameters (single reader? single writer? blocking? bounded? etc) and there is no queue, which performs optimal for every case. I can recommand this paper (paywalled though): http://dl.acm.org/citation.cfm?id=248106 Nevertheless, I believe you rather wanted some comments on your specific code. I wonder why you implemented spinlocks yourself? If you write a blocking algorithm, you should probably use the phobos locks.
Re: Limited Semi-PolyMorphic (LSP) structs?
On Monday, 26 August 2013 at 11:20:17 UTC, Era Scarecrow wrote: Been a while and out of the loop, I need to get my hands dirty in the code again (soon). Anyways, let's get to the matter at hand as I'm thinking about it. I'm working on some code (or will work on code again) that could use a polymorphic type, but at the end it will never be shared externally and can never extend beyond 'Known' types. (and the 'types' are behavior 95% of the time) True polymorphism will let me compile a code to work with say 'Object' and you can plug in any code and pass it an object and it will be happy, or inherit and work with it. These are great as classes. But I want to throw a wrench in the gears, I want to use structs. I know you're asking, Why? Well the data structure I'll be working with have records in the hundreds of thousands, but most of the time looking at/sorting them I don't necessarily need to allocate memory (or really even interact with them beyond sorting). Most of the time the OO aspect is just behavior and the data between them never changes (behave this way because you're a type XXX). It can take a very long time to unpack everything (when you never needed to unpack in the first place, or allocate and then de-allocate immediately, probably without recycling). Alright, structs can't inherit because they don't have an object pointer to go to their parent structures that they are connected to. If we eliminate the pointer and the overhead on some of that, we bring it down to the following: To be fully polymorphic you need to: * Be able to tell what type it is (Probably enum identifier) * Extended types cannot be larger than the base/original (or the base has to hold extra data in reserve for it's other types). When can this LSP be applicable? * When a type can be changed on the fly with no side effects other than intended (This 'text' struct is now 'left aligned text object') * When allocations/pointers aren't needed (why fully build the object at all?) * When it won't be extended beyond the current type... (only a few fixed subtypes) * When teardown/deallocation/~this() isn't needed (never allocates? Never deallocates! Just throw it all away! POD's are perfect!) * When you have no extra 'data' to append to a class/struct and only override methods/behavior (Encryption type switch from DES to BlowFish! Same API/methods, otherwise nothing really changed) * When you need a half step up from structs but don't need full classes/objects Limitations: Hmmm.. * LSP's cannot be a template or mixin (they can call on them) * Known at compile-time * Only one of them can handle setup/teardown. Now, I wonder. What if we make it so it CAN inherit? We need 3 examples, where something is in A, AB, and B. We will get to that. iA and iB are the class/structs and A/B/C are the methods/functions. So... //original based on... class iA { void A(); void C(); } class iB : iA { void A(); void B(); } Hm, my try would be alias this for inheritance and function pointers for virtual methods. struct iA { void function(iA) A; void C(); } struct iB { iA _a; alias this = _a; void B(); } If you have multiple subclasses for iA, you can use a tagged-union from std.variant.
ElementType!string
Apparently, ElementType!string evaluates to dchar. I would have expected char. Why is that?
Re: ElementType!string
On Sunday, 25 August 2013 at 19:38:52 UTC, Paolo Invernizzi wrote: On Sunday, 25 August 2013 at 19:25:08 UTC, qznc wrote: Apparently, ElementType!string evaluates to dchar. I would have expected char. Why is that? I think is because they are iterated by ranges as dchar, that's equivalent to iterating the unicode symbol. If they were iterated by char, you would get during the iteration the singles pieces of the utf8 encoding, and usually that is not what an user is expecting. Note on the other side that static assert( is(typeof( [0]) == immutable(char)) ), so you can iterate the string by chars using the index. - Paolo Invernizzi Thanks, somewhat unintuitive. This also seems to the explanation, why the types documentation decribes char as unsigned 8 bit UTF-8, which is different than ubyte unsigned 8 bit. Confirmed by this unittest: string raw = Maß;↵ assert(raw.length == 4);↵ assert(walkLength(raw)== 3);
Range-based INI parser
Playing around with ranges I built [0] a little parser for INI files [1]. It does not support multiline values, since then I cannot do the line splitting in a different component. Any good architecture ideas here? The thing with INI is that the definition is fuzzy. This means the parser should be highly configurable. What symbols for key-value-separation? What symbol for comments? Case sensitivity? Etc. I used template parameters for configuration, since that should be best for performance. Better ideas? I like my idea to output a range of (section,key,value) items. This lets the user decide, what to do with duplicate keys and avoids data structures for sections. Would something like this be a good idea for Phobos? [0] http://dpaste.dzfl.pl/1b29ef20 [1] http://en.wikipedia.org/wiki/INI_file
Re: Creating a growable binary heap or priority queue using Phobos?
On Monday, 14 November 2011 at 06:15:18 UTC, SimonM wrote: On 2011/11/14 02:10 AM, bearophile wrote: SimonM: 2009, 27 April: http://www.digitalmars.com/d/archives/digitalmars/D/std.algorithm.BinaryHeap_88811.html See the working version: http://rosettacode.org/wiki/Huffman_coding#D Bye, bearophile Okay, I looked at the example, and it seems that the only reason it works is because that piece of code never requires the array's length to grow larger than it's initial length (at the start of the loop, 2 elements are taken out, and at the end, only one is inserted back in). If I try using a BinaryHeap with a range, then, like the documentation mentions, I can't grow that BinaryHeap any larger than it's initial size, because I got the following error: Cannot grow a heap created over a range. But somehow I can't get it working with an Array!(T) like the documentation implies it should be capable of? Is this problem resolved? I cannot produce a growable BinaryHeap myself.
Re: Creating a growable binary heap or priority queue using Phobos?
On Saturday, 22 June 2013 at 07:48:25 UTC, qznc wrote: On Monday, 14 November 2011 at 06:15:18 UTC, SimonM wrote: On 2011/11/14 02:10 AM, bearophile wrote: SimonM: 2009, 27 April: http://www.digitalmars.com/d/archives/digitalmars/D/std.algorithm.BinaryHeap_88811.html See the working version: http://rosettacode.org/wiki/Huffman_coding#D Bye, bearophile Okay, I looked at the example, and it seems that the only reason it works is because that piece of code never requires the array's length to grow larger than it's initial length (at the start of the loop, 2 elements are taken out, and at the end, only one is inserted back in). If I try using a BinaryHeap with a range, then, like the documentation mentions, I can't grow that BinaryHeap any larger than it's initial size, because I got the following error: Cannot grow a heap created over a range. But somehow I can't get it working with an Array!(T) like the documentation implies it should be capable of? Is this problem resolved? I cannot produce a growable BinaryHeap myself. Ok, got it. Instead of using a dynamic array directly, wrapping it into a std.container.Array works. import std.container: Array, heapify; Foo[] arr = ...; auto wrapped = Array!Foo(arr); auto queue = heapify(wrapped); In general, other containers should work as well, since containers provide an insertBack method whereas the builtin arrays/ranges do not.
Re: AnalyzeD
On Tuesday, 18 June 2013 at 00:20:38 UTC, Andrej Mitrovic wrote: On Thursday, 30 May 2013 at 08:26:01 UTC, bioinfornatics wrote: hi Someone know if AnalyzeD could to be used from command line ? i.e http://dconf.org/talks/rohe.html I failed to find AnalyzeD source code thanks I think it's closed-source. Website has no information. No download and no licence information suggests close source. http://dlang.funkwerk-itk.com/
Monad and its little sisters
I implemented the Maybe monad using template specialization. Feedback welcome! https://bitbucket.org/qznc/d-monad/src/ba39f2551af0e2e90a40653af92c048fed519a18/generic.d?at=master However, a few questions or possibly shortcomings of D came up. 1. I could not specify the inheritance between the templates. A Monad is an Applicative, which is a Functor. Is there some template magic to check There is a template like this 'Functor!Maybe'? 2. A template cannot restrict template specializations. Specifically, the Functor(T) template should restrict Functor(T:Maybe), such that it must declare functions or templates of a specific signature. 3. Shouldn't a function be a delegate? I assume this question came up before, but there seems to be interest to make it easier. My code specifies function parameters three times. It should be a delegate and the caller should use std.functional.toDelegate to convert it. Why not an implicit cast? Performance seems to be the only problem.
Re: std.net.curl is not working?
Fri, 26 Apr 2013 19:25:16 +0200: mab wrote Why i get the following Error, when i try to compile a simple Hello World that imports std.net.curl= The Error: # dmd hello.d /usr/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4Curl19_sharedStaticCtor28FZv': std/net/curl.d:(.text._D3std3net4curl4Curl19_sharedStaticCtor28FZv+0xf): undefined reference to `curl_global_init' /usr/lib/x86_64-linux-gnu/libphobos2.a(curl.o): In function `_D3std3net4curl4Curl19_sharedStaticDtor29FZv': std/net/curl.d:(.text._D3std3net4curl4Curl19_sharedStaticDtor29FZv+0x5): undefined reference to `curl_global_cleanup' collect2: ld returned 1 exit status --- errorlevel 1 The Code: import std.stdio; import std.net.curl; void main() { writeln(hello world); } My Testsystem: Debian # uname -a Linux dexplorer 2.6.32-5-amd64 #1 SMP Mon Feb 25 00:26:11 UTC 2013 x86_64 GNU/Linux curl is installed by apt-get install curl. Thanks! You have to link libcurl via argument: dmd hello.d -L-lcurl
Re: Random double
Tue, 23 Apr 2013 22:59:41 +0200: bearophile wrote qznc: I want to generate a random double value, excluding wierdos like NaN and Infinity. However, std.random.uniform seems to be useless. Can you explain why you need uniform doubles in their whole range? I think I have never had to generate them so far. Maybe for a unittest? Good guess. :) I want to port QuickCheck. The core problem is: Given a type T, generate a random value. https://bitbucket.org/qznc/d-quickcheck/src/ eca58bb97b24cedd6128cdda77bbebeaf1689956/quickcheck.d?at=master Also note by their nature doubles are not equally spread across the line of Reals, so getting a truly uniform distribution is hard or impossible. It also raises the question what uniform means in the context of floating point. Uniform over the numbers or uniform over the bit patterns?
Re: Random double
Tue, 23 Apr 2013 13:49:48 -0700: Ali Çehreli wrote On 04/23/2013 11:55 AM, qznc wrote: Tue, 23 Apr 2013 16:43:14 +0200: qznc wrote I want to generate a random double value, excluding wierdos like NaN and Infinity. However, std.random.uniform seems to be useless. I tried things like std.random.uniform( double.min, double.max); std.random.uniform(-double.max, double.max); std.random.uniform(0.0, double.max); However, I just get Inf values. :( I assume this is due to floating point computation within uniform, which easily becomes Inf, if you come near the double.max boundary. Should that be considered a bug? Nevertheless, any ideas how to work around that issue? Using a union seems to be a good workaround: union foo { ulong input; double output; } foo val = void; do { val.input = uniform(ulong.min, ulong.max); } while (val.output == double.infinity || val.output == -double.infinity || val.output != val.output); return val.output; Maybe the implementation of uniform should use a similar trick? Unfortunately, that will not produce a uniform distribution. The results will mostly be in the range [-0.5, 0.5]. The lower and higher values will have half the chance of the middle range: Interesting. Why [-0.5,0.5], though? I would have expected [-1.0,1.0] from Clugston's article. http://dlang.org/d-floating-point.html