Re: Array of structs construction
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?
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
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
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
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
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?
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?
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?
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?
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?
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...
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
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
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
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
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
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?
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
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
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
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...
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?
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?
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?
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?
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...
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?
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
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
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...
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?
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?
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
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...
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?
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