Re: Learning delegates
On Sunday, 8 September 2019 at 10:04:57 UTC, Joel wrote: I'm trying to understand delegates. Is there any good ways I can get a better understanding of them? Simple, don't make it harder than it is. Delegates are basically functions... that is, function pointers(they point to some function somewhere in space)... BUT they include a "context". The context a scope. { // In some scope int x; d = () { writeln(x); }; } () { writeln(x); }; is the function defined as a lambda(inline). It accesses a variable outside of it, that is, in the scope... which is called the context. d is the delegate, it is a function pointer that holds the function AND the context pointer. We can then do d(); which called/executes the function... the function is called, and x can be referenced because d stores the context. If you do not understand functions, then function pointers, you can't understand delegates.
Re: Function Arguments with Multiple Types
On Friday, 6 September 2019 at 20:02:35 UTC, Bob4 wrote: Hi, I'm coming from a background in Python, without a lot of experience in statically typed languages, and I'm struggling to see how to make a certain function in D. This is what I have in Python: ``` from typing import Union Number = Union[int, float] def clamp(value: Number, mini: Number, maxi: Number) -> Number: if value >= maxi: return maxi if value <= mini: return mini return value ``` In Python, I could supply this function with any type really; it doesn't type check, and essentially only runs `value.__ge__(maxi)` and `value.__le__(mini)`. How can I simulate this in D? There are already implementations of `clamp` out there, but that isn't the point. I hear that there is a "variant" type, that allows one to pass any type; but I either want to restrict it to certain types, or only to types that possess some kind of `__ge__` or `__le__` method. The only way I found on how to do the former was overloading, like: ``` bool test(int a) {...} bool test(float a) {...} ``` Unfortunately this doesn't seem to work well with the return type, and I feel like it's wrong to rewrite identical functions over and over. Do you know algebra? You know, x? x has a type. That is, it is a class that represents all numbers(usually reals at least but sometimes it's integers or complex or vectors or whatever). In statistically typed languages one must always specify the type int foo(float x) In a dynamically typed language one does not have to specify the type but then one can corrupt data by treating the value as the wrong type. So effectively one has to do static typing in their mind and keep track of everything. Dynamic typing simply allows one to avoid verbosity because they can reuse a variable and treat it differently... the cost is safety. In meta programming, one can sorta do both: A foo(T)(T x) Here T stands for the type, but it is like x in algebra but instead of numbers it can be types. So T can be any type and so it is sorta like dynamic typing... so what's the point then? Well, T can't necessarily be anything and one can check the type using meta programming. What happens is that the compiler can determine what T is suppose to be by how the programmer is using it and this then allows it to revert to static typing internally and get all the safety: e.g., int x; foo(x); double y; foo(y) Now we know that T is being treated as an int in the first case and double in the second. The type is transitive, meaning that the compiler can trace out the type from the call/usage. Inside foo, though, T is sorta like being dynamic and we have to be more careful by telling the compiler what exactly we want T to do. So, we have dynamic <---meta> static and meta sits in between. It gives us the best of both worlds because we can be dynamic and static all in the right places(it's not totally dynamic but as close as one can get and still be fully dynamic). Dynamic is totally typeless static is fully typed and meta allows us to finagle between them to some degree. The cost is that we have to write more complex code to deal with the typing. Number = Union[int, float] def clamp(value: Number, mini: Number, maxi: Number) -> Number: if value >= maxi: return maxi if value <= mini: return mini return value Your number is a union of two types. Either int or float. In D, you do the same thing a number of ways(there is the algebraic type which looks to be the same as Union). auto clamp(A,B,C)(A a, B b, C c) { static if (is(A == int)) { // evaluated only if A is an int) } So now one has deal with what A really is inside the function and so one need extra code... clamp(3, 5.0, "asdf"); inside clamp A is int, B is real, and C is string FOR THAT CALL ONLY! If we call clamp again: clamp(5.0, "asdf", new C); Now A is a real, B is a string, and C is a C class type. The two functions may look the same but in fact the compiler essentially builds two different functions. We essentially have to combine all the code... or we could overload and ignore meta programming. In any case, it is not very difficult, it just seems complicated. If you are used to programming in one language you will have to get used to another. The thing is, if you actually can program then it is really nothing new... you do all of it in your head or use the language to do the same thing all these languages are Turing complete and so nothing is new under the sun.
Shadertoy in Dcompute?
How hard would it be to do something like Shadertoy in Dcompute and would it be any faster? I don't like the basics of Shadertoy, lots of nonsense to do basic stuff. E.g., to work with complex numbers one must essentially do everything manually. Would there be any benefit using Dcompute(last time I tried it I couldn't get it to work).
Re: error : outer function context of `D main` is needed to `new` nested class `main.main.X`
On Thursday, 15 August 2019 at 02:23:06 UTC, Adam D. Ruppe wrote: On Thursday, 15 August 2019 at 01:55:17 UTC, Bert wrote: void main() { class X { ... } I would just make it `static class X` and then it should work fine. Won't be able to access main's local variables then though, but you could pass the necessary ones through the constructors or something. That might work, I can't think of the case where I would need to access them, although some could exist. It's not a general solution though. I've came up with a work around that isn't great but seems to work. So the whole point of this is that the class cannot be constructed because a context pointer won't exist outside of main? It seems that things were done backwards, the class never references anything outside it and for all practical purposes is static... seems that all classes should have been default static and something like `nonstatic class` should have been required to capture the context. Or better yet, some way to construct the class if is effectively a static class to get most use cases and error else rather than just scrub all possibilities. e.g., maybe there could be a way to construct the class manually(emplace?) and just use a null context pointer and hope for the best or somehow figure out if it requires a context and if so then error? If the outer context can be captured by the function, then it could be passed to emplace. For example, one could pass a delegate and use it's context pointer, and as long as it is the same as the context the class is defined in, then it should be used? I am using emplace now to construct the class and it seems to work without the error but, of course, the context will be wrong. Is there any way to somehow get the context properly? (since these things are relatively fixed in code so should the context and one should be able to statically reference it with the appropriate symbol?) So basically I can essentially do what I said above with emplace but this is error prone without a proper context. I assume that when a class is defined, the outer is always the context of where the class is defined and not where it is created. If this is true, and it should be since it would make no real since other wise(unless one was very careful) then one would be able to reference that context statically. e.g., X.Context should return the context for the class X. I haven't been able to figure out how to do this though and I will just rely on my original workaround for now since it is safe.
error : outer function context of `D main` is needed to `new` nested class `main.main.X`
void main() { class X { ... } auto f = foo!X; } then in another module I have a templated function foo that simply new's x: auto foo(T)() { return new T; } yet I get the error. I realize that X is local to main and I realize I could do something like foo(new X); but that completely defeats the purpose(my context is more complicated). I need to construct X, not have the user do it. I thought the templated function would be instantiated at the call site? I've tried to "hack" it in various ways but nothing works. I've imported the model, but since X is local to main it can't be seen. I've tried to fully qualify it but it can't be found. main.main.X says something about void(the return type of main()): no property `` for type `void`. template foo(T) { alias foo = T; alias foo = () { return new T; }; // or } then I can do new foo!T, but I cannot actually construct T like I need to. I cannot seem to return a proper type either. I've tried returning a lambda and so on, but D is enforcing the type be accessible even if the function will be used in the correct context. I don't understand stand why it is a problem when the template functions are suppose to be instantiated at the call site. Seems like a complete pain just to be able to construct a type outside it's context(but the construction is totally within the context, or should be. I'm simply trying to provide a simple wrapper that does some boilerplate and makes everything look nice).
Re: Local static class fields
On Tuesday, 13 August 2019 at 00:17:13 UTC, DanielG wrote: On Monday, 12 August 2019 at 22:48:43 UTC, Bert wrote: I have a recursive class structure(think of a graph or tree) and I need to keep a global state for it, If I'm understanding the problem correctly, it seems like you have a choice to make: either "bloat" the child nodes by the size of a pointer/reference to the shared tree state (4 or 8 bytes), or forego that by traversing the tree (from child to root node) every time you want to access the state. Yes. It's the typical size/speed issue, if, for example, one could somehow use pointer manipulation. If, say, all the nodes could be allocated using special pointer where the first node could be calculated then it would solve both problems optimally(e.g., ptr & 0x/class_size). Of course this is someone rediculous. In my use case the tree is fixed but it might not always be. I was just curious if there was some trick or if's impossible to really make it happen. But if you don't want traversal every time, you're going to have to cache some kind of pointer (or Tree ID in the case of a central dictionary). I suppose if you got down to the nitty-gritty maybe you could use an 8- or 16-bit value for the key ID? (Disclosure: I know absolutely zero about how D lays out classes and structs in memory, this might not save any memory at all) I guess I could wrap some nodes that contain a pointer to the data equally spaced throughout the hierarchy and that will reduce overhead. E.g., The kNth node has a pointer to the state. This reduces the wasted memory by kN and limits the traversal depth to a max of kN. This might be the easiest method that provides the best of both words. Just inherit from Node and cast to check if it contains the info. It would help if you could provide some rough metrics: - How deep you expect each recursive structure to be (from root to deepest leaf node) - How many total nodes you expect to have across all trees (such that adding a single pointer to each instance would be memory-prohibitive) - How often each node will have to access the shared state (such that traversal-every-time would be too slow) That might help in figuring out the best approach. These are all unknown, it is a general solution. Obviously since these are tree's the depth isn't going to be astronomical but they could be quite deep since arrays are technically tree's.
Re: Local static class fields
On Tuesday, 13 August 2019 at 12:22:45 UTC, Simen Kjærås wrote: On Tuesday, 13 August 2019 at 08:41:02 UTC, Bert wrote: On Tuesday, 13 August 2019 at 04:43:29 UTC, Paul Backus wrote: It seems to me like the obvious solution is to use two different classes, one to store the global state, and one to store the individual objects in your structure. For example: class Tree { State state; Node root; } class Node { Node[] children; } Yes, I forgot to mention this as a solution. I was going to go in to more detail. This is not a great solution because it requires a base class simply to hold the "global" state and it requires nodes to have an accessor(they won't know which tree they come from). What you're essentially looking at here is my solution 4): class Node { Node parent; Node[] children; @property State state() { return parent.state; } } class Root : Node { State treeState; override @property State state() { return treeState; } } class State {} What I was thinking though, with D's capabilities, if a constructor could somehow return a "Voldemort" type that makes it all work out. e.g., class Tree { State state; Node root; alias root this; } then the constructor just returns tree which acts as an node. It doesn't have to be a voldemort but it at least hides some of the details... Ultimately it is not too different from using a dictionary though, effectively does the same thing. Something like this may be possible, but it will still need to keep around a pointer to the context (likely the root), costing you the exact same as having a pointer to either the root or the state in each node: class Root { State state; this() { state = new State(); } auto newNode() { class Node { State getState() { return state; } } return new Node(); } } class State { } unittest { auto root1 = new Root(); auto node = root1.newNode(); assert(node.getState() == root1.state); // Note that Node keeps track of its context, thus taking up more space: assert(__traits(classInstanceSize, typeof(node)) > __traits(classInstanceSize, State)); } There may be no way around such a problem in that these might be "optimal". Your's, which added parent in node, might be better since a dictionary doesn't have to be directly maintained. Also, if space is a concern, the dictionary is actually worse than adding a pointer to the state in each node, as the internal book-keeping of the dictionary is more than one pointer's worth per entry (at the very least it needs to keep both the hash of the Node and the pointer to the state). I'd like to get away from actually having a different "root" type though. Mainly because it reduces uniformity and complicates the design I already have. If I could hide all these things and it is not too complicated then it would work better for me. The solution of having a Root class that derives from Node causes complications in three situations: When you create a new tree, when you move a subtree to become a new tree, and when you move a tree to become a subtree. The last two may or may not actually occur in your code, but without knowing more, I have no idea if that's the case. I'm fairly certain you will at some point be creating new trees, though. If the creation of new trees is confined to one or two functions while the creation of new nodes is widespread, this special-casing of roots should be easily manageable. However, since you specifically mention in this post that Paul 'added parent in node', you should definitely go with a pointer to the state in the Node, as per my earlier post. It's faster, you pay the memory cost anyway, and it's easy for maintainers (that's you in 6 months cursing your young-and-careless self) to understand what's going on. Actually, there's one complication with having a pointer to the state in each node that we haven't mentioned: is the state often replaced wholesale? That is, not just its contents changed, but can the state of a tree suddenly point to a wholly different instance of the same class? If each node holds a pointer to it, then this operation is costly. However, this is generally easy to fix/avoid by a) favor mutation over reassignment, or b) another layer of indirection. Generally no, I think that your solution is not great. There is no reason to contain a pointer in each node. I mentioned in the other reply that there might be better alternative, a hybrid. Basically class StateNode : Node and then use a limited traversal. Replace every kth node with a StateNode and simply traverse up to it. One is guaranteed to find one within kN steps and on average half that. It also then reduces memory requires by kN. This seems to be the best all around approach. It still requires some type of construction but this might be done behind the scenes by sil
Re: Local static class fields
On Tuesday, 13 August 2019 at 04:43:29 UTC, Paul Backus wrote: On Monday, 12 August 2019 at 22:48:43 UTC, Bert wrote: Making a field static is effectively a global variable to the class. I have a recursive class structure(think of a graph or tree) and I need to keep a global state for it, but this state actually needs to be different for each tree object. The reason for this is that structurally it will not change per tree and if it it is not static then it wastes space unnecessarily. [...] Is there any way to do this more naturally in D? It seems to me like the obvious solution is to use two different classes, one to store the global state, and one to store the individual objects in your structure. For example: class Tree { State state; Node root; } class Node { Node[] children; } Yes, I forgot to mention this as a solution. I was going to go in to more detail. This is not a great solution because it requires a base class simply to hold the "global" state and it requires nodes to have an accessor(they won't know which tree they come from). What I was thinking though, with D's capabilities, if a constructor could somehow return a "Voldemort" type that makes it all work out. e.g., class Tree { State state; Node root; alias root this; } then the constructor just returns tree which acts as an node. It doesn't have to be a voldemort but it at least hides some of the details... Ultimately it is not too different from using a dictionary though, effectively does the same thing. The main issue with your solution is that Nodes themselves do not have access to the state directly and that is a similar issue with the dictionary. One has to traverse up to the root and then get the state, in your case, Tree would have to inherit from Node so it could be cast and be the root(else the Node would have to reference the tree). There may be no way around such a problem in that these might be "optimal". Your's, which added parent in node, might be better since a dictionary doesn't have to be directly maintained. I'd like to get away from actually having a different "root" type though. Mainly because it reduces uniformity and complicates the design I already have. If I could hide all these things and it is not too complicated then it would work better for me.
Local static class fields
Making a field static is effectively a global variable to the class. I have a recursive class structure(think of a graph or tree) and I need to keep a global state for it, but this state actually needs to be different for each tree object. The reason for this is that structurally it will not change per tree and if it it is not static then it wastes space unnecessarily. class X { X[] x; static State s; } making s non-static has the problem that every X will allocate storage for s wasting space since for any instance chain of X's they will all have the same s. Making it static though then makes it the same for all instance chain's of X, of which it should be local to each. One way around this is to use an dictionary that associates each state to each instance chain. That is there is a initial X that is the parent of the chain and we can then associate a state to it's address, any other chain will have a different initial X and so we can get a new state. class X { X[] x; static State[X] s; } This is not a huge difficulty to do but does require finding the initial X to use, which is not difficult but wastes cycles for large chains. There will, of course, be a constructor that constructs a chain and creates a new state for it and updates s. Is there any way to do this more naturally in D?
Ethan: About your wpf/C# and D integration
One of the biggest issues I have with D is properly gui development. It's just a real pain in the ass compared to wpf and C#. I'm curious about what you have done and if it would let me get the best of both worlds. What I'd like to do is write the business end of apps in D and use C# for the gui(with possibly wpf hosting a D gui window in some cases for performance of graphics). I want to leverage D's meta programming to write efficient oop structures. For it to work well the amount of boilerplate has to be minimized and the interfacing between D and C# also has to be minimal. I'd have to be able to access the D types in C# somehow to access the data so it can be visualized. I'm thinking that D could emit some type of interface that allows referencing the objects in C# as if they were C#, more or less(doesn't have to be full blown, but at least fields and basic methods and properties). I'm just not sure how much you've actually achieved in it or how well it works. If it's just as much trouble as using D directly(I use gtk and it works well for the most part but it's a little bit of pain in some ways).
Re: Help me decide D or C
On Wednesday, 31 July 2019 at 18:38:02 UTC, Alexandre wrote: Hi everyone, I would like an honest opinion. I have a beginner level (able to do very small programs) in a few languages such as python, go, C, guile(scheme) and common lisp. I want to pick a language and go deep with it and focus on only one for at least the next 2 years or so. Should I go for C and then when I become a better programmer change to D? Should I start with D right now? The reason I am considering starting with C: since I am a beginner, obvious I will need lots of books, tutorials, videos etc. And I believe C would have more resources and maybe a low level to help with programming in general. And, when I need a more powerful language, I would than learn D. Since you know the good and the ugly of the D programming language I wonder, what you would think would be the best to do right now? Thank you for your help! I will go against the grain: Start with both! Yes! You can do it! You can! In fact, you will do it better! It will be a little harder at first but much faster in the end. D is C... no real difference, just minor stuff. Things take time to sink in, so if you start D and C now you will be further down the road than if you start D later. But if you really want to learn to program I suggest you go with Haskell. You can do them all together too but Haskell is like learning Alien while D is learning German.