Re: Bikeshed: Implementing a command queue.

2016-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 12 March 2016 at 15:10:16 UTC, maik klein wrote:
I wanted to implement a simple command queue in D. To give a 
bit of context, I want to create a command queue for opengl. 
Instead of interacting directly with opengl, you will create 
commands, put them in a queue and then the renderer will read 
those commands and execute the correct OpenGl calls.


See also https://www.embeddedrelated.com/showarticle/518.php


Is there a sorted map?

2016-03-12 Thread stunaep via Digitalmars-d-learn
Is there any sorted map in D? I need a map and I need to be able 
to get the highest key in the map. In java I would use a TreeMap 
and use map.lastKey(), but since associative arrays are not 
sorted that would be O(n). I know about RedBlackTree, but that's 
a set and it must be a map.


Re: Pattern matching as a library

2016-03-12 Thread Simen Kjaeraas via Digitalmars-d

On Saturday, 12 March 2016 at 20:56:47 UTC, Jacob Carlborg wrote:

On 12/03/16 14:12, Simen Kjaeraas wrote:
As I once again bemoaned D's lack of pattern matching 
yesterday, I was
inspired to create this[0] implementation, that plays to D's 
strengths,
allows for user-defined matching, and has a fairly usable 
syntax. The

core usage looks like this:

unittest {
   auto a = tuple(1, "foo");
   auto b = match(a) (
 _!(int, "foo") = (int i) => 1,
 _!(_, _)   = ()  => 0
   );
   assert(b == 1);
}


What kind of syntax is that? Is "match" returning a struct with 
opCall that is called immediately?


Indeed. The goal was to make it look similar to a switch 
statement. I actually started out with an idea for expanding 
switch with pattern matching using lowerings, then noticed I 
could do most of the stuff I wanted without compiler changes.




With the user-defined matching implemented as follows:

struct Tuple(T...) {
// Implementation

   // Magic happens here
   bool opMatch(Pattern, Args...)(Pattern p, ref Args args) {
 foreach (i, e; p.pattern) {
   static if (isTypeTuple!e) {
 enum n = countTypes!(p.pattern[0..i]);
 args[n] = fields[i];
   } else static if (!ignore!e) {
 if (fields[i] != e) {
   return false;
 }
   }
 }
   }
}


Is the tuple iterating all patterns to see if there's a match? 
Shouldn't that be the job for the the match function?


The match function goes through the list of patterns and for each 
one asks the tuple if opMatch returns true for that pattern. If 
it does, the function assigned that pattern is called with the 
values assigned to args.


opMatch here is checking for each element of the pattern if it 
matches the corresponding element of the tuple. Since the pattern 
is available at compile-time, opMatch can deny patterns it 
doesn't like (e.g. trying to match a Tuple!(int, string) with a 
string).


The match function is really only a framework for having similar 
matching syntax for dissimilar types.


If the capability of matching patterns to types were in the match 
function, how could a user type override it? Matching on a 
Tuple!(string, string) is different from matching on an 
Algebraic!(int[], Foo*) is different from matching on a 
specialized user type that wants to do something real weird (I'm 
not sure what that'd be, but I'm sure there are people who will 
want to).



I've started implementing a pattern matching function as well. 
It has a syntax that only use compile time parameters, because 
both types and values can be passed. I'm not entirely sure on 
the syntax yet. I'll have to see what's possible to implement. 
Some suggestions:


auto a = tuple(1, "foo");
auto b = match!(a,
int, "foo", (int i) => 1,
_, _, () => 0,
);


That works. I feel the grouping is looser than in my example, and 
that the pattern doesn't stand out from the rest of the 
expression, but it certainly works, and there are some benefits 
to that syntax.



If the pull request for inspecting templates ever will be 
merged it won't be necessary to have typed lambdas:


auto b = match!(a,
int, "foo", (i) => 1,
_, _, () => 0,
);


There's a problem using that syntax? It works for me in a toy 
example:


http://dpaste.dzfl.pl/7360ee90b344

Sorry about the lack of comments and stuff, but it's 3:30AM, and 
I probably shouldn't be programming now.


Re: Constructor - the both look the same

2016-03-12 Thread Joel via Digitalmars-d-learn

On Saturday, 12 March 2016 at 23:43:33 UTC, Joel wrote:

On Saturday, 12 March 2016 at 08:11:10 UTC, Iakh wrote:

On Saturday, 12 March 2016 at 07:43:59 UTC, Joel wrote:

Why does it come up with this?

source/setup.d(40,16): Error: constructor 
inputjex.InputJex.this (Vector2!float pos, int fontSize, 
InputType type = cast(InputType)0) is not callable using 
argument types (Vector2!float, int, InputType)

dmd failed with exit code 1.


Can you show your code?


I don't know if I can show the code (maybe the whole lot in a 
zip file). But I did a hack to get it to compile (took the last 
perimeter(sp) out).


Got it fixed. I had 2 base files that were the same (one of them 
a source file of library of mine), I made them so they were 
different.


Re: Potential GSoC project - GC improvements

2016-03-12 Thread Chris Wright via Digitalmars-d
On Sat, 12 Mar 2016 13:23:35 -0800, Adam Wilson wrote:

To start off, let's talk terminology. You seem to be using nonstandard 
terminology and possibly misunderstanding standard terminology.

A GC scan is the mark phase of a mark/sweep collector (and specifically 
the part where the GC examines roots and allocated memory, if that 
matters). The GC searches for pointers to GC memory. Simple GCs only need 
to record whether there is a pointer to a given allocation, not where 
those pointers are coming from.

A conservative GC is one that will encounter some things that aren't 
pointers but must be scanned as if they were pointers. In D, for 
instance, a union between a pointer and a size_t forces collectors to be 
conservative.

A false pointer is something that a conservative GC must treat as a 
pointer and appears to point to an object allocated by that GC. For 
instance, unions in D allow us to create false pointers.

A precise GC is a GC that never mistakes a non-pointer for a pointer.

A moving GC is a GC that can relocate objects.

A generational GC is one that can perform a collection on part of the 
heap without dealing with the full heap. Those parts tend to be organized 
by how long an object has survived. This does not require a precise or 
moving GC, though it works better with a precise, moving GC.

A write barrier is a way to record which sections of memory have been 
altered since the last GC collection. This lets the GC scan only the 
changed data -- useful to any GC, especially useful to generational ones.

A "partially moving" GC does not exist, as far as I know.

> Jeremy DeHaan wrote:
>> On Saturday, 12 March 2016 at 08:50:06 UTC, Adam Wilson wrote:
>>> If I may make a suggestion. The lock free work is unlikely to require
>>> the entirety of GSoC. And the precise GC is the next most important
>>> thing on your list and will have the biggest impact on GC performance.
>>
>> Rainer has two different precise GC's in pull requests right now and
>> both are slower than the current one unless there are false pointers. 
>> I would expect anything I come up with to largely act the same. The
>> reason I keep pushing for a generational garbage collector is because I
>> think it would be where we would see the most benefit in terms of
>> general performance.
>>
>>
> I would contend that it's not quite that simple. Of course the precise
> GC is slower, it's scanning more stuff.

Precise GCs are slower because they must reference some data telling them 
which items on the stack and in allocations represent pointers and which 
do not. This data takes up cache space, and having less cache for memory 
being scanned slows things down. Correlating two pieces of data takes 
extra time, too.

The hope with a precise GC is to avoid false pointers. A false pointer to 
an object that holds references to many other objects can be costly, both 
in GC time and in excess memory usage.

In D, we have a tiny bit of type information surfaced to the GC to reduce 
the incidence of false pointers. We could additionally take advantage of 
the fact that numbers tend to be small and people tend to use 4 to 8 byte 
numbers: we could arrange our address space to avoid ranges where false 
pointers are likely. But that's probably unnecessary.

> The current conservative GC by
> definition can't figure out large chunks of memory so it won't even
> bother scanning them.

It must scan anything that might be a pointer. A precise GC reduces the 
number of things that might be pointers but aren't to zero. Therefore a 
precise GC scans less.

If a conservative GC didn't scan something that might be a pointer, it 
would sometimes free an object that still had live references to it. This 
would result in memory corruption or segmentation faults.

> What it does to those things it can't scan. And
> what it can't scan it has to pin, which means the memory can't be moved.

If a moving GC cannot precisely identify all pointers to an object, it is 
not allowed to move that object. If it can, it is allowed to move that 
object.

A conservative GC can be a moving GC. It must classify things as 
"definitely pointer", "maybe pointer", and "not pointer". It cannot move 
an object with a "maybe pointer" pointing to it, but it can move an 
object with several "definitely pointers" pointing to it.

In D, thanks to unions, we can never create a fully precise collector, 
but we can create a moving collector. Objects pointed to from a union 
can't be moved, but few objects will be pointed to from a union.

> You can't build a fully generational GC until you can move everything.

