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/
Generate toString() method at compile time
Hi, I'd like to generate a toString() method for my classes. For example: --- import std.stdio; class Foo { int x; int y; // mixin ...? } void main() { auto foo = new Foo; foo.x = 1; foo.y = 2; writeln(foo); // prints Foo(x = 1, y = 2) } --- I tried using getAllMembers, but that also gives me all methods of Foo. I just want the fields. I also tried FieldTypeTuple (http://dlang.org/phobos/std_traits.html#FieldTypeTuple) but I get that gives me the types. And then I can't find anything else in std.traits that could help me. Is this possible? Thanks, Ary
Re: Generate toString() method at compile time
On 3/26/14, 11:47 AM, Adam D. Ruppe wrote: On Wednesday, 26 March 2014 at 14:16:08 UTC, Ary Borenszweig wrote: I'd like to generate a toString() method for my classes. For example: Try this: override string toString() { import std.conv; string s; s ~= this.classinfo.name ~ (; foreach(idx, val; this.tupleof) { if(idx) s ~= , ; s ~= this.tupleof[idx].stringof[5 .. $]; s ~= = ; s ~= to!string(val); } s ~= ); return s; } add that method to Foo. $ ./test58 test58.Foo(x = 1, y = 2) Thanks! That's pretty neat. It seems I was missing tupleof.
Re: Generate toString() method at compile time
On 3/26/14, 11:47 AM, Adam D. Ruppe wrote: On Wednesday, 26 March 2014 at 14:16:08 UTC, Ary Borenszweig wrote: I'd like to generate a toString() method for my classes. For example: Try this: override string toString() { import std.conv; string s; s ~= this.classinfo.name ~ (; foreach(idx, val; this.tupleof) { if(idx) s ~= , ; s ~= this.tupleof[idx].stringof[5 .. $]; s ~= = ; s ~= to!string(val); } s ~= ); return s; } add that method to Foo. $ ./test58 test58.Foo(x = 1, y = 2) A small question: tupleof seems to return a tuple of values. So this.tupleof[idx] would return a value. However when you do this.tupleof[idx].stringof that somehow gets the name of the field. Shouldn't it return the name of the value? I'm confused.
Re: SysTime.add!days missing
On 3/17/14, 12:11 PM, Spacen Jasset wrote: On Monday, 17 March 2014 at 14:39:16 UTC, Adam D. Ruppe wrote: On Monday, 17 March 2014 at 14:31:54 UTC, Spacen Jasset wrote: Thanks. What devilish magic allows for the syntax 60.days? (how does it work) There's a function in core.time: Duration days(int n); D functions f(x, t...) can also be called x.f(t) (or x.f without parameters if there's no additional arguments). This works on all types, it is called uniform function call syntax, or UFCS. It lets us extend other things with new methods. Thanks Adam, is there a good explanation anywhere? It must be newish. http://dlang.org/function.html#pseudo-member
Question about dynamic arrays and slices
Hi, I just read this nice article about slices: http://dlang.org/d-array-article.html So I tried this code to see if I understood it correctly: --- import std.stdio; void main() { auto a = new int[5]; auto b = a; a[0] = 1; for(auto i = 0; i 100; i++) { a ~= 0; } a[0] = 2; writefln(a[0] = %d, a[0]); writefln(b[0] = %d, b[0]); } --- This prints: a[0] = 2 b[0] = 1 That is, a was resized to a point where it needed to reallocate its contents. b still holds a reference to the old data. When, after the for loop, I change a's data, b's data doesn't change. Is this expected behaviour? How can I safely pass around a dynamic array without being afraid someone will keep an old copy of the data?
Re: Keywords: How to trick the compiler?
On 1/28/14, 3:17 PM, Chris wrote: On Tuesday, 28 January 2014 at 17:18:44 UTC, Ary Borenszweig wrote: On 1/28/14, 11:30 AM, bearophile wrote: Ary Borenszweig: In Ruby you can do this: class Foo def end 1 end end Foo.new.end Ruby is a different language from D, they define code safety in quite different ways. Bye, bearophile Having a method named end doesn't make the language less safe. End is cumbersome and looks awkward. Sure there are other ways ;) Yes, as there are other ways for body: _body, _body, Body, HtmlBody, etc. But body is the best one.
Re: Keywords: How to trick the compiler?
On 1/28/14, 10:00 AM, Ola Fosheim Grøstad ola.fosheim.grostad+dl...@gmail.com wrote: On Tuesday, 28 January 2014 at 12:58:29 UTC, Stanislav Blinov wrote: I really wonder whether the rule could be relaxed a little bit. o_O How? If body never appears after a ., and is only before a { then there is no conflict? Exactly: body is only a conflict when appearing alone. But after a . it's perfectly fine. In Ruby you can do this: class Foo def end 1 end end Foo.new.end
Re: Keywords: How to trick the compiler?
On 1/28/14, 11:30 AM, bearophile wrote: Ary Borenszweig: In Ruby you can do this: class Foo def end 1 end end Foo.new.end Ruby is a different language from D, they define code safety in quite different ways. Bye, bearophile Having a method named end doesn't make the language less safe.
Re: universal databade connector as jdbc
On 12/11/13 8:05 AM, bioinfornatics wrote: On Wednesday, 11 December 2013 at 11:00:40 UTC, QAston wrote: On Wednesday, 11 December 2013 at 10:49:43 UTC, bioinfornatics wrote: Hi, Little question, I'm looking a jdbc like in D ? Does this exists ? Thanks https://github.com/buggins/ddbc - see readme for more info. Cool thanks, i will take a look. If in more it is able to run at comppile time that could be awesome I don't think you will ever be able to execute an SQL query at compile time...
Re: Is this reasonable?
On 12/5/13 2:15 PM, Steve Teale wrote: Here I feel like a beginner, but it seems very unfriendly: import std.stdio; struct ABC { double a; int b; bool c; } ABC[20] aabc; void foo(int n) { writefln(n: %d, aabc.length: %d, n, aabc.length); if (n aabc.length) writeln(A); else writeln(B); } void main(string[] args) { int n = -1; foo(n); } This comes back with B. If I change the test to (n cast(int) aabc.length), then all is well. Is this unavoidable, or could the compiler safely make the conversion implicitly? Cough, cough, make array length be an int. Do you really need arrays that big? :-S (I'm talking to Mr. D Compiler here)
Re: Is this reasonable?
On 12/5/13 4:59 PM, Maxim Fomin wrote: t and have these surprises all of the time just because a negative length doesn't make sense... I don't know, I feel it's not the right way to do it. ulong, it's the same thing.
Re: Comparison
On 11/26/13 7:00 PM, Namespace wrote: On Tuesday, 26 November 2013 at 21:37:49 UTC, Jonas Drewsen wrote: Isn't it a bug that the assertion is triggered for this: class Test3 {} void main() { assert( (new Test3()) == (new Test3()) ); } Tried it on http://dpaste.dzfl.pl/ as well. /Jonas Because your Test3 class has probably no own opEquals method, your comparison is the same as assert( (new Test3()) is (new Test3()) ); which is obviously wrong. See: https://github.com/D-Programming-Language/druntime/blob/master/src/object_.d#L116 The ddoc for the method is wrong. It should say something like: returns != 0 if this object has the same memory address as obj. Subclasses may override this method to provide custom equality comparison. Because for the OP, Test3 has the same contents as the other Test3 (both empty).
Re: How to make delegate refer to itself?
On 11/23/13 7:57 PM, H. S. Teoh wrote: void delegate(Event) dg = (Event e) { if (e == ...) queue.remove(dg); // NG: Still complains 'dg' isn't defined }; Split it in declaration and initialization: void delegate(Event) dg; dg = (Event e) { if (e == ...) queue.remove(dg); };
Re: OptionalT equivalent in D?
On 11/16/13 7:41 AM, Max Klyga wrote: On 2013-11-16 05:04:20 +, Jonathan M Davis said: I really don't understand this. OptionalT is one of the most useless ideas that I've ever seen in Java. Just use null. Optional specifies explicitly that value can be absent and forces client to check before using the value. Also, if Optional implements monadic interface one can easily chain computations depending on the state of optional values. Even if references are nullable by default users do not check them for null on every usage. NullPointerException and the like are almost always indicators of programming error. Null is just horrible. Null is only horrible if the compiler let's you dereference it... something that happens in almost every language out there.
Re: Is -1 7 ?
On 8/14/13 2:26 PM, Andre Artus wrote: On Sunday, 11 August 2013 at 17:01:46 UTC, Yota wrote: On Friday, 9 August 2013 at 17:35:18 UTC, monarch_dodra wrote: On Friday, 9 August 2013 at 15:28:10 UTC, Manfred Nowak wrote: michaelc37 wrote: WTF - -1 is greater than 7 From the docs: It is an error to have one operand be signed and the other unsigned for a , =, or = expression. -manfred Interesting. I didn't know it was documented as being an outright error, I thought it was just surprising... I don't think Walter will ever accept to make it illegal though, breaks too much code. If this was a change he was OK with, I think we would have had it since day one, or at least, years ago. I remember hearing somewhere that D is about enforcing users to write CORRECT code. I would really be disappointed with the language if this sort of gotcha weren't eliminated. If I look at this assert, I shouldn't be expecting it to pass. static assert(-1 cast(size_t)7); IMHO, as long as this sort of comparison causes a compile-time error, as the docs say they should, this kind of breaking change is the of very good sort. The sort that reveals bugs in code. (Like when they changed the NULL macro to mean 'nullptr' instead of 0 in C++.) I couldn't imagine a programmer exploiting this intentionally, as it serves no purpose. I agree, breaking changes that expose bugs in your code are the good kind. The time spent fixing compile time errors is more than compensated for by the time saved not having to hunt down those bugs. Having worked with languages where reference types are non-nullable by default I wish more languages did the same. Which are those languages? I'm interested.
Re: Associative array key order
On 7/31/13 12:05 PM, bearophile wrote: Daniel Kozak: is there a way for AA to behave same as PHP? D associative arrays are based on hashing, so they do not keep the order of the items. This is true in Python too. The Python standard library has a hash-based ordered dict that keeps the insertion order of the keys. There is no such data structure in Phobos. However in Ruby 1.9 they are ordered. You only need to store in each bucket entry a pointer to the next bucket. Then traversing the hash is super fast (just follow the links) while preserving insertion order. Accessing by key still uses the buckets and entries (if that's how AAs are implemented in D). I don't think adding a pointer to each bucket entry hurts performance that much, and having traversal by insertion order is pretty common (in my opinion). To see a sample code for this: https://github.com/manastech/crystal/blob/master/std/hash.cr#L28
Re: Associative array key order
On 7/31/13 12:56 PM, H. S. Teoh wrote: On Wed, Jul 31, 2013 at 12:51:25PM -0300, Ary Borenszweig wrote: On 7/31/13 12:05 PM, bearophile wrote: Daniel Kozak: is there a way for AA to behave same as PHP? D associative arrays are based on hashing, so they do not keep the order of the items. This is true in Python too. The Python standard library has a hash-based ordered dict that keeps the insertion order of the keys. There is no such data structure in Phobos. However in Ruby 1.9 they are ordered. You only need to store in each bucket entry a pointer to the next bucket. Then traversing the hash is super fast (just follow the links) while preserving insertion order. Accessing by key still uses the buckets and entries (if that's how AAs are implemented in D). I don't think adding a pointer to each bucket entry hurts performance that much, and having traversal by insertion order is pretty common (in my opinion). [...] It does. What do you do when you delete entries? T Sorry, I meant doubly-linked list. But yeah, two pointers seem now too much overhead.
Re: Source code output
On 7/17/13 4:33 AM, Jacob Carlborg wrote: On 2013-07-17 05:27, JS wrote: With heavy ctfe code generation usage is it possible to have the d compiler output the source code after all mixin templates have been used? This way it is easier to visually check for errors in the generated code. I imagine one could use pragma in a special way to do this but I was hoping for something more direct. The Eclipse plugin Descent had a nice compile time view. In general it showed how the compiler lowers some features to other lower level features. I.e. scope is lowered to try-catch-finally. It also showed the result of string and template mixins. It was really nice to have. Too bad the plugin was abandoned. It never got any real support for D2. Since Descent used a port of the D compiler to Java, I think the same can be done by tweaking dmd. You have the generated AST after semantic analysis and you can easily output that. But of course you need to be able to convert the AST to string with correct indentation. In general, I think a compiler should *really* care about setting line and column numbers to AST nodes and assisting the user as much as possible, like providing a way to output the final representation of the program as a String. For example compiling this program with D: --- string foo() { return void bar() {\n return 1 + 2\n}; } void main() { mixin(foo()); } --- gives this error: foo.d(7): Error: expression expected, not ')' foo.d(8): Error: found '}' when expecting ';' following statement foo.d(8): Error: found 'EOF' when expecting '}' following compound statement foo.d(7): Error: + has no effect in expression (1 + 2 + 0) Can you see where is the error? I'll show here some ideas which D can use, which we have implemented in Crystal. 1. Show errors in expanded macros: Compiling this (similar to D's string mixins): --- macro define_method(x) def #{x}(x, y) x + y + ) end end define_method hello --- Gives this error: Error in foo.cr:9: macro didn't expand to a valid program, it expanded to: 1. 2. def hello(x, y) 3. x + y + ) 4. end 5. Syntax error in expanded macro:3: unexpected token: ) x + y + ) ^ define_method hello ^ 2. The above should also work with semantic errors: --- macro define_method(x) def #{x}(x, y) x + y end end define_method hello hello(1, 'a') --- gives this error: Error in /Users/asterite-manas/Projects/crystal/foo.cr:11: instantiating 'hello(Int32, Char)' hello(1, 'a') ^ in macro 'define_method' /Users/asterite-manas/Projects/crystal/foo.cr:1, line 3: 1. 2. def hello(x, y) 3. x + y 4. end 5. x + y ^ no overload matches 'Int32#+' Overloads are: - Int32#+(other : UInt8) - Int32#+(other : UInt16) - Int32#+(other : UInt32) - Int32#+(other : UInt64) - Int32#+(other : Int8) - Int32#+(other : Int16) - Int32#+(other : Int32) - Int32#+(other : Int64) - Int32#+(other : Float32) - Int32#+(other : Float64) Couldn't find overloads for these types: - Int32#+(other : Char) --- If you don't provide clear errors for metaprogramming, even though it can be very powerful, if you don't understand the errors you go slower and slower and maybe eventually you decide not to use those features. For macros (string mixins), associate the AST nodes to virtual files whose source code is the expanded source code. Keep track of line *and* column numbers (lines alone are not enough when you have long lines).
Re: foreach over split string
On 7/17/13 11:38 AM, JS wrote: On Wednesday, 17 July 2013 at 14:18:25 UTC, John Colvin wrote: On Wednesday, 17 July 2013 at 14:09:28 UTC, JS wrote: Ok, spoke too soon again, my string requires compound splitting: foreach(ss; split(s, ,)) { split(ss, |); // ss can't be read at compile time although I can use ss directly string a = ss; // works fine. } Is there any possibility you could provide a compilable example (or not compilable, if that's the point :p )? It's an awful lot easier to quickly give the right answer to a question if you take the time to ask it clearly and precisely, in one go, with a minimised example. Also, by virtue of you having made an example and checked it, it prevents accidentally talking about problems in code that is actually fine. Yes, but if ctfe's wern't so shitty it wouldn't be a problem in the first place. If you think the language is shitty why are you using it? You didn't pay for D, you are receiving it as a free tool. I don't think many people will help you if you continue with that attitude -.-
Re: for loop parens
On 7/12/13 5:38 PM, ixid wrote: On Friday, 12 July 2013 at 20:30:59 UTC, bearophile wrote: ixid: Similarly what are D user's potential issues with Go-like semi-colon rules? And would this be possible as a subset of current D code? Such changes will not happen even in D4. Walter is strongly against the idea of optional semicolons, on the base that semicolons help the parser, so they allow better error recovery and error messages. Bye, bearophile Is there any evidence that these are issues in Go? That sounds like a theoretical objection that isn't attackable when no one has done it but turns out not to be terribly important when someone actually does it. They are not issues in Go, but Walter is strongly against optional semicolons, as bearophile said. Me and others (like you) like optional semicolons, but since Walter doesn't and it's his language, that will not change. I personally understand much better the code without semicolons, like in Ruby and Python. And making a parser that way isn't that much difficult, and error recovery is as powerful.
Re: static class
On 2/21/13 8:34 PM, Jonathan M Davis wrote: On Friday, February 22, 2013 00:06:26 bearophile wrote: Jonathan M Davis: D doesn't bother to check, so you get the natural consequence of mixing them. I'm quite sure that the fact that it works that way is an accident. It was never intentially made to be allowed or disallowed. It's just allowed, because there's nothing intrinsic about either of the attributes which makes it illegal, and no effort was made to do prevent it (it probably didn't even occur to Walter that anyone would do it). I'd expect it to continue to work though, since it doesn't really harm anything, According the way my brain works, sometimes I find the D compiler unnervingly sloppy. True enough, but in this case, I don't think that it's a problem. If the compiler gave you an error if you put static on a top-level class definition, this whole thread wouldn't exist. Don't you see that as a problem? People loosing their time answering this questions over and over again instead of the compiler giving you the answer.
Re: static class
On 2/17/13 7:25 PM, Jonathan M Davis wrote: On Sunday, February 17, 2013 23:00:19 Michael wrote: That's not the meaning of static in that context. As I understand a static class can't be instantiated. I have no idea how you came to that conclusion. Probably because of this: http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
Re: Enhancing foreach
On Thursday, 10 January 2013 at 17:36:15 UTC, Raphaël Jakse wrote: Le 10/01/2013 10:23, monarch_dodra a écrit : On Thursday, 10 January 2013 at 03:29:21 UTC, Peter Summerland wrote: The only thing I'd want to be able to do is: // foreach ( ; 0 .. 5) { writeln(hello); } // If I don't need a named variable, why force me to define a symbol? http://d.puremagic.com/issues/show_bug.cgi?id=9009 I know I could just use i and move on, but when code starts getting complex, and you already have i, j, k, ii, dummy etc..., it can make a difference. What about : foreach (0 .. 5) { writeln(hello); } ? What about: 5 { writeln(hello); } It could even work with floats! 1.5 { writeln(nice); } prints: nice ni
Re: noob Q: declaring string variables
On 05/29/2010 06:38 PM, Duke Normandin wrote: Back again... As an introductory tutorial, I'm now using: http://www.dsource.org/projects/tutorials/wiki/InitializingVariablesExample BTW, somebody fix that page - the `writefln' statements are missing the %d and %s. char[] password = sesame; didn't work on my MacOS X box. Why? Hi Duke, Why it didn't work? Please provide the error message the compiler gave you, otherwise it's hard to reproduce and know exactly what the problem is.
Re: Example in the overview
Walter Bright wrote: bearophile wrote: Walter Bright: Are you sure? What's the mistake in the code? This is the code in the Overview, it prints 1899: http://codepad.org/lzRtggEL This is the code I have suggested in bugzilla, it prints 1027: http://ideone.com/D9ZqQ Wolfram Alpha says they are 1027 (I have left out the last number because Alpha uses a closed interval) http://www.wolframalpha.com/input/?i=primes+in+2+..+8190 It's been printing 1899 primes since the 80's. Just for fun, google [sieve of eratosthenes 1899 primes] A small observation: count +=1 is performed for i = 0, hmmm...
Re: Export values (enum, int, char[]...) for DLL
Nrgyzer wrote: Hello everybody, I'm trying to create a (very) simple DLL by using D. Now I want export values - is there any way do this... for example: Example: mydll.d: export int i; mydll2.d: export int i = 99; dll.d: // Copied from http://www.digitalmars.com/d/2.0/dll.html test.d: import std.stdio; import mydll; void main() { writefln(mydll.i); } - The problem is (same problem for float, enum... , that I always get 0 by calling mydll.i instead of 99. I hope anyone can help me, please :) Thanks for help in advance :) I don't know much about dlls, but aren't you accessing mydll.i, which is 0, instead of mydll2.i, which is 99?
Re: ctfe library
Ellery Newcomer wrote: Are there any good libraries for ctfe/code generation? I don't know, things like parsing support for compile time strings, string formatting, type - string My project seems to be growing ctfe, and it's all horribly hacky and ugly code. I think all ctfe code is horrible hacky and ugly code. :-P
Re: ctfe library
Ellery Newcomer wrote: Are there any good libraries for ctfe/code generation? I don't know, things like parsing support for compile time strings, string formatting, type - string My project seems to be growing ctfe, and it's all horribly hacky and ugly code. I think all ctfe code is horribly hacky and ugly code. :-P
Re: Code speed
bearophile wrote: Ary Borenszweig: My point is, if you are going to pow, you will need std.math, so it'll always be a burden to import it by hand when using it. ^^ Can the automatic import happen only iff a module uses the ^^fp? Bye, bearophile That's what I'm asking for.
Re: Code speed
Don wrote: Lars T. Kyllingstad wrote: Don wrote: bearophile wrote: So far I've just given a light reading of the code. Notes: - pow(x, 2) and sqrt(y) can be written as x ^^ 2 and y ^^ 0.5 (but you have to import std.math anyway, because of a bug). That's not a bug. It's intentional. x ^^ y will probably always require import std.math, if y is a floating point number. Really? Why is that? I find that kind of disappointing, I always believed it to be a temporary solution. I think the inconsistency with the other operators will make this a major WTF for people new to the language. Why should a^^b require an explicit import while a*b doesn't? Because pow() for floating point, when implemented properly, is a HUGE function, that ends up dragging almost all of std.math into the executable. And I think it's deceptive to do that silently. To make it completely built-in, basically all of std.math would need to be moved into druntime. Feel free to try to change my mind, of course. Is there a better way to do pow() for floating point numbers without importing std.math? I see this: 1. You want to do x ^^ fp. 2. The compiler complains saying if you want to do that, import std.math. I'm telling you this just to let you know you'll be importing the whole module. Alternative 1 for user: User says Ok, I import std.math Alternative 2 for user: User says No way I'm importing std.math just to make a pow. But... I still *need* to make that pow... what is your advice, mr. compiler?
Re: Code speed
Don wrote: Ary Borenszweig wrote: Don wrote: Lars T. Kyllingstad wrote: Don wrote: bearophile wrote: So far I've just given a light reading of the code. Notes: - pow(x, 2) and sqrt(y) can be written as x ^^ 2 and y ^^ 0.5 (but you have to import std.math anyway, because of a bug). That's not a bug. It's intentional. x ^^ y will probably always require import std.math, if y is a floating point number. Really? Why is that? I find that kind of disappointing, I always believed it to be a temporary solution. I think the inconsistency with the other operators will make this a major WTF for people new to the language. Why should a^^b require an explicit import while a*b doesn't? Because pow() for floating point, when implemented properly, is a HUGE function, that ends up dragging almost all of std.math into the executable. And I think it's deceptive to do that silently. To make it completely built-in, basically all of std.math would need to be moved into druntime. Feel free to try to change my mind, of course. Is there a better way to do pow() for floating point numbers without importing std.math? I see this: 1. You want to do x ^^ fp. 2. The compiler complains saying if you want to do that, import std.math. I'm telling you this just to let you know you'll be importing the whole module. Alternative 1 for user: User says Ok, I import std.math Alternative 2 for user: User says No way I'm importing std.math just to make a pow. But... I still *need* to make that pow... what is your advice, mr. compiler? That's a good point, it should be possible to use a static import as well. I do think it's pretty odd to be doing floating point without importing std.math, though. I mean, abs() is absolutely fundamental. But if you do a static import the whole module gets linked in, right? My point is, if you are going to pow, you will need std.math, so it'll always be a burden to import it by hand when using it. ^^
Re: Tidy attributes
bearophile wrote: While looking for possible attribute problems to add to Bugzilla, I have seen the following D2 program compiles and runs with no errors or warnings: static foo1() {} final foo2() {} ref foo3() {} enum void foo5() {} nothrow foo4() {} pure foo6() {} static int x1 = 10; static x2 = 10; void main() {} I don't like that code, but I don't know if it's correct. - What is a static global function in D? - A final global function? - Is that ref of void correct? (I think it is not) - A enum of void function? - What are global static variables in D? - Are most of those attributes supposed to not need the void? The following lines don't compile, is this supposed to be correct? int static x3 = 10; int enum x4 = 1; int const x5 = 2; Bye, bearophile I have discussed this subject many times, but it doesn't seem very important to the D dev team. IIRC they said it doesn't cause any harm. But in some real code I have seen: static int foo() { ... } in global scope, and I always wondered why was that static there. Maybe the programmer thought static implied something there and now he's using it incorrectly, and now it confused me too and probably many others. So I think it is harmful because if the compiler allows such things than programmers can assume that must mean something.
Re: interface problem
Trass3r wrote: Cast the instance to the base class and call the method? Surprisingly this does compile. What are the rules for casting between classes? Normally you can cast A to B if B inherits from A. But this seems not to be the case in D. The following compiles without complains: import std.stdio; interface I { } class A : I { } class B { } int main() { I i = new A(); A a = cast(A) i; B b = cast(B) i; // shouldn't compile B c = cast(B) a; // shouldn't compile writeln(a); writeln(b); writeln(c); return 0; } And prints: main.A null null I'll move this to another thread.
Casts that makes no sense (!)
The following compiles: import std.stdio; interface I { } class A : I { } class B { } int main() { I i = new A(); A a = cast(A) i; B b = cast(B) i; // shouldn't compile B c = cast(B) a; // shouldn't compile writeln(a); writeln(b); writeln(c); return 0; } But two lines there doesn't make sense: B b = cast(B) i; An instance of I can never be a B, so why the cast is allowed? B c = cast(B) a; An instance of A can never be an A, so why the cast is allowed? I think these casts should result in an error. This can prevent some bugs. Java and C# work like that. You can't cast an object of instance of type A to type B if both types are classes and B isn't a supertype or subtype of A.
Re: Casts that makes no sense (!)
Steven Schveighoffer wrote: On Mon, 08 Mar 2010 10:12:53 -0500, Ary Borenszweig a...@esperanto.org.ar wrote: Steven Schveighoffer wrote: On Mon, 08 Mar 2010 09:38:08 -0500, Ary Borenszweig a...@esperanto.org.ar wrote: An instance of A can never be an A, so why the cast is allowed? Aside from the typo, I agree with you there, this should never be possible, because a derived class can not inherit both B and A. Where's the typo? An instance of A can never be an A Obviously you meant an instance of B :) -Steve Aaaah... I was looking for the typo in the code
Re: Is there a reason for default-int?
Don wrote: Phil Deets wrote: On Mon, 28 Dec 2009 16:18:46 -0500, Simen kjaeraas simen.kja...@gmail.com wrote: Apart from C legacy, is there a reason to assume anything we don't know what is, is an int? Shouldn't the compiler instead say 'unknown type' or something else that makes sense? C++ abandoned default int. I think it would be best for D to do the same. D never had default int. When there's an error, the compiler just has to choose *some* type, so that it doesn't crash g. It could be an Error type (that's not an alias for int type) that don't start to spit errors everywhere and instead just blocks all further errors on that type.
Re: Is there a reason for default-int?
Don wrote: BCS wrote: Hello Ary, Don wrote: Phil Deets wrote: On Mon, 28 Dec 2009 16:18:46 -0500, Simen kjaeraas simen.kja...@gmail.com wrote: Apart from C legacy, is there a reason to assume anything we don't know what is, is an int? Shouldn't the compiler instead say 'unknown type' or something else that makes sense? C++ abandoned default int. I think it would be best for D to do the same. D never had default int. When there's an error, the compiler just has to choose *some* type, so that it doesn't crash g. It could be an Error type (that's not an alias for int type) that don't start to spit errors everywhere and instead just blocks all further errors on that type. that poses an interesting question: what type does this this give? int i; char[] s; int foo(int); char[] foo(int,char[]); int[] foo(char[],int); auto whatType = foo(i ~ s, s); i~s gives the error type but DMD could tell that as long as the other args are correct, the only foo that works returns a char[] so does the variable get the error type or char[]? Error. Exactly! You would get an error saying i ~ s cannot happen, then it resolves to the Error type. Now resolution of foo is not done (or yes: it defaults to Error) because it has an argument of type Error (one less error in the console is shown). Since foo is error, whatType is Error. Then if whatType is used it won't trigger errors. Etc. You would get a single error in the precise position you need to correct it, instead of one error hidden with other many unrelated errors.
Re: Explicit ordering with std.format
bearophile wrote: Tomek Sowiñski: How do I achieve this with std.format? I think you can't (and I haven't had the need to do it). It's somtimes needed with I18N code.
Re: How do I find the arity of an Expression? (dmd hacking)
Chad J wrote: Given an Expression object in dmd, I'd like to know how many subexpressions it contains and, even better, iterate over them. I'd like to do this in a general way, without having to create cases for all of the different kinds of Expressions. Is there some way to do this that I've been missing? Thanks, - Chad Where's the Expression object defined in D? I don't think there's such a thing (I mean, a reflection capability to get an expression out of something).
Re: How do I find the arity of an Expression? (dmd hacking)
Ellery Newcomer wrote: On 11/30/2009 12:32 PM, Chad J wrote: Ellery Newcomer wrote: On 11/30/2009 03:53 AM, Ary Borenszweig wrote: Chad J wrote: Given an Expression object in dmd, I'd like to know how many subexpressions it contains and, even better, iterate over them. I'd like to do this in a general way, without having to create cases for all of the different kinds of Expressions. Is there some way to do this that I've been missing? Thanks, - Chad Where's the Expression object defined in D? I don't think there's such a thing (I mean, a reflection capability to get an expression out of something). DMD source, eg parse.c, expression.c, etc Right. That. Not that I know anything about DMD outside parse.c, but in expression.h, there be decls along the lines of struct UnaExp{ Expression* e1; } struct BinExp{ Expression* e1; Expression* e2; } Iterating them would just be a tree walk. That takes care of 90% and ... Oh. Yeah. There are a bunch of special cases. But from what I've seen, iterating over an expression or any part of the AST involves implementing a function (like semantic) at each subclass. I'm betting there is no other way to do this. I love ANTLR. It generates an arbitrary child/sibling AST, and walking it is a piece of cake. It would be better if dmd's source code implemented the visitor pattern. Descent's port implements it and it uses it a a lot of places.
Re: Class templates deriving from base class
Michael Mittner wrote: Hi! I'm trying to do something like this (in D1): class Foo { // ... } class Bar(T) : Foo { // ... } alias Bar!(int) IntBar; alias Bar!(Mars) MarsBar; void main() { Foo x = new MarsBar(); } Common base class, one derived template class and a bunch of aliases that are then actually used in the code. But it seems like deriving a template class from a non-template one doesn't work. Is this supposed to work, am I doing something wrong or am I out of luck here? -Mike Hi Mike, Why do you mean with doesn't work? If I define class Mars {} and compile your program it gives no error. Can you show the error the compiler is giving you? (you normally past the compiler output if a program doesn't compile so that others can help you faster... but in case it compiles, weird :-P)
Re: How to set non-static variable in static method within class
Sam Hu wrote: Greetings! How to set value to non-static variable in a static method within a class? Given below code: import std.stdio; class InputDialog { string name; static string s_name; static this() { s_name=; } static string getString(string prompt=Please enter a line of string below, string defaultValue=your string here) { defaultValue=dataFromConsole();//console input s_name=defaultValue; return s_name; } } int main(string[] args) { string str=InputDialog.getString; writefln(You entered %s,str); return 0; } This works.But what if actually I want to set non-static variable name other than static variable s_name in static method getString(...)? How can I do that? Thanks for your help in advance. Regards, Sam You can't access non-static data from a static method. Non-static data is related to an instance of a class, and a static method is not bound to any instance. Why do you want to do that?
Re: Possible?
Simen Kjaeraas wrote: Ary Borenszweig a...@esperanto.org.ar wrote: How can I know at compile time if all of the following are true for a given symbol s: 1. s is a function 2. the return type is a class that extends from class foo.Bar 3. the function has three arguments and it is not variadic 4. the first argument is an int 5. the second argument is a struct 6. the third argument is an associative array with char[] key and float value C f1( int a, S b, float[ char[] ] c ) { return null; } D f2( int a, S b, float[ char[] ] c ) { return null; } C f3( long a, S b, float[ char[] ] c ) { return null; } C f4( int a, string b, float[ char[] ] c ) { return null; } C f5( int a, S b, float[ const char[] ] c ) { return null; } E f6( int a, string b, float[ char[] ] c ) { return null; } E f7( int a, S b, float[ const char[] ]c ) { return null; } C f8( T... )( int a, S b, float[ char[] ] c, T args ) { return null; } template check( alias f ) { pragma( msg, (f).stringof[2..$] ); pragma( msg, isFunction: ~ is( typeof( f ) == function ).stringof ); pragma( msg, isvariadic: ~ to!string( ParameterTypeTuple!( f ).length != 3 ) ); pragma( msg, Derived from C: ~ is( ReturnType!( f ) : C ).stringof ); pragma( msg, p1 == int: ~ is( Unqual!( ParameterTypeTuple!( f )[0] ) == int ).stringof ); pragma( msg, p2 == struct: ~ is(ParameterTypeTuple!( f )[1] == struct ).stringof ); pragma( msg, p2 == float[ char[] ]: ~ is(ParameterTypeTuple!( f )[2] == float[char[]] ).stringof ); } mixin check!( f1 ); mixin check!( f2 ); mixin check!( f3 ); mixin check!( f4 ); mixin check!( f5 ); mixin check!( f6 ); mixin check!( f7 ); mixin check!( f8!( int ) ); Cool, thanks! I just wanted to see how you deal in D with all these reflection stuff. I think it's very bad that you have to look at is, typeof, std.traits and std.conv to accomplish such things (very hard to find if you don't ask here) and also that (f).stringof[2..$] is very misterious... It would be nice to have a uniform syntax for this.
Possible?
How can I know at compile time if all of the following are true for a given symbol s: 1. s is a function 2. the return type is a class that extends from class foo.Bar 3. the function has three arguments and it is not variadic 4. the first argument is an int 5. the second argument is a struct 6. the third argument is an associative array with char[] key and float value
Re: anonymous function/deleget usage
bearophile wrote: Steven Schveighoffer: int c = (){return a + b;}(); You can also write: int c = {return a + b;}(); Bye, bearophile Shorter: int c = a + b;
Re: Descent eclipse plugin - auto code completion
Joel Christensen wrote: I've got one project working ok, but not another. Things like working at the start of the main function but not at the end, and not in other functions. Hi Joel, Do you have something in the Error Log (Window - Show View - Error Log)? How is your project configured? Do you have phobos or Tango in the include path?
Re: version specific enum members
Ellery Newcomer wrote: Phil Deets wrote: Hi, is there a way to add members to an enum based on conditional compilation symbols. I tried enum Tag { A, B, version (symbol) { C, D, } E, } but it doesn't work. I know I could do version (symbol) { enum Tag { A, B, C, D, E } } else { enum Tag { A, B, E } } but I don't want to do that since in my case, there can be quite a few elements outside of the version, and I don't want to repeat them all. Unfortunately, that's going to be about the best you can do, unless you're willing to play with string mixins and their ilk. Or unless you create an enhancement request. That seems a very valid one.
Re: Forward references and more
Steven Schveighoffer wrote: On Mon, 12 Oct 2009 05:26:58 -0400, bearophile bearophileh...@lycos.com wrote: What's wrong with this code? struct MemoryPool(T) { alias T[100_000 / T.sizeof] Chunk; Chunk*[] chunks; } struct Foo { int x; MemoryPool!(Foo) pool; } void main() {} It prints Error: struct problem.Foo no size yet for forward reference. T.sizeof must be 8 in all cases. The compiler does this: Instantiate MemoryPool!(Foo) But for that it needs to know Foo.sizeof. But for that it needs to know MemoryPool!(Foo).sizeof. But for that it needs to instantiate MemoryPool!(Foo) and find it's size. etc. I can see MemoryPool!(Foo) sizeof doesn't depend at all of T.sizeof because it just has a pointer. But how do you suggest to fix the compiler to understand that? What I can see is that to know MemoryPool!(Foo).sizeof the type of the alias doesn't need to be solved completely... but what would you recommend the compiler to do?
Re: How about macro == symbol for mixin statement? [was Re: Member functions C to D]
Jarrett Billingsley wrote: On Thu, Oct 8, 2009 at 11:25 AM, Don nos...@nospam.com wrote: Jarrett Billingsley wrote: On Thu, Oct 8, 2009 at 4:00 AM, Don nos...@nospam.com wrote: So it looks to me like the mechanics of it are basically identical. Just Nemerle's syntax is nicer. Only with trivial examples. With more complicated examples they look less identical. I'm basing my views on pages like this: http://nemerle.org/Macros_-_extended_course._Part_2 Unless I'm totally misunderstanding this, it looks to me as though Nemerle macros are implemented as compiler plugins. All the advanced facilities are obtained by exposing the compiler's API! Well they're not.. plugins per se as much as compiled modules. Okay yes that's basically a plugin :P But it's not that different from D, where you use compile-time executed functions to do the same sorts of things. It's just that you precompile those functions instead of having the compiler compile them on every compilation. No. CTFE is simply taking constant-folding to its logical conclusion. All the Nemerle *implementation* is doing differently here is having you precompile the functions that are to be executed at compile-time. That's it. The resultant semantics are utterly the same. You are running code at compile-time, it doesn't matter if that code is running on the hardware or in a VM in the compiler. But really, I don't see how this is significantly different from hooking into the D compiler's internals with __traits, .stringof, .mangleof and the like. So it uses an object-oriented API to access those things instead of ad-hoc hacks. And? The thing I think is elegant about D's approach, ugly as the syntax currently is, is the complete separation of the lex - parse - semantic - codegen phases. And I think CTFE is fantastic (and I plan to fix it so it works properly). Think about how easy it is to explain. And Nemerle's macros are *hard* to explain? They're a function that executes at compile time. Oh, wait! That's exactly the same as CTFE. I don't know how you can trash Nemerle's approach while leaving D's unmentioned. What do you mean, 'unmentioned'? Hey, you started this by trashing D's approach! I'm not talking about me. I'm talking about you. I don't know how you can trash a language with macros that were designed *from the bottom up* to be used as such and which are treated as first-class citizens, while not admitting the hilariously ad-hoc nature of a language where macros fall out as a consequence of a number of other, ill-defined poorly-implemented unorthogonal features. Sigh, I'm done. I agree with Jarrett here. And also seeing how some things are implemented in D using CTFE and .stringof and it's parsing is very complex to understand. I mean, I read the code and it's very hard for me to understand what's going on. Specially because it's mostly all of the time parsing strings and extracting information which I don't know in what format it comes in the first place, it's just guess and work around it.
Re: looking for an IDE
Trass3r wrote: Phil Deets schrieb: I tried Descent, but it didn't work well at all with my D2 program. It also didn't support building. I'll look into Poseidon. Thanks. D2 support isn't that good in Descent yet. Exactly. I think the parser is ported up to 2.030 but I didn't test it a lot and now I don't think I'll touch descent for at least three months.
Re: Cannot convert of type HANDLE to HANDLE
Sam Hu escribió: div0 Wrote: You must have two different HANDLEs around. The one in phobos is aliased to void* and there is no LoadLibraryEx call in phobos, so you must be using something else. Try using the FQN of the import where you are getting the LoadLibraryEx from. Thanks for your help. Yeah.I use DFL plus win32 package(http://www.dsource.org/projects/bindings/wiki/WindowsApi). import dfl.all; import Win32=win32.windows; Now it got compiled and ran,but all main functions wrote in win32 API did not work(I mean does nothing),almost just a functionless Form. PS.For *FQN of the import*,what do you mean? FQN = Fully Qualified Name
dmd deps switch
Hi, I'm trying to fetch a module's dependencies with the deps switch, but it gives me an empty list. dmd main.d -deps=foo.txt foo.txt is empty. main.d is: --- module main; import other; int main(char[][] args) { someVariable = 3; return 0; } --- and someVariable is defined in other. What am I doing wrong?
Re: Template mixins: Why is the decision to mixin made at the call site?
div0 wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jarrett Billingsley wrote: On Fri, Aug 21, 2009 at 1:36 PM, div0d...@users.sourceforge.net wrote: That's what he's suggesting, and it does make sense. When you write a template, *either* it's meant to be used as a mixin, *or* it's meant to be used some other way. Mixin in a template that wasn't meant to be a mixin or vice versa usually makes no sense. Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both. Can you provide an example?
Re: Template mixins: Why is the decision to mixin made at the call site?
div0 wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Ary Borenszweig wrote: div0 wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jarrett Billingsley wrote: On Fri, Aug 21, 2009 at 1:36 PM, div0d...@users.sourceforge.net wrote: That's what he's suggesting, and it does make sense. When you write a template, *either* it's meant to be used as a mixin, *or* it's meant to be used some other way. Mixin in a template that wasn't meant to be a mixin or vice versa usually makes no sense. Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both. Can you provide an example? Yeah, but it's Friday night, I'm drinking beer now. :o I'll do it tomorrow. Bills response is the start of it though. Ah, it's ok, I saw Bill's answer later.
Re: At compile time
bearophile escribió: Jarrett Billingsley: C++ has static initialization that occurs before main() too. It's just.. hidden. I see. I have to learn more about C++. Thank you. -- Lars T. Kyllingstad: This is good news! The restrictions you are referring to, are they any of the ones documented here: http://www.digitalmars.com/d/2.0/function.html#interpretation That list has a point regarding what I was trying to do: 4. the function may not be a non-static member, i.e. it may not have a this pointer It's true regarding stucts used as values too, and not just classes... It would be nice if the compiler could say so: I can't evaluate it because you are using a this pointer. With other words, but much more useful than non-constant expression.
Re: byte to char safe?
Harry escribió: Again hello, char[6] t = ragain ~ cast(char)7 ~ rhello; If you want the result to be again7hello, then no. You must do: char[6] t = ragain ~ '7' ~ rhello; or: char[6] t = ragain ~ (cast(char)('0' + 7)) ~ rhello;
Re: aa bug?
Saaa escribió: struct S { int i; } S[char[]] aa; void main() { aa[test].i = 10; } Error: ArrayBoundsError D1.046 looks like a bug to me or can't structs be aa's? But you never inserted anything in aa[test]. You must do: S s; aa[test] = s; aa[test].i = 10; or: S s; s.i = 10; aa[test] = s;
Re: How to see result of a mixin? (equivalent of running C preprocessor)
asd wrote: I'm trying to get D-ObjC bridge working and I'm getting weird errors triggered somewhere deeply in a mix of templates and mixins that's too hard for me to understand. How can I analyze such problem in D? Is it possible to tell dmd to run only compile-time functions/templates and output that as a D source? You can debug templates and mixins using Descent: http://dsource.org/project/descent
Re: How to see result of a mixin? (equivalent of running C preprocessor)
Ary Borenszweig wrote: asd wrote: I'm trying to get D-ObjC bridge working and I'm getting weird errors triggered somewhere deeply in a mix of templates and mixins that's too hard for me to understand. How can I analyze such problem in D? Is it possible to tell dmd to run only compile-time functions/templates and output that as a D source? You can debug templates and mixins using Descent: http://dsource.org/project/descent I mean... http://dsource.org/projects/descent
Re: XML D2.x parsing amp;
Brad Roberts escribió: Jarrett Billingsley wrote: On Tue, Jul 21, 2009 at 11:53 PM, Brad Robertsbra...@puremagic.com wrote: Jesse Phillips wrote: On Wed, 22 Jul 2009 01:37:38 +0100, Stewart Gordon wrote: Jesse Phillips wrote: According to the documentation having amp; in a tag will be turned to http://digitalmars.com/d/2.0/phobos/std_xml.html#text I observe that this is not the case. And if an attribute contains amp; it is turned into amp;amp; What is the best way to receive the same output for both. The code that follows outputs Attr: What amp;amp; Up Elem: What amp; Up *testfile.xml:* ?xml version=1.0 encoding=utf-8? Tests Test thing=What amp; UpWhat amp; Up/Test /Tests Clearly std.xml is buggy. Correct behaviour would be Attr: What Up Elem: What Up The best place for bug reports is http://d.puremagic.com/issues/ Stewart. http://d.puremagic.com/issues/show_bug.cgi?id=3200 http://d.puremagic.com/issues/show_bug.cgi?id=3201 The xml parsing code in D2 could use some love and care. It was originally written by Janice who seems to have dropped off the face of the planet. It's little more than a first draft with serious performance problems and several important bugs. Anyone want to volunteer to invest some time in improving it? I don't mean to shoot down the idea? But Tango already has three XML parsers which are, like, the fastest. Ever. http://dotnot.org/blog/archives/2008/03/04/xml-benchmarks-updated-graphs/ I'm just saying, it'd seem like pointless duplication of effort with such parsers _already available_. If it could be relicensed, I'd say that's the best route. Relicensed and separable from the rest of Tango. It's been way too long since I looked at that code in Tango to recall any of its details. Basically I agree with you on this one. :) Can't just phobos dissappear? :-( Like... it must be the first standard library in the world that's developed by 3-5 people.
Re: There is not std.stdio.flush
Lars T. Kyllingstad wrote: Lars T. Kyllingstad wrote: Haruki Shigemori wrote: Hi. The std.cstream.dout has a member function dout.flush. But the std.stdio has not a function flush or a similar function. Why? Don't you want to have it? Give me the std.stdio.flush! All the write functions in std.stdio (write, writeln, writef, writefln) flush automatically, so there is no need for a separate flush function. -Lars Sorry, my mistake. It seems only writef and writefln flush automatically. :( I don't think so. If I run my code in the Eclipse console it doesn't flush automatically and I have to do fflush(stdout). I think it depends on the console implementation.
Re: How to release memory? (D2.0.30)
AxelS escribió: BCS Wrote: You can't. The D runtime (and most other runtimes) don't ever reduce the amount of memory they keep in the heap. If you where to allocate another 25MB right after that function you would see no change in the memory usage. The good news is that with virtual memory, all of that has almost zero cost. What matters is how much ram you are actively using. I want to load and send a file via network...when I load the entire file into memory it's very stupid that I can't release that memory again... Why not pipe it?
Re: Cross-references in ddoc
Robert Clipsham escribió: Ary Borenszweig wrote: I've seen both Tango and phobos documentation and it's really hard to navigate. Consider this: class HttpPost { void[] write(Pump pump) } Pump has no link on it. I can't tell what Pump is. I can see the source code (in the web page) invokes super.write(pump), or something like that, so I go to HttpClient and there it's not defined. Tangos docs are generated with dil, which currently has limited semantic analysis, so adding a link isn't possible yet. Once dil gets more semantic analysis I believe links will be added in. I open Tango's source code and I find this: alias void delegate (IBuffer) Pump; So some questions: 1. (minor problem) Why isn't this appearing in the documentation? I'd like an answer to this too, it's a pain to have to look at the source code to find something simple like this. 2. (major problem) How do you expect users to use your code if they can't know what a given method accepts, or what that type is, or how to find where a type that's returned by a function is defined? Don't the docs already give this? (Except where it's defined, which isn't possible due to the aforementioned reason) I mean, you can click on the type to see it's documentation. It would also be nice if, if the type is an alias, show the alias resolution when hovering it. Documentation is *really* important when programming. 3. Is this a limitation in ddoc? It's a limitation in dil. dmd does not have the same limitations, however I've never needed to generate any docs so can't say much here. 4. Is there a tool to generate documentation with cross-references? dmd probably can do this, again I've never done it so don't know. No, it doesn't. I think it doesn't because semantic analysis isn't run when generating docs. 5. Would it help if Descent generated cross-referenced documentation for a project? I'm sure someone would find it useful to be able to click a button to generate documentation rather than hit a terminal and enter a command. You are right. :) I'll try to work on something... Thanks for your answers, Robert!
Re: help with c translation
Lars T. Kyllingstad escribió: robby wrote: i'm using D1/Tango. sorry, im not sure to how to explain the error messages, but if you need to look a t full code, here is the link http://www.ibsensoftware.com/download.html thanks again. Several places in that code, I notice things like this: const type foo; ... foo = bar; I have no idea why this works in C, but in D it certainly doesn't. Well, it should work! const means, once a value is assigned to that variable, it never changes again. The compiler can do static analysis to verify this. And that's why it works. And that's why D should also work this way, IMHO.
Re: alias foo this compiles when foo is not defined
Stewart Gordon escribió: Jarrett Billingsley wrote: On Fri, Jun 26, 2009 at 5:54 PM, Ary Borenszweiga...@esperanto.org.ar wrote: Is is ok that this compiles without errors? class Foo { alias errorProne this; } Errors as expected on 1.042; compiles on 2.029. If I had to guess, it's only OK because the compiler probably doesn't actually look for the aliased symbol until you actually try to access something from it. But that does seem .. wrong. It is wrong. Since this isn't in a template, the compiler should perform semantic analysis on it in any case, and thus report an error. But the really strange thing is that it doesn't complain about the attempt to redefine 'this', which is a keyword. It's called alias this, that's not the problem: http://digitalmars.com/d/2.0/class.html#AliasThis I also think it should complain, because it makes no sense to just leave it there, unresolved.
Re: Object.factory create instance failed?
Sam Hu escribió: John C Wrote: Object.factory requires a fully qualified class name, so if class Dog resides in module animals, call Object.factory(animals.Dog). It works now.Great!Thanks so much! But...may I ask how do you know that?(requires full name).I went through the object.di but nothing relative found. There: http://d.puremagic.com/issues/show_bug.cgi?id=3093
Re: Expanded source code
Paul D. Anderson wrote: Paul D. Anderson Wrote: Is there a way to see the source for a D program after the mixins and templates, etc., are expanded? I get occasional error messages saying I've got incompatible types, for example, but the error message only makes sense when I mentally instantiate a template. Is there a way to see this instantiation in print? At what phase of compilation does this occur? Has the code been tokenized? (It's okay with me if it is--I just want to know.) Paul Thanks for the help. So the short answer is no. I thought the short answer was yes. Did you try Descent? You can hover a template instance to see it's expansion. Same goes with mixins. Doesn't this help you?
Re: is this right??
BCS escribió: Hello Ary, BCS escribió: Hello BCS, void main() { int s; mixin(s) = 5; } - Line 4: found '=' when expecting ';' http://www.digitalmars.com/d/1.0/expression.html#MixinExpression (mixin(s)) = 5; Given that the above works, it looks like the parser prematurely commits to a mixin declaration when it finds mixin ( at function scope. Unless someone spots a flaw in this, I'll post a bug. Yes, at that point the parser is parsing statements, so if it finds a mixin(...) it turns it into a statement. http://d.puremagic.com/issues/show_bug.cgi?id=3073 Hope you don't mind me quoting you. Not at all! But later when I went to sleep I thought about that a little more, and look at this: 1. mixin(int x = 2;); 2. mixin(x = 2); The first should be treated as a MixinStatement, because it ends with a semicolon. The second should be treated as a MixinExpression, because it doesn't end with a semicolon (and it's a perfectly valid expression, it's an assign expression). But according to my patch it'll be treated as a statement and it'll fail. Now this: 3. mixin(int x = 2); is neither of them. You can only deduce that information if you can extract the contents of the mixin, paste it in the source file and treat the whole line as a statement, and you'd get things right. But now all of those lines can be: mixin(secret()); and now you don't know, you'll have to wait for semantic anlaysis to know that, but then it's too late. But I think my patch is reasonable because it allows you to do more things than before, it's backwards compatible and also you'd almost never do number 2 but instead use number 1.
Re: Expanded source code
BCS escribió: Reply to Paul, Is there a way to see the source for a D program after the mixins and templates, etc., are expanded? Descent has a compile time view that is supposed to do some of this. If you are only looking at string mixins you can use pragma(msg, string) to view the string I get occasional error messages saying I've got incompatible types, for example, but the error message only makes sense when I mentally instantiate a template. You can also debug the template instantiation with Descent. But only for D1, aw...
Re: Inside the switch statement
grauzone wrote: BCS wrote: Hello grauzone, http://groups.google.com/group/net.lang.c/msg/66008138e07aa94c Many people (even Brian Kernighan?) have said that the worst feature of C is that switches don't break automatically before each case label. Oh god, that's from 1984, and even today we're struggling with this bullshit in the most modern dialect of C, D. I'm sorry, you don't have my sympathy on this one. There are to many place I've used fall throught to chuck it out. What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break; The solution is to forbid fallthrough, and change the switch syntax: switch(value) { case 1: case 2: // something break; } gives: Error, missing break at the end of case1. But: switch(value) { case 1, 2: // something break; } works as expected. What's wrong with that?
Re: Inside the switch statement
Saaa wrote: What kind of fall-throughs were these? A: case value1: case value2: case valueN: code1(); break; B: case value1: code1(); case value2: code2(); break; The solution is to forbid fallthrough, and change the switch syntax: switch(value) { case 1: case 2: // something break; } gives: Error, missing break at the end of case1. But: switch(value) { case 1, 2: // something break; } works as expected. What's wrong with that? Doesn't support B :) How about a warning instead? The idea is that it not supporting B is something good. An error is ok, and if you want to translate C code then it's really easy to change the code to not give errors.
Re: Inside the switch statement
Saaa wrote: How do you know? BCS didn't reply to my idea. Your idea was to give an error on the case (B) he uses. Or did I miss something? You missed the alternative syntax to get the same behaviour. But it's a very subtle difference.
Re: Inside the switch statement
Saaa wrote: You missed the alternative syntax to get the same behaviour. But it's a very subtle difference. Do you mean the multiple cases? http://www.digitalmars.com/d/1.0/statement.html#SwitchStatement Yes, but make the multiple cases the *only* way to make case statements fallthrough. That would be the change.
Re: Inside the switch statement
Saaa wrote: Yes, but make the multiple cases the *only* way to make case statements fallthrough. That would be the change. That is the same as giving an error on case B, right? Well, yes, but you also have to prepare your mind for the change. This is a huge step. (nah, just kidding, you're right, I didn't realize it :-P)