Re: core.sys.posix.unistd link error

2013-09-22 Thread Ruslan Mullakhmetov


Didn't catch. How can I use it at runtime? I can not link to 
actually C function?


On Saturday, 21 September 2013 at 19:40:48 UTC, Jonathan M Davis 
wrote:
On Saturday, September 21, 2013 20:30:00 Ruslan Mullakhmetov 
wrote:
i use pipe() syscall from my program. when i compile it I got 
the

following msg:

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

no available source code

how can i fix it?

dmd 2.063.2, Mac OS X


It sounds like you're trying to use pipe at compile time, and 
as the error
says, you can't use it at compile time, because no source code 
for it is
available. The same goes for all C functions. They can only be 
used at

runtime.

- Jonathan M Davis




Re: core.sys.posix.unistd link error

2013-09-22 Thread Ruslan Mullakhmetov


I found where the problem is.

I used a system call (external C function) in class ctor. then I 
declared global variable of this class and INITIALZIED that 
variable inplace. If i move initalization in module static this() 
everything compiles.


the code is:

incorrect version:
http://dpaste.com/hold/1391530/

correct:
http://dpaste.com/hold/1391523/


But now i need to sort out what the difference between
// global scope

int a = 10;

and

int a;

static this()
{
 a = 10;
}


I appreciate if somebody give a link or chapter number where to 
read.


Cannot use locat x as parameter to non-global template y

2013-09-22 Thread simendsjo
God, I hate these errors. Tried updating dmd head, and these 
started popping up.

Now I have to move all templates out...


Re: Cannot use locat x as parameter to non-global template y

2013-09-22 Thread bearophile

simendsjo:

God, I hate these errors. Tried updating dmd head, and these 
started popping up.

Now I have to move all templates out...


Can you show a small example of code that gives that error?

Bye,
bearophile


Re: Cannot use locat x as parameter to non-global template y

2013-09-22 Thread simendsjo

On Sunday, 22 September 2013 at 12:26:03 UTC, bearophile wrote:

simendsjo:

God, I hate these errors. Tried updating dmd head, and these 
started popping up.

Now I have to move all templates out...


Can you show a small example of code that gives that error?

Bye,
bearophile


Nope. I cannot get dustmite to work: 
https://github.com/CyberShadow/DustMite/issues/16


Re: Cannot use locat x as parameter to non-global template y

2013-09-22 Thread simendsjo

On Sunday, 22 September 2013 at 12:26:03 UTC, bearophile wrote:

simendsjo:

God, I hate these errors. Tried updating dmd head, and these 
started popping up.

Now I have to move all templates out...


Can you show a small example of code that gives that error?

Bye,
bearophile


dustmite for the win!

template A(T...) {
template B(alias T) { }
}

void main() {
void fv() {}
alias A!(fv) F;
F.B!F;
}

dmd -unittest t.d
t.d(8): Error: template instance B!(A!(fv)) cannot use local 
'A!(fv)' as parameter to non-global template B(alias T)


Regression or bugfix?

2013-09-22 Thread simendsjo
In 2.063.2, (T!int).stringof == T!(int). In current head, it's 
T!int.

Even (T!(int)).stringof == T!int.

So is this a regression bug or a bugfix?


Re: Cannot use locat x as parameter to non-global template y

2013-09-22 Thread simendsjo

On Sunday, 22 September 2013 at 13:36:48 UTC, simendsjo wrote:

On Sunday, 22 September 2013 at 12:26:03 UTC, bearophile wrote:

simendsjo:

God, I hate these errors. Tried updating dmd head, and these 
started popping up.

Now I have to move all templates out...


Can you show a small example of code that gives that error?

Bye,
bearophile


dustmite for the win!

template A(T...) {
template B(alias T) { }
}

void main() {
void fv() {}
alias A!(fv) F;
F.B!F;
}

dmd -unittest t.d
t.d(8): Error: template instance B!(A!(fv)) cannot use local 
'A!(fv)' as parameter to non-global template B(alias T)


Added a ticket too: 
http://d.puremagic.com/issues/show_bug.cgi?id=11098
Probably a dup of many of the other local aliasing tickets 
though..


join of range of ranges?

2013-09-22 Thread bearophile
In some cases I'd like to join a range of ranges in a single 
array/string (I know here the inner map could be replaced by 
something better, this code is just an example):



import std.algorithm: map;
import std.array: join, array;
void main() {
auto r1 = [1, 2]
  .map!(x = [1, 2].map!(y = '*').array)
  .join(_);
auto r2 = [1, 2]
  .map!(x = [1, 2].map!(y = '*'))
  .join(_);
}