You can build a more efficient generational GC if you can move objects. 
However, it's not impossible to build a non-moving generational GC. 
Instead of having large blocks of address space for each generation, you 
would have each Pool indicate its generation. Then you have to find the 
Pool for a pointer and check that flag.

That's comparatively slow, but it'd still be 

Re: Bikeshed: Implementing a command queue.

2016-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 12 March 2016 at 15:10:16 UTC, maik klein wrote:
I wanted to implement a simple command queue in D. To give a 
bit of context, I want to create a command queue for opengl. 
Instead of interacting directly with opengl, you will create 
commands, put them in a queue and then the renderer will read 
those commands and execute the correct OpenGl calls.



I have a few options:

I could use an ADT to create commands but then all commands 
would have the size of the biggest command, also Algebraic is 
not nice nicest thing in D.


I could use runtime polymorphism `class SomeCommand: Command{}` 
but then I would end up with a lot of pointers in the queue, 
also I would need to worry about the allocations.


I have also seen this, but it is a bit more low level and is 
similar to assembly.


Queue:
Command1
int
int
Command2
float
Command3
Command4
int
float double

The first entry would always be the command which is followed 
by the arguments. So you would pop the command out and with the 
command you know how far you need to go into the queue


//pseudo code
auto c = queue.pop!Command;

if(c == Command1){
   int arg1 = queue.pop!int;
   int arg2 = queue.pop!int;
}
if(c == Command2){
   int arg1 = queue.pop!float;

}

How would you implement a simple command queue?


for the sake of simplicity I'm going to assume that the arguments 
to your commands are 32bit values ((u)int and float,) make the 
command type an enum : uint. if you are going to have 64bit 
values you will have to take care of alignment or waste space.

then have a "buffer" of 32bit value (circular is fine)
while(!buffer.empty)
{
final switch(buffer.next32bitValue()) with(Command)
{
case command1:
{
Command1 cmd;
cmd.firstInt  = cast(int)buffer.next32bitValue();
cmd.secondInt = cast(int)buffer.next32bitValue();
uint value = cast(int)buffer.next32bitValue();
cmd.firstFloat   = *cast(float*)
glSomeCall(cmd);
break;
}
...
}
}



Re: std.xml2 (collecting features)

2016-03-12 Thread Alex Vincent via Digitalmars-d
For everyone's information, I've posted a pull request to Mr. 
Schadek's github repository, with a proposed Simple API for XML 
(SAX) stub.  I'd really appreciate reviews of the stub's 
interfaces.


https://github.com/burner/std.xml2/pull/5


Re: Using tango or other static lib in static lib

2016-03-12 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 13 March 2016 at 01:06:33 UTC, Mike Parker wrote:

it. Assuming both files live in the same directory, they can be 
compiled with this command:


Somehow I deleted that line:

dmd main.d something.d


Re: Using tango or other static lib in static lib

2016-03-12 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 12 March 2016 at 22:34:19 UTC, Voitech wrote:
At beginning I want to say that I'm Java devloper so most of 
linking, joining, dependent classes, libs could be solve with 
simple 3 click in eclipse so please be patient with me :).
I'm using Mono-D under Ubuntu 14.04 to create my project it 
would be a library for further development process, but I'm a 
guy who don't want to invite wheel again and again, so i wanted 
to use Tango-D2 (for now HashMap implemenetation).


Anything wrong with the built in associative arrays that cause 
you not to use them?


From what i red you cant import one static library with another 
but somehow import o. files, or just copy sources .d to proper 
folder and use them as yours (with proper license of course). 
Tango-D2 by itself compiles nicely with bob and produces many 
.o files. How to use them though ?


Forget the word 'import' for a minute. There are two basic steps 
to concern yourself with: compiling and linking. D's approach is 
the traditional C approach. We can loosely define the terms like 
so:


compile: take source files as input and generate object files as 
output
link: take object files as input and generate executables (or 
shared libraries, but let's not confuse things) as output.


In order to compile, the compiler needs to be aware of every 
symbol that is visible and usable in the source module it is 
currently compiling. As an example, consider the following two 
files:


main.d something.d

When compiling main.d, all of the symbols inside main.d are 
visible by default. In order for main.d to use the symbols in 
something.d, it must 'import' something.d.


import something;
void main() { aFunctionInSomething(); }

Assuming the implementation of aFunctionInSomething lives in 
something.d, it is now visible inside main.d because of the 
import. Take away the import, and you get a /compiler error/. The 
compiler doesn't know about that function, so you can't use it. 
Assuming both files live in the same directory, they can be 
compiled with this command:


Once the object files are generated, they are passed to the 
linker. The important thing to understand here is that the 
'import' statement in the source code above has absolutely no 
bearing on the link stage. It is exclusively for the compiler. 
The linker will never, ever, see it. All the linker cares about 
are symbols in the object files. To fully appreciate that, try 
this experiment.


Take the main.d source as it is above. Then implement something.d 
like so:


module something;
import std.stdio;
void aFunctionInSomething() { writeln("Something"); }

Next, cd to the directory where you saved the files and compile 
them both:


dmd -c main.d
dmd -c something.d

The -c option tells the compiler to only generate the object 
files and do not pass them to the linker. The result is that you 
will now have two object files. If you next take the following 
step (assuming Windows -- change .obj to .o elsehwere):


dmd main.obj something.obj

The compiler will recognize you've passed it object files and 
will hand them off to the linker. However, try this:


dmd main.obj

Using the default linker on Windows (OPTLINK -- passing 
-m32mscoff or -m64 uses the Microsoft linker if you have it 
installed, but the source must be compiled with the same flag) 
yields the following output:


OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
main.obj(main)
 Error 42: Symbol Undefined _D9something20aFunctionInSomethingFZv
main.obj(main)
 Error 42: Symbol Undefined _D9something12__ModuleInfoZ
--- errorlevel 2

These are linker errors. You can know this because of two things: 
the big OPTLINK in the first line and the error type 'Symbol 
Undefined'. The Microsoft linker produces this:


main.obj : error LNK2001: unresolved external symbol 
_D9something12__ModuleInfoZ
main.obj : error LNK2019: unresolved external symbol 
_D9something20aFunctionInSomethingFZv referenced in function 
_Dmain

main.exe : fatal error LNK1120: 2 unresolved externals

You can know these are linker errors because of the Microsoft 
erro codes containing the 'LNK' prefix and because of 'unresolved 
external symbol', which is the equivalent of OPTLINK's 'Symbol 
Undefined'. It's important to be able to distinguish linker 
errors from compiler errors.


When you pass both objects on the command line, the linker is 
then able to find the symbol it needs.


A static library is one or more object files bundled into a 
single file:


dmd lib something.d

This will create a static library called something.lib. Then you 
can do this:


dmd main.d something.lib

In this particular case, it's exactly equivalent to the following:

dmd -c something.d
dmd main.d something.obj

The benefit of static libraries is when you have multiple object 
files:


dmd lib foo.d bar.d baz.d
dmd main.d foo.lib

Much more convenient to deal with one library than three 

Re: Constructor - the both look the same

2016-03-12 Thread Joel via Digitalmars-d-learn

On Saturday, 12 March 2016 at 08:11:10 UTC, Iakh wrote:

On Saturday, 12 March 2016 at 07:43:59 UTC, Joel wrote:

Why does it come up with this?

source/setup.d(40,16): Error: constructor 
inputjex.InputJex.this (Vector2!float pos, int fontSize, 
InputType type = cast(InputType)0) is not callable using 
argument types (Vector2!float, int, InputType)

dmd failed with exit code 1.


Can you show your code?


I don't know if I can show the code (maybe the whole lot in a zip 
file). But I did a hack to get it to compile (took the last 
perimeter(sp) out).


[Issue 15793] Change !is error to warning

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15793

Sobirari Muhomori  changed:

   What|Removed |Added

   Severity|major   |regression

--


Using tango or other static lib in static lib

2016-03-12 Thread Voitech via Digitalmars-d-learn
At beginning I want to say that I'm Java devloper so most of 
linking, joining, dependent classes, libs could be solve with 
simple 3 click in eclipse so please be patient with me :).
I'm using Mono-D under Ubuntu 14.04 to create my project it would 
be a library for further development process, but I'm a guy who 
don't want to invite wheel again and again, so i wanted to use 
Tango-D2 (for now HashMap implemenetation). From what i red you 
cant import one static library with another but somehow import o. 
files, or just copy sources .d to proper folder and use them as 
yours (with proper license of course). Tango-D2 by itself 
compiles nicely with bob and produces many .o files. How to use 
them though ?
If using sources by just copping them into one folder, creating 
Mono-D project, dmd complains about many, many errors, mostly 
import errors (in tango.sys.win32). I fixed them adding version 
to each of included files and adding some imports first:

module tango.sys.win32
version(Windows){
...
...
}

But i think I'm doing something wrong, if Tango-D2 compiles with 
bob it should also by creating project in Mono-D (or this is 
linking problem ?). In Mono-D there is also possibility in 
Project-> Options-> Build-> Compiling to add Libraries (there is 
a tick Link static libraries from nested dependencies) how to use 
this ? Or rather how should i obtain what i want ?


