Re: Associative arrays with keys containing mutable indirections

2017-10-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/30/17 6:49 AM, Tony wrote:
I prefer the built-in associative array over using some template 
library. It has the clean look and ease-of-use that you get with a 
similar data structure in dynamic languages like Python. I consider it a 
top feature of D.


There is a misunderstanding here. The goal is to replace the 
implementation of the builtin AA with a template implementation. Right 
now there are some "magic" pieces of the AA that are helped by the 
compiler. If we can do this all in a template library, then the syntax 
doesn't change at all, but now you have better abilities to customize 
the builtin AAs, or use more specialized templates in some cases.


-Steve


Re: Associative arrays with keys containing mutable indirections

2017-10-30 Thread Tony via Digitalmars-d-learn
I prefer the built-in associative array over using some template 
library. It has the clean look and ease-of-use that you get with 
a similar data structure in dynamic languages like Python. I 
consider it a top feature of D.





Re: Associative arrays with keys containing mutable indirections

2017-10-29 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, October 29, 2017 22:24:57 Nordlöw via Digitalmars-d-learn wrote:
> Shouldn't associative arrays with key types (K) having mutable
> indirections (std.traits.hasAliasing!K) such as
>
>  string[ubyte[]]
>
> be disallowed?
>
> If not, in what cases do we want this?

Well, the built-in associative arrays _are_ kind of a mess (though the
situation has improved somewhat over time), but the way that this was
handled does make _some_ sense, even if it's still not correct. If you had
something like

string[ubyte[]] aa;
pragma(msg, (typeof).string);

This will print

string[const(ubyte)[]]

So, similar to C++'s std::map, const gets added for you underneath the hood
for the keys, which does prevent _some_ bad assignments. Unfortunately,
that's still not enough - it really should be immutable. For instance,

void main()
{
string[ubyte[]] aa;
ubyte[] a = [1, 2, 3];
aa[a] = "hello";
}

fails to compile and gives the error

q.d(5): Error: associative arrays can only be assigned values with immutable 
keys, not int[]

but this code

void main()
{
string[ubyte[]] aa;
ubyte[] a = [1, 2, 3];
const b = a;
aa[b] = "hello";
}

does compile. So, the way it handles this avoids forcing you to explicitly
put the const or immutable on the key type, which makes for less typing, but
the fact that it's using const and not immutable is definitely a bug. Based
on the error message, clearly it was acknowledged that the keys need to be
immutable, but clearly that hasn't quite made it how the rest of it was
implemented. IIRC, the implementation using void* and casts everywhere, so
it's pretty trivial for it to break the type system if anything gets screwed
up.

But as I said, the built-in AAs are a mess. They work reasonably well for
basic cases but start falling apart when you do stuff like use classes for
keys. While the situation is better than it used to be, historically, we've
had tons of bugs in the implementation, and overall, I'd argue that having
AAs in the language was a mistake. It probably made more sense in the D1
days, but at this point, the only real advantage over a library type is that
the built-in AAs work with AA literals, and a library type wouldn't (though
with a solid DIP, I'm sure that that could be fixed).

Work has been done on templatizing the AA implementation, which should help,
but we'd be much better off sorting out a proper library type and
encouraging its use. One of the suggestions of how to improve things has
been to restrict keys for the built-in AAs to simpler types (e.g. no
classes), but there hasn't been agreement on that, and we'd actually need a
proper library type in Phobos before doing something like that (and the
situation with Phobos and containers is its own mess).

The whole AA mess comes up probably just about every dconf, and I expect
that it will be sorted out eventually, but when that will be, I don't know.
A big part of the question is what's going to happen with Martin's work on
templatizing the implementation. It may be that that can salvage things, but
in the interim, bugs in in the built-in AAs are no surprise. If anything,
it's probably a miracle that they work as well as they do.

- Jonathan M Davis




Re: Associative arrays

2015-11-09 Thread TheFlyingFiddle via Digitalmars-d-learn

On Monday, 9 November 2015 at 04:52:37 UTC, rsw0x wrote:
On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole 
wrote:
Fwiw, EMSI provides high quality containers backed by 
std.experimental.allocator.

https://github.com/economicmodeling/containers


I have a question regarding the implementation of the 
economicmodeling hashmap. Why must buckets be a power of two? Is 
it to be able to use the: hash & (buckets.length - 1) for index 
calculations or is there some other reason?


Re: Associative arrays

2015-11-09 Thread Brian Schott via Digitalmars-d-learn

On Tuesday, 10 November 2015 at 01:29:11 UTC, Brian Schott wrote:
Yes. It's a hack that gives you a modulus without having to do 
a modulus. It only works on powers of two.


http://graphics.stanford.edu/~seander/bithacks.html#ModulusDivisionEasy


Re: Associative arrays

2015-11-09 Thread TheFlyingFiddle via Digitalmars-d-learn

On Monday, 9 November 2015 at 04:52:37 UTC, rsw0x wrote:
On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole 
wrote:

On 09/11/15 4:57 PM, TheFlyingFiddle wrote:

[...]


Nope.


[...]


As far as I'm aware, you are stuck using e.g. structs to 
emulate AA behavior.
I have a VERY basic implementation here: 
https://github.com/rikkimax/alphaPhobos/blob/master/source/std/experimental/internal/containers/map.d

Feel free to steal.


Fwiw, EMSI provides high quality containers backed by 
std.experimental.allocator.

https://github.com/economicmodeling/containers


Thanks for the suggestions. I also made a hashmap using 
allocators some time ago that I use in-place of the built in 
hashmap for most of my purposes. The syntax of a custom hash map 
is somewhat lacking in comparison to the built in one however and 
I was hoping that I could either make the built in work with 
allocators or replace it with my own implementation.


In addition to this I am building a pointer patching binary 
serializer and I hoped that I could make it work with the built 
in aa without requiring to many gc allocations.


The economicmodeling one seems interesting ill try it out and see 
if it's better then the one I am currently using.





Re: Associative arrays

2015-11-09 Thread rsw0x via Digitalmars-d-learn

On Monday, 9 November 2015 at 21:33:09 UTC, TheFlyingFiddle wrote:

On Monday, 9 November 2015 at 04:52:37 UTC, rsw0x wrote:
On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole 
wrote:
Fwiw, EMSI provides high quality containers backed by 
std.experimental.allocator.

https://github.com/economicmodeling/containers


I have a question regarding the implementation of the 
economicmodeling hashmap. Why must buckets be a power of two? 
Is it to be able to use the: hash & (buckets.length - 1) for 
index calculations or is there some other reason?


I have no idea, sorry.
Schott wrote them AFAIK, he might be able to respond if he sees 
this.


Re: Associative arrays

2015-11-09 Thread Brian Schott via Digitalmars-d-learn

On Monday, 9 November 2015 at 21:33:09 UTC, TheFlyingFiddle wrote:

On Monday, 9 November 2015 at 04:52:37 UTC, rsw0x wrote:
On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole 
wrote:
Fwiw, EMSI provides high quality containers backed by 
std.experimental.allocator.

https://github.com/economicmodeling/containers


I have a question regarding the implementation of the 
economicmodeling hashmap. Why must buckets be a power of two? 
Is it to be able to use the: hash & (buckets.length - 1) for 
index calculations or is there some other reason?


Yes. It's a hack that gives you a modulus without having to do a 
modulus. It only works on powers of two.


Re: Associative arrays

2015-11-08 Thread Rikki Cattermole via Digitalmars-d-learn

On 09/11/15 4:57 PM, TheFlyingFiddle wrote:

I have a few questions about the pseudo built in associative arrays.

1. Is it possible to have the built in associative array use a custom
allocator from std.experimental.allocator to service it's allocation needs?


Nope.


2. A while ago I read on the newsgroup a while back that there was a
plan to make it possible for a user to swap out the standard associative
array implementation by modifying druntime and or implementing some
linker functions. Have this been done yet? And if so what must I do to
swap the implementation?


As far as I'm aware, you are stuck using e.g. structs to emulate AA 
behavior.
I have a VERY basic implementation here: 
https://github.com/rikkimax/alphaPhobos/blob/master/source/std/experimental/internal/containers/map.d

Feel free to steal.


Re: Associative arrays

2015-11-08 Thread rsw0x via Digitalmars-d-learn
On Monday, 9 November 2015 at 04:29:30 UTC, Rikki Cattermole 
wrote:

On 09/11/15 4:57 PM, TheFlyingFiddle wrote:

[...]


Nope.


[...]


As far as I'm aware, you are stuck using e.g. structs to 
emulate AA behavior.
I have a VERY basic implementation here: 
https://github.com/rikkimax/alphaPhobos/blob/master/source/std/experimental/internal/containers/map.d

Feel free to steal.


Fwiw, EMSI provides high quality containers backed by 
std.experimental.allocator.

https://github.com/economicmodeling/containers




Re: Associative arrays, multithreading, Rebindable

2014-04-12 Thread bearophile

Jack Applegame:


Should Rebindable to support associative arrays?


I guess so. But how to implement it?

Bye,
bearophile


Re: Associative arrays, multithreading, Rebindable

2014-04-12 Thread Jack Applegame

On Saturday, 12 April 2014 at 09:18:12 UTC, bearophile wrote:

Jack Applegame:


Should Rebindable to support associative arrays?


I guess so. But how to implement it?

Bye,
bearophile

May be just like Rebindable for classes?


Re: Associative arrays, multithreading, Rebindable

2014-04-12 Thread monarch_dodra

On Saturday, 12 April 2014 at 09:18:12 UTC, bearophile wrote:

Jack Applegame:


Should Rebindable to support associative arrays?


I guess so. But how to implement it?

Bye,
bearophile


Related: Rebindable supports arrays (Which makes no sense)
https://issues.dlang.org/show_bug.cgi?id=12046

Quote:
It *might* make sense with associative arrays though... Not sure


Re: associative arrays

2012-01-10 Thread Manfred Nowak
dennis luehring wrote:

 so your FileDelete would not return an FileDoesNotExists-Error?
Correct.
 
 would it not help to better understand big code if the remove
 would be renamed to remove_existing or to add something like this?
Maybe.

You possibly know about the `rm'-command of *nix-like systems and the 
by typo inserted space, which makes
  `rm -r *.obj' to
  `rm -r * .obj'
This will certainly result in the nice error-message:
  cannot remove `.obj': No such file or directory

Therefore: trying to help a minority possibly routes the majority.

-manfred 


Re: associative arrays

2012-01-09 Thread Kapps

Looks like this is fixed for 2.058.

https://github.com/D-Programming-Language/dmd/commit/3e23b0f5834acb32eaee20d88c30ead7e03bb2f4

On 08/01/2012 3:43 AM, Jonathan M Davis wrote:

On Sunday, January 08, 2012 03:24:22 Kapps wrote:

Ah, found the bug / pull request.

https://github.com/D-Programming-Language/dmd/pull/597
http://d.puremagic.com/issues/show_bug.cgi?id=4523


Ah, TDPL says that it returns bool. Well, then it definitely needs to be
changed, and it's good to see that that there's a pull request for it. So, it
should be fixed in the next release. In fact, the number of TDPL-related bugs
fixed for the next release should be quite high, which is great.

- Jonathan M Davis




Re: associative arrays

2012-01-09 Thread dennis luehring

assert(key in aa);
aa.remove(key);

So, as far as I can tell, the current situation is more efficient, and it
doesn't cost you any expressiveness. You can still have an exception thrown
when remove fails if you use enforce before the call if you want an exception
thrown when the element isn't there.


but then it should be called optional_remove - because it mabye removes

its like file_delete, DeleteFile (and all the others) on non existing 
files - why is there an exception/error neeeded if missing?


the maybe-situation is not that often used in good code - because you 
can't find your errors if many routines would work like remove




Re: associative arrays

2012-01-09 Thread Steven Schveighoffer
On Sun, 08 Jan 2012 08:40:27 -0500, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



On Sunday, January 08, 2012 14:24:32 simendsjo wrote:

Thanks for your clarifications.

Does this mean even this is undefined?
aa[a] = new C();
auto c = a in aa;
aa[b] = new C();
// Using c here is undefined as an element was added to aa


Yes. Depending on the current implementation of AAs and the state of aa  
when
b is added to it, c could still point to exactly what it did before,  
or aa
could have been rehashed, which could move any or all of its elements  
around,

in which case who knows what c points to.


