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.
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: 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.
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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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 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: 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
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: 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=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: 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.
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: 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());
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: 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: 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).
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: 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.
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 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 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: 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: 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: 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: 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: 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: 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: 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: 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: 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)...?
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: 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.
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.
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: 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 :)
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 :)
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: 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()"
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: 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.
Re: multi-dimensional array whole slicing
On Tuesday, 25 April 2017 at 20:46:24 UTC, Ali Çehreli wrote: I think it's still consistent because the element type is not int in the case of multi-dimensional arrays. [...] int[3][4] b; b[] = [1, 1, 1]; It is consistent, I just miss the possibility to more easily initialize multi-dimensional arrays uniformly in the same way as uni-dimensional ones. I do not mean it would be good to change the current behavior. I think the best solution would be for D to implement built-in truly multi-dimensional arrays like T[,] as well as the existing (jagged) arrays of arrays T[][]. That's what C# does. The former could maybe even be lowered into jagged arrays (together with their initializations and slicings). But again most people probably don't miss T[,] built-in arrays, specially since we can implement such [,] indexing for custom types. So there's not a strong use case. But actually where I'm using multi-dimensional built-in arrays right now is in the private storage of a custom multi-dimensional type. Then I have the choice of either use them and live with this, but forward indexing transparently; or use uni-dimensional as private storage and map from 2d to linear during indexing...
Re: function type parameter inference not working
On Tuesday, 25 April 2017 at 19:57:30 UTC, Ali Çehreli wrote: This is an intentional limitation of D. It's not possible to bind rvalues (temporaries) to reference parameters. The best option here is 'auto ref': Aha I had forgotten about the ref (obviously, otherwise I wouldn't have passed a temporary even in the unit test -- I'm embarrassed). If that's the reason why it doesn't work I'm satisfied. It would be helpful if the error message talked about the ref qualifier as the root cause instead of the consequent failure to infer template parameters.
Re: function type parameter inference not working
On Sunday, 23 April 2017 at 19:40:39 UTC, ag0aep6g wrote: Please post self-contained code. When I fill the gaps you left, it works for me: Found it! It stops working (DMD v2.073.0 for Windows) if it has to infer the type of a temporary local variable -- constructed in place of the argument: struct Matrix(size_t nr, size_t nc) {} struct Vector(size_t n) {} void assembleMass1D(Mat, Vec)(ref Mat M, const ref Vec x) { /* ... */ } Matrix!(2,2) M; Vector!2 V; assembleMass1D(M, V); // OK assembleMass1D(M, Vector!2()); // ERROR template cannot deduce function Is this a bug?
Re: function type parameter inference not working
On Sunday, 23 April 2017 at 19:40:39 UTC, ag0aep6g wrote: Please post self-contained code. When I fill the gaps you left, it works for me: Interesting, thanks a lot. I'll test and narrow down what's in my code preventing this from working (I can't really think of anything) and I'll report back.
function type parameter inference not working
It's not working for my case, while I see no special reason why it couldn't. Also I can't find specific inference rules at http://dlang.org/spec/function.html#function-templates Is it a problem that the types to be inferred are in turn also templated? Any workaround that can make inference work? Otherwise I would re-consider my design rather than having to specify types already available in the runtime arguments :( void assembleMass1D(Mat, Vec)(ref Mat M, const ref Vec x) { /* ... */ } Matrix!(2,2) M = /* ... */; Vector!2 V = /* ... */; assembleMass1D(M, V); // ERROR template cannot deduce function from argument types
Re: multi-dimensional array whole slicing
On Sunday, 23 April 2017 at 09:06:35 UTC, Ali Çehreli wrote: It took me a while to convince myself that there is no bug here. The problem, as is obvious to others, ;) a whole slice of a whole slice is still the same slice. Ha, you're right, I hadn't realized. But I still have a problem. For both multi-dimensional and uni-dimensional arrays a[] and a[][] are the same. And yet, a[] has different type in both cases and a[]=1 compiles for uni-dimensional but not for multi-dimensional.
Re: multi-dimensional array whole slicing
On Saturday, 22 April 2017 at 22:25:58 UTC, kinke wrote: int[3][4] arr = void; (cast(int[]) arr)[] = 1; assert(arr[3][2] == 1); Thanks... I think I prefer to write two loops though :p I wish D built-in arrays supported [,] indexing notation like C# (or as you can do in D for custom types)
multi-dimensional array whole slicing
I can do: int[3] arr = void; arr[] = 1; But apparently I can't do: int[3][4] arr = void; arr[][] = 1; What is the best way? What am I missing?
Re: DMD requirements (VC runtime version) where?
On Friday, 21 April 2017 at 11:37:07 UTC, Mike Parker wrote: sc.ini manually is the better option if you don't need or want the 2015 build tools. Thanks! Nevertheless I think it would be good that the supported version of VS is documented on the website of DMD, just like it is on VisualD's. When the installer is updated, this document/webpage can be updated as well. I don't immediately know how to find VS paths/exes and how to insert manually into sc.ini... But the VS extension manager is giving me some weird error message, so I'll just switch to 2015, even uninstall 2017.
DMD requirements (VC runtime version) where?
Visual D has just added support for VS 2017 (kudos), whereas before I had to stick with 2015 at the latest. But DMD has an additional dependency on VS (for x64), and it is not documented, as far as I've been able to find, which versions. So I just tried, and now the DMD Windows installer complains that it can't find any compatible versions of MSVC and the Windows SDK, after having installed 2017. Is this documented somewhere that I've missed? Otherwise, would it be possible to add this information somewhere, namely which versions of what dependencies are required for what features?
Re: Can we disallow appending integer to string?
On Wednesday, 19 April 2017 at 14:50:38 UTC, Stanislav Blinov wrote: On Wednesday, 19 April 2017 at 14:36:13 UTC, Nick Treleaven Why is it legal to append an integer? Because integrals implicitly convert to characters of same width (byte -> char, short -> wchar, int -> dchar). Huh... I hadn't used but I'd been assuming probably biased from C# that str ~ i would be equivalent to str ~ to!string(i) instead of str ~ cast(char) i Now I see the problem too...
Re: Use of "T"
On Wednesday, 12 April 2017 at 14:46:20 UTC, solidstate1991 wrote: Yes, templates. I've looked this up a bit, and I found it. I want to use it to use the dictionaries for different things than string<->int conversion. T is just the common name of a (type) parameter, mostly whenever the template is more generic that you can't think of a more informative (template) parameter name. Just like you could use "str" for a string or "i" for an int name. But in you case you could use a more informative name such as "keyType" since you are describing keyType -> valueType dictionaries, also called associative arrays. Moreover these dictionaries are built-in basic types in D: https://dlang.org/spec/hash-map.html This should be the Dictionary(int), string<->string conversion should be done with Dictionary(string). Int<->string should be done as Dictionary(string,int) if possible. So according to the spec linked above, those examples would be declared: string[int] dict1; string[string] dict2; int[string] dict3;
Re: Why is this legal?
On Wednesday, 29 March 2017 at 09:50:10 UTC, abad wrote: Is this on purpose and what's the rationale? In Andrei's book, chapter 6.9.1 "the non virtual interface (NVI) idiom" answers your question. It cites this article by Herb Sutter as the originator of the idea: http://www.gotw.ca/publications/mill18.htm
Re: How to continue after the book?
On Tuesday, 28 March 2017 at 07:27:31 UTC, I Lindström wrote: I do have a need for which I've been trying out a few languages and D seems by far the best for me. Should I just start doing that project and learn as I go by googling and asking here, or are there some other things you did before starting your first "real" project. If you have a project in mind and that's the reason why you've looked into D, just start it now. After reading a book and preferably before, doing is the way to learn programming. Worst case, you'll decide later to re-design a lot of your code. But you will have used your time in learning much more, more relevant for your specific needs, than with any toy exercises.
Re: how to define my own traits
On Monday, 27 March 2017 at 16:28:13 UTC, Gary Willoughby wrote: Even Andrei was baffled: http://forum.dlang.org/thread/nepm2k$311l$1...@digitalmars.com I see... And Walter went further and reported it as a DMD bug (still open clearly). It's what I mean. This strange behavior is more typical of C++, in D this is a rare corner case, but I can sympathize if Andrei and Walter don't want to accumulate issues like this one in the language, and on top of that fill the standard library and user code with this kind of workarounds. First the solution is a hack, but ideally it wouldn't be needed, the original code should have worked with inout ranges all the same. So ideally DMD should be fixed to make the hack unnecessary. Andrei's proposal of deprecating inout entirely is also consistent at the expense of losing a feature. When I first read about inout as a device to obviate code duplication typical in C++ const ref overloads, I liked it but I assumed it was implemented by lowering it into the actual duplicate overloads. Though I'm not even sure right now if such overloading is allowed in D. I haven't tried if this happens with other compilers than DMD...
Re: how to define my own traits
On Monday, 27 March 2017 at 00:49:14 UTC, Moritz Maxeiner wrote: Have you tried it without the dummy parameter on the example given in the bug report [2]? I see, thanks for finding it! Looks a bit hacky but I can live with it. Indeed if I remove the argument from Phobos, Martin's example breaks again. Incidentally, everything keeps working if I qualify the function literal as (inout int = 0) pure
how to define my own traits
I've looked into Phobos to emulate it when defining my own trait template, and when I see this: module std.range.primitives; // ... template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke popFront() auto h = r.front; // can get the front of the range })); I wonder, why that unused parameter (inout int = 0)? In my project () { /* ... */ } works the same for a custom trait.
Re: really why module declarations?
On Sunday, 26 March 2017 at 20:58:24 UTC, Adam D. Ruppe wrote: Module declarations are only optional in the most trivial case that is rarely useful in real world code. I recommend you ALWAYS use them (and always put a ddoc comment on them!), and moreover that you avoid top name modules (use `myproject.modname` instead of `modname`) to avoid conflicts. OK I was already doing it all this in the multi-file project. I was curious but I guess it's long to explain the different things that can go wrong if one doesn't declare module names. Followup question: if I am inside module myproj.pack1.mod1 and want to import myproj.pack1.mod2... should I import myproj.pack1.mod2; or import mod2; ?
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
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
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: 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: 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: 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: 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
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: 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.
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: 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: 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 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: 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: 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 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: 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: 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 = [ , , , , , , , , , , ]; 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 :)
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: 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 ;)
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: 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: 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 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 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; [, , , ]) 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?
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 ???
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; [, , , ]) enforce(*p > 0); } body { /* ... */ }
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
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 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: @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.
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
@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?
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