Re: Array of structs construction

2012-10-19 Thread H. S. Teoh
On Fri, Oct 19, 2012 at 10:42:08PM -0700, H. S. Teoh wrote:
[...]
>   import std.stdio;
>   string structArray(S)(string[] args...) {
>   string s = "[";
>   string delim = "";
>   foreach (a; args) {
>   s ~= delim ~ S.stringof ~ "(" ~ a ~ ")";
>   delim = ",";
>   }
>   return s ~ "]";
>   }
[...]

Here's how to use it for making BigInt arrays:

void main() {
BigInt[] arr = mixin(structArray!BigInt(
`"12345678901234567890"`,
`"4294967296000"`,
`"10"`,
`"120300400056070080009"`,
));

writeln(arr);
}

It works for any kind of struct with ctors. Should be trivially
extendible to array of class objects. Some improvement in usage syntax
is probably possible, too, but I'll leave it up to the CTFE experts here
to figure that out. ;-)


T

-- 
Why ask rhetorical questions? -- JC


Re: private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread Nick Sabalausky
On Sat, 20 Oct 2012 00:18:28 +0200
"foobar"  wrote:
> 
> virtual private is an obscure C++ idiom which I think the 
> argument for is extremely week.


Well like I said though, virtual private is *very* different in C++
than it is in D, because private itself is very different in C++ than
in D.

> I think Walter made the right 
> decision here in favor of more readable code.
> 



Re: Array of structs construction

2012-10-19 Thread H. S. Teoh
On Fri, Oct 19, 2012 at 10:32:48PM -0700, H. S. Teoh wrote:
> On Sat, Oct 20, 2012 at 03:06:56AM +0200, bearophile wrote:
> > I'd like to write code like this (the constructors of the structs
> > must take 1 argument):
> > 
> > // some imports here
> > void main() {
> > BigInt[] data1 = [5, 6, 9];
> > Ranged!(int,5,10)[] data2 = [5, 6, 9];
> > Nibble[] data3 = [1, 2, 15]; // Nibble.sizeof == 1
> > alias Typedef!int Mint;
> > Mint[] data4 = [5, 6, 9];
> > }
> > 
> > 
> > Do you like this feature?
> [...]
> 
> What about mixin() with a CTFE function that expands an array of
> initializers at compile-time? Something like:
[...]

OK, here's a tested, working example:

import std.stdio;
string structArray(S)(string[] args...) {
string s = "[";
string delim = "";
foreach (a; args) {
s ~= delim ~ S.stringof ~ "(" ~ a ~ ")";
delim = ",";
}
return s ~ "]";
}
struct AStruct {
int x, y;
}
void main() {
AStruct[] arr = mixin(structArray!AStruct("1,1", "1,2", "2,2", 
"2,3"));
writeln(arr);
}


T

-- 
"Life is all a great joke, but only the brave ever get the point." -- Kenneth 
Rexroth


Re: Array of structs construction

2012-10-19 Thread H. S. Teoh
On Sat, Oct 20, 2012 at 03:06:56AM +0200, bearophile wrote:
> I'd like to write code like this (the constructors of the structs
> must take 1 argument):
> 
> // some imports here
> void main() {
> BigInt[] data1 = [5, 6, 9];
> Ranged!(int,5,10)[] data2 = [5, 6, 9];
> Nibble[] data3 = [1, 2, 15]; // Nibble.sizeof == 1
> alias Typedef!int Mint;
> Mint[] data4 = [5, 6, 9];
> }
> 
> 
> Do you like this feature?
[...]

What about mixin() with a CTFE function that expands an array of
initializers at compile-time? Something like:

