Re: Should we add `a * b` for vectors?
On Thursday, 28 September 2017 at 01:58:24 UTC, Walter Bright wrote: On 9/27/2017 4:21 PM, Manu wrote: [...] but I see no advantage to it over D's approach (the reverse operand lookup scheme). I couldn't find anything focused on D's overloading resolution scheme (or anything with the specific term "reverse operand lookup"). Can you elaborate?
Re: C++ / Why Iterators Got It All Wrong
On Sunday, 3 September 2017 at 09:24:03 UTC, Ilya Yaroshenko wrote: 1. Contiguous tensors. Their data is located contiguously in memory. Single dense memory chunk. All strides between subs-tensors can be computed from lengths. 2. Canonical tensors. Only data for one dimension is dense, other dimensions has strides that can not be computed from lengths. BLAS matrixes are canonical tensors: they have two lengths and one stride. 3. Universal tensors. Each dimension has a stride. Numpy ndarrays are universal tensors. Can you elaborate?
Re: C++17 Init statement for if/switch
On Wednesday, 16 August 2017 at 14:19:59 UTC, SrMordred wrote: On Tuesday, 15 August 2017 at 21:05:09 UTC, bachmeier wrote: On Tuesday, 15 August 2017 at 20:31:50 UTC, Jonathan Marler wrote: Without alot of usage, it will just be an esoteric construct that looks confusing to the average developer. That is correct. After a while it gets tiring to see a neverending stream of complexity added to the language while things that would actually help (like IDE support) do not get any attention. As a general rule, if it's being added to C++, it's probably a bad idea. There are two thinks of c++ that I miss a little on D: - Structured binding - Uniform initialization But in general, I agreed with you. Initialization in D is pretty uniform now though. What corners am I missing? It's usually: name = (args); Structured bindings... I think C++ did it badly, actually. They had the {...} syntax fr object construction that worked everywhere and using the same for deconstruction would've allowed for quite natural tuples, which manifest almost as language-level constructs by then (with the help of 'auto' in template parameters).
Re: The X Macro using D
On Thursday, 20 July 2017 at 22:02:32 UTC, Walter Bright wrote: On 7/20/2017 2:21 PM, Stefan Koch wrote: Please tell me this is not going to get into dmd :) templates are so much more expensive then macros. (Well, for now :) ) Those templates can and should be replaced by CTFE. If you like, present the CTFE solution. Should be fun! How about this (if I'm not mistaken, this's only one template instantiation per tuple-type&extracted-index): ```d import std.typecons: tuple, Tuple; import std.algorithm: map; import std.array: array; enum regm_t { AX, BX, CX, DX, DI, SI, None } enum tym_t { uchar_, ushort_, ulong_ } enum Ydata = [ tuple("AH", 4, regm_t.AX, tym_t.uchar_), tuple("AL", 0, regm_t.AX, tym_t.uchar_), tuple("AX", 8, regm_t.AX, tym_t.ushort_), tuple("BH", 7, regm_t.BX, tym_t.uchar_), tuple("BL", 3, regm_t.BX, tym_t.uchar_), tuple("BP", 13, regm_t.None, tym_t.ushort_), tuple("BX", 11, regm_t.BX, tym_t.ushort_), tuple("CH", 5, regm_t.CX, tym_t.uchar_), tuple("CL", 1, regm_t.CX, tym_t.uchar_), tuple("CX", 9, regm_t.CX, tym_t.ushort_), tuple("DH", 6, regm_t.DX, tym_t.uchar_), tuple("DI", 15, regm_t.DI, tym_t.ushort_), tuple("DL", 2, regm_t.DX, tym_t.uchar_), tuple("DX", 10, regm_t.DX, tym_t.ushort_), tuple("EAX", 16, regm_t.AX, tym_t.ulong_), tuple("EBP", 21, regm_t.None, tym_t.ulong_), tuple("EBX", 19, regm_t.BX, tym_t.ulong_), tuple("ECX", 17, regm_t.CX, tym_t.ulong_), tuple("EDI", 23, regm_t.DI, tym_t.ulong_), tuple("EDX", 18, regm_t.DX, tym_t.ulong_), tuple("ESI", 22, regm_t.SI, tym_t.ulong_), tuple("ESP", 20, regm_t.None, tym_t.ulong_), tuple("SI", 14, regm_t.SI, tym_t.ushort_), tuple("SP", 12, regm_t.None, tym_t.ushort_), ]; static auto Y(size_t idx, T...)(Tuple!(T)[] ts) pure nothrow { // I thought to try something like assumeUnique here // but was thinking of the Rust semantics in doing so // Not sure if this leads to spurious allocations at // the points where Y is used. Is there someway to tell them, // even if the target type is const or immutable // that this returned array is brand new with no other references // around? return ts .map!(x => x[idx]) .array ; } enum { Xtab = 0, Xreg, Xmask, Xty, } // Register number to use in addressing mode private __gshared const(char)*[24] pseudotab = Y!Xtab(Ydata); // Register number to use in addressing mode __gshared ubyte[24] pseudoreg = Y!Xreg(Ydata); // Mask to use for registers affected __gshared regm_t[24] pseudomask = Y!Xmask(Ydata); // Table for type of pseudo register variable private __gshared const(tym_t)[24] pseudoty = Y!Xty(Ydata); ```
Re: Compilation times and idiomatic D code
On Saturday, 15 July 2017 at 15:58:12 UTC, Jonathan M Davis wrote: On Saturday, July 15, 2017 11:10:32 Enamex via Digitalmars-d wrote: [...] The issue has to do with how each invocation of a range-based function tends to result in a new template instantiation, and it's common practice in D to chain a bunch of templated function calls together. For instance, if you have [...] The type is getting progressively longer and more complicated, because when the function template is instantiated, it's instantiated with the type from the previous function call, so it's wrapping the previous type, and you get a new type that has the name of the type of its argument embedded in it. It's like if you keep wrapping a container inside another container. [...] - Jonathan M Davis This was quite insightful, thank you. All that time I'd assumed that 'symbols' as linkers used them were constant length :T Just to be clear: 100% of that bloat resides in the symbol table? So the current proposed remedy is to hash symbols above a length threshold? Besides the symbol problem though, does the template instantiation explosion problem imply as many duplicated function bodies corresponding to the new type symbols?
Re: Compilation times and idiomatic D code
On Friday, 14 July 2017 at 22:45:44 UTC, H. S. Teoh wrote: Here's a further update to the saga of combating ridiculously large symbol sizes. So yesterday I wrote a new module that also heavily uses UFCS chains. My initial draft of the module, once I linked it with the main program, particularly with a UFCS chain that has led to the 600MB executable sizes seen above, caused another explosion in symbol size that actually managed to reach 100MB in *one* symbol, triggering a DMD termination complaining about possible infinite template recursion. :-D Funnier still, temporarily simplifying part of the chain to bring symbol sizes down, I eventually got it below 100MB but ended up with linker segfaults and ELF errors because the huge symbol was too ridiculously huge. Eventually, it drove me to refactor two Phobos functions that are used heavily in my code: std.range.chunks and std.algorithm.joiner, using the same "horcrux" technique (see Phobos PRs #5610 and #5611). This, together with some further refactoring in my own code, eventually brought things down to the 20MB range of executable sizes. Then an idea occurred to me: the reason these symbol sizes got so large, was because the UFCS chain preserves *all* type information about every component type used to build the final type. So, by necessity, the type name has to somehow encode all of this information in an unambiguous way. Now, arguably, DMD's current mangling scheme is at fault because it contains too many repeating components, but even if you disregard that, the fact remains that if you have 50+ components in your overall UFCS chain, the symbol length cannot be less than 50*n where n is the average length of a single component's type name, plus some necessary overhead to account for the mangling scheme syntax. Let's say n is on average 20-25 characters, say round it up to 35 for mangling syntax, so you're still looking at upwards of 1700+ characters *minimum*. That, coupled with the current O(n^2) / O(n^3) mangling scheme, you easily reach megabytes of symbol length. We can compress the symbols all we want, but there's a limit as to how much compression will help. At the end of the day, you still have to represent those 50+ components *somehow*. But what if most of this type information is actually *unnecessary*? To use a range example, if all you care about at the end of the chain is that it's a forward range of ubyte, then why even bother with multi-MB symbols encoding type information that's never actually used? Maybe a little type-erasure would help, via hiding those 50+ component types behind an opaque runtime OO polymorphic interface. Phobos does have the facilities of this, in the form of the InputRange, ForwardRange, etc., interfaces in std.range.interfaces. In my case, however, part of the chain uses another generic type (a kind of generalization of 2D arrays). But either way, the idea is simple: at the end of the UFCS chain, wrap it in a class object that inherits from a generic interface that encodes only the primitives of the 2D array concept, and the element type. The class object itself, of course, still must retain knowledge of the full-fledged type, but the trick is that if we insert this type erasure in the middle of the chain, then later components don't have to encode the type names of earlier components anymore. T I have some stupid questions: - What does everyone mean when they say 'symbol' here? I'm probably misunderstanding symbols gravely or it's something that DMD in particular handles in a strange way. - What type information are being kept because of UFCS chains? Doesn't that mechanism simply apply overload resolution then choose between the prefix and .method forms as appropriate, rewriting the terms? Then it's a problem of function invocation. I don't get what's happening here still. Does this tie to the Voldemort types problem? (=> are many of the functions in the chain returning custom types?) It doesn't make sense, especially if, from your indirection workaround, it looks like it would work around the same but without the bloat problem if we unlinked the chain into many intermediate temporary parts. So how is this a type information issue? Thanks!
Re: Request for a more powerful template specialization feature
On Friday, 14 July 2017 at 19:49:05 UTC, Andrei Alexandrescu wrote: On 7/14/17 2:19 PM, data pulverizer wrote: template Construct(R: Union{double, int}, W: Union{string, char, dchar}) template Construct(R, W) if ((is(R == double) || is(R == int)) && (is(W == string) || is(W == char) || is(W == dchar)) It would be good to get comments and suggestions before I write a DIP. An effective way of improving the state of affairs would be to create a PR that makes the constraint easier to read and write, e.g.: among!(R, double, int) && among!(W, string, char, dchar) In fact it's surprising it hasn't been proposed yet. Andrei But specializations are quite different from constraints, no? Constraints wouldn't help when the template name is overloaded and passes the constraint checks of several different template implementations; specializations narrow things down for overload resolution. Unless I'm misunderstanding the OP or everyone else in the thread somehow :/
Re: D easily overlooked?
On Friday, 14 July 2017 at 09:02:58 UTC, Stefan Koch wrote: On Friday, 14 July 2017 at 08:57:17 UTC, Wulfklaue wrote: https://blog.sourced.tech/post/language_migrations/ A recent article where github programming languages popularity and migration got analysed was very interesting but it showed one noticeable thing: [...] The beauty of D lies in it's holistic approach. The one unique feature to point out would be CTFE which is not to be found in other compiled langauges. constexpr does not even come close since it cannot return literals :0 There's Red: http://red-lang.org (to my understanding, you can execute arbitrary Red (*) code in macro context; which is basically CTFE+macros). (*) Right now it accepts Rebol code because of implementation limitations; the spec says Red code though and the developers says this is planned.
Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1
On Wednesday, 28 June 2017 at 12:34:59 UTC, Moritz Maxeiner wrote: On Wednesday, 28 June 2017 at 12:17:36 UTC, Enamex wrote: `out(return > 0, "message")`? Yes, see [1] It has the already used `typeof(return)` going for it, though. A big point against it IMO would be its moving further from `return`'s signal that a function scope is exited at that line (instead it could be a variable assignment which is meh (usage in a contract check is OK since we're already outside the function)). `out(someCond($), "message")`? Overloading symbols with context dependent meaning is one more step into obfuscation. True. So using either `out` or `return` or `$` or whatever to always refer to the return value of the function. Just something that's already relevant and used instead of `__result`. Well, `__result` is already implemented and usable, so I would argue it is thus relevant. It's not used in the wild yet though :T R foo(Args...)(Args args) { out(return > bar && ensured(return), "foo() fudged its return"); Contracts inside function bodies should not be allowed imho. [1] http://forum.dlang.org/post/oihbot$134s$1...@digitalmars.com I was going with the current 'Proposal' syntax in the DIP's document. There a more recent proposal here?
Re: DIP 1009--Improve Contract Usability--Preliminary Review Round 1
On Sunday, 25 June 2017 at 17:20:51 UTC, Timon Gehr wrote: On 25.06.2017 17:46, Petar Kirov [ZombineDev] wrote: On Sunday, 25 June 2017 at 12:10:02 UTC, Timon Gehr wrote: On 25.06.2017 13:37, Andrei Alexandrescu wrote: out(result){ assert(result > 0); } // exists out result => assert(result > 0) // more of the same out(result; result > 0) // better out result => result > 0 // not much worse out(result; result > 0, "worse enough") Also, what Guillaume said. Why do we need to name the result at all? Any conflicts with using `out(out > 0, "message")` or `out(return > 0, "message")`? Or even `out(someCond($), "message")`? So using either `out` or `return` or `$` or whatever to always refer to the return value of the function. Just something that's already relevant and used instead of `__result`. This could even be naturally extended to having an implicitly declared 'result' variable for functions (which could help in optimizations maybe? Something like always having NRVO possible) called `out` or `return`. R foo(Args...)(Args args) { out(return > bar && ensured(return), "foo() fudged its return"); // ... return = blah; // ... return.quux(var); static assert(is(typeof(return) == R)); // of course; this's old syntax }
C++ Metaclasses proposal
PDF: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0707r0.pdf Reddit: https://www.reddit.com/r/programming/comments/6js4uv/metaclasses_in_c/ I thought a bit on possible patterns in D to accomplish the same without string mixins. For example, defining the prototype `Foo_` then mixing in `mixin MyMetaclass!Foo_ Foo`. Got stuck trying to 'forward' (or copy the implementation of) functions in `Foo_` into `Foo` after modifying them, though. Besides trying to do it in D (please try still!), what do you think of the idea? In general and say versus a robust macro system with some level of access to CTFE? Or even just a good macro system (someone began discussing this on the reddit thread; talking about Racket macros).
Re: Idea: Reverse Type Inference
On Wednesday, 24 May 2017 at 15:02:05 UTC, Steven Schveighoffer wrote: In fact, you could simulate overloading of return values based on IFTI instantiation: void fooImpl(ref int retval, int x) { ... } void fooImpl(ref string retval, int x) { ... } T foo(T)(int x) { T t; fooImpl(t, x); return t; } int x = foo(1); string y = foo(2); -Steve https://dpaste.dzfl.pl/7d8351fe2f07 What am I doing wrong?
Re: Interesting paper on composing type definitions
On Monday, 6 March 2017 at 01:37:18 UTC, Andrei Alexandrescu wrote: On 3/4/17 10:36 PM, Andrei Alexandrescu wrote: https://pdfs.semanticscholar.org/5de7/591a853ec947f8de7dc70df0b2ecc38b8774.pdf -- Andrei An idea inspired by this paper would be a type Sum such that Sum!(A, B) stores both states of A and B and the joint API offered by the two. Would be a good exercise in applying introspection. Also, when there are clashing primitives, Sum might offer the option to make one of the types "dominant", eliminate the function from the joint interface, or disallow composition altogether. -- Andrei I haven't read the paper yet but doesn't that sound exactly opposite to what 'sum types' is usually used to mean? The value of the variable has to be either A or B. If it stores the status of both then it's basically a struct, right? Probably I'm misunderstanding your point on composition and 'joint API'.
Re: If Statement with Declaration
On Sunday, 6 November 2016 at 05:07:10 UTC, Andrei Alexandrescu wrote: The declaration with "if" seems to be a recent fashion. I've first seen it in Go and now C++17 took a shine to it - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html. A DIP would do good to cite that related work. It seems a low impact feature. Also, the Go/C++ syntaxes seem suboptimal to me because they are stuttering: if variable := fun(); variable != 42 { ... } or (C++): if (auto variable = fun(); variable != 42) { ... } Why does the word "variable" need to appear twice? It seems simpler to allow punctuation around existing syntax: // possible future D if ((auto variable = fun()) != 42) { ... } Defining a variable in an expression wouldn't be allowed everywhere (but might be contemplated later as an possibility, which is a nice thing about this syntax). Andrei I remember an old suggestion/DIP allowing 'with' statements to introduce/declare symbols/variables. Might be a cleaner extension to existing language: with(auto x = f()) if(foo(x)) {} else with(auto r = root(t)) if(leaf(r) || blah < bar) {}
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: So, consider a set of overloads: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} void f(T)(T t) {} I have a recurring problem where I need a fallback function like the bottom one, which should be used in lieu of a more precise match. This is obviously an ambiguous call, but this is a pattern that comes up an awful lot. How to do it in D? I've asked this before, and people say: void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} Consider that more overloads are being introduced by users spread out across many modules that define their own kind of T; this solution is no good. An easy workaround with a bit of boilerplate would be: void f(T)(T t) { static if(isSomething!T) { // special impl } else { fallback_f(t); } } void fallback_f(T)(T t) { ... }
Re: How about a special null template parameter?
On Friday, 19 August 2016 at 23:12:39 UTC, Engine Machine wrote: On Friday, 19 August 2016 at 22:20:09 UTC, Enamex wrote: On Friday, 19 August 2016 at 18:25:06 UTC, Engine Machine wrote: [...] Something like this: class Type(T: typeof(null)) { //< L1 (specialization) int x; } class Dog {} class Type(T) : Type!(typeof(null)) { //< L2 (`typeof(null)`) static if(is(T: Dog)) //< L3 (`is(MyType: IntendedType)` or `is(MyType == ExactType)`) int y; } What you're looking for is "specialization", on line "L1". Also some corrections on lines "L2" and "L3" How is this any different, besides adding meaningless complexity, to inheritence as it already is? Um, not sure what you mean. This isn't suggesting adding anything; it's already legal/compiles.
Re: How about a special null template parameter?
On Friday, 19 August 2016 at 18:25:06 UTC, Engine Machine wrote: So we can create types relationships easier: class Type(T) : Type!null { int x; static if (T is Dog) int y; } Type == Type!null (!null implicit, only if defined in the above way. Essentially an alias is created for us automatically) Type(T) : Type!nullinherits only if T is not null(or a type that inherits from itself, which would then be valid). Type!Dog inherits from Type/Type!null. Type!T inherits from Type/Type!null as long as T != null. Members in base(null) are not re-included in derived(e.g., int x; isn't include in Type!Dog because it's already there from base). Something like this: class Type(T: typeof(null)) { //< L1 (specialization) int x; } class Dog {} class Type(T) : Type!(typeof(null)) { //< L2 (`typeof(null)`) static if(is(T: Dog)) //< L3 (`is(MyType: IntendedType)` or `is(MyType == ExactType)`) int y; } What you're looking for is "specialization", on line "L1". Also some corrections on lines "L2" and "L3"
Re: Fact checking for my talk
On Sunday, 14 August 2016 at 18:57:14 UTC, ZombineDev wrote: Ok, maybe it's a matter of taste and opinion, but I consider them to be bad design (idea-wise, not implementation-wise) because they're sort of the opposite of DbI and compile-time duck-typing. Maybe they fit nicely in Rust's world but they're definitely something I would want NOT to use. Concepts/traits are useless when you have DbI, because you can implement them in a library if you need dynamic dispatch (e.g. std.range.InputRangeObject, std.experimental.allocator.allocatorObject, std.typecons.wrap, etc.). Can you demonstrate it through the example you linked to? And sorry, what's DbI again? :D
Re: Fact checking for my talk
On Sunday, 14 August 2016 at 18:05:12 UTC, ZombineDev wrote: [...] OTOH, they're used in more places in their standard library, than mixins are used in Phobos, because of the lack of variadic templates, because in Rust you can't generalize over mutability, like you can in D with `inout` and also because of the stupidly designed trait system (e.g. see [9]). I'm confused by your example. How exactly is Rust's trait system 'stupidly designed'? [...] From my understanding of Rust macros, they're kind of like the AliasSeq algorithms in std.meta (because they're declarative), but instead of operating on sequences (e.g. template arguments lists) they operate on Rust's AST (e.g. statements and expressions). The AliasSeq algorithms are defined recursively for obvious reasons, but they rely on branching and a lot of obviously not declarative code in their definition. :? [...] [9]: https://github.com/rust-lang/rust/blob/master/src/libcore/slice.rs#L804
Re: DIP1000: Scoped Pointers (Discussion)
On Wednesday, 10 August 2016 at 20:36:38 UTC, Dicebot wrote: http://forum.dlang.org/post/pqsiqmkxenrwxoruz...@forum.dlang.org - Please submit pull requests to adjust the markdown document if you want to propose any improvements (mentioning @WalterBright and @andralex for confirmation). Personally I wouldn't recommend directly submitting pull requests for improvement suggestions. Keep those in the forum/git discussions (maybe open an RFC issue on GitHub?) with the pull requests only after enough people have commented on the suggestions. (I just don't want to have to follow several PR threads for every single improvement suggestion to every DIP in its final comment period.)
Re: This fellow is writing an operating system in D live
On Wednesday, 10 August 2016 at 14:03:22 UTC, Wild wrote: Thanks for posting a link to my lastest VOD :) Here is all of my past streams: https://www.livecoding.tv/wild/playlists/lpVPZ-powernex-os-development/ You should be able to watch the whole development of PowerNex from those videos. If anybody wants to read the code it is located here: https://github.com/Vild/PowerNex Are they available on Youtube or something similar? I can't find a way on livecoding.tv to decrease the resolution and it's putting a lot of strain on my connection. If you're narrating it I could probably follow along at 480p or something. And the code is apparently open source so I can see that.
Re: [DIP] In-place struct initialization
On Wednesday, 3 August 2016 at 20:30:07 UTC, deadalnix wrote: On Sunday, 31 July 2016 at 14:38:33 UTC, Lodovico Giaretta wrote: I support this idea of extending curly-brace initializers. It would be very useful and less ambiguous than parenthesized initializers. Curly braces are already extremely overloaded. They can start a block statement, a delegate literal, a struct literal and I'm sure I forgot something. Well, this extended case would fall under "struct literal". And personally I'm against starting function literals with just a brace (always use `(){...}` instead).
Re: [DIP] In-place struct initialization
On Sunday, 31 July 2016 at 07:10:46 UTC, cym13 wrote: The proposed change is litteraly just equivalent to the already existing struct initialization, just made usable: struct S { int a; int b; } auto s = S(b:42); // equivalent to S s = { b:42 }; Having the possibility to initialize structs without tying them to a variable proves useful when combined with functions that take this struct but those functions aren't directly impacted by the change. I suggest extending the existing `S s = {field: value}` syntax to allow specifying the type itself next to the field list and make it usable generally everywhere. So, instead: takeThing(Thing{ field: val, num: 43 }); It shouldn't clash with anything else, I think.
Re: What is the current progress on "Safety and Memory Management"?
On Saturday, 16 July 2016 at 21:45:17 UTC, maik klein wrote: I was actually thinking of contributing something bigger as part of my bachelor thesis. (Not sure if I am allowed to do that) What I wanted to do is to translate a big part of Rust's std to D. Stuff like Rc, Arc, Box, Optional + all the necessary tools for ownership semantics. Also implement data structures that work with ownership semantics (Rc, Box, Arc etc) like Vec, HashMap. Add ownership semantics to phobos, for example a lot of stuff in phobos can't be used with non copyable types. (A lot of things rely on copying) I have already implemented a small part of Rusts std but it felt like that I was the only one interested in this. (I am aware of RefCounted, Unique, Nullable etc) I would definitely put some spare time into researching this a bit more if there is some interest. That sounds very interesting. You mean to encode Rust-like ownership semantics at runtime for a complete alternative stdlib in D?
Re: Allocator troubles
On Friday, 15 July 2016 at 18:44:26 UTC, Luís Marques wrote: I'm not having success trying to use the allocator API. void main() { [...] enforce(alloc.make!int !is null); enforce(alloc.deallocateAll()); enforce(alloc.make!int !is null); writeln("OK 1"); [...] } I get a segmentation fault before "OK 1", actually. I'd have expected all enforce checks to pass in this snip, but they don't after the first `deallocateAll()` so I'm misunderstanding the semantics big time.
Go's march to low-latency GC
https://news.ycombinator.com/item?id=12042198 ^ reposting a link in the right place.
Re: C++17 is feature complete
Some updates: https://www.reddit.com/r/cpp/comments/4rj7us/trip_report_c_standards_meeting_in_oulu_june_2016/ Especially interesting are the mentions of 'accepted' features/proposals for 'C++20', including: - `operator.` (opDispatch) which /might/ even make it into C++17 given push by some international body; also includes some facets of `alias this` as it's hoped to be a core part of some of the reflection proposals [1] - designated initializers (from C) (D's static initializers but tied to struct names and usable anywhere `MyStruct{ field2: 0, field1: 'a' }`; and some requiring 'further thought' like: - discriminated unions (even full-blown pattern matching); [2] - 'overload sets as function arguments' (basically the delegate pattern in D for passing a lazily determined member function pointer (or an untyped closure in general)); - contracts ('expects = in' and 'ensures = out()' but they take one big boolean expression; a bit more complicated than in D, but they're adding them in, not taking them out) [3] - 'parameter packs outside templates' which could go several ways from being basically native tuples with dedicated syntax, to almost (? not sure about differences in the proposal's specification vs behavior in D) the same thing as alias tuples in D now. [4] I tried to focus on stuff already in D and stuff people are asking to add to D and the differences between the languages in them. I'll stop if it's deemed too off-topic :/ [1] http://wg21.link/p0252 http://wg21.link/p0352 http://wg21.link/p0060 [2] http://wg21.link/p0095r1 [3] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4415.pdf [4] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0341r0.html
Re: Logical location of template instantiations
On Friday, 1 July 2016 at 12:08:49 UTC, Lodovico Giaretta wrote: On Friday, 1 July 2016 at 11:45:12 UTC, Robert burner Schadek wrote: IMO, this is one of these places where theory meets practice. Do what works, write a comment explaining the problem, and move on ;-) Yes, well, I successfully bypassed my issues with this thing, but I wanted to share my thoughts about the need to express this kind of thing (i.e. to give a template instantiation the privileges of the instantiating module), and to know if someone else has some opinion on this matter. Yeah. I don't know if it's _needed_ by enough people or by the language, but a way to force templates to be hijacked while being instantiated (not at point of definition but at instantiation; though I imagine this might prove troublesome for reflection and template identity, somehow) if we want to. The default hygienic behavior is great, but bypassing it when needed is not.
Re: C++17 is feature complete
On Tuesday, 28 June 2016 at 19:27:36 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 28 June 2016 at 18:50:25 UTC, Enamex wrote: Also, C++17 is 'getting' Modules and Concepts Lite later in tech specs... that don't even have working drafts according to this [https://isocpp.org/std/status] (but have experimental implementations in Clang and VC++, at least). Modules is not part of C++17, it is on a separate track. Concepts are also not part of C++17. Maybe it would be a good idea to not complain so much about languages you guys don't know much about. I suggest focusing on making D better instead. That's what I said. They're not in the C++17 spec but we won't be waiting for C++Next for them, hopefully. And I complained about nothing; and know little about _any_ language; still so much to learn.
Re: C++17 is feature complete
On Monday, 27 June 2016 at 19:47:14 UTC, Ola Fosheim Grøstad wrote: On Monday, 27 June 2016 at 19:39:20 UTC, luminousone wrote: OpenCL is for micro threading, not simd. What is your point? Clang++ vector extensions use OpenCL semantics, so you need to look up the OpenCL spec to figure out what it supports. It is not well-documented in the Clang documentation. Are you trolling me? Please, no need to. Also, C++17 is 'getting' Modules and Concepts Lite later in tech specs... that don't even have working drafts according to this [https://isocpp.org/std/status] (but have experimental implementations in Clang and VC++, at least).
C++17 is feature complete
https://www.reddit.com/r/cpp/comments/4pmlpz/what_the_iso_c_committee_added_to_the_c17_working/ Added stuff like: - a very limited destructuring syntax (structured bindings) (use case is for tuples; but likely to use a new reserved function name for general struct destructuring (like 'get<>()' or something); - template arguments that accept constant values of any type whatsoever 'template'; - 'constexpr if'; - specified order of evaluation for function calls and any syntax with arguments (including built-in operators on primitive types).
Re: [OT] Swift removing minor features to piss me off
On Friday, 29 April 2016 at 12:06:40 UTC, Nick Treleaven wrote: A complication with the delegate way is break/continue/return in the statement block, but I suppose it already works for opApply. I'm curious: what does this actually lower to when compiling?
Re: [dlang.org] new forum design
On Monday, 18 January 2016 at 10:20:13 UTC, Vladimir Panteleev wrote: On Monday, 18 January 2016 at 10:20:13 UTC, Vladimir Panteleev wrote: - Disabled text-size-adjust (font size inflation on mobile browsers) - Removed font size changing depending on window width - Tweaked forum and group index background colors - Various fixes, including: - "Current thread" and other labels not fitting in the search dropdown - Height calculations for the split view modes - Restrict breadcrumbs to one line 2. Page width, especially in horizontal-split mode As mentioned above, the navigation has been made narrower and the content wider, and the horizontal-split view mode can fit 73 characters at its widest. Hopefully this should be sufficient. If not I posted some ideas here: https://github.com/CyberShadow/DFeed/pull/51#issuecomment-172468784 As I posted in the previous thread, it would be: - GOOD if you are as specific as possible in what can be improved. I'm not sure if this's the same for everyone but the forum on mobile is unusable for me now. The thread titles are so squished next to the Last Post column that barely 2 words, max, show from the title. I forgot (yes) how it'd been in the old design but maybe have the 'columns' aligned horizontally in the new design on narrow screens?
Re: Expression-bodied functions
On Friday, 1 January 2016 at 00:27:49 UTC, ZombineDev wrote: By the way, a very similar language feature was approved and implemented for the upcomming DMD 2.070 release. It allows you to use a short syntax for function templates: alias add = (a, b) => a + b; // Shorthand for: // auto add(T1, T2)(T1 a, T2 b) { return a + b; } IFTI makes it look like a regular function call: writeln(add(3, 4.5)); It works for free functions, but I'm not sure if it would also work for member-functions (methods). https://issues.dlang.org/show_bug.cgi?id=12421 IMHO, anything like that is just a tangential 'fix' to the fact that D's design rests on commands like 'return' to leave scope and return values. Something like auto add(auto x, auto y) { x + y } would be much more wholesome IMO. (The 'funcName(auto arg)' syntax is just a convenience suggestions; the important part is '{ x + y }'). That said, it does fix something that 'alias' should've been able to do from the beginning. I'm not sure what else but I think there other places where alias needs '= I!(stuff)' identity template to accept the 'stuff'.
Re: Efficient binary search using two-way comparisons
On Saturday, 28 November 2015 at 20:04:11 UTC, Andrei Alexandrescu wrote: While reading Okasaki's bool on persistent data structures, I found (page 14) a reference to a nice idea applicable to binary search using D's two-way "less than" comparisons. https://issues.dlang.org/show_bug.cgi?id=15385 Any takers? Andrei Looks really simple. I could try? Though I'll probably come asking here about contribution procedures and stuff (especially that I can't, not possibly, compile Phobos or anything close to it with tests and such).
Re: Type helpers instead of UFCS
On Saturday, 12 September 2015 at 20:40:35 UTC, Adam D. Ruppe wrote: On Saturday, 12 September 2015 at 20:37:37 UTC, BBasile wrote: - code completion in IDE. It'will never work. Why not? I haven't actually tried it, but it seems like a pretty easy problem, except perhaps with complex templates. - noobs, code is unreadable. meh There's the bigger problem that extending a type via UFCS is 'open'; there can always be more functions where the first parameter accepts that type you're using. With a dedicated syntax, specific functions/groups-of-functions could be easily recognized as extensions of a type and could even be made to be recognized by templates (when the type is passed as type parameter or alias param) even though they're not in its definition. Kinda like type classes. But, anyway...
Re: Rust style memory management
On Saturday, 12 September 2015 at 20:17:04 UTC, Freddy wrote: So I saw this video: https://air.mozilla.org/guaranteeing-memory-safety-in-rust/ and was amazed. Is there any way we can implement this in D? What language extensions would be required? My idea on implement this would be to add 3 new pointer (and array) types : [owned,shared immutable,borrow mutable] and depend on casting raw pointers to the new types. Thoughts? There's been: http://wiki.dlang.org/User:Schuetzm/scope1 http://wiki.dlang.org/User:Schuetzm/scope2 http://wiki.dlang.org/User:Schuetzm/scope3 And at least one earlier proposal that's been accepted already. It requires the '@safe' annotation to work and is quite limited to anything more general. Although the basic opinion was that it covered a large proportion of the inherently unsafe cases that Rust aims to cover compared to C++ or unsafe D (but Rust's approach is more 'safe by proof' vs D's 'safe by prohibiting known unsafe').
Re: A collection of DIPs
On Monday, 7 September 2015 at 14:44:05 UTC, nx wrote: https://github.com/NightmareX1337/DX Don't kill me, I'm just trying to help... You can report issues and create pull requests :) Destroy! - Your point against undisciplined UFCS: Completely agree. I'm writing a 'DIP' that I'm probably never gonna submit to add "extension interfaces" (my syntax ATM is leaning towards "alias class/interface") that add callable-with-method-syntax free functions in a way that they're treated as native parts of the supporting type (one case: when passing the type name into a foreign template they're picked up as if they were methods instead of being out-of-scope). In a (very big) way, they're stolen whole-sale and are being adopted to fit from Rust's traits. - Null-coalescing operator: No. Pattern matching and a `std.typecons.Option(T)` would do better IMHO and are more general. - I've stayed away from UDAs but your points make me finally want to stay away a bit more. (except for a small side project but, well, necessities) - Managed~unManaged pointers: needlessly complicated. Just provide a non-GC 'new'. What wouldn't that solve as well as your `type*` vs `type^` pointers? (btw, `^` wouldn't conflict with the xor-operator as I understand it. `!` is already used both as a unary prefix and binary infix operator). - Not sure about `alias this`/`opCast`. I just use `opDispatch` whenever I need something more complicated than alias this (not much at all). - I VERY strongly believe in the inherent superiority of kebab-case compared to CamelCase and snake_case. KEBAB-CASE FOR PRESIDENT! - I hated D's module system at first. I still hate that I have to create separate files just to have a small internal namespace-separation. But I like being able to just go find something in a file in a project based on its compile-time path (granted, good design should enforce this but...). I dunno; on a fence about it. - `__traits(callerName) & __traits(callerChain) & __traits(callerPath)`: I want a `__traits(instanceContext, symbol)` that returns an alias allowing me to access all compile-time info on surrounding symbols to the passed one (which are local to the /instance/ so include imported names and local types and such). That would solve SO MANY THINGS with template adventures. Not sure on what it'd make worse, though. - Partial lock for arrays: Sounds complicated for D's current analysis abilities. But sounds cool. - pragma(inline): ABSOLUTELY. The idea that `pragma(inline)` verbatim tells the compiler precisely nothing hurts my OCD so much. - Old attributes got a space in the keyword list. There were proposals to shift them all to `@` syntax but it stalled early on. - Runtime reflection: Hmmm... Runtime UDA's sound suspiciously like a type-state system. Complicated, interesting. - Templates are obvious enough as they are IMHO. - Friend classes: Um, maybe make a separate MyTypeImpl struct/class that takes a MyType instance and initializes itself with a pointer and through it you can access all the private stuff you want? (MyTypeImpl would be in the same module as MyType, of course.) Good stuff ;)
Re: "else if" for template constraints
On Friday, 4 September 2015 at 15:52:08 UTC, Enamex wrote: The biggest problem, I think, is that a template can has multiple 'predicates' to agree to be instantiated, but only some of them can mutually exclusive (the specialization syntax produces mutually exclusive ones, the if-constraints don't). [...] template Bar(T) { static if( is(T == int) || is(T == string) || ... ) { //stuff } else static if( stuff ) { // other stuff } else { template return; // I know my T took whatever your type was but I actually don't match, please exclude me from your list for this instance... } } [...] On second thought, it wouldn't help as much as I'd thought with overloading problems. What we want is a 'which template has more '&&'ed expressions in its constraint?' which sounds pretty awful. I have no idea how this could work :/ Especially given that D's constraints are way more open than, say, Haskell's, in their checking; though ironically not their declaration/implementation (D is open because it checks for structural conformance of a struct instead of nominative & structural; but it's more restricted because it easily only checks for structure of the type as declared, with no way to attach recognized-to-the-constraint ad-hoc interfaces to a type like Haskell's with type-classes).
Re: "else if" for template constraints
On Monday, 17 August 2015 at 13:18:43 UTC, Steven Schveighoffer wrote: I was just looking at fixing this bug:https://issues.dlang.org/show_bug.cgi?id=14925 [...] How often are you writing overloaded templates, and you want to say "if it doesn't match anything else, do this"? I'd love to see some form of syntax that brings template constraints in line with tried-and-true if/else statements. One way to do this is to lexically order the if constraints, and if any of them start with "else", then they are mutually exclusive with the immediately preceding constraint for the same symbol (just like normal else). So for example, you'd have: void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff) if(isDynamicArray!Range && is(Unqual!(ElementEncodingType!Range) == T) && !is(T == const T) && !is(T == immutable T)) { /* version 1 that tries to write into the array directly */ } void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff) else if(is(typeof(replace(array, from, to, stuff { /* version 2, which simply forwards to replace */ } looks much better IMO. Can we do something like this? I'm not a compiler guru, so I defer to you experts out there. -Steve The biggest problem, I think, is that a template can has multiple 'predicates' to agree to be instantiated, but only some of them can mutually exclusive (the specialization syntax produces mutually exclusive ones, the if-constraints don't). Thinking about it from this angle, I believe the most flexible and sensible solution would be to support a sort of "early return" from a template. Thus: template Bar(T) { static if( is(T == int) || is(T == string) || ... ) { //stuff } else static if( stuff ) { // other stuff } else { template return; // I know my T took whatever your type was but I actually don't match, please exclude me from your list for this instance... } } template Bar(T) { static if( is(T == float) || is(T == int[]) || ... ) { // Bar!float/Bar!(int[]) stuff } else static if( OTHER_OTHER_stuff ) { // other other stuff } else { template return; // I know my T took whatever your type was but I actually don't match, please exclude me from your list for this instance... } }
Re: Interesting user mistake
On Thursday, 3 September 2015 at 16:46:30 UTC, Andrei Alexandrescu wrote: we should disallow during tokenization the sequence "=", "+", whitespace. Surely it's not a formatting anyone would aim for, but instead a misspelling of +=. Andrei Wasn't the original design for these operators in whichever language started them actually the swapped form? In any case, I'd personally choose to warn against any operator sequence without separating whitespaces if the sequence isn't in fact one operator (like "=!" (non-warn: "= !") vs "!=", and "=&", and a lot others, given operator overloading). Looking again, it's mostly the fault of OpAssign operators, isn't it?
Re: Review needed for the EnumSet template
On Thursday, 3 September 2015 at 00:12:06 UTC, BBasile wrote: Memebers should be notified. https://github.com/D-Programming-Language/phobos/pull/3623 It's not a big stuff but it's neither a small addition. The thing is there. Slightly tangential question: in your "superset" enumset package, what's the use of 'static' annotation on a free function (was the first function I saw in the file, I believe)?
Re: Dazz new description for D
On Monday, 31 August 2015 at 07:57:46 UTC, wobbles wrote: I'd remove the "joy to write and easy to maintain" bit. That's personal opinion. Could use the "Systems scripting with native performance" as a tag line though. It's nice! My, slightly altered, version: D is a multiparadigm systems programming language with deep static introspection that lets you choose exactly what to pay for. Systems scripting. Native performance. I'm somewhat boring in public but anyway, I'm voting for this ;)
Dazz new description for D
Some posters on reddit remarked that D's sales pitch on the website is unnecessarily long and unindicative. I'm only making a suggestion; suggest others or comment on this one: D is a multiparadigm systems programming language with excellent static introspection that lets you choose exactly what to pay for. D is a joy to write and easy to maintain: it's systems scripting with native performance. Turned out too long :/
Re: Ruby 3.0 to have immutable strings by default / C++ heading towards "generic all the time".
On Thursday, 20 August 2015 at 22:07:10 UTC, John Carter wrote: https://twitter.com/yukihiro_matz/status/634386185507311616 Pity that concepts looks to be a very painful syntax for expressing what D does so clearly. One big difference is that C++1z concepts are supposed to allow looking for external functions, not only methods. That would require some kind of principled hijacking of templates in Dlang (or else the constraint template would keep looking for the functions, called by ufcs, either inside the type of in the templates declaration position). I haven't managed to work that out yet except by using mixins :/
Re: Rant after trying Rust a bit
On Friday, 24 July 2015 at 21:44:42 UTC, Tofu Ninja wrote: But the part that I don't think makes sense for auto a = {return 4;}; to type "a" to a function pointer. I would expect {return 4;} to be treated as a function(not a function pointer). With it being treated as a function, I would expect it to be called with optional parens and type "a" to an int. I would expect auto a = &{return 4;}; to type "a" to a function pointer, which makes much more sense to me. But that's not how function literals work right now. Treating {return 4;} as a function(not a function pointer) makes a lot more sense and allows alias a = {return 4;}; to work as well, which is simply a function declaration. Not crazy about your last point, TBH. Personally I really dislike function literals being _just_ `{ ... }` and as a matter of principle only write `(){...}` when I need one. `{}` to me can only mean blocks that are part of the current scope, but they're sometimes that and sometimes lambdas, depending on whether they had any `return`s and are in a place to be assigned a name or immediately called :/ A related thing is having _some way_ to quickly return a value from inside an invoked function literal without `return`. Somme stuff can't be done in a one-liner and need _two_(ish) lines and have to write, say, `{ Type myval, myres; res_by_ref(myval, myres); return myres; }()` instead of `{ Type myval, myres; res_by_ref(myval, myres); myres }` (expression-oriented) or `(){ ...; => myres; }()`(hypothetically). Point is, writing `return` in the middle of a function and having it return _only_ from a lambda breaks the flow, I believe, same as in C++.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 14:21:13 UTC, jmh530 wrote: On Wednesday, 5 August 2015 at 06:03:14 UTC, rsw0x wrote: This thread is really long so I didn't read all the posts. Sorry if this has been mentioned. Don't worry, I don't recall anybody talking about it. Nevertheless, plugins aren't unique to Rust: GCC and Clang allow plugins. Nevertheless, I think that the Rust C++ plugin you posted was cool. Reminds me of Rcpp. Oh, it _is_ talked about a lot. Just normally called 'syntax extensions' (the most used aspect of the plugin system), so it _is_ used. Though because it relies on compiler internals everything released as a plugin is only usable on Nightly.
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 09:37:10 UTC, Jonathan M Davis wrote: On Friday, 31 July 2015 at 04:47:20 UTC, Enamex wrote: Right now docs say that `delete` is getting deprecated but using it on DMD .067.1 gives no warnings. There are no warnings because it hasn't actually been deprecated yet. [...] - Jonathan M Davis GC and memory management in general are inadequately documented. There're doc-pages and answers on SO and discussions on the forum about stuff that (coming from C++) should be so basic, like how to allocate an instance of a struct on the heap (GC'ed or otherwise) or how to allocate a class on non-managed heap (still don't get how `Unique!` works; does it even register with the GC? How to deep-copy/not-move its contents into another variable?), or on the stack, for that matter (there's `scoped!` but docs again are confusing. It's somehow stack-allocated but can't be copied?). Eventually deprecating it while leaving it now without any warnings (though the docs warn; offer no replacement) seems like it'd be more trouble than it's worth down the line, since it's not a feature addition or even full deprecation but -AFAIU- a replacement of semantics for identical syntax.
Re: Last call for AliasSeq
On Friday, 24 July 2015 at 08:51:04 UTC, Marc Schütz wrote: Martin has just merged the rename of `TypeTuple` to `AliasSeq` into the stable branch, which will be released soon. If anyone wants to change the name again, please open a PR immediately, this is the last chance. Slightly non-sequitur question: Does this whole thing mean that tuple literals are never going to be implemented? The DIP I found mentioned most often is from 2013...
Re: [OT] Rust discussion about uniqueness/mutability
On Wednesday, 14 May 2014 at 14:47:24 UTC, David Nadlinger wrote: It's not directly related to the discussion we are currently having, and to most of us regulars their debate will appear to be somewhat trivial, as the distinction is so explicit in D and we don't have automatic borrowing. But maybe a look at a similar situation (but with different terminology) will lead to some nice ideas, so I figured I'd post this here. Cheers, David How is it explicit in D? Something to do with shared/const? But the default-owned/borrow vs explicit unique-borrow (but `&mut`) in Rust /are/ explicit, while in D anything passed to a function is by default either a completely independent copy or a shallow copy of a reference that needs mutex'ing or a const-qualified view to be safe. Asking, not arguing, 'cause I'm new to D and a bit confused. I hope replying to old topics is okay...
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 03:41:35 UTC, Enamex wrote: [...] Mostly my experience, so far. If I have to choose the 'most important' things that Rust has that I'd *definitely* want in D, I'd pick (in order): * A really nicely integrated package manager like Cargo that goes seamlessly hand-in-hand with DMD. * DDMD [...] Ouch. Actually forgot second most important point (right before DDMD): a ~99.99% @nogc Phobos and better documentation for GC stuff. Right now docs say that `delete` is getting deprecated but using it on DMD .067.1 gives no warnings.
Re: Rant after trying Rust a bit
On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote: Long rant ahead - a bit dipsy.. TL;DR: Rust has momentum, manpower and tooling. Tooling matters. Safe defaults. Ergonomics like expressions and deconstructing rocks. [...] But again... After playing a bit with Rust, I feel it lacks a lot in expressive power. D has templates, template mixins, alias this, string mixins, opDispatch etc. In my little time with Rust, I've seen several pages of generic constrains that is expressible in a couple of lines with D. I've seen copy/pasted code that just isn't necessary when you code in D. Anyways - my little ramblings after trying the Rust programming language while I haven't used D in a long, long while (But I'm still here now, as I'm not sure Rust is able to express everything that is possible with D). Looking forward to following D again :) Mostly my experience, so far. If I have to choose the 'most important' things that Rust has that I'd *definitely* want in D, I'd pick (in order): * A really nicely integrated package manager like Cargo that goes seamlessly hand-in-hand with DMD. * DDMD * An attribute or something that makes it explicit to the compiler that this type is a 'one time use' deal, and /exactly/ one-time-use (or, to be practical, zero-or-one times). Copying instances of objects of that type is done by `.dup`. (Like a non-Copy type in Rust currently.) * Sum Data Types (`enum`s in Rust and `data D = VarA | VarB` in Haskell). As well as: * Pattern matching. `Algebraic!` is okay but pattern-matching that goes with it isn't PM. But maybe that's for D 3.0 in 2030 or maybe another language... (I just want SML with at least D's speed T_T. I already got something /very roughly/ akin to ML's functors from D's template and mixin magic...)
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 19:21:10 UTC, Tobias Müller wrote: trait A {...} trait B {...} trait C : A,B { } impl C for T { } fn myFunction(c: C) {...} Tobi Has to be: fn my_function(c: &C) { ... } actually, because trait objects can only be passed by reference/borrowed-pointer.
Re: Rant after trying Rust a bit
On Sunday, 26 July 2015 at 15:21:32 UTC, Timon Gehr wrote: On 07/25/2015 02:18 PM, Andrei Alexandrescu wrote: On 7/23/15 4:47 PM, Ziad Hatahet via Digitalmars-d wrote: On the other hand, Rust does not require parenthesis around if conditions: Yet it requires braces around the arms. Rust taketh away, Rust requireth back :o). -- Andrei It's arguably a better trade-off. Yeah. Instead of sometimes requiring just parentheses and sometimes them and braces. It's also less error-inducing. I rather like it though it's not exactly a functionality thing.
Re: Last call for AliasSeq
On Friday, 24 July 2015 at 10:35:35 UTC, Tofu Ninja wrote: On Friday, 24 July 2015 at 08:51:04 UTC, Marc Schütz wrote: Martin has just merged the rename of `TypeTuple` to `AliasSeq` into the stable branch, which will be released soon. If anyone wants to change the name again, please open a PR immediately, this is the last chance. Here are the final results of the poll if any one cares... AliasTuple 3.08333 AliasList 2.85 Aliases 2.71667 AliasSeq2.55 Why is the poll at odds with the supposed-to-be-final decision?
Re: Rant after trying Rust a bit
On Saturday, 25 July 2015 at 09:14:04 UTC, Jonathan M Davis wrote: . . . auto foo(alias pred, R)(R r) if(testPred!pred && isInputRange!R && !isForwardRange!R) {} auto foo(alias pred, R)(R r) if(testPred!pred && isForwardRange!R) {} and be turning it into something like template foo(alias pred) if(testPred!pred) { auto foo(R)(R r) if(isInputRange!R && !isForwardRange!R) {} auto foo(R)(R r) if(isForwardRange!R) {} } . . . - Jonathan M Davis The example(s) is confusing me. `foo!(first)(second);` isn't really an alternative to `foo(first, second);`. Am I misreading something?
Re: Rant after trying Rust a bit
On Thursday, 23 July 2015 at 15:03:56 UTC, Dicebot wrote: At the same time one HUGE deal breaker with rust traits that rarely gets mentioned is the fact that they are both constraints and interfaces at the same time: ... It kills all the necessity for hacks like RangeObject and is quite a salvation once you get to defining dynamic shared libraries with stable ABI. This is probably my most loved feature of Rust. Sorry, I don't quite get this. How is the most loved feature of Rust (that interfaces are also constraints for generics), a *deal breaker*?