The code works only if I add an 'array' inside, to turn it into a 
range of arrays. Do you think it's right to ask as enhancement 
for std.array.join to work with a range of ranges too, as in the 
r2 case?


Bye,
bearophile


Re: Regression or bugfix?

2013-09-22 Thread simendsjo

On Sunday, 22 September 2013 at 13:50:00 UTC, simendsjo wrote:
In 2.063.2, (T!int).stringof == T!(int). In current head, 
it's T!int.

Even (T!(int)).stringof == T!int.

So is this a regression bug or a bugfix?


Added a ticket so it doesn't get lost: 
http://d.puremagic.com/issues/show_bug.cgi?id=11100


Re: join of range of ranges?

2013-09-22 Thread David Nadlinger

On Sunday, 22 September 2013 at 14:26:14 UTC, bearophile wrote:
In some cases I'd like to join a range of ranges in a single 
array/string (I know here the inner map could be replaced by 
something better, this code is just an example):


std.algorithm.joiner, or am I missing something?

David


const and immutable members

2013-09-22 Thread Daniel Davidson
In this thread 
(http://forum.dlang.org/thread/uvhwkgljavskqfueq...@forum.dlang.org) 
I asked this:



3) Also, is storing immutable(STUFF) in a struct in the general
case (as opposed to just this one) useful or silly?


Johnathan M Davis replied:


As soon as you have a const or immutable member in a
struct, you can't ever assign anything to it, even if
all of its other members are mutable (you could
assign the individual, mutable members but not the
whole struct). That means stuff like if the struct is
ever default-initialized, you can't even give it
another value, which tends to mean that you can't use
such a struct in places like arrays.

All in all, I think that it's pretty much always a
bad idea to have a struct with const or immutable
members. It's just begging for problems. Tail-const
or tail-immutable is fine, because the members
themselves aren't const or immutable (just what they
refer to), but having them be directly const or
immutable is a bad idea IMHO.



I don't really understand the _tail-const_, _tail-immutable_ 
argument. Why is _tail-const_ fine but not _const_ when there is 
transitivity anyway?


I think there are only a handful of places you consider using 
const/immutable:


- Global variables
- Local variables
- Member variables
- Function signatures

Are there any missing?

If right out of the gate the feeling is member variables should 
not be const or immutable, doesn't that greatly reduce the value 
of the mutability specificiers? Members are used to hold onto the 
data for the lifecycle of the object and if those should not make 
claims or guarantees on mutability then that seems a shame.


What do others think?
Are there cases where const/immutable members are being used in a 
good way?


In that thread I gave a motivation for it (I used emacs and the 
formatting turned out awful - so sorry about that). But not sure 
if my logic holds water.


Thanks
Dan


Re: cast(immutable) vs extra variable

2013-09-22 Thread Ali Çehreli

On 09/19/2013 03:07 PM, Daniel Davidson wrote:

 Here is a setup: Data is coming in - say over the wire or from a
 database. It is very rich data with nestings of primitives, lists and
 string keyed associative arrays, recursively - think nested json. Once
 a data object is read in it is passed off to classes that use the data
 in read-only fashion.

And there are two types of read-only data:

const: A promise to not mutate

immutable: A requirement that nobody mutates either.

 So, for example, assume the root of the rich data is a Portfolio
 instance. All members of Portfolio recursively are public since it is
 really plain old data from one perspective and this makes using vibe
 json serialization simple. Assume that a user of Portfolio data is an
 Analyzer. This analyzer will need to do lots of complex operations
 with the portfolio that it uses in readonly fashion.

Yes, that sounds like immutable(Portfolio), as the Analyzer would not be 
happy if the data could mutate.


 It may have many
 mutable members for intermediate calculations.

 Here is a mockup http://pastebin.com/nBLFDgv6 which is making use of
 immutable(Portfolio) to ensure that (a) the analyzer does not modify
 the data and (b) no other code can modify the data. To achieve this
 there needs to be a point in time where the modifiable Portfolio is
 done being read and made immutable. At this point it is cast to
 immutable and henceforth only accessed that way.

I have added a couple of comments to you program:

import std.stdio;

struct Portfolio {
double[string] data;
// ...
}

struct HedgeRecommendation {
string recommendation;
this(int) {
recommendation = Sell, the market is rigged;
}
}

struct Analyzer {
// [Ali] Since you are worried about cost of copying, why not make 
this a

//   pointer as well?
immutable(Portfolio)* portfolio;
this(ref immutable(Portfolio) portfolio) {
// [Ali] Otherwise, this assignment would copy as well.
this.portfolio = portfolio;
}

HedgeRecommendation createHedge() {
auto result = HedgeRecommendation(1);
//...
return result;
}
}