Actually, not invalid for the current implementation.  I don't know if  
it's stated whether an AA specifically requires that elements do not  
re-associate on a rehash.


There are certain hash implementations (such as ones that involve a single  
array), which would invalidate pointers on a rehash.  So there is the  
potential (if it's not a stated requirement to the contrary in the spec)  
that some future AA implementation would invalidated references.  However,  
I'd say it's unlikely this would happen.


BTW, dcollections' HashMap, HashSet, and HashMultiset do guarantee that  
adding elements does not invalidated cursors (dcollections' safe version  
of pointers) as long as you use the default Hash implementation.  However,  
I just noticed this is not stated anywhere in the docs (will fix).




-Steve


Re: associative arrays

2012-01-09 Thread Jonathan M Davis
On Monday, January 09, 2012 09:25:14 Steven Schveighoffer wrote:
 Actually, not invalid for the current implementation. I don't know if
 it's stated whether an AA specifically requires that elements do not
 re-associate on a rehash.

Well, like I said, it depends on the current implementation. There are hash 
table implementations where rehashing would invalidate the pointer returned by 
in, and I don't believe that the spec specificies that D's AA guarantees that 
rehashing doesn't do that. So in the future, it _could_ be changed to an 
implementation which invalidates the pointers on rehash. As such, it doesn't 
really matter what the current implementation does. Relying on the current 
behavior is unsafe if it's not guaranteed by the spec. Now, if we want to 
change the spec to make such guarantees, that's fine, but I don't believe it 
makes them right now. Good to know what the current implementation is doing 
though.

- Jonathan m Davis


Re: associative arrays

2012-01-09 Thread Andrej Mitrovic
On 1/9/12, Steven Schveighoffer schvei...@yahoo.com wrote:
 BTW, dcollections' HashMap, HashSet, and HashMultiset do guarantee that
 adding elements does not invalidated cursors (dcollections' safe version
 of pointers) as long as you use the default Hash implementation.  However,
 I just noticed this is not stated anywhere in the docs (will fix).

Funny, I was looking at the docs a few days ago and it said Adding an
element can invalidate cursors depending on the implementation., so I
just assumed it did invalidate the cursors.

I do think those are dcollections v1 docs though. Anyway glad to hear
from you about this.


Re: associative arrays

2012-01-09 Thread Steven Schveighoffer
On Mon, 09 Jan 2012 13:35:26 -0500, Andrej Mitrovic  
andrej.mitrov...@gmail.com wrote:



On 1/9/12, Steven Schveighoffer schvei...@yahoo.com wrote:

BTW, dcollections' HashMap, HashSet, and HashMultiset do guarantee that
adding elements does not invalidated cursors (dcollections' safe version
of pointers) as long as you use the default Hash implementation.   
However,

I just noticed this is not stated anywhere in the docs (will fix).


Funny, I was looking at the docs a few days ago and it said Adding an
element can invalidate cursors depending on the implementation., so I
just assumed it did invalidate the cursors.


Yeah, I could have sworn I stated somewhere that the current  
implementation doesn't invalidate cursors, but apparently it's not  
stated.  I think the docs need a lot of TLC before the first release.   
Some day when I have time...


To clarify what I plan to do, the add doc will say something like adding  
an element can invalidate cursors depending on the implementation, however  
the default implementation guarantees not to invalidate them.  I don't  
want to specifically disallow implementations which do invalidate  
(dcollections' implementations are pluggable so anyone can replace the  
internals).



I do think those are dcollections v1 docs though. Anyway glad to hear
from you about this.


The D2 docs are somewhat leftover from D1 version.  However, I do remember  
when implementing the hash code that it purposely does not invalidate  
cursors on a rehash.  Ranges can be invalidated, however.  Given the  
implementation, it's actually faster *not* to invalidate them when  
rehashing because I just relink all the link-list nodes instead of  
reallocating them.


-Steve


Re: associative arrays

2012-01-09 Thread Andrej Mitrovic
Ok, allow me to temporarily hijack again and ask: Would you mind
adding opIn_r (or rather the newer opBinaryRight with in) that
forwards to contains() for the HashSet and similar hash-based classes
that define contains()? It would make porting code that uses builtin
hashes to your own implementation easier.


Re: associative arrays

2012-01-09 Thread Steven Schveighoffer
On Mon, 09 Jan 2012 14:57:36 -0500, Andrej Mitrovic  
andrej.mitrov...@gmail.com wrote:



Ok, allow me to temporarily hijack again and ask: Would you mind
adding opIn_r (or rather the newer opBinaryRight with in) that
forwards to contains() for the HashSet and similar hash-based classes
that define contains()? It would make porting code that uses builtin
hashes to your own implementation easier.


Could this be you?

http://www.dsource.org/projects/dcollections/ticket/18

If so, this means you are OK with the last suggestion I made?

-Steve


Re: associative arrays

2012-01-09 Thread Andrej Mitrovic
On 1/9/12, Steven Schveighoffer schvei...@yahoo.com wrote:
 Could this be you?

Ah, yes. I didn't even notice you've replied to that, sorry. Yes, I'm
ok with it.


Re: associative arrays

2012-01-09 Thread Manfred Nowak
dennis luehring wrote:
 why is there an exception/error neeeded if missing?

Exceptions or errors are not _needed_.

Their existence stems from the modell under which the user of the 
operation _has_ to think about the operation, especially whether it 
is
  a:only the outcome of the operation or
  b:the amount of work to get to this outcome
and maybe 
  c:at runtime has to be known, whether the object exists.


Jesse Phillips wrote:
 I have a lot of if(exists) remove() in my code

As one can see, Jesse does not know, whether the object exists and 
has to ask, before he in fact removes the object, i.e. doubled access 
to the file, which may cause a slowdown.

As Jesse states the designer of the API has made up false assumptions 
about his knowledge, described in c:,  _and_ his interests, described 
in b:.

Jesse is interested only in the outcome of the operation, as 
described in a:,

Therefore the likely answer to your question stated at the beginning 
is: the designer of the API made a mistake.

-manfred 

  


Re: associative arrays

2012-01-09 Thread dennis luehring

Am 09.01.2012 22:08, schrieb Manfred Nowak:

dennis luehring wrote:

 why is there an exception/error neeeded if missing?


Exceptions or errors are not _needed_.

Their existence stems from the modell under which the user of the
operation _has_ to think about the operation, especially whether it
is
   a:only the outcome of the operation or
   b:the amount of work to get to this outcome
and maybe
   c:at runtime has to be known, whether the object exists.


Jesse Phillips wrote:

 I have a lot of if(exists) remove() in my code


As one can see, Jesse does not know, whether the object exists and
has to ask, before he in fact removes the object, i.e. doubled access
to the file, which may cause a slowdown.


so your FileDelete would not return an FileDoesNotExists-Error?

it isn't always clear what is ok to happen - there are million types 
of remove-like-semantic, an Jesse's scenario is one type of usage, which 
other type of remove allows silently non-remove-removes? STL? Python, 
etc. (how do others handle such cases)


would it not help to better understand big code if the remove would be 
renamed to remove_existing or to add something like this?


Re: associative arrays

2012-01-08 Thread Stephen Bennett
On 1/7/2012 8:54 PM, bearophile wrote:
 Yes, Jonathan, you're right.
 the question arose precisely from a typo... i had to remove an
 item with key length... i wrote lengt and the item never went
 away... i knew that lengt was not in my key list... This kind of
 mistake is quite tricky, may be using and IDE could help.
 
 This an example that shows that silent failures are sources of bugs...
 So this time I don't agree with Jonathan Davis.

a.remove(x) doesn't fail though. It successfully satisfies its own
postconditions by placing a in a state whereby it no longer contains x.
The real source of bugs in this example is using hardcoded strings
instead of named constants. :)

Besides, one frequently doesn't know if (x in a) or not ahead of time.
Think of evicting some computed intermediate results from a cache when
you detect that the underlying resource has changed, for instance. In
fact, it's really rare for an item to be removed from a long-lived
collection anywhere near the point that it was added. Insisting on
existence before removal clutters up the code for an extremely common
use case.

FWIW, Java's Map and .NET's IDictionary also handle this situation silently.

Regards,
~Stephen


Re: associative arrays