[Issue 15793] New: Change !is error to warning

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15793

  Issue ID: 15793
   Summary: Change !is error to warning
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: major
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: dfj1es...@sneakemail.com

interface A { void f(); }
void f(A a)
{
if(a!=null)a=null;
}

Error: use '!is' instead of '!=' when comparing with null

Mother of god.

--


Re: Potential GSoC project - GC improvements

2016-03-12 Thread Adam Wilson via Digitalmars-d

Jeremy DeHaan wrote:

On Saturday, 12 March 2016 at 08:50:06 UTC, Adam Wilson wrote:

If I may make a suggestion. The lock free work is unlikely to require
the entirety of GSoC. And the precise GC is the next most important
thing on your list and will have the biggest impact on GC performance.


Rainer has two different precise GC's in pull requests right now and
both are slower than the current one unless there are false pointers.  I
would expect anything I come up with to largely act the same. The reason
I keep pushing for a generational garbage collector is because I think
it would be where we would see the most benefit in terms of general
performance.



I would contend that it's not quite that simple. Of course the precise 
GC is slower, it's scanning more stuff. The current conservative GC by 
definition can't figure out large chunks of memory so it won't even 
bother scanning them. What it does to those things it can't scan. And 
what it can't scan it has to pin, which means the memory can't be moved. 
You can't build a fully generational GC until you can move everything. 
They talk about this problem in the books. However, once you have a 
precise GC, a fully moving GC becomes possible and only then do the 
performance benefits of a generational GC become realized. I strongly 
suspect that a partially moving GC will perform worse than the precise 
GC. And I know for a fact that it will suffer enormously from 
fragmentation and Out-of-Memory issues. Precision is the basis from 
which all higher order GC functions flow.





Once the GC is fully precise we can implement a fully compacting GC,
which improves the usefulness of generational collection.
Additionally, precision allows a significant amount of work to be done
in improving the performance of the GC in multi-threaded scenarios. It
should be quite possible to avoid needing fork() or anything like it
altogether. I know that the .NET GC doesn't need to use anything like it.


A compacting GC could be built on top of a generational GC without much
difficulty I would think, if we wanted to go that route. The compaction
would just happen as part of a collection cycle when things are moved
into the next generation. I have concerns about doing any compaction
though, mostly because D can have both references and pointers to
objects, and I don't know how we would want to go about updating
pointers. Especially since pointers to D objects can exists in C and C++
code.



Erm, a generational GC is, in practice, a moving GC as it must move the 
blobs around from the various heaps. The commonly used method is 
Stop-and-Copy.


As for the C/C++ code problem various solutions have been proposed here. 
For one, D knows the difference between the two, so pinning is possible 
there. Or a separate heap space can be used. AFIAK each OS allows you to 
specify multiple heaps, so you could specify an unmanaged heap to go 
along with the managed heaps. IIRC, C++/CLI does something similar on 
Windows. This would be the preferred solution IMO. (Look into HeapCreate 
on Windows for example.)



Another reason I want to work on a generational GC is because this can
also lead into a concurrent GC without trying to emulate fork() on
windows. The .Net GC has 3 generations with the last one having its
collections running concurrently because it is unlikely to affect
anything else going on. They don't bother running the other generations
concurrently because their collections are really short. We could do
something similar.



A concurrent GC without precision is mostly useless because the GC roots 
are primarily derived from the stack which the thread was spawned and 
the stack roots are not scanned in a conservative GC. Additionally, the 
Async/Await pattern is not practical without a precise GC.



Perhaps someone more intimate with GC's than I am can speak up, but I
think that a generational GC would be the best use of time in relation
to performance gains. Other things can then be implemented on top of it
later.



The problem is that performance is the most obvious problem with the GC, 
but not the most important problem, or most useful. Precision enables a 
fully moving, fully generational, fully concurrent, GC. It also enables 
other major features that have nothing to do with GC.





Also, I would strongly recommend getting this book and reading it
cover to cover before starting:
http://www.amazon.com/gp/product/1420082795/ref=pd_lpo_sbs_dp_ss_1?pf_rd_p=1944687562_rd_s=lpo-top-stripe-1_rd_t=201_rd_i=0471941484_rd_m=ATVPDKIKX0DER_rd_r=0QD9X3E5QATSBCBT6BMM



Thank you for the link to the book. I was planning on this one
http://www.amazon.com/gp/product/0471941484/ , but maybe I will buy them
both.




Obviously you can do whatever you want. :) And I'll admit that precision 
isn't sexy, and it won't improve performance right away, but it opens 
the door way to further work that will provide those things. It's hard 
and thankless work, but you'll be better setup for 

[Issue 15792] Error Filling an array

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15792

Alex  changed:

   What|Removed |Added

   Severity|major   |minor

--


Re: Pattern matching as a library

2016-03-12 Thread Jacob Carlborg via Digitalmars-d

On 12/03/16 14:12, Simen Kjaeraas wrote:

As I once again bemoaned D's lack of pattern matching yesterday, I was
inspired to create this[0] implementation, that plays to D's strengths,
allows for user-defined matching, and has a fairly usable syntax. The
core usage looks like this:

unittest {
   auto a = tuple(1, "foo");
   auto b = match(a) (
 _!(int, "foo") = (int i) => 1,
 _!(_, _)   = ()  => 0
   );
   assert(b == 1);
}


What kind of syntax is that? Is "match" returning a struct with opCall 
that is called immediately?



With the user-defined matching implemented as follows:

struct Tuple(T...) {
// Implementation

   // Magic happens here
   bool opMatch(Pattern, Args...)(Pattern p, ref Args args) {
 foreach (i, e; p.pattern) {
   static if (isTypeTuple!e) {
 enum n = countTypes!(p.pattern[0..i]);
 args[n] = fields[i];
   } else static if (!ignore!e) {
 if (fields[i] != e) {
   return false;
 }
   }
 }
   }
}


Is the tuple iterating all patterns to see if there's a match? Shouldn't 
that be the job for the the match function?



Or for Algebraic:

struct Algebraic(T...) {
   union {
 T fields;
   }
   size_t which;

   bool opMatch(Pattern, Type)(Pattern p, ref Type args) if
(staticIndexOf!(Type, T) > -1) {
 enum index = staticIndexOf!(Type, T);
 if (index == which) {
   args = fields[index];
   return true;
 }
 return false;
   }
}

The main problem I see is the temporary allocation of function arguments
on line 124 and their assignment in opMatch, but I currently don't have
a better solution.

Also, while I very much dislike using _ for an identifier, I feel it may
be the best alternative here - it conveys the meaning of 'don't care'
for the pattern, and doesn't stand out like a sore thumb before the
exclamation mark. Other suggestions are welcome.


I've started implementing a pattern matching function as well. It has a 
syntax that only use compile time parameters, because both types and 
values can be passed. I'm not entirely sure on the syntax yet. I'll have 
to see what's possible to implement. Some suggestions:


auto a = tuple(1, "foo");
auto b = match!(a,
int, "foo", (int i) => 1,
_, _, () => 0,
);

If the pull request for inspecting templates ever will be merged it 
won't be necessary to have typed lambdas:


auto b = match!(a,
int, "foo", (i) => 1,
_, _, () => 0,
);

If you only want to match types it could look like this:

auto b = match!(a,
(int a) => 1
);

Matching a value:

auto b = match!(a,
1, () => 2
);

Matching a pattern:

auto b = match!(a,
(a, b) => a + b
);

The else pattern (executed if nothing else matches):

auto b = match!(a,
() => 4,
);

It would be nice if it was possible to verify at compile time if at 
least one pattern will match. For example:


match!("foo",
(int a) => 1,
);

It's clear that the above pattern can never match.

--
/Jacob Carlborg


Re: Filling an array

2016-03-12 Thread Alex via Digitalmars-d-learn

On Saturday, 12 March 2016 at 19:35:30 UTC, ag0aep6g wrote:

On 12.03.2016 16:44, Mike Parker wrote:

arr[] = cast(Nullable!uint)1;


Nicer than a cast: construct a Nullable!int.

arr[] = Nullable!uint(1);


ok... so... this makes the error very strange, then... almost 
senseless...


[Issue 15792] Error Filling an array

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15792

--- Comment #2 from Alex  ---
filling via 

arr[] = Nullable!uint(1); 

is also possible

--


Re: Filling an array

2016-03-12 Thread ag0aep6g via Digitalmars-d-learn

On 12.03.2016 16:44, Mike Parker wrote:

arr[] = cast(Nullable!uint)1;


Nicer than a cast: construct a Nullable!int.

arr[] = Nullable!uint(1);


Re: Potential GSoC project - GC improvements

2016-03-12 Thread Jeremy DeHaan via Digitalmars-d

On Saturday, 12 March 2016 at 08:50:06 UTC, Adam Wilson wrote:
If I may make a suggestion. The lock free work is unlikely to 
require the entirety of GSoC. And the precise GC is the next 
most important thing on your list and will have the biggest 
impact on GC performance.