// [Ali] If possible, make this function pure so that its return value can
//   automatically be casted to immutable.
Portfolio readPortfolio(string id) pure {
// read portfolio from database
return Portfolio([ IBM : 100.0, SPY : 300.0 ]);
}

HedgeRecommendation getHedgeRecommendation(string portfolioId) {
// [Ali] No explicit cast needed because of that 'pure'.
immutable(Portfolio) portfolio = readPortfolio(portfolioId);
auto analyzer = Analyzer(portfolio);
return analyzer.createHedge();
}

void main() {
writeln(getHedgeRecommendation(1234));
}

 Given this setup - what do you see as the trade-offs?

 What can not be done or will be challenging in face of refactor?

 What are some better alternatives/recommendations?

 I am a fan of D but my struggles with const/immutable transitivity
 feel endless and are wearing on me. I feel like having an ability to
 say something will not change and not using that ability is like being
 teased.

You are not alone. I tried to answer some of these questions in my DConf 
2013 talk. I think I have only scratched the surface:


  http://dconf.org/talks/cehreli.html

Ali



[Question] About mixin, template and alias

2013-09-22 Thread Michael

/// fire.d

import std.stdio;

alias void delegate() EventHandler;

class Event(T)
{
private T[] _events;

public void opOpAssign(string op)(T param) if (op == ~)
{
writeln(param.funcptr);
_events ~= param;
}

public void opCall(ParamType ...)(ParamType params)
{
emit(params);
}

protected void emit(ParamType ...)(ParamType params)
{
foreach (event; _events)
event(params);
}
}

mixin template AddEvent(DelegateType, string member)
{
auto eventObserver =  new Event!DelegateType();

mixin(alias eventObserver  ~ member ~ ;);
}

class Fire
{
public mixin AddEvent!(EventHandler, click);
}

/// water.d
import std.stdio;

import fire;

class Water : Fire
{

}

void main()
{
auto fire  = new Fire();
auto water = new Water();
water.click ~= () { writeln(Water!); };
fire.click  ~= () { writeln(Fire!);  };

fire.click();
}


Output:
Water!
Fire!

Someone can explain me a behaviour of above code? Why not Fire! 
only?


Re: [OT] Pathfinding algorithm

2013-09-22 Thread Ivan Kazmenko
On Saturday, 21 September 2013 at 15:49:00 UTC, rasmus svensson 
wrote:
Assuming the shortest path from from all nodes to every other 
node is already pre-computed:


What is a fast algorithm to update all paths, if one node is 
marked as inpassible.


Any good 3rd party library or research paper out there?


A short note on worst case complexity.  In a star graph, if you 
remove the central vertex, *all* paths between pairs of other 
vertices are affected (they become pairwise unreachable).  So, if 
there is a way to do it in less than V^2, it will at least have 
to store paths in some sophisticated way, better than just a VxV 
matrix with one element for each path.


Ivan Kazmenko.


Re: core.sys.posix.unistd link error

2013-09-22 Thread Jonathan M Davis
On Sunday, September 22, 2013 13:52:54 Ruslan Mullakhmetov wrote:
 But now i need to sort out what the difference between
 // global scope
 
 int a = 10;

That directly initializes the variable at compile time, meaning that whatever 
is used to initialize the variable must be callable at compile time. And the 
value must be able to be set at compile time and then be carried over to 
runtime. That will work with int, but it does not work with most stuff that's 
on the heap (like classes or AAs) - arrays would be the major exception to 
that, since they can be set at compile time (and I believe that it was 
recently changed so that immutable classes could be set at compile time, but 
not const or mutable ones - implementing that is rather complicated, and it 
may or may not ever happen). Over time, what you can do at compile time with 
CTFE (Compile Time Function Evaluation) has improved, but there are still 
restrictions, and some things will never be possible (e.g. I/O or calling C 
functions).

 and
 
 int a;
 
 static this()
 {
   a = 10;
 }

That does not set the variable at compile time. Rather, the static constructor 
sets it at runtime. So, this has none of the restrictions that directly 
initializing a module or static variable does. However, it does have the 
downside that two modules that have static constructors can't import each 
other (either directly or indirectly), because then the runtime wouldn't know 
which order to run them in. If you do that, you'll get an exception at runtime 
complaining about a circular import (which sucks, but unfortunately, the 
circular import can't always be detected at compile time - thanks in part to 
.di files - so runtime detection is the best that can be done). So, while 
static constructors can be really nice, you do have to avoid having modules 
that use them import each other, which means either being careful about how 
your modules import each other or avoiding static constructors. Which is 
easier depends on your code.


Re: core.sys.posix.unistd link error

2013-09-22 Thread Ruslan Mullakhmetov



I would be curious to see why you believe them to be the same.


