Re: Class inside a Struct?

2015-01-30 Thread Ary Borenszweig via Digitalmars-d-learn

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?

2015-01-30 Thread Ary Borenszweig via Digitalmars-d-learn

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?

2014-11-29 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-11-21 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-11-21 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-11-20 Thread Ary Borenszweig via Digitalmars-d-learn

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)

2014-09-04 Thread Ary Borenszweig via Digitalmars-d-learn

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)

2014-09-04 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-08-29 Thread Ary Borenszweig via Digitalmars-d-learn

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?

2014-08-21 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-08-12 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-08-06 Thread Ary Borenszweig via Digitalmars-d-learn

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?!)

2014-07-25 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-07-25 Thread Ary Borenszweig via Digitalmars-d-learn

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?!)

2014-07-24 Thread Ary Borenszweig via Digitalmars-d-learn

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?!)

2014-07-24 Thread Ary Borenszweig via Digitalmars-d-learn

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?

2014-07-16 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-07-11 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-06-28 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-06-28 Thread Ary Borenszweig via Digitalmars-d-learn

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!

2014-06-24 Thread Ary Borenszweig via Digitalmars-d-learn

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.

2014-06-23 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-05-15 Thread Ary Borenszweig via Digitalmars-d-learn

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

2014-05-13 Thread Ary Borenszweig via Digitalmars-d-learn

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?

2014-05-12 Thread Ary Borenszweig via Digitalmars-d-learn

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)

2014-05-04 Thread Ary Borenszweig via Digitalmars-d-learn

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/