2012-01-08 Thread Jonathan M Davis
On Sunday, January 08, 2012 01:39:24 Kapps wrote:
 For most languages (such as C# and maybe Java), the Remove method on
 collections returns a boolean indicating whether it was removed. So you
 could write:
 
 enforce(MyAA.remove(lenght))
 or
 bool Result = MyAA.remove(lenght);
 assert(Result);
 
 I'm not sure why it doesn't in D, but I thought I remembered seeing a
 pull request or change that added it. Maybe I'm imagining things since I
 can't find it now.

There _is_ extra cost in returning bool rather than void, but I'm not at all 
sure that it's unreasonable to incur that cost. std.container.RedBlackTree's 
remove function returns how many elements were removed. Other functions in 
Phobos do similar in similar situations.

It probably merits an enhancement request.

- Jonathan M Davis


Re: associative arrays

2012-01-08 Thread Kapps

Ah, found the bug / pull request.

https://github.com/D-Programming-Language/dmd/pull/597
http://d.puremagic.com/issues/show_bug.cgi?id=4523

On 08/01/2012 1:39 AM, Kapps wrote:

For most languages (such as C# and maybe Java), the Remove method on
collections returns a boolean indicating whether it was removed. So you
could write:

enforce(MyAA.remove(lenght))
or
bool Result = MyAA.remove(lenght);
assert(Result);

I'm not sure why it doesn't in D, but I thought I remembered seeing a
pull request or change that added it. Maybe I'm imagining things since I
can't find it now.

On 07/01/2012 4:11 PM, RenatoL wrote:

Very quick question

import std.stdio;
void main()
{
auto arr1 = [uno:1, due:2, tre:3];
arr1.remove(xxx);
}

also in this case the compiler does not say anything and the
program goes out silently ... why? Would not it be better if an
exception was raised? After all if i write:

writeln(arr1[xxx]);

runtime expresses its disappointment...






Re: associative arrays

2012-01-08 Thread Jonathan M Davis
On Sunday, January 08, 2012 03:24:22 Kapps wrote:
 Ah, found the bug / pull request.
 
 https://github.com/D-Programming-Language/dmd/pull/597
 http://d.puremagic.com/issues/show_bug.cgi?id=4523

Ah, TDPL says that it returns bool. Well, then it definitely needs to be 
changed, and it's good to see that that there's a pull request for it. So, it 
should be fixed in the next release. In fact, the number of TDPL-related bugs 
fixed for the next release should be quite high, which is great.

- Jonathan M Davis


Re: associative arrays

2012-01-08 Thread simendsjo

On 08.01.2012 10:43, Jonathan M Davis wrote:

On Sunday, January 08, 2012 03:24:22 Kapps wrote:

Ah, found the bug / pull request.

https://github.com/D-Programming-Language/dmd/pull/597
http://d.puremagic.com/issues/show_bug.cgi?id=4523


Ah, TDPL says that it returns bool. Well, then it definitely needs to be
changed, and it's good to see that that there's a pull request for it. So, it
should be fixed in the next release. In fact, the number of TDPL-related bugs
fixed for the next release should be quite high, which is great.

- Jonathan M Davis


Wouldn't it make sense to return a pointer to the item being 
removed/null? This way you can continue to work with the item, and it 
would be consistent with `in`.


if (auto item = aa.remove(key)) {
  // some additional work on item
} else { // not found
  // throw or something
}


Re: associative arrays

2012-01-08 Thread Manfred Nowak
simendsjo wrote:

 Wouldn't it make sense to return a pointer to the item being 
 removed/null?

According to the docs this is the intended behavior.

-manfred


Re: associative arrays

2012-01-08 Thread simendsjo

On 08.01.2012 11:09, Manfred Nowak wrote:

simendsjo wrote:


Wouldn't it make sense to return a pointer to the item being
removed/null?


According to the docs this is the intended behavior.

-manfred


The only mention I can see of remove is at the top, and it doesn't state 
return value: http://dlang.org/hash-map.html


The pull changes the return value to bool: 
https://github.com/9rnsr/dmd/commit/f3cc75445775927e2036054811afb686cf4f1624





Re: associative arrays

2012-01-08 Thread Jonathan M Davis
On Sunday, January 08, 2012 11:02:41 simendsjo wrote:
 On 08.01.2012 10:43, Jonathan M Davis wrote:
  On Sunday, January 08, 2012 03:24:22 Kapps wrote:
  Ah, found the bug / pull request.
  
  https://github.com/D-Programming-Language/dmd/pull/597
  http://d.puremagic.com/issues/show_bug.cgi?id=4523
  
  Ah, TDPL says that it returns bool. Well, then it definitely needs to be
  changed, and it's good to see that that there's a pull request for it.
  So, it should be fixed in the next release. In fact, the number of
  TDPL-related bugs fixed for the next release should be quite high,
  which is great.
  
  - Jonathan M Davis
 
 Wouldn't it make sense to return a pointer to the item being
 removed/null? This way you can continue to work with the item, and it
 would be consistent with `in`.
 
 if (auto item = aa.remove(key)) {
// some additional work on item
 } else { // not found
// throw or something
 }

Since the element has been removed from the container, what would the pointer 
point to? The element doesn't exist anymore.

- Jonathan m Davis


Re: associative arrays

2012-01-08 Thread simendsjo

On 08.01.2012 11:27, Jonathan M Davis wrote:

On Sunday, January 08, 2012 11:02:41 simendsjo wrote:

On 08.01.2012 10:43, Jonathan M Davis wrote:

On Sunday, January 08, 2012 03:24:22 Kapps wrote:

Ah, found the bug / pull request.

https://github.com/D-Programming-Language/dmd/pull/597
http://d.puremagic.com/issues/show_bug.cgi?id=4523


Ah, TDPL says that it returns bool. Well, then it definitely needs to be
changed, and it's good to see that that there's a pull request for it.
So, it should be fixed in the next release. In fact, the number of
TDPL-related bugs fixed for the next release should be quite high,
which is great.

- Jonathan M Davis


Wouldn't it make sense to return a pointer to the item being
removed/null? This way you can continue to work with the item, and it
would be consistent with `in`.

if (auto item = aa.remove(key)) {
// some additional work on item
} else { // not found
// throw or something
}


Since the element has been removed from the container, what would the pointer
point to? The element doesn't exist anymore.

- Jonathan m Davis


I was thinking it could be a shorthand for the following:

auto item = key in aa;
if (item) key.remove(key);



Re: associative arrays

2012-01-08 Thread Andrej Mitrovic
On 1/8/12, simendsjo simend...@gmail.com wrote:
 Wouldn't it make sense to return a pointer to the item being
 removed/null?

Seems like that would be even more costly. Personally I think
returning bool is unnecessary, if we really want to know if something
is in the hash we can check with the `in` operator.

I filed that bug ages ago simply because it was in TDPL, but I didn't
really give it much thought.


Re: associative arrays

2012-01-08 Thread Manfred Nowak
simendsjo wrote:

 it doesn't state return value
Yes, I haven't read carefully enough.

-manfred


Re: associative arrays

2012-01-08 Thread simendsjo

On 08.01.2012 12:18, Jonathan M Davis wrote:

On Sunday, January 08, 2012 11:33:51 simendsjo wrote:

I was thinking it could be a shorthand for the following:

auto item = key in aa;
if (item) key.remove(key);


I take it that you then intend to use item after that? I'm not sure that item
is actually valid at that point. It points to memory which _was_ inside of aa
but may or may not be now, depending on the AA implementation, and it may or
may not be reused by aa. Because it's on the GC heap, the memory itself won't
be invalid, but the memory could be reused by the AA for another element,
depending on its implementation. If you're lucky, it's memory that's just
sitting on the GC heap and now unrelated to the AA, but I wouldn't bet on it.

I would _not_ consider that to be good code. It's just asking for trouble.

- Jonathan M Davis


Ah.. This should be documented in http://dlang.org/hash-map.html
The only documentation for remove is:

Particular keys in an associative array can be removed with the remove 
function:

b.remove(hello);



Re: associative arrays

2012-01-08 Thread Jonathan M Davis
On Sunday, January 08, 2012 12:35:27 simendsjo wrote:
 On 08.01.2012 12:18, Jonathan M Davis wrote:
  On Sunday, January 08, 2012 11:33:51 simendsjo wrote:
  I was thinking it could be a shorthand for the following:
  
  auto item = key in aa;
  if (item) key.remove(key);
  
  I take it that you then intend to use item after that? I'm not sure that
  item is actually valid at that point. It points to memory which _was_
  inside of aa but may or may not be now, depending on the AA
  implementation, and it may or may not be reused by aa. Because it's on
  the GC heap, the memory itself won't be invalid, but the memory could
  be reused by the AA for another element, depending on its
  implementation. If you're lucky, it's memory that's just sitting on the
  GC heap and now unrelated to the AA, but I wouldn't bet on it.
  
  I would _not_ consider that to be good code. It's just asking for
  trouble.
  
  - Jonathan M Davis
 
 Ah.. This should be documented in http://dlang.org/hash-map.html
 The only documentation for remove is:
 
 Particular keys in an associative array can be removed with the remove
 function:
  b.remove(hello);
 

I confess that it's one of those things that I would have thought would have 
been fairly obvious, but it certainly wouldn't hurt to add it. The 
documentation does tend to be sparse of details in any case.

- Jonathan M Davis


Re: associative arrays

2012-01-08 Thread simendsjo

On 08.01.2012 12:57, Jonathan M Davis wrote:

On Sunday, January 08, 2012 12:35:27 simendsjo wrote:

On 08.01.2012 12:18, Jonathan M Davis wrote:

On Sunday, January 08, 2012 11:33:51 simendsjo wrote:

I was thinking it could be a shorthand for the following:

auto item = key in aa;
if (item) key.remove(key);


I take it that you then intend to use item after that? I'm not sure that
item is actually valid at that point. It points to memory which _was_
inside of aa but may or may not be now, depending on the AA
implementation, and it may or may not be reused by aa. Because it's on
the GC heap, the memory itself won't be invalid, but the memory could
be reused by the AA for another element, depending on its
implementation. If you're lucky, it's memory that's just sitting on the
GC heap and now unrelated to the AA, but I wouldn't bet on it.

I would _not_ consider that to be good code. It's just asking for
trouble.

- Jonathan M Davis


Ah.. This should be documented in http://dlang.org/hash-map.html
The only documentation for remove is:

Particular keys in an associative array can be removed with the remove
function:
  b.remove(hello);



I confess that it's one of those things that I would have thought would have
been fairly obvious, but it certainly wouldn't hurt to add it. The
documentation does tend to be sparse of details in any case.

- Jonathan M Davis


Certainly not obvious to me :)

auto c = new C();
C[string] aa;
aa[c] = c;
aa.remove(c);

I guess using c from this point is valid, but if the only reference to c 
was inside the aa (and we got c using `in`), using c would have been 
undefined..?




Re: associative arrays

2012-01-08 Thread Jonathan M Davis
On Sunday, January 08, 2012 13:06:06 simendsjo wrote:
 Certainly not obvious to me :)

Well, what's obvious to one person is not always obvious to another. I'm sure 
that there are plenty of things that Walter thinks should be perfectly obvious 
which 90% of programmers would never think of. A lot of it depends on what 
you're experience level is and what you have experience in. In this case, it's 
very much like dealing with C++ iterators, so if you're used to dealing with 
them and when they do or don't get invalidate, then the situation with in and 
remove is probably quite straightforward and intuitive.

 auto c = new C();
 C[string] aa;
 aa[c] = c;
 aa.remove(c);
 
 I guess using c from this point is valid, but if the only reference to c
 was inside the aa (and we got c using `in`), using c would have been
 undefined..?

Using c is valid regardless. The problem is the in operator. It returns a 
pointer to the element inside of the AA. So, if you did

C* d = aa[c];

then d would be a pointer to a reference to a C, and after the call to remove, 
the pointer is pointing to memory which may or may not be part of the AA 
anymore and which may or may not hold a reference to what c refers to. It's 
bit like doing this

int* a()
{
int b;
return b;
}

though the compiler should catch this, since it's obviously wrong. In both 
cases, you're referring to memory which your really not supposed to be 
accessing anymore and may point to invalid memory. The case of the AA probably 
isn't as bad, since either you're pointing to memory on the GC which isn't 
part of the AA (but hasn't been collected, since you have a pointer to it), or 
you're pointing to an element in the AA which may still be the same as it was 
before it was removed, or it may be another element, or it may be garbage 
memory. You really don't know. It's undefined and therefore shouldn't be used.

I don't believe that it's ever safe to assume that the pointer returned by the 
in operator is still valid after the AA that it comes from has had an element 
added or removed. It's the same with iterators or ranges with many iterators 
and ranges. If they point to elements within a container, and that container 
is altered, they're invalidated and aren't safe to use.

So, your example is fine, because it doesn't involve the in operator, and 
therefore doesn't involve any pointers into the AA. It's only once you have 
pointers into the AA that you get into trouble.

- Jonathan M Davis


Re: associative arrays

2012-01-08 Thread simendsjo

On 08.01.2012 13:49, Jonathan M Davis wrote:

On Sunday, January 08, 2012 13:06:06 simendsjo wrote:

Certainly not obvious to me :)


Well, what's obvious to one person is not always obvious to another. I'm sure
that there are plenty of things that Walter thinks should be perfectly obvious
which 90% of programmers would never think of. A lot of it depends on what
you're experience level is and what you have experience in. In this case, it's
very much like dealing with C++ iterators, so if you're used to dealing with
them and when they do or don't get invalidate, then the situation with in and
remove is probably quite straightforward and intuitive.


auto c = new C();
C[string] aa;
aa[c] = c;
aa.remove(c);

I guess using c from this point is valid, but if the only reference to c
was inside the aa (and we got c using `in`), using c would have been
undefined..?


Using c is valid regardless. The problem is the in operator. It returns a
pointer to the element inside of the AA. So, if you did

C* d = aa[c];

then d would be a pointer to a reference to a C, and after the call to remove,
the pointer is pointing to memory which may or may not be part of the AA
anymore and which may or may not hold a reference to what c refers to. It's
bit like doing this

int* a()
{
 int b;
 returnb;
}