Cause i'm a C++ programmer and there is no such thing as module 
and module initializer, in fact object file initialization 
consist of initialization of all its static variables somewhen 
before the first call of a function in that object file (if any).


On Sunday, 22 September 2013 at 19:50:14 UTC, Dmitry Olshansky 
wrote:

22-Sep-2013 15:52, Ruslan Mullakhmetov пишет:


I found where the problem is.

I used a system call (external C function) in class ctor. then 
I
declared global variable of this class and INITIALZIED that 
variable
inplace. If i move initalization in module static this() 
everything

compiles.

the code is:

incorrect version:
http://dpaste.com/hold/1391530/

correct:
http://dpaste.com/hold/1391523/


But now i need to sort out what the difference between
// global scope

int a = 10;



This just puts calculated value 10 into TLS data section as 
initializer for a.



and

int a;

static this()
{
 a = 10;
}



This defines a global with 0 initializer.

Then static this is a function that is executed for each D 
thread on creation, following the module dependency chain (i.e. 
if there is static this in imported module it should be run 
first).


I would be curious to see why you believe them to be the same.

I appreciate if somebody give a link or chapter number where 
to read.


Re: const and immutable members

2013-09-22 Thread Jonathan M Davis
On Sunday, September 22, 2013 18:15:08 Daniel Davidson wrote:
 In this thread
 (http://forum.dlang.org/thread/uvhwkgljavskqfueq...@forum.dlang.org)
 
 I asked this:
  3) Also, is storing immutable(STUFF) in a struct in the general
  case (as opposed to just this one) useful or silly?
 
 Johnathan M Davis replied:
  As soon as you have a const or immutable member in a
  struct, you can't ever assign anything to it, even if
  all of its other members are mutable (you could
  assign the individual, mutable members but not the
  whole struct). That means stuff like if the struct is
  ever default-initialized, you can't even give it
  another value, which tends to mean that you can't use
  such a struct in places like arrays.
  
  All in all, I think that it's pretty much always a
  bad idea to have a struct with const or immutable
  members. It's just begging for problems. Tail-const
  or tail-immutable is fine, because the members
  themselves aren't const or immutable (just what they
  refer to), but having them be directly const or
  immutable is a bad idea IMHO.
 
 I don't really understand the _tail-const_, _tail-immutable_
 argument. Why is _tail-const_ fine but not _const_ when there is
 transitivity anyway?

If you have

struct S
{
immutable int[] arr;
}

then arr can never be assigned to, so a variable of type S can never be 
assigned to. But if you have

struct S
{
immutable(int)[] arr;
}

then arr can be reassigned as much as you'd like, so S can be assigned to. In 
both cases, the elements of the array are immutable, so it can freely be a 
slice of another array and not care or affect that other array, but the array 
variable itself - which only exists local to the struct - is not restricted in 
being assigned to. So, you get the immutability of the data without 
restricting the struct. All making arr itself immutable does (rather than 
tail-immutable) is make it so that you can't reassign arr, which can be useful 
sometimes, but in the case of a struct, it makes it so that the whole struct 
can't be reassigned, so it's pretty much never a good idea IMHO to have a 
struct with const or immutable members - but having them be tail-const or 
tail-immutable still makes it so that what they refer to gets all of the 
benefits of const or immutable without restricting the struct.

If you're dealing with a class, then the situation is a bit different, because 
the class is always on the heap, and you don't normally assign to classes. You 
reassign the reference that refers to them or you assign to their member 
variables, but you don't assign to the block of data that is the class itself 
like you would with a struct. So, making a class' member variable const or 
immutable does not restrict the class, which means that if you want to make it 
so that the member variable can't be reassigned, making it fully const or 
fully immutable is fine.

 I think there are only a handful of places you consider using
 const/immutable:
 
 - Global variables
 - Local variables
 - Member variables
 - Function signatures
 
 Are there any missing?

You can use const and immutable anywhere that you declare a variable or member 
function.

 If right out of the gate the feeling is member variables should
 not be const or immutable, doesn't that greatly reduce the value
 of the mutability specificiers? Members are used to hold onto the
 data for the lifecycle of the object and if those should not make
 claims or guarantees on mutability then that seems a shame.

