Mimicking C++'s indexing behavior in D associative arrays

2015-02-17 Thread Matt Kline via Digitalmars-d-learn
In C++, the index operator for maps will either return a 
reference to the existing value if the key can be found, or a 
reference to a new, default-initialized value if one with the 
given key cannot be found.


In D, an exception is thrown instead when a value with the given 
key cannot be found, similar to unordered_map::at in C++. So if I 
want to mimic the same behavior (get or initialize to default), I 
have to do something like


// Assume bar is some associative array of type Foo[string]
Foo* value = key in bar;
if (value) {
bar[key] = Foo.init;
value = bar[key];
}
This seems sub-optimal, given that in involves three hashes (two 
lookups and one insertion). Is there a more efficient or cleaner 
way to do so?


Re: Mimicking C++'s indexing behavior in D associative arrays

2015-02-17 Thread Matt Kline via Digitalmars-d-learn

On Wednesday, 18 February 2015 at 00:21:11 UTC, Matt Kline wrote:


if (value) {


should of course be

 if (!value) {

Sorry for the typo.


Re: BigFloat?

2015-02-17 Thread Vlad Levenfeld via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 14:03:45 UTC, Kagamin wrote:
On Tuesday, 17 February 2015 at 09:08:17 UTC, Vlad Levenfeld 
wrote:
For my use case I'm less concerned with absolute resolution 
than with preserving the information in the smaller operand 
when dealing with large magnitude differences.


What do you mean? As long as you don't change the operand, it 
will preserve its value.


If you add or subtract two floating point numbers whose 
magnitudes differ, then the lower bits of the smaller operand 
will be lost in the result. If the magnitudes are different 
enough, then the result of the operation could even be equal to 
the larger operand. In vivo: http://dpaste.dzfl.pl/870c5e61d276


Dividing D Module between multiple files

2015-02-17 Thread Muahmmad Adel via Digitalmars-d-learn
I have searched online and I found no way for dividing D Module 
between multiple files.


While other languages move to making classes distributed on 
multiple files (like C#'s partial classes), D is moving in the 
opposite direction, and makes a bigger code unit in one file.


Biding every module to single file means large files, with high 
probability of merge conflicts (as more developers are working on 
the same file) makes separating developer's code from IDE 
generated code more difficult.


I need to understand the rationale behind binding the module to 
the file. Although Alexandrescu explained rationale behind 
different language design decisions in his book, he didn't 
explain this one.


Thanks



Re: Dividing D Module between multiple files

2015-02-17 Thread Daniel Kozák via Digitalmars-d-learn

On Wed, 18 Feb 2015 07:23:24 +
Muahmmad Adel via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 I have searched online and I found no way for dividing D Module 
 between multiple files.
 
 While other languages move to making classes distributed on 
 multiple files (like C#'s partial classes), D is moving in the 
 opposite direction, and makes a bigger code unit in one file.
 
 Biding every module to single file means large files, with high 
 probability of merge conflicts (as more developers are working on 
 the same file) makes separating developer's code from IDE 
 generated code more difficult.
 
 I need to understand the rationale behind binding the module to 
 the file. Although Alexandrescu explained rationale behind 
 different language design decisions in his book, he didn't 
 explain this one.
 
 Thanks
 

You are not force to do so I do not see any trouble here.

For eg. I have lots of file where I have only one class (similar to
java concept).


Re: BigFloat?

2015-02-17 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn
On Tuesday, 17 February 2015 at 09:08:17 UTC, Vlad Levenfeld 
wrote:

On Tuesday, 17 February 2015 at 08:05:49 UTC, Kagamin wrote:

Periodic fractions.


Or transcendental numbers, for that matter, but arbitrary != 
infinite. A max_expansion template parameter could be useful 
here.


For my use case I'm less concerned with absolute resolution 
than with preserving the information in the smaller operand 
when dealing with large magnitude differences.


We have rational (two bigint, one for the numerator and one for 
the denominator), which I like better than floatingpoint (it's 
more expressive).


Re: Type-Strict Indexes: IndexedBy

2015-02-17 Thread anonymous via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 13:38:41 UTC, Per Nordlöw wrote:
This looses most of the meaning of my idea. I still want my 
range to inherit all the powers of its wrapped range.


Is there no way to disable member functions in D?


I hadn't thought of @disable. Played around with it a bit. The 
following code seems to work. I didn't really test it or think 
very hard about it, though.


Regarding opIndexAssign: Without it, alias this jumps in on 
assignments, and the ref opIndex is not considered. This may be a 
compiler bug.


Be aware that with alias this, IndexedBy!(R, I) implicitly 
converts to R. So it's easy to (accidentally) fall back to a 
plain R, where nothing is `@disable`d. I don't know if this is 
desirable or not.



struct Ix(T = size_t)
{
@safe pure: @nogc nothrow:
this(T ix) { this._ix = ix; }
alias _ix this;
private T _ix = 0;
}

struct IndexedBy(R, I)
{
auto ref opIndex(I ix) inout { return _r[ix]; }
void opIndexAssign(V)(V value, I ix) {_r[ix] = value;}
alias RI = size_t; /* TODO: Extract this from R somehow. */
static if(!is(RI == I))
{
@disable void opIndex(RI i);
@disable void opIndexAssign(V)(V value, RI i);
}
R _r;
alias _r this;
}

auto indexedBy(I, R)(R range)
{
return IndexedBy!(R, I)(range);
}

unittest
{
import std.stdio;
auto x = [1, 2, 3];
alias I = int;
auto ix = x.indexedBy!I;
ix[0] = 11;

alias J = Ix!size_t;
auto jx = x.indexedBy!J;
jx[J(0)] = 11;
static assert(!__traits(compiles, (jx[0] = 11)));
}



Re: Type-Strict Indexes: IndexedBy

2015-02-17 Thread via Digitalmars-d-learn

On Monday, 16 February 2015 at 20:17:55 UTC, anonymous wrote:
Remove that `alias _r this;`. You don't want to forward 
opIndex, so you can't use alias this which forwards everything 
that doesn't compile. opDispatch may be an option to forward 
everything but opIndex.


This looses most of the meaning of my idea. I still want my range 
to inherit all the powers of its wrapped range.


Is there no way to disable member functions in D?


Re: How to pass -rpath=$ORIGIN to the linker via dub?

2015-02-17 Thread Gary Willoughby via Digitalmars-d-learn

On Monday, 16 February 2015 at 23:49:31 UTC, 岩倉 澪 wrote:
I'm looking to manage my current project with dub, but there is 
one problem that has been getting in my way. I want to use 
`-rpath=$ORIGIN`, which I can pass with `-L-rpath=\$ORIGIN` 
when directly invoking the compiler, but when putting 
`-rpath=$ORIGIN` or `-rpath=\$ORIGIN` in lflags, dub 
complains - Error executing command build: Invalid variable: 
ORIGIN.


I am unsure of what I am missing; any help would be greatly 
appreciated :)


This may be a bug in dub. Try posting here:
http://forum.rejectedsoftware.com/groups/rejectedsoftware.dub/


Re: BigFloat?

2015-02-17 Thread Kagamin via Digitalmars-d-learn
On Tuesday, 17 February 2015 at 09:08:17 UTC, Vlad Levenfeld 
wrote:
For my use case I'm less concerned with absolute resolution 
than with preserving the information in the smaller operand 
when dealing with large magnitude differences.


What do you mean? As long as you don't change the operand, it 
will preserve its value.


Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 19:17:42 UTC, Paul wrote:
I don't understand the error and Google doesn't help - can it 
be fixed or am I just using the wrong approach?


Trying to create it as a global tries to make it as a static 
variable which means it constructs at compile time. It can't 
access the TERM environment variable at compile time and that 
causes the error.


Putting Terminal at global scope isn't really ideal, there'd be 
potential destructor problems (the terminal needs to be cleaned 
up at program termination). You could stick a pointer to it up 
there though:



Terminal* terminal; // maybe make it shared too but i'd try to 
avoid that, terminal isn't quite thread safe



void main() {
   auto main_terminal = Terminal(options...);
   terminal = main_terminal;
   scope(exit) terminal = null; // clean up the pointer too when 
it goes invalid

   // the rest of your program goes normally
   // and other functions can use the global pointer
}



Just make sure you set it in main before doing anything else so 
the pointer isn't null and you should be good to go. Then when 
main returns, it will clean up.


Error: getenv cannot be interpreted at compile time

2015-02-17 Thread Paul via Digitalmars-d-learn
I'd like to create a Terminal using terminal.d and make it 
available across several source files (as a global rather than 
having to pass it around) but when I define it like this in 
global scope:


Terminal Screen = Terminal(ConsoleOutputType.cellular);

I get this error:

Error: getenv cannot be interpreted at compile time, because it 
has no available source code


I don't understand the error and Google doesn't help - can it be 
fixed or am I just using the wrong approach?


TIA

Paul


Re: what is the offical way to handle multiple list in map() ?

2015-02-17 Thread Ali Çehreli via Digitalmars-d-learn

On 02/16/2015 01:51 AM, Baz wrote:

 For each language there is a column about handing multiple
 list, i thought it could be a good idea to see how D handle
 this:

I've updated the page with my understanding:

  http://en.wikipedia.org/wiki/Map_(higher-order_function)

I think they mean walking the lists in sync:

import std.stdio;
import std.algorithm;
import std.typecons;
import std.range;

int func(int a)
{
return a * 2;
}

auto func(Tuple!(int, int) t)
{
return t[0] + t[1];
}

void main()
{
{
auto list = [ 1, 10, 100 ];
auto result = list.map!func;

writeln(result);
}

{
auto list1 = [ 1, 10, 100 ];
auto list2 = [ 2, 20, 200 ];
auto result = zip(list1, list2).map!func;  // -- HERE

writeln(result);
}
}

Ali



Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread ketmar via Digitalmars-d-learn
On Tue, 17 Feb 2015 19:56:19 +, Paul wrote:

 I see, thanks once again :D I don't know why the environment variable
 isn't accessible at compilation (from a terminal)

'cause you can't execute C code in CTFE.

signature.asc
Description: PGP signature


Re: A specifier readf() for BigInt

2015-02-17 Thread Dennis Ritchie via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 07:20:19 UTC, Ivan Kazmenko wrote:


The readf function does not seem to support reading BigInts 
directly.


However, you can read a string and construct a BigInt from it, 
either by std.conv.to or directly invoking the constructor:


import std.algorithm, std.bigint, std.conv, std.stdio, 
std.string;


void main () {
// read a line of space-separated BigInts and print their 
sum:

readln.split.map !(to!BigInt).sum.writeln;
// read a line containing one BigInt and print it squared:
auto s = BigInt (readln.strip);
writeln (s ^^ 2);
}


Thanks.


Re: Type-Strict Indexes: IndexedBy

2015-02-17 Thread Nordlöw

On Tuesday, 17 February 2015 at 15:02:05 UTC, anonymous wrote:
I hadn't thought of @disable. Played around with it a bit. The 
following code seems to work. I didn't really test it or think 
very hard about it, though.


Superb! I'd like to see this getting into std.typecons.

Having this in the language will attract (more) Ada programmers 
to D.


Should I do PR for std.typecons.[iI]ndexedBy?


Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread Paul via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 19:35:27 UTC, H. S. Teoh wrote:
On Tue, Feb 17, 2015 at 07:17:41PM +, Paul via 
Digitalmars-d-learn wrote:
I'd like to create a Terminal using terminal.d and make it 
available
across several source files (as a global rather than having to 
pass it

around) but when I define it like this in global scope:

Terminal Screen = Terminal(ConsoleOutputType.cellular);

I get this error:

Error: getenv cannot be interpreted at compile time, because 
it has no

available source code

I don't understand the error and Google doesn't help - can it 
be fixed

or am I just using the wrong approach?

[...]

The problem is that the Terminal constructor reads runtime 
information
from the OS, so it cannot be run at compile-time. What you need 
to do is

to initialize it at runtime inside a static this() block:

Terminal* screen;
static this() {
*screen = Terminal(ConsoleOutputType.cellular);
}

Note that you have to use a pointer, because the Terminal 
struct does

not allow default construction of a Terminal.

However, this isn't the end of the story... because the Terminal
destructor also resets the terminal back to its original state 
--
otherwise after the program exits, you'll be stuck in cellular 
mode,
which may not be very nice on some systems where the shell will 
get very
confused (or rather, the user will see gibberish and not 
understand

what's going on).

So the *correct* approach is to initialize the Terminal struct 
in

main(), so that when main() exits it will clean up properly:

Terminal* screen;
void main(string[] args) {
// Create the Terminal here
auto term = Terminal(ConsoleOutputType.cellular);
screen = term; // so that everybody else can see it

... // main program goes here
} // Terminal will clean up properly here

It's a bit ugly, but it should work. At least, that's what I do 
in my

own programs that use terminal.d. :-)


T


Got it, I thought it might be something like this but when I 
tried to do:


Terminal screen;

...and initialise it later it failed because of the disabled 
default constructor.


There doesn't seem to be an alternative to using a pointer as 
it's rather a large struct to pass to functions as is!


which was falling


Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Feb 17, 2015 at 07:17:41PM +, Paul via Digitalmars-d-learn wrote:
 I'd like to create a Terminal using terminal.d and make it available
 across several source files (as a global rather than having to pass it
 around) but when I define it like this in global scope:
 
 Terminal Screen = Terminal(ConsoleOutputType.cellular);
 
 I get this error:
 
 Error: getenv cannot be interpreted at compile time, because it has no
 available source code
 
 I don't understand the error and Google doesn't help - can it be fixed
 or am I just using the wrong approach?
[...]

The problem is that the Terminal constructor reads runtime information
from the OS, so it cannot be run at compile-time. What you need to do is
to initialize it at runtime inside a static this() block:

Terminal* screen;
static this() {
*screen = Terminal(ConsoleOutputType.cellular);
}

Note that you have to use a pointer, because the Terminal struct does
not allow default construction of a Terminal.

However, this isn't the end of the story... because the Terminal
destructor also resets the terminal back to its original state --
otherwise after the program exits, you'll be stuck in cellular mode,
which may not be very nice on some systems where the shell will get very
confused (or rather, the user will see gibberish and not understand
what's going on).

So the *correct* approach is to initialize the Terminal struct in
main(), so that when main() exits it will clean up properly:

Terminal* screen;
void main(string[] args) {
// Create the Terminal here
auto term = Terminal(ConsoleOutputType.cellular);
screen = term; // so that everybody else can see it

... // main program goes here
} // Terminal will clean up properly here

It's a bit ugly, but it should work. At least, that's what I do in my
own programs that use terminal.d. :-)


T

-- 
Too many people have open minds but closed eyes.


Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread Paul via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 19:29:52 UTC, Adam D. Ruppe wrote:

On Tuesday, 17 February 2015 at 19:17:42 UTC, Paul wrote:
I don't understand the error and Google doesn't help - can it 
be fixed or am I just using the wrong approach?


Trying to create it as a global tries to make it as a static 
variable which means it constructs at compile time. It can't 
access the TERM environment variable at compile time and that 
causes the error.


Putting Terminal at global scope isn't really ideal, there'd be 
potential destructor problems (the terminal needs to be cleaned 
up at program termination). You could stick a pointer to it up 
there though:



Terminal* terminal; // maybe make it shared too but i'd try to 
avoid that, terminal isn't quite thread safe



void main() {
   auto main_terminal = Terminal(options...);
   terminal = main_terminal;
   scope(exit) terminal = null; // clean up the pointer too 
when it goes invalid

   // the rest of your program goes normally
   // and other functions can use the global pointer
}



Just make sure you set it in main before doing anything else so 
the pointer isn't null and you should be good to go. Then when 
main returns, it will clean up.


I see, thanks once again :D I don't know why the environment 
variable isn't accessible at compilation (from a terminal) but 
that's OS business I guess rather than D related.


I did try something similar to your solution but not using a 
pointer - I'd prefer to avoid using pointers if at all possible!


Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 20:06:15 UTC, Paul wrote:
There doesn't seem to be an alternative to using a pointer as 
it's rather a large struct to pass to functions as is!


yeah, copying is disabled too. The struct isn't big in memory 
terms (it has few actual data members) but since the destructor 
does a bunch of things, you wouldn't want it being called often, 
so a pointer to one made in main is the way to go.


Re: BigFloat?

2015-02-17 Thread Kagamin via Digitalmars-d-learn

Periodic fractions.


Re: Error: getenv cannot be interpreted at compile time

2015-02-17 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Feb 17, 2015 at 07:56:19PM +, Paul via Digitalmars-d-learn wrote:
[...]
 I see, thanks once again :D I don't know why the environment variable isn't
 accessible at compilation (from a terminal) but that's OS business I guess
 rather than D related.

Even if you *could* access it at compile time, you don't necessarily
want to -- for example, if you distribute your program to other users,
they would be stuck with the terminal settings you had while compiling,
rather than adapting to *their* environment at runtime. If your terminal
doesn't match theirs, it would screw up big time. :-)


T

-- 
Shin: (n.) A device for finding furniture in the dark.


Re: BigFloat?

2015-02-17 Thread Vlad Levenfeld via Digitalmars-d-learn

On Tuesday, 17 February 2015 at 08:05:49 UTC, Kagamin wrote:

Periodic fractions.


Or transcendental numbers, for that matter, but arbitrary != 
infinite. A max_expansion template parameter could be useful here.


For my use case I'm less concerned with absolute resolution than 
with preserving the information in the smaller operand when 
dealing with large magnitude differences.