though the compiler should catch this, since it's obviously wrong. In both
cases, you're referring to memory which your really not supposed to be
accessing anymore and may point to invalid memory. The case of the AA probably
isn't as bad, since either you're pointing to memory on the GC which isn't
part of the AA (but hasn't been collected, since you have a pointer to it), or
you're pointing to an element in the AA which may still be the same as it was
before it was removed, or it may be another element, or it may be garbage
memory. You really don't know. It's undefined and therefore shouldn't be used.

I don't believe that it's ever safe to assume that the pointer returned by the
in operator is still valid after the AA that it comes from has had an element
added or removed. It's the same with iterators or ranges with many iterators
and ranges. If they point to elements within a container, and that container
is altered, they're invalidated and aren't safe to use.

So, your example is fine, because it doesn't involve the in operator, and
therefore doesn't involve any pointers into the AA. It's only once you have
pointers into the AA that you get into trouble.

- Jonathan M Davis


Thanks for your clarifications.

Does this mean even this is undefined?
aa[a] = new C();
auto c = a in aa;
aa[b] = new C();
// Using c here is undefined as an element was added to aa


Re: associative arrays

2012-01-08 Thread Jonathan M Davis
On Sunday, January 08, 2012 14:24:32 simendsjo wrote:
 Thanks for your clarifications.
 
 Does this mean even this is undefined?
 aa[a] = new C();
 auto c = a in aa;
 aa[b] = new C();
 // Using c here is undefined as an element was added to aa

Yes. Depending on the current implementation of AAs and the state of aa when 
b is added to it, c could still point to exactly what it did before, or aa 
could have been rehashed, which could move any or all of its elements around, 
in which case who knows what c points to.

- Jonathan M Davis


Re: associative arrays

2012-01-08 Thread Manfred Nowak
Jonathan M Davis wrote:

 In this case, it's very much like dealing with C++ iterators

A relevant part of Andrei's thread on associative arrays iteration:

http://www.digitalmars.com/d/archives/digitalmars/D/associative_arrays_
iteration_is_finally_here_99576.html#N99614

-manfred


Re: associative arrays

2012-01-08 Thread Jesse Phillips
Based on these arguments does that mean std.file.remove should 
not be throwing when a file doesn't exist?


Or more precisely should I add a bugzilla entry to change this. I 
certainly have a lot of if(exists) remove() in my code and end up 
having to change where I just use remove().


On Sunday, 8 January 2012 at 05:03:45 UTC, Manfred Nowak wrote:

Jonathan M Davis wrote:

So, as far as I can tell, the current situation is more 
efficient


There are some more arguments:

1) Different threads might want to `remove' the same key from 
the AA. I don't see a reason why only the first served thread 
should complete the operation without an error.


2) Because there is only one operation for insertion of a key 
into an AA, only one operation should be used for removing that 
key.


Note: This argument vanishes if insertions are divided in
a:declaration of a key as valid in that AA,
b:first assignment to the value of a key,
c:reassignment to the value of a key

3) Reverse operations should not implement more functionality 
than the reversed operation. Because `remove' is the reverse 
operation for inserting a key and that operation does not cause 
any error, neither should errors be given from `remove'.


Note: Reassigning to the value of a key might very well treated 
as an error.


-manfred





Re: associative arrays

2012-01-08 Thread RenatoL
Very interesting discussion. Tk u all.


Re: associative arrays

2012-01-07 Thread Ali Çehreli

On 01/07/2012 02:11 PM, RenatoL wrote:
 Very quick question

 import std.stdio;
 void main()
 {
auto arr1 = [uno:1, due:2, tre:3];
arr1.remove(xxx);
 }

 also in this case the compiler does not say anything and the
 program goes out silently ... why? Would not it be better if an
 exception was raised?

I think that could be a valid design choice. On the other hand, since 
what is required is to remove the element, it is not really an error if 
the object is already missing. The requirement is met.


 After all if i write:

 writeln(arr1[xxx]);

 runtime expresses its disappointment...

You get the exception more simply by this:

auto e = arr1[xxx];

But that's understandable because the [] operator is supposed to provide 
access to a usable object. Since there is no general concept of a null 
object, there is no object to provide access to, so there is nothing 
else to do but to throw.


Ali



Re: associative arrays

2012-01-07 Thread Manfred Nowak
RenatoL wrote:
 Would not it be better if an exception was raised?
No, because exceptions are guarenteed to be slow.

 if i write:   writeln(arr1[xxx]);
 runtime expresses its disappointment...
I would be disappointed too, if the commands for removing and for 
requesting something are sequenced in that order.

-manfred


Re: associative arrays

2012-01-07 Thread Jonathan M Davis
On Saturday, January 07, 2012 15:06:30 Ali Çehreli wrote:
 On 01/07/2012 02:11 PM, RenatoL wrote:
   Very quick question
   
   import std.stdio;
   void main()
   {
   
  auto arr1 = [uno:1, due:2, tre:3];
  arr1.remove(xxx);
   
   }
   
   also in this case the compiler does not say anything and the
   program goes out silently ... why? Would not it be better if an
   exception was raised?
 
 I think that could be a valid design choice. On the other hand, since
 what is required is to remove the element, it is not really an error if
 the object is already missing. The requirement is met.
 
   After all if i write:
   
   writeln(arr1[xxx]);
   
   runtime expresses its disappointment...
 
 You get the exception more simply by this:
 
  auto e = arr1[xxx];
 
 But that's understandable because the [] operator is supposed to provide
 access to a usable object. Since there is no general concept of a null
 object, there is no object to provide access to, so there is nothing
 else to do but to throw.

You likely know this, but I'll point it out in case a newbie to decide to get 
htrowing behavior out of the substript operator.

If the element is not in the container, then the subscript operator throws a 
RangeError if -release isn't used, so it's an Error, not an Exception, and 
isn't a Throwable that you're supposed to catch (since the unwinding of the 
stack skips destructors, scope statements, finall blocks for any Throwables 
which aren't either Exception or derived from Exception). Also, without -
release, it does no bounds checking and will likely result in a segfault. So, 
relying on the subscript operator throwing is a _bad_ idea. The idea is that 
you never give it something that isn't actually in the container.

If you need to check it, and you're dealing with a dynamic or static array, 
then you check the array's length. If you're dealing with an associative 
array, then you use the in operator to get a pointer to the element from the 
container and check whether it's null or not (since if it's null, it wasn't 
there).

It would probably make remove more expensive if it had to throw when it didn't 
find an element, and for the most part, it's rather meaningless whether it was 
in the container before that. As pointed out, remove makes sure that the 
element is no longer in the container after it's been called. It has no real 
reason to care whether an element was in there before or not. And if _you_ 
don't care, then being forced to check whether an element was in the container 
before trying to remove it would make your code less efficient. The way remove 
is now, the check only occurs if you do it yourself and therefore actually 
_want_ it. And odds are, such a check would be an assertion anyway (and 
therefore would be throwing an AssertError on failure, not an Exception), 
since the fact that the element wasn't in there anymore is a bug in your code, 
since your code is assuming that it's there.

So, while I can understand someone's first reaction being why remove doesn't 
throw if the element isn't there, when you really think through it, it does 
make more sense for it not to throw.

- Jonathan M Davis


Re: associative arrays

2012-01-07 Thread Jonathan M Davis
On Saturday, January 07, 2012 23:34:05 RenatoL wrote:
 Yes, i agree this may acceptable. On the other hand if i really
 want/have to remove an item i have to be very careful cause a
 trivial typo could cause a disaster

In general, if an element isn't in a container, and you expect it to be there, 
it's bug in your code and _should_ cause disaster. That is, if your code is 
assuming that the element must be in the container before you remove it, you 
should be asserting for that.

assert(key in aa);
aa.remove(key);

This will result in an AssertError if key is not in aa, and upon failure will 
indicate that you have a bug in your code that you need to fix.

If, on the other hand, it's not a bug if that element is not in the container, 
then why would your code be assuming that it is? In that case, I don't see why 
you'd care whether it was actually in the container or not, and having remove 
not do anything if it isn't there is the perfect behavior in that case.

So, I'd argue that if your code is assuming that the element is in the 
container, an assertion should be used, and the fact that remove doesn't throw 
an exception is irrelevant, since it would be the wrong thing to do anyway. 
And if your code can't assume that the element is in the container already, 
then just let remove remove it if it's there and do nothing if it's not.

- Jonathan M Davis


Re: associative arrays

2012-01-07 Thread Manfred Nowak
Jonathan M Davis wrote:

[...]

This sort of explanation is missing in the docs.

-manfred


Re: associative arrays

2012-01-07 Thread Jonathan M Davis
On Sunday, January 08, 2012 00:13:12 Manfred Nowak wrote:
 Jonathan M Davis wrote:
 
 [...]
 
 This sort of explanation is missing in the docs.

Which part?

- Jonathan M Davis


Re: associative arrays

2012-01-07 Thread RenatoL
Yes, Jonathan, you're right.
the question arose precisely from a typo... i had to remove an
item with key length... i wrote lengt and the item never went
away... i knew that lengt was not in my key list... This kind of
mistake is quite tricky, may be using and IDE could help.


Re: associative arrays

2012-01-07 Thread bearophile
RenatoL:

 Yes, Jonathan, you're right.
 the question arose precisely from a typo... i had to remove an
 item with key length... i wrote lengt and the item never went
 away... i knew that lengt was not in my key list... This kind of
 mistake is quite tricky, may be using and IDE could help.

This an example that shows that silent failures are sources of bugs...
So this time I don't agree with Jonathan Davis.

Python Zen contains:
Errors should never pass silently.

And Python associative arrays show it:

 d = {1:2, 3:4}
 del d[5]
Traceback (most recent call last):
  File stdin, line 1, in module
KeyError: 5


The successive rule of the Python Zen says:
Unless explicitly silenced.

Python sets show this at work, they have a 'remove' method that throws if the 
item is missing, plus a 'discard' method that acts more like D associative 
arrays, in a sense it's a way to silence explicitly the error:

 s = set([1, 2])
 s.discard(1)
 s
set([2])
 s = set([1, 2])
 s.discard(3)
 s
set([1, 2])
 s.remove(3)
Traceback (most recent call last):
  File stdin, line 1, in module
KeyError: 3

Maybe D associative arrays too should have both kinds of deleting methods :-)

Bye,
bearophile


Re: associative arrays

2012-01-07 Thread Jonathan M Davis
On Saturday, January 07, 2012 21:54:07 bearophile wrote:
 Maybe D associative arrays too should have both kinds of deleting methods
 :-)

Why? What's the gain? If you care that the element is already in the AA, then 
do either

assert(key in aa);
aa.remove(key);

or

enforce(key in aa);
aa.remove(key);

I suppose that that's less efficient than remove throwing on failure, since it 
has to do a double lookup, but since throwing the exception costs _far_ more 
than that, I don't think that the extra cost really matters

But if you _don't_ care whether the element is in the AA when you remove it, 
and remove threw when the element wasn't there, then you'd have to do

if(key in aa)
aa.remove(key);

which would result is a double lookup when you don't want one, and performance 
_would_ matter, since there isn't necessarily another operation which would 
cost a lot which is overshadowing the cost of the double lookup (as occurs in 
the case where you throw the exception when the element isn't there). Also, if 
you considered the key not being there to be a bug (as seems more likely to 
me), the fact that remove then threw an assertion would force you to do the 
extra check _anyway_.

assert(key in aa);
aa.remove(key);

So, as far as I can tell, the current situation is more efficient, and it 
doesn't cost you any expressiveness. You can still have an exception thrown 
when remove fails if you use enforce before the call if you want an exception 
thrown when the element isn't there.

- Jonathan M Davis


Re: associative arrays

2012-01-07 Thread Manfred Nowak
Jonathan M Davis wrote:

 So, as far as I can tell, the current situation is more efficient

There are some more arguments:

1) Different threads might want to `remove' the same key from the AA. I 
don't see a reason why only the first served thread should complete the 
operation without an error.

2) Because there is only one operation for insertion of a key into an 
AA, only one operation should be used for removing that key.

Note: This argument vanishes if insertions are divided in 
  a:declaration of a key as valid in that AA,
  b:first assignment to the value of a key,
  c:reassignment to the value of a key

3) Reverse operations should not implement more functionality than the 
reversed operation. Because `remove' is the reverse operation for 
inserting a key and that operation does not cause any error, neither 
should errors be given from `remove'.

Note: Reassigning to the value of a key might very well treated as an 
error.

-manfred


Re: associative arrays

2012-01-07 Thread Kapps
For most languages (such as C# and maybe Java), the Remove method on 
collections returns a boolean indicating whether it was removed. So you 
could write:


enforce(MyAA.remove(lenght))
or
bool Result = MyAA.remove(lenght);
assert(Result);

I'm not sure why it doesn't in D, but I thought I remembered seeing a 
pull request or change that added it. Maybe I'm imagining things since I 
can't find it now.


On 07/01/2012 4:11 PM, RenatoL wrote:

Very quick question

import std.stdio;
void main()
{
auto arr1 = [uno:1, due:2, tre:3];
arr1.remove(xxx);
}

also in this case the compiler does not say anything and the
program goes out silently ... why? Would not it be better if an
exception was raised? After all if i write:

writeln(arr1[xxx]);

runtime expresses its disappointment...




Re: Associative arrays give compile error

2010-10-06 Thread Steven Schveighoffer
On Tue, 05 Oct 2010 22:02:30 -0400, bearophile bearophileh...@lycos.com  
wrote:



Denis Koroskin:


Compute mutable copy and then cast to immutable. Am I missing something?


That's possible. But it's an exceptionally dirty thing, I am not sure it  
works in SafeD. A well designed const system has to offer a more clean  
solution :-) Do you agree?


Casting to immutable is the only way to create such a beast.  The best way  
to ensure as few bugs as possible is to create the object you wish to be  
immutable in a function, and cast at the end before returning.  This at  
least encapsulates the dirtiness in one function (which would probably be  
marked @trusted).


You can also use assumeUnique (which I'm guessing is there so it can be  
called in safeD?).


-Steve


Re: Associative arrays give compile error

2010-10-06 Thread bearophile
Steven Schveighoffer:

 Casting to immutable is the only way to create such a beast.

Then maybe we have to improve the language semantics to allow a better 
solution. See the Transients of Clojure or the larval objects of Java :-)

The compiler may need to test (at compile time) that there's only one reference 
to the AA and its contents, and turn it into immutable.

Bye,
bearophile


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 I can't seem to get any sense out of associative arrays. Even the
simplest definition won't compile so I must be doing something daft.

int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight out the
book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no args)?
Works perfectly fine here (dmd2.049).


Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even the
 simplest definition won't compile so I must be doing something daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is straight out the
 book. Using D 2.0.

 bob

 What exactly compiler version are you using (run dmd with no args)?
 Works perfectly fine here (dmd2.049).