It's only a problem to make members fully const or immutable with structs, 
because then you can't reassign the struct, which does nasty things like make 
it so that you can't put them in arrays unless you want all the elements of 
the array to have the init value for that struct or you want to append each 
element individually (which won't work with static arrays).

Also, the benefits of sharing data are only gained when that data is on the 
heap, in which case you can just make the data const or immutable without 
making the member variable in the struct const or immutable - you make it 
tail-const or tail-immutable rather than const or immutable.

If the data were directly in the struct (i.e. the member variable is a value 
type), then the only way to share it would be via a pointer or via ref. ref 
doesn't really matter, since you can make that const, and it only refers to 
the data until the function call has completed. And pointers don't matter, 
because you can't actually rely on a pointer to a struct's member variable 
staying valid longer than ref would have anyway, because structs can be moved 
rather than copied. So, sharing via the heap is the only viable way, and if 
you do that, you can use tail-const or tail-immutable for all of the same 
benefits that making the member variable fully const or immutable would have 
given you (since you're sharing the data, not the variable).

And again, the problems with making a member variable fully const or 

Re: core.sys.posix.unistd link error

2013-09-22 Thread Ruslan Mullakhmetov


Thanks. I suspected it but i wanted a formal reference. the 
logic, though little bit cleared by you is quite obvious. But 
don't waste time, if you can not tell  from a scratch that this 
is clause x.y.z of the Standard, sorry, Book.


On Sunday, 22 September 2013 at 19:56:36 UTC, Jonathan M Davis 
wrote:
On Sunday, September 22, 2013 13:52:54 Ruslan Mullakhmetov 
wrote:

But now i need to sort out what the difference between
// global scope

int a = 10;


That directly initializes the variable at compile time, meaning 
that whatever
is used to initialize the variable must be callable at compile 
time. And the
value must be able to be set at compile time and then be 
carried over to
runtime. That will work with int, but it does not work with 
most stuff that's
on the heap (like classes or AAs) - arrays would be the major 
exception to
that, since they can be set at compile time (and I believe that 
it was
recently changed so that immutable classes could be set at 
compile time, but
not const or mutable ones - implementing that is rather 
complicated, and it
may or may not ever happen). Over time, what you can do at 
compile time with
CTFE (Compile Time Function Evaluation) has improved, but there 
are still
restrictions, and some things will never be possible (e.g. I/O 
or calling C

functions).


and

int a;

static this()
{
  a = 10;
}


That does not set the variable at compile time. Rather, the 
static constructor
sets it at runtime. So, this has none of the restrictions that 
directly
initializing a module or static variable does. However, it does 
have the
downside that two modules that have static constructors can't 
import each
other (either directly or indirectly), because then the runtime 
wouldn't know
which order to run them in. If you do that, you'll get an 
exception at runtime
complaining about a circular import (which sucks, but 
unfortunately, the
circular import can't always be detected at compile time - 
thanks in part to
.di files - so runtime detection is the best that can be done). 
So, while
static constructors can be really nice, you do have to avoid 
having modules
that use them import each other, which means either being 
careful about how
your modules import each other or avoiding static constructors. 
Which is

easier depends on your code.




Re: join of range of ranges?

2013-09-22 Thread bearophile

Peter Alexander:

The problem is that you are trying to map a range of range of 
chars with a range of dchars.


auto r2 = [1, 2]
  .map!(x = [1, 2].map!(y = cast(dchar)'*'))
  .join(_);

This works.


I see, thank you. When I ask a question it seems my brain 
switches off a bit :-)




I really wish character literals in D where always dchar.


This is supported:

void main() {
auto s1 = hellow;
auto s2 = hellod;
}


So, what about adding support for this?

void main() {
auto c1 = 'X'w;
auto c2 = 'X'd;
static assert(is(typeof(c1) == wchar));
static assert(is(typeof(c2) == dchar));
}


Bye,
bearophile


Re: const and immutable members

2013-09-22 Thread anonymous
On Sunday, 22 September 2013 at 16:15:09 UTC, Daniel Davidson 
wrote:

[...]
3) Also, is storing immutable(STUFF) in a struct in the 
general

case (as opposed to just this one) useful or silly?



[...]


I don't really understand the _tail-const_, _tail-immutable_ 
argument. Why is _tail-const_ fine but not _const_ when there 
is transitivity anyway?



[...]


If right out of the gate the feeling is member variables should 
not be const or immutable, doesn't that greatly reduce the 
value of the mutability specificiers? Members are used to hold 
onto the data for the lifecycle of the object and if those 
should not make claims or guarantees on mutability then that 
seems a shame.


By marking the tail of the member const -- e.g. const(int)[] --, 
you're committing to not altering the refered-to data. This 
means, the user of your struct can put in mutable and immutable 
data.


When you mark it full-const -- const(int[]) -- you're taking away 
from the user the ability to make it refer to some other data. In 
particular, setting a variable of your struct type to a new value 
requires mutable members. There may be special cases where that 
extra restriction is desired, but I can't think of one. Unless 
you're in such a special case, it just hurts the user for no 
reason.


And when the user needs a const object, they can do that on their 
own:

struct S {int x;}
const s = S(42);
static assert(is(typeof(s.x) == const));


