Re: Should the "front" range primitive be "const" ?
On Wednesday, 31 January 2018 at 01:45:57 UTC, H. S. Teoh wrote: .headConst .headMutable. :p Head-const is something we generally want to avoid. -- Simen
Re: Union Initialization
On 01/30/2018 07:33 PM, Rubn wrote: Is there any way to initialize an array of unions with more than just the first union type? struct A { float a; } struct B { uint b; } union Test { A a; B b; } Test[2] test = [ Test(A(1.0f)), Test(B(10)), // ERROR ]; AFAIK there's no way to specify to use D with an initializer: Test test = { b: B(10) }; You can have explicit constructors: union Test { A a; B b; this(A a) { this.a = a; } this(B b) { this.b = b; } } Ali
Re: How to test a DUB-based library during development?
On Thursday, 11 January 2018 at 12:36:22 UTC, Guillaume Piolat wrote: On Thursday, 11 January 2018 at 12:27:27 UTC, DanielG wrote: [snip] You may have some unittest blocks in your source files, and then type: $ dub test [snip] When I try 'dub test' I get errors like 'Source file '/Users/joelchristensen/jpro/dpro2/JMiscLib/source/jmisc/base.d' not found in any import path.' Here's the dub.json file I'm using: ``` { "name": "timelog", "targetType": "executable", "description": "A Joel D program. A D Diary program.", "copyright": "Copyright © 2018, joelcnz - note: I don't understand this", "authors": ["Joel Ezra Christensen"], "DFLAGS": ["g"], "sourcePaths" : ["source", "../JTaskLib/source", "../JMiscLib/source" ], "dependencies": { "dlangui": "~>0.9.56" } } ```
Union Initialization
Is there any way to initialize an array of unions with more than just the first union type? struct A { float a; } struct B { uint b; } union Test { A a; B b; } Test[2] test = [ Test(A(1.0f)), Test(B(10)), // ERROR ]; AFAIK there's no way to specify to use D with an initializer: Test test = { b: B(10) };
Re: Should the "front" range primitive be "const" ?
On Tue, Jan 30, 2018 at 06:05:47PM -0700, Jonathan M Davis via Digitalmars-d-learn wrote: > On Tuesday, January 30, 2018 07:49:28 H. S. Teoh via Digitalmars-d-learn > wrote: [...] > > Simen has had some ideas recently about "head mutable" aka > > tail-const, which could be a first step towards making const ranges, > > or rather tail-const ranges, actually usable: > > > > https://forum.dlang.org/post/cpxfgdmklgusodqou...@forum.dlang.org > > > > tl;dr summary: > > > > (1) Ranges implement a standard method, tentatively called > > opHeadMutable, that returns a head-mutable version of > > themselves. For example, const(MyRange!T).opHeadMutable would > > return MyRange!(const(T)). > > > > (2) Standard library functions would recognize opHeadMutable and use > > it where needed, e.g., when you hand them a const range. > > > > (3) Profit. :-P > > I still need to look over what he's proposing in more detail - it's > been proposed before (by Andrei IIRC) that one possible solution would > be to add an operator for returning a tail-const version of a type, > but no one has ever taken that idea anywhere. Well, that's essentially what Simen has done, and he has code to show for it. > Personally, I'm getting to the point that I'd rather just avoid const > than deal with any further complications for ranges. In principle, I > like the idea of const, but in practice, it just constantly gets in > the way, and I've rarely actually seen any benefit from it in either > C++ or D. I can think of one time in my entire life where const has > prevented a bug for me - which was when I got the arguments backwards > to C++'s std::copy function. I have been saved by const (in D) a few times when I by mistake tried mutating something that shouldn't be mutated. But yeah, more often than not it just gets in the way. However, my hope is that if Simen's proposal gets somewhere, it will reduce the annoyance of const and (hopefully) increase its benefits. Note that while Simen's code example uses ranges, since that's a common blocker for using const, it extends beyond that. For example, consider a const(RefCounted!Object). Right now, this is unusable because you cannot update the reference count of a const object without casting const away and treading into UB territory. But if const(RefCounted!Object).opHeadConst returned a RefCounted!(const(Object)) instead, then this could be made usable: the payload can now become const while keeping the reference count mutable. Of course, as currently designed, the API is kinda awkward. But that's just a syntactic issue. We could call it instead .headConst, and you'd have: // mutable refcount, mutable payload RefCounted!Object // mutable refcount, const payload (useful) RefCounted!Object.headConst --> RefCounted!(const(Object)) // const refcount, const payload (useless) const(RefCounted!Object) Standardizing .headConst means that we now have a reliable way to construct a RefCounted!(const(Object)) from a RefCounted!Object, whereas currently we can only construct const(RefCounted!Object), which is unusable. In general, this lets us construct a Template!(const(T)) from a Template!T without needing to know what Template is. For example, Template could take multiple parameters, like Template!(x,T), such that the correct head-const is actually Template!(x, const(T)). Generic code can't know this, but if .headConst is standardized, then it provides a way for generic code to create a Template!(x, const(T)) from a Template(x,T) without needing special knowledge of Template's implementation. We could even put a generic .headConst in druntime that implements the conversion for built-in types like int* -> const(int)*. Then .headConst becomes the standard idiom to go from any type T to a head-const version of T. Generic code that relies on .headConst would work for both built-in types and custom user types without any change. Best of all, this doesn't even require a language change, which is a big plus. > At least with immutable, you get implicit sharing and some > optimization opportunities. In principle, const can get you some of > the optimization opportunities but only in really restricted > circumstances or circumstances where you could have used immutable and > the code would have been the same (e.g. with int). [...] I haven't thought through it carefully, but if .headConst is a viable solution to the head-const problem, then conceivably we could also extend it to deal with immutable payloads too. Then we could go from, say, RefCounted!(immutable(T)) to RefCounted!(const(T)) generically, without any casting or breaking the type system. We could potentially expand the scope of usefulness of immutable this way, if this approach turns out to be workable. T -- If Java had true garbage collection, most programs would delete themselves upon execution. -- Robert Sewell
Re: Should the "front" range primitive be "const" ?
On Tuesday, January 30, 2018 07:49:28 H. S. Teoh via Digitalmars-d-learn wrote: > On Tue, Jan 30, 2018 at 08:54:00AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > > On 1/29/18 8:20 PM, Jonathan M Davis wrote: > [...] > > > > If you want to put an attribute on it, inout is better, because then > > > it will work with any constness, but in general, I'd suggest just > > > avoiding the use of const or immutable altogether when dealing with > > > ranges. front can return a const element, and that will happen if > > > you use auto and whatever you're wrapping is const, but const ranges > > > are utterly useless, because they can't be mutated and thus can't be > > > iterated. As such, almost no code is ever going to have a range that > > > is anything but mutable, which means that having front be anything > > > but mutable is generally pointless. > > I think you're conflating a const range, which *is* pretty useless since > you can't iterate it, and a const .front, which only means "calling > .front will not change the state of the range". The latter is very > possible, and potentially useful. Well, there's also a .front that > returns a const element, which means "you can't change the current > element of the range". That's also possible, and useful. Except that unless front returns by ref, it really doesn't matter whether front is const unless it's violating the range API, since front is supposed to return the same value until popFront is called (or if it's assigned a new value via a front that returns by ref). So, in practice, putting const on front really doesn't help you any, and it actually hurts you for range composability. > Simen has had some ideas recently about "head mutable" aka tail-const, > which could be a first step towards making const ranges, or rather > tail-const ranges, actually usable: > > https://forum.dlang.org/post/cpxfgdmklgusodqou...@forum.dlang.org > > tl;dr summary: > > (1) Ranges implement a standard method, tentatively called > opHeadMutable, that returns a head-mutable version of themselves. > For example, const(MyRange!T).opHeadMutable would return > MyRange!(const(T)). > > (2) Standard library functions would recognize opHeadMutable and use it > where needed, e.g., when you hand them a const range. > > (3) Profit. :-P I still need to look over what he's proposing in more detail - it's been proposed before (by Andrei IIRC) that one possible solution would be to add an operator for returning a tail-const version of a type, but no one has ever taken that idea anywhere. Personally, I'm getting to the point that I'd rather just avoid const than deal with any further complications for ranges. In principle, I like the idea of const, but in practice, it just constantly gets in the way, and I've rarely actually seen any benefit from it in either C++ or D. I can think of one time in my entire life where const has prevented a bug for me - which was when I got the arguments backwards to C++'s std::copy function. At least with immutable, you get implicit sharing and some optimization opportunities. In principle, const can get you some of the optimization opportunities but only in really restricted circumstances or circumstances where you could have used immutable and the code would have been the same (e.g. with int). - Jonathan M Davis
Re: How to proceed with learning to code Windows desktop applications?
On Tuesday, 30 January 2018 at 18:41:57 UTC, I Lindström wrote: On Tuesday, 30 January 2018 at 05:56:51 UTC, DanielG wrote: There are far too many options for Windows GUI programming, so we probably need a bit more information about any constraints that are important to you. For example: - do you specifically want something that works well with D? or are you open to other languages? - are you just wanting to learn desktop programming in general? (Like the concepts involved) Or do you have a specific thing you want to create? I would personally suggest Delphi to somebody who wants to write Windows desktop apps and learn about event-driven development, howeverrr the language (Object Pascal) is insufferably archaic compared to something like D. But it is definitely the cleanest, least-overwhelming method of writing native Win32 applications for somebody with no prior experience. Then there's all the modern Microsoft stuff (WPF/XAML/WinRT/etc), but you pretty much have to use either .NET or C++ for that. I have a specific thing I want to create and I could do it in a console but it'd be very clunky to use, but at the moment I need to learn the basic stuff for this. I'd like to use D as I've grown quite fond of it after my earlier attempts at first Perl, then Python, C++ and now D for the past year and a half. For some reason D feels the most... homey and comfortable of the languages I've tried. There is a D GUI library called DlangUI at https://github.com/buggins/dlangui. The README file show some basic examples on how to use it. More demo apps are in the "examples" folder. Looking through those examples can really help. It works on windows and will work on Mac and Linux too. I use it on Linux and its quite impressive. Some people here have used it to develop commercial softwares. I'm in a process of learning and creating a much nicer theme for it. Not much progress for now.
Re: enforce (i > 0) for i = int.min does not throw
On Sunday, 28 January 2018 at 19:17:49 UTC, Steven Schveighoffer wrote: This is insane. i > 0 is used in so many places. The only saving grace appears to be that int.min is just so uncommonly seen in the wild. And another one that it does not happen when compiled with optimization (-O) and also that it does not affect all the ints: --- import std.stdio; void foo (T) () { auto i = T.min; writefln ("%12s: %24X %12s", T.stringof, i, i > cast(T) 0); } void main () { foo!byte; foo!short; foo!int; foo!long; } --- byte: 80false short: 8000false int: 8000 true long: 8000 true In 32 bit mode: byte: 80false short: 8000false int: 8000 true long: 8000false
Re: questions around mutating range algorithms, const, and return ref
On Tuesday, 30 January 2018 at 09:51:18 UTC, Ali Çehreli wrote: > [...] is trying to > [...] It's the same with C++: A type with a const member cannot have a compiler-generated assignment operator. Ok, that made it obvious :) 'const' as a member function attribute is meaningful: It makes the implicit 'this' parameter const. Same as a function parameter attribute in that regard. >>> [...] I can >> [...] as in move >> [...] the >> [...] point. > [...] constructed, > [...] I'm not happy that I can answer that question. At least I opened a bug about some part of the confusion recently. :) https://issues.dlang.org/show_bug.cgi?id=18036 Ali ah, ok. Gotcha, thanks again, Ali.
Re: How to get a range from std.container.array for use with std.format.sformat?
On Tuesday, 30 January 2018 at 18:42:45 UTC, Steven Schveighoffer wrote: On 1/30/18 12:53 PM, cc wrote: import std.container; import std.format; Array!char str; str.length = 256; str.sformat!"%s:%s"("some", "string"); // Error: template std.format.sformat cannot deduce function from argument types !("%s:%s")(Array!char, string, string), candidates are: // std.format.sformat(alias fmt, Args...)(char[] buf, Args args) if (isSomeString!(typeof(fmt))) // std.format.sformat(Char, Args...)(char[] buf, in Char[] fmt, Args args) sformat requires a builtin array, apparently. It doesn't work for other types. For everything else, you can use formattedWrite: ``` import std.array : appender; auto writer = appender!string(); writer.formattedWrite!"%s is the ultimate %s."(42, "answer"); writeln(writer.data); ``` without any GC: ``` /+dub.sdl: dependency "emsi_containers" version="~>0.6.0" +/ import std.format, std.stdio; void main() { import containers; DynamicArray!char arr; arr.formattedWrite!"%s is the ultimate %s."(42, "answer"); printf("%.*s\n", arr.length, arr.ptr); } ``` https://run.dlang.io/is/Taem9j
Re: How to get a range from std.container.array for use with std.format.sformat?
Still doesn't work without the cast it seems.. auto rng = str[]; rng.sformat!"%s:%s"("some", "string"); // Error: template std.format.sformat cannot deduce function from argument types !("%s:%s")(RangeT!(Array!char), string, string)
Re: How to proceed with learning to code Windows desktop applications?
On Tuesday, 30 January 2018 at 12:30:36 UTC, rjframe wrote: VS release builds compile to native now by default; for easy Windows programming, you really can't beat C# and drawing the GUI (Windows Forms, not necessarily the new stuff). If the OP wants to learn what's needed for more complex GUI tasks (like for most non-simple applications), learning to build a GUI from source is kind of necessary though. I've been looking into C# and VS2017 today along with VisualD. Reading through all this it looks like the simplest path is to learn C# and VS and go from there. I've found a pile of courses on LinkedIn that seem to build up to what I need. What makes me sad is that I have to drop D for at least the time being.
Re: How to get a range from std.container.array for use with std.format.sformat?
On 1/30/18 12:53 PM, cc wrote: import std.container; import std.format; Array!char str; str.length = 256; str.sformat!"%s:%s"("some", "string"); // Error: template std.format.sformat cannot deduce function from argument types !("%s:%s")(Array!char, string, string), candidates are: // std.format.sformat(alias fmt, Args...)(char[] buf, Args args) if (isSomeString!(typeof(fmt))) // std.format.sformat(Char, Args...)(char[] buf, in Char[] fmt, Args args) sformat requires a builtin array, apparently. It doesn't work for other types. auto rng = cast(char[]) str[]; // Error: cannot cast expression `str.opSlice()` of type `RangeT!(Array!char)` to `char[]` why not just auto rng = str[]? Additionally, would sformat cause GC allocations even when writing to a preallocated buffer? Not directly. If sformat needs to call a function on what you are asking to format that would use the GC, then it would not be @nogc. -Steve
Re: How to proceed with learning to code Windows desktop applications?
On Tuesday, 30 January 2018 at 05:56:51 UTC, DanielG wrote: There are far too many options for Windows GUI programming, so we probably need a bit more information about any constraints that are important to you. For example: - do you specifically want something that works well with D? or are you open to other languages? - are you just wanting to learn desktop programming in general? (Like the concepts involved) Or do you have a specific thing you want to create? I would personally suggest Delphi to somebody who wants to write Windows desktop apps and learn about event-driven development, howeverrr the language (Object Pascal) is insufferably archaic compared to something like D. But it is definitely the cleanest, least-overwhelming method of writing native Win32 applications for somebody with no prior experience. Then there's all the modern Microsoft stuff (WPF/XAML/WinRT/etc), but you pretty much have to use either .NET or C++ for that. I have a specific thing I want to create and I could do it in a console but it'd be very clunky to use, but at the moment I need to learn the basic stuff for this. I'd like to use D as I've grown quite fond of it after my earlier attempts at first Perl, then Python, C++ and now D for the past year and a half. For some reason D feels the most... homey and comfortable of the languages I've tried.
How to get a range from std.container.array for use with std.format.sformat?
import std.container; import std.format; Array!char str; str.length = 256; str.sformat!"%s:%s"("some", "string"); // Error: template std.format.sformat cannot deduce function from argument types !("%s:%s")(Array!char, string, string), candidates are: // std.format.sformat(alias fmt, Args...)(char[] buf, Args args) if (isSomeString!(typeof(fmt))) // std.format.sformat(Char, Args...)(char[] buf, in Char[] fmt, Args args) auto rng = cast(char[]) str[]; // Error: cannot cast expression `str.opSlice()` of type `RangeT!(Array!char)` to `char[]` Additionally, would sformat cause GC allocations even when writing to a preallocated buffer?
Re: Best Practice: Alternatives to Void Pointers
On Tuesday, 30 January 2018 at 17:41:53 UTC, jsako wrote: So what's considered the best alternative to void pointers in D if you don't want to use objects? Make a tagged Union of all possible datatypes in the struct? Have a Byte array and cast that instead of a void pointer? Some sort of magic involving templates or other metaprogramming mechanisms? https://dlang.org/phobos/std_variant.html -- Simen
Best Practice: Alternatives to Void Pointers
The common C way to get a blob of generic data at runtime is to use void pointers like so: struct Structo { int type; void* data; } Then cast the void pointer to whatever data you needed based on the type. I imagine D has a better mechanism for this sort of thing, but after some searching I couldn't find what is considered "best practice" for this application. The obvious solution is to use objects and have polymorphism solve the problem, but if you want to avoid as much memory dereferencing as possible (say, to avoid cache misses), objects seem a poor choice since they are always reference variables. So what's considered the best alternative to void pointers in D if you don't want to use objects? Make a tagged Union of all possible datatypes in the struct? Have a Byte array and cast that instead of a void pointer? Some sort of magic involving templates or other metaprogramming mechanisms?
Re: rdmd main.d leads to Segmentation fault
On Tuesday, 30 January 2018 at 14:08:35 UTC, Kagamin wrote: On Sunday, 28 January 2018 at 22:02:11 UTC, Timoses wrote: How would I do that? https://forum.dlang.org/post/mailman.39.1510078013.9493.digitalmars-d-...@puremagic.com like this Thanks! I did $ gdb main $ (gdb) set logging on $ (gdb) r $ (gdb) disas Output: https://pastebin.com/raw/SSx0P1Av Helps?
Re: Discarded return values
On Tuesday, 30 January 2018 at 14:01:00 UTC, bauss wrote: unittest { auto a = foo(); // This should fail, because a is never used. No it shouldn't. It is assigned to a variable, as the constraint said. // This should also fail, because b is never used actually used afterwards. auto b = foo() b.morph(); No it shouldn't. It is assigned to a variable, as the constraint said. // This should fail, because d does not use c. // A simply analysis of d will not work, you'll have to track all passed values to d and whether they themselves should be tracked with the attribute. auto c = foo(); d(c); No it shouldn't. It is assigned to a variable, as the constraint said. // Same as above, should fail too since d doesn't use the return value d(foo()); No it shouldn't. It is passed to a function, as the constraint said. } The above is going to be very complex to implement in the compiler. Sure a simple check if it has just been assigned to a variable would work fine, but in the reality people would most likely just do something like this then: auto unused = foo(); And there ... we "hacked" our way around the attribute. Yes, that's the point. Now it's visible that you're discarding the result. The point isn't actually to make sure people keep the variable around - that'd be silly - it's to inform the programmer that potentially important information is discarded, and to stop the programmer from calling mutating functions on a temporary return value where it will have no effect. For pure functions, this gives a warning: auto fun() pure { return 3; } unittest { fun(); // calling without side effects discards return value } Does that in any way whatsoever stop me from assigning the return value to a variable and then ignoring it? No. But doing so would make me an idiot. The compiler suggests I cast it to void if I really intended to discard the result. The reason for this is cast(void) is relatively easy to grep for, and sticks out like a sore thumb when looking through the code. So for it to work it has to track every single return value from a function that implements the attribute and that is borderline impossible to get correct. No it's not. It's *perfectly* impossible the way your scheme works. What does this function do to its parameters? extern(C) void foo(S s); In other words, your idea of perfectly tracking how a value is used cannot be implemented at all. Trying to equate that with what I'm asking is disingenuous. -- Simen
Re: Should the "front" range primitive be "const" ?
On Tue, Jan 30, 2018 at 08:54:00AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 1/29/18 8:20 PM, Jonathan M Davis wrote: [...] > > If you want to put an attribute on it, inout is better, because then > > it will work with any constness, but in general, I'd suggest just > > avoiding the use of const or immutable altogether when dealing with > > ranges. front can return a const element, and that will happen if > > you use auto and whatever you're wrapping is const, but const ranges > > are utterly useless, because they can't be mutated and thus can't be > > iterated. As such, almost no code is ever going to have a range that > > is anything but mutable, which means that having front be anything > > but mutable is generally pointless. I think you're conflating a const range, which *is* pretty useless since you can't iterate it, and a const .front, which only means "calling .front will not change the state of the range". The latter is very possible, and potentially useful. Well, there's also a .front that returns a const element, which means "you can't change the current element of the range". That's also possible, and useful. > Not necessarily. A main reason for const is to advertise "I'm not > going to change your mutable data" on a function. So reading that > front is const (or inout more appropriately) can assure you front > makes this guarantee. > > Yes, it also allows you to call on an immutable or const range, both > of which are for the most part useless. > > So I would say const ranges are useless, but const members of ranges > provide some value. > > That being said, const is viral, as is inout. So unfortunately if you > *don't* mark your functions const or inout, then wrappers need to take > this into account. [...] Simen has had some ideas recently about "head mutable" aka tail-const, which could be a first step towards making const ranges, or rather tail-const ranges, actually usable: https://forum.dlang.org/post/cpxfgdmklgusodqou...@forum.dlang.org tl;dr summary: (1) Ranges implement a standard method, tentatively called opHeadMutable, that returns a head-mutable version of themselves. For example, const(MyRange!T).opHeadMutable would return MyRange!(const(T)). (2) Standard library functions would recognize opHeadMutable and use it where needed, e.g., when you hand them a const range. (3) Profit. :-P T -- In a world without fences, who needs Windows and Gates? -- Christian Surchi
Re: How to proceed with learning to code Windows desktop applications?
On Monday, 29 January 2018 at 22:55:12 UTC, I Lindström wrote: Hello all! I've been doing console apps for about a year and a half now, but my requirements are reaching the limits of easy to use with ASCII-based UI and typed commands so I'm thinking of moving into GUI-era with my projects. I was wondering if some one could help me into the right direction. I've been Googling a ton these past few days for some kind of a book or a course on how to code desktop applications for Windows, but either there isn't one, or it's very well hidden. I've found bits and pieces but nothing to give me a coherent approach. The other way I've been thinking is to do the thing browser-based, but for some reason that doesn't feel right. You may have a look at Delta https://forum.dlang.org/post/hpodoabutuakfxbzz...@forum.dlang.org It is a solution to write a gui application using all the benefits Embarcadero Delphi RAD Studio gives you, while all of your coding is written in D. Kind regards Andre 13
Re: inline @trusted code
On Tuesday, 30 January 2018 at 15:05:38 UTC, ikod wrote: Hello, Several times I faced with next problem: I have "@safe" routine with few calls to @system functions inside: OS calls (recv, send, kqueue) os some phobos unsafe functions like assumeUnique. I'd like not to wrap these @system functions in @trusted wrappers, but somehow mark these calls @trusted inline. In ideal case this should look like import std.exception; void main() @safe { ubyte[] a; @trusted { auto b = assumeUnique(a); }; } But the closest variant is import std.exception; void main() @safe { ubyte[] a; delegate void() @trusted { auto b = assumeUnique(a); }(); } Which looks a bit verbose. How do you solve this problem? Thanks! ubyte[] a; auto b = (() @trusted => assumeUnique(a))();
inline @trusted code
Hello, Several times I faced with next problem: I have "@safe" routine with few calls to @system functions inside: OS calls (recv, send, kqueue) os some phobos unsafe functions like assumeUnique. I'd like not to wrap these @system functions in @trusted wrappers, but somehow mark these calls @trusted inline. In ideal case this should look like import std.exception; void main() @safe { ubyte[] a; @trusted { auto b = assumeUnique(a); }; } But the closest variant is import std.exception; void main() @safe { ubyte[] a; delegate void() @trusted { auto b = assumeUnique(a); }(); } Which looks a bit verbose. How do you solve this problem? Thanks!
Re: How to proceed with learning to code Windows desktop applications?
On Monday, 29 January 2018 at 22:55:12 UTC, I Lindström wrote: I've been Googling a ton these past few days for some kind of a book or a course on how to code desktop applications for Windows, but either there isn't one, or it's very well hidden. "Programming Windows" by Charles Petzold, 5th edition, 1998, The definitive developer's guide to the Windows 98 API. The book goes through the classic application development cycle and explanation of features.
Re: How to proceed with learning to code Windows desktop applications?
On Tuesday, 30 January 2018 at 05:47:11 UTC, thedeemon wrote: It's like saying "everything you need is assembly language" when talking about languages and compilers. Pure WinAPI is a cruel advice for a novice. He's not a novice: he wrote console applications that pushed through complexity limit. Writing complex GUI application in winapi is cruel, but for hello world it's fine and gives good understanding of principles. To use GUI frameworks one must understand both underlying principles and abstractions rolled on top of them.
Re: rdmd main.d leads to Segmentation fault
On Sunday, 28 January 2018 at 21:41:39 UTC, Timoses wrote: Got it from here: http://d-apt.sourceforge.net/ with $ apt-get install dmd-compiler Sometimes such crashes can be caused by files left from previous installation. Or maybe confusion between gdc and dmd files.
Re: rdmd main.d leads to Segmentation fault
On Sunday, 28 January 2018 at 22:02:11 UTC, Timoses wrote: How would I do that? https://forum.dlang.org/post/mailman.39.1510078013.9493.digitalmars-d-...@puremagic.com like this
Re: Discarded return values
On Tuesday, 30 January 2018 at 10:49:54 UTC, Simen Kjærås wrote: Is there a way to get a compile error when returning a temporary from a function and then not assigning it to a variable or passing it to a different function? E.g: struct S { int[] a; void morph() {} } @warnOnDiscard S foo() { return S([1,2,3]); } unittest { auto a = foo(); // Fine, assigned to variable. bar(foo()); // Fine, passed to other function. foo(); // Error: return value is discarded. foo().morph(); // Error: return value is discarded. } I know that pure functions give errors when their results are discarded, but in this case foo() might not be pure. -- Simen On top of what's said. It would be very complex to implement properly. For example the following should fail, but will be very hard for the compiler to actually track. struct S { int[] a; void morph() {} } @warnOnDiscard S foo() { return S([1,2,3]); } void d(S s) { } unittest { auto a = foo(); // This should fail, because a is never used. // This should also fail, because b is never used actually used afterwards. auto b = foo() b.morph(); // This should fail, because d does not use c. // A simply analysis of d will not work, you'll have to track all passed values to d and whether they themselves should be tracked with the attribute. auto c = foo(); d(c); // Same as above, should fail too since d doesn't use the return value d(foo()); } The above is going to be very complex to implement in the compiler. Sure a simple check if it has just been assigned to a variable would work fine, but in the reality people would most likely just do something like this then: auto unused = foo(); And there ... we "hacked" our way around the attribute. So for it to work it has to track every single return value from a function that implements the attribute and that is borderline impossible to get correct.
Re: Should the "front" range primitive be "const" ?
On 1/29/18 8:20 PM, Jonathan M Davis wrote: On Tuesday, January 30, 2018 01:05:54 Drone1h via Digitalmars-d-learn wrote: Hello all, I am trying to implement a ("struct template" ? what is the correct word ?) range that just forwards its primitives ("empty", "front", "popFront") to another range, possibly with some very limited filtering/alteration, as std.range.Take (just to learn). Initially, the "front" member function (property) used to be declared "const", but that was not accepted when the underlying range (denoted "R" in the code below) was std.stdio.File.ByChunk ("Error: mutable method std.stdio.File.ByChunk.front is not callable using a const object"). Is there any value in having the "front" range primitive declared to be a "const" member function ? And if so, is the following implementation okay ? Could it be further simplified ? struct Taker (R) { private R _r; ... static if (functionAttributes ! (R.front) & FunctionAttribute.const_) public @property auto front () const { return _r.front; } else public @property auto front () { return _r.front; } ... } Thank you respectfully ! Drone1h If you want to put an attribute on it, inout is better, because then it will work with any constness, but in general, I'd suggest just avoiding the use of const or immutable altogether when dealing with ranges. front can return a const element, and that will happen if you use auto and whatever you're wrapping is const, but const ranges are utterly useless, because they can't be mutated and thus can't be iterated. As such, almost no code is ever going to have a range that is anything but mutable, which means that having front be anything but mutable is generally pointless. Not necessarily. A main reason for const is to advertise "I'm not going to change your mutable data" on a function. So reading that front is const (or inout more appropriately) can assure you front makes this guarantee. Yes, it also allows you to call on an immutable or const range, both of which are for the most part useless. So I would say const ranges are useless, but const members of ranges provide some value. That being said, const is viral, as is inout. So unfortunately if you *don't* mark your functions const or inout, then wrappers need to take this into account. -Steve
Re: How to proceed with learning to code Windows desktop applications?
On Monday, 29 January 2018 at 22:55:12 UTC, I Lindström wrote: The other way I've been thinking is to do the thing browser-based, but for some reason that doesn't feel right. Ironically the trick for native programming is to depend on the OS as less as possible, with a small "API surface".
Re: How to proceed with learning to code Windows desktop applications?
On Tue, 30 Jan 2018 05:56:51 +, DanielG wrote: > Then there's all the modern Microsoft stuff (WPF/XAML/WinRT/etc), > but you pretty much have to use either .NET or C++ for that. VS release builds compile to native now by default; for easy Windows programming, you really can't beat C# and drawing the GUI (Windows Forms, not necessarily the new stuff). If the OP wants to learn what's needed for more complex GUI tasks (like for most non-simple applications), learning to build a GUI from source is kind of necessary though. If/when .NET Core becomes something people can rely on and are willing to try, I think we'll see more people using C# outside the enterprise; you get easy when you want it, power when you need it, native code generation on Windows, and OS portability.
Re: Discarded return values
On Tuesday, 30 January 2018 at 11:36:25 UTC, Jonathan M Davis wrote: [nope] Thanks. It's what I thought, though not what I wanted. IIRC, the Weka guys wanted to be able to have attributes tell the compiler stuff so that it could yell at the programmer when appropriate, so I think that there is some interest in this area, but I have no idea how such a thing would be implemented. New built-in attributes that warn about specific stuff could certainly be added, but in each case, there would have to be a solid enough argument as to why it was worth adding that further complication to the language. I have no idea what the chances of being accepted would be for a DIP specifically for an attribute to warn if the return value is ignored, but you can certainly create such a DIP if you feel strongly enough about it and feel that you can argue it well. It's been on my mind for years, so it probably will happen eventually. Can't promise this is the year, though. -- Simen
Re: Discarded return values
On Tuesday, January 30, 2018 10:49:54 Simen Kjærås via Digitalmars-d-learn wrote: > Is there a way to get a compile error when returning a temporary > from a function and then not assigning it to a variable or > passing it to a different function? E.g: > > struct S { > int[] a; > void morph() {} > } > > @warnOnDiscard > S foo() { > return S([1,2,3]); > } > > unittest { > auto a = foo(); // Fine, assigned to variable. > bar(foo()); // Fine, passed to other function. > foo(); // Error: return value is discarded. > foo().morph(); // Error: return value is discarded. > } > > I know that pure functions give errors when their results are > discarded, but in this case foo() might not be pure. Well, the first problem is that you simply can't warn or give an error about that if the function isn't pure, because if it isn't pure, then it could be doing work, and it might be perfectly okay for the return value to be ignored. So, while it might make sense for some functions, it wouldn't make sense for others, and unless it never makes sense to ignore the return value, the compiler can't reasonably warn about it. Having an attribute that tells the compiler that it's not okay to ignore the return value for that specific function could solve that problem, because it would give the programmer a way to tell the compiler that that particular function is not doing work such that it's reasonable to ignore the return value, but that brings up the second problem which is that no such attribute exists and that there is no way to create attributes to tell the compiler to warn about something. UDAs are simply there to be used by code introspection done by user code. The compiler itself doesn't do anything interesting with them. So, in order to get something like that, a DIP would be required. IIRC, the Weka guys wanted to be able to have attributes tell the compiler stuff so that it could yell at the programmer when appropriate, so I think that there is some interest in this area, but I have no idea how such a thing would be implemented. New built-in attributes that warn about specific stuff could certainly be added, but in each case, there would have to be a solid enough argument as to why it was worth adding that further complication to the language. I have no idea what the chances of being accepted would be for a DIP specifically for an attribute to warn if the return value is ignored, but you can certainly create such a DIP if you feel strongly enough about it and feel that you can argue it well. - Jonathan M Davis
Discarded return values
Is there a way to get a compile error when returning a temporary from a function and then not assigning it to a variable or passing it to a different function? E.g: struct S { int[] a; void morph() {} } @warnOnDiscard S foo() { return S([1,2,3]); } unittest { auto a = foo(); // Fine, assigned to variable. bar(foo()); // Fine, passed to other function. foo(); // Error: return value is discarded. foo().morph(); // Error: return value is discarded. } I know that pure functions give errors when their results are discarded, but in this case foo() might not be pure. -- Simen
Re: Question about std.conv.parse
On Tuesday, 30 January 2018 at 09:29:22 UTC, Jonathan M Davis wrote: On Tuesday, January 30, 2018 09:19:22 Jacky via Digitalmars-d-learn wrote: [...] The first one passes an lvalue. The second one passes an rvalue. parse takes its argument by ref so that what is parsed is removed from the input. As such, it requires an lvalue. [...] You don't. parse requires that you pass it a variable. std.conv.to does not take its argument by ref, so you can use that instead, but it converts the entire argument instead of just the front portion that matches the requested type. So, if you're trying to convert the entire argument, then you can use to, but if you're trying to just convert the front, then you have to use parse, and that means passing a variable. - Jonathan M Davis Thank you very much!I think i should dig deeper into this interesting language. :)
Re: questions around mutating range algorithms, const, and return ref
On 01/30/2018 12:17 AM, aliak wrote: > So if a struct has a struct that has any member const, then effectively > that whole struct is a const (well immutable it seems, so not even > const)? No, it cannot be assigned but the other parts of the object can be mutated. > Is that really correct? What is this sorcery? If yes I find it > very surprising, but I don't think I'm very clear on what D is trying to > solve with const ... yet. It's the same with C++: A type with a const member cannot have a compiler-generated assignment operator. > I find const a little hard to swallow so far. From what I understand, > it's good for function parameters, and as a function attribute for > functions that return temporaries, except don't use it with ranges (i.e. > don't put it on front). Actually not sure about function attributes on > second thought. So... function parameters and local variables that you > know won't change is what I'm going to go with for now. 'const' as a member function attribute is meaningful: It makes the implicit 'this' parameter const. Same as a function parameter attribute in that regard. >>> Also hasMobileElements!(const int[]) is true, so that means I can >>> move elements around right? >> >> hasMobileElements checks if the value of front can be moved as in move >> constructors, not as in 'can be moved to a different spot in the >> range'. I will admit the name does little to unconfuse this point. > > I'm not following here :s If value of front can be move constructed, > then something can take it's place no? I'm not happy that I can answer that question. At least I opened a bug about some part of the confusion recently. :) https://issues.dlang.org/show_bug.cgi?id=18036 Ali
Re: Question about std.conv.parse
On Tuesday, January 30, 2018 09:19:22 Jacky via Digitalmars-d-learn wrote: > Hello everyone.I'm a newbie on the D language.When i use the > library 'std.conv' ,i met some problem. > This is what I have: > > static import std.conv; > string aaa = "123456789"; > uint idx = 5; > string bbb = aaa[0 .. idx]; > > uint work = std.conv.parse!(uint)(bbb); // this works > > uint didnotwork = std.conv.parse!(uint)(aaa[0 .. idx]); > //but here's a error > //template std.conv.parse cannot deduce function from > argument types !(uint)(string) > > So my questions are: > 1) What is the difference between these two lines? The first one passes an lvalue. The second one passes an rvalue. parse takes its argument by ref so that what is parsed is removed from the input. As such, it requires an lvalue. > 2) How to correct the second without assign a new variable? You don't. parse requires that you pass it a variable. std.conv.to does not take its argument by ref, so you can use that instead, but it converts the entire argument instead of just the front portion that matches the requested type. So, if you're trying to convert the entire argument, then you can use to, but if you're trying to just convert the front, then you have to use parse, and that means passing a variable. - Jonathan M Davis
Question about std.conv.parse
Hello everyone.I'm a newbie on the D language.When i use the library 'std.conv' ,i met some problem. This is what I have: static import std.conv; string aaa = "123456789"; uint idx = 5; string bbb = aaa[0 .. idx]; uint work = std.conv.parse!(uint)(bbb); // this works uint didnotwork = std.conv.parse!(uint)(aaa[0 .. idx]); //but here's a error //template std.conv.parse cannot deduce function from argument types !(uint)(string) So my questions are: 1) What is the difference between these two lines? 2) How to correct the second without assign a new variable? Cheers, Jacky
Re: questions around mutating range algorithms, const, and return ref
On Monday, 29 January 2018 at 13:55:04 UTC, Seb wrote: On Monday, 29 January 2018 at 11:36:26 UTC, aliak wrote: On Monday, 29 January 2018 at 06:46:26 UTC, Ali Çehreli wrote: I think the following trivial wrapper around std.algorithm.remove() should do: void removeMatching(R, N)(ref R r, N needles) { import std.algorithm : remove, canFind; r = r.remove!(e => needles.canFind(e)); } Haha awesome! Yes that's much better :) Note to self: learn to scroll down in the docs to find other definitions. I was convinced that remove only acted on indices :p Not too hard to fix: https://github.com/dlang/phobos/pull/6090 Nice! :D
Re: questions around mutating range algorithms, const, and return ref
On Monday, 29 January 2018 at 12:10:16 UTC, Simen Kjærås wrote: Consider this case: immutable(int)[] a = [1,2,3]; immutable(int)* b = &a[1]; You're free to slice the array or pop elements off its front or back, but if you change the order of elements, the value that b points to will change. D does not allow this. You can create a new array with the elements moved into the locations you want, and with another layer of indirections (int*[]) you can move the elements of the array without mutating the values. Ooh my... yes I can understand that. And I guess immutable is implicitly convertible to const and then if you can move const stuff then you have that problem. From the FAQ, my general understanding is that const is there as a bridge from immutable to mutable as a promise that the memory under this symbol will not be altered by that reference. While experimenting a bit I came across this though which, currently, I do understand that value of struct Int { const int value; } void main() { Int i0 = Int(0); Int i1 = Int(1); Int i2 = Int(2); Int[3] arr0 = [i0, i1, i2]; Int[] arr1; arr1 ~= i0; arr1 ~= i1; arr1 ~= i2; arr1[0] = i0; // nope, Error: cannot modify struct arr1[0] Int with immutable members } So if a struct has a struct that has any member const, then effectively that whole struct is a const (well immutable it seems, so not even const)? Is that really correct? What is this sorcery? If yes I find it very surprising, but I don't think I'm very clear on what D is trying to solve with const ... yet. I find const a little hard to swallow so far. From what I understand, it's good for function parameters, and as a function attribute for functions that return temporaries, except don't use it with ranges (i.e. don't put it on front). Actually not sure about function attributes on second thought. So... function parameters and local variables that you know won't change is what I'm going to go with for now. Also hasMobileElements!(const int[]) is true, so that means I can move elements around right? hasMobileElements checks if the value of front can be moved as in move constructors, not as in 'can be moved to a different spot in the range'. I will admit the name does little to unconfuse this point. I'm not following here :s If value of front can be move constructed, then something can take it's place no? Thank you!