Re: Class inside a Struct?
On 1/30/15 5:28 PM, Ali Çehreli wrote: On 01/30/2015 11:59 AM, chardetm wrote: struct Container { private RedBlackTree!int _rbtree = new RedBlackTree!int; I think you are expecting the new expression to be be executed for every object individually. It is not the case: That new expression determines the initial value of the _rbtree for every single object of type Container. As a result, they will all be sharing the same tree. The best solution is 1) Remove the new expression: 2) Use a static opCall: Why not use this() ?
Re: Class inside a Struct?
On 1/30/15 7:29 PM, Ali Çehreli wrote: On 01/30/2015 01:28 PM, Ary Borenszweig wrote: On 1/30/15 5:28 PM, Ali Çehreli wrote: On 01/30/2015 11:59 AM, chardetm wrote: struct Container { private RedBlackTree!int _rbtree = new RedBlackTree!int; I think you are expecting the new expression to be be executed for every object individually. It is not the case: That new expression determines the initial value of the _rbtree for every single object of type Container. As a result, they will all be sharing the same tree. The best solution is 1) Remove the new expression: 2) Use a static opCall: Why not use this() ? In fact, I think a better solution is to use a constructor that takes the tree: this(RedBlackTree!int rbtree) // -- good practice // (parameterize from above) { _rbtree = rbtree; } However, I thought that OP did not want the users know about that member. So, as you say, the next option that comes to mind is to use the default constructor: this() { _rbtree = new RedBlackTree!int; } Unfortunately, D does not allow defining the default constructor for structs: Error: constructor deneme.Container.this default constructor for structs only allowed with @disable and no body The reason is, the default constructor happens to be the .init value of that type and it must be known at compile time. Ali Thanks for explanation. I was sure there was some reason why you didn't suggest it. It's an unfortunate inconsistency, I think. I don't know why `.init` is so important or why the default value of a type has any importance at all.
Re: Why the DMD Backend?
On 11/29/14, 3:48 PM, ketmar via Digitalmars-d-learn wrote: On Sat, 29 Nov 2014 15:37:32 + Joakim via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: build time for the whole DMD compiler with standard library, using G++: 100 seconds. yea, no kidding. gdc: i don't even want to think about that, way t long. ldc: not that long as gcc, but still much longer than DMD. I haven't timed it, but compiling ldc feels about 50-100% longer to me, which isn't too bad. Unless you're including the time to compile llvm, which is a different story. at least 80%-100% longer. this is noticable. besides, i don't want to use anything llvm-related. Why not?
Re: write multiple lines without \n with writeln
On 11/21/14, 1:59 PM, Marc Schütz schue...@gmx.net wrote: On Friday, 21 November 2014 at 15:00:31 UTC, ketmar via Digitalmars-d-learn wrote: On Thu, 20 Nov 2014 14:23:23 -0300 Ary Borenszweig via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: This way you avoid silly typing mistakes while at the same time you allow splitting a string across several lines without having to concatenate them at runtime. i bet that current D frontend is able to concatenate string literals in compile time. AFAIK yes. There was a change to guarantee that string literals concatenated by ~ are joined at compile time. The goal was to deprecated concatenation by juxtaposition, which hasn't happened yet, though. What's concatenation by juxtaposition?
Re: write multiple lines without \n with writeln
On 11/21/14, 2:46 PM, Adam D. Ruppe wrote: On Friday, 21 November 2014 at 17:43:27 UTC, Ary Borenszweig wrote: What's concatenation by juxtaposition? When foo bar turns into foobar. The two string literals are right next to each other, no operator or anything else in between, so they are combined. Ah, I see. Yes, I guess that's a bug-prone thing to have. And since there's already `~` to concatenate strings (even at compile time) removing that feature would be good.
Re: write multiple lines without \n with writeln
On 11/20/14, 9:05 AM, uri wrote: On Thursday, 20 November 2014 at 10:41:24 UTC, bearophile wrote: uri: It's by design And it's a nice handy design. Bye, bearophile For Wysiwyg strings I agree that it's great but I prefer C/C++/Python like behaviour for double quoted strings. I guess it's what I'm used to :) Cheers, uri In Crystal we chose the following: you can have two consecutive string literals but only if they are separated by a `\` at the end of the line. So this is a syntax error: foo(bar baz) But this is ok: foo(bar \ baz) Likewise, this is an error: [foo, bar baz, qux] # most probably we forgot to add a comma But this is ok: [foo, bar \ baz, qux] This way you avoid silly typing mistakes while at the same time you allow splitting a string across several lines without having to concatenate them at runtime.
Re: Allowing Expressions such as (low value high)
On 9/4/14, 5:03 PM, Nordlöw wrote: Are there any programming languages that extend the behaviour of comparison operators to allow expressions such as if (low value high) ? This syntax is currently disallowed by DMD. I'm aware of the risk of a programmer misinterpreting this as if ((low value) high) Is this the reason why no languages (including D allows it). I'm asking for in some cases, where value is a long expression, it would be a nice syntatic sugar to use. Crystal has that syntax: ~~~ def foo puts Computing! a = 0 10.times do |i| a += i end a end if 0 foo = 45 puts Yes end ~~~ Prints: Computing! Yes That's because the middle expression in the comparison is first assigned to a temporary variable, so `foo` is only invoked once. This makes both the code more readable, efficient and saves the programmer from having to save that value to a temporary variable itself. I guess D doesn't have it because it has (...why?) to be compatible with C's semantic. Also, as you can see, it's not that trivial to implement because you need to assign that value first to a temporary variable.
Re: Allowing Expressions such as (low value high)
On 9/4/14, 7:03 PM, Nordlöw wrote: On Thursday, 4 September 2014 at 22:02:20 UTC, Nordlöw wrote: D can also, in this case, do (or will do) common sub-expression elimination because it has a strict memory model (const and immutability) and function purity (template inference). Correction: foo cannot be pure in this case. But I believe your example is misguiding in this case. The most common use case for this is when foo is pure. No, why? ~~~ min_alert_level = 5 max_alert_level = 10 if min_alert_level compute_current_alert_level max_alert_level send_email end ~~~ I don't see anything wrong with that code.
Re: DMD Compiler - lexer
On 8/29/14, 10:41 AM, Mike James wrote: Hi, Looking at the DMD Source Guide it says The lexer transforms the file into an array of tokens. Why is this step taken instead of, say, just calling a function that returns the next token (or however many required for the look-ahead)? Regards, -=mike=- I believe this is just an abstract description of how it works. It actually uses something like next token with a freelist of tokens if it needs to do some lookahead. https://github.com/D-Programming-Language/dmd/blob/master/src/lexer.h#L260 https://github.com/D-Programming-Language/dmd/blob/master/src/lexer.h#L261 https://github.com/D-Programming-Language/dmd/blob/master/src/lexer.h#L237
Re: Auto-add static field when inherit // mixins, templates?
On 8/21/14, 6:38 AM, MarisaLovesUsAll wrote: tl;dr - how to get child classname from inherited parent function at compile time? class A { string getName(); }; class B { }; B foo = new B; assert(foo.getName() == B); ... Hi! I'm stuck at one issue, and I don't know how to solve it. I think this is about mixins/templates, isn't it? When inherit from base class Component, I need to auto-create child own static fields with child type. It should look like this, after compilation: class Component { //it doesn't matter to have any fields here //but it's important to be able to create an instance of Component //and when inherit, all childs will get their own static T list; where T is a type of child. }; class Sprite:Component { static Sprite list; //auto-added static void fun() { } //auto-added, operates with Sprite } class Camera:Component { static Camera list; //auto-added static void fun() { } //auto-added, operates with Camera instead of Sprite } ... //so this must be correct: Component foo; Sprite bar; void foobar(Component one) { } foobar(Sprite); ... Sorry for bad English. Best regards, Alex I'll tell you how it's done in Crystal in case someone wants to come up with a proposal to make it work in D. ~~~ class Foo macro inherited def method_in_{{@class_name.downcase.id}} puts Hello {{@class_name.id}}! end end end class Bar Foo end Bar.new.method_in_bar #= Hello Bar! ~~~ When you inherit a class, the macro inherited is automatically executed by the compiler in the context of the inheriting class. There you can use special variables like @class_name and interpolate them with {{ ... }}. I guess a similar thing to do in D would be to define a function to be executed at compile time and automatically mix it, and the context of execution would be the inherited class. (sorry if this is of no interest to all of you, let me know if I should stop trying to bring ideas to D from other languages)
Re: implicit conversion
On 8/12/14, 6:31 PM, H. S. Teoh via Digitalmars-d-learn wrote: On Tue, Aug 12, 2014 at 08:23:30PM +, Jonathan M Davis via Digitalmars-d-learn wrote: On Tuesday, 12 August 2014 at 19:03:58 UTC, H. S. Teoh via Digitalmars-d-learn wrote: tl;dr: there are so many ways template code can go wrong, that I don't it justifies blaming alias this for problems. Allowing implicit conversions makes the problem much worse IMHO. It makes it far too easy to write a template constraint which passes due to the implicit conversion (even if an implicit conversion wasn't explicitly checked for) but then have the function fail to work properly because the implicit conversion never actually takes place within the function (and if the template constraint doesn't explicitly test for an implicit conversion, then the argument that the value should have been explicitly converted doesn't hold). Fortunately, in many cases, the result is a compilation error rather than weird behavior, but in some cases, it will be weird behavior - especially when the code involved is highly templatized and generic. [...] Y'know, after seeing the recent problem with deprecated functions in template code... Duck typing FTW
Re: Associative value order
On 8/6/14, 2:59 PM, H. S. Teoh via Digitalmars-d-learn wrote: On Wed, Aug 06, 2014 at 05:54:23PM +, Patrick via Digitalmars-d-learn wrote: I know that there is no prescribed order that the .values array will be sorted in, however I'm curious if the order is deterministic based on keys. If I have two associative arrays with strings for keys and ints for values and they each have an identical set of keys, would the .values property return the values in the same order? In the current implementation, yes. But I think it's a bad idea to rely on that, since a future implementation might no longer do this. (E.g., if we use a different hash collision resolution algorithm that is sensitive to insertion order.) It is probably safest to make an array of keys with .keys, and sort the array in the order you want. T Why is a dictionary something built-in the language? Can't it be some standard library class/struct with syntax sugar for creation? All of these questions about associative arrays wouldn't exist if the source code for these operations was available. (it's probably available, but buried in some C++ code, I guess, on in dmd?)
Re: D JSON (WAT?!)
On 7/25/14, 1:06 PM, Justin Whear wrote: On Thu, 24 Jul 2014 22:00:43 +, Pavel wrote: On Thursday, 24 July 2014 at 16:09:25 UTC, Justin Whear wrote: On Thu, 24 Jul 2014 16:04:01 +, Pavel wrote: Thanks to all you folks who explained in operator for me. My bad. Let's focus on the real problem, which is JSON wrapper class. Is it needed? Wouldn't it be better to get AA from parseJSON? The following are valid JSON: auto json1 = parseJSON(`1`); auto json2 = parseJSON(`foo`); auto json3 = parseJSON(`[1, 2, 3]`); None of these fit naturally into an JSONValue[string] return type. Now we figured it out about JSON, but in that case: Why not just use std.variant.Variant construct instead of JSONValue? While I suspect the reason is simply historical, it might be a type- safety/information problem as well. Variant can store values of essentially any type whereas JSON is strictly limited to a handful of simple types. Going from a JSON string to Variant might not be troublesome, but going from Variant to JSON string almost certainly would. That said, if you think it's worth it, I'd be up for reviewing a revamped std.json. Or use Algebraic, but it currently doesn't support recursive type definitions. I think this would be the best way.
Re: myrange.at(i) for myrange.dropExactly(i).front
On 7/25/14, 6:39 PM, Jonathan M Davis wrote: On Friday, 25 July 2014 at 21:33:23 UTC, Timothee Cour via Digitalmars-d-learn wrote: Is there a function for doing this? myrange.at(i) (with meaning of myrange.dropExactly(i).front) it's a common enough operation (analog to myrange[i]; the naming is from C++'s std::vectorT::at) That would require a random access range, in which case you can just index directly. For a non-random access range, which you're doing would be the most direct way of doing it. - Jonathan M Davis No, the OP said the meaning was `myrange.dropExactly(i).front`, which is not a random access. Sometimes you *do* want the n-th element of a range even if the range is not a random access.
Re: D JSON (WAT?!)
On 7/24/14, 1:09 PM, Justin Whear wrote: On Thu, 24 Jul 2014 16:04:01 +, Pavel wrote: Thanks to all you folks who explained in operator for me. My bad. Let's focus on the real problem, which is JSON wrapper class. Is it needed? Wouldn't it be better to get AA from parseJSON? The following are valid JSON: auto json1 = parseJSON(`1`); auto json2 = parseJSON(`foo`); auto json3 = parseJSON(`[1, 2, 3]`); None of these fit naturally into an JSONValue[string] return type. Nope, a JSON can only be an array or an object (hash). In Crystal we have this definition: alias JsonType = Nil | Bool | Int64 | Float64 | String | Array(JsonType) | Hash(String, JsonType) (note that this is a recursive type definition) Then when you do Json.parse you get a value whose type is Array(JsonType) | Hash(String, JsonType). The good thing about this is that Json.parse gives you types that already exist: Array, Hash, Int64, etc. No need to define extra types and no need for users to learn a new API with new types. Wouldn't something like this be better to do in D? That is, return something that is an array or an associative array...
Re: D JSON (WAT?!)
On 7/24/14, 1:58 PM, Justin Whear wrote: On Thu, 24 Jul 2014 13:49:27 -0300, Ary Borenszweig wrote: Nope, a JSON can only be an array or an object (hash). Ary, can you point out the place in the spec where this is specified? Not to be pedantic, but the spec only seems to define a JSON value, not a JSON document. You are right, my bad. According to Wikipedia (which has links to RFCs): Early versions of JSON (such as specified by RFC 4627) required that a valid JSON document must consist of only an object or an array type—though they could contain other types within them. This restriction was relaxed starting with RFC 7158, so that a JSON document may consist entirely of any possible JSON typed value.
Re: md5 hashing acting strangly?
On 7/16/14, 10:22 AM, bearophile wrote: Kagamin: Report for the problem when a temporary fixed-size array is assigned to a slice, which is escaped. I think this is already in Bugzilla. But the point is: you can't solve this problem locally and with small means. You need a principled solution (or no solution at all, as now) of memory area lifetime management, as discussed in the scope threads. Bye, bearophile When assigning a fixed size array to a slice, can't you just allocate memory and copy the data there (I mean, let the compiler do that in that case)? That would be safe, right?
Re: get number of items in DList
On 7/11/14, 4:46 AM, bearophile wrote: pgtkda: How can i get the number of items which are currently hold in a DList? Try (walkLength is from std.range): mydList[].walkLength Bye, bearophile So the doubly linked list doesn't know it's length? That seems a bit inefficient...
Can't modify this
This doesn't work: class Foo { this() { this = new Foo; } } Error: Cannot modify 'this' However you can do this: class Foo { this() { auto p = this; *p = new Foo(); } } It even changes the value of this! Should that compile? I mean, it's the same as modifying 'this'...
Re: Can't modify this
On 6/28/14, 6:21 PM, H. S. Teoh via Digitalmars-d-learn wrote: On Sat, Jun 28, 2014 at 05:40:19PM -0300, Ary Borenszweig via Digitalmars-d-learn wrote: This doesn't work: class Foo { this() { this = new Foo; } } Error: Cannot modify 'this' However you can do this: class Foo { this() { auto p = this; *p = new Foo(); } } It even changes the value of this! Should that compile? I mean, it's the same as modifying 'this'... I'd say, file an enhancement request on the bug tracker. However, there comes a point, where given enough indirections, it would be infeasible for the compiler to figure out exactly where everything points, and so you'll be able to circumvent the compiler check somehow. If you're out to thwart the compiler, then eventually you will succeed, but it begs the question, why? T I think that if you disallow taking the address of `this`, then the problem is solved. This is not a big issue (more a curiosity). I just wanted to know what is the correct way to do in this case.
Re: Another rambling musing by a Dynamic Programmer - map!
On 6/24/14, 4:13 PM, Jacob Carlborg wrote: On 2014-06-24 04:34, John Carter wrote: So in Ruby and R and Scheme and... I have happily used map / collect for years and years. Lovely thing. So I did the dumb obvious of string[] stringList = map!...; And D barfed, wrong type, some evil voldemort thing again. So.. auto stringList = map!; and we're good.. and happily use it as foreach( s; stringList) Suddenly the words in the map! documentation made sense to me... unlike Ruby, map doesn't allocate and populate an array. It just returns a lazy range. No array is allocated (unless I ask for one), it just does the lambda when I want it in the foreach! Cool! Very very cunning. Very light on resources. I wished Ruby behaved that way quite often, especially when chaning multiple functions. In Ruby 2.0 there are lazy map and similar functions but I've heard they are slower than the eager ones. My guess is that it's slower because it's implemented using fibers, so you loose a lot of time creating the fiber and switching contexts. But in this way any Enumerable can be turned into a lazy one. I think they could optimize it for arrays by, for example, making a specific Enumerator without the need to use fibers. In fact, I tried this in Crystal and I got performance similar to that of D. So you get the best of both worlds: you can either choose to always return an array, or to lazily apply transformations to it. I find returning an array to be more intuitive and easier to reason about.
Re: Momentary Eh?! for a Dynamic Language Programmmer. Tuples vs Arrays. Just rambling.
On 6/23/14, 6:18 PM, John Carter wrote: I guess between perl and Ruby and Scheme etc. I got used to creating hybrid containers Want a pair of [string, fileList]? Just make an Array with two items, one a string, one and array of strings. Done. D barfed... leaving me momentarily stunned... then Oh Yes, type safety, Tuple's are the answer where Tuples where Tuples... Eventually found http://dlang.org/tuple.html and more specifically the somewhat unexpectedly named http://dlang.org/phobos/std_typecons.html and off I went... I do have a personal design guideline of when you adding too much behaviour to a heterocontainer, refactor into a class. But I guess I have never realised how often I do casually create heterogenous containers Just rambling and musing. Union types are very common (I use them every day), and IMHO it's very nice to have them included in the language (either built-in or as a library solution). As a library solution I would do something like this: Union!(int, string)[] elements; elements ~= 1; elements ~= hello; auto x = elements[0].cast!(int); // etc. The difference with Variant is that (I think) Variant allows any kind of type to be inserted into it, but for a Union you are just limited to a set of types. For example, the following would be a compile-time error: elements[0].cast!(float); // error, Union!(int, string) doesn't include float As a built-in way the way to use it would be much nicer, but of course it involves too many changes for that to happen...
Re: Array!T and find are slow
On 5/15/14, 1:31 AM, Jonathan M Davis via Digitalmars-d-learn wrote: On Thu, 15 May 2014 01:29:23 + Kapps via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: On Wednesday, 14 May 2014 at 23:50:34 UTC, Meta wrote: On the topic of lazy, why *is* it so slow, exactly? I thought it was just shorthand for taking a function that evaluates the expression, and wrapping said expression in that function at the call site. That is, I thought that: int doSomething(lazy int n) { return n(); } Was more or less equivalent to: int doSomething(int function(int) n) { return n(); } It's more equivalent to: int doSomething(int delegate(int) n) { return n(); } And (I could be very likely wrong here), I believe that it's expensive because it's not scope and possibly requires a closure. Again, very likely may be wrong. Yeah. It generates a delegate. You even use the value internally as a delegate. So, that's definitely part of the problem, though IIRC, there were other issues with it. However, I don't remember at the moment. The big one IIRC (which may be due to its nature as a delegate) is simply that it can't be inlined, and in many cases, you very much what the code to be inlined (enforce would be a prime example of that). enforce(cond, failure); really should just translate to something close to if(!cond) throw new Exception(failure); but it doesn't do anything close to that. Isn't there a way in D to just expand: enforce(cond, failure); (or something with a similar syntax) to this, at compile-time: if(!cond) throw new Exception(failure); I thought D could do this, so enforce should do this instead of using lazy arguments.
Re: RegEx for a simple Lexer
On 5/13/14, 5:43 PM, anonymous wrote: On Tuesday, 13 May 2014 at 19:53:17 UTC, Tim Holzschuh via Digitalmars-d-learn wrote: If I also want to create a RegEx to filter string-expressions a la xyz , how would I do this? At least match( src, r^\ (.*) $\ ); doesn't seem to work and I couldn't find in the Library Reference how to change it.. I think he's confusing r... with a regular expression literal (I also confused them)
Re: Templating everything? One module per function/struct/class/etc, grouped by package?
On 5/12/14, 5:37 AM, JR wrote: Given that... 1. importing a module makes it compile the entirety of it, as well as whatever it may be importing in turn 2. templates are only compiled if instantiated 3. the new package.d functionality ...is there a reason *not* to make every single function/struct/class separate submodules in a package, and make *all* of those templates? Unnused functionality would never be imported nor instantiated, and as such never be compiled, so my binary would only include what it actually uses. Welcome to Crystal :-) In Crystal, every function and method is templated. When you compile your program, only what you use gets compiled. A simple hello world program is just 16KB. And contrary to what Jonathan M. Davis says, compiling programs is very fast. In fact, compilation times might indeed be faster, because you don't need to compile unused code. And the resulting binary is as small as possible. And the error messages are pretty good, also. But D has an entirely different philosophy, so I don't think they will like it. I also once suggested auto for parameters, but they didn't like it. I'm just saying this to say that yes, it's possible, and no, it doesn't hurt compilation times or error messages.
Re: C++ std::map equivalent? (An in-order iterable associative container)
On 5/4/14, 6:04 PM, Mark Isaacson wrote: I'm looking for a means to associate a key with a value and iterate over said container in-order. My natural choice in C++ would be std::map. When I look in std.container, I see that there is a RedBlackTree implementation, however this does not associate a key with a value (it is the equivalent of std::set). My question is essentially what the best/most idiomatic way to represent this is in D? I don't think there's an idiomatic way to do it in D. You'll probably have to create a class for it (and I think it would be good if D included such class in the standard library so nobody does this job twice). You can copy what Ruby (and Crystal :-P) does: a hash table where each entry has reference to the previous and next entries, in the way they were inserted. That way the entries form a doubly-linked list. You get in-order iteration cost and also amortized O(1) insertion/lookup. When you need to delete a key you'd repoint the previous/next pointers (that's why you need the previous pointer). Here's some code you can copy from: https://github.com/manastech/crystal/blob/master/src/hash.cr And here an article about how they added this notion of order to Ruby hashes from 1.8 to 1.9: http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/