Re: Mobile support
On Monday, 26 October 2015 at 05:34:05 UTC, Dan Olson wrote: Andrei Alexandrescu writes: On 10/18/15 7:55 AM, Joakim wrote: Now, the download page has not traditionally listed alphas and betas. But the importance of mobile is so high that I think it is worth it to do so, with the appropriate cautions about alpha quality. Yes, very much so. Please make that happen. Thanks! -- Andrei I think it makes sense to add a link to the LDC iOS releases in http://wiki.dlang.org/Compilers. Perhaps a row for iOS in table "Package and/or binary availability, by platform and compiler". I am not sure it belongs on http://dlang.org/download.html though until somebody besides me has reported success using D in an iOS App. How should I proceed? Hi Dan, Regardless of what happens on http://dlang.org/download.html, please add it to the wiki. I've been chasing after compiler hackers to update the wiki with very little success (and then they complain how their projects are not getting enough attention etc.).
Re: Mobile support
Andrei Alexandrescu writes: > On 10/18/15 7:55 AM, Joakim wrote: >> Now, the download page has not traditionally listed alphas and betas. >> But the importance of mobile is so high that I think it is worth it to >> do so, with the appropriate cautions about alpha quality. > > Yes, very much so. Please make that happen. Thanks! -- Andrei I think it makes sense to add a link to the LDC iOS releases in http://wiki.dlang.org/Compilers. Perhaps a row for iOS in table "Package and/or binary availability, by platform and compiler". I am not sure it belongs on http://dlang.org/download.html though until somebody besides me has reported success using D in an iOS App. How should I proceed? -- Dan
Re: DMD is slow for matrix maths?
On Mon, Oct 26, 2015 at 02:37:16AM +, Etienne Cimon via Digitalmars-d wrote: > I've been playing around with perf and my web server and found that > the bottleneck is by far the math module of Botan: > https://github.com/etcimon/botan/blob/master/source/botan/math/mp/mp_core.d > > I'm probably a bit naive but I was wishing for some inlining to > happen. I see LOTS of CPU time spent on "pop" instructions to return > from a simple multiply function, and the pragma(inline, true) was > refused on all of these. So, should I wait for an inline? Should I > import another library? Should I rewrite all the maths in assembly > manually for each processor? Should I write another library that must > be compiled with LDC/release for maths? > > I think the best option would be for an inline feature in DMD that > works, but I'm wondering what the stance is right now about the > subject? For an immediate solution to performance-related issues, I recommend using GDC or LDC (with maximum optimization options) instead of DMD. If you must use DMD, I recommend filing an enhancement request and bothering Walter about it. T -- MS Windows: 64-bit rehash of 32-bit extensions and a graphical shell for a 16-bit patch to an 8-bit operating system originally coded for a 4-bit microprocessor, written by a 2-bit company that can't stand 1-bit of competition.
DMD is slow for matrix maths?
I've been playing around with perf and my web server and found that the bottleneck is by far the math module of Botan: https://github.com/etcimon/botan/blob/master/source/botan/math/mp/mp_core.d I'm probably a bit naive but I was wishing for some inlining to happen. I see LOTS of CPU time spent on "pop" instructions to return from a simple multiply function, and the pragma(inline, true) was refused on all of these. So, should I wait for an inline? Should I import another library? Should I rewrite all the maths in assembly manually for each processor? Should I write another library that must be compiled with LDC/release for maths? I think the best option would be for an inline feature in DMD that works, but I'm wondering what the stance is right now about the subject?
Re: Playing SIMD
On 10/25/15 6:57 PM, Iakh wrote: On Sunday, 25 October 2015 at 21:13:56 UTC, Andrei Alexandrescu wrote: [...] This is compelling but needs a bit of work to integrate. Care to work on a PR that makes std.algorithm use it? Thanks! -- Andrei First of all I need sort of investigation about PRs and std.algorithm. But in general challenge accepted. Thanks! -- Andrei
Re: Playing SIMD
On 25.10.2015 20:37, Iakh wrote: Full exaple with comparation of algorithms (SIMD, naive, binary search): http://dpaste.dzfl.pl/f3b8989841e3 From there: void runBinary() { static int i = 0; naiveIndexOf(cast(ubyte)(i++/ArraySize + 1), arr); } runBinary calls naiveIndexOf. You're not testing binaryIndexOf.
Re: Playing SIMD
On Sunday, 25 October 2015 at 21:13:56 UTC, Andrei Alexandrescu wrote: [...] This is compelling but needs a bit of work to integrate. Care to work on a PR that makes std.algorithm use it? Thanks! -- Andrei First of all I need sort of investigation about PRs and std.algorithm. But in general challenge accepted.
Re: Playing SIMD
On Sunday, 25 October 2015 at 22:17:58 UTC, Matthias Bentrup wrote: On Sunday, 25 October 2015 at 19:37:32 UTC, Iakh wrote: Is it optimal and how do you implement this stuf? I think it's better to use PMOVMSKB to avoid storing the PCMPEQB result in memory and you need only one BSF instruction. Yeah but PMOVMSKB not implemented in core.simd. Bit more comprehensive here: http://forum.dlang.org/post/20150923115833.054fdb09@marco-toshiba
Re: Playing SIMD
On Sunday, 25 October 2015 at 19:37:32 UTC, Iakh wrote: Is it optimal and how do you implement this stuf? I think it's better to use PMOVMSKB to avoid storing the PCMPEQB result in memory and you need only one BSF instruction.
Re: Kinds of containers
On Sunday, 25 October 2015 at 15:42:02 UTC, Andrei Alexandrescu wrote: Jonathan, do you have a link to your work? Sorry, but no. I haven't mucked around with this issue recently, and whatever I have left on the topic is either buried in a newsgroup post somewhere or buried on my hard drive somewhere where I wouldn't know where to find it. Searching on the newsgroup for discussions on tail-const would find stuff related to this if you want to go spelunking, since it's the tail-const issues where the fact that const(Foo!T) and Foo!(const T) aren't related typically comes up and likely causes the largest problems. The EMSI containers may have some interesting stuff with regards to the problem, since I know that those guys tried very hard to be able to support tail-const ranges. The main thing that I recall is that if you want to be able to get a tail-const range from a const range, you have to use a static if to protect the const opSlice declaration so that you don't end up with a recursive template instantiation (since it has to return another instantiation of the range's template). And even then, an opSlice with no arguments isn't technically a standard range function, because none of the range traits require it (so you can't rely on a range having it). Rather, it's a container function for getting a range. And even if it were a range function, it wouldn't get the special treatment that arrays get when being passed to a templated function (IFTI infers an array's type as being a tail-const slice, which doesn't happen with anything else), and even if it did, a const range wouldn't implicitly convert to its tail-const variant without an alias this, which is likely to create a whole other set of problems - particularly since implicit conversions tend to wreak havoc in generic code. Handling tail-const with ranges in a manner consistent with arrays and supporting $ with ranges are probably the two big places that ranges can't currently emulate the behavior of arrays. The $ problem is technically solvable as-is, but without some form of https://issues.dlang.org/show_bug.cgi?id=7177 being implemented, changing hasSlicing or isRandomAccessRange to require that a range works with $ would likely break too much code, so no range-based code can really using $ unless it explicitly checks for it. However, I'm not sure that the tail-const problems is solvable without further language improvements. We likely need some sort of standard way to convert a const(Foo!T) to a Foo!(const T) - possibly via opSlice, since it wouldn't make sense for something that wasn't emulating an array. And we might need to make changes to IFTI so that it infers tail-const for ranges (at least if they provide such a conversion), but I'm not sure what the implications of that are. There's also the issue of accidentally slicing ranges (e.g. https://issues.dlang.org/show_bug.cgi?id=14619 ) which can cause incorrect behavior in at least some cases, depending on the range type - and if a range is a reference type, then slicing it would be akin to saving it, which could mean allocating. So, unlike with arrays, we probably don't want ranges in general to get sliced just because they're passed to a function, meaning that we may just want IFTI to not play fun games with ranges and let arrays be special there. In any case, I should probably try and find time soon to sit down and at least go over the issues in detail again so that I'm clearer on them and could possibly present a DIP intended to resolve them. I haven't dug through them recently, and my general approach up until now when I've needed to actually get work done has been to just not use const or inout with ranges. - Jonathan M Davis
Re: Kinds of containers
On 10/25/2015 08:33 PM, Andrei Alexandrescu wrote: On 10/24/2015 07:03 PM, Timon Gehr wrote: On 10/24/2015 09:22 PM, Andrei Alexandrescu wrote: On 10/24/15 3:19 PM, Timon Gehr wrote: Even if this was possible, it would not be a very good idea. Persistent data structures have use cases that would be hindered by required transitive immutability. This part I don't quite get. The slots are not mutable, but they are not /transitively/ immutable either. Note that this does not require any special effort, nor does it /prevent/ stored elements from being (transitively) immutable. Scala does it this way. (Haskell as well, basically.) I see. Well, this will be unpleasant to implement in D. One simple way to do so would be to have accessors return rvalues: T front() { ... } Then you get to change the indirections of T, if any, but not what's stored in the container directly. Problem is accessing every element by rvalue is likely to be inefficient in the general case (even on data without copy ctors). Andrei As I mentioned, the cheap way out for performance would be to provide what you suggested (persistent topology, arbitrary reference access to slots). Users can then use type qualifiers at their own discretion. There could probably even be short aliases to automatically have immutable elements. What's important is that use cases for mutable elements are not ruled out. They don't necessarily need to be on the path of least resistance.
Re: Kinds of containers
On 10/25/2015 05:06 PM, Timon Gehr wrote: class A{}; class B: A{}; int main(){ vector a; vector b; a=b; } However, the conversion would be safe. Agreed. I don't see that as an important matter though; it's after all a coercion so a function call is plenty fine. -- Andrei
Re: Playing SIMD
On 10/25/2015 03:37 PM, Iakh wrote: Here is my implementatation of SIMD find. Function returns index of ubyte in static 16 byte array with unique values. -- immutable size_t ArraySize = 16; int simdIndexOf(ubyte niddle, ref const ubyte[ArraySize] haystack) { ubyte16 arr; arr.array = haystack[]; ubyte16 niddles; niddles.array[] = niddle; ubyte16 result; result = __simd_sto(XMM.PCMPEQB, arr, niddles); alias Mask = ulong; static assert(2 * Mask.sizeof == result.sizeof); immutable BitsInByte = 8; if (Mask mask = *cast(Mask*)(result.array.ptr)) { return bsf(mask) / BitsInByte; } else if (Mask mask = *cast(Mask*)(result.array.ptr + Mask.sizeof)) { return bsf(mask) / BitsInByte + cast(int)Mask.sizeof; } else { return -1; } } -- Is it optimal and how do you implement this stuf? Full exaple with comparation of algorithms (SIMD, naive, binary search): http://dpaste.dzfl.pl/f3b8989841e3 Benchmark result on dpaste.dzfl.pl: SIMD: TickDuration(157000) Binary: TickDuration(472000) Naive: TickDuration(437000) At home with defult dub config "dub run --build=release": SIMD:TickDuration(241566) Binary: TickDuration(450515) Naive: TickDuration(450371) This is compelling but needs a bit of work to integrate. Care to work on a PR that makes std.algorithm use it? Thanks! -- Andrei
Re: Kinds of containers
On 10/25/2015 08:31 PM, Andrei Alexandrescu wrote: On 10/23/2015 07:21 PM, bigsandwich wrote: On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote: On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote: [...] Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect. [...] Its not just type qualifiers. Containers of derived types have the same problem. This is also a problem in C++. This is something easy to live with. In fact, mutable containers are not supposed to even convert to containers of base objects. -- Andrei This is true for containers with reference semantics, but not for containers with value semantics. This compiles (D code): class A{} class B: A{} void main(){ A[2] a; B[2] b; a=b; } This does not compile (C++ code): class A{}; class B: A{}; int main(){ vector a; vector b; a=b; } However, the conversion would be safe. For persistent and COW containers, the copy would even be fast.
Re: Is dlangui dead?
On Tuesday, 20 October 2015 at 17:01:19 UTC, karabuta wrote: I hope I am wrong, but dlangui seems to be abandoned for some time after all the hard work that went into it. I really like it since it was easy to setup and get things working. Maybe the author decided it's "done and ready"? In fact, I consider it the best option. Yep, I'm using it in one important project and several small ones. So with Vadim or without, DlangUI will live.
Re: Adapting Tree Structures for Processing with SIMD,Instructions
On Wednesday, 23 September 2015 at 09:58:39 UTC, Marco Leise wrote: Am Tue, 22 Sep 2015 16:36:40 + schrieb Iakh : [...] Implementatation of SIMD find algorithm: http://forum.dlang.org/post/hwjbyqnovwbyibjus...@forum.dlang.org
Playing SIMD
Here is my implementatation of SIMD find. Function returns index of ubyte in static 16 byte array with unique values. -- immutable size_t ArraySize = 16; int simdIndexOf(ubyte niddle, ref const ubyte[ArraySize] haystack) { ubyte16 arr; arr.array = haystack[]; ubyte16 niddles; niddles.array[] = niddle; ubyte16 result; result = __simd_sto(XMM.PCMPEQB, arr, niddles); alias Mask = ulong; static assert(2 * Mask.sizeof == result.sizeof); immutable BitsInByte = 8; if (Mask mask = *cast(Mask*)(result.array.ptr)) { return bsf(mask) / BitsInByte; } else if (Mask mask = *cast(Mask*)(result.array.ptr + Mask.sizeof)) { return bsf(mask) / BitsInByte + cast(int)Mask.sizeof; } else { return -1; } } -- Is it optimal and how do you implement this stuf? Full exaple with comparation of algorithms (SIMD, naive, binary search): http://dpaste.dzfl.pl/f3b8989841e3 Benchmark result on dpaste.dzfl.pl: SIMD: TickDuration(157000) Binary: TickDuration(472000) Naive: TickDuration(437000) At home with defult dub config "dub run --build=release": SIMD:TickDuration(241566) Binary: TickDuration(450515) Naive: TickDuration(450371)
Re: Kinds of containers
On 10/24/2015 07:03 PM, Timon Gehr wrote: On 10/24/2015 09:22 PM, Andrei Alexandrescu wrote: On 10/24/15 3:19 PM, Timon Gehr wrote: Even if this was possible, it would not be a very good idea. Persistent data structures have use cases that would be hindered by required transitive immutability. This part I don't quite get. The slots are not mutable, but they are not /transitively/ immutable either. Note that this does not require any special effort, nor does it /prevent/ stored elements from being (transitively) immutable. Scala does it this way. (Haskell as well, basically.) I see. Well, this will be unpleasant to implement in D. One simple way to do so would be to have accessors return rvalues: T front() { ... } Then you get to change the indirections of T, if any, but not what's stored in the container directly. Problem is accessing every element by rvalue is likely to be inefficient in the general case (even on data without copy ctors). Andrei
Re: Kinds of containers
On 10/23/2015 07:21 PM, bigsandwich wrote: On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote: On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote: [...] Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect. [...] Its not just type qualifiers. Containers of derived types have the same problem. This is also a problem in C++. This is something easy to live with. In fact, mutable containers are not supposed to even convert to containers of base objects. -- Andrei
Re: Option types and pattern matching.
On 2015-10-25 20:00, John Colvin wrote: Without having looked at this in detail, phobos should have a good generic implementation of pattern matching, so you should consider creating a pull request (std.functional would be the natural home I think). I've been waiting for this PR [1] to get merged before implementing pattern matching as a library function. [1] https://github.com/D-Programming-Language/dmd/pull/5201 -- /Jacob Carlborg
Re: Option types and pattern matching.
On Sunday, 25 October 2015 at 18:15:20 UTC, TheFlyingFiddle wrote: This problem has gained my interest and I plan on implementing this sometime this week. I'll post a link to the source when it's done if anyone is interested in it. Without having looked at this in detail, phobos should have a good generic implementation of pattern matching, so you should consider creating a pull request (std.functional would be the natural home I think).
Re: Option types and pattern matching.
On Sunday, 25 October 2015 at 18:23:42 UTC, Dmitry Olshansky wrote: I humbly believe that D may just add special re-write rule to the switch statement in order to allow user-defined switchable types. This goes along nicely with the trend - e.g. foreach statement works with anything having static range interfaces or opApply. I don't think I understand this, could you elaborate?
Re: Option types and pattern matching.
On 25-Oct-2015 08:01, Nerve wrote: Hello D community! First time poster, I'm utterly fascinated with this language's mix of features. It's powerful and expressive. There are just two conveniences I'd like to see out of D. The first is pattern matching, a functional construct which can unwrap tuples or other containers, usually evaluates to a value (in most languages), and which almost always idiomatically enforces the programmer to match over every possible case of a given type. While ML-inspired languages like F# and OCaml have some good pattern matching syntax, it's not syntax which would fit in to D; I suggest taking inspiration of Rusts's matching construct. match x { Some(7) => "Lucky number 7!", Some(_) => "No lucky number.", None => "No value found" } I humbly believe that D may just add special re-write rule to the switch statement in order to allow user-defined switchable types. This goes along nicely with the trend - e.g. foreach statement works with anything having static range interfaces or opApply. All in all we've seen a lot of examples of how it's done in the library but always somewhat cumbersome. The next big problem would be that switch is a statement not expression which limits use-cases of user-defined pattern matching. -- Dmitry Olshansky
Re: Option types and pattern matching.
On Sunday, 25 October 2015 at 14:43:25 UTC, Nerve wrote: On Sunday, 25 October 2015 at 06:22:51 UTC, TheFlyingFiddle wrote: That is actually freaking incredible. It evaluates to a value, unwraps values, matches against the None case...I guess the only thing it doesn't do is have compiler-enforced matching on all cases. Unless I'm just slow this morning and not thinking of other features a pattern match should have. With some changes to the match function one could enforce that a default handler is always present so that all cases are handled or error on compilation if it's not. Something like: (naive way) auto ref match(Handlers...)(Variant v) { //Default handler must be present and be the last handler. static assert(Parameters!(Handlers[$ - 1]).length == 0, "Matches must have a default handler."); } now //Would be a compiler error. v.match!((int n) => n.to!string)); //Would work. v.match!((int n) => n.to!string), () => "empty"); Additionally one could check that all return types share a common implicit conversion type. And cast to that type in the match. //Returns would be converted to long before being returned. v.match!((int n) => n, //Returns int (long n) => n, //Returns long () => 0); Or if they don't share a common implicit conversion type return a Variant result. Also the handlers could be sorted so that the more general handlers are tested later. //Currently v.match!((int n) => n, (CMatch!7) => 0, () => 0); Would not really work since (int n) is tested for first so CMatch!7 would never get called even if the value was 7. But if we sort the incoming Handlers with CMatch instances at the front then the above would work as a user intended. This would also allow the empty/default case to be in any order. For even more error checking one could make sure that no CMatch value intersects with another. That way if there are for example two cases with CMatch!7 then an assert error would be emited. So: v.match!((CMatch!7) => "The value 7", (CMatch!7) => "A seven value", () => "empty"); Would error with something like "duplicate value in match" Other extensions one could do to the pattern matching is: 1. Allow more then one value in CMatch. So CMatch!(5, 7) would mean either 5 or 7. 2. Rust has a range syntax, this could be kind of nice. Maybe RMatch!(1, 10) for that. 3. Add a predicate match that takes a lambda. //Predicate match. struct PMatch(alias lambda) { alias T = Parameters!(lambda)[0]; alias this value; T value; static bool match(Variant v) { alias P = Parameters!lambda; if(auto p = v.peek!P) { if(lambda(*p)) { value = *p; return true; } } return false; } } struct RMatch(T...) if(T.length == 2) { alias C = CommonType!(typeof(T[0]), typeof(T[1])); C value; alias this value; static bool match(Variant v) { if(auto p = v.peek!C) { if(*p >= T[0] && *p < T[1]) { value = *p; return true; } } return false; } } v.match!( (RMatch!(1, 10) n) => "Was (1 .. 10): " ~ n.to!string; (PMatch!((int x) => x % 2 == 0) n) => "Was even: " ~ n.to!string, (PMatch!((int x) => x % 2 == 1) n) => "Was odd: " ~ n.to!string, () => "not an integer"); The PMatch syntax is not the most fun... It can be reduced slightly if your not using a variant but a Maybe!T type or a regular old type to. The pattern matching can have more static checks and the syntax can look a somewhat better if we are matching on a Maybe!T type or a regular type instead of a variant. We could for example make sure that all CMatch/RMatch values have the correct type and (in some limited cases) ensure that all cases are covered without the need for a default switch. All in all I think that something like this would be a fairly comprehensive library pattern matching solution. Catching many types of programming errors at compile-time. It could be fast as well if all the constants and ranges are converted into a switch statements (via string mixin magic). This problem has gained my interest and I plan on implementing this sometime this week. I'll post a link to the source when it's done if anyone is interested in it.
Re: Kinds of containers
On 10/23/2015 01:44 PM, deadalnix wrote: On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote: On 10/22/15 1:09 AM, deadalnix wrote: The elephant in the room: make the template parameter's type qualifier transitive with the collection's qualifier. Could you please give more detail on this? Thanks! -- Andrei Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect. Collection!T and Collection!const(T) are 2 completely different types. There is a good reason for this : static if (is(T == const)) { ... } . As a result thing like : void foo(T)(const Collection!const(T) c) {} void main() { Collection!T c; foo(c); // Error, GTFO ! } Makes sense. The way I like to think about it is in terms of compatibility with built-in types such slices. This code works: void foo(T)(const T[] c) {} void main() { int[] c; foo(c); // fine } With the different qualifiers and implicit conversion, thing become quite tricky. You can simulate them partially with a set of carefully crafted alias this (but not having multiple alias this doesn't make things any simpler) but there is the monster of mutually recursive template instanciation that is lurking. As far as i know, jmdavis had some good work done on this, but it was far from perfect. Thanks, I see. The way I see it is as the work of "alias this"; any failure can be ascribed as a burden on the alias this definition. Jonathan, do you have a link to your work? Andrei
Re: Option types and pattern matching.
On Sunday, 25 October 2015 at 06:22:51 UTC, TheFlyingFiddle wrote: You can do something very similar to that. With slightly different syntax. import std.traits; import std.conv; import std.variant; struct CMatch(T...) if(T.length == 1) { alias U = typeof(T[0]); static bool match(Variant v) { if(auto p = v.peek!U) return *p == T[0]; return false; } } auto ref match(Handlers...)(Variant v) { foreach(handler; Handlers) { alias P = Parameters!handler; static if(P.length == 1) { static if(isInstanceOf!(CMatch, P[0])) { if(P[0].match(v)) return handler(P[0].init); } else { if(auto p = v.peek!(P[0])) return handler(*p); } } else { return handler(); } } assert(false, "No matching pattern"); } unittest { Variant v = 5; string s = v.match!( (CMatch!7) => "Lucky number seven", (int n)=> "Not a lucky number: " ~ n.to!string, () => "No value found!"); writeln(s); } That is actually freaking incredible. It evaluates to a value, unwraps values, matches against the None case...I guess the only thing it doesn't do is have compiler-enforced matching on all cases. Unless I'm just slow this morning and not thinking of other features a pattern match should have.
Re: Vision
Many thanks to all who replied. I have integrated feedback and moved the page: http://wiki.dlang.org/Vision/2015H2 (Of course it remains open for improvement.) One note of importance: PR activity has not grown a lot in this half - we have 1037 pull requests as of end of Oct 24. Compare with 1054 for the same period in 2014 and with 1538 for the entire H2 2014. Please accept my apologies for being ridiculously behind schedule. I knew since the beginning of 2015 it's going to be a weird year: new kid, moving across the country, new home, new job for my spouse, leaving Facebook, conference travels... things are only starting to unwind properly now. We should be able to find the time and focus to deliver the vision documents in a timely manner to keep the community engaged. Andrei
Re: Vision
On 10/22/2015 11:09 AM, Jonathan M Davis wrote: Maybe the color stuff belongs in Phobos. Maybe not. But IMHO, concerns about 3rd party projects dying off is _not_ a good reason to put something in the standard library. I don't think that we want large amounts of code being thrown into Phobos on the theory that the Phobos devs will maintain it and whoever wrote it can stop caring. Wise words. -- Andrei
Re: Vision
On 10/21/2015 10:17 PM, Vladimir Panteleev wrote: On Wednesday, 21 October 2015 at 22:35:35 UTC, Andrei Alexandrescu wrote: TWiD is an official newsletter. -- Andrei For being an official newsletter, it doesn't get the exposure it deserves. So Adam and I put this together today: https://github.com/D-Programming-Language/dlang.org/pull/1136 Looks fantastic and Adam sent me word it increased traffic considerably - good job! -- Andrei
Re: My experience from learning Polish language
On Sunday, 25 October 2015 at 05:15:04 UTC, Ali Çehreli wrote: On 10/24/2015 04:15 AM, Cauterite wrote: On Saturday, 24 October 2015 at 11:01:24 UTC, grumpyalittle wrote: My name is Daisy and I was on Erasmus program in Poland. During This looks like spam to me. Of course spam but it's pretty amusing. :) It must have happened like this: - Polish language school, which happens to be named PROLOG hires spammers for some effective spamming. - Clueless spammers search for newsgroups that are related to "prolog language". - Prolog happens to be a programming language. So is D, and we get the spam. :) And one of the new sample programs on the start page is an RPN calculator :-P
Re: My experience from learning Polish language
On Sat, 2015-10-24 at 22:15 -0700, Ali Çehreli via Digitalmars-d wrote: > […] > > (Why did I write all this?) Explanations help people understand. I for one am pleased you took the time. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Kinds of containers
On Sunday, 25 October 2015 at 05:37:02 UTC, deadalnix wrote: On Saturday, 24 October 2015 at 19:33:03 UTC, David Nadlinger wrote: On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote: Collection!T and Collection!const(T) are 2 completely different types. Isn't this also required anyway because of covariance vs. contravariance considerations? — David It is close, but not exactly the same. Covariance/contravariance can be emutalted via alias this without too much trouble for a container (however, it is hard to ensure correctness, but I'd assume not too hard). On the other hand, the qualifier thing turtle from the collection to the element in the collection, which is not that easy to achieve. The bigger problem is probably ranges rather than containers. We get tail-const slices from arrays all the time, but opSlice with no arguments isn't really a range operation (none of the range traits require it), and it's pretty painful to get it to make tail-const work with opSlice anyway (though I know that the EMSI guys were jumping through all kinds of hoops to make it work, so their containers make actually handle it reasonably well). Plus there's the fun problem of how declaring opSlice on a range causes foreach to call it, which essentially means that your range can get saved accidentally, which can be problematic (especially for ranges like RefRange). It's been a while since I sat down and worked through the various issues that we have here. I should probably do that soon and see if I can distill them down well enough to come up with a DIP to resolve them - or at least to clearly present them so that they can be discussed. What we have right now mostly works, but it falls apart in some corner cases - especially if you want to be able to operate on a range like you would an array. - Jonathan M Davis
Re: Option types and pattern matching.
On 2015-10-25 06:01, Nerve wrote: Hello D community! First time poster, I'm utterly fascinated with this language's mix of features. It's powerful and expressive. There are just two conveniences I'd like to see out of D. The first is pattern matching, a functional construct which can unwrap tuples or other containers, usually evaluates to a value (in most languages), and which almost always idiomatically enforces the programmer to match over every possible case of a given type. While ML-inspired languages like F# and OCaml have some good pattern matching syntax, it's not syntax which would fit in to D; I suggest taking inspiration of Rusts's matching construct. match x { Some(7) => "Lucky number 7!", Some(_) => "No lucky number.", None => "No value found" } From that bit of code, we can see another feature at work: The Option type. It wraps another type (i.e. Option int, Option Car) and represents a wrapped presence of a value of that type (Some(n), Some(aCar)) or an absence of that type (None). Combined with pattern matching, we end up with a safe, functional construct which can replace a switch statement in most cases, returns a value, is incredibly compact and readable, and can be used with Options to ensure that we always account for the possibility of a value not present, eliminating a whole class of errors when we use it judiciously. My only concern is that switch statements, while horrendous syntactically, are extremely performant and essentially compile to a series of branches. Are there any counter-arguments for the implementation of these two features? Is D in a state where language additions have come to a stop? Both of these can be implemented in library code. Although the syntax won't be as nice. I wouldn't mind having pattern matching as a language feature. -- /Jacob Carlborg