Re: join of range of ranges?

2013-09-22 Thread monarch_dodra

On Sunday, 22 September 2013 at 20:27:01 UTC, bearophile wrote:

Peter Alexander:

The problem is that you are trying to map a range of range of 
chars with a range of dchars.


auto r2 = [1, 2]
 .map!(x = [1, 2].map!(y = cast(dchar)'*'))
 .join(_);

This works.


I see, thank you. When I ask a question it seems my brain 
switches off a bit :-)




I really wish character literals in D where always dchar.


This is supported:

void main() {
auto s1 = hellow;
auto s2 = hellod;
}


So, what about adding support for this?

void main() {
auto c1 = 'X'w;
auto c2 = 'X'd;
static assert(is(typeof(c1) == wchar));
static assert(is(typeof(c2) == dchar));
}


Bye,
bearophile


Even helloc is supported actually :) It can make a difference 
if you *don't* want your string implicitly promoted on 
declaration. EG:


dstring ds1 = hello; //Fine
dstring ds2 = helloc; //Nope.

As for allowing 'X'w, I think the rationale is that a cast will 
get you the same result (not so with string literals).


Re: join of range of ranges?

2013-09-22 Thread Peter Alexander
On Sunday, 22 September 2013 at 18:13:39 UTC, Peter Alexander 
wrote:

On Sunday, 22 September 2013 at 14:26:14 UTC, bearophile wrote:

   auto r2 = [1, 2]
 .map!(x = [1, 2].map!(y = '*'))
 .join(_);


The problem is that you are trying to map a range of range of 
chars with a range of dchars.


This could also be solved by having join return an array of the 
CommonType of the elements of both ranges.


Re: [Question] About mixin, template and alias

2013-09-22 Thread monarch_dodra

On Sunday, 22 September 2013 at 18:31:20 UTC, Michael wrote:

/// fire.d

import std.stdio;

alias void delegate() EventHandler;

class Event(T)
{
private T[] _events;

public void opOpAssign(string op)(T param) if (op == ~)
{
writeln(param.funcptr);
_events ~= param;
}

public void opCall(ParamType ...)(ParamType params)
{
emit(params);
}

protected void emit(ParamType ...)(ParamType params)
{
foreach (event; _events)
event(params);
}
}

mixin template AddEvent(DelegateType, string member)
{
auto eventObserver =  new Event!DelegateType();

mixin(alias eventObserver  ~ member ~ ;);
}

class Fire
{
public mixin AddEvent!(EventHandler, click);
}

/// water.d
import std.stdio;

import fire;

class Water : Fire
{

}

void main()
{
auto fire  = new Fire();
auto water = new Water();
water.click ~= () { writeln(Water!); };
fire.click  ~= () { writeln(Fire!);  };

fire.click();
}


Output:
Water!
Fire!

Someone can explain me a behaviour of above code? Why not 
Fire! only?


This:
//
auto eventObserver =  new Event!DelegateType();
//
Does not do what you think it does: It *statically* initializes 
eventObserver to the *single* new Event!DelegateType();. SO 
basically, all your instances are sharing the same Event.


I'm surprised this compiles at all, what with Fire.init depending 
on a run-time call, but apparently, dmd is smart enough to do 
the allocation at compile time.


Re: [Question] About mixin, template and alias

2013-09-22 Thread Michael

This:
//
auto eventObserver =  new Event!DelegateType();
//
Does not do what you think it does: It *statically* initializes 
eventObserver to the *single* new Event!DelegateType();. SO 
basically, all your instances are sharing the same Event.


I'm surprised this compiles at all, what with Fire.init 
depending on a run-time call, but apparently, dmd is smart 
enough to do the allocation at compile time.


Why like static?



Re: join of range of ranges?

2013-09-22 Thread bearophile

monarch_dodra:

As for allowing 'X'w, I think the rationale is that a cast will 
get you the same result (not so with string literals).


OK. I have desired those char suffixes for years, so now I have 
written an ER:


http://d.puremagic.com/issues/show_bug.cgi?id=11103

Bye,
bearophile


C++ library says to delete data that it allocates

2013-09-22 Thread Charles Hixson
I'm trying to use a C++ library that allocates data and returns a 
pointer to it.  It tells me that I should delete the data when I'm 
through with it.


Can I do this from within D?  Or do I need to write some C++ code to 
manage the delete, and pass the pointer on to it?


--
Charles Hixson



Re: C++ library says to delete data that it allocates

2013-09-22 Thread w0rp

On Sunday, 22 September 2013 at 23:09:52 UTC, Charles Hixson
wrote:
I'm trying to use a C++ library that allocates data and returns 
a pointer to it.  It tells me that I should delete the data 
when I'm through with it.