Rainer has two different precise GC's in pull requests right now 
and both are slower than the current one unless there are false 
pointers.  I would expect anything I come up with to largely act 
the same. The reason I keep pushing for a generational garbage 
collector is because I think it would be where we would see the 
most benefit in terms of general performance.



Once the GC is fully precise we can implement a fully 
compacting GC, which improves the usefulness of generational 
collection. Additionally, precision allows a significant amount 
of work to be done in improving the performance of the GC in 
multi-threaded scenarios. It should be quite possible to avoid 
needing fork() or anything like it altogether. I know that the 
.NET GC doesn't need to use anything like it.


A compacting GC could be built on top of a generational GC 
without much difficulty I would think, if we wanted to go that 
route. The compaction would just happen as part of a collection 
cycle when things are moved into the next generation. I have 
concerns about doing any compaction though, mostly because D can 
have both references and pointers to objects, and I don't know 
how we would want to go about updating pointers. Especially since 
pointers to D objects can exists in C and C++ code.


Another reason I want to work on a generational GC is because 
this can also lead into a concurrent GC without trying to emulate 
fork() on windows. The .Net GC has 3 generations with the last 
one having its collections running concurrently because it is 
unlikely to affect anything else going on. They don't bother 
running the other generations concurrently because their 
collections are really short. We could do something similar.


Perhaps someone more intimate with GC's than I am can speak up, 
but I think that a generational GC would be the best use of time 
in relation to performance gains. Other things can then be 
implemented on top of it later.



Also, I would strongly recommend getting this book and reading 
it cover to cover before starting:

http://www.amazon.com/gp/product/1420082795/ref=pd_lpo_sbs_dp_ss_1?pf_rd_p=1944687562_rd_s=lpo-top-stripe-1_rd_t=201_rd_i=0471941484_rd_m=ATVPDKIKX0DER_rd_r=0QD9X3E5QATSBCBT6BMM


Thank you for the link to the book. I was planning on this one 
http://www.amazon.com/gp/product/0471941484/ , but maybe I will 
buy them both.





Re: code-d 0.10.1 released (D support for vscode)

2016-03-12 Thread WebFreak001 via Digitalmars-d-announce

On Saturday, 12 March 2016 at 18:57:41 UTC, Dmitry wrote:

On Saturday, 12 March 2016 at 18:44:23 UTC, WebFreak001 wrote:

Is it work only with GDC and LDC? Because with DMD it doesn't.
Then where I can get GDC and LDC for Windows (of course, I'm 
about binaries)?


P.S. Windows 7 x64


the debugger extension is using GDB or LLDB, just install one 
of those programs. Both GDB and LLDB work with gdc, ldc and dmd

I have installed GDB, and debugging doesn't start.
In previous version of code-d I saw something like "not in 
executable format: File format not recognized" in the console 
output (current version has no any messages).


LLDB - I didn't found binaries for Widnows.


Not sure how that happens... You need code-debug and just follow 
the instructions in the code-debug README.


But both for GDB and LLDB you need to compile it yourself for 
Windows


Re: code-d 0.10.1 released (D support for vscode)

2016-03-12 Thread Dmitry via Digitalmars-d-announce

On Saturday, 12 March 2016 at 18:44:23 UTC, WebFreak001 wrote:

Is it work only with GDC and LDC? Because with DMD it doesn't.
Then where I can get GDC and LDC for Windows (of course, I'm 
about binaries)?


P.S. Windows 7 x64


the debugger extension is using GDB or LLDB, just install one 
of those programs. Both GDB and LLDB work with gdc, ldc and dmd

I have installed GDB, and debugging doesn't start.
In previous version of code-d I saw something like "not in 
executable format: File format not recognized" in the console 
output (current version has no any messages).


LLDB - I didn't found binaries for Widnows.


Re: code-d 0.10.1 released (D support for vscode)

2016-03-12 Thread WebFreak001 via Digitalmars-d-announce

On Saturday, 12 March 2016 at 18:41:23 UTC, Dmitry wrote:

On Friday, 11 March 2016 at 20:03:47 UTC, WebFreak001 wrote:

[...]
After last update I have an exeption when close VSCode: 
https://dl.dropboxusercontent.com/u/78963719/D/forum/error.png



[...]

Error: http://pastebin.com/wqmkMw7c


Right, gonna fix the bugs later. Didn't test it on windows yet


[...]

Is it work only with GDC and LDC? Because with DMD it doesn't.
Then where I can get GDC and LDC for Windows (of course, I'm 
about binaries)?


P.S. Windows 7 x64


the debugger extension is using GDB or LLDB, just install one of 
those programs. Both GDB and LLDB work with gdc, ldc and dmd




Re: code-d 0.10.1 released (D support for vscode)

2016-03-12 Thread Dmitry via Digitalmars-d-announce

On Friday, 11 March 2016 at 20:03:47 UTC, WebFreak001 wrote:
I just released a new version of code-d, it now supports 
projects without any dub.json file which some people probably 
will like. This is really useful for standalone projects with a 
custom build system like writing an OS/Kernel or other projects 
that don't want to use dub.
After last update I have an exeption when close VSCode: 
https://dl.dropboxusercontent.com/u/78963719/D/forum/error.png


If you want to give it a try just install the most recent 
workspace-d build using the workspace-d CLI installer:


https://github.com/Pure-D/workspace-d-installer

Error: http://pastebin.com/wqmkMw7c

If you need a debugger frontend (currently GDB and LLDB) for 
vscode, try my debugging extension. It supports most features 
and D is working like a charm in there: 
https://github.com/WebFreak001/code-debug (install using 'ext 
install gdb')

Is it work only with GDC and LDC? Because with DMD it doesn't.
Then where I can get GDC and LDC for Windows (of course, I'm 
about binaries)?


P.S. Windows 7 x64



Re: Filling an array

2016-03-12 Thread Alex via Digitalmars-d-learn

On Saturday, 12 March 2016 at 16:37:25 UTC, user42 wrote:

On Saturday, 12 March 2016 at 14:33:19 UTC, Alex wrote:

/snip


I thought this was supposed to halt with an error rather than 
compile and set all members to 1.
The syntax, to me anyways, doesn't really communicate the 
intention of: set all members to 1.

//arr[] = 1;


Whereas the following does

fill(arr, 1);


Well, this was not the question. As stated here:
https://dlang.org/spec/arrays.html
in the section "array setting", it is possible to set an array in 
such a manner. And my question was, why a specific array behaves 
not as expected.
So, either there is a problem with filling an array, or, there is 
a problem with implicit conversion of a Nullable!T to its 
underlying type.


[Issue 15792] Error Filling an array

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15792

--- Comment #1 from Alex  ---
The error is: 
Error: cannot implicitly convert expression (1) of type int to Nullable!uint[]

--



Re: Pitching D to a gang of Gophers

2016-03-12 Thread Jon D via Digitalmars-d
On Saturday, 12 March 2016 at 08:09:41 UTC, Dmitry Olshansky 
wrote:

On 05-Mar-2016 14:05, Dmitry Olshansky wrote:
Obligatory slides:
http://slides.com/dmitryolshansky/deck/fullscreen/


Very nice slide deck. Thanks for publishing.  --Jon



[Issue 15780] CTFE foreach fails with tuple

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15780

greenify  changed:

   What|Removed |Added

  Component|phobos  |dmd

--


[Issue 15780] CTFE foreach fails with tuple

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15780

greenify  changed:

   What|Removed |Added

 CC||greeen...@gmail.com

--- Comment #1 from greenify  ---
AFAIK foreach isn't implemented in phobos, but a feature of the compiler - so
it seems to me to be an issue with dmd.

--


Re: Potential GSoC project - GC improvements

2016-03-12 Thread Chris Wright via Digitalmars-d
On Sat, 12 Mar 2016 00:50:06 -0800, Adam Wilson wrote:
> If I may make a suggestion. The lock free work is unlikely to require
> the entirety of GSoC. And the precise GC is the next most important
> thing on your list and will have the biggest impact on GC performance.
> 
> Once the GC is fully precise we can implement a fully compacting GC,

Unions mean we can't be entirely precise, but we can get pretty close. 
Stack maps and type pointer maps are entirely separate efforts, and type 
pointer maps will be easier to implement, so the first pass will probably 
only include type pointer maps.

Switching to a compacting GC is risky. It's a transparent change if 
you're only working with D code, but if you interface to other languages, 
it breaks things horribly.

> which improves the usefulness of generational collection. Additionally,
> precision allows a significant amount of work to be done in improving
> the performance of the GC in multi-threaded scenarios.

Primarily because less memory needs to be scanned on average, so less 
work needs to be done and GC pauses are shorter. There's nothing specific 
to multithreading there.

> It should be
> quite possible to avoid needing fork() or anything like it altogether.

fork() is used to avoid pausing the program at all during the mark phase.

> I know that the .NET GC doesn't need to use anything like it.

