Re: is opOpAssign returning a value less than ideal ?
On Thursday, 8 November 2018 at 06:01:57 UTC, Jonathan M Davis wrote: On Wednesday, November 7, 2018 10:45:07 PM MST Jonathan M Davis via Digitalmars-d-learn wrote: [...] Rereading what you wrote, are you asking whether it's reasonable to return a value instead of a reference? Personally, I don't think that that's good design at all, but I also don't see any reason for the compiler to prevent it. Personally, I think that the default design should be to return by ref. Returning void is less than ideal but isn't necessarily bad, depending on the situation (especially if we're not talking about a general purpose library). However, I expect that returning non-void by value rather than by ref is rarely -if ever - going to be a good design choice. It's just going to be confusing and not particularly useful. - Jonathan M Davis NB its not returning a ref to the list, its returning the newly created node when you use the operator you add a type to the list, so it possibly wouldn't be that much use for chaining?
Re: Is this a bug? +goto
On Thursday, 8 November 2018 at 06:56:14 UTC, Jonathan M Davis wrote: On Wednesday, November 7, 2018 10:50:29 PM MST Michelle Long via Digitalmars-d-learn wrote: On Thursday, 8 November 2018 at 02:22:42 UTC, Jonathan M Davis wrote: > On Wednesday, November 7, 2018 1:03:47 PM MST Michelle Long > via > > Digitalmars- d-learn wrote: >> Don't let their psychobabble fool you. They are wrong and >> you were right from the start. > > ... > >> Case A: >> { >> >> if (true) goto X; >> int x; >> >> } >> X: >> >> >> Case B: >> { >> >> if (true) goto X; >> { >> >>int x; >> >> } >> >> } >> X: >> >> >> These two cases are EXACTLY the same semantically. It's like >> writing A + B and (A + B). > > That's not the situation that the OP was describing. If > adding braces in a situation where the braces have no > semantic effect has any impact on goto, then it's a compiler > bug. It's adding a new scope that affects the lifetime of a > variable whose declaration is being jumped over by a goto > that matters. > > I know that you're frustrated, because you've hit a problem > with goto in complex code, and you don't have a simple > example that shows the compiler bug, but the approach that D > takes with goto (and any construct that potentially requires > code flow analysis) of avoiding requiring that the compiler > be smart is precisely to reduce the risk of there being > cases where the compiler is going to screw it up in complex > code even though it gets it right in the simple cases. If > the language required the compiler to be smart about such > things, we'd have a lot more problems with subtle, hard to > track down compiler bugs in complex code. So, we'd just have > _more_ cases where people would be hitting frustrating bugs > like you are. That's fine. The D compiler writers can decide to do whatever they want. I can simply take my "business" elsewhere if I don't like it. What I am talking about is about an obvious error(Ok, I haven't produced a simplified test case but dustmite or visual D is not working for me to do so at this point in time, but it would be nice for sake of argument to assume I'm right...). > Regardless, if you want to actually have your problem fixed, > you're going to need to provide a reproducible test case in > a bugzilla report, even if it's large, otherwise no one is > going to be able to track it down for you. That's easier said than done. I wasn't expecting anyone to be able to fix a bug that can't be reproduced. What I expect is that, given my assumptions that I'm right, that people can agree the compiler does have a bug or flaw that can easily be fixed give then two simplified test cases basic purely what I have done in my own code. 1. foreach(...) { if (x) goto Y: int z; } Y: Fails. foreach(...) { if (x) goto Y: { int z; } } Y: Passes. THAT IS FACT! It doesn't matter if the examples work above. I have simplified what I have done and in my code I simply add brackets and it works! That is what people should be thinking about... not test cases, MWE's, compiler versions, etc. Is it logical that the compiler **should** error out in the first case and no in the second? That is what the discussion is ALL about. Once that is dealt with then we can move on to finding out more specifics. There is no reason to build the windows of a house before the foundation, it's just far more work without any benefit. Once people can say: If that is all you are doing is adding brackets around what follows the goto and break out of scope(which is what the code above says) and you can compile, then it is a compiler bug or flaw. Once people verify that, rather than trying to create rabbit holes, then I can do more work on finding out more specifics. Until then, it is pointless to do anything on my side because if people come back and say "No, it is suppose to work that way" then what the hell am I trying to simplify and fix? It's not a bug then. If you have code where you get a compiler error about a goto skipping the initializiation of a variable, and you add braces that should have no semantic effect on the code whatsoever, and the error goes away, then yes, that's a compiler bug. If, however, the braces do affect the semantics of the code, then that's not necessarily a compiler bug. At that point, whether it's a compiler bug or not would depend on what exactly the code was. In an example such as while(1) { if(cond) goto label; int x; } label: adding braces such as while(1) { if(cond) { goto label; } int x; } label: or while(1) { if(cond) goto label; { int x; } } label: should have no effect. However, in an example such as goto label; int x; label: adding braces such as goto label; { int x; } label: changes the code entirely. Obviously, but that is not the case I mentioned. You can assume that I k
Re: is opOpAssign returning a value less than ideal ?
On Thursday, November 8, 2018 2:15:43 AM MST Codifies via Digitalmars-d-learn wrote: > On Thursday, 8 November 2018 at 06:01:57 UTC, Jonathan M Davis > > wrote: > > On Wednesday, November 7, 2018 10:45:07 PM MST Jonathan M Davis > > > > via Digitalmars-d-learn wrote: > >> [...] > > > > Rereading what you wrote, are you asking whether it's > > reasonable to return a value instead of a reference? > > Personally, I don't think that that's good design at all, but I > > also don't see any reason for the compiler to prevent it. > > > > Personally, I think that the default design should be to return > > by ref. Returning void is less than ideal but isn't necessarily > > bad, depending on the situation (especially if we're not > > talking about a general purpose library). However, I expect > > that returning non-void by value rather than by ref is rarely > > -if ever - going to be a good design choice. It's just going to > > be confusing and not particularly useful. > > > > - Jonathan M Davis > > NB its not returning a ref to the list, its returning the newly > created node when you use the operator you add a type to the > list, so it possibly wouldn't be that much use for chaining? The normal thing to do with any of the assignment operators is to return a reference to the object you're assigning to. Doing much of anything else other than returning void (and thus not allowing chaining) would be pretty abnormal. If it's appropriately documented, having an assignment operator return something else could certainly be made to work, but I expect that most programmers would consider it to be a backwards API. - Jonathan M Davis
Re: Is this a bug? +goto
On Thursday, November 8, 2018 2:34:34 AM MST Michelle Long via Digitalmars- d-learn wrote: > Obviously, but that is not the case I mentioned. You can assume > that I know how scopes work. No need to assume everyone that > shows two cases that you have to bring up an unrelated case as a > potential cause unless it is relevant. > > Remember, I'm showing the starting case that has the bug and the > final case that doesn't... it is simply "mental dustmite" on the > code I have. > > You shouldn't assume everyone can't comprehend such trivialities. > > If a person cannot understand scope then I doubt they understand > goto's... and definitely not that adding braces should not change > the compiler behavior. > > What happens when you do that you just create noise that makes it > more difficult to have a proper discussion that gets at the whole > point of the conversation. > > You seem to default to assuming that the person you are talking > to has no clue about the problem at hand. You might not do it > intentionally but it is wrong to assume that because it almost > never helps. If you fully understood the situation, you wouldn't be asking whether your case was a compiler bug or not, and I don't know which parts you do and don't understand. So, I tried to be thorough in explaining the situation. And yes, by being thorough, I'm more likely to cover information that you already know and understand, but I'm also more likely to cover the information that you actually need. In order to avoid repeating anything you already understand and only tell you exactly what you need to know, I would have to somehow understand exactly which piece of the puzzle it is you're missing, and I don't. Honestly, that rarely seems to be easy to do, and for whatever reason, it seems to be even harder to do than normal when discussing this issue with you. It seems like most of the discussion of this issue between you and various folks has been people talking passed each other without really coming to an understanding, which always makes for a frustrating discussion. I'd like to help, but I don't know what else I can say. I've tried to explain how braces interact with goto and why, so you should be able to figure out whether you're dealing with a compiler bug or not. And if you are, unless you're dealing with one that someone else already has found independently and reported with a test case, somehow, you're going to need to reduce it enough to be able to create a bug report with an example if you want it fixed. A small example would be nice, but even a large example would be better than nothing. Either way, ultimately, without a reproducible test case, compiler bugs almost never get fixed. It just isn't practical for the compiler devs to track down bugs based on vague bug reports, even if they'd like to be helpful. - Jonathan M Davis
scoped classes and dependency inversion
I'm trying to invert the dependency from the classes `Bar -> Foo` to `Foo -> IFoo <- Bar` at compile time. I do want `Foo's` to be embedded into `Bar` So silly me tried something like this: module main; ```import std.stdio; import std.typecons; void main() { auto bar = new Bar!(scoped!Foo()); } class Bar (TFoo) if(is(TFoo == IFoo)) { scoped!TFoo _foo; this(scoped!TFoo foo) { _foo = foo; } } class Foo : IFoo { void baz(){} } interface IFoo { void baz(); }``` This fails to compile on line 8 since you can't move a scoped!Foo. So how can I delay the construction of scoped!Foo that it'll end up inside Bar? If there is a more elegant solution I'm also interested.
new returning the same memory....
when creating a new instance of a class aclass a = new aclass(); I was under the impression that this created a new chunk of memory on the heap... however I'm trying to create this class instance in another classes method, I also need to store a pointer to this newly created instance in the same method. when I look at the actual value of the pointer, although it does change after multiple goes, frequently its the same value. It almost looks like its allocating on the local stack and its made a new instance thats entirely local to the factory method. do I need to manually allocate the memory ?? how do I do this? how can I allow the GC to clean this up? I'm *really* discombobulated now, as new doesn't seem to be working how I thought it did!!!
Re: new returning the same memory....
On Thursday, 8 November 2018 at 11:46:44 UTC, Codifies wrote: when creating a new instance of a class aclass a = new aclass(); I was under the impression that this created a new chunk of memory on the heap... however I'm trying to create this class instance in another classes method, I also need to store a pointer to this newly created instance in the same method. when I look at the actual value of the pointer, although it does change after multiple goes, frequently its the same value. It almost looks like its allocating on the local stack and its made a new instance thats entirely local to the factory method. do I need to manually allocate the memory ?? how do I do this? how can I allow the GC to clean this up? I'm *really* discombobulated now, as new doesn't seem to be working how I thought it did!!! I'll try to spin up a minimal example...
Re: new returning the same memory....
08.11.2018 14:48, Codifies пишет: On Thursday, 8 November 2018 at 11:46:44 UTC, Codifies wrote: when creating a new instance of a class aclass a = new aclass(); I was under the impression that this created a new chunk of memory on the heap... however I'm trying to create this class instance in another classes method, I also need to store a pointer to this newly created instance in the same method. when I look at the actual value of the pointer, although it does change after multiple goes, frequently its the same value. It almost looks like its allocating on the local stack and its made a new instance thats entirely local to the factory method. do I need to manually allocate the memory ?? how do I do this? how can I allow the GC to clean this up? I'm *really* discombobulated now, as new doesn't seem to be working how I thought it did!!! I'll try to spin up a minimal example... You take address of local variable, not a class instance. Just use the var, not its address: ``` auto a = new MyClass(); writefln("%s", &a); // here you write to console address of local var a, not the class instance writefln("%s", cast(void*)a); // here you write to console address of the class instance ```
Re: new returning the same memory....
Did you try disable gc? import core.memory : GC; GC.disable; aclass a = new aclass(); I believe that your aclass go out of scope and there is no active reference to this so GC can collected it and reuse its memory On Thu, Nov 8, 2018 at 12:50 PM Codifies via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Thursday, 8 November 2018 at 11:46:44 UTC, Codifies wrote: > > when creating a new instance of a class > > > > aclass a = new aclass(); > > > > I was under the impression that this created a new chunk of > > memory on the heap... > > > > however I'm trying to create this class instance in another > > classes method, I also need to store a pointer to this newly > > created instance in the same method. > > > > when I look at the actual value of the pointer, although it > > does change after multiple goes, frequently its the same value. > > > > It almost looks like its allocating on the local stack and its > > made a new instance thats entirely local to the factory method. > > > > do I need to manually allocate the memory ?? how do I do this? > > how can I allow the GC to clean this up? > > > > I'm *really* discombobulated now, as new doesn't seem to be > > working how I thought it did!!! > > I'll try to spin up a minimal example... >
Re: scoped classes and dependency inversion
On Thursday, 8 November 2018 at 11:04:19 UTC, Sjoerd Nijboer wrote: I'm trying to invert the dependency from the classes `Bar -> Foo` to `Foo -> IFoo <- Bar` at compile time. I do want `Foo's` to be embedded into `Bar` So silly me tried something like this: [...] So how can I delay the construction of scoped!Foo that it'll end up inside Bar? If there is a more elegant solution I'm also interested. Hmm... not sure, if I got your idea... Do you think about something like this? ´´´ import std.stdio; import std.typecons; void main() { auto bar = new Bar!Foo(); } class Bar(TFoo) if(is(TFoo : IFoo)) { typeof(scoped!TFoo()) _foo; this() { _foo = scoped!TFoo(); } } class Foo : IFoo { void baz(){} } interface IFoo{ void baz(); } ´´´
Creating InputRanges from strings, files etc.
Excuse my ignorance, but from looking at the documentation on std.range and a quick skim of the guides mentioned there near the top, I can't see what the simple way is of creating an InputRange!(ubyte) from strings, files etc. I would have expected to find something in the DLang Tour about this, but couldn't find anything. Please can someone tell me how to do it? Just to be clear, I want to create an object which is an InputRange!(ubyte) and pass that around, rather than e.g. iterate over a string or a file.
Re: Creating InputRanges from strings, files etc.
On 09/11/2018 2:58 AM, Vinay Sajip wrote: Excuse my ignorance, but from looking at the documentation on std.range and a quick skim of the guides mentioned there near the top, I can't see what the simple way is of creating an InputRange!(ubyte) from strings, files etc. I would have expected to find something in the DLang Tour about this, but couldn't find anything. Please can someone tell me how to do it? Just to be clear, I want to create an object which is an InputRange!(ubyte) and pass that around, rather than e.g. iterate over a string or a file. TLDR of how to write an input range: struct MyInputRange { ubyte[] input; @property { ubyte front() { return this.input[0]; } bool empty() { return this.input.length == 0; } } void popFront() { this.input = this.input[1 .. $]; } } import std.stdio; void main() { foreach(b; MyInputRange([1, 2, 3])) { writeln(b); } }
Re: Creating InputRanges from strings, files etc.
On Thursday, 8 November 2018 at 13:58:55 UTC, Vinay Sajip wrote: Excuse my ignorance, but from looking at the documentation on std.range and a quick skim of the guides mentioned there near the top, I can't see what the simple way is of creating an InputRange!(ubyte) from strings, files etc. I would have expected to find something in the DLang Tour about this, but couldn't find anything. Please can someone tell me how to do it? Just to be clear, I want to create an object which is an InputRange!(ubyte) and pass that around, rather than e.g. iterate over a string or a file. You can iterate through a file one ubyte at a time using `byChunk` and `joiner`: auto r1 = stdin.byChunk(1024).joiner; assert(is(typeof(r1.front) == ubyte)); You can iterate through a string one ubyte at a time using `representation`: auto r2 = "To be or not to be".representation; assert(is(typeof(r2.front) == immutable(ubyte))); To pass these ranges around using the `InputRange` interface, use `inputRangeObject` to wrap them: InputRange!ubyte r3 = inputRangeObject(r1); InputRange!(immutable(ubyte)) r4 = inputRangeObject(r2);
A `dub test` problem...
WTF, why i got a this modal messagebox when i trying `dub test --build=unittest` ?? i just captured messagebox and using OCR, and that's it. here: core.exceptionAssertError@source\dub\internal\vibecompat\core\log.d(85): Enforcement failed (No error) 0x00594079 in _d_assert_msg Ox0056A55D in nothrow @safe void dub.intemal.vibecompatcore.logiogErrorRimmutable(chae.lo gError(immutable(char)g, lazy immutable(char)g) at CWUsersWvagrantVklonesVidubVisourceVeduhAVinternalWvibeco mpatwcorewlog.d(47) Ox00409C24 in int dub.commandline.runDubCommandLine(immutable(chaOgg) at CWUsersWvagrantVklonesVidubVisourceViduhAikommandline.d( 272) Ox0040256E in _Dmain at CWUsersWvagrantVklonesWdubVisourceWapp.d(15) Ox00592DDF in void rtdmain2._d_run_mainent, char*, extern (C) int function(chargr).runA110._lambdal 0 Ox00592D61 in void rtdmain2._d_run_mainent, char", extern (C) int function(chargg)").runAll0 Ox00592BFB in _d_run_main Ox0040894C in main at CV/UsersWvagrantVklonesVidubVisourceiVapp.d(7) Ox0060D535 in mainCRTStartup 0x77608484 in BaseThreadlnitThunk Ox77E13O5A in RtlValidSecurityDescriptor Ox77E1302A in RtlValidSecurityDescriptor yah, `dub test --build=unittest` didn't work. a dub made a test file for library(eg. libname-test-library.exe), but couldn't executed it. WHY??? But it didnt have no problem, when i tried executing `libname-test-library.exe` directly. WHY??? i have no idea.
Exception slipping through the catch block?
How does exception work? I am inside a function that calls a constructor. Inside the constructor, an exception is thrown. However even though I have wrapped the body of the function inside a try/catch block, the program crashes from inside that constructor. Shouldn't the catch block in the function catch the exception? Picture should clear it up a little bit: https://i.imgur.com/3zinoZq.png // ui.d 103 deviceCombo.addOnChanged(delegate void(ComboBoxText _) { 104 try { 105 device = new Device(deviceCombo.getActiveText()); // <-- call sight 106 auto status = sanityCheck(device, fcb.getFilename); 107 if (status.pass) 108 triggerHboxRevealer.setRevealChild(true); 109 else { 110 deviceCombo.setTooltipText(status.reason); 111 triggerHboxRevealer.setRevealChild(false); 112 } 113 } 114 catch (Exception e) { 115 deviceCombo.setTooltipText("Cannot read device"); 116 triggerHboxRevealer.setRevealChild(false); 117 } 118 }); // backend.d 34 this(in string lsblkLine) { 35 auto lineSplit = lsblkLine.split(" "); 36 name = lineSplit.front(); 37 sizePretty = lineSplit.back(); 38 foreach (str; lineSplit.dropOne().dropBackOne()) // <-- throws exception 39 model ~= str ~ " "; 40 summary = format("%s\t%s\t%s", name, model, sizePretty); 41 } // error message core.exception.AssertError@/usr/include/dlang/dmd/std/range/primitives.d(2340): Assertion failure ??:? _d_assertp [0x4e81ee29] /usr/include/dlang/dmd/std/range/primitives.d:2340 pure nothrow @nogc @safe void std.range.primitives.popBack!(immutable(char)[]).popBack(ref immutable(char)[][]) [0x4e5e417e] /usr/include/dlang/dmd/std/range/package.d:3190 pure nothrow @nogc @safe immutable(char)[][] std.range.dropBackOne!(immutable(char)[][]).dropBackOne(immutable(char)[][]) [0x4e5e41d4] source/backend.d:38 backend.Device backend.Device.__ctor(const(immutable(char)[])) [0x4e5e8e6d] source/ui.d:105 void ui.PrimaryWindow.__ctor(gtk.Application.Application).__dgliteral4(gtk.ComboBoxText.ComboBoxText) [0x4e5ea17f] ../../../../.dub/packages/gtk-d-3.8.3/gtk-d/generated/gtkd/gobject/DClosure.d:135 extern (C) void gobject.DClosure.DClosure.d_closure_marshal!(void delegate(gtk.ComboBoxText.ComboBoxText)).d_closure_marshal(gobject.c.types.GClosure*, gobject.c.types.GValue*, uint, gobject.c.types.GValue*, void*, void*) [0x4e7bf095] ??:? g_closure_invoke [0x4f9573d4] Program exited with code 1
Re: A `dub test` problem...
On Thursday, 8 November 2018 at 15:01:04 UTC, duge wrote: WTF, why i got a this modal messagebox when i trying `dub test --build=unittest` ?? i just captured messagebox and using OCR, and that's it. here: core.exceptionAssertError@source\dub\internal\vibecompat\core\log.d(85): Enforcement failed (No error) 0x00594079 in _d_assert_msg Ox0056A55D in nothrow @safe void dub.intemal.vibecompatcore.logiogErrorRimmutable(chae.lo gError(immutable(char)g, lazy immutable(char)g) at CWUsersWvagrantVklonesVidubVisourceVeduhAVinternalWvibeco mpatwcorewlog.d(47) Ox00409C24 in int dub.commandline.runDubCommandLine(immutable(chaOgg) at CWUsersWvagrantVklonesVidubVisourceViduhAikommandline.d( 272) Ox0040256E in _Dmain at CWUsersWvagrantVklonesWdubVisourceWapp.d(15) Ox00592DDF in void rtdmain2._d_run_mainent, char*, extern (C) int function(chargr).runA110._lambdal 0 Ox00592D61 in void rtdmain2._d_run_mainent, char", extern (C) int function(chargg)").runAll0 Ox00592BFB in _d_run_main Ox0040894C in main at CV/UsersWvagrantVklonesVidubVisourceiVapp.d(7) Ox0060D535 in mainCRTStartup 0x77608484 in BaseThreadlnitThunk Ox77E13O5A in RtlValidSecurityDescriptor Ox77E1302A in RtlValidSecurityDescriptor yah, `dub test --build=unittest` didn't work. a dub made a test file for library(eg. libname-test-library.exe), but couldn't executed it. WHY??? But it didnt have no problem, when i tried executing `libname-test-library.exe` directly. WHY??? i have no idea. oh, sorry... my mistake. the content was mix. here is my original article: WTF, why i got a this modal messagebox when i trying `dub test --build=unittest` ?? i just captured messagebox and using OCR, and that's it. here: core.exceptionAssertError@source\dub\internal\vibecompat\core\log.d(85): Enforcement failed (No error) 0x00594079 in _d_assert_msg Ox0056A55D in nothrow @safe void dub.intemal.vibecompatcore.logiogErrorRimmutable(chae.lo gError(immutable(char)g, lazy immutable(char)g) at CWUsersWvagrantVklonesVidubVisourceVeduhAVinternalWvibeco mpatwcorewlog.d(47) Ox00409C24 in int dub.commandline.runDubCommandLine(immutable(chaOgg) at CWUsersWvagrantVklonesVidubVisourceViduhAikommandline.d( 272) Ox0040256E in _Dmain at CWUsersWvagrantVklonesWdubVisourceWapp.d(15) Ox00592DDF in void rtdmain2._d_run_mainent, char*, extern (C) int function(chargr).runA110._lambdal 0 Ox00592D61 in void rtdmain2._d_run_mainent, char", extern (C) int function(chargg)").runAll0 Ox00592BFB in _d_run_main Ox0040894C in main at CV/UsersWvagrantVklonesVidubVisourceiVapp.d(7) Ox0060D535 in mainCRTStartup 0x77608484 in BaseThreadlnitThunk Ox77E13O5A in RtlValidSecurityDescriptor Ox77E1302A in RtlValidSecurityDescriptor yah, `dub test --build=unittest` didn't work. the dub made a test file for library(eg. libname-test-library.exe) successfull but couldn't executed it. WHY??? one of thing funny, it was work clearly when i tried executing `libname-test-library.exe` directly. WHY??? i have no idea.
Re: scoped classes and dependency inversion
On Thursday, 8 November 2018 at 12:45:57 UTC, Alex wrote: Hmm... not sure, if I got your idea... Do you think about something like this? **snip** class Bar(TFoo) if(is(TFoo : IFoo)) { typeof(scoped!TFoo()) _foo; this() { _foo = scoped!TFoo(); } } Yes, pretty much. Except if you want to pass a parameter to TFoo it'll become a mess. And I expecially don't want it to become messy.
Re: Creating InputRanges from strings, files etc.
On Thursday, 8 November 2018 at 14:38:37 UTC, Paul Backus wrote: You can iterate through a file one ubyte at a time using `byChunk` and `joiner`: auto r1 = stdin.byChunk(1024).joiner; assert(is(typeof(r1.front) == ubyte)); You can iterate through a string one ubyte at a time using `representation`: auto r2 = "To be or not to be".representation; assert(is(typeof(r2.front) == immutable(ubyte))); To pass these ranges around using the `InputRange` interface, use `inputRangeObject` to wrap them: InputRange!ubyte r3 = inputRangeObject(r1); InputRange!(immutable(ubyte)) r4 = inputRangeObject(r2); Aha - inputRangeObject was the thing I was missing. Thanks!
Re: Exception slipping through the catch block?
On Thursday, 8 November 2018 at 15:08:40 UTC, helxi wrote: Shouldn't the catch block in the function catch the exception? You caught Exception, but it throws Error. They have separate inheritance trees. The common ancestor is actually Throwable, though note that there is no guarantee that Errors actually unwind the stack; with certain compile flags they might just abort the program.
Re: scoped classes and dependency inversion
On Thursday, 8 November 2018 at 15:11:16 UTC, Sjoerd Nijboer wrote: Except if you want to pass a parameter to TFoo it'll become a mess. And I expecially don't want it to become messy. I thought of this case... But passing the argument to TFoo directly while constructing Bar is messier, I think. With the solution above you could just: ´´´ import std.stdio; import std.typecons; void main() { auto initData = 42; auto bar = new Bar!Foo(initData); assert(bar._foo.orWhatTypeEver == initData); } class Bar(TFoo) if(is(TFoo : IFoo)) { typeof(scoped!TFoo()) _foo; this(T)(T fooParam) //if(__traits(compiles, new TFoo(T.init))) { _foo = scoped!TFoo(fooParam); } } class Foo : IFoo { int orWhatTypeEver; this(T)(T myParam) { orWhatTypeEver = /*cast(int)*/myParam; } void baz(){} } interface IFoo{ void baz(); } ´´´ In this case, Bar's constructor is not bound to any special type of input, letting Foo handle any input you want. Still, the solution is type safe. And, maybe to calm my mind: Bar is the context of Foo, so it is allowed to see its inputs...
Re: Exception slipping through the catch block?
On Thursday, 8 November 2018 at 15:50:38 UTC, helxi wrote: Thanks. Although it's pretty frustrating, isn't it? Now not only I have to think about catching exceptions but also about Errors, and have no guarantee that I have everything under control. Isn't it rather the case, that you have to think about errors while developing? ;)
Re: Exception slipping through the catch block?
On Thursday, 8 November 2018 at 15:41:11 UTC, Adam D. Ruppe wrote: On Thursday, 8 November 2018 at 15:08:40 UTC, helxi wrote: Shouldn't the catch block in the function catch the exception? You caught Exception, but it throws Error. They have separate inheritance trees. The common ancestor is actually Throwable, though note that there is no guarantee that Errors actually unwind the stack; with certain compile flags they might just abort the program. Thanks. Although it's pretty frustrating, isn't it? Now not only I have to think about catching exceptions but also about Errors, and have no guarantee that I have everything under control.
Re: Exception slipping through the catch block?
On Thursday, 8 November 2018 at 15:50:38 UTC, helxi wrote: On Thursday, 8 November 2018 at 15:41:11 UTC, Adam D. Ruppe wrote: On Thursday, 8 November 2018 at 15:08:40 UTC, helxi wrote: Shouldn't the catch block in the function catch the exception? You caught Exception, but it throws Error. They have separate inheritance trees. The common ancestor is actually Throwable, though note that there is no guarantee that Errors actually unwind the stack; with certain compile flags they might just abort the program. Thanks. Although it's pretty frustrating, isn't it? Now not only I have to think about catching exceptions but also about Errors, and have no guarantee that I have everything under control. Just don't have errors thrown.
Re: scoped classes and dependency inversion
On Thu, 08 Nov 2018 12:45:57 +, Alex wrote: > Hmm... not sure, if I got your idea... Do you think about something like > this? The point is dependency inversion. The class shouldn't need to know how to build its dependencies; it should leave that to other code. The fact that you can use the default constructor to build a thing is more coupling than desired.
Re: Exception slipping through the catch block?
On Thursday, 8 November 2018 at 15:50:38 UTC, helxi wrote: On Thursday, 8 November 2018 at 15:41:11 UTC, Adam D. Ruppe wrote: On Thursday, 8 November 2018 at 15:08:40 UTC, helxi wrote: Shouldn't the catch block in the function catch the exception? You caught Exception, but it throws Error. They have separate inheritance trees. The common ancestor is actually Throwable, though note that there is no guarantee that Errors actually unwind the stack; with certain compile flags they might just abort the program. Thanks. Although it's pretty frustrating, isn't it? Now not only I have to think about catching exceptions but also about Errors, and have no guarantee that I have everything under control. No, you should never catch Errors. They're separate for a reason.
Re: Creating InputRanges from strings, files etc.
On Thursday, 8 November 2018 at 14:38:37 UTC, Paul Backus wrote: To pass these ranges around using the `InputRange` interface, use `inputRangeObject` to wrap them: InputRange!ubyte r3 = inputRangeObject(r1); InputRange!(immutable(ubyte)) r4 = inputRangeObject(r2); I did a bit more digging, and it seems to work for strings but not for files: The program import std.algorithm.iteration; import std.format; import std.range; import std.stdio; import std.string; void somefn(InputRange!(immutable(ubyte)) r) { writeln(format!"%s"(r)); } void main() { auto a = "Hello, world!"; auto b = inputRangeObject(a.representation); somefn(b); auto c = stdin.byChunk(1024).joiner; auto d = inputRangeObject(c); //somefn(d); } compiles as given above, but if the somefn(d) line is uncommented, I get an error: function onlineapp.somefn(InputRange!(immutable(ubyte)) r) is not callable using argument types (InputRangeObject!(Result)) onlineapp.d(18):cannot pass argument d of type std.range.interfaces.InputRangeObject!(Result) to parameter InputRange!(immutable(ubyte)) r Do I need to do an explicit cast? If so, can someone tell me the precise incantation? How come it doesn't figure out that the underlying range is a ubyte range, or is it to do with immutability, or something else altogether?
Re: Creating InputRanges from strings, files etc.
On Thursday, 8 November 2018 at 16:15:25 UTC, Vinay Sajip wrote: On Thursday, 8 November 2018 at 14:38:37 UTC, Paul Backus wrote: To pass these ranges around using the `InputRange` interface, use `inputRangeObject` to wrap them: InputRange!ubyte r3 = inputRangeObject(r1); InputRange!(immutable(ubyte)) r4 = inputRangeObject(r2); I did a bit more digging, and it seems to work for strings but not for files: The program import std.algorithm.iteration; import std.format; import std.range; import std.stdio; import std.string; void somefn(InputRange!(immutable(ubyte)) r) { writeln(format!"%s"(r)); } void main() { auto a = "Hello, world!"; auto b = inputRangeObject(a.representation); somefn(b); auto c = stdin.byChunk(1024).joiner; auto d = inputRangeObject(c); //somefn(d); } compiles as given above, but if the somefn(d) line is uncommented, I get an error: function onlineapp.somefn(InputRange!(immutable(ubyte)) r) is not callable using argument types (InputRangeObject!(Result)) onlineapp.d(18):cannot pass argument d of type std.range.interfaces.InputRangeObject!(Result) to parameter InputRange!(immutable(ubyte)) r Do I need to do an explicit cast? If so, can someone tell me the precise incantation? How come it doesn't figure out that the underlying range is a ubyte range, or is it to do with immutability, or something else altogether? you could use a template for somefn definition: ´´´ void somefn(T)(T r) { writeln(format!"%s"(r)); } ´´´
Re: scoped classes and dependency inversion
On Thu, 08 Nov 2018 11:04:19 +, Sjoerd Nijboer wrote: > I'm trying to invert the dependency from the classes `Bar -> Foo` to > `Foo -> IFoo <- Bar` at compile time. > > I do want `Foo's` to be embedded into `Bar` These goals are a *little* at odds with each other; having a scoped!Foo puts significant constraints on how to build the object. But you know your needs a lot better than some generic advice. I believe what you need to do is pass a factory function into the constructor. This is a bit awkward. The really annoying part is that std.typecons doesn't have a named type for the scoped wrapper for a type. It's actively hostile to having scoped fields for no discernable reason. Filed https://issues.dlang.org/ show_bug.cgi?id=19379 Anyway, here's some code to make it work. It's kind of ugly. --- import std.stdio; import std.typecons; void main() { auto bar = new Bar!Foo((ref f) { f = scoped!Foo(); }); } class Bar(TFoo) if(is(TFoo : IFoo)) { alias SFoo = typeof(scoped!TFoo()); SFoo _foo; this(void delegate(ref SFoo) dg) { dg(_foo); } } class Foo : IFoo { void baz(){} } interface IFoo { void baz(); } ---
Re: Creating InputRanges from strings, files etc.
On 11/8/18 11:15 AM, Vinay Sajip wrote: On Thursday, 8 November 2018 at 14:38:37 UTC, Paul Backus wrote: To pass these ranges around using the `InputRange` interface, use `inputRangeObject` to wrap them: InputRange!ubyte r3 = inputRangeObject(r1); InputRange!(immutable(ubyte)) r4 = inputRangeObject(r2); I did a bit more digging, and it seems to work for strings but not for files: The program import std.algorithm.iteration; import std.format; import std.range; import std.stdio; import std.string; void somefn(InputRange!(immutable(ubyte)) r) { writeln(format!"%s"(r)); } void main() { auto a = "Hello, world!"; auto b = inputRangeObject(a.representation); somefn(b); auto c = stdin.byChunk(1024).joiner; auto d = inputRangeObject(c); //somefn(d); } compiles as given above, but if the somefn(d) line is uncommented, I get an error: function onlineapp.somefn(InputRange!(immutable(ubyte)) r) is not callable using argument types (InputRangeObject!(Result)) onlineapp.d(18): cannot pass argument d of type std.range.interfaces.InputRangeObject!(Result) to parameter InputRange!(immutable(ubyte)) r Do I need to do an explicit cast? If so, can someone tell me the precise incantation? How come it doesn't figure out that the underlying range is a ubyte range, or is it to do with immutability, or something else altogether? A cool feature of D is to have it tell you something about your code at compile time. I did this in a run.dlang.org playground: pragma(msg, ElementType!(typeof(b))); pragma(msg, ElementType!(typeof(d))); I get: immutable(ubyte) ubyte Which means they aren't the same type, and they don't define the same interface (InputRange!(ubyte) is not the same as InputRange!(immutable(ubyte)) ). Other than simply using compile-time functions, and dropping the object interface as Alex suggests, the easiest thing I can recommend is wrapping representation into a casting input range such as map: auto b = inputRangeObject(a.representation.map!(b => ubyte(b))); You can see all this here: https://run.dlang.io/is/1E6Uqj -Steve
Re: Creating InputRanges from strings, files etc.
On Thursday, 8 November 2018 at 16:41:50 UTC, Steven Schveighoffer wrote: I did this in a run.dlang.org playground: pragma(msg, ElementType!(typeof(b))); pragma(msg, ElementType!(typeof(d))); I get: immutable(ubyte) ubyte Which means they aren't the same type, and they don't define the same interface (InputRange!(ubyte) is not the same as InputRange!(immutable(ubyte)) ). Other than simply using compile-time functions, and dropping the object interface as Alex suggests, the easiest thing I can recommend is wrapping representation into a casting input range such as map: auto b = inputRangeObject(a.representation.map!(b => ubyte(b))); You can see all this here: https://run.dlang.io/is/1E6Uqj -Steve Thanks, guys, those are helpful pointers.
Re: Exception slipping through the catch block?
On Thursday, 8 November 2018 at 16:13:55 UTC, Mike Parker wrote: On Thursday, 8 November 2018 at 15:50:38 UTC, helxi wrote: Although it's pretty frustrating, isn't it? Now not only I have to think about catching exceptions but also about Errors, and have no guarantee that I have everything under control. No, you should never catch Errors. They're separate for a reason. Never say never :) There are legitimate cases for catching an Error or even a Throwable (for example, error propagation in a multi-threaded environment). However, this is not one of such cases. helxi, an AssertError means there's a problem with your code, it needs to be dealt with by fixing the code, not swallowing the Error.
Re: Exception slipping through the catch block?
On Thursday, November 8, 2018 10:55:45 AM MST Stanislav Blinov via Digitalmars-d-learn wrote: > On Thursday, 8 November 2018 at 16:13:55 UTC, Mike Parker wrote: > > On Thursday, 8 November 2018 at 15:50:38 UTC, helxi wrote: > >> Although it's pretty frustrating, isn't it? Now not only I > >> have to think about catching exceptions but also about Errors, > >> and have no guarantee that I have everything under control. > > > > No, you should never catch Errors. They're separate for a > > reason. > > Never say never :) There are legitimate cases for catching an > Error or even a Throwable (for example, error propagation in a > multi-threaded environment). However, this is not one of such > cases. Yeah, but basically, the rule of thumb is never. Errors are fatal error conditions which are supposed to terminate the program, and programs should not be trying to recover from them. No one should be attempting to catch them unless they know what they're doing, which honestly, probably isn't going to be very many people for something like this. Exceptions are for error conditions which are potentially recoverable. Program input or environmental state was bad (e.g. a missing file). They aren't necessarily indicative of bugs in the program, and the program can potentially recover from them and continue to function perfectly fine. Errors on the other hand, are used to indicate actual bugs in the program or fatal conditions with resources which cannot be recovered from (e.g. the GC running out of memory). They are intended simply to be informative and not to be caught. The stack is not necessarily properly unwound when they are thrown. Full exception handling code is not necessarily even in place when they are thrown, and they can be thrown from nothrow code. By definition, your program is in an invalid state when you catch an Error, and catching an Error to do much of anything is dangerous. > helxi, an AssertError means there's a problem with your code, it > needs to be dealt with by fixing the code, not swallowing the > Error. Specifically, AssertError means that either an assertion failed or something simulating an assertion failed (such as std.exception.assertThrown), so it's something in the code that quite specifically indicates that there's a bug in the code and that a condition that must be true for the code to be in a valid state was false. So, whatever it reported should be tracked down and fixed. In this particular case, it looks like a piece of code called dropBackOne on an empty range. - Jonathan M Davis
Re: scoped classes and dependency inversion
On Thursday, 8 November 2018 at 16:31:26 UTC, Neia Neutuladh wrote: I believe what you need to do is pass a factory function into the constructor. This is a bit awkward. Yep, but I want a "nice and descriptive syntax" for it. Anyway, here's some code to make it work. It's kind of ugly. --- import std.stdio; import std.typecons; void main() { auto bar = new Bar!Foo((ref f) { f = scoped!Foo(); }); } class Bar(TFoo) if(is(TFoo : IFoo)) { alias SFoo = typeof(scoped!TFoo()); SFoo _foo; this(void delegate(ref SFoo) dg) { dg(_foo); } } class Foo : IFoo { void baz(){} } interface IFoo { void baz(); } --- I tried to get something more nice looking and I'm stuck on the following. I tried tom make a lazyscoped!T but I'm stuck at creating a constructor and determining the arguments from the Type. If I could do that I could just forward a lazyscoped!T which would have my parameters encapsulated to an object and have that object instantiate it at its place. Maybe not the smartest idea but I think it's a little more descriptive than using a factory lambda. ``` import std.typecons : scoped; void main() { auto initData = 42; auto bar = new Bar!Foo(lazyscoped!(Foo)(initData)); } class Bar(TFoo, TArgs...) if(is(TFoo : IFoo)) { private typeof(scoped!TFoo()) _foo; this(lazyscoped!TFoo foo) { foo.construct(_foo); } } class Foo : IFoo { int orWhatTypeEver; this(T)(T myParam) { orWhatTypeEver = /*cast(int)*/myParam; } void baz(){} } interface IFoo{ void baz(); } struct lazyscoped(T) { import std.typecons : scoped; TArgs args; // somehow determine TArgs assumimg there is only one __ctor of type T. this(TArgs args) { static if(TArgs.length > 0) this.args = args; } void construct(ref typeof(scoped!T()) scoped_t) { scoped_t = scoped!T(args); } }```
Re: Exception slipping through the catch block?
On Thu, Nov 08, 2018 at 01:28:47PM -0700, Jonathan M Davis via Digitalmars-d-learn wrote: > On Thursday, November 8, 2018 10:55:45 AM MST Stanislav Blinov via > Digitalmars-d-learn wrote: > > On Thursday, 8 November 2018 at 16:13:55 UTC, Mike Parker wrote: [...] > > > No, you should never catch Errors. They're separate for a > > > reason. > > > > Never say never :) There are legitimate cases for catching an > > Error or even a Throwable (for example, error propagation in a > > multi-threaded environment). However, this is not one of such > > cases. > > Yeah, but basically, the rule of thumb is never. Errors are fatal > error conditions which are supposed to terminate the program, and > programs should not be trying to recover from them. No one should be > attempting to catch them unless they know what they're doing, which > honestly, probably isn't going to be very many people for something > like this. Recently I ran into a case where catching Throwable makes sense: I have an Android application where the main code interfacing with the Android OS is written in Java, but program logic is written in D, called via JNI. Since the JVM obviously cannot handle D exceptions, any unhandled D exception that makes it past the JNI boundary would cause the application to crash. So what I did was to have the JNI interfacing code (on the D side) catch *everything*, i.e., Throwable, marshall the error message into a Java object, then send it via JNI back to the Java code that then displays the error message before aborting the application. Extremely valuable in debugging, since otherwise I'd have to extract the stacktrace from the system logs, which is a pain. > Exceptions are for error conditions which are potentially recoverable. > Program input or environmental state was bad (e.g. a missing file). > They aren't necessarily indicative of bugs in the program, and the > program can potentially recover from them and continue to function > perfectly fine. > > Errors on the other hand, are used to indicate actual bugs in the > program or fatal conditions with resources which cannot be recovered > from (e.g. the GC running out of memory). They are intended simply to > be informative and not to be caught. The stack is not necessarily > properly unwound when they are thrown. Full exception handling code is > not necessarily even in place when they are thrown, and they can be > thrown from nothrow code. By definition, your program is in an invalid > state when you catch an Error, and catching an Error to do much of > anything is dangerous. [...] Agreed in general. In my case, though, being able to catch an Error makes it possible to pass on the error message to the Java code and displayed on the screen, instead of the whole thing crashing and burning with no indication of what went wrong. T -- Bare foot: (n.) A device for locating thumb tacks on the floor.
How do I install a library?
I want to install the library DlangUI but I don't know how to do it. In python I just type pip and it works, but in D I don't know how to do it. Can anyone help me?
Re: How do I install a library?
On 11/8/18 4:46 PM, Murilo wrote: I want to install the library DlangUI but I don't know how to do it. In python I just type pip and it works, but in D I don't know how to do it. Can anyone help me? dlangui will be fetched if you make it a dependency of your project. When you run dub init on your project, it will ask for dependencies, just type dlangui in there. -Steve
Re: How do I install a library?
On Thursday, 8 November 2018 at 22:28:38 UTC, Steven Schveighoffer wrote: On 11/8/18 4:46 PM, Murilo wrote: I want to install the library DlangUI but I don't know how to do it. In python I just type pip and it works, but in D I don't know how to do it. Can anyone help me? dlangui will be fetched if you make it a dependency of your project. When you run dub init on your project, it will ask for dependencies, just type dlangui in there. -Steve Thanks, I tried that but when I add the import dlangui in the beginning it doesn't work. I wanted to just type import dlangui in the beginning of the file so I can call the dlangui functions.
Re: How do I install a library?
On 11/8/18 5:46 PM, Murilo wrote: On Thursday, 8 November 2018 at 22:28:38 UTC, Steven Schveighoffer wrote: On 11/8/18 4:46 PM, Murilo wrote: I want to install the library DlangUI but I don't know how to do it. In python I just type pip and it works, but in D I don't know how to do it. Can anyone help me? dlangui will be fetched if you make it a dependency of your project. When you run dub init on your project, it will ask for dependencies, just type dlangui in there. Thanks, I tried that but when I add the import dlangui in the beginning it doesn't work. I wanted to just type import dlangui in the beginning of the file so I can call the dlangui functions. D uses dub and code.dlang.org to fetch dependencies (similar to python or other ecosystems). If you are using dub to build your project, just add dlangui as a dependency, and you can then import and use it. This goes in your dub.json or dub.sdl file. See documentation here: http://code.dlang.org/getting_started If you want to build the dlangui library directly and install it on your own without dub, you would need to download the source (probably from github) and build it using dub. -Steve
Re: How do I install a library?
On 11/8/18 6:07 PM, Steven Schveighoffer wrote: If you want to build the dlangui library directly and install it on your own without dub, you would need to download the source (probably from github) and build it using dub. When I said without using dub, I meant without using dub to build your project. You still need to use dub to build the library. -Steve
Re: How do I install a library?
On Thursday, 8 November 2018 at 23:28:05 UTC, Steven Schveighoffer wrote: On 11/8/18 6:07 PM, Steven Schveighoffer wrote: If you want to build the dlangui library directly and install it on your own without dub, you would need to download the source (probably from github) and build it using dub. When I said without using dub, I meant without using dub to build your project. You still need to use dub to build the library. -Steve It finally worked, but I can't just compile it normally, I have to use dub run, I wish it were something simple that I just download into the folder and then use an import statement and then compile it like any other program. I wish it were as simple as using std.stdio for example.
Re: How do I install a library?
On Thursday, 8 November 2018 at 23:43:38 UTC, Murilo wrote: It finally worked, but I can't just compile it normally, I have to use dub run, I wish it were something simple that I just download into the folder and then use an import statement and then compile it like any other program. I wish it were as simple as using std.stdio for example. Unfortunately your stuck with Dub if you want to use D. It's an awful experience compared to Python and other scripting languages, so I understand what you're saying, but most people around here think Dub is the way to go.
Re: How do I install a library?
On 11/8/18 6:43 PM, Murilo wrote: On Thursday, 8 November 2018 at 23:28:05 UTC, Steven Schveighoffer wrote: On 11/8/18 6:07 PM, Steven Schveighoffer wrote: If you want to build the dlangui library directly and install it on your own without dub, you would need to download the source (probably from github) and build it using dub. When I said without using dub, I meant without using dub to build your project. You still need to use dub to build the library. It finally worked, but I can't just compile it normally, I have to use dub run, I wish it were something simple that I just download into the folder and then use an import statement and then compile it like any other program. I wish it were as simple as using std.stdio for example. It's actually not a bad idea to be able to "install" libraries like you have your compiler installed. It could be done with the infrastructure that's there already. Would be cool for playing around with toy projects without having to initialize a dub project. There is the ability to include the dub file in the source file itself, but that may be too complex for your taste. For most people who want to have their projects depend on others, there is the need to specify the projects, how they should be built, and what versions, etc. Which is why dub is used to build most things. -Steve
Re: How do I install a library?
On Thursday, 8 November 2018 at 23:43:38 UTC, Murilo wrote: It finally worked, but I can't just compile it normally, I have to use dub run, I wish it were something simple that I just download into the folder and then use an import statement and then compile it like any other program. I wish it were as simple as using std.stdio for example. Whenever you import a module from a folder somewhere else than your project, you need to pass the location to the compiler with the -I flag. The reason std.stdio works from everywhere is because if you go to /windows/bin/sc.ini (assuming you use Windows and dmd), you will find: [Environment] DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import" This will add the -I flag with the phobos location by default. If you run: dub --verbose --force You will see how dub invokes the compiler. If you look at the compiler flags, you will likely find something like this: -I..\..\..\AppData\Roaming\dub\packages\\source What you could do is locate the package, move it to a folder of your choice, and add an import to that location to your sc.ini. The Gtkd UI-framework actually prescribes such a global install: https://github.com/gtkd-developers/GtkD/wiki/Installing-on-Windows I don't know how comfortable you are doing this, it may be easier to just use dub like it's intended. This could actually be a neat feature of dub: a global install of a dependency.
Re: How do I install a library?
On Thu, Nov 08, 2018 at 11:51:39PM +, bachmeier via Digitalmars-d-learn wrote: > On Thursday, 8 November 2018 at 23:43:38 UTC, Murilo wrote: > > > It finally worked, but I can't just compile it normally, I have to > > use dub run, I wish it were something simple that I just download > > into the folder and then use an import statement and then compile it > > like any other program. I wish it were as simple as using std.stdio > > for example. > > Unfortunately your stuck with Dub if you want to use D. It's an awful > experience compared to Python and other scripting languages, so I > understand what you're saying, but most people around here think Dub > is the way to go. It's not true that you're stuck with dub. And I'm not among the people who think dub is the way to go (though it's true that that's a minority opinion around here). Where I have a choice, my own D projects do not use dub. I have one project that uses dub because it's based on vibe.d, but I mostly avoid needing to use dub by creating an empty dub project in a subdirectory whose sole purpose is to declare a dependency on vibe.d. Then I build that once with dub, and outside in my real project I just link directly to the produced artifacts. (The exact path(s) to the dub products can be extracted from the output of `dub -v`. This can probably be automated and translated into your build system of choice, though I haven't quite gone that far yet.) Then I don't need to use dub except when upgrading the dub-dependent library. I find dub almost completely unusable for normal development, because: (1) it requires network access, (2) it's dog-slow compared to how fast the actual D compiler runs (it tries to do dependency updating every single time it runs, even when all you've done is to change 1 line in your code), (3) it either does not support incremental builds, or else is so bad at doing it that it takes about just as long as a full build from scratch; (4) it's not configurable enough to meet my build needs -- e.g., it's completely unable to handle my current Android project that involves compiling Java code, D code, GLSL code, and cross-compiling / linking / building an APK, plus compile and link an X11 test driver on the host PC, which involves invoking a different (non-cross) compiler with different libraries and a different set of source files -- dub's build spec simply isn't capable of expressing the level of configurability required to do all of this; (5) it imposes a source tree hierarchy that conflicts with what I need (Android SDK's APK tools expect a particular directory structure that does not fit into dub's model). While I appreciate the amount of effort it took to develop and deploy dub, I am sorry to say that it falls far short of my expectations and I can't see myself using it in any meaningful sense in the foreseeable future. Using it as a dependency puller for vibe.d is about as far as I will go, unfortunately. Many of dub's limitations, AFAICT, are inherent to its design and architecture, so I don't see any easy way to fix these problems either, short of rewriting it from scratch (and I have no inclination to take on something that big at this time). Atila Neves has also created his own D-based build system that reportedly is much superior to dub. You might want to look into that as well. T -- INTEL = Only half of "intelligence".
Re: Exception slipping through the catch block?
On Thursday, November 8, 2018 2:34:38 PM MST H. S. Teoh via Digitalmars-d- learn wrote: > On Thu, Nov 08, 2018 at 01:28:47PM -0700, Jonathan M Davis via Digitalmars-d-learn wrote: > > On Thursday, November 8, 2018 10:55:45 AM MST Stanislav Blinov via > > > > Digitalmars-d-learn wrote: > > > On Thursday, 8 November 2018 at 16:13:55 UTC, Mike Parker wrote: > [...] > > > > > No, you should never catch Errors. They're separate for a > > > > reason. > > > > > > Never say never :) There are legitimate cases for catching an > > > Error or even a Throwable (for example, error propagation in a > > > multi-threaded environment). However, this is not one of such > > > cases. > > > > Yeah, but basically, the rule of thumb is never. Errors are fatal > > error conditions which are supposed to terminate the program, and > > programs should not be trying to recover from them. No one should be > > attempting to catch them unless they know what they're doing, which > > honestly, probably isn't going to be very many people for something > > like this. > > Recently I ran into a case where catching Throwable makes sense: I have > an Android application where the main code interfacing with the Android > OS is written in Java, but program logic is written in D, called via > JNI. Since the JVM obviously cannot handle D exceptions, any unhandled > D exception that makes it past the JNI boundary would cause the > application to crash. So what I did was to have the JNI interfacing > code (on the D side) catch *everything*, i.e., Throwable, marshall the > error message into a Java object, then send it via JNI back to the Java > code that then displays the error message before aborting the > application. Extremely valuable in debugging, since otherwise I'd have > to extract the stacktrace from the system logs, which is a pain. You ran into one of the rare cases where it makes sense catch an Error or a Throwable, and you're one of the few people who understands the situation well enough to deal with it properly. The vast majority of D programmers don't. Certainly, anyone who has to ask about the differences between Throwable, Error, and Exception doesn't. - Jonathan M Davis
Re: Exception slipping through the catch block?
On Thu, 08 Nov 2018 17:27:40 -0700, Jonathan M Davis wrote: > You ran into one of the rare cases where it makes sense catch an Error > or a Throwable, and you're one of the few people who understands the > situation well enough to deal with it properly. The vast majority of D > programmers don't. Certainly, anyone who has to ask about the > differences between Throwable, Error, and Exception doesn't. I really don't believe it's that rare or that fraught, most of the time. If an error happens, it's better for most programs to try to leave behind enough artifacts for you to start debugging the problem. Most of the time, a stacktrace on stderr is good enough and still possible. And that's what the runtime does. This isn't, strictly speaking, safe. Your program detected an error, and in Walter's book, that means you can't trust the program to do *anything*. Unwinding the stack, formatting a stacktrace, writing to stderr, this is all Dangerous Stuff You Shouldn't Be Doing. Even sending your process sigabrt to trigger a core dump is potentially dangerous. But the utility is greater than the likely harm, which is why druntime will unwind the stack, format a stacktrace, and write to stderr when an Error is thrown and not caught. Similarly, if your program logs to a file normally and you use that logfile for most of your debugging, it's sensible to try to log the error to that file and then exit. Especially if, like with H. S. Teoh's case, it's difficult or impossible for you to access the process's stderr. This is still *slightly* fraught. If your logging system is responsible for that Error being thrown, you probably won't succeed in logging the Error. If you have custom Error classes that do weird things, those things are more likely to break. Your application might be out of memory, so the allocations involved in logging could also fail. So, moderately fraught, but I don't think it's "here be dragons" any more than usual.
Re: How do I install a library?
On Friday, 9 November 2018 at 00:18:28 UTC, H. S. Teoh wrote: It's not true that you're stuck with dub. And I'm not among the people who think dub is the way to go (though it's true that that's a minority opinion around here). Where I have a choice, my own D projects do not use dub. I have one project that uses dub because it's based on vibe.d, but I mostly avoid needing to use dub by creating an empty dub project in a subdirectory whose sole purpose is to declare a dependency on vibe.d. Then I build that once with dub, and outside in my real project I just link directly to the produced artifacts. (The exact path(s) to the dub products can be extracted from the output of `dub -v`. This can probably be automated and translated into your build system of choice, though I haven't quite gone that far yet.) Then I don't need to use dub except when upgrading the dub-dependent library. This is still a build system though. It might have advantages over Dub, but I think the OP wants to avoid build systems altogether. Someone coming from a scripting language wants to add import foo; to their program and not think about package foo further. There's no obvious reason it can't be done that way in D, but the C/C++ foundation of this community leads to a mindset that it's wrong, because you need to be able to set all kinds of configuration options, guarantee reproducible builds, etc. All of which are of no importance to someone using D as a scripting language.
Why is stdio ... stdio?
Simple curious question. Why isn't : import std.stdio; instead: import std.io; (Also, while we're at it. Why doesn't this form have code highlighting? It would much improve readibility. Doesn't that seem almost essential for a programming forum?) I mean, I get it. stdio is the c header from a thousand years ago. But this isn't C. So it's kind of odd to ask for the "Standard standard" io library.
Re: Exception slipping through the catch block?
On Fri, Nov 09, 2018 at 01:14:08AM +, Neia Neutuladh via Digitalmars-d-learn wrote: [...] > This isn't, strictly speaking, safe. Your program detected an error, > and in Walter's book, that means you can't trust the program to do > *anything*. Unwinding the stack, formatting a stacktrace, writing to > stderr, this is all Dangerous Stuff You Shouldn't Be Doing. Even > sending your process sigabrt to trigger a core dump is potentially > dangerous. If we wanted to be *completely* safe according to Walter's definition, we'd have to completely decouple Error handling from the process that reaches a `throw new Error(...)` (or any of its derived classes thereof). You'd have a monitor running in a completely separate process from the main program, that regularly checks up on the health of the latter. When the latter encounters an Error, it should immediately execute a 'hlt' instruction, or enter a 1-instruction empty infinite loop, and the monitor process (which, presumably, has not had its logic compromised) would detect this and kill / restart / extract core dump info from the failed process. Anything inside the failed process itself would not be trustworthy. (Conceivably, for example, a remote attacker may have triggered a buffer overflow that overwrote, say, the variables holding the file descriptors for the logfile, so as to redirect any logged messages to a publicly-readable place, and may have further corrupted the logging module's state so that instead of writing the stacktrace or error message to the file, it writes the contents of /etc/passwd or some such sensitive file instead. All bets are off once an assertion fails. Or worse yet, the assertion failure may have been caused by some internal code gone wrong that has overwritten some critical function pointers so that calling a dynamically-linked druntime function accidentally ends up invoking the function to increase laser output intensity 100x instead, thereby killing the patient undergoing surgery by the machine controlled by the code.) > But the utility is greater than the likely harm, which is why druntime > will unwind the stack, format a stacktrace, and write to stderr when > an Error is thrown and not caught. Yes, the utility outweighs the potential dangers, especially during development when you want maximum information about what went wrong, so it makes sense to catch Errors for that purpose. Catching Errors and then continuing to execute application logic as if nothing happened, though, is a big no-no. T -- Caffeine underflow. Brain dumped.
Re: Why is stdio ... stdio?
On Fri, Nov 09, 2018 at 02:03:36AM +, Chris Katko via Digitalmars-d-learn wrote: > Simple curious question. > > Why isn't : > > import std.stdio; > > instead: > > import std.io; The reason is that std.stdio is basically just a nice D wrapper with syntactic sugar around the C library's stdio.h. There has been a std.io in the works, but unfortunately it hasn't quite materialized yet. So for now, we're stuck with std.stdio. > (Also, while we're at it. Why doesn't this form have code > highlighting? It would much improve readibility. Doesn't that seem > almost essential for a programming forum?) [...] Because this "forum" isn't really a web forum, but just a web interface to an NNTP server that also has a mailing list interface (I (mostly) use the mailing list interface). Haven't really felt a need for syntax highlighting myself, though most opinions differ. :-D T -- Latin's a dead language, as dead as can be; it killed off all the Romans, and now it's killing me! -- Schoolboy
Re: Why is stdio ... stdio?
On Fri, 09 Nov 2018 02:03:36 +, Chris Katko wrote: > Simple curious question. > > Why isn't : > > import std.stdio; > > instead: > > import std.io; IO includes things like memory mapping, sockets, listing files, named pipes, that sort of thing. Standard IO includes only reading and writing to files and the console. > (Also, while we're at it. Why doesn't this form have code highlighting? > It would much improve readibility. Doesn't that seem almost essential > for a programming forum?) It's not a forum. It's a newsgroup that happens to have a web interface. Newsgroups are text-only. So bbcode is out, html is out, but interpreting markdown might be reasonable. But nobody's done that work.
Re: Is this a bug? +goto
On Thursday, 8 November 2018 at 10:31:31 UTC, Jonathan M Davis wrote: On Thursday, November 8, 2018 2:34:34 AM MST Michelle Long via Digitalmars- d-learn wrote: Obviously, but that is not the case I mentioned. You can assume that I know how scopes work. No need to assume everyone that shows two cases that you have to bring up an unrelated case as a potential cause unless it is relevant. Remember, I'm showing the starting case that has the bug and the final case that doesn't... it is simply "mental dustmite" on the code I have. You shouldn't assume everyone can't comprehend such trivialities. If a person cannot understand scope then I doubt they understand goto's... and definitely not that adding braces should not change the compiler behavior. What happens when you do that you just create noise that makes it more difficult to have a proper discussion that gets at the whole point of the conversation. You seem to default to assuming that the person you are talking to has no clue about the problem at hand. You might not do it intentionally but it is wrong to assume that because it almost never helps. If you fully understood the situation, you wouldn't be asking whether your case was a compiler bug or not, and I don't know which parts you do and don't understand. So, I tried to be thorough in explaining the situation. And yes, by being thorough, I'm more likely to cover information that you already know and understand, but I'm also more likely to cover the information that you actually need. In order to avoid repeating anything you already understand and only tell you exactly what you need to know, I would have to somehow understand exactly which piece of the puzzle it is you're missing, and I don't. Nope, you are simply wrong here. You have a need to try to show that you know these trivial difference rather than, as you claim, to show that they exist because the other party doesn't know them. To say that anyone posting a problem doesn't fully understand the situation simply because they don't know it is a compiler bug is either a very arrogant and blatant egotism at work in your mind(if you really believe what you said is true) or you are just ignorant of the facts. I mean, obviously I don't fully understand the situation, but neither do you... so for you to claim that the poser must not fully understand you are implying that you do, which you don't. See, you will say the person asking must be ignorant(not fully understand) of some facts about the problem. Obviously! Everyone is, Even Walter does not have all the D code memorized. So, in a theoretical sense... but in that same sense neither do you. But you are asserting that you actually do know since you then make the claim that you can solve this "ignorance" problem because you do fully know everything. You are conflating theoretical and factual. You actually have no idea how much I know. You make the very arrogant(even if you don't see it that way) assumption that you know more about it... And guess what? We haven't even defined what "it" is completely. So you simply choose to consistently make decisions based on your ego rather than what is factual and provable. Everything is probabilistic and you mind and it's bias towards stroking your own ego adjusts the probabilities to do this rather than just taking them as very week approximations(that will become more accurate over time by asking questions). The fact is, it is kinda pointless, you will continue to approach "helping" people with the same method. I'm trying to tell you that is the wrong approach(maybe it is better than nothing, but you basically make a shit load of assumptions about things and generally are wrong and the most important ones) I've noticed from the past that you tend to ignore all suggestions that you do this rather than realizing you do and try to be aware and correct them. This means you do not care about growing or are just ignorant of reality. I'm not saying you are evil or stupid but that you can learn to be a better "helper" by actually trying to help people rather than be "Mr. KnowItAll"(not, again, saying you are blatant about it but you seem to go down the path of having to bring up trivial and basically irrelevant things to point them out. It could be that you have a little bit of the Captain Obvious DNA or whatever). I'm only ranting about this so that maybe you can learn how to have a fully productive communication with someone when providing them help rather than waste time. See, even if you were a perfect programmer and knew everything about D it doesn't mean you have any idea how to communicate with other human beings in solving problems with D. Sometimes the answer is a simple "yes" or "no"(0) and sometimes it is a "thesis"(1). Knowing how much to spin it is what is key, and you seem to not be good at that. All I can say is stop making so many assumption... If you d
Re: Why is stdio ... stdio?
On Thursday, November 8, 2018 7:25:45 PM MST Neia Neutuladh via Digitalmars- d-learn wrote: > It's not a forum. It's a newsgroup that happens to have a web interface. > Newsgroups are text-only. So bbcode is out, html is out, but interpreting > markdown might be reasonable. But nobody's done that work. Honestly, having markdown in messages being typical would be _really_ annoying for those of us not using the web interface, because we'd see all of those backticks and the like as backticks, not as syntax highlighting. It would be like seeing html, albeit far less intrusive. I for one would much rather that things just stay as pure text and that we not be adding any features to the web interface that encourages adding _any_ kind of markup to messages. The web interface makes it easier for folks who don't want to use a newsgroup or mailing list to interact with the newsgroup, but it's still a newsgroup, and _many_ of us use it as such. - Jonathan M Davis