It says 2.049. How odd. I've got a fair amount of code and everything
else compiles fine.


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even the
simplest definition won't compile so I must be doing something daft.

int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight out  
the

book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no args)?
Works perfectly fine here (dmd2.049).


It says 2.049. How odd. I've got a fair amount of code and everything
else compiles fine.


Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d


Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 12:04, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even the
 simplest definition won't compile so I must be doing something daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is straight
 out the
 book. Using D 2.0.

 bob

 What exactly compiler version are you using (run dmd with no args)?
 Works perfectly fine here (dmd2.049).

 It says 2.049. How odd. I've got a fair amount of code and everything
 else compiles fine.

 Can you please post complete code snippet that fails to compile?

 Here is the code I used to test:

 module aa;

 import std.stdio;

 void main()
 {
 int[string] aa = [hello:42];
 writeln(aa[hello]);
 }

 # dmd -run aa.d

Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What I was
actually trying to do was create an associative array with a string as a
key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.  Does
anyone know the correct way to define this and then access the tuple.


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 12:04, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even the
simplest definition won't compile so I must be doing something daft.

int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight
out the
book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no args)?
Works perfectly fine here (dmd2.049).


It says 2.049. How odd. I've got a fair amount of code and everything
else compiles fine.


Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d


Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What I was
actually trying to do was create an associative array with a string as a
key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.  Does
anyone know the correct way to define this and then access the tuple.


import std.stdio;
import std.typecons;

void main()
{
auto aa = [hello: tuple(100.0, 6100.0)];
auto result = aa[hello];

writeln(result.field[0],  , result._1); // primary and alternative way
}


Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 12:13, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:04, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even the
 simplest definition won't compile so I must be doing something daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is straight
 out the
 book. Using D 2.0.

 bob

 What exactly compiler version are you using (run dmd with no args)?
 Works perfectly fine here (dmd2.049).

 It says 2.049. How odd. I've got a fair amount of code and everything
 else compiles fine.

 Can you please post complete code snippet that fails to compile?

 Here is the code I used to test:

 module aa;

 import std.stdio;

 void main()
 {
 int[string] aa = [hello:42];
 writeln(aa[hello]);
 }

 # dmd -run aa.d

 Ah! It's some other code below it that is not giving an error but
 causing the error above. So the compiler is getting confused. What I was
 actually trying to do was create an associative array with a string as a
 key and a Tuple as the value. Now

 auto aa = [
 some string: (100.0, 6100.0)
 ]

 compiles but is clearly wrong and gives rise to other errors.  Does
 anyone know the correct way to define this and then access the tuple.

 import std.stdio;
 import std.typecons;

 void main()
 {
 auto aa = [hello: tuple(100.0, 6100.0)];
 auto result = aa[hello];
 
 writeln(result.field[0],  , result._1); // primary and
 alternative way
 }

Thanks. I've established that works for me and also that the actual
array I'm using also works in the test program but it won't compile in
the real program. I've commented everything else out of the file and
just left...

import std.typecons;

auto A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];

I get an error on every line:
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
compile time|
||=== Build finished: 14 errors, 0 warnings ===|

This is a bit worrying now. I moved the array into the file that uses it
but I still get the same errors. Any ideas?




Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 12:40, Bob Cowdery wrote:
  On 05/10/2010 12:13, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:04, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even the
 simplest definition won't compile so I must be doing something daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is straight
 out the
 book. Using D 2.0.

 bob
 What exactly compiler version are you using (run dmd with no args)?
 Works perfectly fine here (dmd2.049).
 It says 2.049. How odd. I've got a fair amount of code and everything
 else compiles fine.
 Can you please post complete code snippet that fails to compile?

 Here is the code I used to test:

 module aa;

 import std.stdio;

 void main()
 {
 int[string] aa = [hello:42];
 writeln(aa[hello]);
 }

 # dmd -run aa.d
 Ah! It's some other code below it that is not giving an error but
 causing the error above. So the compiler is getting confused. What I was
 actually trying to do was create an associative array with a string as a
 key and a Tuple as the value. Now

 auto aa = [
 some string: (100.0, 6100.0)
 ]

 compiles but is clearly wrong and gives rise to other errors.  Does
 anyone know the correct way to define this and then access the tuple.
 import std.stdio;
 import std.typecons;

 void main()
 {
 auto aa = [hello: tuple(100.0, 6100.0)];
 auto result = aa[hello];
 
 writeln(result.field[0],  , result._1); // primary and
 alternative way
 }
 Thanks. I've established that works for me and also that the actual
 array I'm using also works in the test program but it won't compile in
 the real program. I've commented everything else out of the file and
 just left...

 import std.typecons;

 auto A_RX_FILT = [
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
 ];

 I get an error on every line:
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
 compile time|
 ||=== Build finished: 14 errors, 0 warnings ===|

 This is a bit worrying now. I moved the array into the file that uses it
 but I still get the same errors. Any ideas?


Oh dear, this is getting worse and worse. I've still got problems with a
simple definition. If I take out the one with the tuple and leave in
this one:

enum E_MODE
{
  LSB,//  0
  USB,//  1
  DSB,//  2
  CWL,//  3
  CWU,//  4
  FMN,//  5
  AM,//  6
  DIGU,//  7
  SPEC,//  8
  DIGL,//  9
  SAM,// 10
  DRM// 11
}
// Associative array for translation
auto A_MODE = [
LSB: E_MODE.LSB,
USB: E_MODE.USB,
DSB: E_MODE.DSB,
CWL: E_MODE.CWL,
CWU: E_MODE.CWU,
FMN: E_MODE.FMN,
AM: E_MODE.AM,
DIGU: E_MODE.DIGU,
SPEC: E_MODE.SPEC,
DIGL: E_MODE.DIGL,
SAM: E_MODE.SAM,
DRM: E_MODE.DRM
];

I get:
Definitions\dspDefs.d|25|Error: non-constant expression
[LSB:cast(E_MODE)0,USB:cast(E_MODE)1,DSB:cast(E_MODE)2,CWL:cast(E_MODE)3,CWU:cast(E_MODE)4,FMN:cast(E_MODE)5,AM:cast(E_MODE)6,DIGU:cast(E_MODE)7,SPEC:cast(E_MODE)8,DIGL:cast(E_MODE)9,SAM:cast(E_MODE)10,DRM:cast(E_MODE)11]|
||=== Build finished: 1 errors, 0 warnings ===|

Something is seriously broken here.





Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 15:40:39 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 12:13, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:04, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even the
simplest definition won't compile so I must be doing something  
daft.


int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight
out the
book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no args)?
Works perfectly fine here (dmd2.049).


It says 2.049. How odd. I've got a fair amount of code and everything
else compiles fine.


Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d


Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What I  
was
actually trying to do was create an associative array with a string as  
a

key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.  Does
anyone know the correct way to define this and then access the tuple.


import std.stdio;
import std.typecons;

void main()
{
auto aa = [hello: tuple(100.0, 6100.0)];
auto result = aa[hello];

writeln(result.field[0],  , result._1); // primary and
alternative way
}


Thanks. I've established that works for me and also that the actual
array I'm using also works in the test program but it won't compile in
the real program. I've commented everything else out of the file and
just left...

import std.typecons;

auto A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];



You are trying to declare global variable and initialize at in compile  
time. As far as I know, you can't initialize AA at compile time atm (this  
might be implemented in future though).


As such, I'd recommend against using global variables (try moving it to  
some class or something). Anyway, you need to initialize it at some point,  
either manually:


Tuple!(double,double)[string] A_RX_FILT;

void init()
{
A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];
}

or automatically at thread startup:

static this()
{
init();
}

Hope that helps.


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 15:50:44 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 12:40, Bob Cowdery wrote:

 On 05/10/2010 12:13, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:04, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even the
simplest definition won't compile so I must be doing something  
daft.


int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight
out the
book. Using D 2.0.

bob

What exactly compiler version are you using (run dmd with no args)?
Works perfectly fine here (dmd2.049).
It says 2.049. How odd. I've got a fair amount of code and  
everything

else compiles fine.

Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d

Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What I  
was
actually trying to do was create an associative array with a string  
as a

key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.  Does
anyone know the correct way to define this and then access the tuple.

import std.stdio;
import std.typecons;

void main()
{
auto aa = [hello: tuple(100.0, 6100.0)];
auto result = aa[hello];

writeln(result.field[0],  , result._1); // primary and
alternative way
}

Thanks. I've established that works for me and also that the actual
array I'm using also works in the test program but it won't compile in
the real program. I've commented everything else out of the file and
just left...

import std.typecons;

auto A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];

I get an error on every line:
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
compile time|
Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
compile time|
||=== Build finished: 14 errors, 0 warnings ===|

This is a bit worrying now. I moved the array into the file that uses it
but I still get the same errors. Any ideas?



Oh dear, this is getting worse and worse. I've still got problems with a
simple definition. If I take out the one with the tuple and leave in
this one:

enum E_MODE
{
  LSB,//  0
  USB,//  1
  DSB,//  2
  CWL,//  3
  CWU,//  4
  FMN,//  5
  AM,//  6
  DIGU,//  7
  SPEC,//  8
  DIGL,//  9
  SAM,// 10
  DRM// 11
}
// Associative array for translation
auto A_MODE = [
LSB: E_MODE.LSB,
USB: E_MODE.USB,
DSB: E_MODE.DSB,
CWL: E_MODE.CWL,
CWU: E_MODE.CWU,
FMN: E_MODE.FMN,
AM: E_MODE.AM,
DIGU: E_MODE.DIGU,
SPEC: E_MODE.SPEC,
DIGL: E_MODE.DIGL,
SAM: E_MODE.SAM,
DRM: E_MODE.DRM
];

I get:
Definitions\dspDefs.d|25|Error: non-constant expression
[LSB:cast(E_MODE)0,USB:cast(E_MODE)1,DSB:cast(E_MODE)2,CWL:cast(E_MODE)3,CWU:cast(E_MODE)4,FMN:cast(E_MODE)5,AM:cast(E_MODE)6,DIGU:cast(E_MODE)7,SPEC:cast(E_MODE)8,DIGL:cast(E_MODE)9,SAM:cast(E_MODE)10,DRM:cast(E_MODE)11]|
||=== Build finished: 1 errors, 0 warnings ===|

Something is seriously broken here.




Try using enum A_MODE instead of auto A_MODE, it should help. Sorry for  
confusion.


Re: Associative arrays give compile error

2010-10-05 Thread Lars T. Kyllingstad
On Tue, 05 Oct 2010 12:50:44 +0100, Bob Cowdery wrote:

 On 05/10/2010 12:40, Bob Cowdery wrote:
  On 05/10/2010 12:13, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:04, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even
  the
 simplest definition won't compile so I must be doing something
 daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is straight
 out the
 book. Using D 2.0.

 bob
 What exactly compiler version are you using (run dmd with no
 args)? Works perfectly fine here (dmd2.049).
 It says 2.049. How odd. I've got a fair amount of code and
 everything else compiles fine.
 Can you please post complete code snippet that fails to compile?

 Here is the code I used to test:

 module aa;

 import std.stdio;

 void main()
 {
 int[string] aa = [hello:42];
 writeln(aa[hello]);
 }

 # dmd -run aa.d
 Ah! It's some other code below it that is not giving an error but
 causing the error above. So the compiler is getting confused. What I
 was actually trying to do was create an associative array with a
 string as a key and a Tuple as the value. Now

 auto aa = [
 some string: (100.0, 6100.0)
 ]

 compiles but is clearly wrong and gives rise to other errors.  Does
 anyone know the correct way to define this and then access the tuple.
 import std.stdio;
 import std.typecons;

 void main()
 {
 auto aa = [hello: tuple(100.0, 6100.0)]; auto result =
 aa[hello];
 
 writeln(result.field[0],  , result._1); // primary and
 alternative way
 }
 Thanks. I've established that works for me and also that the actual
 array I'm using also works in the test program but it won't compile in
 the real program. I've commented everything else out of the file and
 just left...

 import std.typecons;

 auto A_RX_FILT = [
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
 ];

 I get an error on every line:
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
 compile time|
 Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
 compile time|
 ||=== Build finished: 14 errors, 0 warnings ===|

 This is a bit worrying now. I moved the array into the file that uses
 it but I still get the same errors. Any ideas?


 Oh dear, this is getting worse and worse. I've still got problems with a
 simple definition. If I take out the one with the tuple and leave in
 this one:
 
 enum E_MODE
 {
   LSB,//  0
   USB,//  1
   DSB,//  2
   CWL,//  3
   CWU,//  4
   FMN,//  5
   AM,//  6
   DIGU,//  7
   SPEC,//  8
   DIGL,//  9
   SAM,// 10
   DRM// 11
 }
 // Associative array for translation
 auto A_MODE = [
 LSB: E_MODE.LSB,
 USB: E_MODE.USB,
 DSB: E_MODE.DSB,
 CWL: E_MODE.CWL,
 CWU: E_MODE.CWU,
 FMN: E_MODE.FMN,
 AM: E_MODE.AM,
 DIGU: E_MODE.DIGU,
 SPEC: E_MODE.SPEC,
 DIGL: E_MODE.DIGL,
 SAM: E_MODE.SAM,
 DRM: E_MODE.DRM
 ];
 
 I get:
 Definitions\dspDefs.d|25|Error: non-constant expression
 [LSB:cast(E_MODE)0,USB:cast(E_MODE)1,DSB:cast(E_MODE)2,CWL:cast
(E_MODE)3,CWU:cast(E_MODE)4,FMN:cast(E_MODE)5,AM:cast(E_MODE)
6,DIGU:cast(E_MODE)7,SPEC:cast(E_MODE)8,DIGL:cast(E_MODE)
9,SAM:cast(E_MODE)10,DRM:cast(E_MODE)11]|
 ||=== Build finished: 1 errors, 0 warnings ===|
 
 Something is seriously broken here.