Can I do this from within D?  Or do I need to write some C++ 
code to manage the delete, and pass the pointer on to it?


You can't use delete straight from D, so I'd write the delete in
C++ and pass the pointer back to C++, like you say.


Re: C++ library says to delete data that it allocates

2013-09-22 Thread Jonathan M Davis
On Monday, September 23, 2013 01:12:55 w0rp wrote:
 On Sunday, 22 September 2013 at 23:09:52 UTC, Charles Hixson
 
 wrote:
  I'm trying to use a C++ library that allocates data and returns
  a pointer to it.  It tells me that I should delete the data
  when I'm through with it.
  
  Can I do this from within D?  Or do I need to write some C++
  code to manage the delete, and pass the pointer on to it?
 
 You can't use delete straight from D, so I'd write the delete in
 C++ and pass the pointer back to C++, like you say.

Yeah. Memory needs to be freed by the same allocator that allocated it, as 
that's the allocator that manages it (e.g. if C's malloc allocated the memory, 
then C's free must free it, or if C++'s new allocated it, then C++'s delete 
must free it). So, if C++ code allocated something, it's going to have to be 
C++ code which frees it (though that could be managed by some kind of smart 
pointer in D which called a C++ function to free the memory when the smart 
pointer determined that the memory needed to be freed).

- Jonathan M Davis


Re: const and immutable members

2013-09-22 Thread Daniel Davidson
On Sunday, 22 September 2013 at 20:17:03 UTC, Jonathan M Davis 
wrote:

If you have

struct S
{
immutable int[] arr;
}

then arr can never be assigned to, so a variable of type S can 
never be

assigned to. But if you have


Yes - it (arr) can never be assigned to. That is the idea. It has 
already been assigned to when the data was read in, prior to 
construction of S. arr is initialized in the ctor of S.




struct S
{
immutable(int)[] arr;
}

then arr can be reassigned as much as you'd like, so S can be 
assigned to.


I don't imagine wanting that in this case. I want to ensure the 
array passed at construction in is the same array being used in 
read-only fashion throughout the lifecycle of S. That is my 
intention behind using immutable. I'm saying I'll not change it 
and no one else can, other wise functions of S that might have 
made assumptions about arr could be invalidated.



In
both cases, the elements of the array are immutable, so it can 
freely be a
slice of another array and not care or affect that other array, 
but the array
variable itself - which only exists local to the struct - is 
not restricted in
being assigned to. So, you get the immutability of the data 
without
restricting the struct. All making arr itself immutable does 
(rather than

tail-immutable) is make it so that you can't reassign arr,


It also keeps the contents of arr from growing and surprising S . 
You could try to prevent with private, but still if it is a large 
module why not have the commitment not to change the contents 
(including the length), especially if it is important that you 
know the data is not changing.



which can be useful
sometimes, but in the case of a struct, it makes it so that the 
whole struct
can't be reassigned, so it's pretty much never a good idea IMHO 
to have a

struct with const or immutable members -


Why that conclusion? That is, why should reassignment of S take 
priority over stable data used by S? For example, take something 
like a BalanceSheetForecaster which takes a BalanceSheet as input 
in its ctor. Isn't it important that the numerous queries on and 
forecasts by the BalanceSheetForecaster be on *exactly* the same 
data?



but having them be tail-const or
tail-immutable still makes it so that what they refer to gets 
all of the

benefits of const or immutable without restricting the struct.



I appreciate the explanation and think I understand the benefit 
of tail-const better. You would not easily be able to store 
modifiable collections of BalanceSheetForecasters, unless you did 
it with pointers. But the focus of the discussion seems to be on 
immutable(T)[] which is my fault for choosing the first and 
easiest type of aliasing I could in my example. I think the slice 
is really a special case when it comes to aliasing. With 
immutable(T)[] you have the benefit of not having to worry about 
aliasing because of the way it is implemented - the contiguous 
nature and copy on write semantics. But this is not the general 
case is it? For example, do the same arguments hold for 
associative arrays?


struct S {
  immutable string[string] aarr;
}

Doesn't using immutable there present the same problem as with 
the slice? S is no longer assignable. But who would recommend not 
using immutable in this case if you want aarr to be stable. If 
you do not use immutable then who knows when your array will grow 
without your expecting it? At least with the slice your memory 
safety is in the control of your module if you make it private. 
But with associative array it would depend entirely on client 
code providing the data still having a handle on it.


Re: const and immutable members