The .NET GC stops all managed threads during a collection.

During a nursery or gen 1 collection, on average it's probably fast 
enough that forking wouldn't give that much benefit. During a full 
collection, if your application is latency-sensitive, a forking strategy 
would be better.

But .NET can't do that because Windows doesn't have a fork() system call, 
and it's expensive to emulate.


Re: Filling an array

2016-03-12 Thread user42 via Digitalmars-d-learn

On Saturday, 12 March 2016 at 14:33:19 UTC, Alex wrote:

/snip


I thought this was supposed to halt with an error rather than 
compile and set all members to 1.
The syntax, to me anyways, doesn't really communicate the 
intention of: set all members to 1.

//arr[] = 1;


Whereas the following does

fill(arr, 1);




Re: Why is it not possible to write to a file from a const member function ?

2016-03-12 Thread user42 via Digitalmars-d-learn

On Saturday, 12 March 2016 at 15:32:39 UTC, Mike Parker wrote:

On Saturday, 12 March 2016 at 14:02:31 UTC, user42 wrote:


Why is this thing not compiling ?
Or, in other words, how is is possible to log something to a 
file from a const member function ?




Const member functions functions are not allowed to mutate any 
member state at all. This includes the state of any object 
instances that are members. Since the write method of the File 
type is not declared as const, then you can not call it on a 
member of type File from inside a const member function. 
Logging, by its very definition, mutates state.


Move the File instance outside of the class and it works.

import std.stdio;
private File f;
static this() { f = stdout; }

class X
{
  void p(string s) const
  {
 f.writeln!(string)(s);
  }
}

class Y
{
  private string s = "Y";

  override string toString() const
  {
 return s;
  }
}

void main()
{
  auto x = new X;
  auto y = new Y;

  import std.conv: to;
  x.p(to!string(y));
}


Thanks for your reply.
Unfortunately it only solves the problem for this particular 
snippet.


The most interesting part of your reply is this line:
Since the write method of the File type is not declared as 
const,


At a quick glance I suppose it's because of the locking in 
LockingTextWriter.


I think I will probably pass this stuff to a C implementation, or 
override toString non-const, since adding const to it started 
this const avalanche in the first place.


Anyways, thanks for your input and have a nice weekend.


Re: Filling an array

2016-03-12 Thread Alex via Digitalmars-d-learn

On Saturday, 12 March 2016 at 15:44:00 UTC, Mike Parker wrote:

On Saturday, 12 March 2016 at 14:33:19 UTC, Alex wrote:


//arr[] = 1;

The question is, why the commented out line throws the error:
Error: cannot implicitly convert expression (1) of type int to 
Nullable!uint[],

while the line after that works.


Looks like a bug somewhere. The work around is to cast:

arr[] = cast(Nullable!uint)1;

I suggest you file this in the bug tracker [1] if it isn't 
there already. Just use he minimal code that shows the problem:


void main()
{
import std.typecons;
Nullable!uint[] arr;
arr.length = 5;
arr[] = 1;
}

[1] https://dlang.org/bugstats.php


Thanks!
Bug filed under
https://issues.dlang.org/show_bug.cgi?id=15792


[Issue 15792] New: Error Filling an array

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15792

  Issue ID: 15792
   Summary: Error Filling an array
   Product: D
   Version: D2
  Hardware: x86_64
OS: Mac OS X
Status: NEW
  Severity: major
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: sascha.or...@gmail.com

Didn't find an existing issue for this. Sorry, if missed.

As described here: 
https://forum.dlang.org/post/iizchhylkxistlnbi...@forum.dlang.org

There is an error during an attempt to fill an array of Nullable!uint during
the execution of

void main()
{
import std.typecons;
Nullable!uint[] arr;
arr.length = 5;
arr[] = 1;
}

The suggested workaround is, currently, using a cast:
arr[] = cast(Nullable!uint)1;

Also an option would be: 
import std.algorithm;
fill(arr, 1);

--


[Issue 15789] ICE Assert in TemplateInstance semanticTiargs

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15789

github-bugzi...@puremagic.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--


[Issue 15789] ICE Assert in TemplateInstance semanticTiargs

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15789

--- Comment #3 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/d316ee1dcec77250f1d27b35754d3b0bc703d017
fix Issue 15789 - ICE Assert in TemplateInstance semanticTiargs

https://github.com/D-Programming-Language/dmd/commit/98b7f150bf2c8e802881f91996111665fc35c239
Merge pull request #5520 from 9rnsr/fix15789

Issue 15789 - ICE Assert in TemplateInstance semanticTiargs

--


Re: Filling an array

2016-03-12 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 12 March 2016 at 14:33:19 UTC, Alex wrote:


//arr[] = 1;

The question is, why the commented out line throws the error:
Error: cannot implicitly convert expression (1) of type int to 
Nullable!uint[],

while the line after that works.


Looks like a bug somewhere. The work around is to cast:

arr[] = cast(Nullable!uint)1;

I suggest you file this in the bug tracker [1] if it isn't there 
already. Just use he minimal code that shows the problem:


void main()
{
import std.typecons;
Nullable!uint[] arr;
arr.length = 5;
arr[] = 1;
}

[1] https://dlang.org/bugstats.php




Re: Why is it not possible to write to a file from a const member function ?

2016-03-12 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 12 March 2016 at 14:02:31 UTC, user42 wrote:


Why is this thing not compiling ?
Or, in other words, how is is possible to log something to a 
file from a const member function ?




Const member functions functions are not allowed to mutate any 
member state at all. This includes the state of any object 
instances that are members. Since the write method of the File 
type is not declared as const, then you can not call it on a 
member of type File from inside a const member function. Logging, 
by its very definition, mutates state.


Move the File instance outside of the class and it works.

import std.stdio;
private File f;
static this() { f = stdout; }

class X
{
  void p(string s) const
  {
 f.writeln!(string)(s);
  }
}

class Y
{
  private string s = "Y";

  override string toString() const
  {
 return s;
  }
}

void main()
{
  auto x = new X;
  auto y = new Y;

  import std.conv: to;
  x.p(to!string(y));
}


Bikeshed: Implementing a command queue.

2016-03-12 Thread maik klein via Digitalmars-d-learn
I wanted to implement a simple command queue in D. To give a bit 
of context, I want to create a command queue for opengl. Instead 
of interacting directly with opengl, you will create commands, 
put them in a queue and then the renderer will read those 
commands and execute the correct OpenGl calls.



I have a few options:

I could use an ADT to create commands but then all commands would 
have the size of the biggest command, also Algebraic is not nice 
nicest thing in D.


I could use runtime polymorphism `class SomeCommand: Command{}` 
but then I would end up with a lot of pointers in the queue, also 
I would need to worry about the allocations.


I have also seen this, but it is a bit more low level and is 
similar to assembly.


Queue:
Command1
int
int
Command2
float
Command3
Command4
int
float double

The first entry would always be the command which is followed by 
the arguments. So you would pop the command out and with the 
command you know how far you need to go into the queue


//pseudo code
auto c = queue.pop!Command;

if(c == Command1){
   int arg1 = queue.pop!int;
   int arg2 = queue.pop!int;
}
if(c == Command2){
   int arg1 = queue.pop!float;

}

How would you implement a simple command queue?







[Issue 15789] ICE Assert in TemplateInstance semanticTiargs

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15789

Kenji Hara  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #2 from Kenji Hara  ---
Better fix (IMO):
https://github.com/D-Programming-Language/dmd/pull/5520

--


Filling an array

2016-03-12 Thread Alex via Digitalmars-d-learn

Hi all!
I have, maybe, a silly question..
Not sure, if
https://forum.dlang.org/post/ibxhuqamgclrcatsy...@forum.dlang.org
has something to do with the topic

Having the following code:

import std.typecons;
import std.algorithm;

void main()
{
uint[] arr_ref;
arr_ref.length = 5;
assert(arr_ref == [0, 0, 0, 0, 0]);
arr_ref[] = 1;
assert(arr_ref == [1, 1, 1, 1, 1]);

Nullable!uint[] arr;
arr.length = 5;
bool[] check_arr;
arr.each!(a => check_arr ~= a.isNull);
assert(check_arr == [true, true, true, true, true]);

//arr[] = 1;
fill(arr, 1);
assert(arr == [1, 1, 1, 1, 1]);
}

The question is, why the commented out line throws the error:
Error: cannot implicitly convert expression (1) of type int to 
Nullable!uint[],

while the line after that works.


Why is it not possible to write to a file from a const member function ?

2016-03-12 Thread user42 via Digitalmars-d-learn

Hi

I have the following snippet to illustrate my problem/question:

class X
{
  import std.stdio: write, File, stdout;

  private File* f = 

  void p(string s) const
  {
 f.write(s);
  }
}

class Y
{
  private string s = "Y";

  override string toString() const
  {
 return s;
  }
}

void main()
{
  auto x = new X;
  auto y = new Y;

  import std.conv: to;
  x.p(to!string(y));
}