No, nothing is 

Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 15:53:55 +0400, Denis Koroskin 2kor...@gmail.com  
wrote:


On Tue, 05 Oct 2010 15:40:39 +0400, Bob Cowdery  
b...@bobcowdery.plus.com wrote:



 On 05/10/2010 12:13, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:04, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even the
simplest definition won't compile so I must be doing something  
daft.


int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight
out the
book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no args)?
Works perfectly fine here (dmd2.049).


It says 2.049. How odd. I've got a fair amount of code and  
everything

else compiles fine.


Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d


Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What I  
was
actually trying to do was create an associative array with a string  
as a

key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.  Does
anyone know the correct way to define this and then access the tuple.


import std.stdio;
import std.typecons;

void main()
{
auto aa = [hello: tuple(100.0, 6100.0)];
auto result = aa[hello];

writeln(result.field[0],  , result._1); // primary and
alternative way
}


Thanks. I've established that works for me and also that the actual
array I'm using also works in the test program but it won't compile in
the real program. I've commented everything else out of the file and
just left...

import std.typecons;

auto A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];



You are trying to declare global variable and initialize at in compile  
time. As far as I know, you can't initialize AA at compile time atm  
(this might be implemented in future though).


As such, I'd recommend against using global variables (try moving it to  
some class or something). Anyway, you need to initialize it at some  
point, either manually:


Tuple!(double,double)[string] A_RX_FILT;

void init()
{
 A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
 ];
}

or automatically at thread startup:

static this()
{
 init();
}

Hope that helps.


See my other reply for a better solution.


Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 13:05, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:53:55 +0400, Denis Koroskin 2kor...@gmail.com
 wrote:

 On Tue, 05 Oct 2010 15:40:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:13, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:04, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even
 the
 simplest definition won't compile so I must be doing something
 daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is straight
 out the
 book. Using D 2.0.

 bob

 What exactly compiler version are you using (run dmd with no
 args)?
 Works perfectly fine here (dmd2.049).

 It says 2.049. How odd. I've got a fair amount of code and
 everything
 else compiles fine.

 Can you please post complete code snippet that fails to compile?

 Here is the code I used to test:

 module aa;

 import std.stdio;

 void main()
 {
 int[string] aa = [hello:42];
 writeln(aa[hello]);
 }

 # dmd -run aa.d

 Ah! It's some other code below it that is not giving an error but
 causing the error above. So the compiler is getting confused. What
 I was
 actually trying to do was create an associative array with a
 string as a
 key and a Tuple as the value. Now

 auto aa = [
 some string: (100.0, 6100.0)
 ]

 compiles but is clearly wrong and gives rise to other errors.  Does
 anyone know the correct way to define this and then access the tuple.

 import std.stdio;
 import std.typecons;

 void main()
 {
 auto aa = [hello: tuple(100.0, 6100.0)];
 auto result = aa[hello];

 writeln(result.field[0],  , result._1); // primary and
 alternative way
 }

 Thanks. I've established that works for me and also that the actual
 array I'm using also works in the test program but it won't compile in
 the real program. I've commented everything else out of the file and
 just left...

 import std.typecons;

 auto A_RX_FILT = [
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
 ];


 You are trying to declare global variable and initialize at in
 compile time. As far as I know, you can't initialize AA at compile
 time atm (this might be implemented in future though).

 As such, I'd recommend against using global variables (try moving it
 to some class or something). Anyway, you need to initialize it at
 some point, either manually:

 Tuple!(double,double)[string] A_RX_FILT;

 void init()
 {
  A_RX_FILT = [
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
  ];
 }

 or automatically at thread startup:

 static this()
 {
  init();
 }

 Hope that helps.

 See my other reply for a better solution.

Thanks very much. It compiles now. The reason I thought it was an issue
was because sometime it did compile a global associative array. I need
to do some homework on what 'this' does. It's clearly a powerful concept
and has wider application than class constructors.



Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 16:32:14 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 13:05, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:53:55 +0400, Denis Koroskin 2kor...@gmail.com
wrote:


On Tue, 05 Oct 2010 15:40:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:13, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:04, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even
the
simplest definition won't compile so I must be doing something
daft.

int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is straight
out the
book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no
args)?
Works perfectly fine here (dmd2.049).


It says 2.049. How odd. I've got a fair amount of code and
everything
else compiles fine.


Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d


Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What
I was
actually trying to do was create an associative array with a
string as a
key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.  Does
anyone know the correct way to define this and then access the  
tuple.


import std.stdio;
import std.typecons;

void main()
{
auto aa = [hello: tuple(100.0, 6100.0)];
auto result = aa[hello];

writeln(result.field[0],  , result._1); // primary and
alternative way
}


Thanks. I've established that works for me and also that the actual
array I'm using also works in the test program but it won't compile in
the real program. I've commented everything else out of the file and
just left...

import std.typecons;

auto A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];



You are trying to declare global variable and initialize at in
compile time. As far as I know, you can't initialize AA at compile
time atm (this might be implemented in future though).

As such, I'd recommend against using global variables (try moving it
to some class or something). Anyway, you need to initialize it at
some point, either manually:

Tuple!(double,double)[string] A_RX_FILT;

void init()
{
 A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
 ];
}

or automatically at thread startup:

static this()
{
 init();
}

Hope that helps.


See my other reply for a better solution.


Thanks very much. It compiles now. The reason I thought it was an issue
was because sometime it did compile a global associative array. I need
to do some homework on what 'this' does. It's clearly a powerful concept
and has wider application than class constructors.



static this is called a static constructor and can be used for classes  
and modules. The code in static constructor is guarantied to be called  
before you use that class/module, it usually happens upon thread  
initialization.


The other solution is better though:

enum A_RX_FILT = [  // just works
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
];


Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 13:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 16:32:14 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 13:05, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:53:55 +0400, Denis Koroskin 2kor...@gmail.com
 wrote:

 On Tue, 05 Oct 2010 15:40:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:13, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 12:04, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 11:45, Denis Koroskin wrote:
 On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  I can't seem to get any sense out of associative arrays. Even
 the
 simplest definition won't compile so I must be doing something
 daft.

 int[string] aa = [hello:42];

 Error: non-constant expression [hello:42]

 What exactly is not constant about this. The example is
 straight
 out the
 book. Using D 2.0.

 bob

 What exactly compiler version are you using (run dmd with no
 args)?
 Works perfectly fine here (dmd2.049).

 It says 2.049. How odd. I've got a fair amount of code and
 everything
 else compiles fine.

 Can you please post complete code snippet that fails to compile?

 Here is the code I used to test:

 module aa;

 import std.stdio;

 void main()
 {
 int[string] aa = [hello:42];
 writeln(aa[hello]);
 }

 # dmd -run aa.d

 Ah! It's some other code below it that is not giving an error but
 causing the error above. So the compiler is getting confused. What
 I was
 actually trying to do was create an associative array with a
 string as a
 key and a Tuple as the value. Now

 auto aa = [
 some string: (100.0, 6100.0)
 ]

 compiles but is clearly wrong and gives rise to other errors.  Does
 anyone know the correct way to define this and then access the
 tuple.

 import std.stdio;
 import std.typecons;

 void main()
 {
 auto aa = [hello: tuple(100.0, 6100.0)];
 auto result = aa[hello];

 writeln(result.field[0],  , result._1); // primary and
 alternative way
 }

 Thanks. I've established that works for me and also that the actual
 array I'm using also works in the test program but it won't
 compile in
 the real program. I've commented everything else out of the file and
 just left...

 import std.typecons;

 auto A_RX_FILT = [
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
 ];


 You are trying to declare global variable and initialize at in
 compile time. As far as I know, you can't initialize AA at compile
 time atm (this might be implemented in future though).

 As such, I'd recommend against using global variables (try moving it
 to some class or something). Anyway, you need to initialize it at
 some point, either manually:

 Tuple!(double,double)[string] A_RX_FILT;

 void init()
 {
  A_RX_FILT = [
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
  ];
 }

 or automatically at thread startup:

 static this()
 {
  init();
 }

 Hope that helps.

 See my other reply for a better solution.

 Thanks very much. It compiles now. The reason I thought it was an issue
 was because sometime it did compile a global associative array. I need
 to do some homework on what 'this' does. It's clearly a powerful concept
 and has wider application than class constructors.


 static this is called a static constructor and can be used for
 classes and modules. The code in static constructor is guarantied to
 be called before you use that class/module, it usually happens upon
 thread initialization.

 The other solution is better though:

 enum A_RX_FILT = [// just works
  6K0: tuple(100.0, 6100.0),
  2K4: tuple(300.0, 2700.0),
  2K1: tuple(300.0, 2400.0),
  1K0: tuple(300.0, 1300.0),
  500: tuple(500.0, 1000.0),
  250: tuple(600.0, 850.0),
  100: tuple(700.0, 800.0)
 ];
I'm not totally understanding that. Why can enum compute that at compile
time and the thing which it is, an associative array cannot. Is it to do
with where these things live.


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Tue, 05 Oct 2010 17:00:13 +0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 13:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 16:32:14 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 13:05, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:53:55 +0400, Denis Koroskin 2kor...@gmail.com
wrote:


On Tue, 05 Oct 2010 15:40:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:13, Denis Koroskin wrote:

On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 12:04, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 On 05/10/2010 11:45, Denis Koroskin wrote:

On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
b...@bobcowdery.plus.com wrote:


 I can't seem to get any sense out of associative arrays. Even
the
simplest definition won't compile so I must be doing something
daft.

int[string] aa = [hello:42];

Error: non-constant expression [hello:42]

What exactly is not constant about this. The example is
straight
out the
book. Using D 2.0.

bob


What exactly compiler version are you using (run dmd with no
args)?
Works perfectly fine here (dmd2.049).


It says 2.049. How odd. I've got a fair amount of code and
everything
else compiles fine.


Can you please post complete code snippet that fails to compile?

Here is the code I used to test:

module aa;

import std.stdio;

void main()
{
int[string] aa = [hello:42];
writeln(aa[hello]);
}

# dmd -run aa.d


Ah! It's some other code below it that is not giving an error but
causing the error above. So the compiler is getting confused. What
I was
actually trying to do was create an associative array with a
string as a
key and a Tuple as the value. Now

auto aa = [
some string: (100.0, 6100.0)
]

compiles but is clearly wrong and gives rise to other errors.   
Does

anyone know the correct way to define this and then access the
tuple.


import std.stdio;
import std.typecons;

void main()
{
auto aa = [hello: tuple(100.0, 6100.0)];
auto result = aa[hello];

writeln(result.field[0],  , result._1); // primary and
alternative way
}


Thanks. I've established that works for me and also that the actual
array I'm using also works in the test program but it won't
compile in
the real program. I've commented everything else out of the file and
just left...

import std.typecons;

auto A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
];



You are trying to declare global variable and initialize at in
compile time. As far as I know, you can't initialize AA at compile
time atm (this might be implemented in future though).