2013-09-22 Thread Jonathan M Davis
On Monday, September 23, 2013 05:18:31 Daniel Davidson wrote:
 On Sunday, 22 September 2013 at 20:17:03 UTC, Jonathan M Davis
  which can be useful
  sometimes, but in the case of a struct, it makes it so that the
  whole struct
  can't be reassigned, so it's pretty much never a good idea IMHO
  to have a
  struct with const or immutable members -
 
 Why that conclusion? That is, why should reassignment of S take
 priority over stable data used by S? For example, take something
 like a BalanceSheetForecaster which takes a BalanceSheet as input
 in its ctor. Isn't it important that the numerous queries on and
 forecasts by the BalanceSheetForecaster be on *exactly* the same
 data?

If any of a struct's members are const, you reassign them in a postblit 
constructor, meaning that if they're reference types, you can't copy them.

Dynamic arrays of S become almost useless (and static arrays _definitely become 
useless), because once any value of type S is initialized it can't be 
assigned. So, if you have

S[12] foo;

or

auto bar = new S[](17);

you can't reassign any of the elements in those arrays. Best case, you can 
mutate their members that aren't const or immutable, but all of their const 
and immutable members are stuck referring to the value in S.init.

Anywhere that involves S.init stops working properly, because you can't change 
any S's that were default-initialized with S.init to something else. So, 
outside of the most basic cases where you just put an S on the stack by itself 
and don't pass it to anything or put it in an array or anything like that, you 
start running into trouble, because you can't change the value of S.

Constrast that with where none of the member variables are const or immutable 
(or at most are tail-const or tail-immutable), and you can only not assign S 
when it's a const S or immutable S. In that sort of situation, you can often 
create an S as mutable and then cast it to const or immutable and get around 
the problems with S.init. e.g.

auto temp = new S[](3);
temp[0] = baz();
temp[1] = S(12);
temp[2] = blah();
auto bar = assumeUnique(temp);

bar and all of its elmeents are now immutable, but you could actually tweak 
them initially, whereas if any of the member variables were actually fully 
const or immutable, you couldn't change any of them from their init value.

  but having them be tail-const or
  tail-immutable still makes it so that what they refer to gets
  all of the
  benefits of const or immutable without restricting the struct.
 
 I appreciate the explanation and think I understand the benefit
 of tail-const better. You would not easily be able to store
 modifiable collections of BalanceSheetForecasters, unless you did
 it with pointers. But the focus of the discussion seems to be on
 immutable(T)[] which is my fault for choosing the first and
 easiest type of aliasing I could in my example. I think the slice
 is really a special case when it comes to aliasing. With
 immutable(T)[] you have the benefit of not having to worry about
 aliasing because of the way it is implemented - the contiguous
 nature and copy on write semantics. But this is not the general
 case is it? For example, do the same arguments hold for
 associative arrays?
 
 struct S {
immutable string[string] aarr;
 }
 
 Doesn't using immutable there present the same problem as with
 the slice? S is no longer assignable. But who would recommend not
 using immutable in this case if you want aarr to be stable. If
 you do not use immutable then who knows when your array will grow
 without your expecting it? At least with the slice your memory
 safety is in the control of your module if you make it private.
 But with associative array it would depend entirely on client
 code providing the data still having a handle on it.

Of course, it's the same for AAs. Or classes. Or pointers. Or int. Or float. 
It's the same for _any_ type. If you make any of them fully immutable, then 
you can't reassign the struct, which makes the struct unusable in a number of 
situations.

But if your concern is client code messing with your member variable, then 
don't give them access to it in the first place. Encapsulate it properly, and 
use property functions or getters and setters to access it. If all you provide 
is a getter property or getter function and no setters, then they can't assign 
to it. And if it's a reference type, all you have to do is return a const 
reference to it rather than a mutable one, and client code won't be able to 
alter it. And in most cases, using tail-const also solves the problem, because 
then the reference can be altered but not the data. AAs are one of the few 
cases where that's not true, because there really isn't a way to have a tail-
const AA (not without an AA equivalent to std.typecons.Rebindable anyway). But 
it works with pointers and arrays just fine, and it works with classes if you 
use std.typecons.Rebindable. Just return a mutable reference to const or 
immutable 

Multiline String Literals without linefeeds?

2013-09-22 Thread John Carter

In C/C++ in the presence of the preprocessor a string

char foo[] = \
long\
string\
without\
linefeeds\
;

Is translated by the preprocessor to

char foo[] = longstringwithoutlinefeeds;

is there a similar mechanism in D? Or should I do...

string foo =
long
string
without
linefeeds
;


backtrace_symbols should be called only when exception thrown

2013-09-22 Thread Timothee Cour
in src/druntime/src/core/runtime.d, backtrace_symbols is called in
DefaultTraceInfo constructor.
Shouldn't it be called only when exception is thrown, to speed up the case
when the exception is not thrown?