digitalmars.D - I have made a discovery
- w0rp (32/32) Apr 18 2015 The following code almost compiles.
- w0rp (5/5) Apr 18 2015 I *think* my PR might have also led me to discovering some kind
- w0rp (2/7) Apr 18 2015 Disregard that, I needed to change the .di file too...
- Rikki Cattermole (2/32) Apr 18 2015 Awesome! Although we may need to "undeprecate" that feature.
- ketmar (5/6) Apr 18 2015 as it is not generating deprecation warning now, it should be fairly=20
- weaselcat (5/14) Apr 18 2015 maybe I'm dumb in asking this, but if there was already an API
- ketmar (10/13) Apr 18 2015 ability to override `new` and `delete` is a big can of worms. c++ got=20
- weaselcat (4/25) Apr 18 2015 I was unaware of how the override new worked, after reading the
- Andrei Alexandrescu (2/14) Apr 18 2015 Nah, it's not. -- Andrei
- Brian Schott (4/13) Apr 18 2015 If you overload a class's `new`, you are deciding for your
- Adam D. Ruppe (14/16) Apr 18 2015 Without telling them btw. (Well, except the documentation or the
- Rikki Cattermole (49/63) Apr 18 2015 auto adding(int x, int y) {
- Adam D. Ruppe (11/12) Apr 18 2015 Why would you ever do that? int[3] is statically allocated....
- Rikki Cattermole (3/14) Apr 18 2015 I couldn't fully remember the syntax. So I went with closest I thought
- Adam D. Ruppe (2/3) Apr 19 2015 I don't understand what the point is... is it just syntax?
- Rikki Cattermole (3/6) Apr 19 2015 I was just toying with different syntax's regarding allocation.
- ketmar (2/16) Apr 18 2015 yes, i know all that... but i still want it! ;-)=
- Adam D. Ruppe (6/8) Apr 18 2015 eh i would just call it "New!Exception" where the cool scheme is
- ketmar (3/12) Apr 18 2015 ah, i keep forgetting about D ability to rename imports and detect name=...
- Idan Arye (5/7) Apr 19 2015 Since it's classes we are talking about, wouldn't that mean we
- w0rp (15/15) Apr 19 2015 The interesting thing about this is that 'throw new
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (3/5) Apr 19 2015 What's wrong with just putting exceptions in a dedicated memory
- Jacob Carlborg (4/9) Apr 19 2015 And in Swift they removed then need to call "alloc".
- Martin Nowak (5/9) Apr 21 2015 Though until https://issues.dlang.org/show_bug.cgi?id=14119 is
- ketmar (4/13) Apr 21 2015 the idea is to avoid allocations alltogether. malloc is a sample, one ca...
- Dicebot (4/36) Apr 23 2015 I don't see anything interesting here. Controlling allocation was
The following code almost compiles. -------- import core.stdc.stdlib; class Foo : Exception { nogc pure nothrow safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } nogc new(size_t size) { return malloc(size); } } nogc void main() { throw new Foo("Oh no!"); } -------- That's right. An unofficially deprecated feature of the language and a newer feature of the language coming together in an interesting way. The only thing stopping this code from actually working is a trivial change to druntime to mark the Throwable, Exception, and Error constructors as nogc, which I just created a pull request for directly through GitHub. https://github.com/D-Programming-Language/druntime/pull/1223 Now imagine that instead of just a malloc which leaks memory like the above, other allocation schemes are used here instead. Consider also the coming addition to the language for class reference counting methods opAddRef and opRelease. Then let your imagination run wild. Enjoy!
Apr 18 2015
I *think* my PR might have also led me to discovering some kind of DMD bug to do with not being able to call a nogc super class constructor from a constructor which isn't nogc. It could be something else entirely, but it caused some undefined reference bugs to appear, which is odd.
Apr 18 2015
On Saturday, 18 April 2015 at 15:39:05 UTC, w0rp wrote:I *think* my PR might have also led me to discovering some kind of DMD bug to do with not being able to call a nogc super class constructor from a constructor which isn't nogc. It could be something else entirely, but it caused some undefined reference bugs to appear, which is odd.Disregard that, I needed to change the .di file too...
Apr 18 2015
On 19/04/2015 3:24 a.m., w0rp wrote:The following code almost compiles. -------- import core.stdc.stdlib; class Foo : Exception { nogc pure nothrow safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } nogc new(size_t size) { return malloc(size); } } nogc void main() { throw new Foo("Oh no!"); } -------- That's right. An unofficially deprecated feature of the language and a newer feature of the language coming together in an interesting way. The only thing stopping this code from actually working is a trivial change to druntime to mark the Throwable, Exception, and Error constructors as nogc, which I just created a pull request for directly through GitHub. https://github.com/D-Programming-Language/druntime/pull/1223 Now imagine that instead of just a malloc which leaks memory like the above, other allocation schemes are used here instead. Consider also the coming addition to the language for class reference counting methods opAddRef and opRelease. Then let your imagination run wild. Enjoy!Awesome! Although we may need to "undeprecate" that feature.
Apr 18 2015
On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:Awesome! Although we may need to "undeprecate" that feature.as it is not generating deprecation warning now, it should be fairly=20 easy: just reintroduce it into specs. i can see why it was deprecated in=20 the first place, but it's much easier to simply write "new Exception"=20 instead of "allocateWithMyCoolScheme!Exception".=
Apr 18 2015
On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:maybe I'm dumb in asking this, but if there was already an API for allocators in D... why is a std.allocator not being written ontop of it? it seems much more elegant to begin with.Awesome! Although we may need to "undeprecate" that feature.as it is not generating deprecation warning now, it should be fairly easy: just reintroduce it into specs. i can see why it was deprecated in the first place, but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".
Apr 18 2015
On Sun, 19 Apr 2015 00:50:23 +0000, weaselcat wrote:maybe I'm dumb in asking this, but if there was already an API for allocators in D... why is a std.allocator not being written ontop of it? it seems much more elegant to begin with.ability to override `new` and `delete` is a big can of worms. c++ got=20 into that, and now it's not recommended to touch that operators. in a short: it's inflexible (you can't use two different `new` with one=20 class, for example -- if not count the weirdo `new(5) A()` and such), you=20 can't predict how your class will be allocated (yea, you didn't define=20 `new` for your class... but one of it's parents did and... bam!) and so=20 on. so i fully understand why it's silently deprecated. yet i still don't=20 want it to go. ;-)=
Apr 18 2015
On Sunday, 19 April 2015 at 02:42:28 UTC, ketmar wrote:On Sun, 19 Apr 2015 00:50:23 +0000, weaselcat wrote:I was unaware of how the override new worked, after reading the thread again it makes more sense why it's not used now. Thanks.maybe I'm dumb in asking this, but if there was already an API for allocators in D... why is a std.allocator not being written ontop of it? it seems much more elegant to begin with.ability to override `new` and `delete` is a big can of worms. c++ got into that, and now it's not recommended to touch that operators. in a short: it's inflexible (you can't use two different `new` with one class, for example -- if not count the weirdo `new(5) A()` and such), you can't predict how your class will be allocated (yea, you didn't define `new` for your class... but one of it's parents did and... bam!) and so on. so i fully understand why it's silently deprecated. yet i still don't want it to go. ;-)
Apr 18 2015
On 4/18/15 5:50 PM, weaselcat wrote:On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:Nah, it's not. -- AndreiOn Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:maybe I'm dumb in asking this, but if there was already an API for allocators in D... why is a std.allocator not being written ontop of it? it seems much more elegant to begin with.Awesome! Although we may need to "undeprecate" that feature.as it is not generating deprecation warning now, it should be fairly easy: just reintroduce it into specs. i can see why it was deprecated in the first place, but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".
Apr 18 2015
On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:If you overload a class's `new`, you are deciding for your class's user how it will be allocated. I think it's better to let the programmer decide how they want the class to be allocated.Awesome! Although we may need to "undeprecate" that feature.as it is not generating deprecation warning now, it should be fairly easy: just reintroduce it into specs. i can see why it was deprecated in the first place, but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".
Apr 18 2015
On Sunday, 19 April 2015 at 01:19:47 UTC, Brian Schott wrote:If you overload a class's `new`, you are deciding for your class's user how it will be allocated.Without telling them btw. (Well, except the documentation or the source.) So now, they new it and expect the GC to clean it up like any other class.... but that invisibly doesn't happen. Overriding new was totally a misfeature in D and it should go away. BTW having new in the language at all I wish wasn't a thing. Perhaps it was right back in old D1, but not ideal in D2, where we can easily define a template to do it - which could be easily swapped out at the usage point and enable all kinds of nice things. Of course, we can still define library New!T (and indeed, I think we should), but the keyword will always have a bit of a brainspace edge over it...
Apr 18 2015
On 19/04/2015 1:52 p.m., Adam D. Ruppe wrote:On Sunday, 19 April 2015 at 01:19:47 UTC, Brian Schott wrote:auto adding(int x, int y) { int[3] values = allocate!(int[3]); values[0] = x; values[1] = y; values[2] = x + y; return values; } ... auto adding(int x, int y) { int[3] values = new!(int[3]); values[0] = x; values[1] = y; values[2] = x + y; return values; } ... auto adding(int x, int y) { int[3] values = new int[](3); values[0] = x; values[1] = y; values[2] = x + y; return values; } ... struct MyAllocator { T* opAllocate(T)(){ T* value; // alloc value.rtInfo.fromGC = false; value.rtInfo.isRefCounted = false; value.rtInfo.isGCFree = true; // allows GC to free it value.rtInfo.freeFunction = &opFree; // maybe? return value; } void opFree(T)(T*){ // free } } new(MyAllocator): auto adding(int x, int y) { int[3] values = new int[](3); values[0] = x; values[1] = y; values[2] = x + y; return values; } ... I'm not totally sold.If you overload a class's `new`, you are deciding for your class's user how it will be allocated.Without telling them btw. (Well, except the documentation or the source.) So now, they new it and expect the GC to clean it up like any other class.... but that invisibly doesn't happen. Overriding new was totally a misfeature in D and it should go away. BTW having new in the language at all I wish wasn't a thing. Perhaps it was right back in old D1, but not ideal in D2, where we can easily define a template to do it - which could be easily swapped out at the usage point and enable all kinds of nice things. Of course, we can still define library New!T (and indeed, I think we should), but the keyword will always have a bit of a brainspace edge over it...
Apr 18 2015
On Sunday, 19 April 2015 at 02:24:06 UTC, Rikki Cattermole wrote:int[3] values = allocate!(int[3]);Why would you ever do that? int[3] is statically allocated.... auto values = allocate!(int[])(3); would make a lot more sense, then values would be typed perhaps to int[], but also it might be typed to something like RefCounted!(int[]) or Unique!(int[]) or something, so the requirement to deallocate is encoded right there in the type and thus known to the compiler. But even `int[] values = new!(int[])(3);` is very similar to the built-in syntax and can do exactly the same thing - while also being changeable to a new scheme by importing a different module.
Apr 18 2015
On 19/04/2015 2:45 p.m., Adam D. Ruppe wrote:On Sunday, 19 April 2015 at 02:24:06 UTC, Rikki Cattermole wrote:I couldn't fully remember the syntax. So I went with closest I thought it was to make the point.int[3] values = allocate!(int[3]);Why would you ever do that? int[3] is statically allocated.... auto values = allocate!(int[])(3); would make a lot more sense, then values would be typed perhaps to int[], but also it might be typed to something like RefCounted!(int[]) or Unique!(int[]) or something, so the requirement to deallocate is encoded right there in the type and thus known to the compiler. But even `int[] values = new!(int[])(3);` is very similar to the built-in syntax and can do exactly the same thing - while also being changeable to a new scheme by importing a different module.
Apr 18 2015
On Sunday, 19 April 2015 at 02:50:59 UTC, Rikki Cattermole wrote:So I went with closest I thought it was to make the point.I don't understand what the point is... is it just syntax?
Apr 19 2015
On 19/04/2015 11:48 p.m., Adam D. Ruppe wrote:On Sunday, 19 April 2015 at 02:50:59 UTC, Rikki Cattermole wrote:I was just toying with different syntax's regarding allocation. Atleast to me, none of them really fit.So I went with closest I thought it was to make the point.I don't understand what the point is... is it just syntax?
Apr 19 2015
On Sun, 19 Apr 2015 01:19:46 +0000, Brian Schott wrote:On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:yes, i know all that... but i still want it! ;-)=On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:=20 If you overload a class's `new`, you are deciding for your class's user how it will be allocated. I think it's better to let the programmer decide how they want the class to be allocated.Awesome! Although we may need to "undeprecate" that feature.as it is not generating deprecation warning now, it should be fairly easy: just reintroduce it into specs. i can see why it was deprecated in the first place, but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".
Apr 18 2015
On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".eh i would just call it "New!Exception" where the cool scheme is in the module name. So you "import mycoolscheme;" which defines the New. Then you can disambiguate with the usual module features if you use two schemes in the same scope. It'd be so beautiful.
Apr 18 2015
On Sun, 19 Apr 2015 01:53:41 +0000, Adam D. Ruppe wrote:On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:ah, i keep forgetting about D ability to rename imports and detect name=20 conflicts. too much delphi in my youth. ;-)=but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".=20 eh i would just call it "New!Exception" where the cool scheme is in the module name. So you "import mycoolscheme;" which defines the New. =20 Then you can disambiguate with the usual module features if you use two schemes in the same scope. It'd be so beautiful.
Apr 18 2015
On Saturday, 18 April 2015 at 15:24:27 UTC, w0rp wrote:Consider also the coming addition to the language for class reference counting methods opAddRef and opRelease.Since it's classes we are talking about, wouldn't that mean we need to do a virtual function call each time a class reference gets assigned or goes out of scope(and twice when it gets reassigned)?
Apr 19 2015
The interesting thing about this is that 'throw new ExceptionType(...)' could be reference counted. The downside of not getting rid of the 'new' overloading at some point is that it can make the operator do surprising and unexpected things, so the rationale for getting rid of it is similar to the rationale behind disallowing overloading of '&&' and '||'. What I found more interesting is that class constructors themselves can be marked nogc, which I never thought to do before. So whatever syntax we end up with for 'allocate with this other allocator and call this constructor' could take advantage of that. I'm not sure how that will end up looking in the end, but I am reminded of Objective C again, where allocation and construction are explicitly separated. // Enough time in Wonderland makes this seem perfectly natural. MyClass* foo = [[MyClass alloc] initWithNumber:3];
Apr 19 2015
On Sunday, 19 April 2015 at 09:57:52 UTC, w0rp wrote:The interesting thing about this is that 'throw new ExceptionType(...)' could be reference counted. The downside ofWhat's wrong with just putting exceptions in a dedicated memory area like C++?
Apr 19 2015
On 2015-04-19 11:57, w0rp wrote:I'm not sure how that will end up looking in the end, but I am reminded of Objective C again, where allocation and construction are explicitly separated. // Enough time in Wonderland makes this seem perfectly natural. MyClass* foo = [[MyClass alloc] initWithNumber:3];And in Swift they removed then need to call "alloc". -- /Jacob Carlborg
Apr 19 2015
On Saturday, 18 April 2015 at 15:24:27 UTC, w0rp wrote:nogc void main() { throw new Foo("Oh no!"); }Though until https://issues.dlang.org/show_bug.cgi?id=14119 is resolved the tracehandler GC allocates anyhow. Why are malloc exceptions better then gc exceptions? Are you throwing so many of them that the GC becomes a bottleneck :)?
Apr 21 2015
On Tue, 21 Apr 2015 22:53:15 +0000, Martin Nowak wrote:On Saturday, 18 April 2015 at 15:24:27 UTC, w0rp wrote:the idea is to avoid allocations alltogether. malloc is a sample, one can=20 use statically allocated pool instead, for example. this way functions=20 can throw, yet still be nogc.=nogc void main() { throw new Foo("Oh no!"); }=20 Though until https://issues.dlang.org/show_bug.cgi?id=3D14119 is resolved the tracehandler GC allocates anyhow. Why are malloc exceptions better then gc exceptions? Are you throwing so many of them that the GC becomes a bottleneck :)?
Apr 21 2015
On Saturday, 18 April 2015 at 15:24:27 UTC, w0rp wrote:The following code almost compiles. -------- import core.stdc.stdlib; class Foo : Exception { nogc pure nothrow safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } nogc new(size_t size) { return malloc(size); } } nogc void main() { throw new Foo("Oh no!"); } -------- That's right. An unofficially deprecated feature of the language and a newer feature of the language coming together in an interesting way. The only thing stopping this code from actually working is a trivial change to druntime to mark the Throwable, Exception, and Error constructors as nogc, which I just created a pull request for directly through GitHub. https://github.com/D-Programming-Language/druntime/pull/1223 Now imagine that instead of just a malloc which leaks memory like the above, other allocation schemes are used here instead. Consider also the coming addition to the language for class reference counting methods opAddRef and opRelease. Then let your imagination run wild. Enjoy!I don't see anything interesting here. Controlling allocation was never the issue (MyException.create ftw). It is deallocation that matters.
Apr 23 2015