As such, I'd recommend against using global variables (try moving it
to some class or something). Anyway, you need to initialize it at
some point, either manually:

Tuple!(double,double)[string] A_RX_FILT;

void init()
{
 A_RX_FILT = [
6K0: tuple(100.0, 6100.0),
2K4: tuple(300.0, 2700.0),
2K1: tuple(300.0, 2400.0),
1K0: tuple(300.0, 1300.0),
500: tuple(500.0, 1000.0),
250: tuple(600.0, 850.0),
100: tuple(700.0, 800.0)
 ];
}

or automatically at thread startup:

static this()
{
 init();
}

Hope that helps.


See my other reply for a better solution.


Thanks very much. It compiles now. The reason I thought it was an issue
was because sometime it did compile a global associative array. I need
to do some homework on what 'this' does. It's clearly a powerful  
concept

and has wider application than class constructors.



static this is called a static constructor and can be used for
classes and modules. The code in static constructor is guarantied to
be called before you use that class/module, it usually happens upon
thread initialization.

The other solution is better though:

enum A_RX_FILT = [// just works
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
];

I'm not totally understanding that. Why can enum compute that at compile
time and the thing which it is, an associative array cannot. Is it to do
with where these things live.


Let's say it's a limitation of dmd compiler. I'll submit a bug report.


Re: Associative arrays give compile error

2010-10-05 Thread Steven Schveighoffer
On Tue, 05 Oct 2010 09:00:13 -0400, Bob Cowdery b...@bobcowdery.plus.com  
wrote:



 On 05/10/2010 13:45, Denis Koroskin wrote:



static this is called a static constructor and can be used for
classes and modules. The code in static constructor is guarantied to
be called before you use that class/module, it usually happens upon
thread initialization.

The other solution is better though:

enum A_RX_FILT = [// just works
 6K0: tuple(100.0, 6100.0),
 2K4: tuple(300.0, 2700.0),
 2K1: tuple(300.0, 2400.0),
 1K0: tuple(300.0, 1300.0),
 500: tuple(500.0, 1000.0),
 250: tuple(600.0, 850.0),
 100: tuple(700.0, 800.0)
];

I'm not totally understanding that. Why can enum compute that at compile
time and the thing which it is, an associative array cannot. Is it to do
with where these things live.


I'd be very wary of this solution.  Recently, enum has been shown to  
construct itself on every use.


So what I think is happening is every time you use A_RX_FILT, it's  
building a brand new AA (you can verify this by looking at the  
disassembly).


I'd recommend the static this solution in order to ensure you are not  
accidentally killing performance by just using that AA.


A while back, Don suggested that all literals should be considered  
immutable.  I agree with him, but Walter still doesn't.  If all literals  
are immutable, then they could be truly constructed at compile-time.


-Steve


Re: Associative arrays give compile error

2010-10-05 Thread Bob Cowdery
 On 05/10/2010 15:14, Steven Schveighoffer wrote:
 On Tue, 05 Oct 2010 09:00:13 -0400, Bob Cowdery
 b...@bobcowdery.plus.com wrote:

  On 05/10/2010 13:45, Denis Koroskin wrote:

 static this is called a static constructor and can be used for
 classes and modules. The code in static constructor is guarantied to
 be called before you use that class/module, it usually happens upon
 thread initialization.

 The other solution is better though:

 enum A_RX_FILT = [// just works
  6K0: tuple(100.0, 6100.0),
  2K4: tuple(300.0, 2700.0),
  2K1: tuple(300.0, 2400.0),
  1K0: tuple(300.0, 1300.0),
  500: tuple(500.0, 1000.0),
  250: tuple(600.0, 850.0),
  100: tuple(700.0, 800.0)
 ];
 I'm not totally understanding that. Why can enum compute that at compile
 time and the thing which it is, an associative array cannot. Is it to do
 with where these things live.

 I'd be very wary of this solution.  Recently, enum has been shown to
 construct itself on every use.

 So what I think is happening is every time you use A_RX_FILT, it's
 building a brand new AA (you can verify this by looking at the
 disassembly).

 I'd recommend the static this solution in order to ensure you are not
 accidentally killing performance by just using that AA.

 A while back, Don suggested that all literals should be considered
 immutable.  I agree with him, but Walter still doesn't.  If all
 literals are immutable, then they could be truly constructed at
 compile-time.

 -Steve
I'm happy with the static this solution so will leave well alone. I
generally keep mutable and immutable data structures apart so I tend to
agree that literals should be immutable although of course I'm not aware
of the pros and cons.

bob


Re: Associative arrays give compile error

2010-10-05 Thread bearophile
Denis Koroskin:

 import std.stdio;
 import std.typecons;
 
 void main()
 {
   auto aa = [hello: tuple(100.0, 6100.0)];
   auto result = aa[hello];
   
   writeln(result.field[0],  , result._1); // primary and alternative way
 }

Now Tuples accept the natural syntax too:
writeln(result[0],  , result[1]);



Bob Cowdery:

 enum E_MODE
 {
   LSB,//  0
   USB,//  1
   DSB,//  2
   CWL,//  3
   CWU,//  4
   FMN,//  5
   AM,//  6
   DIGU,//  7
   SPEC,//  8
   DIGL,//  9
   SAM,// 10
   DRM// 11
 }
 // Associative array for translation
 auto A_MODE = [
 LSB: E_MODE.LSB,
 USB: E_MODE.USB,
 DSB: E_MODE.DSB,
 CWL: E_MODE.CWL,
 CWU: E_MODE.CWU,
 FMN: E_MODE.FMN,
 AM: E_MODE.AM,
 DIGU: E_MODE.DIGU,
 SPEC: E_MODE.SPEC,
 DIGL: E_MODE.DIGL,
 SAM: E_MODE.SAM,
 DRM: E_MODE.DRM
 ];

I suggest code similar to:

enum E_MODE {
LSB,  //  0
USB,  //  1
DSB,  //  2
CWL,  //  3
CWU,  //  4
FMN,  //  5
AM,   //  6
DIGU, //  7
SPEC, //  8
DIGL, //  9
SAM,  // 10
DRM   // 11
}

void main() {
// associative array for translation
with (E_MODE) immutable auto a_mode = [
LSB:  LSB,
USB:  USB,
DSB:  DSB,
CWL:  CWL,
CWU:  CWU,
FMN:  FMN,
AM:   AM,
DIGU: DIGU,
SPEC: SPEC,
DIGL: DIGL,
SAM:  SAM,
DRM:  DRM
];
}

Bye,
bearophile


Re: Associative arrays give compile error

2010-10-05 Thread bearophile
 enum E_MODE {
 LSB,  //  0
 USB,  //  1
 DSB,  //  2
 CWL,  //  3
 CWU,  //  4
 FMN,  //  5
 AM,   //  6
 DIGU, //  7
 SPEC, //  8
 DIGL, //  9
 SAM,  // 10
 DRM   // 11
 }
 
 void main() {
 // associative array for translation
 with (E_MODE) immutable auto a_mode = [
 LSB:  LSB,
 USB:  USB,
 DSB:  DSB,
 CWL:  CWL,
 CWU:  CWU,
 FMN:  FMN,
 AM:   AM,
 DIGU: DIGU,
 SPEC: SPEC,
 DIGL: DIGL,
 SAM:  SAM,
 DRM:  DRM
 ];
 }

That code of mine is not good. The following version is more DRY, and in theory 
it's a better, but in practice it doesn't work:


import std.stdio: writeln;

enum E_MODE {
LSB,
USB,
DSB,
CWL,
CWU,
FMN,
AM,
DIGU,
SPEC,
DIGL,
SAM,
DRM
}

/*immutable*/ E_MODE[string] a_mode;

static this () {
foreach (m; __traits(allMembers, E_MODE))
mixin(`a_mode[` ~ m ~ `] = E_MODE.` ~ m ~ `;`);
}

void main() {
writeln(a_mode);
}

Bye,
bearophile


Re: Associative arrays give compile error

2010-10-05 Thread bearophile
 /*immutable*/ E_MODE[string] a_mode;
 
 static this () {
 foreach (m; __traits(allMembers, E_MODE))
 mixin(`a_mode[` ~ m ~ `] = E_MODE.` ~ m ~ `;`);
 }

How do you build an immutable AA that is global or local to a function?

Bye,
bearophile


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Wed, 06 Oct 2010 03:45:11 +0400, bearophile bearophileh...@lycos.com  
wrote:



/*immutable*/ E_MODE[string] a_mode;

static this () {
foreach (m; __traits(allMembers, E_MODE))
mixin(`a_mode[` ~ m ~ `] = E_MODE.` ~ m ~ `;`);
}


How do you build an immutable AA that is global or local to a function?

Bye,
bearophile


I found the following to work fine:

K[V] assocArray = createAssocArray();

K[V] createAssocArray()
{
K[V] assocArray = [
   k1: v1,
   k2: v2,
   ...
];

return assocArray;
}

No idea why the following:

K[V] assocArray = [
   k1: v1,
   k2: v2,
   ...
];

doesn't work directly for global scope.


Re: Associative arrays give compile error

2010-10-05 Thread bearophile
Denis Koroskin:

 I found the following to work fine:
 
 K[V] assocArray = createAssocArray();
 
 K[V] createAssocArray()
 {
  K[V] assocArray = [
 k1: v1,
 k2: v2,
 ...
  ];
 
  return assocArray;
 }

Thank you for your answer. But I need to compute it, so I don't have just an AA 
literal. And I'd like it to be immutable :-)

Bye,
bearophile


Re: Associative arrays give compile error

2010-10-05 Thread Denis Koroskin
On Wed, 06 Oct 2010 04:14:37 +0400, bearophile bearophileh...@lycos.com  
wrote:



Denis Koroskin:


I found the following to work fine:

K[V] assocArray = createAssocArray();

K[V] createAssocArray()
{
 K[V] assocArray = [
k1: v1,
k2: v2,
...
 ];

 return assocArray;
}


Thank you for your answer. But I need to compute it, so I don't have  
just an AA literal. And I'd like it to be immutable :-)


Bye,
bearophile


Compute mutable copy and then cast to immutable. Am I missing something?


Re: Associative arrays give compile error

2010-10-05 Thread bearophile
Denis Koroskin:

 Compute mutable copy and then cast to immutable. Am I missing something?

That's possible. But it's an exceptionally dirty thing, I am not sure it works 
in SafeD. A well designed const system has to offer a more clean solution :-) 
Do you agree?

Bye,
bearophile


Re: associative arrays: to sort or not to sort?

2010-07-21 Thread BCS

Hello Mario,


Unless JSON requiers that the keys be in some order,


No, JSON does not require the names of an object to be in alphabetical
order.


the correct solution is to make the check order independent. For
example:
string s = CallReturningJSON();
s = replace(s,`a:23.54`, `X`);
s = replace(s,`b:0.0012`, `X`);
s = replace(s,`{nested:{X,X}}`, `X`);
s = replace(s,`goodbye:[true,or,false,[test,42,X]]`, `X`);
s = replace(s,`array:[12,null,{}]`, `Y`);
s = replace(s,is\n\ngreat, `Z`);
s = replace(s,`json:Z`, `Y`);
s = replace(s,`hello:{Y,Y}`, `X`);
assert(s == `{X,X}`);.


But this is lengthy and seems to lack additional assert checks.



It's a little wordy but it has one line per things it is checking. And adjusting 
it to give more asserts is trivial.




Until then, broken unit tests pass...



Spot on. The unittest is broken. Not the thing it's testing and not foreach.

--
... IXOYE





Re: associative arrays: to sort or not to sort?

2010-07-21 Thread Mario Kroeplin
  the correct solution is to make the check order independent. For
  example:
  string s = CallReturningJSON();
  s = replace(s,`a:23.54`, `X`);
  s = replace(s,`b:0.0012`, `X`);
  s = replace(s,`{nested:{X,X}}`, `X`);
  s = replace(s,`goodbye:[true,or,false,[test,42,X]]`, `X`);
  s = replace(s,`array:[12,null,{}]`, `Y`);
  s = replace(s,is\n\ngreat, `Z`);
  s = replace(s,`json:Z`, `Y`);
  s = replace(s,`hello:{Y,Y}`, `X`);
  assert(s == `{X,X}`);.
 
  But this is lengthy and seems to lack additional assert checks.
 
 It's a little wordy but it has one line per things it is checking. And 
 adjusting it to give more asserts is trivial.