Why is this thing not compiling ?
Or, in other words, how is is possible to log something to a file 
from a const member function ?


Thanks in advance


[Issue 10987] Add documentation for 'extern (C++)' classes

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=10987

--- Comment #1 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dlang.org

https://github.com/D-Programming-Language/dlang.org/commit/04427d2bf9030725c0cb79328d67ea6762599917
Update cpp_interface.dd for recent developments

Fix issue 10987

--


Pattern matching as a library

2016-03-12 Thread Simen Kjaeraas via Digitalmars-d
As I once again bemoaned D's lack of pattern matching yesterday, 
I was inspired to create this[0] implementation, that plays to 
D's strengths, allows for user-defined matching, and has a fairly 
usable syntax. The core usage looks like this:


unittest {
  auto a = tuple(1, "foo");
  auto b = match(a) (
_!(int, "foo") = (int i) => 1,
_!(_, _)   = ()  => 0
  );
  assert(b == 1);
}

With the user-defined matching implemented as follows:

struct Tuple(T...) {
   // Implementation

  // Magic happens here
  bool opMatch(Pattern, Args...)(Pattern p, ref Args args) {
foreach (i, e; p.pattern) {
  static if (isTypeTuple!e) {
enum n = countTypes!(p.pattern[0..i]);
args[n] = fields[i];
  } else static if (!ignore!e) {
if (fields[i] != e) {
  return false;
}
  }
}
  }
}

Or for Algebraic:

struct Algebraic(T...) {
  union {
T fields;
  }
  size_t which;

  bool opMatch(Pattern, Type)(Pattern p, ref Type args) if 
(staticIndexOf!(Type, T) > -1) {

enum index = staticIndexOf!(Type, T);
if (index == which) {
  args = fields[index];
  return true;
}
return false;
  }
}

The main problem I see is the temporary allocation of function 
arguments on line 124 and their assignment in opMatch, but I 
currently don't have a better solution.


Also, while I very much dislike using _ for an identifier, I feel 
it may be the best alternative here - it conveys the meaning of 
'don't care' for the pattern, and doesn't stand out like a sore 
thumb before the exclamation mark. Other suggestions are welcome.


The code is available here, and I encourage everyone to play with 
it and critique:


[0]: 
https://github.com/Biotronic/Collectanea/blob/master/biotronic/pattern.d


Re: Clearing associative array.

2016-03-12 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 12 March 2016 at 12:59:02 UTC, ciechowoj wrote:
Nice article :), thanks. But still, what about clear()? In the 
documentation https://dlang.org/spec/hash-map.html#properties 
there is written that associative arrays have clear property.


I don't think that actually works... might be out of date 
documentation, I'm not sure.


Re: Clearing associative array.

2016-03-12 Thread ciechowoj via Digitalmars-d-learn

On Saturday, 12 March 2016 at 12:42:04 UTC, Adam D. Ruppe wrote:

