Re: How should I return multiple const values from a function?
On Tuesday, 3 January 2023 at 07:41:46 UTC, Salih Dincer wrote: P.S. Actually the code works when we don't use enum. My mistake, I forgot that enum cannot be inferred! Very very sorry, suppose I didn't intervene 😀 Also this has worked: ```d void main() { template Fun(Key, Value) { import std.typecons; alias Tup = Tuple!(const(Key), const(Value)); enum Fun = (Key k, Value v) => Tup(k, v); } string k; uint v; auto res = Fun!(string, uint)(k, v); assert( is(typeof(res[0]) == const(string)) && is(typeof(res[1]) == const(uint)) ); } ``` SDB@79
Re: Solving optimization problems with D
On Sunday, 1 January 2023 at 21:11:06 UTC, Ogi wrote: I’ve read this [series if articles](https://www.gamedeveloper.com/design/decision-modeling-and-optimization-in-game-design-part-1-introduction) about using Excel Solver for all kinds of optimization problems. This is very neat, but of course, I would prefer to write models with code instead, preferably in D. I glanced at mir-optim but it requires knowledge of advanced math. Is there something more approachable for a layperson? Maybe mir-optim and dopt are the only options. You can check JuMP (Julia package and resources). Maybe port some of them to D will be the start of new optim solver package. But in general behind the optimisation problems always lying math..
Re: Solving optimization problems with D
On Sunday, 1 January 2023 at 22:00:29 UTC, max haughton wrote: On Sunday, 1 January 2023 at 21:11:06 UTC, Ogi wrote: I’ve read this [series if articles](https://www.gamedeveloper.com/design/decision-modeling-and-optimization-in-game-design-part-1-introduction) about using Excel Solver for all kinds of optimization problems. This is very neat, but of course, I would prefer to write models with code instead, preferably in D. I glanced at mir-optim but it requires knowledge of advanced math. Is there something more approachable for a layperson? What do you want to optimize? Optimization in general requires reasonably advanced mathematics, whereas a single problem can be simplified. There are a lot of C libraries too that you can call from D for optimization too, but like Max says knowing what you want to optimize helps a lot. Excel’s optimizer works for small problems but chokes if the dimension increases too much.It is probably some sort of nonlinear gradient free solver.
Re: Solving optimization problems with D
On Tuesday, 3 January 2023 at 21:13:55 UTC, Sergey wrote: On Sunday, 1 January 2023 at 21:11:06 UTC, Ogi wrote: I’ve read this [series if articles](https://www.gamedeveloper.com/design/decision-modeling-and-optimization-in-game-design-part-1-introduction) about using Excel Solver for all kinds of optimization problems. This is very neat, but of course, I would prefer to write models with code instead, preferably in D. I glanced at mir-optim but it requires knowledge of advanced math. Is there something more approachable for a layperson? Maybe mir-optim and dopt are the only options. You can check JuMP (Julia package and resources). Maybe port some of them to D will be the start of new optim solver package. But in general behind the optimisation problems always lying math.. I have a wrapper for the R optimization libraries somewhere. It lets you call the same C libraries underlying R's optim, with the option to choose the algorithm. Haven't used it in a while, but as I recall it was pretty easy to use. I probably also wrapped some of the third-party R optimization libraries at some point.
Is there a way to enforce UFCS?
Say you have the following class which represents a dog 🐶: ```D class Dog { @property { string name(); void name(string name) { _name = name; } } private { string _name; } } ``` And you have the following code with constructs a `Dog` object: ```D void main() { Dog d = new Dog(); d.name = "Poodle"; writeln(d.name); } ``` In the code we can see that we have utilized UFCS (universal function call syntax) to set the properties for the object. This feature is great. We have also used D's `@property` annotation which gives us some other advantages that you can see in the documentation. The issue I have is that UFCS is not enforced, which I thought would be a rather good use for the `@property` annotation. This means that we can do the following in our code: ```D void main() { Dog d = new Dog(); d.name("poodle"); writeln(d.name()); } ``` I prefer the UFCS version over the non-UFCS version since it is more clear that it is a property and it matches closely with the official D style guide. I am disappointed that `@property` does not enforce UFCS, as I believe that it would add to its usefulness. Sometimes throughout my codebase I get confused and write properties in non-UFCS syntax, which bugs me a bit. My question is: is there a way to enforce UFCS-syntax?
Re: Address of a class object
matheus, using dmd64 on my laptop to compile and run this: ```d import std.stdio, std.traits; class MyClass {char[16] c;} void main() { writeln(" Size Alignment Type\n", "="); size_t size = __traits(classInstanceSize, MyClass); size_t alignment = classInstanceAlignment!MyClass; writefln("%4s%8s %s",size, alignment, MyClass.stringof); // my test code added auto MyClassO1 = new MyClass(); auto MyClassO2 = new MyClass(); writeln("\nMyClassObj1 MyClassObj2"); writeln(cast(void*)MyClassO1,"\t",cast(void*)MyClassO2); } ``` I get this: ``` Size Alignment Type = 32 8 MyClass MyClassObj1 MyClassObj2 21EF8E22000 21EF8E22020 ``` If I change this line to: ``` class MyClass {char[1] c;} ``` I get this: ``` Size Alignment Type = 17 8 MyClass MyClassObj1 MyClassObj2 27727202000 27727202020 ``` If my size is 17 bytes and my alignment is 8 bytes, shouldn't my MyClassObj2 in this example be @ 277272020**18** ?
Why does this code only work with `T` and not `typeof(T)`?
I am using the CSFML D bindings, and I am creating my own `draw` template function. I first check that the object passed in is of the appropriate type, and if it is, I call the appropriate function: ```D template isDrawable(T) { enum isDrawable = is(T == sfCircleShape*) || is(T == sfRectangleShape*) || is(T == sfText*) || is(T == sfSprite*); } void sfRenderWindowExt_draw(T)(sfRenderWindow* renderWindow, T obj) { static assert(isDrawable!T, format("Cannot call any draw method on type %s", T.stringof)); if (is(T == sfCircleShape*)) { renderWindow.sfRenderWindow_drawCircleShape(cast(sfCircleShape*)obj, null); } else if (is(T == sfRectangleShape*)) { renderWindow.sfRenderWindow_drawRectangleShape(cast(sfRectangleShape*)obj, null); } else if (is(T == sfText*)) { renderWindow.sfRenderWindow_drawText(cast(sfText*)obj, null); } else if (is(T == sfSprite*)) { renderWindow.sfRenderWindow_drawSprite(cast(sfSprite*)obj, null); } } ``` For some reason, if I replace the `isDrawable` template with the following (using `typeof`), the code does not compile: ```D template isDrawable(T) { enum isDrawable = is(typeof(T) == sfCircleShape*) || is(typeof(T) == sfRectangleShape*) || is(typeof(T) == sfText*) || is(typeof(T) == sfSprite*); } ``` This is really strange, as I assumed that the two pieces of code were essentially the same. Any help as to why this is the case would be appreciated.
Re: Is there a way to enforce UFCS?
On 1/3/23 19:42, thebluepandabear wrote: > @property { As your post proves, that feature is at most half-baked and is discouraged. Today, there is just one known obscure effect of using it. > void name(string name) { > _name = name; > } > d.name = "Poodle"; > In the code we can see that we have utilized UFCS (universal function > call syntax) UFCS is for calling free-standing functions as if they are member functions. Since your example already uses member functions, this feature is not UFCS. And I don't think it has a name. It is always possible to pass a single-argument with the assignment syntax: void foo(int i) {} void main() { foo = 42; } Pretty wild! :) But that's what makes your assignment above work. (Not UFCS.) > not enforced [...] we can > do the following in our code: > d.name("poodle"); I don't see a problem with that. :) > I am disappointed that `@property` does not Many people are disappointed that @property is pretty much useless. > is there a way to enforce D gives us the tools to do that but it's not trivial. The function can return an object that represents a variable (member variable or not). And an assignment to that representative object can set the actual variable. However, I tried to achieve it with an intermediary object but failed because the same ="Poodle" syntax broke it and demanded that we type the empty parenthesis. So, I think what you want does not exist. // I have a feeling something similar exists in Phobos // but I could not find it. // // This is a reference to any variable. struct MyRef(T) { T * ptr; void opAssign(T value) { *ptr = value; } void toString(scope void delegate(in char[]) sink) const { sink(*ptr); } } // This is a convenience function template so that // the users don't have to say e.g. MyRef!string // themselves. (See name() below.) auto myRef(T)(ref T var) { return MyRef!T(&var); } class Dog { @property name() { return myRef(_name); } private { string _name; } } void main() { Dog d = new Dog(); // Great: The following won't work. // d.name("poodle"); // However, now there is the empty parenthesis. :( d.name() = "Poodle"; import std.stdio; writeln(d.name); } Ali
Re: Why does this code only work with `T` and not `typeof(T)`?
On 1/3/23 20:11, thebluepandabear wrote: > if I replace the `isDrawable` template with the > following (using `typeof`), the code does not compile: It must be because T is already a type. It's the same reason why the following code fails to compile: void main() { alias T = int; alias TT = typeof(T); } Error: type `int` is not an expression And the error message tells us typeof requires an expression. What you can do is to use T.init and the code should now work like the following does: alias TT = typeof(T.init); Ali
Re: Why does this code only work with `T` and not `typeof(T)`?
On Wednesday, 4 January 2023 at 04:42:08 UTC, Ali Çehreli wrote: On 1/3/23 20:11, thebluepandabear wrote: > if I replace the `isDrawable` template with the > following (using `typeof`), the code does not compile: It must be because T is already a type. It's the same reason why the following code fails to compile: void main() { alias T = int; alias TT = typeof(T); } Error: type `int` is not an expression And the error message tells us typeof requires an expression. What you can do is to use T.init and the code should now work like the following does: alias TT = typeof(T.init); Ali Ok, that makes sense now, my mistake. I seem to have gotten the wrong impression that typeof is more flexible than it is.