string structArray(S,T...)(T args)
if (is(typeof(S(args[0]
{
// Warning: untested code
return "[" ~ join(
map!(a) => S.stringof ~ "(" ~ a ~ ")", ",") ~
"]";
}

S[] sArr = mixin(structArray(elem0, elem1, elem2));


T

-- 
English has the lovely word "defenestrate", meaning "to execute by
throwing someone out a window", or more recently "to remove Windows from
a computer and replace it with something useful". :-) -- John Cowan


Re: Array of structs construction

2012-10-19 Thread Era Scarecrow

On Saturday, 20 October 2012 at 01:06:57 UTC, bearophile wrote:
I'd like to write code like this (the constructors of the 
structs must take 1 argument):


// some imports here
void main() {
BigInt[] data1 = [5, 6, 9];
Ranged!(int,5,10)[] data2 = [5, 6, 9];
Nibble[] data3 = [1, 2, 15]; // Nibble.sizeof == 1
alias Typedef!int Mint;
Mint[] data4 = [5, 6, 9];
}


Do you like this feature?

Currently in D you write this, it's not handy if you have many 
items:


// some imports here
void main() {
auto data1 = [BigInt(5), BigInt(6), BigInt(9)];
alias Ranged!(int,5,10) R; // a short name
auto data2 = [R(5), R(6), R(9)];
auto data3 = [Nibble(1), Nibble(2), Nibble(15)];
alias Typedef!int Mint;
Mint[] data4 = [Mint(5), Mint(6), Mint(9)];
}


 Only way i can see this working simply, is if it's auto, at 
least one of the items have to specify it's full type and the 
rest can be ignored. Also it must have a constructor that takes 
that one type of argument. So..


//50 & 100 aren't BigInt, but can be constructed to be one..
 auto bignums = [BigInt(25), 50, 100];

 As for above arrays where the type is known, I can't see a 
reason why it can't work.


 In a large array of static data I've had to make shortcut names 
for several structs in order to keep it readable and 
programmable. This may help in some cases, or perhaps all of them.


 Course this also means if a structure is being initialized then 
perhaps it can be extended. Like the above, except...


 struct S {
   int x,y;
   BigInt z;
 }

 S s = {1,2,3}; //3 converted if BigInt has a constructor for int

//if that's illegal, then you'd do this to make it work instead,
//which seems... unnecessary.
 struct S {
   int x,y;
   BigInt[1] z;
 }

 S s = {1,2,[3]};


 The downside is if there's memory allocation or heavy work that 
can't be done at compile-time then there may be more complex 
issues trying to optimize something. Makes it sorta mixed.


Array of structs construction

2012-10-19 Thread bearophile
I'd like to write code like this (the constructors of the structs 
must take 1 argument):


// some imports here
void main() {
BigInt[] data1 = [5, 6, 9];
Ranged!(int,5,10)[] data2 = [5, 6, 9];
Nibble[] data3 = [1, 2, 15]; // Nibble.sizeof == 1
alias Typedef!int Mint;
Mint[] data4 = [5, 6, 9];
}


Do you like this feature?


Scala accepts a similar syntax:
http://ideone.com/mFuVxP


// Scala code
object Main extends App {
  val data : Array[BigInt] = Array(10, 20, 30)
}


Currently in D you write this, it's not handy if you have many 
items:


// some imports here
void main() {
auto data1 = [BigInt(5), BigInt(6), BigInt(9)];
alias Ranged!(int,5,10) R; // a short name
auto data2 = [R(5), R(6), R(9)];
auto data3 = [Nibble(1), Nibble(2), Nibble(15)];
alias Typedef!int Mint;
Mint[] data4 = [Mint(5), Mint(6), Mint(9)];
}


Or you duplicate the arrays to avoid the bit liberals:

import std.bigint;
void main() {
auto aux = [5, 6, 9];
auto data1 = new BigInt[aux.length];
foreach (i, a; aux)
data1[i] = BigInt(a);
// ...
}

Bye,
bearophile


Re: private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread Jonathan M Davis
On Friday, October 19, 2012 23:22:26 monarch_dodra wrote:
> According to TDPL, this should be legal. In particular, there is
> an entire section about it regarding NVI.
> 
> No idea what it going on, but I'm curious for answers.

For interfaces, where it's doing something to specifically enable NVI. It never 
says that for classes.

It's been discussed a number of times before, and I think that it's fairly 
clear that Walter has no intention of changing it. Regardless, it would 
actually be a _huge_ problem for private to be virtual, and it's completely 
unnecessary for NVI (protected does the job just fine). If private were 
virtual, then it that would kill inlining and any other optimization relying 
on knowing the body of the function or anything else which gets affected by a 
function being virtual - including the cost of the vtable lookup. You would be 
forced to mark all private functions as final to fix this, which most people 
won't do, which would lead to performance hits everywhere where classes are 
used. Classes in D would be less performant for essentially _zero_ gain.

If you want virtual but don't want the function to be public, then use 
protected.

- Jonathan M Davis


Re: private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky wrote:

My understanding is that this is intentionally disallowed:

---
module foo;

class Foo
{
private void func() {}
}

class Bar : Foo
{
// Disallowed:
private override void func() {}
}

void foobar(Foo f)
{
f.func();
}
---

If D had C++'s "private", that restriction would make a lot of 
sense
(except possibly for nested classes, but I dunno). That's 
because: How

can you override a class you can't even access?

But D doesn't have a "true" private in the C++ sense. Instead, 
there

is code outside a class which *is* permitted to access "private"
members.

So am I missing something, or was the sample case above 
overlooked when

making the "private must be non-virtual" decision?


virtual private is an obscure C++ idiom which I think the 
argument for is extremely week. I think Walter made the right 
decision here in favor of more readable code.


I'd do the following:
---
module foo;
class Foo {
private void func() { funcImpl(); }
protected void funcImpl() {}
}

class Bar : Foo {
protected override void funcImpl() {}
}

void foobar(Foo f) {
f.func();
}
---


Re: private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread Peter Alexander

On Friday, 19 October 2012 at 21:22:28 UTC, monarch_dodra wrote:

On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky
So am I missing something, or was the sample case above 
overlooked when

making the "private must be non-virtual" decision?


According to TDPL, this should be legal. In particular, there is
an entire section about it regarding NVI.

No idea what it going on, but I'm curious for answers.


It's a bug.

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


Re: private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread monarch_dodra

On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky wrote:

My understanding is that this is intentionally disallowed:

---
module foo;

class Foo
{
private void func() {}
}

class Bar : Foo
{
// Disallowed:
private override void func() {}
}

void foobar(Foo f)
{
f.func();
}
---

If D had C++'s "private", that restriction would make a lot of 
sense
(except possibly for nested classes, but I dunno). That's 
because: How

can you override a class you can't even access?

But D doesn't have a "true" private in the C++ sense. Instead, 
there

is code outside a class which *is* permitted to access "private"
members.

So am I missing something, or was the sample case above 
overlooked when

making the "private must be non-virtual" decision?


According to TDPL, this should be legal. In particular, there is
an entire section about it regarding NVI.

No idea what it going on, but I'm curious for answers.


private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread Nick Sabalausky
My understanding is that this is intentionally disallowed:

---
module foo;

class Foo
{
private void func() {}
}

class Bar : Foo
{
// Disallowed:
private override void func() {}
}

void foobar(Foo f)
{
f.func();
}
---

If D had C++'s "private", that restriction would make a lot of sense
(except possibly for nested classes, but I dunno). That's because: How
can you override a class you can't even access?

But D doesn't have a "true" private in the C++ sense. Instead, there
is code outside a class which *is* permitted to access "private"
members.

So am I missing something, or was the sample case above overlooked when
making the "private must be non-virtual" decision?



Re: D seems interesting, but...

2012-10-19 Thread Era Scarecrow

On Monday, 15 October 2012 at 14:29:42 UTC, foobar wrote:

Java has the correct DRY solution - each class can define a 
static main method but the compiler only uses the one specified 
by a compiler switch.
The above basically asks the programmer to endlessly repeat the 
same trivial implementation boilerplate that should be written 
just once _in_ the compiler.


 I remember this. I remember scratching my head and asking why, 
but then realizing that likely 99% of the time it's never called, 
so I started using it to build and do unittests (without Junit).


 Curiously. I'm suddenly reminded of a test suite I made for a 
company for Visual Basic. It was years ago and a nice little test 
suite; I really wish I had a copy.


Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 18:46:07 UTC, foobar wrote:

On Friday, 19 October 2012 at 15:07:44 UTC, Don Clugston wrote:

On 19/10/12 16:07, foobar wrote:
On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston 
wrote:


We can still have both (assuming the code points are 
valid...):

string foo = "\ua1\ub2\uc3"; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, "assuming the code points are valid". It says so 4 
lines above!


It isn't the same.
Hex strings are the raw bytes, eg UTF8 code points. (ie, it 
includes the high bits that indicate the length of each char).

\u makes dchars.

"\u00A1" is not the same as x"A1" nor is it x"00 A1". It's two 
non-zero bytes.


Yes, the \u requires code points and not code-units for a 
specific UTF encoding, which you are correct in pointing out 
are four hex digits and not two.
This is a very reasonable choice to prevent/reduce Unicode 
encoding errors.


http://dlang.org/lex.html#HexString states:
"Hex strings allow string literals to be created using hex 
data. The hex data need not form valid UTF characters."


I _already_ said that I consider this a major semantic bug as 
it violates the principle of least surprise - the programmer's 
expectation that the D string types which are Unicode according 
to the spec to, well, actually contain _valid_ Unicode and 
_not_ arbitrary binary data.
Given the above, the design of \u makes perfect sense for 
_strings_ - you can use _valid_ code-points (not code units) in 
hex form.


For general purpose binary data (i.e. _not_ UTF encoded Unicode 
text) I also _already_ said IMO should be either stored as 
ubyte[] or better yet their own types that would ensure the 
correct invariants for the data type, be it audio, video, or 
just a different text encoding.


In neither case the hex-string is relevant IMO. In the former 
it potentially violates the type's invariant and in the latter 
we already have array literals.


Using a malformed _string_ to initialize ubyte[] IMO is simply 
less readable. How did that article call such features, "WAT"?


I just re-checked and to clarify string literals support _three_ 
escape sequences:

\x__ - a single byte
\u - two bytes
\U - four bytes

So raw bytes _can_ be directly specified and I hope the compiler 
still verifies the string literal is valid Unicode.





Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 15:07:44 UTC, Don Clugston wrote:

On 19/10/12 16:07, foobar wrote:

On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston wrote:


We can still have both (assuming the code points are 
valid...):

string foo = "\ua1\ub2\uc3"; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, "assuming the code points are valid". It says so 4 
lines above!


It isn't the same.
Hex strings are the raw bytes, eg UTF8 code points. (ie, it 
includes the high bits that indicate the length of each char).

\u makes dchars.

"\u00A1" is not the same as x"A1" nor is it x"00 A1". It's two 
non-zero bytes.


Yes, the \u requires code points and not code-units for a 
specific UTF encoding, which you are correct in pointing out are 
four hex digits and not two.
This is a very reasonable choice to prevent/reduce Unicode 
encoding errors.


http://dlang.org/lex.html#HexString states:
"Hex strings allow string literals to be created using hex data. 
The hex data need not form valid UTF characters."


I _already_ said that I consider this a major semantic bug as it 
violates the principle of least surprise - the programmer's 
expectation that the D string types which are Unicode according 
to the spec to, well, actually contain _valid_ Unicode and _not_ 
arbitrary binary data.
Given the above, the design of \u makes perfect sense for 
_strings_ - you can use _valid_ code-points (not code units) in 
hex form.


For general purpose binary data (i.e. _not_ UTF encoded Unicode 
text) I also _already_ said IMO should be either stored as 
ubyte[] or better yet their own types that would ensure the 
correct invariants for the data type, be it audio, video, or just 
a different text encoding.


In neither case the hex-string is relevant IMO. In the former it 
potentially violates the type's invariant and in the latter we 
already have array literals.


Using a malformed _string_ to initialize ubyte[] IMO is simply 
less readable. How did that article call such features, "WAT"?


Request for Help: D tool for SCons

2012-10-19 Thread Russel Winder
I do not have access to a Windows box or VM, and to be honest, I would
really rather not. This means the D tool for SCons is being developed
and tested on Debian Linux and OS X only. This means Windows is untested
and uncared for. A corollary is that the D tool in SCons will never be
updated, because the Windows tests are failing. Thus there is a need for
a person who has access to a Windows machine or two, some knowledge of
Python, an interest in D development and D software build, and a
willingness to collaborate with me. Oh and must be willing to use
Mercurial.

From what I can see the current D tool fails the tests but this has only
been noticed after a number of years because no SCons CI server had had
D installed until recently, and I never tested on Windows at all.  This
means that the most likely action for the SCons developers is to pull
all D support. This is not good for SCons and not good for D.

The need is to fix the new stuff on Windows.

Clearly for testing in an ideal world we need a Windows with no D, one
with each of GDC, LDC and DMD alone, and then all the various
combinations. But what is needed immediately is to test with no D and
some D so as to get the functional tests not to fail.
 
Thanks.

-- 
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: More range woes: composed ranges are unsafe to return from functions

2012-10-19 Thread H. S. Teoh
On Fri, Oct 19, 2012 at 09:22:29AM +0300, Andrei Alexandrescu wrote:
> On 10/19/12 8:17 AM, H. S. Teoh wrote:
> >On Fri, Oct 19, 2012 at 04:24:53AM +0200, Marco Leise wrote:
> >>Am Tue, 16 Oct 2012 17:28:47 -0700
> >>schrieb "H. S. Teoh":
[...]
> >>>Whew, what a day! Two compiler bugs, no less, and a whole bunch of
> >>>Phobos issues. I think I may need to take a break from D for a day
> >>>or two. :-/
> >[...]
> >>And that's where all the good projects end... :D
> >[...]
> >
> >Actually, I just went back to working on my personal D project for a
> >bit. I was a bit disappointed that what I thought would be a quick
> >side-job (implement cartesianProduct in std.algorithm) turned out to
> >get stymied by compiler bugs and Phobos issues.
> 
> Admittedly cartesianProduct is a nontrivial juxtaposition of quite a
> few other artifacts.

While it is by no means trivial, it is also relatively simple, as far as
functional programming goes. I'd say it's a "real-world" test of our
current implementation of map, zip, & co.. If we're going to be touting
functional programming in D, we'd better get our act together and make
sure putting these primitives together will always work correctly, lest
we get laughed at by real functional programmers.


> The question here is whether this is just endless churn or real
> progress. I'm optimistic, but am curious about others' opinion.

I'm not sure what you're referring to by "this". Are you talking about
cartesianProduct specifically, or something more general?


> [snip]
> >So yes, D still has a ways to go, and it does have its warts, but
> >it's heaven compared to C++.
> 
> One question is how it compares against other languages that foster
> similar bulk processing, such as C# or Scala.
[...]

I haven't programmed in C# and Scala, so I can't really say. I do have a
bias towards compiled languages, though, and so far D is the best of the
lot (that I've tried, anyway).


T

-- 
If the comments and the code disagree, it's likely that *both* are wrong. -- 
Christopher


Re: Regarding hex strings

2012-10-19 Thread Don Clugston

On 19/10/12 16:07, foobar wrote:

On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston wrote:


We can still have both (assuming the code points are valid...):
string foo = "\ua1\ub2\uc3"; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, "assuming the code points are valid". It says so 4 lines above!


It isn't the same.
Hex strings are the raw bytes, eg UTF8 code points. (ie, it includes the 
high bits that indicate the length of each char).

\u makes dchars.

"\u00A1" is not the same as x"A1" nor is it x"00 A1". It's two non-zero 
bytes.


Re: Shared keyword and the GC?

2012-10-19 Thread Michel Fortin

On 2012-10-19 07:42:53 +, Jacob Carlborg  said:


On 2012-10-19 03:06, Michel Fortin wrote:


All this is nice, but what is the owner thread for immutable data?
Because immutable is always implicitly shared, all your strings and
everything else that is immutable is thus "shared" and must be tracked
by the global heap's collector and can never be handled by a
thread-local collector. Even if most immutable data never leaves the
thread it was allocated in, there's no way you can know.

I don't think per-thread GCs will work very well without support for
immutable data, an for that you need to have a distinction between
immutable and shared immutable (just like you have with mutable data). I
complained about this almost three years ago when the semantics of
shared were being defined, but it got nowhere. Quoting Walter at the time:


Would it be any difference if the immutable data was collected from a 
different collector than the shared or thread local?


In this case I guess the collector wouldn't try to make a difference 
between shared and non-shared immutable data.


A thread-local GC would be efficient because it scans only one thread. 
The gain is that you minimize the load on the global GC, reducing 
collection cycles that need to stop all threads. Creating a second 
global GC for immutable data wouldn't free you from the need to stop 
all threads, but now you'd have two global collectors stopping all 
threads which would probably be worse. So I don't see the point in a 
second GC for immutable data.


Immutable data must always be handled by a global GC. There's no way 
around it as long as immutable and shared-immutable are the same thing. 
The more immutable data you have, the more irrelevant the performance 
gains from a thread-local GC becomes, because it get used less often. 
This creates a strange incentive to *not* make things immutable in 
order make things faster.


I'm all for a thread-local GC, but in the current state of the type 
system it'd just be ridiculous. But then, perhaps an implementation of 
it could convince Walter to change some things. So if someone is 
inclined to implement it, go ahead, I'm not here to stop you.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca/



Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston wrote:


We can still have both (assuming the code points are valid...):
string foo = "\ua1\ub2\uc3"; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, "assuming the code points are valid". It says so 4 lines 
above!


Re: Regarding hex strings

2012-10-19 Thread Don Clugston

On 18/10/12 17:43, foobar wrote:

On Thursday, 18 October 2012 at 14:29:57 UTC, Don Clugston wrote:

On 18/10/12 10:58, foobar wrote:

On Thursday, 18 October 2012 at 02:47:42 UTC, H. S. Teoh wrote:

On Thu, Oct 18, 2012 at 02:45:10AM +0200, bearophile wrote:
[...]

hex strings are useful, but I think they were invented in D1 when
strings were convertible to char[]. But today they are an array of
immutable UFT-8, so I think this default type is not so useful:

void main() {
   string data1 = x"A1 B2 C3 D4"; // OK
   immutable(ubyte)[] data2 = x"A1 B2 C3 D4"; // error
}


test.d(3): Error: cannot implicitly convert expression
("\xa1\xb2\xc3\xd4") of type string to ubyte[]

[...]

Yeah I think hex strings would be better as ubyte[] by default.

More generally, though, I think *both* of the above lines should be
equally accepted.  If you write x"A1 B2 C3" in the context of
initializing a string, then the compiler should infer the type of the
literal as string, and if the same literal occurs in the context of,
say, passing a ubyte[], then its type should be inferred as ubyte[],
NOT
string.


T


IMO, this is a redundant feature that complicates the language for no
benefit and should be deprecated.
strings already have an escape sequence for specifying code-points "\u"
and for ubyte arrays you can simply use:
immutable(ubyte)[] data2 = [0xA1 0xB2 0xC3 0xD4];

So basically this feature gains us nothing.


That is not the same. Array literals are not the same as string
literals, they have an implicit .dup.
See my recent thread on this issue (which unfortunately seems have to
died without a resolution, people got hung up about trailing null
characters without apparently noticing the more important issue of the
dup).


I don't see how that detail is relevant to this discussion as I was not
arguing against string literals or array literals in general.

We can still have both (assuming the code points are valid...):
string foo = "\ua1\ub2\uc3"; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 00:14:18 UTC, Nick Sabalausky wrote:

On Thu, 18 Oct 2012 12:11:13 +0200
"foobar"  wrote:


How often large binary blobs are literally spelled in the 
source code (as opposed to just being read from a file)?



Frequency isn't the issue. The issues are "*Is* it ever 
needed?" and
"When it is needed, is it useful enough?" The answer to both is 
most

certainly "yes". (Remember, D is supposed to usable as a systems
language, it's not merely a high-level-app-only language.)


Any real-world use cases to support this claim? Does C++ have 
such a feature?
My limited experience with kernels is that this feature is not 
needed. The solution we used for this was to define an extern 
symbol and load it with a linker script (the binary data was of 
course stored in separate files).




Keep in mind, the question "Does it pull it's own weight?" is 
for

adding new features, not for going around gutting the language
just because we can.


Ok, I grant you that but remember that the whole thread started 
because the feature _doesn't_ work so lets rephrase - is it worth 
the effort to fix this feature?




In any case, I'm not opposed to such a utility library, in 
fact I think it's a rather good idea and we already have a 
precedent with "oct!"
I just don't think this belongs as a built-in feature in the 
language.


I think monarch_dodra's test proves that it definitely needs to 
be

built-in.


It proves that DMD has bugs that should be fixed, nothing more.


Re: Const ref and rvalues again...

2012-10-19 Thread Timon Gehr

On 10/19/2012 09:53 AM, Jacob Carlborg wrote:

On 2012-10-19 04:48, Timon Gehr wrote:


Then how to specify that the value of x cannot be escaped?
I'm in favour of doing it the other way round and disallow escaping of
ref parameters without an unsafe cast.


"scope" is supposed to be used to prevent this.



Sure, but how?

void goo(scope int* x){
global0 = x; // should clearly be disallowed
}

void foo(scope ref int*** x){
global1 = &x; // ?
global2 = x;  // ?
global3 = *x; // ?
globall4 = **x; // ?
}

Maybe we need this:

void foo(scope ref int*** x);   // ?
void foo(ref int(***)scope  x); // no escaping of x, *x, **x
void foo(ref int*(**)scope x);  // may escape **x
void foo(ref int**(*)scope x);  // may escape *x, **x

What about &x?


Re: Shared keyword and the GC?

2012-10-19 Thread sclytrack


Thread-local GC is all about improving scalability by only 
stopping threads that need to be stopped. If you can't even do 
that, then any effort towards thread-local GC is quite 
pointless IMO.


Maybe the goal is to run the thread local garbage collectors very 
frequently and the stop-the-world one's just occasionally. Once 
your thread has shared in it must participate in the 
stop-the-world ones. Maybe the threads needs to register to both 
the thread local garbage collector and the global stop-the-world 
garbage collector.




Re: Shared keyword and the GC?

2012-10-19 Thread sclytrack

On Friday, 19 October 2012 at 09:07:55 UTC, sclytrack wrote:


How does it deal with the problem where a pointer in TLS 
points to global data,


Need to run stop-the-world for shared heap. But it would be 
interesting to have blocks that have no shared pointers in them.




or worse yet, a pointer in the global heap points to TLS?



Could you give an example?




import std.stdio;

class Local
{
}

class Global
{
Local data;
int [] arr;
}

Local l2;
int [] arr; //tls

int main()
{
shared Global g = new shared(Global);   //global heap
Local l1 = new Local(); //future local heap
//  g.data = l1;//disallowed
l2 = new Local();
//  g.data = l2;//disallowed
arr = new int[10];  //future local heap
g.arr = cast(shared(int[])) arr; //bypassed.
writeln("Complete");
return 0;
}


Re: Shared keyword and the GC?

2012-10-19 Thread Alex Rønne Petersen

On 19-10-2012 11:07, sclytrack wrote:



How does it deal with the problem where a pointer in TLS points to
global data,


Need to run stop-the-world for shared heap. But it would be interesting
to have blocks that have no shared pointers in them.


The problem with D is that we have a (more or less) stable language that 
we can't make major changes to at this point.






or worse yet, a pointer in the global heap points to TLS?



Could you give an example?


I don't know Objective-C, so in D:

void* p; // in TLS

void main()
{
p = GC.malloc(1024); // a pointer to the global heap is now in TLS
}

Or the more complicated case (for any arbitrary graph of objects):

Object p; // in TLS

class C
{
Object o;

this(Object o)
{
this.o = o;
}
}

void main()
{
p = new C(new Object); // the graph can be arbitrarily complex and 
any part of it can be allocated with the GC, malloc, or any other mechanism

}




I'm pretty sure it can't without doing a full pass over the entire
heap, which seems to me like it defeats the purpose.


Yeah.


Thread-local GC is all about improving scalability by only stopping 
threads that need to be stopped. If you can't even do that, then any 
effort towards thread-local GC is quite pointless IMO.






But I may just be missing out on some restriction (type system or
whatever) Objective-C has that makes it feasible.






--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: Shared keyword and the GC?

2012-10-19 Thread sclytrack


How does it deal with the problem where a pointer in TLS points 
to global data,


Need to run stop-the-world for shared heap. But it would be 
interesting to have blocks that have no shared pointers in them.




or worse yet, a pointer in the global heap points to TLS?



Could you give an example?

I'm pretty sure it can't without doing a full pass over the 
entire heap, which seems to me like it defeats the purpose.


Yeah.



But I may just be missing out on some restriction (type system 
or whatever) Objective-C has that makes it feasible.





Re: Const ref and rvalues again...

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 07:53:30 UTC, Jacob Carlborg wrote:

On 2012-10-19 04:48, Timon Gehr wrote:


Then how to specify that the value of x cannot be escaped?
I'm in favour of doing it the other way round and disallow 
escaping of

ref parameters without an unsafe cast.


"scope" is supposed to be used to prevent this.


I like Timon's idea. "scope" is a bad fit in that the default 
should be the safe option. Unfortunately this does have the 
potential to brake lots of code, perhaps even if we limit it to 
@safe code.
An argument could be made that it's worth the breakage for @safe 
code to insure better safety.




Re: Shared keyword and the GC?

2012-10-19 Thread Jacob Carlborg

On 2012-10-19 08:48, Alex Rønne Petersen wrote:


How does it deal with the problem where a pointer in TLS points to
global data, or worse yet, a pointer in the global heap points to TLS?

I'm pretty sure it can't without doing a full pass over the entire heap,
which seems to me like it defeats the purpose.

But I may just be missing out on some restriction (type system or
whatever) Objective-C has that makes it feasible.


I'm not sure how this is handled. But the GC is only used for the 
Objective-C allocations, i.e. [NSObject alloc] and not for C 
allocations, i.e. "malloc".


--
/Jacob Carlborg


Re: Import improvement

2012-10-19 Thread Jacob Carlborg

On 2012-10-19 09:22, Marco Leise wrote:


Just an observation...

import fuji: filesystem, render, matrix, material, primitive, system, font;
import std: xml, string, conv, random, algorithm;

...is very easy on the eyes. It gives you that natural "in
package std, there are the modules xml, string, ..."
representation without repeatedly stating "fuji." or "std.".


I think both of these could be useful.

--
/Jacob Carlborg


Re: 48 hour game jam

2012-10-19 Thread Manu
On 19 October 2012 01:12, F i L  wrote:

> Trying to build in Linux, but having problems.
>
> I follow the steps from github wiki "How to build under Windows", except I
> run 'Fuji/create_project.sh' instead of '.bat'... now I'm a bit confused as
> to what steps to take. Running 'Fuji/make' has errors, and running
> 'Stache/make_project.sh' -> 'make' gives me:
>
> make[1]: *** No targets.  Stop.
> make: *** [Stache] Error 2
>
> which I assume is because Fuji isn't built (?). Help please!
>
> Nice screenshot, btw :)
>

I added Linux build instructions to the wiki, includes the Fuji build
instructions. There are a few differences from Windows.
The main problem is a bug in premake4 for D, it seems to throw an error
generating makefiles for my project (D support is new and experimental).
I plan to look into the premake bug this weekend. You can generate a
monodevelop project through, which works fine with the Mono-D plugin
installed. That's how I'm building/running/debugging on Linux at the moment.


Re: Const ref and rvalues again...

2012-10-19 Thread Jacob Carlborg

On 2012-10-19 04:48, Timon Gehr wrote:


Then how to specify that the value of x cannot be escaped?
I'm in favour of doing it the other way round and disallow escaping of
ref parameters without an unsafe cast.


"scope" is supposed to be used to prevent this.

--
/Jacob Carlborg


Re: Shared keyword and the GC?

2012-10-19 Thread Jacob Carlborg

On 2012-10-19 03:06, Michel Fortin wrote:


All this is nice, but what is the owner thread for immutable data?
Because immutable is always implicitly shared, all your strings and
everything else that is immutable is thus "shared" and must be tracked
by the global heap's collector and can never be handled by a
thread-local collector. Even if most immutable data never leaves the
thread it was allocated in, there's no way you can know.

I don't think per-thread GCs will work very well without support for
immutable data, an for that you need to have a distinction between
immutable and shared immutable (just like you have with mutable data). I
complained about this almost three years ago when the semantics of
shared were being defined, but it got nowhere. Quoting Walter at the time:


Would it be any difference if the immutable data was collected from a 
different collector than the shared or thread local?


In this case I guess the collector wouldn't try to make a difference 
between shared and non-shared immutable data.


--
/Jacob Carlborg


Re: Shared keyword and the GC?

2012-10-19 Thread Jacob Carlborg

On 2012-10-18 22:29, Sean Kelly wrote:


It's different in that a variable's address never actually changes.  When a 
thread completes it hands all of its pools to the shared allocator, and then 
per-thread allocators request free pools from the shared allocator before going 
to the OS.  This is basically how the HOARD allocator works.


Ah, now I see.

--
/Jacob Carlborg


Re: Import improvement

2012-10-19 Thread Marco Leise
Am Wed, 17 Oct 2012 08:36:11 +0200
schrieb Jacob Carlborg :

> On 2012-10-16 20:39, Sönke Ludwig wrote:
> 
> > Ah OK, sorry. There is no direct way of course. But assuming that it
> > semantically makes sense to import a package and because it's necessary
> > to look at some kind of documentation before importing anything anyway,
> > I guess that could be a tolerable shortcoming.
> 
> Yeah, I would still prefer "import foo.bar.*" though.

Just an observation...

import fuji: filesystem, render, matrix, material, primitive, system, font;
import std: xml, string, conv, random, algorithm;

...is very easy on the eyes. It gives you that natural "in
package std, there are the modules xml, string, ..."
representation without repeatedly stating "fuji." or "std.".

-- 
Marco



Re: D seems interesting, but...

2012-10-19 Thread Marco Leise
Am Tue, 16 Oct 2012 09:32:25 +0200
schrieb Jacob Carlborg :

> On 2012-10-16 09:04, 1100110 wrote:
> 
> > OK. Install dvm using directions on bitbucket.
> >
> > dvm install -l
> > (no output)
> > dvm list
> > No installed D compilers
> >
> > Thats it.  No errors, I'll make a issue in a bit.
> 
> The -l flag seems to be horrible broken. Can you try "dvm install 2.060".

Ok now that everyone is bashing I can jump in, too. I tried a
few commands and they all failed with bugs already listed in
the bug tracker. no kidding. :D

--- "dvm list": An unknown error occurred:
tango.core.Exception.VfsException: FileFolder.open :: path does not exist: 
/home/marco/.dvm/compilers

--- "dvm -l install":
zsh: segmentation fault  ./dvm-0.4.0-linux-64 -l install

--- "dvm install dmd-2.060":
Fetching: http://ftp.digitalmars.com/dmd.dmd-2.060.zip
An unknown error occurred:
tango.core.Exception.IOException: The resource with URL 
"http://ftp.digitalmars.com/dmd.dmd-2.060.zip"; could not be found.

--- "dvm install 2.060":
Fetching: http://ftp.digitalmars.com/dmd.2.060.zip
[>] 26846/26191 KB

Installing: dmd-2.060
An unknown error occurred:
tango.core.Exception.IOException: /home/marco/.dvm/bin/dmd-2.060 :: No such 
file or directory

At this point I stopped, because I was too scared.

-- 
Marco



Re: Shared keyword and the GC?

2012-10-19 Thread Alex Rønne Petersen

On 18-10-2012 20:26, Sean Kelly wrote:

On Oct 17, 2012, at 1:55 AM, Alex Rønne Petersen  wrote:


So, let's look at D:

1. We have global variables.
1. Only std.concurrency enforces isolation at a type system level; it's not 
built into the language, so the GC cannot make assumptions.
1. The shared qualifier effectively allows pointers from one thread's heap into 
another's.


Well, the problem is more that a variable can be cast to shared after 
instantiation, so to allow thread-local collections we'd have to make 
cast(shared) set a flag on the memory block to indicate that it's shared, and 
vice-versa for unshared.  Then when a thread terminates, all blocks not flagged 
as shared would be finalized, leaving the shared blocks alone.  Then any pool 
from the terminated thread containing a shared block would have to be merged 
into the global heap instead of released to the OS.

I think we need to head in this direction anyway, because we need to make sure 
that thread-local data is finalized by its owner thread.  A blocks owner would 
be whoever allocated the block or if cast to shared and back to unshared, 
whichever thread most recently cast the block back to unshared.  Tracking the 
owner of a block gives us the shared state implicitly, making thread-local 
collections possible.  Who wants to work on this? :-)



I'm not really sure how this solves the problem of having pointers from 
a thread-local heap into the global heap and vice versa. Can you 
elaborate on that?


The problem is that even if you know whether a piece of memory is 
flagged shared, you cannot know if some arbitrary number of threads 
happen to have pointers to it and can thus mutate anything inside it 
while a thread-local collection is in progress.


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org