Re: How often I should be using const? Is it useless/overrated?
On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear wrote: A question I have been thinking about whilst using D is how often I should be using const. Many people claim that all variables should be const by default, but whether or not it is really needed is debatable and oftentimes making everything const could cause readability issues and make the code more complex. I also wonder how important const really is, like 99% of the time you will know when your variable will be changed, and even when a variable changes it's not like it is the end of the world. Also, there is no real end to how much variables can be const. Oftentimes -- interestingly -- in popular repos I don't even see const being used, this is what confuses me. As a newcomer, I'd be interested in hearing everyones thoughts. IMHO and besides other insights in previous replies, in practice this depends on whether you're talking about private implementation code, or an external interface -- of a library, component/unit (under test), etc. In private implementation code, including your scripts, informal code for personal use etc. you should probably not bother more than needed. It's fine that other languages (functional or safety-paranoid) force const or immutable by default, it's fine that D doesn't. Go with the least verbose default for this kind of code. For external interfaces, be mindful that everything that should not be mutated across them, is annotated as const, since languages D or C++ provide this facility. Otherwise you'd have to rely and unsafely trust on naming conventions like Python.
Can't assign extern(C) function pointer to D variable?
I was surprised when it didn't compile, though I immediately found it understandable... Already read through https://dlang.org/spec/interfaceToC.html and https://wiki.dlang.org/Bind_D_to_C Is it really the case (that an extern(C) function pointer cannot be assigned to a D variable)? Or is it a matter of annotating with the right attributes? If so, how? Otherwise I'm interested in the best or most concise workaround. Is there a better one? I came up with a template solution: https://github.com/XavierAP/game-king/blob/master/source/scope_cleanup.d The problem I had was that this ScopeCleanup struct could not be constructed passing a pointer to a function imported from C (from the SDL library; you can browse around the same repo to see its usage; it's just a toy project that's barely started).
Re: Can't assign extern(C) function pointer to D variable?
On Tuesday, 22 November 2022 at 21:32:43 UTC, Hipreme wrote: You need to create an alias containing your callback type. Thanks both!! I have all the pieces of the puzzle. I'm actually staying with the wrapping template solution. (Because the strongly typed one turns out too convoluted, and because it allows the remaining ScopeCleanup struct to be more general purpose, for non-C functions, and for functions that don't return void but an error code which I want to discard.) The first problem was indeed that a C function pointer "is not" a D one. So annotating the variable with extern(C) can indeed solve it. I had actually tried this, but it was not compiling for another reason. The next reason (as you see in the GitHub link) is that the variable in question is a (constructor) parameter. D can't seem to compile extern(C) inlined somewhere else. Indeed aliasing takes care of this second problem: alias CFunction = extern(C) void function(); /// RAII object that does nothing but calling, when destructed, the function passed at construction. struct ScopeCleanup { @disable this(); this(CFunction cleanup) { this.cleanup = cleanup; } ~this() { cleanup(); } CFunction cleanup; } Now this module compiles. BUT the code trying to call this constructor doesn't compile, when called with C function such as SDL_Quit imported from the SDL lib, or IMG_Quit imported from the SDL_image lib. From the compiler error I learn that the imported function is not only extern(C) but also nothrow @nogc. Fair enough, I add it to the alias. BUT still no good, because (as I learn from the same compiler error) this binding imports these functions as extern(C) void function() nothrow @nogc* with this final "*" this turns out, from the D point of view, a "pointer to a function pointer" XD so it has to be called/de-referenced in this way (in destructor): alias CFunctionPtr = extern(C) void function() nothrow @nogc*; /// RAII object that does nothing but calling, when destructed, the function passed at construction. struct ScopeCleanup { @disable this(); this(CFunctionPtr cleanup) { this.cleanup = cleanup; } ~this() { (*cleanup)(); } CFunctionPtr cleanup; } Thanks guys for the learning, I'm staying with the template solution (thanks D), but let me know if you have more insights.
Re: Any easy way to check if an object have inherited an interface?
On Monday, 22 July 2019 at 21:34:18 UTC, solidstate1991 wrote: It seems that I've to write my own function that searches in the given object's classinfo.interfaces since I couldn't find anything related in Phobos. Do you mean...? interface I {} class C : I {} void main() { C c1; writeln(is(typeof(c1) : I)); } No need for Phobos, core language: https://dlang.org/spec/expression.html#IsExpression https://dlang.org/spec/declaration.html#Typeof
Re: Is it possible to disallow import for certain functions?
On Saturday, 27 July 2019 at 11:54:09 UTC, BoQsc wrote: I would like to make sure that function in module that I have won't be imported, is this possible to achieve? In general, make the function private. But indeed, on your case, it is a terrible idea to define a main() function in a module that you plan to import. Move it out into its own main module.
Re: 1 new
On Friday, 2 August 2019 at 18:25:28 UTC, jmh530 wrote: When I navigate to https://forum.dlang.org/ I have a message that says "1 new reply" to "your posts." Normally, I click on that "1 new reply" and find the post that's new, go to it, and the message disappears. However, it doesn't seem to go away anymore. I tried looking at many different old posts without luck. At one point it was up to "2 new replies," but I viewed that other post and it went back down to "1 new reply." Does anyone else have this? For me everything seems to work OK.
Re: How do I execute a sql-file inside D code
On Tuesday, 20 August 2019 at 11:33:33 UTC, Anders S wrote: Use this code to check conn.exec("CREATE DATABASE IF NOT EXISTS boxweb;"); however haven't found a way to run the sql file that create the tables. The file is in the source folder I understand you're using some API to some SQL implementation which allows you to run SQL commands from strings, but not from files which is what you want? Just read the file into a string with the D std lib: import std:file; conn.exec( readText(fileName) ); https://dlang.org/phobos/std_file.html#.readText
Re: Is removing elements of AA in foreach loop safe?
On Thursday, 29 August 2019 at 10:11:58 UTC, berni wrote: Iterating of some structure and removing elements thereby is always errorprone and should be avoided. But: In case of AA, I've got the feeling, that it might be safe: foreach (k,v;ways) if (v.empty) ways.remove(k); Do you agree? Or is there a better way to achieve this? It compiles and it runs without throwing any RangeError... So it appears to be safe. Otherwise it'd be a bug that there's not error.
Re: Is removing elements of AA in foreach loop safe?
On Thursday, 29 August 2019 at 10:11:58 UTC, berni wrote: Do you agree? Or is there a better way to achieve this? An alternative would be to reassign the AAA to the output of std.algorithm.filter()... but assignment between AAs and Ranges isn't so type-direct.
Re: Auto keyword and when to use it
On Monday, 20 August 2018 at 17:52:17 UTC, QueenSvetlana wrote: So I can't declare class level variables with auto, correct? only local method variables? One difference between D's auto and C#'s var or C++'s auto is that the latter languages allow automatically typed declarations only for local (method/function-scope) variables, and forbid them for class or struct member variables (aka fields); whereas D allows auto anywhere (even function/method return type! -- which C# and C++ allow as well but only case of anonymous methods/lambdas). I'm in favor of the AAA ("Auto" Almost Always) paradigm, but as long as the type if obvious to a human reader. I don't favor them for numeric types for this reason (non obvious bitsize, signedness...) It's up to each programmer. Only if someone likes "Type x = new Type()" instead of "auto x = new Type()" I would say they're clearly wrong.
Re: Auto keyword and when to use it
On Tuesday, 21 August 2018 at 21:37:00 UTC, QueenSvetlana wrote: I had a misunderstanding about the keyword auto because I wrongfully believed that it made the code like Python Exactly, you are thinking still like D is Python or also dynamically typed. :) You will get when compiling errors that Python wouldn't detect until run-time (or with your private methods). - A declaration with auto needs to include an initialization. - The code will be equivalent as if replacing "auto" with the inferred type. It is not left for later to check. I'm not terribly bothered btw by "Type = new Type()" but often type names get too long or include namespaces... "mylib.numeric.squareObjectWithPointyCorners = new mylib.numeric.squareObjectWithPointyCorners()"
Templated operator overloading
I've been trying some things to template operator overloads. The reason is that I want very similar code for different types, but I can't use polymorphism, as they're structs rather than classes. Perhaps this choice is not as advantageous as I think, and I may change this design from structs to classes, or else the code duplication would be small and never subject to change. But now I'm just trying for the sake of learning to find out what works or not in terms of templated operator overloading, and whether the reason something doesn't work is by design and if mentioned in the specification, or just an arbitraty result of some unspecified parsing/lowering step order, or it depends on the compiler (I'm using dmd). Since there are in my case two similar types (below just a minimal dumb proof of concept), I want the operator(s) to work within the same type, or also with the other. The following code actually works, including type parameter inferrence, and const ref to avoid struct copying: // import std.stdio; struct S1 { void opOpAssign(string op, T)(const ref T x) { writeln(this, op, x); } } struct S2 {} void main() { S1 s1; S2 s2; s1 *= s2; } // When I want to have the same operator overloading code in both types however, I can't make it work: // private mixin template operator(Tthis) { void opOpAssign(string op, T)(ref Tthis, const ref T x) { writeln(this, op, x); } } struct S1 { mixin operator!S1; } struct S2 { mixin operator!S2; } void main() { S1 s1; S2 s2; s1 *= s2; // Error: s1 *= s2 is not a scalar s1.opOpAssign!"*"(s2); // Error: template test.S1.operator!(S1).opOpAssign cannot deduce function } // And a final try with a global templated function instead of a mixin template: // private void opOpAssign(string op, Tthis, T)(ref Tthis that, const ref T x) { writeln(that, op, x); } struct S1 {} struct S2 {} void main() { S1 s1; S2 s2; s1 *= s2; // Error: s1 *= s2 is not a scalar s1.opOpAssign!"*"(s2); // OK! } //
Re: Templated operator overloading
On Wednesday, 22 August 2018 at 13:20:01 UTC, aliak wrote: "void opOpAssign(string op, T)(ref Tthis, const ref T x)" looks like the wrong signature for opOpAssign. Oh I'll put on my stupid hat now... I realize I had copy-pasted the wrong syntax from the global function attempt, but I swear I thought I had re-typed and tested the right one... It's working now :)
Re: Templated operator overloading
On Wednesday, 22 August 2018 at 12:36:39 UTC, Simen Kjærås wrote: Since both your opOpAssigns match equally, the compiler throws up. The solution is to add some sort of restriction: This doesn't happen apparently: the operator has a left and a right side, even if both types define the operator, only one of them is on the left at each call. It works now after Ali corrected my stupid syntax :)
Nested template arguments
Why foo!bar!x is not understood as foo!(bar!x) but instead gives an error "multiple ! arguments are not allowed"? Precisely because multiple "!" can never belong to the same instantiation, why does the parser not understand without needing brackets that the rightmost template should be nested as the argument for the next one to the left?
Re: Nested template arguments
On Wednesday, 22 August 2018 at 14:48:57 UTC, Alex wrote: Because it could be meant as the argument to some templates to the left. Like (foo!bar)!x Sure, it would be a coincidence, if both will work. However, templates are not something where you can simply imply the associative property, I think. Of course there isn't an associative property... But I was thinking that without brackets the parser could fall back to whatever default "left to right" precedence, as would happen with operators, which needn't be associative either.
Re: Doubt about this book: The D Programming Language
On Sunday, 16 December 2018 at 18:37:15 UTC, Marko wrote: On Amazon The D Programming Language has good reviews but it's 8 years old. So is this book still relevant today? Yes, I would recommend it. It is meant to be comprehensive but introductory, so many language or library changes since are out of the scope anyway. It's then also quite different from a cookbook approach for example -- depends what you're looking for. You may perhaps compare it more closely with Ali's book, but unfortunately I haven't read this one.
Return Value Optimization: specification, requirements?
I've heard here and there that D guarantees RVO, or is even specified to do so... Is it spelled out in the language specification or elsewhere? I haven't found it. Do you know the exact requirements for RVO or NRVO to be possible in theory, and to be guaranteed in practice in D? Does it depend only on what is returned, or does it depend how it's constructed? I know I can debug to find out case by case, but that's the kind of C++ stuff I want to avoid... I want to know the theory/norm/spec. Thanks
Re: static arrays at runtime with templates ?
On Sunday, 3 February 2019 at 16:33:48 UTC, Emil wrote: Is this for real, static arrays at runtime without manually allocating memory ? Is this legitimate or should I expect problems ? Static arrays are always allocated at run-time. It's the size of the array that must be known at compile-time (in this case via a template parameter). What's the advantage (or the essential difference) of auto data = static_array!(int, 5); instead of int[5] data; ? Just asking ;) but it's good to play. What does not compile on my end are the run-time parameters (3) and (2)...?
Re: static arrays at runtime with templates ?
On Monday, 4 February 2019 at 19:14:38 UTC, Emil wrote: Can std.array.staticArray build static arrays with size known only at run time ? Now that I am not overcome with enthousiasm it looks like it too needs to know the size. A static array's size must be known (or computed) at compile time, by definition... There can be no exception; staticArray() gets or infers the size from its template/compile-time arguments. For one, the trivial example on dlang.org/phobos auto a = [0, 1].staticArray; static assert(is(typeof(a) == int[2])); is equivalent to int[2] a = [0, 1]; static assert(is(typeof(a) == int[2])); Is it better? Depends on.? No it really isn't... However one of the possibilities of D is the ability to generate and execute quite some code at compile time by means of meta-programming; and I guess here's where staticArray() may end up being useful enough to have merited introduction into the std library; not for trivial uses where a straightforward T[n] declaration is preferable, being possible... If there is something you want to solve in a program of yours, there may be another way, as H.S. Teoh suggests. If you're just trying out stuff it's also fine, :) there's still more.
Re: Best practices of using const
On Wednesday, 13 February 2019 at 11:32:46 UTC, envoid wrote: Is there an article that explains best practices of using const in D? Chapter 8 of Andrei Alexandrescu's book The D Programming Language.
Re: Distinguish float and integer types from string
On Saturday, 9 March 2019 at 18:11:09 UTC, Jacob Shtokolov wrote: One of the task was to take a string from STDIN and detect its type. There were a few options: Float, Integer, string and "something else" (which, I think, doesn't have any sense under the scope of the task). Another std-based solution I came up with: bool isInteger(string str) { if(str.isNumeric) { try { return str.to!long == str.to!real; } catch(ConvException) { return false; } } else return false; } I tried to use std.conv.to and std.conv.parse, but found that they can't really do this. When I call `data.to!int`, the value of "123.45" will be converted to int! What compiler version are you using? I on the other hand was surprised that I needed the try-catch above, after having already checked isNumeric. The documentation claims that the conversion to int or long would truncate, but my compiler (v2.084.0) throws instead.
Re: Distinguish float and integer types from string
On Monday, 11 March 2019 at 15:03:39 UTC, XavierAP wrote: What compiler version are you using? I on the other hand was surprised that I needed the try-catch above, after having already checked isNumeric. The documentation claims that the conversion to int or long would truncate, but my compiler (v2.084.0) throws instead. Of course now I realize that using try-catch I no longer need to check isNumeric... My design didn't use try-catch but I had to add it because std.conv:to behaves differently from the documentation: https://dlang.org/phobos/std_conv.html#to Not sure if I need to update my DMD, or it's the documentation that's out of date, or something else is wrong.
Re: Poor regex performance?
On Thursday, 4 April 2019 at 09:53:06 UTC, Julian wrote: Relatedly, how can I add custom compiler flags to rdmd, in a D script? For example, -L-lpcre Configuration variable "DFLAGS". On Windows you can specify it in the sc.ini file. On Linux: https://dlang.org/dmd-linux.html
Re: What Does @ Mean?
On Monday, 8 April 2019 at 11:58:49 UTC, Ron Tarrant wrote: And while I'm asking, does an underscore have special meaning when used either at the beginning or end of a variable name? In D, @ is used as Adam has explained as a prefix indicating attributes (either user-defined ones or, confusingly enough, some of the standard ones). The only other example of language using @, in an almost but not quite completely different way, is C#. It's also a prefix that allows you to define names that would collide with reserved words, for example string @class = "menu"; Of course you should never do this unless you absolutely need for interop. Underscore prefixes are used in some languages by pure user convention mainly for private members (fields), to avoid name clashing. For example in D you could have a public property length and a private member _length. Python takes this a step further. Since it supports classes but no public/private visibility at all, users and IDEs have convened to use (one or two) underscore prefixes to signal members that aren't meant to be accessed publicly from outside the class, even if there's nothing stopping you (besides auto code completion not showing them). For C and C++ the convention (recognized by the standards) is different: names prefixed by any number of underscores are all reserved; basically because the global namespace is so badly polluted already. In this case I've seen some other annoying conventions, for example private member variables being prefixed with m_
Re: Are static variables available to other static variables?
On Friday, 12 April 2019 at 10:56:32 UTC, Jamie wrote: On Friday, 12 April 2019 at 10:49:19 UTC, Jamie wrote: I was trying to declare a static variable dependent on another static variable, but it didn't work. Are static variables not known to other static variables at compile time? void main() { C c = new C(); } class C { static size_t A = 2; static size_t B = 2^^A; // A is not known at compile time } Ok I'm confused... why does that above not work but this does: void main() { C c = new C(); } class C { static size_t A = 2; static size_t B; static this() { B = 2^^A; } } May this be a bug? Static mutable is a theoretically valid use case. It looks to me that D often optimizes by evaluating at compile time. But in this case what is a possible optimization breaks a valid program when the optimization is found not to be possible. Other languages e.g. C# would by spec run these static initializations at run-time during the first use of C.
Re: Are static variables available to other static variables?
On Friday, 12 April 2019 at 10:56:32 UTC, Jamie wrote: On Friday, 12 April 2019 at 10:49:19 UTC, Jamie wrote: I was trying to declare a static variable dependent on another static variable, but it didn't work. Are static variables not known to other static variables at compile time? void main() { C c = new C(); } class C { static size_t A = 2; static size_t B = 2^^A; // A is not known at compile time } Ok I'm confused... why does that above not work but this does: void main() { C c = new C(); } class C { static size_t A = 2; static size_t B; static this() { B = 2^^A; } } It's not a bug. I finally found it in the spec: https://dlang.org/spec/class.html#static-constructor "All member initializations must be determinable by the compiler at compile time, hence there is no order-of-evaluation dependency for member initializations, and it is not possible to read a value that has not been initialized. Dynamic initialization is performed by a static constructor"
Re: Subtyping of an enum
On Monday, 15 April 2019 at 08:39:24 UTC, Anton Fediushin wrote: Hello! I am currently trying to add a custom `toString` method Several remarks... First of all, strings can be compared (alphabetically) as well as integers, e.g. assert("foo" > "bar") Perhaps not your use case, but worth noting. You have defined your sub-typing the opposite way that you wanted it to work: every `Enum` is an `internal`, but the other way around an `internal` may not work as an `Enum`. Your `fun` would in principle work if it were defined with an `internal` but passed an `Enum`... Of course you have defined `internal` as nested private so no... But then how did you want anything to work if no one outside Enum knows the super-type? You obviously need to re-think your problem and your design :) Obvious solution is to wrap an enum in a structure and utilize 'alias this' for subtyping like this: Actually the obvious solution (not sure if it otherwise works for you) would be to take advantage of D's Uniform Function Call Syntax [1] and define toString as a global function that can be called as a method: enum Fubar { foo, bar } string toString(Fubar fb) { return "It works."; } void main() { import std.stdio; writeln(Fubar.foo.toString); } _ [1] https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs
Re: Subtyping of an enum
On Monday, 15 April 2019 at 10:34:42 UTC, Anton Fediushin wrote: On Monday, 15 April 2019 at 10:06:30 UTC, XavierAP wrote: You have defined your sub-typing the opposite way that you wanted it to work: every `Enum` is an `internal`, but the other way around an `internal` may not work as an `Enum`. Your `fun` would in principle work if it were defined with an `internal` but passed an `Enum`... Of course you have defined `internal` as nested private so no... But then how did you want anything to work if no one outside Enum knows the super-type? Isn't this how subtyping works for integers and other types? For example, you have subtyped an integer and added some new methods to it? Yes (leaving aside whether stuff is private or nested) but you are using the types' relationship the other way around. You have: static assert(is(Enum : internal)); But you are defining and calling fun() as if it were the other way around (internal : Enum)
Re: Subtyping of an enum
On Monday, 15 April 2019 at 10:34:42 UTC, Anton Fediushin wrote: The problem here is that I want to keep methods that are related to an enum inside of this enum for purely aesthetic and organizational purposes. ... These global functions pollute global namespace. If you have defined `x.toString` as a method, UFCS means of course you can also call `toString(x)`... So it's debatable what polluting means. More generally you insist on modules and namespaces to be different concepts, which they are (pointlessly) for C++, but not for D (purposely).
Re: Subtyping of an enum
On Monday, 15 April 2019 at 12:38:59 UTC, XavierAP wrote: More generally you insist on modules and namespaces to be different concepts, which they are (pointlessly) for C++, but not for D (purposely). Here I should say packages instead of modules... but the general argument stays. Anyway your design is up to you :) but sub-typing is not reflexive, in D or any language.
alias parameters, what for?
What are the benefits of alias parameters, compared to specifying the template parameters fully? https://dlang.org/spec/template.html#aliasparameters In most examples, at places in Phobos, and in Andrei's and Ali’s books, alias parameters are used for functions (in the general sense). Why this instead of specifying and typing the parameter functions or delegates? This brings another question, why is it so widespread in Phobos etc. to template these function parameters instead of declaring them as run-time parameters? Is this really always considered beneficial, why? For one it looks like it saves a lot of typing and makes the whole declaration more readable (not to mention possible attribute soups); but the type-checking code just moves to additional template constraints. And finally what’s the advantage of alias parameters in general, besides function/delegates? But I don’t see other uses in practice, although they’re possible.
Re: alias parameters, what for?
Thanks, I get your points. I do think they make more sense for the standard library, than in every general case (packages for specific uses). Namely, alias parameters provide absolute genericity (instead of overloading every possible use case, or else constraining the API by design), and ultimate runtime performance (always at the expense of compile time).
Re: Does slicing have an effect?
On Tuesday, 21 May 2019 at 20:44:49 UTC, rikki cattermole wrote: On 22/05/2019 8:31 AM, Dennis wrote: Does slicing have an effect I'm not aware of, or is this a bug? It could have an effect if a was a struct/class via operator overloads. But in this case it should probably be a bug. It doesn't look right, even for custom types; because D (and in particular Walter) is against changing the meaning of operators when overloading (e.g. << in C++). At least unofficially, although I may recall it is enforced at a few places elsewhere. Going back to the original question, it may be a bug (for arrays). And if so and if D wants to enforce consistent operator semantics when possible, it may be considered a bug for any type.
Re: Proper desctructor for an class containing dynamic array of objects
On Friday, 14 June 2019 at 11:10:58 UTC, rumbu wrote: On Friday, 14 June 2019 at 07:52:24 UTC, Marco de Wild wrote: On Thursday, 13 June 2019 at 16:08:52 UTC, Mike wrote: Opposed to Java, D's member variables are static initialised. Is there any documentation about this? I find it unexpected. https://dlang.org/spec/class.html#static-constructor «All member initializations must be determinable by the compiler at compile time, hence there is no order-of-evaluation dependency for member initializations, and it is not possible to read a value that has not been initialized. Dynamic initialization is performed by a static constructor»
Re: How does this template work?
On Sunday, 16 June 2019 at 15:11:29 UTC, Robert M. Münch wrote: How does the observerObject Template and function work? I'm struggling because both use the same name and how is the template parameter R deduced/where is it coming from? Looks like it's somehow implicitly deduced. Eponymous templates: https://dlang.org/spec/template.html#implicit_template_properties "Templated types" are actually particular cases of eponymous templates: https://dlang.org/spec/template.html#StructTemplateDeclaration class ObserverObject(R, E...) {...} is equivalent to tempalte ObserverObject(R, E...) { class ObserverObject(R, E...) {...} } So this is I think how everything is made to work with the same compiler engine, both individual "templated types" and "eponymous templates". It's considered idiomatic, but if you don't like it in your case, it's very easy for the author to avoid it: just make the names different in any way. template Observer(E) { ObserverObject!(R, E) Object(R)(R range) { return new ObserverObject!(R, E)(range); } } auto observer = Observer!int.Object(TestObserver());
DIP 1016 and const ref parameters
I often use a pattern of having const ref struct parameters (as in C++) but this doesn't work in the case of rvalues. The workaround of defining an overload that calls its own name is terrible. I understand there was a DIP 1016 by Manu asking for this case to work. As far as I can tell, this was rejected, but later reconsidered, and now Andrei is starting up a new one[1]? Apologies but I'm not sure where these discussions are centralized. But if anyone has any idea or guess how seriously and in what kind of time this could be expected, that would be my first side question. My main learning question is whether the const ref parameter pattern is good in D? In C++ I see it everywhere, but are there better alternatives, in particular in D, or is there no point because some copy elision optimization may be guaranteed? In short am I right in writing const ref parameters, or am I doing something silly (and as important as this DIP may otherwise be, it wouldn't affect me as much as I think)?? As far as I can see, this DIP would be helpful for two use cases: const ref, and return ref with method chains. Are there others? __ [1] https://forum.dlang.org/post/d90a7424-a986-66f1-e889-a9abd55e0...@erdani.org
Re: The problem with the conversion.
On Wednesday, 19 June 2019 at 14:58:44 UTC, drug wrote: 19.06.2019 17:52, Den_d_y пишет: void load (const (char *) path) { SDL_Surface ab = SDL_LoadBMP (path); a = SDL_CreateTextureFromSurface (ab); SDL_FreeSurface (ab); } try the following: ``` void load (string path) { import std.string : toStringz; SDL_Surface ab = SDL_LoadBMP (path.toStringz); // toStringz converts string to null terminated char* auto a = SDL_CreateTextureFromSurface (ab); SDL_FreeSurface (ab); } Also, the return type of SDL_LoadBMP is a pointer, SDL_Surface* not just SDL_Surface. Indeed, in your code do use the D string path, not char*, and use toStringz when passing to C APIs. Also, in D const(char)* would not be the same as const(char*). But don't worry about this and use string.
Re: DIP 1016 and const ref parameters
On Wednesday, 19 June 2019 at 12:55:09 UTC, Jonathan M Davis wrote: Even in C++, using const ref is not as good a practice as it once was, because they added move constructors, finally making object moveable. The result is that in many cases, it's actually more efficient to just copy values in C++ rather than use const &, but which is better does depend on the code. As for D, unless you're dealing with large objects, odds are that worrying about passing by value is pointless. D classes are reference types, and D structs have move semantics built-in. So, you don't get as many copies as you would in C++98, and the situation is probably better than newer versions of C++, since IIRC, C++ classes aren't moveable by default, whereas D structs are. In general, you're probably better off just passing by value unless you find that a particular piece of code is inefficient when benchmarking. Either way, you don't want to be slapping const on everything the way you would in C++, because D's const is far more restrictive. So, while it still can be quite useful, odds are that if you start using it heavily, you're going to run into problems fast - especially since casting away const and mutating an object is undefined behavior in D. D's const has no back doors. If something is const, then you can't mutate it unless you also have a mutable reference to the same data. And because const is transitive, you pretty much can't get mutable stuff from const stuff like you frequently can in C++ (e.g. in C++, it's possible to have a const container of mutable objects, wherein D, once part of something is const, everything within that part is const). As for the DIP, I'd suggest watching Andrei's recent dconf talk on the subject: https://www.youtube.com/watch?v=aRvu2JGGn6E&feature=youtu.be - Jonathan M Davis I am not talking about cases that would be candidate for moving, or where const would be any problem. If you want an example for the sake of argument: struct Matrix3D { Matrix3D opBinary(string op)(const ref Matrix3D rhs) const; } unittest { auto a = Matrix3D.random; assert(a == a * Matrix3D.identity); assert(a == a + Matrix3D.zeros); } I did watch Andrei's talk, actually this is where I started and learned about the DIP(s), then I was confused that 1016 had been rejected, and smelling that it may be "reopening" I was not sure where I can find the "index" of DIPs under discussion or whatever... :) IIRC, C++ classes aren't moveable by default, whereas D structs are. What do you mean that structs are movable? I know about RVO (in both D and C++, supposedly guaranteed by all compilers in practice, but not by language spec -- why not D?), but what about passing up the stack as here?
Re: DIP 1016 and const ref parameters
Hmmm I know about move semantics, and C++11 etc. I just don't know how related all that is to my original question. :) On Wednesday, 19 June 2019 at 19:25:59 UTC, Jonathan M Davis wrote: though if I understand correctly with RVO, it may just place the return value outside of the function in the first place to avoid needing to move. Indeed, unrelated: https://dlang.org/glossary.html#nrvo func(foo(), bar(42), baz("hello")); assuming that none of these functions return by ref, func is taking temporaries from several functions, and the spec actually guarantees that they will not be copied. Where does the spec say this?? (This case is actually my question.) However, please understand that naive moving is not an answer for me. Moving is still work! It would still be more efficient if foo's parameters were references/pointers -- if D functions were able to bind rvalues as such. Theoretically a compiler could optimize by realizing that if a value parameter is not modified by the function (and it doesn't fit in a register etc), it can be read at its original location/address in the caller's stack, i.e. by reference/pointer. Again, nothing to do with moving. But I really doubt the D compilers do this, first because C++ probably don't, or else all C++ programmers are wasting their fingers and screen real state typing const & zillions of times; and second because D would not be able to bind as ref in case the argument happened to be an rvalue. __ OK so I try to experiment myself: /**/ struct XY { int x, y; ~this() { writeln("Destroyed!"); } } int sum(XY p) { return p.x + p.y; } void main() { XY p; p.sum; } /**/ Destroyed! Destroyed! Note that the compiler didn't realize that p isn't needed after the last statement of main, as you thought. /**/ XY get() { XY p; return p; } void main() { get.sum; } /**/ Destroyed! Now with an rvalue returned from get, interesting, no copy. Still, I wonder what really happened. Again, moving between stacks would still be work. And a different optimization can explain this non copy, for example inlining. __ Again, does the spec really mention any of this moving or eliding? I have found nothing.
Re: Is it possible to escape a reserved keyword in Import/module?
On Wednesday, 19 June 2019 at 18:56:57 UTC, BoQsc wrote: I would like to make sure that my modules do not interfere with d lang. Is there any way to escape reserved words? The only reason C# allows this is for interop or code generation for other languages that use the same keyword. For example "class" is an HTML attribute. There is no excuse to do this for any other reason -- and C# gurus would also agree. I would like to make sure that my modules do not interfere Then don't name them as keywords :)
Re: DIP 1016 and const ref parameters
On Wednesday, 19 June 2019 at 21:06:48 UTC, XavierAP wrote: Now with an rvalue returned from get, interesting, no copy. Still, I wonder what really happened. Again, moving between stacks would still be work. And a different optimization can explain this non copy, for example inlining. My guess as to what may be happening (I've never used a disassembler and I wasn't planning on starting today yet) is simple. The rvalue returned by get() is possibly not popped out from the stack, but rather left in the same place as sum() is called on it. This is actually optimum, but hardly an optimization, rather it's the easiest and least effort for the compiler. Again this would mean no moving -- which is good, because moving is work. And also, this doesn't work in the general case. If parameters are by value, everything works perfect when I pass rvalues (but we already knew that, not answering my question); however if I pass lvalues they will be copied every time. So my question is open... what about const ref rvalue parameters? Or another possible optimization: in case the function is declared with const parameters (not ref), lvalues can be accessed by ref as an optimization; and rvalues can use the same trick they do now. As a consequence, no unnecessary copies ever -- thanks to const. This is even better because I don't have to type so many ref, which were never part of the algorithm but baby instructions for the dumb compiler (const & everywhere is one of the ugliest and most annoying things in C++).
Re: The problem with the conversion.
On Wednesday, 19 June 2019 at 17:28:38 UTC, XavierAP wrote: Also, the return type of SDL_LoadBMP is a pointer, SDL_Surface* not just SDL_Surface. Or just use auto of course if you prefer: void load (string path) { import std.string : toStringz; auto ab = SDL_LoadBMP (path.toStringz);
Re: DIP 1016 and const ref parameters
On Thursday, 20 June 2019 at 00:30:35 UTC, Jonathan M Davis wrote: Ultimately, if you want a function to accept both rvalues and lvalues as efficiently as posible, just templatize it and use auto ref. I'm aware of auto ref, and I've used it to solve this same problem when I had a template, but as you say it works with templates only, not plain non-templated functions. Or another possible optimization: in case the function is declared with const parameters (not ref), lvalues can be accessed by ref as an optimization; and rvalues can use the same trick they do now. As a consequence, no unnecessary copies ever -- thanks to const. This is even better because I don't have to type so many ref, which were never part of the algorithm but baby instructions for the dumb compiler (const & everywhere is one of the ugliest and most annoying things in C++). Either way, const has nothing to do with any of this. You're free to mark a ref or auto ref parameter as const, but it has nothing to do with whether rvalues are accepted, and it will never have anything to do with whether rvalues are accepted. D's const is far too restrictive for it to make any sense to base rvalue stuff on it like they do in C++. The DIP has nothing do with const and everything to do with ref. [...] Regardless, the refness of a parameter is part of its type, and I'd be very surprised if it were ever changed so that any parameter that was not marked with ref was ever ref. I know. That's why I look to the general solution to bind ref rvalues as a solution to bind const ref in particular. By the way it looks to me that most of the demand in the D community to bind to ref is for chain return ref functions. I wonder why no one in D is bothered about not being able to use const ref parameters easily, while in C++ everyone is bothered to do it, and passing a read-only struct/class by value won't pass by the least alert reviewer. My guess is that in D it's very often ranges that get passed, and these are passed as slices, which are by nature refs that don't reallocate, and can also be decorated const. Still the const ref concern stays more or less. Rust has a solution too (&) of course. My new idea about const only would be a compiler optimization, not part of the language/ABI. The same way as RVO, which under the hood (but not at the ABI level) is implemented as changing the function signature completely. This const optimization would not change the function's ABI either. However I see a practical problem to implement this optimization idea. RVO changes the function signature under the hood, but in the same way for every occurrence/call. This const optimization would need to change the signature, but only in the occurrences where the function is called with lvalues instead,not rvalues. So in practice turning every function with const struct parameters as a template; but under the hood, maintaining a single plan signature in the ABI. I wonder if this is as easy or feasible as RVO.
Re: Where can find fix length array memory layout document
On Tuesday, 18 June 2019 at 12:26:14 UTC, lili wrote: Hi guys: Is the Dlang fix-length array alloc on stack? when a test writeln([1]).sizeof //16 writeln([2]).sizeof //16 Why, What is the fix-length array memory layout. You are quite confused... [...] is an array literal, not a static array. Those aren't the same thing. When you pass a array literal anywhere in your code, it will in principle be referred as a slice variable. This will not reallocate the contents. However the slice reference is another variable that takes up two words of space (see code below). This slice type is the same variable type that stores dynamic arrays -- be they allocated or null. Array literals are not necessarily allocated. The compiler is free to embed them into the program machine code itself. If you want a static array, you can just declare it directly e.g. int[n] arr. Of course you can also generate is out of an array literal with the staticArray std library function. PS the layout of D arrays is of course linear and contiguous. Both static or dynamic, just like C/C++ static arrays or std::vectors respectively. Hopefully this code makes things clear: /*/ enum lenInts = int.sizeof; static assert(lenInts == 4); int[1] arrStatic; static assert(lenInts == arrStatic.sizeof); auto slice = arrStatic[]; alias sliceType = typeof(slice); static assert(is(sliceType == int[])); enum lenPointers = size_t.sizeof; // fyi (unsinged) pointers static assert(ptrdiff_t.sizeof == lenPointers); // fyi signed pointer diff static assert(sliceType.sizeof == 2 * lenPointers); // because a D array reference remembers a pointer (like C) plus the length (stored in a word-length integer)
Re: Options for unit testing in D?
On Friday, 21 June 2019 at 04:08:42 UTC, Mike Brockus wrote: I am wondering as to what options are available for a Meson build user when unit testing? Unit tests are part of the language in D: https://dlang.org/spec/unittest.html These are compiled when you (or whatever build system you use) pass the argument -unittest to the compiler. If you never herd about Meson before: 🤔. https://mesonbuild.com/ D has an "official" build manager, called dub. Of course you're free to use another one you prefer. https://dub.pm/getting_started PS also embedded documentation is part of the language (no need for e.g. doxygen): https://dlang.org/spec/ddoc.html
Re: Options for unit testing in D?
On Sunday, 23 June 2019 at 01:26:29 UTC, Mike Brockus wrote: I think we made a lot of progress, suddenly it's working and I don't need to include main. Is there a way to indicate based on console output that one executable is the tester and the other is the application? unittest blocks are skipped completely by the compiler when the -unittest command line option is not passed. So you can leave unittest code embedded in between the rest (specially for proper unit tests of functions and classes) and there is no need to worry about file separation. Even when you write a separate file with tests, all its code inside unittest blocks can be skipped for the compiler. In the case of dub, it has a dedicated option, "dub test" instead of "dub build" or "dub run" https://dub.pm/commandline.html#test
Re: assert in unittest has access to private member?
On Sunday, 30 June 2019 at 17:24:03 UTC, Robert M. Münch wrote: I have a case, with templates, where an assert in a unittest can access a private memember and I don't know how this can happen. Modules are the units of encapsulation in D: https://dlang.org/spec/attribute.html#visibility_attributes
Re: New programming paradigm
On Wednesday, 6 September 2017 at 23:20:41 UTC, EntangledQuanta wrote: So, no body thinks this is a useful idea or is it that no one understands what I'm talking about? I think it may be a good use, although I haven't invested so much time looking into your particular application. It looks like a normal, sane use of templates. This is what they are primarily intended for. And yes, combining them with mixins provide some great possibilities that are not available in many other languages. Have you seen how D recommends avoiding duplicate code when overloading operators, also by means of mixins: https://dlang.org/spec/operatoroverloading.html#binary I thought you may come from C since you mention void pointers as an alternative. But that is not considered the normal way in D, your new way is far better, and more "normal". It looks you may be mistaking what happens at "run-time", or it may be a way of speaking. In D, templates called with different types generate different code already at compile-time -- even if in the source code you write, it all looks and works so polymorphically. This is a similar approach as in C++ and it's why D generics are called "templates"; as opposed for example to C#, where generics are not compiled into static types and keep existing at run-time. Andrei discusses both approaches in his book, and why the first one was chosen for D.
multi-dimensional arrays, not arrays of arrays
Does D provide anything like this? Otherwise, was this ever considered and were reasons found not to have it? I mean at least in C# (not talking about C/C++ at all) you can declare two kind of multi-dimensional arrays: T[][][] or T[,,]. The first is the same as the D ones, array of arrays of... (except the order of the indices isn't inverted in C# type declarations IIRC); but the second provides contiguous, rectangular truly multi-dimensional arrays supposedly with one single level of indirection. (Of course static arrays don't exist in C# just dynamic but that's an apart issue.) Is there a reason why this feature would not be really desirable or possible? Does it really exist and I missed it in Andrei's book? As a matter of fact he states in chapter 4.3: «On the minus side, "tall and thin" arrays with many rows and few columns incur a large size overhead as there's one array to keep per column. [...] Jagged arrays may have problems with efciency of access and cache friendliness. Each element access requires two indirections [...] going column-wise through a jagged array is a cache miss bonanza.» It would look that well implemented [,,] arrays would fill some application gaps, even though arrays of arrays (jagged in practice or not) are elsewhere useful as well of course. In the former cases I would think about defining my own struct wrapping a flat array with an n-dimensional api such as return _buff[i*m + j]... but generic in type and maybe also in dimension. Again any special reason why this isn't already provided in the language? Either a generic struct/class like that, or something deeper in the language that allows using the [] operator as transparently as with any other arrays (as in C#). Thanks for any input.
Re: multi-dimensional arrays, not arrays of arrays
Nice, thanks! Will check it out
FEM library?
Is there any D library for FEM (Finite Element Method, see Wikipedia) solving, meshing, etc... already existing somewhere? I'm asking because I'm considering making something in that field as a personal learning project. Depending on what can be found I can jump at some point to use a serious enough library or contribute to it...
Re: FEM library?
@Nicholas yes such a FEM library to be developed would heavily depend on Mir. Ilya Yaroshenko pointed me to it in another thread. I didn't know about DlangScience, thanks. Looks like there is some overlap? @Dukc thanks! Whenever in the future I'm developing for a library project or following it... Looks like those development threads currently go in the General board? Wouldn't it be better to split them together into one board within the Development section? Looks like inside General, library/project threads get lost and buried too quickly. I know many/most people are using this via email though, but still.
Recommend: IDE and GUI library
Hi I've looked at wiki.dlang.org/IDEs, and I see that Visual D is linked from dlang.org/download.html. Still I was looking for personal opinions and experiences beyond hard specs, I wonder if one of the IDEs is already dominant at least for each OS for any good reason. My requirements are quite ordinary: make x64, debug, go to definition, manage projects, code completion. My platform is Windows; interested if the choice would be different for Linux, if the same nice, otherwise I'd prefer to use whatever is best on each OS. And second question, is DWT the de facto standard for creating GUIs? Or are there good competitors. Sorry if I'm asking something too obvious, though I've looked around for answers before. And I've also searched the forum but really equivalent questions were over 2 years old and many things may have changed. Thanks!
Re: Recommend: IDE and GUI library
On Saturday, 25 February 2017 at 20:03:17 UTC, Jacob Carlborg wrote: There's no de factor library for creating GUIs in D. If you want a native look and feel, DWT is a good option. If you want the application to look the same on all platforms, there might be other better suited alternatives. It's not GUI projects that I would plan to work on, just something easy with basic functionality that I can use for my own utilities or test clients for libraries. And if there's anything with any kind of designer support (in which IDE)...
Re: How to enforce compile time evaluation (and test if it was done at compile time)
On Wednesday, 1 March 2017 at 09:19:53 UTC, Christian Köstlin wrote: On 01/03/2017 00:09, Joseph Rushton Wakeling wrote: if (!__ctfe) assert(false); ... might be the best option. That shouldn't be compiled out even in -release builds. thats a nice idea! is this happening because of assert(false) being always part of release builds (as mentioned here: https://dlang.org/spec/contracts.html#assert_contracts) or because the if would have no instructions anymore if this is removed. Yes assert(false) or assert(0) is a special case according to the specification. At least in the DMD implementation it is not removed for -release. If reached it throws an "object.Error@(0): assert(0) or HLT instruction" instead of core.exception.AssertError
Re: Recommend: IDE and GUI library
On Tuesday, 28 February 2017 at 06:16:08 UTC, thedeemon wrote: For me Visual-D served well for years, and for GUI on Windows I've used DFL successfully (quite nice lib, very WinForms-like, with a visual editor) and now mostly use DLangUI (on both Windows and Linux). I'm trying now DlangUI on Visual D. I'm getting different errors from missing Derelict library dependencies... I see at github.com these are "subrepos" but after cloning the subrepo directories are still empty. Sorry this is my first time using Git/GitHub (used Mercurial and TortoiseHg at work, which I think would have cloned the subrepos without additional action). What am I missing?
Re: rdmd with a file with no extension
On Wednesday, 1 March 2017 at 16:06:20 UTC, Colin wrote: When running a small D program through rdmd, it seems the file needs a .d extension to work. It looks like the file extension is enforced: https://dlang.org/dmd-windows.html#switches Looks like a feature rather than a bug... At the command line, both "file" or "file.d" make the compiler look for "file.d". Even "file.c" is understood as "file.c.d"
Re: Recommend: IDE and GUI library
On Wednesday, 1 March 2017 at 20:00:32 UTC, thedeemon wrote: If you're building your app with VisualD (as opposed to invoking dub externally), make sure you've set up import paths in project settings properly. Thanks. With dub everything works straight forward. I just call it blindly since it's the first time I use dub and I'm not sure everything it's supposed to do. Still I want to be able to be able to work and debug from Visual Studio. For this I found out how to clone the dependencies, sorry about that... (Only from the command line... Anyone recommends better free Windows Git gui clients than GitHub Desktop?) Import paths seem correctly setup in the project files from the repo, as I would expect. And once the dependency code is in its place it does build, both the library and the example applications. The problem I was having after all this was a runtime exception, but it happens only on 32-bit. Switching to 64-bit building and debugging works out of the box (after having cloned the subrepos). Here I have no idea if I have a drive issue, in any case 64-bit is enough for me. BTW the exception is: "derelict.util.exception.SymbolLoadException Failed to load OpenGL symbol [glEnableClientStateiEXT] " Also, if you use "minimal" configuration of DLangUI (which I recommend) you can remove mentions of SDL and GL from its dependencies in its dub.json, this way there are less things for compiler and VisualD to look for. I understand that in order to do this from Visual Studio, according to the instructions at github.com/buggins/dlangui, I should use configurations DebugMinimal instead of Debug, etc. But these configurations are not defined; I wonder if this documentation is out of sync with the current code. Otherwise I also though OpenGL wouldn't be used unless the version identifier USE_OPENGL was defined, but apparently it is not in VS as far as I can see? So in the end I'm not very sure whether OpenGL is kicking in in 64-bit when it works, or in general how to disable it (from Visual Studio instead of dub) -- or what are the consequences for performance or whatever. For now I can work like this and if I have additional problems that prevent me from advancing I will research it further... Thanks also @aberba and everyone.
Best memory management D idioms
I was going to name this thread "SEX!!" but then I thought "best memory management" would get me more reads ;) Anyway now that I have your attention... What I want to learn (not debate) is the currently available types, idioms etc. whenever one wants deterministic memory management. Please do not derail it debating how often deterministic should be preferred to GC or not. Just, whenever one should happen to require it, what are the available means? And how do they compare in your daily use, if any? If you want to post your code samples using special types for manual memory management, that would be great. AFAIK (from here on please correct me wherever I'm wrong) the original D design was, if you don't want to use GC, then malloc() and free() are available from std.c. Pretty solid. I guess the downside is less nice syntax than new/delete, and having to check the returned value instead of exceptions. I guess these were the original reasons why C++ introduced new/delete but I've never been sure. Then from this nice summary [1] I've learned about the existence of new libraries and Phobos modules: std.typecons, Dlib, and std.experimental.allocator. Sadly in this department D starts to look a bit like C++ in that there are too many possible ways to do one certain thing, and what's worse none of them is the "standard" way, and none of them is deprecated atm either. I've just taken a quick look at them, and I was wondering how many people prefer either, and what are their reasons and their experience. dlib.core.memory and dlib.memory lack documentation, but according to this wiki page [2] I found, dlib defines New/Delete substitutes without GC a-la-C++, with the nice addition of a "memoryDebug" version (how ironclad is this to debug every memory leak?) From std.typecons what caught my eye first is scoped() and Unique. std.experimental.allocator sounded quite, well, experimental or advanced, so I stopped reading before trying to wrap my head around all of it. Should I take another look? scoped() seems to work nicely for auto variables, and if I understood it right, not only it provides deterministic management, but allocates statically/in the stack, so it is like C++ without pointers right? Looking into the implementation, I just hope most of that horribly unsafe casting can be taken care of at compile time. The whole thing looks a bit obscure under the hood and in its usage: auto is mandatory or else allocation doesn't hold, but even reflection cannot tell the different at runtime between T and typeof(scoped!T) //eew. Unfortunately this also makes scoped() extremely unwieldy for member variables: their type has to be explicitly declared as typeof(scoped!T), and they cannot be initialized at the declaration. To me this looks like scoped() could be useful in some cases but it looks hardly recommendable to the same extent as the analogous C++ idiom. Then Unique seems to be analogous to C++ unique_ptr, fair enough... Or are there significant differences? Your experience? And am I right in assuming that scoped() and Unique (and dlib.core.memory) prevent the GC from monitoring the memory they manage (just like malloc?), thus also saving those few cycles? This I haven't seen clearly stated in the documentation. [1] http://forum.dlang.org/post/stohzfatiwjzemqoj...@forum.dlang.org [2] https://github.com/gecko0307/dlib/wiki/Manual-Memory-Management
Re: Best memory management D idioms
On Monday, 6 March 2017 at 08:26:53 UTC, Eugene Wissner wrote: The memory management in D is becoming a mess. I am aware this is a hot topic, hence the opening joke. But I just want to learn what toolboxes are currently available, not really discuss how adequate they are, or how often GC is adequate enough. Neither how much % GC-haram Phobos or other libraries are internally atm. There are several threads already discussing this, which I've browsed. My impression so far is that dlib's New/Delete is the most straightforward or efficient tool, and it can kind of cover all the bases (and is GC-halal), as far as I can tell in advance. Plus it has printMemoryLog() as a bonus, which is already better than C++ new/delete. Just an observation that it doesn't provide an option to allocate an uninitialized array, considering that this module is already targeting performance applications. Not sure if I would use any other tool (besides GC itself). I'm curious about Unique but it's not fully clear to me what happens (regarding lifetime, deterministic destruction, GC monitoring) when you need to call "new" to use it.
Re: How to compile against GitHub fork of Phobos?
On Tuesday, 7 March 2017 at 01:14:28 UTC, Q. Schroll wrote: I have a fork of the standard-library in the folder "phobos". DMD looking for the built-in phobos is specified in the configuration file (sc.ini on Windows, dmd.conf on Linux), not hardcoded. You may want to remove it from there. When you specify -I on top of this, I guess the compiler looks in both places in some order. You could also clone your modified Phobos to the directory built into the DMD distribution. But maybe you want to have both. You may also keep and use two DMD bin folders, with different configuration files. There are many possibilities for you to configure what you want. Also yes with your configuration I think you should remove the preceding "phobos." from imports, since you're already telling the compiler to look inside the phobos folder.
Re: Best memory management D idioms
On Tuesday, 7 March 2017 at 16:51:23 UTC, Kagamin wrote: There's nothing like that of C++. Don't you think New/Delete from dlib.core.memory fills the bill? for C++ style manual dynamic memory management? It looks quite nice to me, being no more than a simple malloc wrapper with constructor/destructor calling and type safety. Plus printMemoryLog() for debugging, much easier than valgrind. do you want to manage non-memory resources with these memory management mechanisms too? I wasn't thinking about this now, but I'm sure the need will come up.
Re: Best memory management D idioms
On Tuesday, 7 March 2017 at 18:21:43 UTC, Eugene Wissner wrote: To avoid this from the beginning, it may be better to use allocators. You can use "make" and "dispose" from std.experimental.allocator the same way as New/Delete. Thanks! looking into it. Does std.experimental.allocator have a leak debugging tool like dlib's printMemoryLog()?
DUB specify version identifier on command line?
I'm talking about the conditional compilation keyword "version", not about version strings. I've looked in DUB's help and reference [1][2] but can't seem to find how to solve my problem. On the command line it seems to be possible to specify debug identifiers, but not version identifiers. [3] It came up while trying to do something specific, so I'll explain this. I'm learning and trying things, and I was playing with dlib.core.memory. Before moving to the next thing I wanted to try printMemoryLog(). This outputs memory debugging info, only when compiled with version(MemoryDebug) [3]. I'm working with Visual D. However for 3rd party package dependencies it's simpler to compile them with dub, and have VS find the lib for my client project. Without the version identifier, my program works: compiles, links to dlib, and runs ok. Then I instruct VS to define version(MemoryDebug) for some configuration. No matter how I re-run dub to build dlib, I get linking errors from the additional functions defined in the imported dlib source which aren't found in the binary lib. I guess it's also possible to specify this by adding to the dub.json file [2], but for me it's more flexible if I can leave it alone and compile different versions from the command line alone. But if the json is the only way please let me know. Otherwise what am I missing? Thanks in advance. [1] http://code.dlang.org/docs/commandline#build [2] http://code.dlang.org/package-format?lang=json#version-specs [3] https://dlang.org/spec/version.html#DebugCondition [4] https://github.com/gecko0307/dlib/blob/master/dlib/core/memory.d
Re: Best memory management D idioms
On Tuesday, 7 March 2017 at 18:21:43 UTC, Eugene Wissner wrote: To avoid this from the beginning, it may be better to use allocators. You can use "make" and "dispose" from std.experimental.allocator the same way as New/Delete. OK I've been reading on std.experimental.allocator; it looks really powerful and general, more than I need. I see the potential but I don't really have the knowledge to tweak memory management, and the details of the "building blocks" are well beyond me. But even if I don't go there, I guess it's a good thing that I can change my program's allocator by changing one single line or version assigning theAllocator, and benchmark the results among different possibilities. I see the default allocator is the same GC heap used by 'new'. Just for my learning curiosity, does this mean that if I theAllocator.make() something and then forget to dispose() it, it will be garbage collected the same once no longer referenced? And so are these objects traversed by the GC? I've also looked at mallocator, [2] can it be used in some way to provide an allocator instead of the default theAllocator? As far as I can tell mallocator is not enough to implement an IAllocator, is there a reason, or where's the rest, am I missing it? [1] https://dlang.org/phobos/std_experimental_allocator.html [2] https://dlang.org/phobos/std_experimental_allocator_mallocator.html
Re: DUB specify version identifier on command line?
On Wednesday, 8 March 2017 at 02:15:00 UTC, Nicholas Wilson wrote: Setting version identifiers is done by the `-version=ident` command line flag (this is equivalent to `version = ident` at source level) . This should therefore be settable by the "dflags" dub configuration setting. The way I would do it would be to have a custom configuration that sets "dflags" : [ "other normal flags", "-version= MemoryDebug"] and then build the MemoryDebug dub configuration. Hope that makes sense. Yes... Although I was looking for a command line parameter for dub, not dmd, but apparently it's impossible. So thanks for pointing to the DFLAGS possibility, it has worked. :) I still prefer this for building different versions rather than changing the dub.json file every time. Thanks!
DMD default safety command line switch
Andrei's 2010 book states that the default safety level can be changed from @system to @safe by means of a -safe command line switch, in the case of the DMD compiler. Now I've tried it and it's not recognized. Was this feature remove on purpose? I could imagine that. The default safety keeps being @system, right? PS I've found this old thread... I'm looking for a bit less long answer to read ;) http://forum.dlang.org/thread/hcqb44$1nc9$1...@digitalmars.com
@safe console input?
I was surprised by a compiler message saying that std.stdio.readln() (and specifically the overload without arguments) is not safe but @system. Actually I was using it only to pause execution until the user presses Enter. So how else could I do this within a @safe environment? And more generally, is it possible to get user console input in a @safe way?
can I overload operators as extension methods?
The same way as T.foo() is lowered to foo(T) if no such member is defined inside the type. It would allow me to extend 3rd party types with operator notation without wrapping them. After trying and reading the specification, looks like nuts, but just wanted to confirm. Thx
Re: @safe console input?
On Thursday, 9 March 2017 at 23:55:35 UTC, Adam D. Ruppe wrote: Just wrap it in a @trusted function. I knew this answer already of course ;) but I take it as implying that there is no other way. Actually I really wonder why std.stdio.readln() itself is not flagged @trusted. I wouldn't think such a function skips any buffer bounds checking, even in -release -- having to wait for user input anyway performance is no issue.
Re: DMD default safety command line switch
On Friday, 10 March 2017 at 00:48:39 UTC, Jack Stouffer wrote: Don't know the history, but as recently as a week ago Andrei has argued against such behavior has balkanizing the community. What behavior? Anyway my question is answered, thanks :)
Re: DMD default safety command line switch
On Friday, 10 March 2017 at 01:13:26 UTC, XavierAP wrote: What behavior? Anyway my question is answered, thanks :) What behavior is a rhetorical question, meaning that I don't really want it to be answered 0;)
Re: DMD default safety command line switch
On Friday, 10 March 2017 at 01:17:57 UTC, Jack Stouffer wrote: On Friday, 10 March 2017 at 01:13:26 UTC, XavierAP wrote: On Friday, 10 March 2017 at 00:48:39 UTC, Jack Stouffer wrote: Don't know the history, but as recently as a week ago Andrei has argued against such behavior has balkanizing the community. What behavior? Anyway my question is answered, thanks :) Changing default behavior which results in incompatible code. Aha of course I agree. No language wants to do this, it goes beyond what is referred as community. But yeah look what happened to Python 3.x
Can you fix this code to avoid using pointers?
I do not really think it's a bad solution, to check several scalar arguments that must obey the same condition; just wondering if you have better ideas. Try to avoid modifying the function's signature and defining custom types, unless you have a really terrific idea. void calc(double in1, double in2, double in3, double in4) in { foreach(const p; [&in1, &in2, &in3, &in4]) enforce(*p > 0); } body { /* ... */ }
Re: Can you fix this code to avoid using pointers?
Oh... please forget it What a terrible example :p I forgot why I was using pointers at all... I must have had a reason to write this in the past ???
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 12:35:42 UTC, XavierAP wrote: I do not really think it's a bad solution, to check several scalar arguments that must obey the same condition; just wondering if you have better ideas. Try to avoid modifying the function's signature and defining custom types, unless you have a really terrific idea. void calc(double in1, double in2, double in3, double in4) in { foreach(const p; [&in1, &in2, &in3, &in4]) enforce(*p > 0); } body { /* ... */ } Please imagine double is a type that I wanted to avoid copying, just check by ref. Same question :p
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 13:44:30 UTC, Satoshi wrote: void calc(in double[] array...) { foreach (x; array) { } } To do what I want it should be foreach(ref x; array) -- or const ref. But also I don't want to modify the function signature, certainly in this way. In another situation yes, but the arguments are very different magnitudes, for example temperatures, conductivity, heat power, etc. They should be separate arguments with self-documenting names. And it's not worth the bother to define a struct type for them as a set. Specially since this is an internal implementation "problem" that shouldn't affect the outer interface. I know there's something in std.algorithm for this, but afaik it would be relatively bloated compared to this pointer solution. In C++ I would use a &reference instead of a *pointer, but I actually think C++ references are redundant with pointers, not much safer, and plain confusing. I guess it's a not a common case because if a type is non trivial to copy it should probably be a class, which is already assigned by reference so I wouldn't need the pointer/ref.
Re: Can you fix this code to avoid using pointers?
On Saturday, 11 March 2017 at 19:15:59 UTC, H. S. Teoh wrote: What about just: foreach (const ref p; [in1, in2, in3, in4]) I would think there will be already one copy from the local parameter variables to the in situ array. Then from that one into the for each element it's ref'd all right. But I'm afk and can't test. Like the other copy I missed and Adam spotted when passing the arguments with missing ref qualifiers.. I realized that the code that sparked the question made no sense and should be done in a different way... As is always the case when these questions come up. But I still like the version with pointers ;)
Re: Best ways to declare associative arrays
On Sunday, 12 March 2017 at 07:58:40 UTC, helxi wrote: string[string] change(ref string[string] arg_array){ //.. arg_array["first"] = strip(readln()); //.. arg_array["second"] = strip(readln()); //.. return def; } Nicholas clarified why your declaration was wrong, but there are several strange things in your code that you may want to re-think. Also it looks to me that an associative array is not the most appropriate type for what you want to do. To call a function you just pass the names of the arguments, not their types. So simply change(test), NOT change(string[string] test) arg_array is an in-out (ref) parameter, but change() returns another value of the same type, def, not defined in your code, and which you do not use in main(). I think you may be interested only in changing arg_array, so the signature could be instead: void change(ref ...) What you seem to want from your associative array is to associate two strings, "first" and "second" with two values (strings from the user), and only two. An associate array is more flexible than that, which is bad, you want your code to restrict you away from errors. For example if you keep using an associative array you could at the end of change(): assert(arg_array.length == 2); I wonder if it's not enough and better for you to use a plain array. Keys "first" and "second" are not more informative than numeric indices. You may also use the advantage that an array can be hard-typed as fixed-length if this is known at compile time (and if you don't declare it with new), so it restricts your code in the perfect way: void change(ref string[2] arg_array) { arg_array[0] = strip(readln()); arg_array[1] = strip(readln()); } void main() { string[2] test; change(test); } Also another disadvantage of associative arrays is that they are not ordered, so if for example in main() you read through the values in test with a foreach loop, you may get the result in any order (second first, and first second is possible). A simple array will keep order 0, 1. If you were so bummed about using 0-1 instead of "first"-"second" you could define: enum lineKey :size_t { first = 0, second } void change(ref string[2] arg_array) { arg_array[lineKey.first ] = strip(readln()); arg_array[lineKey.second] = strip(readln()); } But at least to me it looks worse. As a programmer you already know that the first index is 0 and 1 comes next.
Re: Code style for property
On Sunday, 12 March 2017 at 11:15:04 UTC, Nicholas Wilson wrote: On Sunday, 12 March 2017 at 10:47:35 UTC, Andrey wrote: And I want make access to read x, y and bar. Probably I should add prefix for private members, that is a question: what prefix should I use? Now I use prefix p_ (from the word property), but maybe prefix m_ is better and you need to use it for all private members? A single leading underscore is usually used to denote a private variable ( names prefixed with two leading underscores are reserved for use by the compiler). If you need any prefix at all, a single underscore is enough, and it's also the tradition in other languages such as Python, C#... Whether a private member is exposed as property or in some other way, can be seen in the getter/setter, no need to classify it into the member declaration. C++ kind or requires a letter on top such as m_ simply because any identifiers starting with an underscore are (mostly and certainly at the global scope) reserved (namespace pollution anyone?). It's really up to you, we won't call the police ;)
Phobos function to check if files are identical?
It's not easy to do by hand of course, but I was wondering if there was one simple function taking two file names and just returning a bool or something like that. I haven't found it in std.file. If such a function doesn't exist in Phobos but there's a good implementation in some other library, I'm interested to know. Although this time it's for a unit test so I'd rather implement it in two lines than add a dependency. And otherwise to write it by hand, how do you think is the best way? And in terms of performance? By chunks in case of a binary comparison? And what about the case of a text comparison? Thanks
Re: Can you fix this code to avoid using pointers?
On Monday, 13 March 2017 at 14:47:20 UTC, H. S. Teoh wrote: On Sat, Mar 11, 2017 at 08:07:39PM +, XavierAP via Digitalmars-d-learn wrote: [...] But I still like the version with pointers ;) There's nothing wrong with using pointers in D. The fact that D alleviates most cases of (explicit) pointers is a testament to just how awesome it is. ;-) But that shouldn't deter anyone from using (explicit) pointers once in a while. In fact, D makes it such that it's a lot safer using pointers than in C/C++, mainly because it alleviates most of the dangerous use cases for pointers so what's left is generally harmless stuff. Unless your code for whatever reason is involved in heavy pointer hackery (like OS writing), but that's not a typical use case. I did it again ;) enum params = [ "Radius of disk in m", "Integration step size along radius", "Total integration time in s", "Integration step size along time", "Time step size for output", "Initial temperature in C", "Edge temperature in C", "Flow temperature in C", "2D conductivity in W K^-1", "2D diffusivity in m^2 s^-1", "Convective coefficient in W m^-2 K^-1" ]; real*[params.length] vals = [ &R, &dr, &T, &dt, &dtOut, &u0, &uc, &ug, &k, &a, &h ]; import std.conv: to; /* ... */ foreach(i, param; params) { /* ... */ *vals[i] = to!real(val); } I had the same requirement to make separate named scalars instead of an array; but also an array was handier to assign the values inside a loop; and I needed a readable and simple way to map between them. An array of pointers is perfect I think. And the only dangerous thing I could do with the pointers is arithmetic on them instead of the pointed values, but: "pointer arithmetic not allowed in @safe functions." So all is good :)
Re: Declaring interfaces with a constructor
On Monday, 13 March 2017 at 02:15:21 UTC, David Zhang wrote: What it says on the tin. Is there a way to create interfaces with a constructor or must I use an abstract class. What do you want to do in your constructor? I can't think of anything that wouldn't change some state, either of the class (but interfaces aren't allowed to have fields either, precisely because they may not have state), or the global state (worse...). Just curious. Additionally, is there a way to force the linker to link a function in a class without an implementation with another that does have an implementation? I'm not sure if you mean the same as generating "interface files"? [1] https://dlang.org/dmd-windows.html#interface-files
Re: code folding
On Monday, 13 March 2017 at 17:29:41 UTC, Inquie wrote: I have been using static if(true) { ... junk } Indeed #region is part of the C# specification, even if it has no effect on the code. (The specification does not say anything about folding/collapsing, just about "marking sections of code", although I guess most IDEs supporting it will follow the example of MS's reference implementation.) Short answer, D does not have this, as far as I know. I don't really think it's good substitute practice to insert meaningless static if(true)... Even if you're really used to that feature, and even if you're right that it does the job and doesn't change the generated code. Unfortunately you can't get this folding easily (I'm sure some Vim wizard would come up with something). Instead if you want to mark regions of code, that's what comments are for. You can't get the folding you want unfortunately (outside of naturally existing bracket pairs) but you can use your editor to search forward and backward in the file for whatever text, e.g. //region: foo//
Re: Phobos function to check if files are identical?
On Monday, 13 March 2017 at 17:47:09 UTC, H. S. Teoh wrote: Why it is not easy to do by hand? Sorry typo, I had intended to type "I know it is easy"
Re: code folding
On Tuesday, 14 March 2017 at 00:38:12 UTC, Vladimir Panteleev wrote: If you have enough declarations in one file that they call for code folding, it may be better to move them to a separate module. Public imports and aliases allow doing this without breaking any code. [...] Generally speaking, I would recommend to simply avoid code folding altogether: https://blog.codinghorror.com/the-problem-with-code-folding/ Indeed good point: http://stackoverflow.com/questions/475675/when-is-a-function-too-long
Re: Phobos function to check if files are identical?
On Monday, 13 March 2017 at 17:47:09 UTC, H. S. Teoh wrote: Binary comparison is easy. Just read the files by fixed-sized chunks and compare them. Follow up question... What is the best @safe way? Since File.byChunk() is @system. Just out of curiosity, I would rather use it and flag my code @trusted, although I guess there could be concurrency issues I have to take into account anyway... anything else?
Re: Phobos function to check if files are identical?
On Tuesday, 14 March 2017 at 08:12:16 UTC, Andrea Fontana wrote: First I would check if the files have different size or if they are the same file (same path, symlink, etc). Good idea. Good reason to have it in std.file. There might also be platform dependent shortcuts?
Re: Phobos function to check if files are identical?
On Tuesday, 14 March 2017 at 18:26:52 UTC, flamencofantasy wrote: import std.mmfile; auto f1 = new MmFile("file1"); auto f2 = new MmFile("file2"); return f1[] == f2[]; Nice! I don't have experience with memory-mapped files. What are the pros and cons?
Re: Sorting Assosiative Arrays and Finding Largest Common Substring
On Thursday, 16 March 2017 at 16:02:13 UTC, helxi wrote: 1. .length is of type ulong Either use auto or if needed size_t. As Thedeemon says this is an alias of ulong on 64-bit and uint on 32. https://dlang.org/spec/hash-map.html
Re: first try
On Friday, 17 March 2017 at 00:35:32 UTC, Philip Miess wrote: https://gitlab.com/pmiess/101gamesDlangComputerGames/blob/master/ aceyducy.d You don't need string literals to be verbatim (r"") in order to insert newlines as in the code (without escape sequences). All string literals behave this way in D -- this is different from C# for example.
GitHub detects .d source as Makefile?
So I have put my first code even on GitHub (comments welcome :)) and GitHub seems to detect the wrong language, even if I'm not familiar with this GH feature. https://github.com/XavierAP/etc/tree/master/heatsim The repository itself ("etc") is flagged as been written in Makefile? Right now I have only two source files (and a couple of images and a pdf). If I look at syntax highlighting online, one of them main.d seems highlighted in D ok. But the other one heatsim.d is not correctly highlighted. https://github.com/XavierAP/etc/blob/master/heatsim/src/heatsim.d https://github.com/XavierAP/etc/blob/master/heatsim/src/main.d Is this a known issue with D on GitHub? Should I report it I guess? How smart is GH that it doesn't look at the file extension? What happened?
Re: GitHub detects .d source as Makefile?
On Saturday, 18 March 2017 at 01:33:13 UTC, David Nadlinger wrote: The code GitHub uses to infer source file languages is open-source, and – fittingly – available on GitHub: https://github.com/github/linguist You should check the issues for reports of similar D-related problems, and if there are none, create a new one. Or, better yet, submit a pull request with an appropriate fix. Thanks! It seems I can also override the language detection in .gitattributes, and it is now fixed :) I'll take a look around and file an issue if it doesn't exist. Probably not PR myself as I don't know Ruby. As a workaround, adding a "module …;" declaration to your file should help. You probably want to be doing that anyway. I know about this and I've read the spec and Andrei's book yet I'm not entirely clear why it is such a mandatory practice. I'll ask in a new thread... [1] https://github.com/github/linguist/blob/master/lib/linguist/documentation.yml
Re: GitHub detects .d source as Makefile?
On Saturday, 18 March 2017 at 10:52:31 UTC, XavierAP wrote: Thanks! It seems I can also override the language detection in .gitattributes, and it is now fixed :) The majority language assigned to the whole repository is fixed, but alas syntax highlighting in heatsim.d is still wrong. Looks like this is handled by code in a different repository[1] from linguist. I'll look at the issues on both... [1] https://github.com/github/linguist/blob/master/vendor/README.md
Re: Error: out of memory
On Saturday, 18 March 2017 at 20:39:20 UTC, StarGrazer wrote: about 2GB before it quites. It also only uses about 12% of cpu. I have 16 GB total memory and about that free. Surely dmd could do a better job? Any way to get it to do such a thing like set the maximum amount of memory it can use? Any 32-bit process gets 2 GB of memory space, regardless of how much physical memory you have. https://msdn.microsoft.com/library/aa366778.aspx If you used a 64-bit version of dmd your problems should go away... If the binary for Windows isn't available from the downloads here, you can try compiling it from source yourself... But I'm sure someone somewhere has done it already. Or you can try another compiler such as GDC, which is available for Windows x64. Also 12.5% probably means 100% of one of 8 cores in your CPU.
Re: Error: out of memory
On Sunday, 19 March 2017 at 20:50:50 UTC, Gand Alf wrote: just use DMD with the -m64 parameter ;) then you should get a x64 DMD No, at least afaik, then you tell DMD to make a x64 exe, but DMD itself (this particular Windows version) is still a 32-bit exe.
Re: GitHub detects .d source as Makefile?
On Sunday, 19 March 2017 at 21:53:17 UTC, Seb wrote: FWIW this has been fixed by Martin last summer, but the people at GitHub aren't very responsive. The PR is still pending :/ More info: https://trello.com/c/g9PB3ISG/233-improve-d-language-recognition-on-github https://github.com/github/linguist/pull/3145 Thanks for the info. Whole thing looks beyond me, plus I'm new to GH so not sure what's polite, but I'll try to remember pinging after a while whenever no one does. In the meantime my file is finally ok, after I added an override in the .gitattributes file,* it looks like there was a time delay from the language being re-classified by the GitHub Linguist until it was processed anew by the appropriate highlight parser. Even though the majority language stat for the repository had updated instantly. * Fyi these are the lines I added to my .gitattributes file: *.d linguist-language=D *.di linguist-language=D
Re: recommend Git GUI client for Linux?
On Thursday, 2 March 2017 at 06:16:09 UTC, Patrick Schluter wrote: Here [1] is the official git page listing all GUI clients for different plartforms. I use GitExtensions[2] and I like it a lot. It works very well and all the complicated stuff can be done from the GUI interface and also from command line. Patrick thanks for the great recommendation! I'm using GitExtensions now on Windows. In comparison I wonder how GitHub's desktop client is even allowed on the Internet. For Linux (Lubuntu) any recommendation among these? https://git-scm.com/download/gui/linux
really why module declarations?
I've perused both the spec[1] and Andrei's book, and I the idea I get is that module declarations are optional, recommended only in case of file names not being valid D names. But in the community (and Phobos) I see it's strongly recommended and used throughout. What's the reason? If the declaration overrides the path (provided the file is found) rather than enforcing path consistency by outputting a compile error, then what's the benefit of module declarations, if we have to be disciplined to keep it consistent with paths anyway? I'm busy starting my first big multi file D project, thanks for any feedback! [1] https://dlang.org/spec/module.html#ModuleDeclaration