On Saturday, 12 March 2016 at 12:34:16 UTC, ciechowoj wrote:
If above doesn't work how am I supposed to clear the array? `x 
= string[string].init;` is somewhat ugly.


Read the Tip of the Week section here:

http://arsdnet.net/this-week-in-d/dec-13.html

Short answer: use `= null` to clear the AA. [] doesn't work 
just because the compiler is a bit stupid about the type you 
intend it to be, but null works fine.


BTW you might want to glance through more of the issues for the 
tip section too and see if there's more that interest you.


Nice article :), thanks. But still, what about clear()? In the 
documentation https://dlang.org/spec/hash-map.html#properties 
there is written that associative arrays have clear property.


Re: Why does array loses it internal capacity on length change?

2016-03-12 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 12 March 2016 at 09:56:48 UTC, Uldis wrote:

Why is this happening, how to avoid it?


Details here: http://dlang.org/d-array-article.html

it is so one slice can never stomp over the contents of another 
slice when you append to it.


array.assumeSafeAppend() can override it.


Up-to-date DIPs list

2016-03-12 Thread Seb via Digitalmars-d

Hey all,

tl;dr: D's DIPs seem not maintained. A couple of ideas are 
proposed to tackle this state.


I really like the List of D Improvement Proposals 
(http://wiki.dlang.org/DIPs), however it seems to me that they 
are lacking a maintainer.

Let me briefly state what I found:

1) Many DIPs have already been implemented and merged or at least 
they are in progress.


http://wiki.dlang.org/DIP22 Private symbol (in)visibility
http://wiki.dlang.org/DIP29 Unique pointers
http://wiki.dlang.org/DIP43 Objective-C (in progress, partially 
merged?)


2) Moreover I found a couple of DIPs that turned out to be 
unfeasible or too much work for the author.


http://wiki.dlang.org/DIP63 Operator overloading for raw templates

3) There are also DIPs that have been superseeded by other:

http://wiki.dlang.org/DIP36 Rvalue References (by #69)

This list is not complete by any means. The general summary is 
that for draft DIPs only the author really knows its current 
status and well most DIPs are drafts...


As I really like those DIPs and it's sad to see them in such a 
careless shape, I have a couple of ideas that might help to avoid 
this in the future:


Idea 1 Have a bit more "formal" DIP protocol


Currently everyone can add his/her new proposal and imho that's 
very nice - however it leads to the problem of stalled DIPs. 
Introducing a "Stalled" state and having an (automated) process 
that looks over it could help too see which DIPs are in work and 
closed (stalled is very similar to closed).


I) Have a maximal draft period of six month
II) After draft there can be four states: "In progress", 
"Rejected",  "Stalled", "Superseded".

III) Define these follow-up states:

Approved = positive approval of the implementation by the 
community and merged into master [end state]
Rejected = negative approval by the community (e.g. major flaws 
or too complicated) [end state]

Stalled = No activity within six months (most likely an end state)
Superseded = Replaced by a newer DIP [end state]

Draft ---> In progress -->  Implemented  --> Approved
  |^|  ||
  |||  ||
  |-> Stalled <-|  ||
  |   |||
  v   vv|
(Rejected || Superseded) <--|


Idea 2 Use a version control system (aka git)
-

Some troubles - like formal review & automated up-to-date status 
- could be easily solved by putting the DIPs into a git 
plain-text "database".



Idea 3 Getting back to the roots: PEPs
--

https://www.python.org/dev/peps/
https://www.python.org/dev/peps/pep-0001/

Their workflow is sophisticated, why not getting inspired again?
Short summary - read PEP #0001 for more details:

I) The PEP champion (a.k.a. Author) should first attempt to 
ascertain whether the idea is PEP-able. Posting to the 
[newsgroup/mailing list]
II) Idea proposal -- submitted to --> PEP editors (which have the 
right to reject PEP proposals if they appear too unfocused or too 
broad)

III) PEP editors -- assign --> a number to PEP
IV) Draft PEP may be discussed further
V) Once a PEP is completed a PEP, the author may request a review 
for style and consistency from the PEP editors. However, the 
content and final acceptance of the PEP must be requested of the 
BDFL [Benevolent Dictator For Life, Guido van Rossum], usually 
via an email. PEPs are reviewed by the BDFL and his chosen 
consultants, who may accept or reject a PEP or send it back to 
the author(s) for revision. For a PEP to be accepted it must meet 
certain minimum criteria:
 - It must be a clear and complete description of the proposed 
enhancement.

 - The enhancement must represent a net improvement.
 - The proposed implementation, if applicable, must be solid and 
must not complicate the interpreter unduly.
VI) When a PEP is Accepted, Rejected or Withdrawn, the PEP should 
be updated accordingly.


-

Those are just some ideas I wanted to send out to you - feel free 
to combine, destroy, cherry-pick them or to add your own ideas ;-)


Cheers,

Seb


Re: Clearing associative array.

2016-03-12 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 12 March 2016 at 12:34:16 UTC, ciechowoj wrote:
If above doesn't work how am I supposed to clear the array? `x 
= string[string].init;` is somewhat ugly.


Read the Tip of the Week section here:

http://arsdnet.net/this-week-in-d/dec-13.html

Short answer: use `= null` to clear the AA. [] doesn't work just 
because the compiler is a bit stupid about the type you intend it 
to be, but null works fine.


BTW you might want to glance through more of the issues for the 
tip section too and see if there's more that interest you.




Clearing associative array.

2016-03-12 Thread ciechowoj via Digitalmars-d-learn

Could someone explain to me, why following code does not compile?

int main()
{
string[string] x = [ "foo" : "bar" ];
x.clear();
x = [];

return 0;
}

Errors:
main.d(7): Error: no property 'clear' for type 'string[string]'
main.d(8): Error: cannot implicitly convert expression ([]) of 
type void[] to string[string]

Failed: ["dmd", "-v", "-o-", "main.d", "-I."]

If above doesn't work how am I supposed to clear the array? `x = 
string[string].init;` is somewhat ugly.


dmd --version
DMD64 D Compiler v2.070.0
Copyright (c) 1999-2015 by Digital Mars written by Walter Bright



[Issue 15788] [REG2.069] ICE assert triggered on overloaded function

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15788

Kenji Hara  changed:

   What|Removed |Added

   Keywords||pull
Summary|ICE assert triggered on |[REG2.069] ICE assert
   |overloaded function |triggered on overloaded
   ||function

--- Comment #1 from Kenji Hara  ---
https://github.com/D-Programming-Language/dmd/pull/5519

--


[Issue 11886] "cannot access frame" error on lambda in lambda

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=11886

Kenji Hara  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #5 from Kenji Hara  ---
https://github.com/D-Programming-Language/dmd/pull/5518

--


[Issue 15791] Cannot get a stored nested struct object from Variant

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15791

Kenji Hara  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #1 from Kenji Hara  ---
https://github.com/D-Programming-Language/phobos/pull/4074

--


[Issue 15791] New: Cannot get a stored nested struct object from Variant

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15791

  Issue ID: 15791
   Summary: Cannot get a stored nested struct object from Variant
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Keywords: rejects-valid
  Severity: normal
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: k.hara...@gmail.com

Following test case fails to compile.

void main()
{
import std.variant;

int n = 3;
struct NS1 { int foo() { return n + 10; } }
struct NS2 { int foo() { return n * 10; } }

Variant v;
v = NS1();
assert(v.get!NS1.foo() == 13);   // Line 11
v = NS2();
assert(v.get!NS2.foo() == 30);   // Line 13
}

$ dmd -o- test
DMD v2.070 DEBUG
phobos\std\variant.d(755): Error: cannot access frame pointer of test.main.NS1
test.d(11): Error: template instance
std.variant.VariantN!20u.VariantN.get!(NS1) error instantiating
phobos\std\variant.d(755): Error: cannot access frame pointer of test.main.NS2
test.d(13): Error: template instance
std.variant.VariantN!20u.VariantN.get!(NS2) error instantiating

--


Re: BZ2 library

2016-03-12 Thread stunaep via Digitalmars-d-learn

On Saturday, 12 March 2016 at 10:10:44 UTC, Basile B. wrote:

On Saturday, 12 March 2016 at 09:53:36 UTC, stunaep wrote:

[...]


"dflags" : ["lib\\libbzip2.lib"] is only if you want to compile 
as 32 bit AND in OMF, so the -m32mscoff switch must NOT be set 
(I see that someone else explained you how to compile using the 
coff object format, which is not the same thing as I've 
explained before)


so in the config you should have something like that

"configurations" :
[
{
  "name" : "win32omf",
  "dflags" : ["lib\\omf32\\libbzip2.lib"] // made with dmc 
or converted

},
{
  "name" : "win64coff",
  "dflags" : ["lib\\coff64\\libbzip2.lib", "-m64"] // made 
with gcc

},
]


Thanks for that. The other issue I had was solved because I wasnt 
using runtime library /MT when compiling the .lib.


[Issue 15789] ICE Assert in TemplateInstance semanticTiargs

2016-03-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15789

--- Comment #1 from Johan Engelen  ---
https://github.com/D-Programming-Language/dmd/pull/5517

--


Re: Why does array loses it internal capacity on length change?

2016-03-12 Thread Jack Applegame via Digitalmars-d-learn

Why is this happening...?
For safety reasons. Your array can be shared between parts of 
application.

...how to avoid it?

https://dlang.org/library/object/assume_safe_append.html




Re: BZ2 library

2016-03-12 Thread Basile B. via Digitalmars-d-learn

On Saturday, 12 March 2016 at 09:53:36 UTC, stunaep wrote:

On Saturday, 12 March 2016 at 07:56:03 UTC, Mike Parker wrote:

 [...]


On Saturday, 12 March 2016 at 09:04:08 UTC, stunaep wrote:

On Saturday, 12 March 2016 at 07:56:03 UTC, Mike Parker wrote:

[...]


If I do "dflags" : ["lib/libbzip2.lib"] as Basile B. suggested 
instead of pragma, I get the same error on x86_64 as I do on 
x86


I think "dflags" : ["lib/libbzip2.lib"] is not loading anything 
at all because the same thing happens if I delete the lib file


"dflags" : ["lib\\libbzip2.lib"] is only if you want to compile 
as 32 bit AND in OMF, so the -m32mscoff switch must NOT be set (I 
see that someone else explained you how to compile using the coff 
object format, which is not the same thing as I've explained 
before)


so in the config you should have something like that

"configurations" :
[
{
  "name" : "win32omf",
  "dflags" : ["lib\\omf32\\libbzip2.lib"] // made with dmc or 
converted

},
{
  "name" : "win64coff",
  "dflags" : ["lib\\coff64\\libbzip2.lib", "-m64"] // made 
with gcc

},
]




Why does array loses it internal capacity on length change?

2016-03-12 Thread Uldis via Digitalmars-d-learn
While writing a structs function that I wanted to minimize 
allocations and use an internal preallocated buffer, but I 
noticed that arrays are losing their capacity when its length is 
changed.


For example:

void main() {

int[] a;
a.reserve = 1024;

void dump(in ref int[] b,size_t line = __LINE__) {
import std.stdio;
writeln(line, ": Buffer length = ", b.length, " 
capacity= ", b.capacity);

}
dump(a); // line 10
a.length = 0;
dump(a);
a ~= [1,2,3];
dump(a);
a.length = 0;
dump(a);
a ~= [4,5,6];
dump(a);
}

gives output:

10: Buffer length = 0 capacity= 2043
12: Buffer length = 0 capacity= 2043
14: Buffer length = 3 capacity= 2043
16: Buffer length = 0 capacity= 0
18: Buffer length = 3 capacity= 3

but I expected:

10: Buffer length = 0 capacity= 2043
12: Buffer length = 0 capacity= 2043
14: Buffer length = 3 capacity= 2043
16: Buffer length = 0 capacity= 2043
18: Buffer length = 3 capacity= 2043


Why is this happening, how to avoid it?




Re: BZ2 library

2016-03-12 Thread stunaep via Digitalmars-d-learn

On Saturday, 12 March 2016 at 07:56:03 UTC, Mike Parker wrote:

 [...]


On Saturday, 12 March 2016 at 09:04:08 UTC, stunaep wrote:

On Saturday, 12 March 2016 at 07:56:03 UTC, Mike Parker wrote:

[...]


If I do "dflags" : ["lib/libbzip2.lib"] as Basile B. suggested 
instead of pragma, I get the same error on x86_64 as I do on x86


I think "dflags" : ["lib/libbzip2.lib"] is not loading anything 
at all because the same thing happens if I delete the lib file


Re: code-d 0.10.1 released (D support for vscode)

2016-03-12 Thread Dmitry Olshansky via Digitalmars-d-announce

On 11-Mar-2016 23:03, WebFreak001 wrote:

I just released a new version of code-d, it now supports projects
without any dub.json file which some people probably will like. This is
really useful for standalone projects with a custom build system like
writing an OS/Kernel or other projects that don't want to use dub.



It would really help to state first of all that code-d is a D extension 
for Visual Studio Code which is a nice thing even though I never tried it.



--
Dmitry Olshansky


Re: code-d 0.10.1 released (D support for vscode)

2016-03-12 Thread WebFreak001 via Digitalmars-d-announce
Additionally if you use dub for your projects you can now get an 
additional package version manager from the vscode marketplace 
which makes sure your dependencies are up to date.


ext install versionlens

then open a dub.json file and you are ready to go

Github: https://github.com/pflannery/vscode-versionlens
Marketplace: 
https://marketplace.visualstudio.com/items?itemName=pflannery.vscode-versionlens


Re: BZ2 library

2016-03-12 Thread stunaep via Digitalmars-d-learn

On Saturday, 12 March 2016 at 07:56:03 UTC, Mike Parker wrote:

[...]


If I do "dflags" : ["lib/libbzip2.lib"] as Basile B. suggested 
instead of pragma, I get the same error on x86_64 as I do on x86


Re: Pitching D to academia

2016-03-12 Thread Russel Winder via Digitalmars-d
On Thu, 2016-03-10 at 23:47 +, Andrew via Digitalmars-d wrote:
[…]
> One of awful things about programming in many languages is that 
> there's a gazillion tools you need to tack-on before you can do 
> any engineering.  In C++ that includes Doxygen for documentation, 
> C++Unit for unit tests, gprof, gcov, valgrind, and so on.  One of 
> the nice things about D is that so much of this is part of the 
> language or build into DMD.

No-one should be using C++Unit for testing in C++ codes. USe a header
only system such as Catch or CUTE.

> So yes, sure, you can add what ever you like the Java and claim 
> its just as good (or better). The difference is that in D its all 
> right there already.

And Java is already right there in the context of teaching. Adding bits
to an extent infrastructure is easier that revolutionizing the
infrastructure. Been there done this three times: far too many
academics are weighed down by inertia when it comes to changing their
infrastructure.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part


Re: Deduction regression or improvement?

2016-03-12 Thread Timon Gehr via Digitalmars-d

On 12.03.2016 08:58, deadalnix wrote:



IMO, this *should* compile and infer T == const(SomeStruct) as the
common type of a and b.  But I'm not sure whether or not this is a
regression.


T


More tricky actually.

If T has indirection, then that is the correct answer. If not, the T ==
SomeStruct.


Actually the documentation currently special-cases pointers and arrays:
"The deduced type parameter for dynamic array and pointer arguments has 
an unqualified head:"


http://dlang.org/spec/template.html#function-templates


Re: Pitching D to a gang of Gophers

2016-03-12 Thread Russel Winder via Digitalmars-d
On Sat, 2016-03-12 at 11:09 +0300, Dmitry Olshansky via Digitalmars-d
wrote:
> On 05-Mar-2016 14:05, Dmitry Olshansky wrote:
> > 
> > I'm having an opportunity to do a small tech-talk on things D in a
> > eCommerce shop that is currently sold on Go (migrating to SOA from
> > PHP
> > monolith). I do not intend that to become Go vs D battle but it
> > gives
> > the context.

Switching from PHP to Go is not a bad idea as CloudFlare have blazed
that trail and created a who community around it. 

> The talk went better then I would expect with lots of good
> questions. 

Sounds like some good people, using Go for good reasons not blind
fashion.

> Compile-time features generated the most favorable discussion.

This is now a bit topic again in C++, witness all the debating over
constexpr and C++17 and C++20.

> Obligatory slides:
> http://slides.com/dmitryolshansky/deck/fullscreen/
> 
> std.concurrency working only with threads and lack of better
> integration 
> of fibers in std is our weak spot as prompted by further questions.

Clearly there are many feature similarities between D and Go as well as
differences (slices vs. generics). looked like a nice selection of
example in teh slides to pick up on this.

Thread pool and work stealing is clearly the way forward for
actor/dataflow architecture, though explicit threads have their place
as well.

std.parallelism has a task pool system. I wonder if there should be a
strategic move to (in some sense) merge std.concurrency, std.fibers and
std.parallelism into a single consistent whole (possibly remaining
three separate by connected packages rather than a single monolith.

Java has had great benefit from having a single concurrency/parallelism
strategy even though it ends up with different leaves not a monolith.
 
-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part


Re: Potential GSoC project - GC improvements

2016-03-12 Thread Adam Wilson via Digitalmars-d

Jeremy DeHaan wrote:

Thank you all for the feedback.

I think I might still need a little more feedback as to what the project
should actually entail, but here's what it's looking like so far:

Implement lock free allocation using std.experimental.allocator's
freelists (SharedFreeList? It was the only thing in the documentation
that specifically mentions lock free allocation)

Implement a generational garbage collector

Implement precise garbage collection (possibly piggybacking off of
Rainer's work)


Does anyone think that might be too much to take on or does it sound
pretty good? I have other garbage collector things I'd like to explore,
but I they should probably go in the "if time allows" category at this
point.

Jeremy


If I may make a suggestion. The lock free work is unlikely to require 
the entirety of GSoC. And the precise GC is the next most important 
thing on your list and will have the biggest impact on GC performance.


Once the GC is fully precise we can implement a fully compacting GC, 
which improves the usefulness of generational collection. Additionally, 
precision allows a significant amount of work to be done in improving 
the performance of the GC in multi-threaded scenarios. It should be 
quite possible to avoid needing fork() or anything like it altogether. I 
know that the .NET GC doesn't need to use anything like it.


Also, I would strongly recommend getting this book and reading it cover 
to cover before starting:

http://www.amazon.com/gp/product/1420082795/ref=pd_lpo_sbs_dp_ss_1?pf_rd_p=1944687562_rd_s=lpo-top-stripe-1_rd_t=201_rd_i=0471941484_rd_m=ATVPDKIKX0DER_rd_r=0QD9X3E5QATSBCBT6BMM

I think Rainer's Precise GC only dealt with Heap objects. What needs 
work is Register and Stack scanning. Expanding on Rainer's existing 
Precise GC work is the right idea, but Register and Stack scanning is a 
very big project in it's own right.I suspect it will take up the 
remainder of your GSoC time. :)


--
// Adam Wilson
// quiet.dlang.dev


Re: Constructor - the both look the same

2016-03-12 Thread Iakh via Digitalmars-d-learn

On Saturday, 12 March 2016 at 07:43:59 UTC, Joel wrote:

Why does it come up with this?

source/setup.d(40,16): Error: constructor 
inputjex.InputJex.this (Vector2!float pos, int fontSize, 
InputType type = cast(InputType)0) is not callable using 
argument types (Vector2!float, int, InputType)

dmd failed with exit code 1.


Can you show your code?


Re: Pitching D to a gang of Gophers

2016-03-12 Thread Dmitry Olshansky via Digitalmars-d

On 05-Mar-2016 14:05, Dmitry Olshansky wrote:

I'm having an opportunity to do a small tech-talk on things D in a
eCommerce shop that is currently sold on Go (migrating to SOA from PHP
monolith). I do not intend that to become Go vs D battle but it gives
the context.


The talk went better then I would expect with lots of good questions. 
Compile-time features generated the most favorable discussion.


Obligatory slides:
http://slides.com/dmitryolshansky/deck/fullscreen/

std.concurrency working only with threads and lack of better integration 
of fibers in std is our weak spot as prompted by further questions.


--
Dmitry Olshansky


Re: BZ2 library

2016-03-12 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 12 March 2016 at 06:50:59 UTC, stunaep wrote:

On Saturday, 12 March 2016 at 06:07:25 UTC, Mike Parker wrote:

[...]


I used visual studio 2013 to build the libraries

With dflag -m64 and dub flag --arch=x86_64, this happens


You shouldn't specify -m64 in your configuration. DUB will do 
that for you when you feed it --arch=x86_64.



LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with 
use of other libs; use /NODEFAULTLIB:library

.dub\build\application-debug-windows-x86_64-dmd_2070-F2AB32EEAA78A29A3AA6010749D38D4A\rsdlib.exe : fatal error LNK1169: one or more multiply defined symbols found

--- errorlevel 1169
dmd failed with exit code 1169.



Make sure that DMD's sc.ini is configured to point to the same 
developer binaries you used to compile the bzip binary. If, for 
example, it is pointing to, say, an older version of the Windows 
SDK, but you used VS 2013 Community to compile bzip, conflicts 
like this are possible. I've had this sort of issue before.





and with dflag -m32mscoff, this happens

Performing "debug" build using dmd for x86.
rsdlib ~master: building configuration "application"...
Linking...
rsdlib.obj : error LNK2019: unresolved external symbol 
_BZ2_bzDecompressInit referenced in function 
_D6rsdlib6cache39Container6decodeFC6rsdlib2io10ByteBufferAiZC6rsdlib6cache39Container
rsdlib.obj : error LNK2019: unresolved external symbol 
_BZ2_bzDecompress referenced in function 
_D6rsdlib6cache39Container6decodeFC6rsdlib2io10ByteBufferAiZC6rsdlib6cache39Container
rsdlib.obj : error LNK2019: unresolved external symbol 
_BZ2_bzDecompressEnd referenced in function 
_D6rsdlib6cache39Container6decodeFC6rsdlib2io10ByteBufferAiZC6rsdlib6cache39Container

.dub\build\application-debug-windows-x86-dmd_2070-E301E842F2B5FA1A3A9D79D8EE34C4E8\rsdlib.exe : fatal error LNK1120: 3 unresolved externals

--- errorlevel 1120
dmd failed with exit code 1120.


DUB does not yet have built-in support for -m32mscoff. Passing it 
in 'dflags' will cause it to be used to compile your executable, 
but it will not apply to any dependencies you have. I don't know 
if this is the cause of these errors or not, but there is an 
enhancement request in DUB's issue tracker for it [1].


[1] https://github.com/D-Programming-Language/dub/issues/628


Re: Deduction regression or improvement?

2016-03-12 Thread deadalnix via Digitalmars-d

On Tuesday, 8 March 2016 at 22:35:57 UTC, H. S. Teoh wrote:
On Tue, Mar 08, 2016 at 09:22:35PM +, Johan Engelen via 
Digitalmars-d wrote:

Hi all,
  Should the following compile or not?

auto foo(T)(T start, T end) {}
void main() {
const SomeStruct a;
SomeStruct b;
foo(a,b);
}
See http://dpaste.dzfl.pl/15581af64747

DMD 2.068.2 compiles and does not complain.
DMD 2.069.2 gives deduction error: "cannot deduce function 
from argument
types !()(const(SomeStruct), SomeStruct),   candidates are:  
foo(T)(T start,

T end)"

Is this a regression or intended?  I did not find something 
about it in the release notes.

[...]

IMO, this *should* compile and infer T == const(SomeStruct) as 
the common type of a and b.  But I'm not sure whether or not 
this is a regression.



T


More tricky actually.

If T has indirection, then that is the correct answer. If not, 
the T == SomeStruct.