Re: [OT] Music to Program Compilers To
On Friday, 29 July 2016 at 22:44:04 UTC, Walter Bright wrote: http://70sdisconights.com/ Yes, I listen to it while I work. For a somewhat more...traditional genre: http://musopen.org/radio
Re: Overflows in Phobos
On Wednesday, 27 July 2016 at 07:59:54 UTC, Walter Bright wrote: "The expression assert(0) is a special case; it signifies code that should be unreachable. If it is reached at runtime, either AssertError is thrown or execution is terminated in an implementation-defined manner. Any code after the assert(0) is considered unreachable." Let me take a stab at it: The expression assert(0) is a special case; it signifies that the code which follows it (in its scope of execution) should be unreachable. If execution reaches an assert(0) expression at runtime, either AssertError is thrown, or execution is terminated in an implementation-defined manner.
Re: The Sparrow language
On Wednesday, 6 April 2016 at 20:48:20 UTC, Lucian Radu Teodorescu wrote: Compared to CTFE, in Sparrow you can run at compile-time *any* algorithm you like. No restrictions apply. Not only you can do whatever your run-time code can do, but can also call external programs at compile-time. Imagine that you are calling the D compiler from inside the Sparrow compiler to compile some D code that you encounter. Interesting. I guess that's why you'd have annotations on variables that are set at compile time; without those annotations, there would be no way to tell when the value is calculated, and with non-pure functions, that becomes important. In a way, requiring annotations is almost more elegant than requiring functional purity...
Re: The Sparrow language
On Wednesday, 6 April 2016 at 18:25:11 UTC, BLM768 wrote: Aside from the explicit annotations, I don't see how their solution is more flexible than D's CTFE, but I might be missing something. Never mind. Just saw their language embedding example. Neat!
Re: The Sparrow language
On Wednesday, 6 April 2016 at 13:15:48 UTC, Andrei Alexandrescu wrote: On the plus side Sparrow has a smoother integration of compile-time vs. run-time computation, which makes it a bit easier to transition from one to another. Aside from the explicit annotations, I don't see how their solution is more flexible than D's CTFE, but I might be missing something. What I think could be really interesting is a unification of functions and templates. Template argument inference aside, a template is basically just a memoized pure function that can take types as arguments and/or return them. It would be interesting to have a language that uses CTFE as its only "template" mechanism.
Re: Could we reserve void[T] for builtin set of T ?
On Thursday, 31 March 2016 at 20:51:53 UTC, Jack Stouffer wrote: Wouldn't just be better to use a std.allocator backed set container instead over special casing the AA syntax like this? Syntactically, that makes more sense. Or there's always ubyte[0][T].
Re: Concatenative Programming Languages
On Wednesday, 30 March 2016 at 22:20:02 UTC, John Colvin wrote: import std.functional : pipe; alias allThree = pipe!(foo, bar, baz); :) Interesting, but I'd call that a concatenative sub-language at most. ;) There's certainly some conceptual overlap between concatenative languages and D under certain conditions, but there's not much syntactic overlap.
Re: Concatenative Programming Languages
On Wednesday, 30 March 2016 at 20:53:02 UTC, Shammah Chancellor wrote: I just stumbled on this wikipedia article: https://en.wikipedia.org/wiki/Concatenative_programming_language Seems like D falls under that category? -S. Not really. UFCS allows the syntax "x.foo.bar.baz", which is similar to a concatenative syntax, but the existence of "x" in the expression means it's not purely concatenative. In a purely concatenative language, "foo bar baz" would produce a function that pipelines those three functions. "foo.bar.baz" in D would produce a compiler error.
Re: Jai - interesting programming language
On Saturday, 19 March 2016 at 08:38:20 UTC, Basile B. wrote: Otherwise there's something that's pretty in the syntax: Very much so. My own "toy language" project uses (well, _will_ use once I have more than 5% of a parser) a similar syntax, so it could just be my own biases talking, but I like it. However later in the function declaration: "sum := (x: float, y: float, z: float) -> float { return x + y + z; };" I would expect the same system as for variables: "sum : float = (x: float, y: float, z: float) { return x + y + z; };" or return type inference: "sum := (x: float, y: float, z: float) { return x + y + z; };" As far as the second example goes, sum is a function returning float, not a float variable. I could be wrong, but it appears to me that using variable-like syntax would make the grammar (or at least its semantics) less context-free. Plus the () -> type {} syntax works nicely for lambdas. I'm sure the type-inference option could be supported, though. The language has some very interesting ideas. I probably wouldn't use it for general-purpose programming, though. I like my OOP, at least when it fits the problem at hand.
Re: What are you planning for 2016?
On Tuesday, 5 January 2016 at 12:27:12 UTC, Ola Fosheim Grøstad wrote: I wonder what kind of programming people plan or _hope_ to use D for in 2016? 8. or something else? The toy language bug has bitten me, too. I'm going for maximum modularity in the compiler to make it easy to hook in fancy tools. What other languages do you think you will use or toy with in 2016 and for what purpose? Probably a lot of C++ for my computer science classes. What would it take for you to use D instead, or what changes would be needed for you to move from language X to D? Some very forward-thinking professors. ;)
Re: DMD now does Dwarf style exception handling!
On Sunday, 3 January 2016 at 01:51:35 UTC, Jonathan M Davis wrote: So, we have ELF binaries and DWARF exceptions. Are we going to get something related to orcs or goblins next? ;) - Jonathan M Davis I don't know about that, but with better C++ interop, it might be easier to bind to OGRE. (See http://www.ogre3d.org/)
Re: Redesign of dlang.org
On Monday, 21 December 2015 at 15:09:06 UTC, Adam D. Ruppe wrote: Dedicated pages is a good idea and can be done trivially with ddoc macros to avoid repetition of the content in the source. It could also be a css :hover dropdown instead of JS, but I hate drop downs on hover so I'd prefer the dedicated pages. We could use the :hover dropdowns as a fallback for the JS, though. It might not be ideal, but isn't that basically the definition of a fallback?
Re: Redesign of dlang.org
On Saturday, 19 December 2015 at 14:33:35 UTC, Jacob Carlborg wrote: Thoughts? The template constraints being on their own line is a nice touch. Overall, the design looks very clean-cut. The only real issue I see is that it could use a bit more contrast. Those light gray lines fade into the background just a bit too much.
Re: What is the state of D for game development?
On Friday, 18 December 2015 at 00:03:06 UTC, extrawurst wrote: What PR is that ? Link ? --Stephan https://github.com/D-Programming-Language/dmd/pull/5290 It adds some __traits that would make it easier for me to introspect my binding modules and generate glue code. Right now, I'm using several stages of build tools which loop over the actual source files to generate the necessary code, which has gotten quite ugly. With the right __traits, it's possible to cut out some steps. Once I've refactored everything, it might actually be a viable method to bind all sorts of C++ libraries.
Re: Some feedback on the website.
On Thursday, 17 December 2015 at 23:50:34 UTC, Andrei Alexandrescu wrote: * "Examples:" is a historical error. All instances should be "Example:". Just one diff making that change throughout would be a meaningful contribution. Like so? https://github.com/blm768/phobos/commit/5f08c058abd2bafe91056d5223d45ed5c07a748c Sed for the win! (With manual review of the changes, of course.) I'll open a pull request in a moment.
Re: Some feedback on the website.
On Thursday, 17 December 2015 at 19:50:40 UTC, Andrei Alexandrescu wrote: If you have some time and motivation to improve the documentation, there's tremendous opportunity for impact. So much low-hanging fruit, all well before we explore switching to a different way of building the site. And whatever improvements you make won't compete with future changes. There's so much opportunity there it hurts. -- Andrei As long as the main page still works, then yeah, that's first priority. Is there a particular spot that stands out as needing the most improvement? I'm no Phobos expert, but I can at least fill any glaring holes.
Re: What is the state of D for game development?
On Thursday, 17 December 2015 at 17:38:31 UTC, Ali Çehreli wrote: I am stealing HerrDrFaust's question from the following Reddit thread: https://www.reddit.com/r/programming/comments/3wqt3p/programming_in_d_ebook_is_at_major_retailers_and/ Please answer here or there. Thank you, Ali Well, we have some bindings to game dev libraries, but the ecosystem isn't nearly as rich as what's available with C++. Derelict has bindings to almost all the "basic" libraries, though. I've been working on a binding to Bullet Physics, but it's stalled while I wait on a DMD pull request that I put in to allow the kind of introspection my method requires.
Re: Some feedback on the website.
On Thursday, 17 December 2015 at 07:51:42 UTC, Jacob Carlborg wrote: On 2015-12-17 00:43, BLM768 wrote: One is to make as much of it as possible in plain old static HTML. Stuff like the articles rarely changes, after all. This is an horrible idea. No sane person would use raw HTML. The only advantage is that it's HTML so there's documentation available. Yeah. I didn't think that one through. The idea I had in my head was to build a template in (mostly) raw HTML, write each article as an HTML snippet, and use either a framework or a build script to paste them together, so it's not _completely_ raw, just enough so you actually see the HTML. The main thing was to move away from building all the tags with macros. But yeah, I didn't express that clearly enough (or think through it properly).
Re: Some feedback on the website.
On Wednesday, 16 December 2015 at 23:49:52 UTC, Andrei Alexandrescu wrote: But I dislike typing HTML. DDoc improves on that significantly. Fair enough. Vibe.d has diet templates, though. They're pretty nice. As long as the pages are mainly static anyway, though, it's all plain boring HTML to the client no matter what's used on the back end. Ironically Ddoc does exactly that, and quite nicely. I thought about that, too. It's great for static content, but doesn't dynamic content become kind of tricky? Given that the forum sidebar operates differently from the main page sidebar (most noticeably in the giant image link at the top), I'd guess that it's not using the same DDoc template. (I haven't looked at the source, though.) Of course, it would need custom template code for the forum menu, so there's really not much to share with the main site...
Re: Some feedback on the website.
On Wednesday, 16 December 2015 at 23:43:41 UTC, BLM768 wrote: [snip] ...and as I read some older posts, I see that mine is completely redundant. ;) Seriously, though, I'm willing to help prototype something. I've got time before the next semester starts.
Re: Some feedback on the website.
On Wednesday, 16 December 2015 at 23:01:47 UTC, Walter Bright wrote: Exactly. We'll never get anywhere chasing people who say "I'll help only if you convert to my way of doing things." I've done enough of that in the past, and concluded they're just seeing how long you'll dance to their tune and have no real intention of ever helping - there will just be another excuse. It's funny how much "better" one's own ideas seem until one realizes that implementing them usually takes just as much effort as with someone else's idea, and work is almost always the limiting factor. On the subject of "one's own ideas", here's mine, FWIW: First, my background thoughts. We seem to have four main "sections" of the site: the forums (built on DFeed), the wiki (built on MediaWiki), the language docs (DDoc), and the "main" site (in DDoc/HTML). The first three are using technologies which were explicitly designed for what they do, and they work quite nicely. The only thing left is the "main" site (the download page, articles, etc.), which doesn't fit into the models of the first two technologies and is somewhat clumsy for some people to edit because it's built on more than just "common" Web standards. I can think of a couple of ideas for making the main page more palatable to Web developers. One is to make as much of it as possible in plain old static HTML. Stuff like the articles rarely changes, after all. Another idea is to use a Web application framework. There's a significant advantage there: we can have one master "layout" template, and almost any content we want (forums, DDoc-generated HTML, static HTML, and so on) can be rendered in that template with relatively minimal code. There are lots of frameworks that shouldn't be hard to use. I'm sure that someone has already suggested doing it in vibe.d, and that probably got shot down due to a technical issue or something, but it would be interesting from a PR standpoint.
Re: And yet another cool project: fetching multiple URLs at once
On Wednesday, 16 December 2015 at 21:00:55 UTC, Andrei Alexandrescu wrote: I should add I've argued for including some of the core vibe.d stuff in Phobos. Sadly nobody is championing such a project for the time being. Andrei Would that include its stream stuff? We've been needing a std.stream replacement for a long time.
Re: Complexity nomenclature
On Sunday, 6 December 2015 at 03:30:51 UTC, Timon Gehr wrote: log(x^2) = 2 log x. Why do log rules have to make everything so simple? ;)
Re: Complexity nomenclature
On Saturday, 5 December 2015 at 22:56:23 UTC, H. S. Teoh wrote: Multi-term complexities arise from trivial graph algorithms. They are not limited to the use of multiple containers. More precisely, the multiple terms arise because of the structure of the graph (being composed of nodes and edges); what the algorithms add are functions on nodes and edges. True. I don't expect that very many people would want to specify an algorithmic complexity for those operations, though. It seems much more rigidly defined than for lists, arrays, etc. The question is not really about whether "complex complexities" will exist but whether the user has a practical reason to care about specifying them. Unfortunately, once you have more than a single variable in your functions, the big-O expressions rapidly become inextricably complex, and can no longer map to nice abstractions like the reals + infinities + infinitesimals linear ordering. For example, two graph algorithms may be, respectively, O(V^2 + E) and O(V + E^2); it's difficult to judge based on that which one is "superior". Well, if one variable is "capped" (or at least expected to be "small") it's easy enough to eliminate that term. Beyond that, there isn't necessarily a single ordering of big-O expressions, but many of them can be ordered relative to a single variable. For instance, O(n + m^2) is less complex than O(n^2 + m) with respect to n (and vice versa for m). It's trickier when expressions are more deeply nested, but if select one term (in this case, n), set all the others to be constant (since none of them depends on n), and evaluate the resulting expression tree, you should get something half-usable. Some simplifying rules may be useful. For instance, log(x^2) should approach log(x) as x approaches infinity, I think. (My calculus is a bit rusty.)
Re: Complexity nomenclature
On Saturday, 5 December 2015 at 20:48:16 UTC, Andrei Alexandrescu wrote: On 12/04/2015 10:24 PM, Timon Gehr wrote: In fact I went through the implementation but soon I hit a wall: what's the _relationship_ between the two growths? It may be the sum O(m + n) but also the product O(m * n). So the operator must be encoded as well. Then what do we do with more complex relationships like O((m + n) log n) etc. Then once you get to some reasonable formula, what's the ordering on top of these complexities? Probably difficult. I gave up on this for the time being. Ideas welcome. Andrei Well, we could see how CAS libraries handle this kind of stuff (if there _is_ one which handles it)... Really, though, with the more complex algorithms, you start running into the kinds of issues noted in the first reply to this article: http://www.perlmonks.org/?node_id=573138 Besides, is anyone actually going to specify that they need an algorithm that is O(log(n) + m^2) or whatever? Or would a function just take _two_ algorithms, assert that each is O(log(n)) and O(m^2), respectively, and then compose them itself? The complexities depend on the types of container anyway, so in general, you should get only multi-term big-O notation when you're using multiple containers (or Cartesian products of a container with itself or something like that). Can't we just make sure one container's insert() and the other container's sort() work within a certain complexity?
Re: Complexity nomenclature
On Saturday, 5 December 2015 at 00:13:02 UTC, BLM768 wrote: list.removeWithComplexity(Complexity.linear, 3); Uh, I mean list.removeWithComplexity!(Complexity.linear)(3).
Re: Complexity nomenclature
On Friday, 4 December 2015 at 22:17:21 UTC, Jonathan M Davis wrote: Either of those would be better than stableLinearRemove or stable.linear.remove. The UDAs would be more documentation friendly, though being able to pass around template arguments could be valuable for the cases where you're trying to enforce specific complexity requirements. It should be possible to unify the template and UDA forms. Assuming a template supportsComplexity(func, complexity) that determines whether a function or method has the specified complexity UDA (or a "faster" one), it's not hard to implement something like this: void removeWithComplexity(T, complexity)(T collection, size_t index) if(supportsComplexity!(T.remove, complexity) { collection.remove(idx); } List!int list; //... list.removeWithComplexity(Complexity.linear, 3); --- Of course, this implementation has issues with collection operations which are defined as UFCS functions (as opposed to methods), but it should be possible to get around that issue.
Re: Complexity nomenclature
On Friday, 4 December 2015 at 18:21:41 UTC, Walter Bright wrote: I suggested in the pseudo namespaces thread using template parameters to express characteristics, as in: remove!(stable, linear) with sensible defaults so most of the time the user would just use: remove The nice thing about this is that it can be easy to specify which complexities an operation supports. --- void remove(complexity, T)(List!T list, size_t index) if(complexity >= Complexity.linear); //or however complexity objects work... List l; //... l.remove(3); l.remove!(Complexity.polynomial(2))(3); l.remove!(Complexity.constant)(3);//fails; there's no template specialization for this case because complex < linear.
Re: Three people out of four dislike SDL
On Tuesday, 1 December 2015 at 18:25:06 UTC, Bubbasaur wrote: Really, do really believe in what you wrote? So if you take a look right now, the "YES" option for the question: "Do you like new DUB config format?" Is somehow "magically" winning the poll right now! Bubba. Huh. That changed quickly. My Z-test is already out of date. ;)
Re: Three people out of four dislike SDL
On Tuesday, 1 December 2015 at 17:26:13 UTC, Andrei Alexandrescu wrote: Independent on the topic at hand - wondering what your reasoning is. I just took a look and there are 205 votes. Not a large number, but quite a lot more than any voting we saw in the past (when consensus was proclaimed after like 15 votes :o)). Intuitively I agree with you, but I wonder at what point numbers become large enough to capture meaning. Thx! -- Andrei Time for a proportion Z-test! Assuming that this poll represents a simple random sample (which it almost certainly doesn't, but it's the best we have), let's test the claim that at least 50% of the community dislikes the SDL format. For reference, I'm using the poll data at the time of this post: 124 for, 145 against. According to my calculations, at a 95% confidence level, there's not sufficient evidence to reject the hypothesis that at least 50% of the community dislikes the new format. However, FWIW, we can say with very high confidence that at least 25% of the whole community likes the new format.
Re: I hate new DUB config format
On Saturday, 28 November 2015 at 18:13:51 UTC, Kagamin wrote: Then XML is clear winner, its support, spread, availability and tooling is unmatched. So is its complexity. ;) Do we even have a good standard XML parser? std.xml has been languishing for years...
Re: New __traits
On Thursday, 26 November 2015 at 23:16:59 UTC, BLM768 wrote: [snip] It lists a bunch of symbols that most certainly _aren't_ direct ancestors of the "std" package: "object", "core", "std", "KeepTerminator", "GCC_IO", "HAS_GETDELIM", "FSChar", and a bunch of others. That's a bug, right? I've tacked on a comment to the relevant issue (11595) with some info that may or may not help figure out what the problem is. I might play with it, too, but I'm only a junior-level CS student who has basically no familiarity with how DMD does symbol resolution, so I doubt that I'll be able to find exactly where the issue is.
Re: I hate new DUB config format
On Friday, 27 November 2015 at 19:29:48 UTC, Jacob Carlborg wrote: Just throwing it out there: CSON [1]. "CoffeeScript-Object-Notation. Same as JSON but for CoffeeScript objects". It's used by the Atom editor. [1] https://github.com/bevry/cson Hmm. Pretty, standardized, similar to JSON. I like it! ...but we don't have a parser yet, do we? That might be an obstacle.
Re: New __traits
On Thursday, 26 November 2015 at 20:56:39 UTC, Jonathan M Davis wrote: Yes, code can forward-reference an import. e.g. this code compiles just fine: void main() { writeln("Where's my import?"); } import std.stdio; Now, when the import is inside of a function, then it can't be forward-referenced, but that's in line with how variable declarations work. - Jonathan M Davis Oh, duh. I should have remembered that. In any case, I my tests work when I forward-reference, too, so I'll probably just put an assert on it and call it good. I've got some unit tests on my code now, so it looks like it's almost time for my first PR. I don't know if this is at all related to how top-level packages aren't resolving to Package objects by the time the __traits run, but while testing this code, I found what seems to be a bug related to __traits(allMembers). Specifically, this code produces an extremely strange output: --- import std.stdio; pragma(msg, __traits(allMembers, std)); void main() {} --- It lists a bunch of symbols that most certainly _aren't_ direct ancestors of the "std" package: "object", "core", "std", "KeepTerminator", "GCC_IO", "HAS_GETDELIM", "FSChar", and a bunch of others. That's a bug, right?
Re: I hate new DUB config format
On Thursday, 26 November 2015 at 19:57:19 UTC, Jacob Carlborg wrote: Everyone will hate me for saying this, but in that case, just go with Ruby (or some other similar language) That was actually one of my first thoughts. It would be pretty, but we'd have another dependency then. Also, Ruby doesn't embed well into other applications, and if we're using another general-purpose programming language for our config format, what kind of impression does that give others about our confidence in D? That said, I found a neat language today, and it might be usable for config files. See nim-lang.org.
Re: New __traits
On Thursday, 26 November 2015 at 02:20:43 UTC, Daniel Murphy wrote: Unfortunately I have no idea. You'll have to have a look at what other code that resolves packages is doing. If you can't find it it might be worth emailing Kenji Hara, since he knows everything. Well, expression.d seems to do it this way. It's also got a check for "pkg == null", so maybe I should include that. Currently my code would just swallow the issue and report that the argument isn't a package. Then again, I don't even know whether it's possible for my code to forward-reference an import; if not, pkg will never be null anyway. Maybe I'll just assert it or something...
Re: I hate new DUB config format
On Wednesday, 25 November 2015 at 22:20:39 UTC, Andrei Alexandrescu wrote: It's more like "Do this, no need to argue". There's really no need, and we're arguing too much over too little. -- Andrei Is anyone else having flashbacks to Phobos vs. Tango? In this case, as much as I like how the SDL syntax is more readable (at least to me), the history of Phobos shows that standardization wins in most cases. I don't know if we want to yank the syntax right out of DUB, but we could at least deprecate it until things settle out. Or, hey, we could use XML. ;)
Re: New __traits
On Wednesday, 25 November 2015 at 15:39:17 UTC, Daniel Murphy wrote: What you're seeing is just an artifact of how dmd's internals work. 'std' is an 'import' (call Dsymbol.kind() for the category of symbol) and you'll have to resolve it to work out which module/package is being imported. It's possible that this is a bug in the symbol resolution, and that it should have already been resolved to a package. It seems that I can resolve the import by using "theImport.pkg", but I'm not sure if it's the "correct" way. It works in my tests, though. Is that the right way to do it, or is there a better method?
Re: New __traits
On Wednesday, 25 November 2015 at 15:39:17 UTC, Daniel Murphy wrote: What you're seeing is just an artifact of how dmd's internals work. 'std' is an 'import' (call Dsymbol.kind() for the category of symbol) and you'll have to resolve it to work out which module/package is being imported. It's possible that this is a bug in the symbol resolution, and that it should have already been resolved to a package. Keep in mind also that isPackage and isModule are RTTI functions, and since Module inherits from Package all modules will appear to be packages if that's all you check. That helps immensely! I'll play with that a bit. As far as semantics go, if this were ever officially integrated into DMD, would it make sense for __traits(isModule, somePackage) to return false (unless it has a package.d) since the inheritance of Module from Package is basically a DMD implementation detail, or would it be better to just follow DMD's convention directly?
New __traits
For a project I've been working on, I found that it would be helpful to have a way to determine whether a symbol represents a module or package. Since I couldn't find an easy way to do it, I forked DMD and made some tweaks. ;) Anyway, I uncovered an interesting issue. According to my test program (https://gist.github.com/blm768/42f40aa5a0c49bb8bd16), these are the "types" of various packages/modules in Phobos: std: std.stdio: package, module std.algorithm: package std.digest: package In other words, "std" isn't a package _or_ module, and std.stdio is both (even though it's just a single D source file). This doesn't seem quite right. There could be an error in my patch to DMD, but I don't see where it could be because it's so simple. The code is at https://github.com/blm768/dmd/tree/new_traits if anyone wants to look over it. If anyone can help me figure out what's going on, I'd greatly appreciate it.
Re: New __traits
On Wednesday, 25 November 2015 at 01:06:55 UTC, BLM768 wrote: In other words, "std" isn't a package _or_ module, and std.stdio is both (even though it's just a single D source file). This doesn't seem quite right. I just confirmed that this also applies to other root packages, i.e. "core" or any root packages from third-party libraries.
Re: Easy and efficient database usage
On Friday, 23 October 2015 at 12:42:08 UTC, w0rp wrote: Does anyone have any thoughts on this topic? A couple of years ago, I started playing with the idea. The basic concept was to dump DB records into "dumb" (i.e. representing just the basic aspects of the model object) structs, which can be stack-allocated to minimize GC usage. It's very far from complete and has been dormant for a while, but someone might be able to make use of some of the code. It would probably need to be rewritten to use a "standard" DB driver framework, though; right now, it's just got its own abstraction layer over SQLite.
Re: Improvements to std.typecons.Nullable
On Wednesday, 9 October 2013 at 17:07:18 UTC, monarch_dodra wrote: That was my point. Writting "Nullable!T == T" is the exact same thing: Comparison of a value with the absence of a value. It's neither equal nor different, it's an error. Equality comparison is a bit different from properties such as emptiness. Virtually every language allows comparisons between null and non-null objects. In D and Java, this is the behavior for object references; in Ruby and Lua, this is the behavior for all values. Nullable!T was seemingly designed to emulate that sort of behavior, and overloading opEquals() would provide semantically correct behavior without any exceptions ever being thrown. My point though is that it's implicit nature makes it so that you forget about said state. Adding a simple ".get()" is not that much verbose, and sticks out that you are calling something that can be an error. You should either be operating the handler (Nullable), or the Value itself. Not a bit of "maybe the nullable, maybe the value" Ultimately, it seems to boil down to a personal preference: should Nullable!T emulate the behavior of D's existing nullable types, or should it use a more explicit syntax? I personally lean toward consistency, in part because doing otherwise would be a breaking change that doesn't really seem justified unless we can solve the issue with _all_ nullable references. I do see the merits of your proposal, though.
Re: Improvements to std.typecons.Nullable
On Wednesday, 9 October 2013 at 06:48:31 UTC, monarch_dodra wrote: OK, so that's two functions already. What about opCmp? What about toHash? Since ordered comparisons make no sense with null values, opCmp would need to throw an exception when working with null values anyway. That's exactly what it does right now. I've considered the other operators, and the same logic seems to apply to them. As for toHash, that needs to be overloaded whenever opEquals is. That's true for all types. What if T is a range? Then "Nullable!T.empty" should return true if the Nullable is empty. IF we don't, we'll get a crash in foreach. It does. Null is not an "empty" range; it's the _absence_ of a range. They are not the same concept, and a null range _cannot_ be empty because the range does not exist. Therefore, it's a logic error and should throw an exception. If your range were class-based, you'd have exactly the same issue, except that instead of getting an exception, you'd get a segfault. On Tue, 08 Oct 2013 22:55:34 +0200 "monarch_dodra" wrote: Is it though? C++ has done without it, and is still doing without it. It has "implicit build from" which every one says is mostly an abomination. Then here we are, bashing on their implicit constructors, yet using "implicit cast to" O_o. A major part of the problem in C++ stems from the existence of two different forms of implicit conversion: the overloaded cast operator and copy-constructors. D does not allow implicit conversions with the latter, and it only allows implicit conversion to one type with the former, which is considered acceptable according to every C++ book I've read. I draw the line when convenience gets in the way of my programs not crashing. Whether you have the "alias this" or not, if you try to get a T out of a null Nullable!T, your program will throw an exception. Leaving out the "alias this" would serve only as a reminder to check for null, not as a solution to logic errors. When dealing with a Nullable!T, just like when dealing with a nullable object reference or a nullable pointer, you have to account for the null state.
Re: Improvements to std.typecons.Nullable
On Tuesday, 8 October 2013 at 19:04:33 UTC, BLM768 wrote: * Making isNull() @property Hmm... looks like it's already @property. I guess this happened after the last update to the Phobos docs. I'll still need to fix the other stuff, though.
Re: Improvements to std.typecons.Nullable
On Tuesday, 8 October 2013 at 20:55:35 UTC, monarch_dodra wrote: Or we could just nuke the alias this. A Nullable!T isn't a T. It's a T handler. "alias this" allows implicit cast, which should only happen with a "is a" relation. Using it in a different context (such as nullable) is wrong, and these errors are the price we are paying for it. It's a bit more verbose, but it would solve *all* of these ambiguity and unexpected error problems. Maybe... An object reference can be null, but a null "Object" isn't really an Object but the absence of one. With "alias this", the behavior meshes with the behavior of object references. Whether that's good or bad, it does add some consistency. I'm not sure what I'd like to see in the long term, but I'll leave the "alias this" in for my pull request because removing it would be a breaking change.
Re: Improvements to std.typecons.Nullable
On Tuesday, 8 October 2013 at 19:20:05 UTC, Brad Anderson wrote: The wiki has a pretty good guide of the overall process: http://wiki.dlang.org/Pull_Requests That answers most of my questions, but it seems a little... informal. I guess the formal review process doesn't really apply to minor API changes. If it's really that easy, I'll just go for it.
Improvements to std.typecons.Nullable
I've been working on a project that makes relatively heavy use of nullable values. I've been using std.typecons.Nullable, and it mostly works well, but there are some improvements that could be made to the implementation: * A toString() method (needed to fix bug #10915) * An opEquals for comparisons with the type that the Nullable wraps * Currently, comparing a null Nullable!T with a T produces an error, but it makes more sense to just return false. * Making isNull() @property get() might also make more sense as a property, but not with its current name; it would be better to make the name a noun such as "value" rather than a verb. If it were to be changed, it could be done in a fully backward-compatible way by making "get" an alias of "value". These would all be simple changes, so if someone's willing to guide me through the formalities, I could make this my first contribution to Phobos.
Re: std.rational?
On Friday, 27 September 2013 at 15:36:12 UTC, Dmitry Olshansky wrote: I bet the reason is practicality: try using full names of denominator/numerator in some involved numeric code. It's a mess. One may argue you need not access numerator and denominator explicitly that much but I think it happens. I'm not sure if this fits with Phobos style, but they could be defined as "numerator" and "denominator" and aliased to "num" and "denom", respectively. That way, we get the best of both worlds.
Re: std.allocator needs your help
On Monday, 23 September 2013 at 17:01:47 UTC, deadalnix wrote: What you call safe really isn't. Allocate something on the GC, store a pointer on a custom allocated location, collect, enjoy the memory corruption. All operation are safe according to your proposal. Allocation can only be safe if the GRAND MASTER GC is aware of it. I don't see why the GC can't be allocator-agnostic. In principle, it should be possible to register arbitrary allocators with the GC (possibly by storing a pointer to the allocator in each GC-managed block of memory). The GC would have a default allocator which would be used with the "new" operator, and something like the aforementioned create!() syntax could be used for custom allocators: SomeClass c1 = new SomeClass("arg"); //Managed by the GC SomeClass c2 = gcCreate!SomeClass(someAllocator, "arg"); //Another possible syntax (much prettier!): SomeClass c3 = someAllocator.new SomeClass("arg"); This could also integrate with DIP46; instead of pushing and popping a GC object, one would push and pop the GC's default allocator (for the current thread, of course). There would be a bit of overhead, but that seems to be unavoidable in a sufficiently generic design, and I doubt that it would cut performance to an unacceptable level, especially because really performance-critical code would avoid the GC anyway. You proposal allocate shared memory. This is common in C/C++ world as memory is shared by default, but shouldn't be in D. It is highly desirable to allocate with different methods for different type qualifier. How does your design adapt to that ? If the aforementioned thread-local GC reference is implemented, it should be possible to provide decent thread-local allocation. I'm not sure exactly how to design that, but it seems like thread-local GC allocation would require some work at the GC level; a global GC won't necessarily play nicely with thread-local allocators. For non-GC thread-local allocations, I'd imagine that you could just create a thread-local allocator.
Re: Mixin overload sets
On Friday, 16 August 2013 at 07:48:52 UTC, QAston wrote: You can put those functions into HasOtherMixins by using alias. struct HasOtherMixins { ... alias someMixin!int.abc abc; alias someMixin!float.abc abc; alias someOtherMixin abc; } Actually, that syntax only works for regular templates, not mixins. Trying it with a mixin template gives an error. It's also not very useful when mixing in several methods from the same template. However, the first solution I suggested could be expanded to support that type of syntax: struct HasMixins { alias mixin someMixin!int.abc abc; //etc. } I'm starting to lean toward the first option as the more "correct" solution because it's more flexible and follows the principle of least surprise. If it's decided that this would be an acceptable addition to the language, I could try to cobble a pull request together. I don't have any experience with the DMD codebase, but it might be a good introductory project for me...
Mixin overload sets
The current behavior of placing identically-named functions from separate mixins into separate overload sets works well most of the time, but there are cases when the functions should be in the same overload set, and the aliasing required to allow overloading can quickly get tedious and clutter the namespace where the mixins are used, especially if the mixins define multiple functions. mixin template someMixin(Args ...) { void abc(Args) {}; void def(int, Args); } struct HasMixins { mixin someMixin!int mixinInt; alias mixinInt.abc abc; alias mixinInt.def def; mixin someMixin!float mixinFloat; alias mixinFloat.abc abc; alias mixinFloat.def def; //and so on... } It would be nice if we had a more concise way to pull all of the duplicate functions into a single overload set. I can think of two ways to handle this: 1. Introduce a new syntax. struct HasMixins { //One possible syntax: alias mixin someMixin!int this; alias mixin someMixin!float this; //etc. } HasMixins hm; hm.abc(3f); //Would call HasMixins.abc(float) 2. Automatically place functions that come from different instances of the same mixin template into the same namespace. struct HasMixins { mixin someMixin!int; mixin someMixin!float; } HasMixins hm; hm.abc(3f); //Would call HasMixins.abc(float) mixin template someOtherMixin { void abc() {}; } struct HasOtherMixins { mixin someMixin!int; mixin someMixin!float; mixin someOtherMixin; } HasOtherMixins hm2; hm2.abc(3f); //error Thoughts?
Re: @property - take it behind the woodshed and shoot it?
On Saturday, 10 August 2013 at 17:48:34 UTC, BLM768 wrote: On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote: To add to the mess - or maybe suggest a new approach, what about: class A { int foo(); void foo=(int a); private foo_; } Then a.foo = 42; calls the foo= method. No other conversions from a=b to a method invocation. It may be suggested in one of these 46 pages which I haven't read. And it'll probably break a lot of stuff. The problem with this approach is that the getter is still operating under the semantics of a method, but, as a property, it should be acting like a field. An approach like this would work: class A { Sorry; message got cut off when I tried to insert a tab and then pressed space with the "Send" button focused. Continuing... class A { @property int foo(); @property void foo=(int a); //etc. } However, it doesn't offer any significant advantage over the current property syntax other than providing a clearer distinction between getters and setters, which is only important when dealing with UFCS, as pointed out in an earlier post.
Re: @property - take it behind the woodshed and shoot it?
On Saturday, 10 August 2013 at 10:29:51 UTC, Stian Pedersen wrote: To add to the mess - or maybe suggest a new approach, what about: class A { int foo(); void foo=(int a); private foo_; } Then a.foo = 42; calls the foo= method. No other conversions from a=b to a method invocation. It may be suggested in one of these 46 pages which I haven't read. And it'll probably break a lot of stuff. The problem with this approach is that the getter is still operating under the semantics of a method, but, as a property, it should be acting like a field. An approach like this would work: class A {
Re: Compile time executable calling?
On Saturday, 13 July 2013 at 04:23:56 UTC, Walter Bright wrote: A big problem with it would be the equivalent of the "SQL Injection Exploit". Since the compiler can now execute arbitrary code, someone passing around malicious source code could do anything to your system. Assuming that the user is compiling the code in order to run it (which does seem to be the most common case, at least in my experience), the user is already running arbitrary code. I don't really see how this would create a greater security risk than what already exists. That said, I'm not completely sold on this idea, either, at least not while there are more important issues to solve. It could be nice at times, but I'm having a hard time coming up with a usage case where this would really be much more convenient than just using the build system.
Re: Memory management design
On Wednesday, 10 July 2013 at 07:50:17 UTC, JS wrote: One can already choose their own memory model in their own code. The issue is with the core library and pre-existing code that forces you to use the GC model. It's possible to use your own memory model, but that doesn't mean it's necessarily convenient or safe, and there's no standardized method of going about it. If it becomes standardized, there's a much higher chance of the core library using it. @nogc has been proposed several years ago but not gotten any footing. By having the ability to mark stuff has @nogc phobos could be migrated slowly and, at least, some libraries would be weaned off the GC and available. I think the use of custom allocators would be better. Plug your own memory management model into D. Memory management and memory allocation are not the same issue; from a purely theoretical standpoint, they're nearly orthogonal, at least without a compacting collector. If the both the GC and the allocators are designed in a sufficiently flexible and modular manner, it would be possible to tie several general-purpose allocators to the GC at once. There are some allocators that can't be shoehorned into the GC model, but those would just return non-GC references. On Wednesday, 10 July 2013 at 07:59:41 UTC, Dicebot wrote: I think merging "scope" and "owned" can be usable enough to be interesting without introducing any new concepts. Simply make it that "scope" in a variable declaration means it is a stack-allocated entity with unique ownership and "scope" as a function parameter attribute is required to accept scope data, verifying no references to it are taken / stored. Expecting mandatory deadalnix comment about lifetime definition ;) Most of the functionality of "owned" is redundant, but there are still some corner cases where it could be useful. The idea behind it is to have it function very much like a pointer in C++ code. For non-reference types, you could just use a pointer, but using a pointer with reference types introduces an extra dereference operation to get to the real data. This is something that could be implemented as a library type rather than an intrinsic part of the language, and that would probably be better because it's really sort of a low-level tool. Only thing I have no idea about is if "scope" attribute should be shallow or transitive. Former is dangerous, latter severely harms usability. I'm not sure how shallow "scope" would be dangerous. If a "scope" object contains non-scope references to GC-allocated data, it's perfectly safe to stash those references somewhere because the target of the reference won't be collected. If the object contains "scope" members (if the language even allows that), then references to those members should actually inherit the container's "scope" status, not the members' "scope" status, because "scope" would be "overloaded" in that case to mean "packed into a (potentially heap allocated) object". "scope" is all about where the objects might be allocated, which is not a transitive property.
Memory management design
Given all of this talk about memory management, it would seem that it's time for people to start putting forward some ideas for improved memory management designs. I've got an idea or two of my own, but I'd like to discuss my ideas before I draft a DIP so I can try to get everything fleshed out and polished. Anyway the core idea behind my design is that object lifetimes tend to be managed in one of three ways: 1. Tied to a stack frame 2. Tied to an "owner" object 3. Not tied to any one object (managed by the GC) To distinguish between these types of objects, one could use a set of three storage classes: 1. "scope": refers to stack-allocated memory (which seems to be the original design behind "scope"). "scope" references may not be stashed anywhere where they might become invalid. Since this is the "safest" type of reference, any object may be passed by "scope ref". 2. "owned": refers to an object that is heap-allocated but manually managed by another object or by a stack frame. "owned" references may only be stashed in other "owned" references. Any non-scope object may be passed by "owned ref". This storage class might not be usable in @safe code without further restrictions. 3. GC-managed: the default storage class. Fairly self-explanatory. GC-managed references may not refer to "scope" or "owned" objects. Besides helping with the memory management issue, this design could also help tame the hairy mess of "auto ref"; "scope ref" can safely take any stack-allocated object, including temporaries, so a function could have "scope auto ref" parameters without needing to be a template function and with greater safety than "auto ref" currently provides.
Re: why allocators are not discussed here
On Wednesday, 26 June 2013 at 23:59:01 UTC, Adam D. Ruppe wrote: On Wednesday, 26 June 2013 at 23:02:47 UTC, H. S. Teoh wrote: Maybe a type distinction akin to C++'s auto_ptr might help? It might not be so bad if we modified D to add a lent storage class, or something, similar to some discussions about scope in the past. These would be values you may work with, but never keep; assigning them to anything is not allowed and you may only pass them to a function or return them from a function if that is also marked lent. Any regular reference would be implicitly usable as lent. Something along those lines would probably be a good solution. It seems that we're working with three types of objects: 1. Objects that are "owned" by a scope (can be stack-allocated) 2. Objects that are "owned" by a another object (C/C++-like memory management) 3. Objects that have no single "owner" (GC memory management) The first two would probably operate under semantics like "lent" or "scope", although I'd like to propose an extension to the rules: it should be possible to store a weak reference to these types (or at least to #2) once we have weak reference support. The third type seems to be pretty much solved, seeing as we have a (mostly) working GC. Something like this might be a nice way to implement it: class Thing {} void doSomething(scope Thing t); //Takes #1, #2, or #3 by reference void doSomethingElse(owned Thing t); //Takes only #2 or #3 void main() { scope Thing t1; //stack-allocated doSomething(t1); owned Thing t2 = new Thing; //heap-allocated but freed at end of scope doSomething(t2); }
Re: Automatic Equation and Inequation evaluation.
On Saturday, 15 June 2013 at 13:23:07 UTC, Carlos wrote: OK but if developed it would be included in D ? Right ? It would be very useful I think. It could be useful, but only in a very specific type of program, so it's unlikely that it would be bundled with the D compiler. It would almost certainly be distributed as a separate download from its own site.
Re: What is the current state of D for android development?
On Friday, 29 March 2013 at 06:35:10 UTC, js.mdnq wrote: I guess that means none... :/ Unfortunately, there hasn't been a lot of focus on ARM platforms; people are too busy improving the language and tools to work on standard PC hardware. The DMD compiler definitely won't work for Android development, but I'm pretty sure that GDC can be compiled for ARM output, and I think LDC has that capability as well. You'd probably need to write your own linkscripts, and the runtime would definitely have to be modified.
Re: std.stream replacement
One thing to remember is that streams need to be runtime swappable. For instance, I should be able to replace stdout with a stream of my choice. That does make my solution a little tougher to implement. Hmmm... It looks like a monolithic type is the easiest solution, but it definitely should have range support somewhere. Since that's already planned (at least as I understand it), I guess I don't really have any complaints about it. Now, I wouldn't mind if you made the default source a "block-input range", since it could have very similar performance characteristics to an integrated source and would provide a useful range for other stuff, but an integrated source would be manageable and probably just a hair faster.
Re: std.stream replacement
On Thursday, 7 March 2013 at 12:42:23 UTC, Steven Schveighoffer wrote: If the function is optimized, it can essentially bypass the range layer and operate directly on the buffer while using the same interface it would use if it were operating on the range. As I understand it, some of the operations in Phobos do that as well when given arrays. This is the wrong track to take. There have been quite a few people in the D community that have advocated for the syntax: int[] arr; auto p = 5 in arr; Just like AAs. It looks great! Why shouldn't we have a way to search for data with such a concise interface? The problem is then that diminishes the value of 'in'. For AAs, this lookup is O(1) amortized, For an array, it's O(n). This means any time a coder sees x in y, he has to consider whether that is a "slow lookup" or a "quick lookup". Not only that, but generic code that uses the in operation has to insert caveats "this function is O(n) if T is an array, otherwise it's O(1)". The situation is not something we want. Maybe "takeArray" is a bad design, but it was just an example. The "block input"/"slice-assignable" range idea would still work well, though. We could provide a "RangeStream" type which shoehorns any range into a stream, but I'd want it tucked in some shadowy corner of Phobos, not to be used except in emergencies when nothing else will do. It should be discouraged. One of my main reasons for wanting ranges as the input was to allow this sort of an interface. This looks like a usable solution for that need. I hope my above comments have made clear that I am not against having ranges be forcibly changed into streams. What I don't want is ranges implicitly treated as streams. I'd say that my idea is more about having ranges implicitly treated as stream sources rather than as true streams, but having a method to explicitly make them stream sources would still be quite usable. Ultimately, I think that the differences between our designs boil down to having a more monolithic stream interface with an internal stream source or having a lighter-weight but more ad-hoc stream interface with an external and more exposed stream source. At this point, I'd probably be happy with either as long as they have equivalent functionality.
Re: std.stream replacement
That certain specific types of range can't implement a given operation efficiently isn't a reason to reject the idea. If somebody tries using takeArray on a range that by its very nature can only pick off elements one by one, they should expect it to be as slow as a for loop. OTOH, when used on a file, array or similar structure, it will perform much better than this. But thinking about it now, maybe what we need is the concept of a "block input" range, which is an input range with the addition of the takeArray method. Of course, standard D arrays would be block input ranges. Then (for example) a library that reads a binary file format can be built to accept a block input range of bytes. Stewart. That's basically what my thinking was, but you've expressed it in a better way than I think I could have. I'd definitely like to see this idea implemented; it could be useful for just about anything involving a buffer.
Re: std.stream replacement
On Wednesday, 6 March 2013 at 16:36:38 UTC, Steven Schveighoffer wrote: On Tue, 05 Mar 2013 18:24:22 -0500, BLM768 wrote: Ranges aren't necessarily higher- or lower-level than streams; they're completely orthogonal ways of looking at a data source. It's completely possible to build a stream interface on top of a range of characters, which is what I was suggesting. In that situation, the range is at a lower level of abstraction than the stream is. I think you misunderstand. Ranges absolutely can be a source for streams, especially if they are arrays. The point is that the range *interface* doesn't make a good stream interface. So we need to invent new methods to access streams. Although I probably didn't communicate it very well, my idea was that since we already have functions like std.conv.parse that essentially provide parts of a stream interface on top of ranges, the most convenient way to implement a stream might be to build it on top of a range interface so no code duplication is needed. Create a range operation like "r.takeArray(n)". You can optimize it to take a slice of the buffer when possible. This is not a good idea. We want streams to be high performance. Accepting any range, such as a dchar range that outputs one dchar at a time, is not going to be high performance. If the function is optimized, it can essentially bypass the range layer and operate directly on the buffer while using the same interface it would use if it were operating on the range. As I understand it, some of the operations in Phobos do that as well when given arrays. On top of that, in some cases, the result will be a slice, in some cases it will be a copy. Generic code will have to figure out that difference if it wants to save the data for later, or else risk double copying. That could definitely be an issue. It should be possible to enforce slicing semantics somehow, but I'd have to think about it. Range operations like std.conv.parse implicitly progress their source ranges. That's not a range operation. Range operations are empty, popFront, front. Anything built on top of ranges must use ONLY these three operations, otherwise you are talking about something else. I guess that's not the right terminology for what I'm trying to express. I was thinking of "operations that act on ranges." From what I see, at least in terms of the interface, a stream is basically just a generalization of a range that supports more than one type as input/output. There's no reason that such a system couldn't be built on top of a range, especially when the internal representation is of a single type: characters. streams shouldn't have to support the front/popFront mechanism. empty may be the only commonality. I think that is an awkward fit for ranges. Certainly it is possible to take a *specific* range, such as an array, and add a stream-like interface to it. But not ranges in general. I hadn't considered the case of r.front; I was only thinking about r.popFront. Looks like they're a little more different than I was thinking, but they're still very similar under certain conditions. Ultimately, we do need some type of a traditional stream interface; I was just thinking about using ranges behind the scenes and using existing pieces of the standard library for stream operations rather than putting all of the operations into a unified data type. I'm not sure if it could really be called an "ideal" design, but I do think that it could provide a good minimalist solution with performance that would be acceptable for at least many applications.
Re: std.stream replacement
On Tuesday, 5 March 2013 at 16:12:24 UTC, Steven Schveighoffer wrote: On Tue, 05 Mar 2013 03:22:00 -0500, Jonathan M Davis wrote: In general, a stream _is_ a range, making a lot of "stream" stuff basically irrelevant. What's needed then is a solid, efficient range interface on top of I/O (which we're lacking at the moment). This is not correct. A stream is a good low-level representation of i/o. A range is a good high-level abstraction of that i/o. Ranges aren't necessarily higher- or lower-level than streams; they're completely orthogonal ways of looking at a data source. It's completely possible to build a stream interface on top of a range of characters, which is what I was suggesting. In that situation, the range is at a lower level of abstraction than the stream is. Ranges make terrible streams for two reasons: 1. r.front does not have room for 'read n bytes'. Making it do that is awkward (e.g. r.nextRead = 20; r.front; // read 20 bytes) Create a range operation like "r.takeArray(n)". You can optimize it to take a slice of the buffer when possible. 2. ranges have separate operations for getting data and progressing data. Streams by their very nature combine the two in one operation (i.e. read) Range operations like std.conv.parse implicitly progress their source ranges. For example: auto stream = file.byChars; while(!stream.empty) { doSomethingWithInt(stream.parse!int); } Except for the extra ".byChars", it's just as concise as any other stream, and it's more flexible than something that *only* provides a stream interface. It also saves some duplication of effort; everything can lean on std.conv.parse. Besides, streams don't necessarily progress the data; C++ iostreams have peek(), after all. From what I see, at least in terms of the interface, a stream is basically just a generalization of a range that supports more than one type as input/output. There's no reason that such a system couldn't be built on top of a range, especially when the internal representation is of a single type: characters.
std.stream replacement
While working on a project, I've started to realize that I miss streams. If someone's not already working on bringing std.stream up to snuff, I think that we should start thinking about to do that. Of course, with ranges being so popular (with very good reason), the new stream interface would probably just be a range wrapper around a file; in fact, a decent amount of functionality could be implemented by just adding a byChars range to the standard File struct and leaving the parsing functionality to std.conv.parse. Of course, there's no reason to stop there; we could also add socket streams, compressed streams, and just about any other type of stream, all without an especially large amount of effort. Unless someone already wants to tackle the project (or has already started), I'd be willing to work out at least a basic design and implementation.
Re: DIP23 draft: Fixing properties redux
On Monday, 4 February 2013 at 04:00:28 UTC, David Nadlinger wrote: On Monday, 4 February 2013 at 03:15:51 UTC, David Nadlinger wrote: And how often do you think you'll find yourself in the situation of needing to get a delegate from a property anyway? Can't we just make »@property getter expressions are always equivalent to their return value« a hard (simple!) rule and add something like __traits(propertyGetter, ...) for the rare cases where you really need to get hold of the underlying function? David I like this solution; it follows the Principle of Least Surprise quite well. The syntax may be a bit longer, but it's immediately obvious even to a beginning/intermediate D user what's going on without having to worry about too many nuances.
Re: Array in array
Ack! I just realized that this doesn't work because D isn't dynamically typed. I've had way too much Ruby on the brain lately... You could use std.variant to simulate dynamic typing, but can be a bit of a mess. You also could do something like this: int[][] a = [[1], [2, 3, 4], [5]]; That's also a bit ugly, though. In the end, you'll probably end up structuring your data in some other way. Next time I answer a question, I'd better make sure I'm thinking of the right language.
Re: Array in array
On Saturday, 27 October 2012 at 21:16:56 UTC, xfiles wrote: Hi everybody! I want create a multi array like python. For example(in python): a=[1,2] a.append([1234],3) a.append([[4],5],6) and result is = [1,2,[1234],3,[[4],5],6] How can I do this in D If you want to create it with one line, you can just write something like this: int[] a = [1,2,[1234],3,[[4],5],6]; To build the array by appending to it, the ~= operator appends to an array in place: int[] a = [1,2]; a ~= [[1234],3]; a ~= [[[4],5], 6]; You can also use the ~ operator: a = [1,2,3]; a = a ~ [4, 5]; //a is now [1,2,3,4,5] However, this is less efficient because it makes a copy of the original array. The ~ and ~= operators can also append individual values: a = [1]; a ~= 2; a ~= 3; //a is now [1,2,3]
Re: [just talk] what if implicitly typed literals were disallowed
And what about _transparent substitution_ of AA literals for a custom hash implementation? That would also be an excellent way to sidestep the current issues with AAs. The AA code would have to be heavily refactored, which could clean up the mess and probably get rid of a lot of bugs. It could also make performance tuning easier. Hopefully, this would make other aspects of the compiler and runtime simpler as well. I'm not sure how the optimizer would like the new system, though. It's likely that it would have to be beefed up, especially in the area of function inlining between compilation units.
Re: SQL working [ was Re: The sorry state of the D stack? ]
I've been thinking about writing an interface inspired by ActiveRecord. It would probably be relatively simple and lightweight, but it should be enough for simple REST applications, and the interface would (hopefully) be extremely nice to use. Of course, with all the other projects I want to do, I'm not sure how long this will live :).
Re: Rust and D
Looking at Rust's concurrency model, it does have some great ideas. I wonder what would happen if D used thread-local heaps... As far as syntax goes, the "shared" keyword could be used to distinguish between the heap types. I'm not sure how all this would work with "new", but I'm sure someone can think of a clean syntax. In all, it's an intriguing idea, and it could fit with D's current concurrency model extremely well. I can definitely see this breaking code, but not much more than the switch to TLS globals did. It might be something to consider eventually.
Re: getcwd behaves inconsistent?
Is there any chance of this code being added to Phobos? I think it would get a fair bit of use.