Product Versioning Microservices
I go into microservices engineering in view of docker and I have 3 microservices, which together make one item for instance "CRM framework". Presently I need my customer to have the capacity to update his item, at whatever point he needs to. I have 3 distinct renditions of my microservices, which one should customer see? I figure item form ought to be autonomous of microservices, since duplicating one of the microservices variant would raise me go into more hell than having no rendition by any stretch of the imagination. So is there any example, thought to deal with such circumstance? The main thing that rings a bell is to have another store which will be formed at whatever point one of the microservices https://mindmajix.com/microservices-training will deliver generation prepared bundle. Nonetheless, I currently have a form, which none of my Product Owners (PO) could ever think about.
Re: On Forum Moderation
On Sunday, 27 May 2018 at 05:30:22 UTC, TheUncivilServant wrote: On Sunday, 27 May 2018 at 04:57:20 UTC, SlimeBag wrote: surely the best form of professional etiquette is to NOT be offended by what others say. as soon as you ignore that etiquette, it's a slippery slope to utlimately controlling others. I agree. One can also argue, that for those who are intent on practisiing 'etiquette', those who are not practicing 'etiquette', become (initially) an irritant (to those intent on practicing 'etiquette'). Eventually, this cultivates into a 'hatred' (of those not practicing 'etiquette'). So, 'etiquette' actually leads to an uncivilised society. The 'victorian era' of Emily Post, was stife with 'etiquette', and is why Freud had so many patients. This is precisely why their are so many problems in the world. So many people believe that the way to achieve some imaginary ideal is to forcibly go that way and just through "banging ones head" enough it will magically materialize. What happens, at least in the long run, in fact is that they do the exact opposite of what they were trying to achieve. You can point to any number of the major social issues and see that they have progressively worsened precisely because of the people supposedly trying to make things better have done this. So society progressively gets worse in many areas and more and more people come out to "fix" things only to dig the hole deeper. Sometimes people just need to be told off, sometimes people need to be shot, some times people need bad thing to happen so that worse things don't. Humans can't control everything and trying only makes things worse. It's built in to the system. The Heisenberg uncertainty principle is built in to everything. It is applicable not just to atoms but things composed of atoms like love(which is a very complex system of atoms), gun rights, education, etc. It's bad enough that humans are pretty clueless about the true complexities of the universe but their ignorance in the very basic concept of balance is what really makes the world the way it is. Westerners tend to be extremely ignorant of balance for some reason.
Re: Why 'getSymbolsByUDA' filters private members?
On Sunday, 27 May 2018 at 17:42:15 UTC, Sobaya wrote: I'd like to get symbols that have an UDA. But when the member is private, it is not obtained. And I found a comment saying "Filtering inaccessible members" in the source. Why is it necessary to filter out private members? Since the members are private, they're not visible to code in other modules. getSymbolsByUDA is in std.traits, which is another module, so code in it can't interact with the private members. There is definitely an argument to be made for allowing reflection access to private members from other modules, but the buck has to stop somewhere, and this is a complex problem. If 'private' is to respected at all, clearly we can't have a different module call our private methods, or read our private fields. That means something as simple as a wrapper around a function can't work. -- Simen
Re: On Forum Moderation
On Saturday, 26 May 2018 at 03:34:50 UTC, Walter Bright wrote: From time to time, the issue comes up. The standard here is professional demeanor. For what professional demeanor is, see: https://www.amazon.com/Etiquette-Society-Business-Politics-Home/dp/1497339979 Unprofessional demeanor will get removed at the forum staff's sole discretion on a case by case basis, as well as replies to it. For unprofessional demeanor, I recommend reddit. Why can't we just follow 'the presidential guide to etiquette', instead of that old, outdated stuff from the 1900's? https://www.nytimes.com/interactive/2018/05/25/opinion/editorials/Donald-Trumps-Guide-To-Presidential-Etiquette.html
Re: D's Destructors are What Scott Meyers Warned Us About
On Sunday, 27 May 2018 at 22:27:52 UTC, sarn wrote: I've been thinking this through a bit, and here's what I've got so far: Here's a tweak that should be implementable without any language changes: Instead of trying to detect an empty destructor, we use a UDA on the class --- call it BaseObject or something. A BaseObject-marked class is meant to be something like Andre's ProtoObject, or a custom alternative base. It must not define a destructor or include members with destructors (could relax this in future but works for now), and must only inherit from other BaseObject-marked classes. With that, __vdtor could be implemented using a template mixin. For a BaseObject class, that would generate an empty virtual __vdtor. For other classes, it would call __xdtor and then (non-virtually) call __vdtor for the superclass as long as it's not a BaseObject class. Can anyone see something I've missed? I think it works with the current type system, makes Andre's ProtoObject possible while supporting subclassing with @nogc or whatever, and gives us safe class destructors that could be compatible with C++.
Re: SecureD Futures (v2.0)
On Monday, 28 May 2018 at 02:25:20 UTC, Adam Wilson wrote: I like it. But it does require more space. We need three salts and three lengths in the header. One for the PBKDF2 KDK, one for the MAC key, and one for the encryption key. HKDF-Expand doesn't need a salt. You just need one salt to make the KDK (whether you use PBKDF2 or HKDF-Extract for that) and no extra salts for deriving the encryption and MAC key.
Re: General problem I'm having in D with the type system
On 05/27/2018 04:50 PM, IntegratedDimensions wrote: On Sunday, 27 May 2018 at 18:16:25 UTC, JN wrote: On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: animal a = new cat(); a.f = new food() auto c = cast(cat)a; as now f in cat will be food rather than catfood. I think the problem is in your hierarchy. If Animal can have Food, that means that any animal should be able to accept any food, without knowing what kind of food is this. Cat requiring cat food is a leaky abstraction, the cat shouldn't know nor care what kind of food it gets, as it's an animal and it will eat any food. This is clearly false. A Kola does not eat any type of food, nor does a whale or most animals. Exactly. That's why your hierarchy is wrong. If any Animal COULD eat any food, THEN you would want the Animal class to contain a Food object. Clearly that's not the case. Clearly, any Animal CANNOT eat any food, therefore the Animal class should not contain a Food object. At least, I think that's what JN was saying. Of course, removing Food from the Animal class *does* cause other problems: You can no longer use OOP polymorphism to tell any arbitrary Animal to eat. (Part of the problem here is that using base classes inherently involves type erasure, which then makes a mess of things.) Honestly though, the real problem here is using class hierarchies for this at all. Yea, I know, OOP was long held up as a holy grail. The one right way to do everything. But it turned out class hierarchies have a lot of problems. And you're hitting exactly one such problem: There's many modelling scenarios they just don't fit particularly well. (And this isn't a D problem, this is just OOP class hierarchies in general.) D has plenty of other good tools, so it's become more and more common to just avoid all that class inheritance. Instead of getting polymorphism from class inheritance, get it from templates and/or delegates. Things tend to work better that way: it's more flexible AND gives better type safety because it doesn't necessitate type erasure. This does involve approaching things a little bit differently: Instead of thinking/modelling in terms of nouns, think more in terms of verbs. It's all about what you're *doing*, not what you're modelling. And prefer designing things using composition ("has a") over inheritance ("is a"). So, regarding the Animal/Food/Cat/CatFood example, here is how I would approach it: What's something our program needs to do? For one, it needs to feed an animal: void feedAnimal(...) {...} But in order to do that, it needs an animal and a food: void feedAnimal(Animal animal, Food food) { animal.eat(food); } That's still incomplete. What exactly are these Animal and Food types? We haven't made them yet. There are different kinds of animal and different kinds of food. We have two main options for handling different kinds of Animal and Food, each with their pros and cons: There can be a single Animal/Food type that knows what kind of animal, or each kind of animal/food can be a separate type. A. Single types (many other ways to do this, too): struct Animal { enum Kind { Cat, Dog, Bird } Kind kind; // Eating is overridable: void delegate(Food) customEat; void eat(Food food) { enforce(food.kind == this.kind, "Wrong kind of food!"); if(customEat !is null) customEat(food); else writeln("Munch, munch"); } Food preferredFood() { return Food(kind); } } struct Food { Animal.Kind kind; } Animal cat() { return Animal(Animal.Kind.Cat, (Food f){ writeln("Munch, meow"); }); } Animal dog() { return Animal(Animal.Kind.Dog, (Food f){ writeln("Munch, woof"); }); } Animal bird() {...} Animal[] zoo; B. Separate types (many other ways to do this, too): import std.traits : isInstanceOf; import std.variant : Variant; struct Cat { void eat(Food!Cat) { writeln("Munch, meow"); } } struct Dog { void eat(Food!Dog) { writeln("Munch, woof"); } } struct Bird {...} enum isAnimal(T) = /+ however you want to determine whether a type is Animal +/ struct Food(Animal) if(isAnimal!Animal) {} enum isFood(T) = isInstanceOf!(Food, T); void feedAnimal(Animal, Food)(Animal animal, Food food) if(isAnimal!Animal && isFood!Food) { // Compiler gives error if it's the wrong food: animal.eat(food); } Variant[] zoo;
Re: SecureD Futures (v2.0)
On 05/27/2018 05:11 PM, sarn wrote: On Sunday, 27 May 2018 at 10:27:45 UTC, Adam Wilson wrote: struct cryptoHeader { ubyte hdrVersion; // The version of the header ubyte encAlg; // The encryption algorithm used ubyte hashAlg; // The hash algorithm used uint kdfIters; // The number of PBKDF2 iterations ubyte authLen; // The length of the authentication value ubyte saltLen; // The length of the PBKDF2 salt ubyte ivLen; // The length of the IV ulong encLen; // The length of the encrypted data ulong adLen; // The length of the additional data } Should there be any kind of key identifier, or do you consider that a separate issue? hashAlg is used for everything related to key derivation. Salts and IVs are random. - MacKey = PBKDF2 over EncKey once using same inputs as EncKey How about this? Use PBKDF2 to generate a key-derivation-key (KDK), then use HKDF-Expand (https://tools.ietf.org/html/rfc5869) to derive the encryption key and MAC key separately. I think that's more standard. I don't know how much it matters in practice, but a lot of cryptographers don't like generating MAC/encryption keys from each other directly. I like it. But it does require more space. We need three salts and three lengths in the header. One for the PBKDF2 KDK, one for the MAC key, and one for the encryption key. Something like this: struct cryptoHeader { ubyte hdrVersion;// The version of the header ubyte encAlg;// The encryption algorithm used ubyte hashAlg; // The hash algorithm used uint kdfIters; // The number of PBKDF2 iterations ubyte kdkSLen; // The length of the KDK Salt ubyte macSLen; // The length of the MAC Salt ubyte keySLen; // The length of the KEY Salt ubyte ivLen; // The length of the IV ulong encLen;// The length of the encrypted data ulong adLen; // The length of the additional data ubyte authLen; // The length of the authentication value } Also, it's probably safer to use HKDF-Extract instead of using raw keys directly when not using PBKDF2. It is. And we could dot that if you stick to the default encrypt/decrypt routines. I want to expand the symmetric capabilities of SecureD so I am going to rebuild the encrypt/decrypt routines as a composition of smaller methods. That will allow users to either use the default encryption (simple) or if they have to interoperate with other systems, use the component methods to perform their operations. I am not looking to cover all scenarios though, just the common ones. If you have something truly unusual, you'll still need to drop down the base crypto libraries. -- Adam Wilson IRC: LightBender import quiet.dlang.dev;
Re: using wkhtmltopdf with D
On Monday, 28 May 2018 at 01:28:10 UTC, Dr.No wrote: I'm trying to use wkhtmltopdf[1] with D. I converted this header[2] with little modification using htod tool which resulted in this[3]. The libray is passed to link using: pragma(lib, "wkhtmltox.lib"); (that file is in wkhtmltopdf\lib folder) and the module imported with: import pdf; but it crashes right upon the start with a SEGFAULT: void main() { wkhtmltopdf_global_settings * gs; wkhtmltopdf_object_settings * os; wkhtmltopdf_converter * c; /* Init wkhtmltopdf in graphics less mode */ wkhtmltopdf_init(0); } toolset I'm using: DUB version 1.8.1, built on Apr 29 2018 LDC - the LLVM D compiler (1.9.0): based on DMD v2.079.1 and LLVM 5.0.1 built with LDC - the LLVM D compiler (1.9.0) Default target: i686-pc-windows-msvc Host CPU: skylake http://dlang.org - http://wiki.dlang.org/LDC What's likely the reason of the crash? mismatch between D and C memory alignment? [1]: https://wkhtmltopdf.org/index.html [2]: https://github.com/clowder/wkhtmltopdf/blob/master/src/lib/pdf.h [3]: https://pastebin.com/SrtDUhPf You're missing const on a couple of the pointer parameters, but if it segfaults on calling a function then my question is: is wkhtmltox.lib a library that was generated to link to a dynamic library (is there an associated .dll)? If so you need to ensure that it is loaded and the function pointers are initialised.
Re: using wkhtmltopdf with D
On Monday, 28 May 2018 at 01:28:10 UTC, Dr.No wrote: What's likely the reason of the crash? mismatch between D and C memory alignment? From an ABI point of view, the raw pointers won't care about the memory structure they point to. The function call is the only thing that depends on the binary interface. If you translate the code into C, does it work?
using wkhtmltopdf with D
I'm trying to use wkhtmltopdf[1] with D. I converted this header[2] with little modification using htod tool which resulted in this[3]. The libray is passed to link using: pragma(lib, "wkhtmltox.lib"); (that file is in wkhtmltopdf\lib folder) and the module imported with: import pdf; but it crashes right upon the start with a SEGFAULT: void main() { wkhtmltopdf_global_settings * gs; wkhtmltopdf_object_settings * os; wkhtmltopdf_converter * c; /* Init wkhtmltopdf in graphics less mode */ wkhtmltopdf_init(0); } toolset I'm using: DUB version 1.8.1, built on Apr 29 2018 LDC - the LLVM D compiler (1.9.0): based on DMD v2.079.1 and LLVM 5.0.1 built with LDC - the LLVM D compiler (1.9.0) Default target: i686-pc-windows-msvc Host CPU: skylake http://dlang.org - http://wiki.dlang.org/LDC What's likely the reason of the crash? mismatch between D and C memory alignment? [1]: https://wkhtmltopdf.org/index.html [2]: https://github.com/clowder/wkhtmltopdf/blob/master/src/lib/pdf.h [3]: https://pastebin.com/SrtDUhPf
Re: Naming conventions for export and import members of a struct
On Sunday, May 27, 2018 21:54:42 Per Nordlöw via Digitalmars-d-learn wrote: > The integer type in gmp-z just got export (binary serialization) > support at > > https://github.com/nordlow/gmp-d/pull/8 > > Next up is import (binary deserialization). > > What's the preferred D-style naming convention for wrapping > exporting and exporting to binary formats? > > I'm thinking > > Z.to!(U[]) > > for exporting and > > Z(U[]) > or > Z.from(U[]) > > for importing but I'm not sure. > > Phobos' std.bigint doesn't have any binary serialization so we > can't mimic that. In general, I'd advise against using the function name to. If you use it, then to!(U[])(myZ) and myZ.to!(U[])() will do different things, which could be error-prone. Now, if it just results in a compilation error when you use it with std.conv.to, then that's probably not a big deal, but it will probably be confusing to some users of your library. If you really want using to to do the serialzation, then for better or worse, opCast would be the way that std.conv.to figures out how to convert your type. If you don't want to confuse your serialization with to, or you want it to work with to but also want a more explicit name for the function, then you can always have opCast call another function. If you want it to work with std.conv.to in both directions, then you should be able to do that by overloading opCast for serialization and adding a construtor for deserialization. Then which is called depends on the direction of the conversion, and there's no need for a from function. Now, if you need extra arguments to the functions (as a quick glance at that PR seems to indicate), then std.conv.to isn't going to work, in which case, I don't think that it's a great idea to try to reuse the name, since at that point, it's a bit like overloading an operator to do something different than it normally does, since you're replacing a standard function with one that works differently rather than just providing a way to use a type with the standard function. Personally, I'd probably just have serialize and deserialize functions rather than trying to make them look like std.conv.to, but that's obviously a matter of preference. Either way, because Phobos doesn't really do this sort of thing, there isn't any kind of "official" style or convention for functions like this. It's ultimately up to you and what you like best. I'd just advise that you be careful with overloading to, because if your type _looks_ like it works with std.conv.to but doesn't, that could be confusing and error-prone. I'd advise treating the name to a bit like an operator that you overload and thinking of it that way. - Jonathan M Davis
iz v0.6.18 - Now with a modern, fast, @safe, getopt-like function
Last time i promoted my stuff here there were two compiler/Phobos bugs preventing to activate this nice getopt-like function. specs: - It's based on UDA. - It supports multiple locations for UDA-fied functions and variables. - It doesn't use pointers, UDA-ified variable are accessed without intermediary. - It's faster than the phobos one (although getopt is never a bottleneck) - It's `@safe` and can be even `nothrow` It could be easily added to phobos (just need to convert some EnumSet to BitFlag). - code: https://github.com/BBasile/iz/blob/master/import/iz/options.d#L596 - DUB: https://code.dlang.org/packages/iz - doc: https://iz.dpldocs.info/v0.6.18/iz.options.handleArguments.html - cool demo: https://github.com/BBasile/Coedit/blob/master/dastworx/src/main.d#L18 Note that despite of the run-time compatibility mention in the README, this module is part of a subset of IZ that can be used without all the concept of Nogc as used in iz. (at some point i should split the twos parts).
Re: SecureD Futures (v2.0)
On Sunday, 27 May 2018 at 10:27:45 UTC, Adam Wilson wrote: struct cryptoHeader { ubyte hdrVersion; // The version of the header ubyte encAlg; // The encryption algorithm used ubyte hashAlg; // The hash algorithm used uint kdfIters; // The number of PBKDF2 iterations ubyte authLen; // The length of the authentication value ubyte saltLen; // The length of the PBKDF2 salt ubyte ivLen;// The length of the IV ulong encLen; // The length of the encrypted data ulong adLen;// The length of the additional data } Should there be any kind of key identifier, or do you consider that a separate issue? - MacKey = PBKDF2 over EncKey once using same inputs as EncKey How about this? Use PBKDF2 to generate a key-derivation-key (KDK), then use HKDF-Expand (https://tools.ietf.org/html/rfc5869) to derive the encryption key and MAC key separately. I think that's more standard. I don't know how much it matters in practice, but a lot of cryptographers don't like generating MAC/encryption keys from each other directly. Also, it's probably safer to use HKDF-Extract instead of using raw keys directly when not using PBKDF2.
Re: Getter an lvalue and cannot be modified
On Sunday, 27 May 2018 at 23:21:05 UTC, IntegratedDimensions wrote: I came across a few posts mentioning this after the fact. It's been this way since at least 2012 so... It's now may so not sure how much longer we'll have to wait. That pull seems to have stalled. So close but so far away ;/ It's currently on me to finish the DIP, but I'd rather find a way to implement this in the library, so we can deprecate @property altogether favoring fewer, more powerful language features. The more I think about it though, that's probably not feasible. Anyway, after I finish the DIP it will have to go through the review process, and given the current rate of review, that's going to take a very long time, unfortunately. Mike
Re: Getter an lvalue and cannot be modified
On Sunday, 27 May 2018 at 09:28:36 UTC, Mike Franklin wrote: On Sunday, 27 May 2018 at 09:23:09 UTC, IntegratedDimensions wrote: C[] c; @property C[] get() { return c; } get ~= something; errors out, yet auto q = get; q ~= something; is fine. Why is D thinking that ~= is being applied to get, the function, rather than what it returns? Also When I converted a field in to a property, an AA, it is returning null rather than being initialized by default. Seems like properties are broke. I'd expect a property getter to behave, for all intents and purposes as if it were field. I shouldn't have to have a temp variable to be able to use it as such. You'll probably get your answer and more by reading this: https://github.com/dlang/DIPs/pull/97 I came across a few posts mentioning this after the fact. It's been this way since at least 2012 so... It's now may so not sure how much longer we'll have to wait. That pull seems to have stalled. So close but so far away ;/
Re: Code repetition
On Sunday, 27 May 2018 at 13:20:08 UTC, Adam D. Ruppe wrote: On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote: Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists. I think you might just be using the wrong kind of function. --- import std.stdio; // the helper does the setup then calls another function for specific stuff void helper(void delegate(ref int) specialized) { // setup stuff int x; scope(exit) writeln("exit ", x); // specialized stuff abstracted out specialized(x); } void foo() { helper( (ref x) { x = 34; }); } void main() { foo(); } --- Yeah, this should work. Was hoping there was just a simple way to pull the code out but I guess this provides the best alternative. Thanks.
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 21:16:46 UTC, Neia Neutuladh wrote: On Sunday, 27 May 2018 at 20:50:14 UTC, IntegratedDimensions wrote: The only problem where it can leak is when we treat an cat as an animal then put in dog food in to the animal, which is valid when cat as treated as an animal, then cast back to cat. Now cat has dog food, which is invalid. It sounds like you don't want to have a `food` setter in the `Animal` base class. Instead, you want setters in each child class that take the specific type required, and possibly an abstract getter in the base class. You could use a mixin to ease the process of defining appropriate food types, and you could have a method that takes the base `Food` class and does runtime validation. You might also change `Animal` to `Animal!(TFood : Food)` and go from there. You'd likely need to extract another base class or interface so you can have a collection of arbitrary animals. The problem with all this is that it is not the correct way. For N types you have to scale: Animal(Food, Skin, Eyes, ...). While not having a specific setter in the Animal class does solve the problem of preventing assignment and sorta solve the problem by requiring assignment to occur at the proper object it does not solve the general problem. If we create an animal we should we able to assign it animal food(rather than tools). In a sense this goes a bit too far. Remember, a type hierarchy could be much more complex and we can have types of types which will then all have to follow these "workarounds" resulting if a very complex mess. life domain kingdom phylum class order family genus species ... Within each of these types there are specializations the human species is a type of species in the homo genus, etc. Now, how can we model such a thing be providing maximum compile time typing structure? class life; // Sorta like object, something that can be anything and contains only the common structure to all things that can be considered living class domain : life; ... class species : genus; class human : species; Now, this is all standard. But all types will *use* other types. Humans will use, for example, tools. So we will have another complex hierarchy where tools fall somewhere class tool : object; class hammer : tool; so class human : species { tool[] t; } Now, suppose we have bob the house builder, a human, class houseBuilder : humanWorker; in which we could add a tool to bob auto bob = new houseBuilder(); bob.tools ~= new hammer(); All fine an dandy! This is because tool there is not a natural transformation between human and houseBuilder and tool and hammer. There a hammer being derived from a tool in no way corresponds to a houseBuilder being derived from a human. The "uses" in this case is from types to types and objects to objects (humans use tools and bob uses a hammer). For the structure I am talking about, "parallel inheritance" there is a natural relationship between types to types and types to types that naturally transform in "parallel". To understand this we need to think about something that parallels our taxonomy so that as we inherit through one there is a *natural* inheritance through the other and a sort of "correspondence"(the natural transformation) that keeps everything aligned. Sorta like a ladder where we can only move up and down but each end of a rung. Life ->A Domain ->B ... ->... Genus->X Species ->Y Human->Z houseBuilder ->_ Now, if your paying attention, Human is actually not part of the taxonomy above, it is a specialization of Species. Unfortunately in D we only have one level of typing rather that types of types. We only have a type. The taxonomy above would be a type of a type of an object while humans would be a type of object. So what happens is the different conceptualizations are conflated. Since types can be treated as sets, this is like saying that sets of sets are the same as sets. Well, sets of sets are sets but not all sets are sets of sets, hence they are not exactly the same(it is inclusion rather than equality). {1,2,3} is not a set of sets. (although, it is true we can treat 1,2,3 as sets and so we could say it is but but I don't want to get in to the sets of things that are not sets problem). So, really what we have is that the taxonomy is precisely this paralleling that goes on: Life ->Life Domain ->Eukaryote ... ->...... ... Genus->Homo _> ... ... Species ->Human _> houseBuilder --> bob --> hammer So, for example, Eukaryote's have cells that build things and different ways to class them. Hence "Builders" would have
Re: DIP 1012--Attributes--Preliminary Review Round 1
On Sunday, 27 May 2018 at 13:44:40 UTC, Mike Franklin wrote: I don't know what's happening with this DIP, but I've recently encountered a real-world problem for which there is no palatable workaround that this DIP would likely solve: https://github.com/dlang/druntime/pull/2184#pullrequestreview-120643123 My attempts to workaround the issue I posted at https://forum.dlang.org/post/uhgzgmowqcczczrdt...@forum.dlang.org That PR may be useful for motivating this DIP. Mike It looks like all you need is a way to toggle attributes with a flag, like pure(isPure) or something. IIRC, last time that came up, it turned into a bikeshedding fest about the syntax. (I don't think parentheses works with UDAs.) Anyway, yeah, we need the functionality. However, this DIP is *way* more complicated. I stand by what I said before: https://forum.dlang.org/post/dnmcqwkdfmommiiug...@forum.dlang.org Jonathan M Davis said it in long form: https://forum.dlang.org/post/mailman.5429.1501206646.31550.digitalmar...@puremagic.com
Re: D's Destructors are What Scott Meyers Warned Us About
On Sunday, 27 May 2018 at 09:55:56 UTC, Mike Franklin wrote: TypeInfo has become my nemesis. I've been trying to replace runtime hooks that depend on TypeInfo with templates that can get their information at compile-time, but I'm running into all sorts of problems. e.g. Did you know array.length can be set in @safe nothrow pure code, but it lowers to runtime functions that are neither @safe, nothrow, nor pure? Ouch. Anyway, I'm getting better at modifying the compiler/runtime interface. If we can come up with a solution to this mess, and I can understand it, I might be able to implement it. I've been meaning to learn more about how the compiler/runtime interface works myself but still haven't got around it. I'm probably going to learn a lot by looking at your PRs. I've been thinking this through a bit, and here's what I've got so far: At first I obviously wanted an all-round "just works" low-level interface for destroying objects. But after looking at how people are using __dtor/__xdtor in real code, and looking at the PRs for destroy(), it's obvious that there's a lot of disagreement about what that means. Let's leave that topic for now. If we just focus on fixing classes, we can add, say, __vdtor (I really don't care much about the name, BTW). This needs to be a normal virtual function in the vtable (preferably in a way that's compatible with C++ ABIs) that runs the user-defined destructor code, then recursively calls destructors for members and base classes. The generation of __vdtor also needs a special case to make attributes work. Something like "an empty destructor has attributes inferred like templated functions are, restricted by any of its bases". For example, this needs to work: extern(C++) { class Base { // Virtual ~this() @nogc { } } class Derived { // Not marked pure but is still @nogc // (NB: explicitly marking @nogc isn't needed in current language) override ~this() @nogc { } } class Derived2 : Derived { override ~this() @nogc pure { // Marked pure, but still recurses to empty destructors in Derived and Base } } } Right now __vdtor would need to be implemented with a thunk that wraps around __xdtor (like I implemented here: https://theartofmachinery.com/2018/05/27/cpp_classes_in_betterc.html). But if __vdtor is implemented, the D runtime code can be simplified to use __vdtor for classes, then hopefully we can deprecate and remove __dtor and __xdtor for classes, and then __vdtor can become the native destructor implementation.
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: […] This is a potential suggestion for including such a feature in the D language to provide sightly more consistency. Solving this in the general case requires explicitly allowing, specifying, and tracking covariance and contravariance relations throughout the type system. Object-oriented programming in the usual sense only models arrows in one direction – covariance of return types (and possibly contravariant argument types). As far as I'm aware, there is little more useful to be done without making both compile-time and run-time representations (i.e., type system and memory layout) significantly more complex. The only problem where it can leak is when we treat an cat as an animal then put in dog food in to the animal, which is valid when cat as treated as an animal, then cast back to cat. […] But I've already pointed out two things about this: 1. The hierarchy is maintained to be non-leaky at runtime(I never down cast). […] Even without explicit downcasts, there are still implicit upcasts and covariant `this` pointers. Consider this: --- class Food; class Catfood : Food; class Animal { Food f; void eat() { /+ eat f +/ } } class Cat : Animal { Catfood : Food f; override void eat() { /+ eat f +/ } } Animal a = new Cat; a.f = new Food; a.eat(); // calls Cat.eat() --- As per your problem statement, given a (this) pointer of type Cat – such as in Cat.eat() –, you'd presumably want `f` to be of type Catfood. However, as shown, this is incompatible with Cat being a subtype of Animal. Haskell can handle these situations just fine. Haskell also (mostly) lacks subtyping and mutable data. ––– In general, this is a fun problem to think about – at least if one does not expect to (quickly) come up with generic solutions. Given your Haskell background, you might enjoy having a look at what Scala and others have done with generics for an illustration of what makes this tricky in an OOP environment. As for D, I'd recommend taking a closer look at what your actual design requirements are. If you don't require the full flexibility of arbitrary co-/contravariance relations on an unrestricted set of types, it is likely that you can brew your own subtyping system with template magic to provide exactly the required structure and behaviour. Template application is invariant, so you have full freedom to allow precisely those conversions you want to exist. The implementation will involve structs that internally cast unrelated pointers, but that can be hidden from the interface. You can always package this up as a library if you succeed in making it generally useful. — David
Re: D's Destructors are What Scott Meyers Warned Us About
On Sunday, 27 May 2018 at 21:11:42 UTC, 12345swordy wrote: On Sunday, 27 May 2018 at 18:55:41 UTC, Mike Franklin wrote: And see this talk for a demonstration of the benefits https://www.youtube.com/watch?v=endKC3fDxqs Mike Can you actually reply to me instead of saying "read/watch this"? I'm not going to watch an hour, just to see how you going to achieve this. tl;dw: there's precedent. Historically typeinfo has been overused in the runtime library (I think it's because a lot of the code/architecture predates today's templates). For example, if you compared an int[] to an int[], the compiler would generate a function that looked up a comparator for int using RTTI, and would iterate over the arrays calling it on each element. That video is about replacing code like that with smarter templated code that's not only faster but results in *less* code bloat.
Naming conventions for export and import members of a struct
The integer type in gmp-z just got export (binary serialization) support at https://github.com/nordlow/gmp-d/pull/8 Next up is import (binary deserialization). What's the preferred D-style naming convention for wrapping exporting and exporting to binary formats? I'm thinking Z.to!(U[]) for exporting and Z(U[]) or Z.from(U[]) for importing but I'm not sure. Phobos' std.bigint doesn't have any binary serialization so we can't mimic that.
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 06:59:43 UTC, Vijay Nayar wrote: On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: The problem description is not very clear, but the catfood example gives a bit more to work with. animal -> food || vv cat -> catfood Of course, I'm not sure how to avoid the problem in D of animal a = new cat(); a.f = new food() auto c = cast(cat)a; Cast operations are generally not guaranteed to preserve type safety and should be avoided when possible. But if I understand your description, you have the following relations and transitions: animal owns food catowns catfood animal may be treated as a cat (hence the casting) food may be treated as a catfood (hence the casting) It may be that the inheritance relationship is backwards in your use case. If "animal" may be treated as a "cat", then the inheritance should be other other way around, and "animal" would inherit from "cat". No, this would make no sense. Inheritance is about specialization, taking a type and specifying more constraints or properties to make it more well defined or more specific. Or, simply, a superset. What specific kinds of relationships are you trying to model among what kinds of entities? I've already mentioned this. It is natural for specializations of a type to also specialize dependencies. The animal/cat example is valid. A animal can be any thing that is an animal that eats any food. a cat is an animal that is a cat and eats only food that cats eat. This is true, is it not? cats may eat dog food, it is true, but cats do not eat any animal food. They do specialize. Cat food may be less specialized to some in between thing for this specific case to work but it's only because I used the term cat food rather than some other more general class. Animal -> Animal food Koala -> Koala food A Koala only eats specific types of food, nothing else. We can call that Koala food. As an animal, koala food is still animal food, so casting still works. It is only the upcasting that can fail. But that is true in general(we can't cast all animals to Koala's... and similarly we can't cast all animal food to all Koala food). D's cast will only enforce one side because he does not have the logic deal with dependent parallel types. This is a very natural thing to do. Haskell can handle these situations just fine. With D, and it's inability to specify the relationship dependencies, it does not understand that things are more complex. Hence we can, in D, put any type of food in Koala in violation of the natural transformations we want: (cast(Animal)koala).food = catFood; This is a violation of the structure but allowable in D due to it not being informed we cannot do this. If we had some way to specify the structure then it would result in a runtime error(possibly compile time if it new koala was a Koala and could see that we are trying to assign catFood to a KoalaFood type). auto a = (cast(Animal)koala); a.food = someFood; auto k = cast(Koala)a; k.food =?= someFood; // error of course, if cast worked using deeper structural logic then k.food would be null or possibly k would be null(completely invalid cast). You have to realize that I am talking about applying constraints on the type deduction system that do not already exist but that actually make sense. If you wanted to model the animal kingdom and made a list of all the animals and all the food they ate, there would be relationships. Some animals will eat just about anything while others will eat only one thing. AnimalsFoods ...... If you were to model this in using classes you would want some way to keep some consistency. If you do class Animal { Food food; } class Koala : Animal { } Then Koala allows *any* food... then you have to be careful of sticking in only koala food! But if we *could* inform the compiler that we have an additional constraint: class SmartKoala : Animal { KoalaFood : Food food; } then SmartKoala will be able to prevent more compile time errors and enforce the natural inherence relationship that exists between animals on food. We can do this with properties on some level class Animal { @property void food(Food food); } class SemiSmartKoala : Animal { override @property void food(Food food) { if (!is(typeof(food) == KoalaFood)) throw ... } } This, of course, only saves us at runtime and is much more verbose and is not really naturally constraining dependencies.
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 20:50:14 UTC, IntegratedDimensions wrote: The only problem where it can leak is when we treat an cat as an animal then put in dog food in to the animal, which is valid when cat as treated as an animal, then cast back to cat. Now cat has dog food, which is invalid. It sounds like you don't want to have a `food` setter in the `Animal` base class. Instead, you want setters in each child class that take the specific type required, and possibly an abstract getter in the base class. You could use a mixin to ease the process of defining appropriate food types, and you could have a method that takes the base `Food` class and does runtime validation. You might also change `Animal` to `Animal!(TFood : Food)` and go from there. You'd likely need to extract another base class or interface so you can have a collection of arbitrary animals.
Re: D's Destructors are What Scott Meyers Warned Us About
On Sunday, 27 May 2018 at 18:55:41 UTC, Mike Franklin wrote: On Sunday, 27 May 2018 at 16:06:21 UTC, 12345swordy wrote: You are replacing runtime typeinfo with compiletime templates. Unless you can guarantee that the type information won't change during runtime, you are going to have a hard time. Read this thread for context https://forum.dlang.org/post/mr7a65$2hc$1...@digitalmars.com See this PR for an example https://github.com/dlang/dmd/pull/7225 And see this talk for a demonstration of the benefits https://www.youtube.com/watch?v=endKC3fDxqs Mike Can you actually reply to me instead of saying "read/watch this"? I'm not going to watch an hour, just to see how you going to achieve this.
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: (see my other most recent post for disclaimer) My designs generally work like this: Main Type uses Subservient types A a B b C c where C : B : A, c : b : a. In the usage I must also keep consistent the use of c in C, b in B, a in A. There is little if nothing in the type system that allows me to specify and force this type of relationship. Although there is some covariant functions that do help such as overriding properties with covariance. class a; class b : a; class A { a x; @property a X() { return x; } @property void X(a v) { x = v; } } class _B { b x; @property b X() { return x; } @property void X(a v) { x = v; } } class B : A { @property b X() { return cast(b)x; } @property void X(b v) { x = v; } } Note that class _B is basically that of A which changes the type a in to a b but otherwise is identical. This is to prove a point of relationship in that _B uses b just as B should. Class B tries to treat x as a type b as much as possible. IN fact, by design, x is always assigned a b. In this case, the design is safe by effort rather than type consistency. A f = new B(); f.x is a type of b which is of type a, so no violations here. B g = new B(); g.x is of b type of so no violations. but note that f.x and g.x both accept type a. Of course g.X enforces type safety. Effectively the subservient types always grow with the main types in parallel so they never get out of step. In category theory this is equivalent to a natural transformation. A -> a || vv B -> b Ideally one simply should express this in a meaningful way: class B : A { extend b : a x; @property b X() { x; } // note that we do not need a cast @property void X(b v) { x = v; } } the syntax tells the compile that x of type a in A is of type b in B and that b must extend a. This then gives us something more proper to _B. Note that now B g = new B(); g.x = new a(); // is invalid g.x is forced to be b which is derived from a(or anything derived from b) These designs are very useful because they allow a type and all it's dependencies to be extended together in a "parallel" and keep type consistency. Natural transformations are extremely important in specify structural integrity between related types. While D allows this using "hacks"(well, in fact I have yet to get the setter to properly work but it is not necessary because of direct setting and avoiding the property setter). This is a potential suggestion for including such a feature in the D language to provide sightly more consistency. Here is a "real world"(yeah, right!) example: class food; class catfood; class animal { food f; } class cat : animal { catfood : food f; } animal -> food || vv cat -> catfood Of course, I'm not sure how to avoid the problem in D of animal a = new cat(); a.f = new food() auto c = cast(cat)a; as now f in cat will be food rather than catfood. The cast may have to be applied for the subservient types too internally. (which the compiler can do internally) but should the main object be set to null or just the subservient object? auto c = cast(cat)a; // if cast(cat) is extended should c be null or just c.f? The first case is safer but harder to fix and is the nuke option. In this case one might require two casting methods auto c1 = cast(cat)a; // c1 is null auto c2 = ncast(cat)a; // c2 is not null, c2.f is null Thoughts, ideas? 1/ I think that signatures could solve this problem in a nice way (https://github.com/rikkimax/DIPs/blob/master/DIPs/DIP1xxx-RC.md). 2/ For now you can solve the problem with a "template this" parameter. This is not a perfectly clean solution but not an ugly one either. You don't need to rewrite the x setter and getter and in order to cast because you get the most derived type in the calling context (although the compiler still does a dynamic cast, but not for the "parallel type", which is provided by a "mixin template"). ``` module runnable; class a {} class b : a {} class c : b {} mixin template Extensible(E) if (is(E : a)) { alias Extended = E; Extended _x; this() { _x = new Extended; } } class A { mixin Extensible!a; @property auto x(this T)() { return (cast(T) this)._x; } @property void x(this T, V)(V v) { (cast(T) this)._x = v; } } class B : A { mixin Extensible!b; // extend b : a x; } class C : B { mixin Extensible!c; // extend c : b x; } void main() { B someB = new B; C someC = new C; static assert(is(typeof(someB.x()) == b)); static assert(is(typeof(someC.x()) == c)); } ``` What's not nice is that even if the "template this" parameter allows to select the right x, there's still an instance of x for each sub
[Issue 18912] [REG 2.080 git] "switch skips declaration" of foreach variable
https://issues.dlang.org/show_bug.cgi?id=18912 --- Comment #2 from JR--- I see. The code was naturally heavily reduced. I have up until now been using the foreach without any issues, though mostly indexing the .tupleof directly to access the underlying symbol rather than using the member variable. I only use member once with std.traits.isType. https://github.com/zorael/kameloso/blob/f4617a5e5c796fcc9797e1f556b0861f44930f40/source/kameloso/config.d#L519 Slightly less reduced: --- thingloop: foreach (immutable i, thing; things) { switch (hits["entry"]) { foreach (immutable n, ref member; things[i].tupleof) { static if (!isType!member && !hasUDA!(Things[i].tupleof[n], Unconfigurable)) { enum memberstring = __traits(identifier, Things[i].tupleof[n]); case memberstring: things[i].setMemberByName(hits["entry"], hits["value"]); continue thingloop; } } default: // Unknown setting in known section invalidEntries[section] ~= hits["entry"].length ? hits["entry"] : line; break; } } --- Thanks, I will try your other approaches. --
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 18:16:25 UTC, JN wrote: On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: animal a = new cat(); a.f = new food() auto c = cast(cat)a; as now f in cat will be food rather than catfood. I think the problem is in your hierarchy. If Animal can have Food, that means that any animal should be able to accept any food, without knowing what kind of food is this. Cat requiring cat food is a leaky abstraction, the cat shouldn't know nor care what kind of food it gets, as it's an animal and it will eat any food. This is clearly false. A Kola does not eat any type of food, nor does a whale or most animals. While it is just an example, it still applies in general. Natural transformations are fundamental to type theory. The only problem where it can leak is when we treat an cat as an animal then put in dog food in to the animal, which is valid when cat as treated as an animal, then cast back to cat. Now cat has dog food, which is invalid. But I've already pointed out two things about this: 1. The hierarchy is maintained to be non-leaky at runtime(I never down cast). 2. casting can be designed to handle this behavior. When we cast animal to cat then the cast can null dog food since it isn't cat food. No different than if we cast animal to hammer but requires a bit more compiler logic.
Re: Clash When Using Function as Template Value-Parameters?
I would rewrite it to something like this: import std.stdio; import std.functional; template BTree(ValueT, KeyT = ValueT,alias KeyF = unaryFun!"cast(const)a") { class BTree { auto getKey(ValueT val) { return KeyF(val); } } } void main() { auto btree1 = new BTree!(char)(); // Removing this line eliminates the error. auto btree2 = new BTree!(int)(); } On Sun, May 27, 2018 at 9:03 AM, Vijay Nayar via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Saturday, 26 May 2018 at 11:56:30 UTC, Vijay Nayar wrote: > >> The error is: >> ``` >> onlineapp.d(8): Error: function literal `__lambda6(char a)` is not >> callable using argument types `(int)` >> onlineapp.d(8):cannot pass argument `val` of type `int` to >> parameter `char a` >> onlineapp.d(15): Error: template instance `onlineapp.BTree!(int, int, >> function (char a) => a)` error instantiating >> ``` >> > > Just to clarify. In the example above, if I create a 'BTree!int' by > itself, it's fine. If I create a 'BTree!char' by itself, it's fine also. > But if I create both, even if they are created in different modules, the > compiler seems to mix up the types of the function template-parameter, and > tries to fit a 'char' to the 'int' function or an 'int' to the 'char' > function, depending on which was declared first. >
[Issue 18912] [REG 2.080 git] "switch skips declaration" of foreach variable
https://issues.dlang.org/show_bug.cgi?id=18912 ag0aep6gchanged: What|Removed |Added Status|NEW |RESOLVED CC||ag0ae...@gmail.com Resolution|--- |INVALID Severity|normal |regression --- Comment #1 from ag0aep6g --- (In reply to JR from comment #0) > Is this a regression or was my code always broken? As far as I see, the error is good, and your code should not be allowed. So I'm closing this as invalid. But please feel free to reopen if you disagree with my reasoning. Note that the compiler complains about the `member` variable, not `memberstring`. You're not using `member` in your code, so you don't see that it's broken, but it is. For example, you can try printing `member` in the case statement: struct Foo { string abc, def; } void main() { Foo foo = Foo("hello", "world"); switch ("abc") { foreach (immutable n, ref member; foo.tupleof) { enum memberstring = __traits(identifier, Foo.tupleof[n]); case memberstring: import std.stdio; writeln(member); /* prints garbage and/or crashes */ break; } default: break; } } You can use `static foreach` to get a compile-time loop without declaring a broken `member` variable: struct Foo { string abc, def; } void main() { Foo foo = Foo("hello", "world"); sw: switch ("abc") { static foreach (immutable n; 0 .. foo.tupleof.length) {{ enum memberstring = __traits(identifier, Foo.tupleof[n]); case memberstring: import std.stdio; writeln(foo.tupleof[n]); /* Prints "hello". */ break sw; }} default: break; } } --
Re: SecureD Futures (v2.0)
On 05/27/2018 09:54 AM, Neia Neutuladh wrote: On Sunday, 27 May 2018 at 10:27:45 UTC, Adam Wilson wrote: Now that SecureD v1 is in the books This would have been a great place to insert a brief description of what SecureD is or a link to the project. Good point. SecureD is a cryptography library that is designed to make non transport-layer cryptography simple to use. I created it after working with OpenSSL and observing that the API design of OpenSSL actively encourages broken implementations. Think of it as a cryptography library for the rest of us. You can read more about it here: http://code.dlang.org/packages/secured -- Adam Wilson IRC: LightBender import quiet.dlang.dev;
Re: D's Destructors are What Scott Meyers Warned Us About
On Sunday, 27 May 2018 at 16:06:21 UTC, 12345swordy wrote: You are replacing runtime typeinfo with compiletime templates. Unless you can guarantee that the type information won't change during runtime, you are going to have a hard time. Read this thread for context https://forum.dlang.org/post/mr7a65$2hc$1...@digitalmars.com See this PR for an example https://github.com/dlang/dmd/pull/7225 And see this talk for a demonstration of the benefits https://www.youtube.com/watch?v=endKC3fDxqs Mike
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: animal a = new cat(); a.f = new food() auto c = cast(cat)a; as now f in cat will be food rather than catfood. I think the problem is in your hierarchy. If Animal can have Food, that means that any animal should be able to accept any food, without knowing what kind of food is this. Cat requiring cat food is a leaky abstraction, the cat shouldn't know nor care what kind of food it gets, as it's an animal and it will eat any food.
Why 'getSymbolsByUDA' filters private members?
I'd like to get symbols that have an UDA. But when the member is private, it is not obtained. And I found a comment saying "Filtering inaccessible members" in the source. Why is it necessary to filter out private members?
Re: SecureD Futures (v2.0)
On Sunday, 27 May 2018 at 10:27:45 UTC, Adam Wilson wrote: Now that SecureD v1 is in the books This would have been a great place to insert a brief description of what SecureD is or a link to the project.
Re: On Forum Moderation
On Sunday, 27 May 2018 at 04:01:27 UTC, 12345swordy wrote: On Saturday, 26 May 2018 at 07:35:31 UTC, Dukc wrote: On Saturday, 26 May 2018 at 03:34:50 UTC, Walter Bright wrote: For unprofessional demeanor, I recommend reddit. Wat?!? Enough of the sex talk here. Stop
Database rollback
Hello, Due to an error during emergency server maintenance yesterday, some data was deleted. This includes forum.dlang.org and wiki.dlang.org databases. I managed to recover the MySQL databases, so wiki.dlang.org should work as before. Unfortunately, the last working backup of the forum.dlang.org database is from March 11. (Normally, we have hourly off-site backups of everything, but this data was excluded from backups due to a misconfiguration introduced during another emergency server maintenance...) As a result, all account changes (new accounts, subscriptions, read post history...) since March 11 have been lost, and will need to be recreated. Forum posts are not affected, as they are not stored elsewhere. If you are missing some data and don't have a copy elsewhere, let me know and I'll see if I can recover it from other sources (like logs). Apologies for the inconvenience.
Re: D's Destructors are What Scott Meyers Warned Us About
On Sunday, 27 May 2018 at 09:55:56 UTC, Mike Franklin wrote: On Friday, 25 May 2018 at 23:47:33 UTC, sarn wrote: [...] I'm very much interested in doing something about these functions. __xdtor is just one. There are others at https://github.com/dlang/druntime/blob/54ab96e9977e0c6baa7ed9740810058fd4aec6ef/src/object.d#L1212-L1229. __xtoHash is currently causing problems at https://github.com/dlang/dmd/pull/8222 TypeInfo has become my nemesis. I've been trying to replace runtime hooks that depend on TypeInfo with templates that can get their information at compile-time, but I'm running into all sorts of problems. e.g. Did you know array.length can be set in @safe nothrow pure code, but it lowers to runtime functions that are neither @safe, nothrow, nor pure? Anyway, I'm getting better at modifying the compiler/runtime interface. If we can come up with a solution to this mess, and I can understand it, I might be able to implement it. Mike You are replacing runtime typeinfo with compiletime templates. Unless you can guarantee that the type information won't change during runtime, you are going to have a hard time. Alex
Re: What's the purpose of the 'in' keyword ?
On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn wrote: > On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via Digitalmars-d-learn > > wrote: > > On Sunday, 27 May 2018 at 13:02:23 UTC, loloof64 wrote: > > > What's the purpose of this 'in' keyword ? I could not process a > > > good Google request to get an answer. > > > > It means you are taking the parameter in to look at, but not > > modify or store. > > > > Basically "const". (well, for now, literally "const" but that can > > change with other details) > > Is there an easy set of "rules" as to when to use 'const' and when to use > 'in'? > > In a situation where there are multiple ways of expressing the same > concept there needs to be idioms to guide people to do the right thing in > a given context. Honestly, I'd suggest that folks never use in at this point. There's zero benefit to it. In principle, in was supposed to be const scope, but scope has never really done anything for anything other than delegates, so there has been no reason to use it over const. However, many folks seem to like it based on the idea that it was the opposite of out - and some folks used it based n what they expected scope to end up meaning whenever it finally got implemented for more than just delegates. Either way, it didn't actually buy them anything as long as scope has done nothing. Now with DIP 1000, scope is actually starting to mean something, but there's the concern that enabling scope for all of the places that in was used would break a lot of code. So, the spec now says that in means const rather than const scope, and as I undertand it, for the most part, the compiler doesn't treat it as scope anywhere aside from a a few buggy cases (even when -dip1000 is used). Some folks are not happy about that, and the situation may yet change (heck, we haven't even figured out how to switch to -dip1000 being the default without breaking everyone in the process yet - e.g. it's not ABI compatible with code that's not compiled with -dip1000, because it mangles differently). So, we can't really say what in is going to end up meaning when the dust settles. Ultimately, it may permanently just be const, or it may end up actually being const scope. But it's never actually bought you anything over using const (other than being shorted), and if it does end up becoming const scope, you're almost certainly going to have to fix a lot of the code that you wrote using in. So, I really don't think that it's a good idea to use in at all, but there are definitely folks who disagree with me, some of whom very much hope that it ends up meaning const scope and who want it to break their code if/when it does if there's any kind of escaping in their code - though given how confusing -dip1000 seems to be for many folks, I seriously question that much code using in would just work if it's changed to properly mean const scope or that all that many programmers using in understand scope well enough to use it correctly. - Jonathan M Davis
Re: Draft for DIP concerning destroy is up.
On Sunday, 27 May 2018 at 09:04:20 UTC, Go-Write-A-DIP wrote: On Saturday, 26 May 2018 at 02:25:30 UTC, 12345swordy wrote: k Though I had posted a thread regarding my DIP and no one seems to care. Alex When someone has an idea, that you don't care about, you tell them to go write a DIP. Apparently, that is the more acceptable 'etiquette', rather than telling them to FO. Is this another alt account of yours? If you not going to discuss my DIP then go away.
Re: What's the purpose of the 'in' keyword ?
On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via Digitalmars-d-learn wrote: > On Sunday, 27 May 2018 at 13:02:23 UTC, loloof64 wrote: > > What's the purpose of this 'in' keyword ? I could not process a > > good Google request to get an answer. > > It means you are taking the parameter in to look at, but not > modify or store. > > Basically "const". (well, for now, literally "const" but that can > change with other details) Is there an easy set of "rules" as to when to use 'const' and when to use 'in'? In a situation where there are multiple ways of expressing the same concept there needs to be idioms to guide people to do the right thing in a given context. -- Russel. = Dr Russel Winder t:+44 20 7585 2200 41 Buckmaster Road m:+44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Conditionally set nothrow: for a block of code.
On Thursday, 24 May 2018 at 18:51:31 UTC, Mike Franklin wrote: I'm trying to find a way to declare a block of code `nothrow:` when compiling with -betterC, but not `nothrow` when not compiling with -betterC. The solution is needed for this PR: https://github.com/dlang/druntime/pull/2184/files#r188627707 [...] Given that the PR above is for object.d, I can't turn the entire object.d source file into a string and conditionally mix that in. Does anyone have a solution to this? Thanks, Mike I think conditional application of attributes would be something useful. Something like this: version (D_BetterC) enum BetterC = true; else enum BetterC = false; nothrow!(BetterC): ... Of course that would require a DIP though
Re: DIP 1012--Attributes--Preliminary Review Round 1
On Thursday, 27 July 2017 at 14:44:23 UTC, Mike Parker wrote: DIP 1012 is titled "Attributes". https://github.com/dlang/DIPs/blob/master/DIPs/DIP1012.md All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on August 10 (3:59 AM GMT August 11), or when I make a post declaring it complete. I don't know what's happening with this DIP, but I've recently encountered a real-world problem for which there is no palatable workaround that this DIP would likely solve: https://github.com/dlang/druntime/pull/2184#pullrequestreview-120643123 My attempts to workaround the issue I posted at https://forum.dlang.org/post/uhgzgmowqcczczrdt...@forum.dlang.org That PR may be useful for motivating this DIP. Mike
Re: Code repetition
On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote: Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists. I think you might just be using the wrong kind of function. --- import std.stdio; // the helper does the setup then calls another function for specific stuff void helper(void delegate(ref int) specialized) { // setup stuff int x; scope(exit) writeln("exit ", x); // specialized stuff abstracted out specialized(x); } void foo() { helper( (ref x) { x = 34; }); } void main() { foo(); } --- A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc. Configure your editor so the q{ code... } strings don't highlight as a string and you get that at least.
Re: What's the purpose of the 'in' keyword ?
On Sunday, 27 May 2018 at 13:02:23 UTC, loloof64 wrote: What's the purpose of this 'in' keyword ? I could not process a good Google request to get an answer. It means you are taking the parameter in to look at, but not modify or store. Basically "const". (well, for now, literally "const" but that can change with other details)
Re: What's the purpose of the 'in' keyword ?
On Sunday, 27 May 2018 at 13:04:54 UTC, rikki cattermole wrote: On 28/05/2018 1:02 AM, loloof64 wrote: Hello everyone, I've just completed the language tour, and I am starting a tutorial in order to use Gtk binding. But somewhere, they use the 'in' keyword for the constructor : (https://sites.google.com/site/gtkdtutorial/#chapter2 : in section 3 for Buttons and Callbacks, main.d snippet). What's the purpose of this 'in' keyword ? I could not process a good Google request to get an answer. Regards https://dlang.org/spec/function.html#parameters Thank you very much : I'm going to look at it right now.
Re: What's the purpose of the 'in' keyword ?
On 28/05/2018 1:02 AM, loloof64 wrote: Hello everyone, I've just completed the language tour, and I am starting a tutorial in order to use Gtk binding. But somewhere, they use the 'in' keyword for the constructor : (https://sites.google.com/site/gtkdtutorial/#chapter2 : in section 3 for Buttons and Callbacks, main.d snippet). What's the purpose of this 'in' keyword ? I could not process a good Google request to get an answer. Regards https://dlang.org/spec/function.html#parameters
What's the purpose of the 'in' keyword ?
Hello everyone, I've just completed the language tour, and I am starting a tutorial in order to use Gtk binding. But somewhere, they use the 'in' keyword for the constructor : (https://sites.google.com/site/gtkdtutorial/#chapter2 : in section 3 for Buttons and Callbacks, main.d snippet). What's the purpose of this 'in' keyword ? I could not process a good Google request to get an answer. Regards
Re: SecureD Futures (v2.0)
On Sunday, 27 May 2018 at 10:27:45 UTC, Adam Wilson wrote: Now that SecureD v1 is in the books I thought it would be worthwhile to explore what a second version could like. I specifically want to focus on expanding compatibility with other systems. [...] No, it’s not. Look at IOpipe and no further it provides the exact abstraction that works for any form buffered I/O doing stream processing at top speeds. I’m doing IOpipe regex, it looks to be just what the doctor ordered. But that means pulling in Vibe.D for a simple cryptography library. At this point that doesn't seem like the right idea. If someone is willing to step-up and do the work I'd be willing to look at it, but for now I want to wait on this, preferably for a standard/generic streams interface to be made available. [...]
Re: Any way to override base type with dervived in derived type
On 5/25/18 4:02 PM, IntegratedDimensions wrote: So, I upgraded everything, tried to add the setter and get an compile time access violation: override @property T t(T v) { _t = v; return v; } Changing T v to TT v gives the violation override @property T t(TT v) { _t = v; return v; } Parameters work the opposite way as return values. That is, you can't override a base class's function that accepts a base type with one that accepts a derived type. This is because you must be able to call the virtual function with the base type, and this would not work. So what is technically possible is to call an overridden function with a base type (i.e. override a function that accepts a TT with one that accepts a T), but I don't know if D allows this, and obviously it doesn't help with your use case. object.Error@(0): Access Violation 0x004850C8 0x00485C96 0x0043E22A 0x0047FB50 0x0046109A 0x0052401A 0x77D0B605 in LdrQueryProcessModuleInformation 0x77D11D02 in RtlQueryProcessLockInformation 0x77D11705 in RtlQueryProcessDebugInformation 0x77CA47DF in RtlAllocateHeap Hm... this is a runtime stack trace. And a crappy one at that (very little info at the top of the stack). If you are getting this at compile time, then it's the compiler having an issue, which is automatically a bug (compiler should never throw an error). If you have a reduced test case, I'd recommend filing an issue, and tagging it with ICE. But it needs to be reproducible. -Steve
Re: Code repetition
On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote: A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc. I'd love to have something like a template mixin where I can just do mixin template fooSetup(ret) { // setup stuff int x; scope(exit) something; } and void foo() { fooSetup(3); } void foo4() { fooSetup(13); } and everything behave as it should. I'm guessing this is going to be impossible to achieve in D? Well, if you want to have the same power as Cs textual replacement, you need string mixins. Often you can replace it with templates, but that depends on the application. I would avoid it if you can though, but more for debugging and not because of syntax highlighting. void main() { import std.stdio; int y = 1; mixin(fooSetup(3)); writeln("x is ",x); x = 5; } string fooSetup(int val) { import std.conv; return q{ int x = }~val.to!string~q{; scope(exit) { writeln("x was ", x); writeln("y was ", y); } }; }
[Issue 18911] __FILE_FULL_PATH__ is wrong in imported module
https://issues.dlang.org/show_bug.cgi?id=18911 --- Comment #2 from github-bugzi...@puremagic.com --- Commit pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/4db37440bf6da60f485b6469f8dea1ec83a1f143 Add testcase for __FILE_FULL_PATH__ in imported file. See issue 18911. --
[Issue 18912] New: [REG 2.080 git] "switch skips declaration" of foreach variable
https://issues.dlang.org/show_bug.cgi?id=18912 Issue ID: 18912 Summary: [REG 2.080 git] "switch skips declaration" of foreach variable Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: zor...@gmail.com I have a function with a switch, with an inner foreach to generate cases based on a template parameters .tupleof. It still works in 2.080.0 and even with "dmd-nightly" on run.dlang.io, but not with dmd from git as of 180527. --- struct Foo { string abc, def; } void applyConfiguration(Thing)(ref Thing thing) { switch ("asdf") { foreach (immutable n, ref member; thing.tupleof) { enum memberstring = __traits(identifier, Thing.tupleof[n]); case memberstring: // ... break; } default: break; } } void main() { Foo foo; applyConfiguration(foo); } --- > switch.d(8): Error: `switch` skips declaration of variable > `switch.applyConfiguration!(Foo).applyConfiguration.member` at switch.d(11) > switch.d(27): Error: template instance `switch.applyConfiguration!(Foo)` > error instantiating The offending commit is eabc6a62b1d2f5924637f1e61464b9a975341dd4, "fix Issue 18858 - switch 'skips declaration' test only checks last declaration". Is this a regression or was my code always broken? --
Re: Remove closure allocation
On Saturday, 26 May 2018 at 18:10:30 UTC, Neia Neutuladh wrote: On Saturday, 26 May 2018 at 15:00:40 UTC, Malte wrote: This compiles with DMD, however it returns random numbers instead of the value I passed in. Looks like a bug to me. Should that work or is there any other pattern I could use for that? Filed as https://issues.dlang.org/show_bug.cgi?id=18910 As for the larger issue, you have to store `q` somewhere. The compiler could store it on the stack, but the compiler would have to do a lot of work to prove that that's safe -- that the return value from `arr.map` doesn't escape the current function, that `map` doesn't save the thing you passed to it anywhere, that sort of thing. And that sort of analysis is flaky. It's a recipe for code that compiles on one version of a compiler and not the next, a lot of bug reports that are hard to track down, that sort of thing. And it means that it has to assume the worst for functions that it doesn't have the source for -- when you pass a delegate, when you call an extern(D) function, when you call a virtual method. So the compiler does the safe thing, and it has the GC allocate a bit of memory to hold `q`. The way around that is the `scope` keyword. The compiler can do that complex analysis one function at a time; that's sufficiently simple. So if you wrote a `map` function, you could define it as taking a `scope U delegate(T)` and the compiler wouldn't need to use the GC there. That obviously adds restrictions on how you can write that function. I had filed a bugreport already, but this is only slightly related. It might be the solution to my problem and just not working because it's a compiler bug, but could also be supposed to give me a compile error instead for some reasons I don't know yet. I understand the general issue why a closure can be necessary, but it shouldn't be here, because all I have are value types (int) and strongly pure function calls. In fact even that immutable on q should be merely an optimization hint that the compiler could use the same register when inlining it instead of having to make a copy. Adding scope and immutable at will wouldn't be an issue, but it doesn't solve the problem and wouldn't make sense to me if it did. In fact, my actual issue is not that I need a @nogc function. I have a working code that is designed with that principle to have data transformation using pure functions and I want to parallelise it by just replacing map with taskPool.amap. I had exactly that problem before and was more or less randomly trying to make changes to get rid of the "cannot access frame of function" error messages. However, if I try to make it a nogc function first, the compiler gives me useful information like "onlineapp.identity.__lambda4 closes over variable q at onlineapp.d(24)", so I can have a closer look at q instead of blindly guessing why the compiler thinks it needs another frame pointer. What I did last time is rewrite the whole function to fit into a parallel foreach and I guess I have to do the same here too. It's not that I can't rewrite it to something like int identity(immutable int q) pure nothrow @safe @nogc { static immutable auto arr = [42]; int getSecondArgument(int a, int b) { return b; } foreach(i, a; arr) { auto tmp = getSecondArgument(a, q); if (i==0) return tmp; } assert(0); } , I just don't think I should have to rewrite it that much. But I currently see no other way to use taskPool and in general I see very little possibilities to utilize taskPool.amap even though it looks like a handy tool at first sight, but is just too limited when you actually try to do something with it.
SecureD Futures (v2.0)
Now that SecureD v1 is in the books I thought it would be worthwhile to explore what a second version could like. I specifically want to focus on expanding compatibility with other systems. For example: AWS uses SHA2-256 for signing requests. As implemented today SecureD does not support this. However, this is one of the scenarios that falls under SecureD's mission of ease-to-use cryptography for non-transport layer security. I am curious what people would like to see in SecureD moving forward and I would love to get your feedback on what works and what doesn't work in v1 of SecureD. With this in mind here are my ideas for expanding SecureD's capabilities. I'll start with the idea that I think will be the least controversial. 1. Full support for SHA-2 and SHA-3 for Hashes and HMAC's. This means the following modes would be supported: SHA2: 224, 256, 384, 512, 512/224, 512/256 SHA3: 224, 256, 384, 512 The PBKDF2 implementation would also be updated to support the above hash functions. Hash methods supporting salts will be added. To maintain backwards compatibility with v1, methods that match the v1 signatures and forward to the correct implementation would be provided as the v1 defaults are still secure. This requires OpenSSL 1.1.1 at a minimum. Note that SHA3 support could be delayed until SecureD 2.1 if OpenSSL 1.1.1 is not available on a majority of systems prior to shipping 2.0. In such case OpenSSL 1.1.0 would become the minimum supported version. 2. More Flexibility for Symmetric Encryption. Currently SecureD only supports AES256-CTR-HMAC384 and the encrypted data is laid out as: HASH+IV+DATA. This is only useful in scenarios where the developer controls both the encryption and decryption of the data. Additionally, this does not support AEAD modes, only AE modes. The first thing I would like to do is to support all AES, SHA2, and SHA3 modes. I also want to add support for the CBC cipher mode with PCKS#7 padding as that is the most common cipher mode in use. One of the primary use cases for SecureD is long-term storage of data. To facilitate this requirement I would like to add a binary encoded header to each encrypted blob. This header would contain the necessary information to decode the blob (minus the key of course). The header would cost 26 bytes per encrypted blob and would have the following layout: struct cryptoHeader { ubyte hdrVersion; // The version of the header ubyte encAlg; // The encryption algorithm used ubyte hashAlg; // The hash algorithm used uint kdfIters; // The number of PBKDF2 iterations ubyte authLen; // The length of the authentication value ubyte saltLen; // The length of the PBKDF2 salt ubyte ivLen;// The length of the IV ulong encLen; // The length of the encrypted data ulong adLen;// The length of the additional data } The data layout would be: HEADER+AUTH+SALT+IV+ENC+AD Any excluded elements would be marked as 0 in the header and completely excluded from the data layout. The MAC would be computed as: HMAC(HEADER+SALT+IV+ENC+AD) The full encryption process would be as follows: - Create a PBKDF2 salt via RNG - Create IV via RNG - Create header from user inputs - EncKey = PBKDF2 over RawKey unless hashAlg is None or kdfIters == 0 - Use RawKey as-is if hashAlg is None or kdfIters == 0 - MacKey = PBKDF2 over EncKey once using same inputs as EncKey - Encrypt data - Compute HMAC(HEADER+SALT+IV+ENC+AD) - Return RESULT(HEADER+AUTH+SALT+IV+ENC+AD) Methods would be added to work with the following: - Simple encrypted blobs (no header/auth/salt/iv/ad included) - Creating and Verifying AE/AD MACs without headers - Methods to read SecureD v1 encrypted data Note that this plan is NOT compatible with the SecureD v1 encryption data layout and data would need to be re-encrypted. 3. Re-implement the OpenSSL Bindings The Deimos/DUB bindings are ancient and do not support OpenSSL 1.1.x. We can re-implement the bindings taking care to only include the symbols we need. 4. Streams I get asked about this, and, as much as I want to do this, it is not a simple topic. std.streams was removed and right now the only viable replacement is Vibe.D streams. But that means pulling in Vibe.D for a simple cryptography library. At this point that doesn't seem like the right idea. If someone is willing to step-up and do the work I'd be willing to look at it, but for now I want to wait on this, preferably for a standard/generic streams interface to be made available. Please let know what you think! I am very interested to hear about what would make your life easier when working with SecureD an cryptography in general. -- Adam Wilson IRC: LightBender import quiet.dlang.dev;
Re: D's Destructors are What Scott Meyers Warned Us About
On Friday, 25 May 2018 at 23:47:33 UTC, sarn wrote: That std.signals code that Steven filed a bug report for is example of why we can't just fix the behaviour, though. If we just fixed __dtor/__xdtor, any code that used std.signals would start having ugly bugs at run time. I think that longer term we'll have to deprecate and remove these functions. I'm very much interested in doing something about these functions. __xdtor is just one. There are others at https://github.com/dlang/druntime/blob/54ab96e9977e0c6baa7ed9740810058fd4aec6ef/src/object.d#L1212-L1229. __xtoHash is currently causing problems at https://github.com/dlang/dmd/pull/8222 TypeInfo has become my nemesis. I've been trying to replace runtime hooks that depend on TypeInfo with templates that can get their information at compile-time, but I'm running into all sorts of problems. e.g. Did you know array.length can be set in @safe nothrow pure code, but it lowers to runtime functions that are neither @safe, nothrow, nor pure? Anyway, I'm getting better at modifying the compiler/runtime interface. If we can come up with a solution to this mess, and I can understand it, I might be able to implement it. Mike
[Issue 18911] __FILE_FULL_PATH__ is wrong in imported module
https://issues.dlang.org/show_bug.cgi?id=18911 --- Comment #1 from johanenge...@weka.io --- Testcase added: https://github.com/dlang/dmd/pull/8301 --
[Issue 18911] __FILE_FULL_PATH__ is wrong in imported module
https://issues.dlang.org/show_bug.cgi?id=18911 johanenge...@weka.io changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
[Issue 18911] New: __FILE_FULL_PATH__ is wrong in imported module
https://issues.dlang.org/show_bug.cgi?id=18911 Issue ID: 18911 Summary: __FILE_FULL_PATH__ is wrong in imported module Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: johanenge...@weka.io In a module that is imported after being found by the import path on the cmdline, __FILE_FULL_PATH__ is wrong, e.g. it is: "/Users/johan/bla/bla/include//Users/johan/bla/bla/bla/" (somehow duplicating part of the path). Testcase: ``` // File: fullfilepath.d import a; enum THIS_FILE = __FILE_FULL_PATH__; enum suffix_this = "fullfilepath.d"; static assert(THIS_FILE[0..$-suffix_this.length] == A_FILE[0..$-suffix_a.length]); ``` ``` // File: include/a.d enum A_FILE = __FILE_FULL_PATH__; enum suffix_a = "include/a.d"; ``` Compilation fails both with relative include path: ``` dmd -c -Iinclude fullfilepath.d ``` and with absolute include path: ``` dmd -c -I/your/absolute/path/include fullfilepath.d ``` This was fixed in DMD 2.079. But there is no testcase for it, so opening this bug report and submitting a PR with testcase soon after. --
Re: Getter an lvalue and cannot be modified
On Sunday, 27 May 2018 at 09:23:09 UTC, IntegratedDimensions wrote: C[] c; @property C[] get() { return c; } get ~= something; errors out, yet auto q = get; q ~= something; is fine. Why is D thinking that ~= is being applied to get, the function, rather than what it returns? Also When I converted a field in to a property, an AA, it is returning null rather than being initialized by default. Seems like properties are broke. I'd expect a property getter to behave, for all intents and purposes as if it were field. I shouldn't have to have a temp variable to be able to use it as such. You'll probably get your answer and more by reading this: https://github.com/dlang/DIPs/pull/97 TL;DR: return `ref C[]` Mike
Getter an lvalue and cannot be modified
C[] c; @property C[] get() { return c; } get ~= something; errors out, yet auto q = get; q ~= something; is fine. Why is D thinking that ~= is being applied to get, the function, rather than what it returns? Also When I converted a field in to a property, an AA, it is returning null rather than being initialized by default. Seems like properties are broke. I'd expect a property getter to behave, for all intents and purposes as if it were field. I shouldn't have to have a temp variable to be able to use it as such.
Re: D's Destructors are What Scott Meyers Warned Us About
On Wednesday, 23 May 2018 at 19:05:38 UTC, Manu wrote: For my money it would be: destroy() <- just destroy reset() <- destroy and re-init Or something like that. Maybe: class.destruct(); <- destroy without init? Yeah that. I'll make a PR! I had an in-depth discussion with Andrei about this at https://github.com/dlang/druntime/pull/2115 He ultimately gave up on trying to explain it to me and created his own PR here: https://github.com/dlang/druntime/pull/2126 It's be good to review that discussion, and perhaps weigh in on #2126. Mike
Re: Draft for DIP concerning destroy is up.
On Saturday, 26 May 2018 at 02:25:30 UTC, 12345swordy wrote: k Though I had posted a thread regarding my DIP and no one seems to care. Alex When someone has an idea, that you don't care about, you tell them to go write a DIP. Apparently, that is the more acceptable 'etiquette', rather than telling them to FO.
[Issue 18880] [REG2.079] Miscompilation of unittests when two are mixed-in on one line
https://issues.dlang.org/show_bug.cgi?id=18880 --- Comment #3 from johanenge...@weka.io --- https://github.com/dlang/dmd/pull/8255 --
Re: Friends in D, a new idiom?
On Sunday, 27 May 2018 at 06:37:56 UTC, IntegratedDimensions wrote: I'm looking for something lightweight and direct. It is not for total encapsulation control but to simply provide an extra level of indirection for write access to make the object look read only to those that directly use it. I think const is something that may be helpful then. If applied consistently, especially with methods, it can also protect you from accidentally making mutations in functions where were originally intended to be read-only. Having an object "look" read-only is more of a stylistic thing based on conventions about method naming, etc. Personally I lean towards having the compiler enforce it.
Re: Clash When Using Function as Template Value-Parameters?
On Saturday, 26 May 2018 at 11:56:30 UTC, Vijay Nayar wrote: The error is: ``` onlineapp.d(8): Error: function literal `__lambda6(char a)` is not callable using argument types `(int)` onlineapp.d(8):cannot pass argument `val` of type `int` to parameter `char a` onlineapp.d(15): Error: template instance `onlineapp.BTree!(int, int, function (char a) => a)` error instantiating ``` Just to clarify. In the example above, if I create a 'BTree!int' by itself, it's fine. If I create a 'BTree!char' by itself, it's fine also. But if I create both, even if they are created in different modules, the compiler seems to mix up the types of the function template-parameter, and tries to fit a 'char' to the 'int' function or an 'int' to the 'char' function, depending on which was declared first.
Re: General problem I'm having in D with the type system
On Sunday, 27 May 2018 at 06:00:30 UTC, IntegratedDimensions wrote: The problem description is not very clear, but the catfood example gives a bit more to work with. animal -> food || vv cat -> catfood Of course, I'm not sure how to avoid the problem in D of animal a = new cat(); a.f = new food() auto c = cast(cat)a; Cast operations are generally not guaranteed to preserve type safety and should be avoided when possible. But if I understand your description, you have the following relations and transitions: animal owns food catowns catfood animal may be treated as a cat (hence the casting) food may be treated as a catfood (hence the casting) It may be that the inheritance relationship is backwards in your use case. If "animal" may be treated as a "cat", then the inheritance should be other other way around, and "animal" would inherit from "cat". What specific kinds of relationships are you trying to model among what kinds of entities?
Re: Code repetition
I guess I should have mentioned that basically this is like a C macro.
Code repetition
I have some code like void foo() { // setup stuff int x; scope(exit) something; // x = 34; } void foon() { // setup stuff int x; scope(exit) something; // } All the setup stuff is virtually identical in each foo. There are slight differences such as a return value. I would like to abstract the code code so that it can be handled in one place. I have not found a way to do this in D. Template mixins do not work because of the arbitrary expressions. Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists. A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc. I'd love to have something like a template mixin where I can just do mixin template fooSetup(ret) { // setup stuff int x; scope(exit) something; } and void foo() { fooSetup(3); } void foo4() { fooSetup(13); } and everything behave as it should. I'm guessing this is going to be impossible to achieve in D?
Re: Friends in D, a new idiom?
On Sunday, 27 May 2018 at 06:24:13 UTC, Vijay Nayar wrote: On Sunday, 27 May 2018 at 05:25:53 UTC, IntegratedDimensions wrote: Re: Friends in D, a new idiom? In D, there's no exact equivalent to friend, but there are a few more specialized tools at your disposal. Normally all code in the same module is essentially a friend, so if the classes you are dealing with are tightly coupled, they can simply be in the same module. Yes, but this is not the case. I have two classes somewhat related but in different modules so I am looking for a more general solution. I do not like chunking everything in to the same module just to get around this type of problem. For example: module m; class C { // This is still visible in the same module. // See https://dlang.org/spec/attribute.html#VisibilityAttribute private int data; ... } class CAccessor { C _this; this(C c) { _this = c; } @property void data(int v) { _this.data = v; } ... } Initially I thought nested classes contained an inherent super but I guess that is not the case? Super is for inheritance rather than inner classes. So another way to tackle your problem using super would be this: class C { protected int _data; @property int data() { return _data; } } class CAccessor : C { @property void data(int v) { _data = v; } C toC() { return this; } } Yeah, but this is a bit bulky. Although maybe UFCS could work well in this case although one would end up requiring different names in modules rather than Access or Friend. I haven't tried it but if UFCS allows a module function to access the protected member and outside the module the UFCS could be called. I think this might defeat the usage except I recently saw that UFCS can be called with = so they can emulate setters, so it might work well(until that syntax is depreciated). I also imagine that one could enhance this so that write access could also be allowed by certain types. The 'package' visibility attribute can also be given a parameter if you need to limit access only to certain module. Yeah, maybe using packages is the best way to go. The modules I'm using are related so they could be used in a package. Doesn't help with the general case though. Any ideas about this type of pattern, how to make it better, already exists etc? You might be looking for the "Builder Pattern" which uses a separate object to construct and modify objects, and then it creates a read-only object with those values upon request. I'm looking for something lightweight and direct. It is not for total encapsulation control but to simply provide an extra level of indirection for write access to make the object look read only to those that directly use it. Basically I have another class outside the module that needs to write to a variable in side an object to set it up, from then on it is read only. It can't be done at construction. Maybe their will be one or two other times that it will need to change but I don't see why I should have to expose it for anyone nor create a huge layer of complexity to allow for a single access. The method I gave works fine for this type of behavior and the UFCS probably will even be easier if it works.
Re: On Forum Moderation
On 05/27/2018 12:57 AM, SlimeBag wrote: surely the best form of professional etiquette is to NOT be offended by what others say. as soon as you ignore that etiquette, it's a slippery slope to utlimately controlling others. Hear, hear.
Re: Friends in D, a new idiom?
On Sunday, 27 May 2018 at 05:25:53 UTC, IntegratedDimensions wrote: Re: Friends in D, a new idiom? In D, there's no exact equivalent to friend, but there are a few more specialized tools at your disposal. Normally all code in the same module is essentially a friend, so if the classes you are dealing with are tightly coupled, they can simply be in the same module. For example: module m; class C { // This is still visible in the same module. // See https://dlang.org/spec/attribute.html#VisibilityAttribute private int data; ... } class CAccessor { C _this; this(C c) { _this = c; } @property void data(int v) { _this.data = v; } ... } Initially I thought nested classes contained an inherent super but I guess that is not the case? Super is for inheritance rather than inner classes. So another way to tackle your problem using super would be this: class C { protected int _data; @property int data() { return _data; } } class CAccessor : C { @property void data(int v) { _data = v; } C toC() { return this; } } I also imagine that one could enhance this so that write access could also be allowed by certain types. The 'package' visibility attribute can also be given a parameter if you need to limit access only to certain module. Any ideas about this type of pattern, how to make it better, already exists etc? You might be looking for the "Builder Pattern" which uses a separate object to construct and modify objects, and then it creates a read-only object with those values upon request. Also, I would recommend using "const" to control access as well. Setter methods will not be const, but getters will be. Those that have a `const(C)` reference will only be able to read, and those with a `C` will be able to call all methods. For example: class C { private int _data; @property int data() const { return _data; } @property void data(int v) { _data = v; } } void main() { C a = new C(); const(C) b = a; a.data(3); a.data(); b.data(); // b.data(4); Compile error. }
Re: On Forum Moderation
On Saturday, 26 May 2018 at 03:34:50 UTC, Walter Bright wrote: From time to time, the issue comes up. The standard here is professional demeanor. For what professional demeanor is, see: https://www.amazon.com/Etiquette-Society-Business-Politics-Home/dp/1497339979 Unprofessional demeanor will get removed at the forum staff's sole discretion on a case by case basis, as well as replies to it. For unprofessional demeanor, I recommend reddit. I love reddit! (cause it's so unprofessional). I wonder whether Freud might characterise 'etiquette' as a way to protect society from the destructive, aggressive forces that control the superego. The premise of that being, that humans are unhappy animals intent on aggression and destruction. So 'etiquette' in that sense, is really a form of 'armour', designed to 'protect us' from savages. Unfortunately, that same 'armour' is now frequently mis-used throughout society, to protect us from all kinds of things, that we don't agree with. Freud speaks to this, somewhat, in Civilisation and its Discontents. (i.e. the ongoing, never ending battle, for the desire of individuality vs the expectations of society).
General problem I'm having in D with the type system
(see my other most recent post for disclaimer) My designs generally work like this: Main Type uses Subservient types A a B b C c where C : B : A, c : b : a. In the usage I must also keep consistent the use of c in C, b in B, a in A. There is little if nothing in the type system that allows me to specify and force this type of relationship. Although there is some covariant functions that do help such as overriding properties with covariance. class a; class b : a; class A { a x; @property a X() { return x; } @property void X(a v) { x = v; } } class _B { b x; @property b X() { return x; } @property void X(a v) { x = v; } } class B : A { @property b X() { return cast(b)x; } @property void X(b v) { x = v; } } Note that class _B is basically that of A which changes the type a in to a b but otherwise is identical. This is to prove a point of relationship in that _B uses b just as B should. Class B tries to treat x as a type b as much as possible. IN fact, by design, x is always assigned a b. In this case, the design is safe by effort rather than type consistency. A f = new B(); f.x is a type of b which is of type a, so no violations here. B g = new B(); g.x is of b type of so no violations. but note that f.x and g.x both accept type a. Of course g.X enforces type safety. Effectively the subservient types always grow with the main types in parallel so they never get out of step. In category theory this is equivalent to a natural transformation. A -> a || vv B -> b Ideally one simply should express this in a meaningful way: class B : A { extend b : a x; @property b X() { x; } // note that we do not need a cast @property void X(b v) { x = v; } } the syntax tells the compile that x of type a in A is of type b in B and that b must extend a. This then gives us something more proper to _B. Note that now B g = new B(); g.x = new a(); // is invalid g.x is forced to be b which is derived from a(or anything derived from b) These designs are very useful because they allow a type and all it's dependencies to be extended together in a "parallel" and keep type consistency. Natural transformations are extremely important in specify structural integrity between related types. While D allows this using "hacks"(well, in fact I have yet to get the setter to properly work but it is not necessary because of direct setting and avoiding the property setter). This is a potential suggestion for including such a feature in the D language to provide sightly more consistency. Here is a "real world"(yeah, right!) example: class food; class catfood; class animal { food f; } class cat : animal { catfood : food f; } animal -> food || vv cat -> catfood Of course, I'm not sure how to avoid the problem in D of animal a = new cat(); a.f = new food() auto c = cast(cat)a; as now f in cat will be food rather than catfood. The cast may have to be applied for the subservient types too internally. (which the compiler can do internally) but should the main object be set to null or just the subservient object? auto c = cast(cat)a; // if cast(cat) is extended should c be null or just c.f? The first case is safer but harder to fix and is the nuke option. In this case one might require two casting methods auto c1 = cast(cat)a; // c1 is null auto c2 = ncast(cat)a; // c2 is not null, c2.f is null Thoughts, ideas?