The order of name/value pairs in JSON objects is as unspecified as the order of 
foreach iteration for associative arrays.
So, agreed, you would have to unittest a serialization against all permutations.
But then, JSON has a jew more unspecified gaps like whitespace can be inserted 
between any pair of tokens.
Shall we rely on the fact that the implementation currently does not insert 
whitespace between tokens?
This would work for the unittest of std.json, but what's with the unittest of 
an implementation using std.json?
Or, shall we implement a tokenizer in the unittest to get rid of extra 
whitespace between tokens?

  Until then, broken unit tests pass...
 
 Spot on. The unittest is broken. Not the thing it's testing and not foreach.

Maybe, the thing under test is not broken.
But there seems to be something wrong with the thing when it forces you to 
examine the unspecified result of toString in a unittest.
I mean, it would have been easy for the author of the code to provide 
toCanonicalJSON, and a lot easier for users of the code.

And, of course, foreach is not broken.
But D removes a lot of unspecified gaps that make life hard in C or C++.
And you have to provide opCmp in order to put your own keys into an associative 
array, so why don't you get them out in order?

However, let's get things done: can the attached unittest be an acceptatble 
replacement for the broken one of std.json?
begin 644 json-unittest.d
M=6YI='1EW0@PH@(`...@+r\@06X@;W9EFQY('-I;7!L92!T97-T('-U:71E
M+!I9B!I=!C86X@%Rv...@82!s97)I86QIF5D('-TFEN9R!A;F0*(`@
M(\O('1h...@=7-e('1H92!R97-U;'1I;F@=F%L=65S('1r...@=\...@9v5n
M97)A=4...@86x@:61E;G1I8V%LB`@(`O+R!S97)I86QIF%T:6]N+!B;W1H
M('1H92!D96-O95R(%N9!E;F-O95R('=Of...@h*(`@($I33TY686QU
M92!V86QU93L*(`@('-TFEN9R!JV]N.PH@(`@B`@(!V86QU92`]('!A
MG-E2E-/3BA@;G5L;`I+!AW-EG0H=]*4T].*9V86QU92D@/3...@8YU
M;q...@*3l*(`@('9A;'5E(#T@%RV5*4T].*!TG5E8DL(%SV5R=AT
M;TI33TXH)G9A;'5E*2`]/2...@=')U96`I.PH@(`...@=f%l=64@/2!P87)S94I3
M3TXH89A;'-E8DL(%SV5R=AT;TI33TXH)G9A;'5E*2`]/2...@9f%lV5@
M*3L*(`@('9A;'5E(#T@%RV5*4T].*`P8DL(%SV5R=AT;TI33TXH
M)G9A;'5E*2`]/2!@,`I.PH@(`...@=f%l=64@/2!P87)S94I33TXH8#$R,V`I
M+!AW-EG0H=]*4T].*9V86QU92D@/3...@8#$r,V`I.PH@(`...@=f%l=64@
M/2!P87)S94I33TXH8TT,S(Q8DL(%SV5R=AT;TI33TXH)G9A;'5E*2`]
M/2...@+30s,c...@*3l*(`@('9A;'5E(#T@%RV5*4T].*`P+C(S8DL(%S
MV5R=AT;TI33TXH)G9A;'5E*2`]/2!@,XR,V`I.PH@(`...@=f%l=64@/2!P
M87)S94I33TXH8TP+C(S8DL(%SV5R=AT;TI33TXH)G9A;'5E*2`]/2!@
M+3`N,c...@*3l*(`@('9A;'5E(#T@%RV5*4T].*!N=6QL8DL(%SV5R
M=AT;TI33TXH)G9A;'5E*2`]/2!@;G5L;`I.PH@(`...@=f%l=64@/2!P87)S
M94I33TXH8(B8DL(%SV5R=AT;TI33TXH)G9A;'5E*2`]/2!@(B)@*3L*
M(`@('9A;'5E(#T@%RV5*4T].*`Q+C(R,V4K,c...@*2p@87-S97)T*'1O
M2E-/3...@f=f%l=64i(#T](`Q+C(R,V4K,c...@*3l*(`@('9A;'5E(#T@%R
MV5*4T].*`B:5L;];G=OFQD(F`I+!AW-EG0H=]*4T].*9V86QU
M92D@/3...@8)H96QL;UQN=V]R;0B8D[B`@(!V86QU92`]('!AG-E2E-/
M3BA@(EPB7%Q+UQB79;EQR7'0B8DL(%SV5R=AT;TI33TXH)G9A;'5E
M*2`]/2!@(EPB7%Q+UQB79;EQR7'0B8D[B`@(!V86QU92`]('!AG-E
M2E-/3...@6uu@*...@87-s97)T*'1O2E-/3...@f=f%l=64i(#T](!;76`I.PH@
M(`...@=f%l=64@/2!P87)S94I33TXH8%LQ,BPB9F]O(BQTG5E+9A;'-E76`I
M+!AW-EG0H=]*4T].*9V86QU92D@/3...@8%lq,BPB9F]O(BQTG5E+9A
M;'-E76`I.PH@(`...@=f%l=64@/2!P87)S94I33TXH8'M]8DL(%SV5R=AT
M;TI33TXH)G9A;'5E*2`]/2!@w...@*3l*(`@('9A;'5E(#T@%RV5*4T].
M*![(F$B.C$L(F(B.FYU;Q]8D[@H@(`@:G-O;B`]('1O2E-/3...@f=f%l
m=64i...@+r\@;W)D97(@;V8@;F%M92]V86QU92!P86ERR!I;B!*4T].(]B
M:F5C=',@:7,@=6YS5C:69I960*(`@(%SV5R=AJV]N(#T](![(F$B
M.C$L(F(B.FYU;Q]8!\?!JV]N(#T](![(F(B.FYU;PL(F$B.C%]8D[
M@H@(`...@=f%l=64@/2!P87)S94I33TXH8'LB:5L;\B.GLB:G-O;B(Z(FES
M(=R96%T(BPB87)R87DB.ELQ,BQN=6QL+'M]77TL8`H@(`@(`@(`@(`@
M(`@(`@(`...@8)G;V]D8GEE(CI;=')U92PB;W(B+9A;'-E+%LB=5S=(L
M-#(LR)N97-T960B.GLB82(Z,C,N-30L(F(B.C`N,#`Q,GU]75U]8D[B`@
M(!JV]N(#...@=]*4T].*9V86QU92D[(`O+R!OF1EB!O9B!N86UE+W9A
M;'5E('!A:7)S(EN($I33TX@;V)J96-TR!IR!U;G-P96-I9FEE9`H@(`@
M87-S97)T*EN95X3V8H:G-O;b...@8'LB:G-O;B(Z(FES(=R96%T(BPB87)R
M87DB.ELQ,BQN=6QL+'m]...@*2`a/2`M,2!\?`H@(`@(`@(`@(EN95X
M3V8H:G-O;b...@8'LB87)R87DB.ELQ,BQN=6QL+'M]72PB:G-O;B(Z(FES(=R
M96%T(g...@*2`a/2`M,2D[B`@(!JV]N(#T@F5P;%C92AJV]N+!@R)J
MV]N(CHB:7,@9W)E870B+)AG)A2(Z6S$R+YU;PLWU=?6`L(![(F%R
MF%Y(CI;,3(L;G5L;Q[?5TL(FIS;VXB.B)IR!GF5A=)]8D[B`@(!A
MW-EG0H:6YD97A/9BAJV]N+!@R)A(CHR,RXU-PB8B(Z,XP,#$R?6`I
M($](TQ('Q\B`@(`@(`@(`@:6YD97A/9BAJV]N+!@R)B(CHP+C`P
M,3(L(F$B.C(S+C4T?6`I($](TQ*3L*(`@(!JV]N(#T@F5P;%C92AJ

Re: associative arrays: to sort or not to sort?

2010-07-21 Thread BCS

Hello Mario,


But then, JSON has a jew more unspecified gaps like whitespace can be
inserted between any pair of tokens.



That can be dealt with by just being consistent.


Shall we rely on the fact that the implementation currently does not
insert whitespace between tokens?


On the output side, why not? The unit test is for this implementation after 
all.




And you have to provide opCmp in order to put your own keys into an
associative array, so why don't you get them out in order?


That's because AA's use closed hashing with tree used to deal with col3sions.



However, let's get things done: can the attached unittest be an
acceptatble replacement for the broken one of std.json?



Move line 35 and 38 up one place each and you can drop the check for 
permutations.

--
... IXOYE





Re: associative arrays: to sort or not to sort?

2010-07-20 Thread Mario Kroeplin
 Unless JSON requiers that the keys be in some order,

No, JSON does not require the names of an object to be in alphabetical order.

 the correct solution is to make the check order independent. For example:
 string s = CallReturningJSON();
 s = replace(s,`a:23.54`, `X`);
 s = replace(s,`b:0.0012`, `X`);
 s = replace(s,`{nested:{X,X}}`, `X`);
 s = replace(s,`goodbye:[true,or,false,[test,42,X]]`, `X`);
 s = replace(s,`array:[12,null,{}]`, `Y`);
 s = replace(s,is\n\ngreat, `Z`);
 s = replace(s,`json:Z`, `Y`);
 s = replace(s,`hello:{Y,Y}`, `X`);
 assert(s == `{X,X}`);.

But this is lengthy and seems to lack additional assert checks.

One way out could be to avoid real-world examples in the unittest.
For the simple example of std.json that is only broken in theory, the correct 
solution could be:

assert(s == `{a:1,b:null}` || s == `{b:null,a:1}`)

But now assume, I want to implement a JSON-RPC encoder that uses std.json.
A JSON-RPC request object has up to four name/value pairs (jsonrpc, method, 
params, id).
Instead of only 2!, I now have 4! (too many) possible orders to check in the 
unittest of the JSON-RPC encoder.

The unspecified order of the foreach iteration does not only affect the 
unittest of std.json, but also leaks out to far away implementations using 
std.json.
The same is true for std.xml:

assert(s == `tag goodbye=1 hello=0/`);

may pass today, but is broken in theory!
You have to notice that XML attributes are stored in an associative array and 
that toString is implemented using foreach.
Until then, broken unit tests pass...

This is a problem, isn't it?


Re: associative arrays: to sort or not to sort?

2010-07-18 Thread BCS

Hello Mario,


That is, shall we produce canonical JSON text at the price of

efficiency.

Or, shall the perfect implementation of JSON objects as associative
arrays be dropped?

Or, what else?



Unless JSON requiers that the keys be in some order, the correct solution 
is to make the check order independent. For example:


string s = CallReturningJSON();

s = replace(s,`a:23.54`, `X`);
s = replace(s,`b:0.0012`, `X`);
s = replace(s,`{nested:{X,X}}`, `X`);
s = replace(s,`goodbye:[true,or,false,[test,42,X]]`, `X`);
s = replace(s,`array:[12,null,{}]`, `Y`);
s = replace(s,is\n\ngreat, `Z`);
s = replace(s,`json:Z`, `Y`);
s = replace(s,`hello:{Y,Y}`, `X`);
assert(s == `{X,X}`);.

--
... IXOYE





Re: associative arrays with arrays as value

2009-04-19 Thread bearophile
MLT:
 Why is that?

I think this is the right syntax (I am using Phobos on D1):

import std.stdio: writefln;
void main() {
int[5][string] aa = [a: [1, 2, 3, 4, 5]];
aa[b][] = aa[a]; # line 5
writefln(aa);
}

But it gives an:
Error: ArrayBoundsError temp(5)
It looks like a bug. Static arrays will need to be improved in D, they have lot 
of bugs/limits.

Note that in the current D there's a way to walk around that problem, you can 
wrap your static array into a struct. Here I use my Record (from my dlibs) that 
defines on the fly a struct that has several smart methods, among them there 
are opEquals, onHash, opCmp, toString, etc:
http://www.fantascienza.net/leonardo/so/libs_d.zip

import std.stdio: writefln;
import d.templates: Record;
import d.string: putr;

alias Record!(int[5]) R;

void main() {
R[string] aa = [a: R([1, 2, 3, 4, 5])];
aa[b] = aa[a];
writefln(aa);
putr(aa);
}

This works, and prints:
[a:record([1, 2, 3, 4, 5]),b:record([1, 2, 3, 4, 5])]
[a: record([1, 2, 3, 4, 5]), b: record([1, 2, 3, 4, 5])]

Bye,
bearophile