Re: Image of D code on Norwegian IT news site
On Wednesday, 31 August 2016 at 18:50:58 UTC, simendsjo wrote: An article about how outsourcing reduces the need for Norwegian developers. No links to D other than the image on top though. I wonder what they searched for to find this image. http://www.digi.no/artikler/rader-norske-it-folk-til-a-droppe-programmering/279380 Well, it seems that outsourcing to India is over. Now it's outsourcing to Eastern Europe. 2/3 of the developers in my company reside in a country in Eastern Europe. In my previous country that ratio was even higher. The CTO wasted a lot of money (because not talking to his people who would have told him) and then had to look for ways to compensate for the losses. I once followed a phone conversation between a C++ developer in India and C++ developers in Germany. The developer in India thought those in Germany were stupid and not getting it while the developers in Germany tried to explain to him that they were not stupid, but that he was missing some detail. Seems to me that outsourcing development in a very difficult language such as C++ does not work. But as what "simpler" languages are concerned such as Java or C# it is currently happening at full high. The dream about systems programming is starting to fade away. There are only very few jobs for it. And the dream about application development is fading away, too. But illusions are here to stay ;-).
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: I have a recurring problem where I need a fallback function like the bottom one, which should be used in lieu of a more precise match. +1. I've already hit this a few times with Binderoo. I would have assumed that constraints are just another form of specialisation, but it requires me to be explicit with the base functionality.
Re: Why D is not popular enough?
On Tuesday, 30 August 2016 at 18:36:19 UTC, CRAIG DILLABAUGH wrote: I am going to vote with Adam here. If memory serves me correctly what initially drew me in to the D language was a statement on the main page that "D is not a religion". I think at the time I had been doing some work with Java, where everything had to be an object. Man, I hate Java for that. Many of the inconsitencies and problems in Java come from basic types not being objects. Everything being objects is a great way to keep things easy to understand, consistent and clean. It has some impact on performance, but a lot can be done here which is more than sufficient for application programming. Hot Spot runtime code optimization in Java is very effective. Also, I think saying if you don't like functional programming you will miss 'most' of what D has to offer is really selling the language short. After all you can write C or C++ style code in D if you want, which may be very attractive to some folks. D has a lot to offer with regard to functional programming. It has pure functions and true immutable classes (true = also sub objects become immutable), which Scala all doesn't have (because of restrictions of the JVM). Does D have tail call recursion optimization? I don't know, actually. If D had that and pattern matching, it would beat Scala with all it's hype by a big leap.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: So, consider a set of overloads: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} void f(T)(T t) {} I have a recurring problem where I need a fallback function like the bottom one, which should be used in lieu of a more precise match. This is obviously an ambiguous call, but this is a pattern that comes up an awful lot. How to do it in D? I've asked this before, and people say: void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} Consider that more overloads are being introduced by users spread out across many modules that define their own kind of T; this solution is no good. To my knowledge there is currently no clean way of doing this. The easiest workaround would be to introduce another name for the implementation. then it would look like void f(T)(T t) { static if (is(fImpl(t) == void)) { f(t); } else { // default impl here } }
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 08:44:38 UTC, Stefan Koch wrote: void f(T)(T t) { static if (is(fImpl(t) == void)) { f(t); } else { // default impl here } } Was meant to be void f(T)(T t) { static if (is(fImpl(t) == void)) { fImpl(t); } else { // default impl here } }
Re: Fallback 'catch-all' template functions
On 9/1/16, Manu via Digitalmars-d wrote: > So, consider a set of overloads: > > void f(T)(T t) if(isSomething!T) {} > void f(T)(T t) if(isSomethingElse!T) {} > void f(T)(T t) {} > Best thing I can think of is to use a forwarding template: - import std.stdio; // forwarding (or dispatching) template void f(T)(T t) { static if(is(typeof( fImpl(t) ))) // found match { fImpl(t); } else // no matches, use fallback { fallback(t); } } void fImpl(T)(T t) if (is(T == int)) { writefln("Int: %s", t); } void fImpl(T)(T t) if (is(T == float)) { writefln("Float: %s", t); } void fallback(T)(T t) { writefln("Generic: %s", t); } void main ( ) { f(int(1)); f(float(1.0)); f("string"); } -
Re: Fallback 'catch-all' template functions
On 1 September 2016 at 18:44, Stefan Koch via Digitalmars-d wrote: > On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: >> >> So, consider a set of overloads: >> >> void f(T)(T t) if(isSomething!T) {} >> void f(T)(T t) if(isSomethingElse!T) {} >> void f(T)(T t) {} >> >> I have a recurring problem where I need a fallback function like the >> bottom one, which should be used in lieu of a more precise match. This is >> obviously an ambiguous call, but this is a pattern that comes up an awful >> lot. How to do it in D? >> >> I've asked this before, and people say: >> >> void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} >> >> Consider that more overloads are being introduced by users spread out >> across many modules that define their own kind of T; this solution is no >> good. > > > To my knowledge there is currently no clean way of doing this. > The easiest workaround would be to introduce another name for the > implementation. > > then it would look like > void f(T)(T t) { > static if (is(fImpl(t) == void)) { > f(t); > } else { > // default impl here > } > } This was my fallback plan, but it seems a bit shit.
Re: Image of D code on Norwegian IT news site
On Thursday, 1 September 2016 at 07:09:24 UTC, Bienlein wrote: Well, it seems that outsourcing to India is over. Now it's outsourcing to Eastern Europe. 2/3 of the developers in my company reside in a country in Eastern Europe. In my previous country that ratio was even higher. The CTO wasted a lot of money (because not talking to his people who would have told him) and then had to look for ways to compensate for the losses. I once followed a phone conversation between a C++ developer in India and C++ developers in Germany. The developer in India thought those in Germany were stupid and not getting it while the developers in Germany tried to explain to him that they were not stupid, but that he was missing some detail. Seems to me that outsourcing development in a very difficult language such as C++ does not work. But as what "simpler" languages are concerned such as Java or C# it is currently happening at full high. So they're still holding on to this "new" strategy that has failed over and over again. It failed in the 80ies when my old man was in IT, it failed in the 90ies and it is failing again. The bosses' dream of "24 hour coding" is not working. Apart from communication problems, e.g. simple things like the language barrier (accents of English), expensive errors have been introduced due to the time gap, i.e. team A arrives at work in the morning and finds that some things have been changed that should never have been changed, and now the program doesn't compile anymore (there are myriads of stories like that). One of the most expensive (offshore) outsourcing "success stories" I've heard of is the one by Ulster Bank (rumors have it that it was an infinite loop in the update that was never tested before being applied): https://en.wikipedia.org/wiki/2012_RBS_Group_computer_system_problems http://www.computerworlduk.com/news/it-business/ulster-bank-receives-275m-fine-for-it-failure-3585612/ http://www.computerweekly.com/news/2240214081/Why-IT-outsourcing-is-increasingly-fingered-for-IT-failures-at-banks But go ahead CEOs, yeah!
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 09:08:31 UTC, Manu wrote: This was my fallback plan, but it seems a bit shit. Hmm I get your point. But there is not really another way within the current langauge. Also overloading lot of templates with templates constraints will eat into your compile-time!
Re: Why D is not popular enough?
On Friday, 19 August 2016 at 15:01:58 UTC, Marco Leise wrote: Am Fri, 19 Aug 2016 13:36:05 + schrieb Adam D. Ruppe : On Friday, 19 August 2016 at 08:31:39 UTC, Marco Leise wrote: > If we hypothetically switched to a ubyte+ubyte=ubyte > semantic, then code like this breaks silently: However, if it took the entire statement into account, it could handle that... by my rule, it would see there's a float in there and thus automatically cast a and b to float before doing anything. Float math is slow compared to integer math and precision loss occurs when this rule is also applied to (u)int and (u)long with only the deprecated (as per amd64 spec) real type being large enough for 64-bit integers. Try multiplications and divisions.
Re: Fallback 'catch-all' template functions
On 1 September 2016 at 19:16, Stefan Koch via Digitalmars-d wrote: > On Thursday, 1 September 2016 at 09:08:31 UTC, Manu wrote: >> >> >> This was my fallback plan, but it seems a bit shit. > > > Hmm I get your point. > But there is not really another way within the current langauge. > Also overloading lot of templates with templates constraints will eat into > your compile-time! I know, but it's core language feature of D! Basically every function in the std library has some constraints. It's critical for anything range based... Perhaps if concepts existed, it might be a more direct and less computationally intensive mechanism to deal with it. I've been feeling like that'd really simplify the situation a lot for quite a few years now.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: So, consider a set of overloads: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} void f(T)(T t) {} I have a recurring problem where I need a fallback function like the bottom one, which should be used in lieu of a more precise match. This is obviously an ambiguous call, but this is a pattern that comes up an awful lot. How to do it in D? I've asked this before, and people say: void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} Consider that more overloads are being introduced by users spread out across many modules that define their own kind of T; this solution is no good. Simply void f(T)(T t) { static if(isSomething!T) { } else static if(isSomethingElse!T) { } else { } } I personally hate overloads, especially if the condition has a fallback, so I like to see no condition in the function signature, what makes for a much cleaner API. I have never seen what benefit could be gained from having overloads. I think they are a relict from languages without static if.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 10:43:50 UTC, Dominikus Dittes Scherkl wrote: I have never seen what benefit could be gained from having overloads. I think they are a relict from languages without static if. I mean, overloads with same function signature except for the condition. Of course if the overloads have different parameters or return type, they may make sense. But they still uglyfy the API, so I try to avoid them - instead I use default parameters and template parameters what pretty much always works.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 10:43:50 UTC, Dominikus Dittes Scherkl wrote: I have never seen what benefit could be gained from having overloads. Oh, it's perfectly fine if you're not writing a library that's designed to allow user extension by going the "all in one" method. If you encourage your users to modify your function itself, they can no longer drop in a new version and have to do a merge. Templates in general seem weak for libraries in D, which is a pain considering templates are one of the areas where the language otherwise excels.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 10:53:01 UTC, Ethan Watson wrote: On Thursday, 1 September 2016 at 10:43:50 UTC, Dominikus Dittes Scherkl wrote: I have never seen what benefit could be gained from having overloads. Oh, it's perfectly fine if you're not writing a library that's designed to allow user extension by going the "all in one" method. If you encourage your users to modify your function itself, they can no longer drop in a new version and have to do a merge. Ok, that may be fine, until you reach the point with the fallback version: if after that point someone "drops in" a new version, he silently changes the behavior of the function, because he "steals" some type which used to use the fallback version. --> overloads make only sense, if a function is NOT for all types, so you can add an overload for some type that was not considered so far, but you should not change the behaviour for some type that was already covered. At all, most of the time I prefer that the users directly change the function, yes.
Re: Fallback 'catch-all' template functions
On 1 September 2016 at 20:43, Dominikus Dittes Scherkl via Digitalmars-d wrote: > On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: >> >> Consider that more overloads are being introduced by users spread out >> across many modules that define their own kind of T; this solution is no >> good. > > > Simply > void f(T)(T t) > { >static if(isSomething!T) >{ >} >else static if(isSomethingElse!T) >{ >} >else >{ >} > } > > I personally hate overloads, especially if the condition has a fallback, so > I like to see no condition in the function signature, what makes for a much > cleaner API. > I have never seen what benefit could be gained from having overloads. I > think they are a relict from languages without static if. I think you must have not read the line of text that you replied to...
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 10:50:18 UTC, Dominikus Dittes Scherkl wrote: On Thursday, 1 September 2016 at 10:43:50 UTC, Dominikus Dittes Scherkl wrote: I have never seen what benefit could be gained from having overloads. I think they are a relict from languages without static if. I mean, overloads with same function signature except for the condition. Of course if the overloads have different parameters or return type, they may make sense. But they still uglyfy the API, so I try to avoid them - instead I use default parameters and template parameters what pretty much always works. When you're specialising on type classes rather than concrete types, you have no choice: auto f(T)(T source) if (is(ElementType!T : int)) {...}; auto f(T)(T source) if (is(ElementType!T : Object)) {...}; There is nothing you can write in the template parameters list to enable the same kind of specialisation.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 05:37:50 UTC, Manu wrote: So, consider a set of overloads: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} void f(T)(T t) {} I have a recurring problem where I need a fallback function like the bottom one, which should be used in lieu of a more precise match. This is obviously an ambiguous call, but this is a pattern that comes up an awful lot. How to do it in D? I've asked this before, and people say: void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} Consider that more overloads are being introduced by users spread out across many modules that define their own kind of T; this solution is no good. An easy workaround with a bit of boilerplate would be: void f(T)(T t) { static if(isSomething!T) { // special impl } else { fallback_f(t); } } void fallback_f(T)(T t) { ... }
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 11:01:28 UTC, Dominikus Dittes Scherkl wrote: Ok, that may be fine, until you reach the point with the fallback version: if after that point someone "drops in" a new version, he silently changes the behavior of the function, because he "steals" some type which used to use the fallback version. I don't see how that can be considered anything other than "expected behaviour" and thus ensure your design takes this in to account. If you give your user the keys to the kingdom, you need to expect them to use it.
Re: So why was typedef bad?
On 08/31/2016 04:44 PM, Ethan Watson wrote: > http://dlang.org/deprecate.html#typedef > > "typedef is not flexible enough to cover all use cases. This is better > done with a library solution." > > [Citation needed] > > What use cases is it not flexible enough for? It has unadjustable semantics that were both more restrictive than alias and at the same time not restrictive enough to introduce completely new type. Wasn't supposed to be compatible with base type but sometimes did, with no reasons other than "historical". In my own experience creating dedicated struct type is always superior to typedef if you want to go for type safety. It can start with simple `alias this` struct to have permissive semantics similar to old typedef and later changed to operator overloading for more fine tuned control. It can also provide methods for verified conversion between base type and new domain type. And if type safety is not a goal, there isn't much point in all the typedef restrictions and alias should do as well. signature.asc Description: OpenPGP digital signature
Re: Low level unit test library in druntime
On 08/30/2016 10:40 PM, Jacob Carlborg wrote: > On 2016-08-30 18:31, Dicebot wrote: > >> I definitely wouldn't want to use API like you proposed if I was to >> write my own test runner. Minimal common ground which would be cool to >> have is getting range/array of all unittest blocks together with their >> annotations. Anything more than that is optional luxury that specific >> test systems may define. > > Basically the only thing that would be different in different frameworks :( What would be different? List of unit test blocks available in the program? >> And any usage of classes in what is supposed to be a base ground API is >> immediate "no" for me :) > > Yeah that would be crazy, like threads, fibers, sockets and exceptions ;) _forcing_ usage of threads, fibers, sockets and exceptions in runtime outside of their respective modules would be rather outrageous too. druntime should reasonably simple to port to systems that may not have any of those - and still degrade gracefully. signature.asc Description: OpenPGP digital signature
Re: Why D is not popular enough?
On Thursday, 1 September 2016 at 08:04:00 UTC, Bienlein wrote: D has a lot to offer with regard to functional programming. It has pure functions and true immutable classes (true = also sub objects become immutable), which Scala all doesn't have (because of restrictions of the JVM). Does D have tail call recursion optimization? I don't know, actually. If D had that and pattern matching, it would beat Scala with all it's hype by a big leap. D does not guarantee tail calls, but the compiler might sometimes decide to do it. Functional programmer usually want to guarantee, so they don't have to write a loop. The downside of TCO is that the stack trace is missing frames, which can be very confusing. D has no syntax for pattern matching, but some library support: https://p0nce.github.io/d-idioms/#Recursive-Sum-Type-with-matching
Re: Low level unit test library in druntime
On 08/31/2016 01:01 PM, Atila Neves wrote: > And never mind that any such low level library would suffer from the > same problem unit-threaded did until dub fixed it: D can't reflect on > packages so a program must be written that explicitly lists all modules > that need to be looked at. I don't even think fixing package reflection would truly help here because there exist legit D projects that don't transitively import all modules from `main` and recursive compile-time visiting of all symbols would miss them. > There's a disconnect between what's possible at runtime with ModuleInfo > and what's possible at compile-time with __traits(getUnittests). > Fortunately for me, running unit-threaded itself as an executable with > dub fixed the problem, but in the general case this proposal would > suffer from the same problems. Unless we force everyone to use dub. To me it feels like mandatory per-requisite for any test runner changes in druntime right now is to: 1) make compiler emit runtime info on test block basis instead of per module 2) store TypeInfo of unittest block attributes as part of that runtime info signature.asc Description: OpenPGP digital signature
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 08:46:07 UTC, Stefan Koch wrote: On Thursday, 1 September 2016 at 08:44:38 UTC, Stefan Koch wrote: void f(T)(T t) { static if (is(fImpl(t) == void)) { f(t); } else { // default impl here } } Was meant to be void f(T)(T t) { static if (is(fImpl(t) == void)) { fImpl(t); } else { // default impl here } } why not: static if (__traits(compiles, fImpl(t))) ? Andrea
Re: DMD front-end can be used as a library with Dub
I didn't see your announcement, but... AWESOME!! This could be the basis for some really good tutorials on making compiler backends etc... We need more little teaser examples like the one you posted in the beginning of this thread. PS: I did already check the code out on github because I watch code.dlang.org (a lot). Thanks! On Mon, Aug 29, 2016 at 12:42 PM, Alexander Breckel via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > I just tried to use the DMD frontend as a Dub package in my own project to > parse and analyze D files and it ... just worked. The dub.json for dmd is > fairly small and doesn't require any changes to the code. This might be > common knowledge, but I was completely unprepared for this :) > > Please note: This is "only" the dmd frontend (lexer, parser, semantic > passes, CTFE). Code generation will be more complicated. > > The following dub pre-generation hooks were necessary: > > - run src/idgen.d to generate src/id.d > - create verstr.h and SYSCONFDIR.imp > - create and link source/ddmd/ to src/ > > The last point makes ddmd modules reside in its correct package. I'm using > a symbolic link for this, which is the only reason this approach is > currently limited to Linux. In the long run, I think the cleanest way would > be to place all ddmd files in src/ddmd/ and just leave mars.d and things > like idgen.d in the main src/ directory. > > For demonstration purposes, here is a dub package to play around with: > http://code.dlang.org/packages/ddmd-experimental > > Here is the dub.json that was used: > https://github.com/aneas/ddmd-experimental/blob/master/dub.json > > And here is an example program using this API, have fun! > (run with $ chmod +x file.d; ./file.d) > --- > #!/usr/bin/env dub > /+ dub.sdl: > name "ddmd-example" > dependency "ddmd-experimental" version="~>2.71.2-b2dub" > +/ > > import std.path; > import std.stdio; > import std.string; > import ddmd.builtin; > import ddmd.dmodule; > import ddmd.dclass; > import ddmd.dsymbol; > import ddmd.expression; > import ddmd.func; > import ddmd.globals; > import ddmd.id; > import ddmd.identifier; > import ddmd.mtype; > import ddmd.visitor; > > void main(string[] args) { > if(args.length != 2) { > writeln("prints top-level function and class > declarations"); > writeln("usage: ", args[0].baseName, " d-filepath"); > return; > } > > // Initialization > global._init(); > global.params.isLinux = true; > Type._init(); > Id.initialize(); > Module._init(); > Expression._init(); > builtin_init(); > > // Read and parse specified module > auto id = Identifier.idPool(args[1].baseName.stripExtension); > auto m = new Module(args[1].toStringz, id, false, false); > m.read(Loc()); > m.parse(); > > // Output > m.accept(new class Visitor { > extern(C++): > alias visit = Visitor.visit; > override void visit(Module m) { > foreach(i; 0 .. m.members.dim) > (*m.members)[i].accept(this); > } > override void visit(Dsymbol s) { > } > override void visit(FuncDeclaration fd) { > writeln("function ", fd.ident.toString); > } > override void visit(ClassDeclaration cd) { > writeln("class ", cd.ident.toString); > } > }); > } > >
Re: Fallback 'catch-all' template functions
On Thu, Sep 01, 2016 at 03:37:50PM +1000, Manu via Digitalmars-d wrote: > So, consider a set of overloads: > > void f(T)(T t) if(isSomething!T) {} > void f(T)(T t) if(isSomethingElse!T) {} > void f(T)(T t) {} > > I have a recurring problem where I need a fallback function like the > bottom one, which should be used in lieu of a more precise match. > This is obviously an ambiguous call, but this is a pattern that comes > up an awful lot. How to do it in D? > > I've asked this before, and people say: > > void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} > > Consider that more overloads are being introduced by users spread out > across many modules that define their own kind of T; this solution is > no good. Here's a possible workaround: void f(T)(T t) { static if (isSomething!T) { ... } else static if (isSomethingElse!T) { ... } else { ... } } But this won't work across modules. :-( T -- The early bird gets the worm. Moral: ewww...
Statistics functions
Is there no module in D for statistics functions such as mean, median, mode, standard deviation, linear least squares, etc. There are codes on Rosetta Code but a) they seem a bit inconsistent in style; and b) they are not in a module available for use. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: DMD front-end can be used as a library with Dub
On Monday, 29 August 2016 at 10:42:23 UTC, Alexander Breckel wrote: Because of the poor memory management in the compiler, I included a modified GC-stub when I compiled the frontend as a library, so that it can be used in long-running processes: https://gist.github.com/Cauterite/4eb74347aea040f5d371fb49054e1819 You can call gc_annihilate(true) to delete the entire heap. Obviously you need to keep the library in a separate DLL with its own runtime, and carefully avoid holding references to GC memory across annihilations. This technique is working pretty smoothly for me so far. Also to compile it as a DLL you either have to remove main() from mars.d or play games with the C runtime: https://gist.github.com/Cauterite/b190e62891c773703d0de3a1d99df362
Re: Low level unit test library in druntime
On Thursday, 1 September 2016 at 12:06:21 UTC, Dicebot wrote: On 08/31/2016 01:01 PM, Atila Neves wrote: And never mind that any such low level library would suffer from the same problem unit-threaded did until dub fixed it: D can't reflect on packages so a program must be written that explicitly lists all modules that need to be looked at. I don't even think fixing package reflection would truly help here because there exist legit D projects that don't transitively import all modules from `main` and recursive compile-time visiting of all symbols would miss them. [snip] Not a problem, since you can do things like this: // Prints: // tuple("CSVException", "IncompleteCellException", // "HeaderMismatchException", "Malformed", "JSONFloatLiteral", // "JSONOptions", "JSON_TYPE", "JSONValue", "JSONException") pragma (msg, ModuleTypes!("std.csv", "std.json")); /** * Params: *Takes a sequence of module name strings and returns a sequence of all types names *defined in those modules */ template ModuleTypes(ModuleNames...) { import std.meta : staticMap, aliasSeqOf; alias ModuleTypes = aliasSeqOf!(getTypes()); string[] getTypes() { import std.meta : AliasSeq; string[] result; foreach (fqModuleName; ModuleNames) { mixin ("import " ~ fqModuleName ~ ";"); foreach (member; __traits(allMembers, mixin(fqModuleName))) { static if (mixin("is(" ~ member ~ ")")) { result ~= member; } } } return result; } }
Re: Statistics functions
On Thursday, 1 September 2016 at 15:58:38 UTC, Russel Winder wrote: Is there no module in D for statistics functions such as mean, median, mode, standard deviation, linear least squares, etc. There are codes on Rosetta Code but a) they seem a bit inconsistent in style; and b) they are not in a module available for use. Have you tried dstats https://github.com/DlangScience/dstats
Re: Low level unit test library in druntime
On 09/01/2016 07:17 PM, ZombineDev wrote: > On Thursday, 1 September 2016 at 12:06:21 UTC, Dicebot wrote: >> On 08/31/2016 01:01 PM, Atila Neves wrote: >>> And never mind that any such low level library would suffer from the >>> same problem unit-threaded did until dub fixed it: D can't reflect on >>> packages so a program must be written that explicitly lists all >>> modules that need to be looked at. >> >> I don't even think fixing package reflection would truly help here >> because there exist legit D projects that don't transitively import >> all modules from `main` and recursive compile-time visiting of all >> symbols would miss them. >> >>> [snip] > > Not a problem, since you can do things like this: It is exactly _THE_ problem. You can't have the imaginary test runner to reliably find all tests automatically, at least all compiled modules have to be listed explicitly. This is not good, thus I am inclined to call extending RTTI an only viable long-term solution. signature.asc Description: OpenPGP digital signature
Re: DMD front-end can be used as a library with Dub
Thanks, for the GC stub, that will be great for playing with whether or not a little dmd app crashes after gc_annihilate(true). Did I understand that right? R On Thu, Sep 1, 2016 at 6:16 PM, Cauterite via Digitalmars-d < digitalmars-d@puremagic.com> wrote: > On Monday, 29 August 2016 at 10:42:23 UTC, Alexander Breckel wrote: > >> >> > Because of the poor memory management in the compiler, I included a > modified GC-stub when I compiled the frontend as a library, so that it can > be used in long-running processes: > > https://gist.github.com/Cauterite/4eb74347aea040f5d371fb49054e1819 > > You can call gc_annihilate(true) to delete the entire heap. > > Obviously you need to keep the library in a separate DLL with its own > runtime, and carefully avoid holding references to GC memory across > annihilations. > > This technique is working pretty smoothly for me so far. > > Also to compile it as a DLL you either have to remove main() from mars.d > or play games with the C runtime: https://gist.github.com/Cauter > ite/b190e62891c773703d0de3a1d99df362 >
Re: Low level unit test library in druntime
On Thursday, 1 September 2016 at 16:38:15 UTC, Dicebot wrote: On 09/01/2016 07:17 PM, ZombineDev wrote: On Thursday, 1 September 2016 at 12:06:21 UTC, Dicebot wrote: On 08/31/2016 01:01 PM, Atila Neves wrote: And never mind that any such low level library would suffer from the same problem unit-threaded did until dub fixed it: D can't reflect on packages so a program must be written that explicitly lists all modules that need to be looked at. I don't even think fixing package reflection would truly help here because there exist legit D projects that don't transitively import all modules from `main` and recursive compile-time visiting of all symbols would miss them. [snip] Not a problem, since you can do things like this: It is exactly _THE_ problem. You can't have the imaginary test runner to reliably find all tests automatically, at least all compiled modules have to be listed explicitly. This is not good, thus I am inclined to call extending RTTI an only viable long-term solution. Ooh, I thought that by "fixing package reflection" Atila meant the ability to get a list of all modules/packages that the compiler knows about, assuming an all at once compilation. For things like dynamic libraries and incremental compilation, there's obviously no other way than RTTI. But for many use-cases CT reflection should be enough.
Re: Fallback 'catch-all' template functions
On 9/1/16 1:37 AM, Manu via Digitalmars-d wrote: So, consider a set of overloads: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} void f(T)(T t) {} I have a recurring problem where I need a fallback function like the bottom one, which should be used in lieu of a more precise match. This is obviously an ambiguous call, but this is a pattern that comes up an awful lot. How to do it in D? I've asked this before, and people say: void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {} Consider that more overloads are being introduced by users spread out across many modules that define their own kind of T; this solution is no good. I agree. Note that if(isSomethingElse!T) may also need to have if(!isSomething!T && isSomethingElse!T). A suggestion in the past was to allow "else" clauses with if constraints. I had envisioned: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) else if(isSomethingElse!T) {} void f(T)(T t) else {} But someone also suggested this more DRY solution as well (can't remember the thread for it): void f(T)(T t) if(isSomething!T) {} else if(isSomeghingElse!T) {} else {} Obviously this doesn't work across modules, but how does that even work? You need some sort of ordering for an if/else if/else scheme to work. Having a "fallback" template could potentially define a way to handle the default, but it doesn't fix the other issues. I don't know if it's because of the current rules, or just natural, but typically I'm not splitting my template functions between many modules. -Steve
Re: Why D is not popular enough?
On Thursday, 1 September 2016 at 12:04:51 UTC, qznc wrote: On Thursday, 1 September 2016 at 08:04:00 UTC, Bienlein wrote: D has a lot to offer with regard to functional programming. It has pure functions and true immutable classes (true = also sub objects become immutable), which Scala all doesn't have (because of restrictions of the JVM). Does D have tail call recursion optimization? I don't know, actually. If D had that and pattern matching, it would beat Scala with all it's hype by a big leap. D does not guarantee tail calls, but the compiler might sometimes decide to do it. Functional programmer usually want to guarantee, so they don't have to write a loop. The downside of TCO is that the stack trace is missing frames, which can be very confusing. There's a DIP about adding a TCO attribute/pragma: https://github.com/dlang/DIPs/pull/6 FYI: There's some discussion about it's benefit in comparison to functional language D does have loops and it's a lot easier to write and read them. If you want to chime in, please do so at the PR discussion. D has no syntax for pattern matching, but some library support: https://p0nce.github.io/d-idioms/#Recursive-Sum-Type-with-matching Yep it's pretty easy to do within library code, if you use an object chain you might also want to have a look at castSwitch. https://dlang.org/phobos/std_algorithm_comparison.html#.castSwitch
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 16:50:49 UTC, Steven Schveighoffer wrote: I agree. Note that if(isSomethingElse!T) may also need to have if(!isSomething!T && isSomethingElse!T). A suggestion in the past was to allow "else" clauses with if constraints. I had envisioned: void f(T)(T t) if(isSomething!T) {} void f(T)(T t) else if(isSomethingElse!T) {} void f(T)(T t) else {} But someone also suggested this more DRY solution as well (can't remember the thread for it): void f(T)(T t) if(isSomething!T) {} else if(isSomeghingElse!T) {} else {} Obviously this doesn't work across modules, but how does that even work? You need some sort of ordering for an if/else if/else scheme to work. Having a "fallback" template could potentially define a way to handle the default, but it doesn't fix the other issues. I don't know if it's because of the current rules, or just natural, but typically I'm not splitting my template functions between many modules. -Steve I just thought of this, but cannot test if it works. If it does, maybe it would be a suitable solution? void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} //Taken if no other "overload" of f will intantiate with the given T void f(T)(T t) if(!__traits(compiles, alias _ = .f!T)) {}
Re: Fallback 'catch-all' template functions
On 01.09.2016 19:21, Meta wrote: ... I just thought of this, but cannot test if it works. If it does, maybe it would be a suitable solution? void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} //Taken if no other "overload" of f will intantiate with the given T void f(T)(T t) if(!__traits(compiles, alias _ = .f!T)) {} It shouldn't work, but DMD currently seems to allow it. (If you fix the syntax error.) I would expect it to break later. The following causes an ICE (DMD segfaults). import std.stdio; int f(T)(T t) if(!__traits(compiles,.f!T)) { return 0; } int f(T)(T t) if(!__traits(compiles,.f!T)) { return 1; } void main(){ writeln(f(2)); }
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 17:49:13 UTC, Timon Gehr wrote: On 01.09.2016 19:21, Meta wrote: ... I just thought of this, but cannot test if it works. If it does, maybe it would be a suitable solution? void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} //Taken if no other "overload" of f will intantiate with the given T void f(T)(T t) if(!__traits(compiles, alias _ = .f!T)) {} It shouldn't work, but DMD currently seems to allow it. (If you fix the syntax error.) I would expect it to break later. The following causes an ICE (DMD segfaults). import std.stdio; int f(T)(T t) if(!__traits(compiles,.f!T)) { return 0; } int f(T)(T t) if(!__traits(compiles,.f!T)) { return 1; } void main(){ writeln(f(2)); } The idea is that there'd only be one such "fallback" template, so that you cannot get into a situation such as this. I'm guessing the ICE is due to a recursive dependency between the two f templates?
Is it a bug in unittest ?
If one creates a unittest block in a templated class (or struct), the unittest block will be multiplied per class specialization, which might turn out to be quite large number. E.g. struct A(T) { ... unittest { ... } } ... auto a = A!int; auto b = A!int; auto c = A!double; The unittest block will be instantiated twice (per A!int and A!double). But in some (many ?) cases unittest doesn't even exercise the generics, merely using some particular type. What is it, a bug ?
Re: Is it a bug in unittest ?
On Thursday, 1 September 2016 at 18:11:55 UTC, angel wrote: If one creates a unittest block in a templated class (or struct), the unittest block will be multiplied per class specialization, which might turn out to be quite large number. E.g. struct A(T) { ... unittest { ... } } ... auto a = A!int; auto b = A!int; auto c = A!double; The unittest block will be instantiated twice (per A!int and A!double). But in some (many ?) cases unittest doesn't even exercise the generics, merely using some particular type. What is it, a bug ? I think this is inteded behaviour. If the unittest is not dependent on the current instantiation, you can move it outside the template. By the way, it is common practice to put unittests after, and not inside, the tested struct/class. That is: === struct A(T) { unittest { A a; // uses current instantiation; repeated for every instantiation } } unittest { A!int b;// tests specific instantiations A!double c; // not repeated } ===
Re: Fallback 'catch-all' template functions
On 01.09.2016 19:55, Meta wrote: On Thursday, 1 September 2016 at 17:49:13 UTC, Timon Gehr wrote: On 01.09.2016 19:21, Meta wrote: ... I just thought of this, but cannot test if it works. If it does, maybe it would be a suitable solution? void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} //Taken if no other "overload" of f will intantiate with the given T void f(T)(T t) if(!__traits(compiles, alias _ = .f!T)) {} It shouldn't work, but DMD currently seems to allow it. (If you fix the syntax error.) I would expect it to break later. The following causes an ICE (DMD segfaults). import std.stdio; int f(T)(T t) if(!__traits(compiles,.f!T)) { return 0; } int f(T)(T t) if(!__traits(compiles,.f!T)) { return 1; } void main(){ writeln(f(2)); } The idea is that there'd only be one such "fallback" template, so that you cannot get into a situation such as this. I'm guessing the ICE is due to a recursive dependency between the two f templates? I posted the ICE to show that DMD does not necessarily have a clear concept of how your code should be interpreted. Note that you are essentially saying: "If not X then X". It's very easy to run into behaviour that seems inconsistent once you do things like this. enum isSomething(T)=false; int f(T)(T t) if(isSomething!T){ return 0; } int f(T)(T t) if(!compiles!".f!int") { return 2; } enum compiles(string s) = __traits(compiles,mixin(s)); pragma(msg, compiles!".f!int"); // false pragma(msg, __traits(compiles,.f!int)); // true DMD cannot properly process code like this (i.e. code that contradicts itself, where the same expression in the same context can be true in one part of the compilation, but false later). Examples can be constructed where the semantics of the resulting code depends on the order that modules are passed on the command line. It's not specified anywhere what should happen, and it is not immediately clear. DMD shouldn't accept code like this in the first place. It's very brittle, the result depends on random compiler implementation details.
Re: Is it a bug in unittest ?
On Thu, Sep 01, 2016 at 06:11:55PM +, angel via Digitalmars-d wrote: > If one creates a unittest block in a templated class (or struct), the > unittest block will be multiplied per class specialization, which > might turn out to be quite large number. > > E.g. > struct A(T) { > ... > unittest { > ... > } > } > > ... > > auto a = A!int; > auto b = A!int; > auto c = A!double; > > The unittest block will be instantiated twice (per A!int and > A!double). But in some (many ?) cases unittest doesn't even exercise > the generics, merely using some particular type. > > What is it, a bug ? It can be construed to be a bug or a feature, depending on how you use it. :-) A unittest block inside a template is generally useful for testing things that depend on the template parameters, e.g., to ensure that A!int, A!double, A!string, etc., all satisfy certain requirements. But if the unittest block tests only specific instantiations, e.g., only A!int, then it's better to move it outside the template body, so that it's only instantiated once. In other words, unittest inside a template body is useful for testing *all* instantiations of a template; unittest outside a template body is useful for testing *specific* instantiations. Of course, moving unittests outside the template is troublesome if you're using the ddoc'd unittest feature (where the body of a unittest becomes part of a member function's documentation). In such cases you could do something like this: struct A(T) { /// ddoc body here auto myMethod(Args)(Args args) { ... } static if (T == int) /// unittest { ... // test A!int here } } // of course, make sure the unittest actually runs! version(unittest) auto A_int = A!int; T -- Doubtless it is a good thing to have an open mind, but a truly open mind should be open at both ends, like the food-pipe, with the capacity for excretion as well as absorption. -- Northrop Frye
Re: Image of D code on Norwegian IT news site
On Wednesday, 31 August 2016 at 18:50:58 UTC, simendsjo wrote: An article about how outsourcing reduces the need for Norwegian developers. No links to D other than the image on top though. I wonder what they searched for to find this image. http://www.digi.no/artikler/rader-norske-it-folk-til-a-droppe-programmering/279380 I assume Norwegian jobs are taken away by these annoying Romanians :)
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 18:24:13 UTC, Timon Gehr wrote: The idea is that there'd only be one such "fallback" template, so that you cannot get into a situation such as this. I'm guessing the ICE is due to a recursive dependency between the two f templates? I posted the ICE to show that DMD does not necessarily have a clear concept of how your code should be interpreted. Note that you are essentially saying: "If not X then X". It's very easy to run into behaviour that seems inconsistent once you do things like this. Well, I'd argue that's not quite right and the correct interpretation is "If not the other X then this X", due to the `!__traits(compiles, .f!T)`, explicitly telling the compiler to check if the *other* "overloads" compile. I don't actually know whether template constraints are considered to be at module scope or in the template scope, though, so maybe I'm completely wrong on this. enum isSomething(T)=false; int f(T)(T t) if(isSomething!T){ return 0; } int f(T)(T t) if(!compiles!".f!int") { return 2; } enum compiles(string s) = __traits(compiles,mixin(s)); pragma(msg, compiles!".f!int"); // false pragma(msg, __traits(compiles,.f!int)); // true DMD cannot properly process code like this (i.e. code that contradicts itself, where the same expression in the same context can be true in one part of the compilation, but false later). Examples can be constructed where the semantics of the resulting code depends on the order that modules are passed on the command line. It's not specified anywhere what should happen, and it is not immediately clear. DMD shouldn't accept code like this in the first place. It's very brittle, the result depends on random compiler implementation details. I would argue that this is an entirely different case than my example, but we are getting into compiler implementation details that I know nothing about, so I can't actually say whether it is (or should) be valid code.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 17:21:02 UTC, Meta wrote: I just thought of this, but cannot test if it works. If it does, maybe it would be a suitable solution? void f(T)(T t) if(isSomething!T) {} void f(T)(T t) if(isSomethingElse!T) {} //Taken if no other "overload" of f will intantiate with the given T void f(T)(T t) if(!__traits(compiles, alias _ = .f!T)) {} That's so dirty, I love it. I imagine if __traits(getOverloads worked for templates we could actually use this pretty reliably (by excluding the fallback template from the search).
Re: Usability of "allMembers and derivedMembers traits now only return visible symbols"
On Wednesday, 31 August 2016 at 13:29:52 UTC, Basile B. wrote: On Wednesday, 31 August 2016 at 13:12:30 UTC, Adam D. Ruppe wrote: Ugh, it really should just give everything and have getMember bypass it. That won't even break any code! you're right. "allMembers" means "all" after all. Another reason why the idea of "allVisibleMembers" is good. Puristes will be able to use this traits without messing with "getProtection". https://github.com/dlang/DIPs/pull/39 Co-authors welcome.
Re: Fallback 'catch-all' template functions
On 01.09.2016 21:02, Meta wrote: On Thursday, 1 September 2016 at 18:24:13 UTC, Timon Gehr wrote: The idea is that there'd only be one such "fallback" template, so that you cannot get into a situation such as this. I'm guessing the ICE is due to a recursive dependency between the two f templates? I posted the ICE to show that DMD does not necessarily have a clear concept of how your code should be interpreted. Note that you are essentially saying: "If not X then X". It's very easy to run into behaviour that seems inconsistent once you do things like this. Well, I'd argue that's not quite right and the correct interpretation is "If not the other X then this X", due to the `!__traits(compiles, .f!T)`, explicitly telling the compiler to check if the *other* "overloads" compile. Even if that was the intention of the compiler implementation, the example below demonstrates why it cannot work. I don't actually know whether template constraints are considered to be at module scope or in the template scope, though, so maybe I'm completely wrong on this. ... Template scope, but /nothing/ about '.' says "other". enum isSomething(T)=false; int f(T)(T t) if(isSomething!T){ return 0; } int f(T)(T t) if(!compiles!".f!int") { return 2; } enum compiles(string s) = __traits(compiles,mixin(s)); pragma(msg, compiles!".f!int"); // false pragma(msg, __traits(compiles,.f!int)); // true DMD cannot properly process code like this (i.e. code that contradicts itself, where the same expression in the same context can be true in one part of the compilation, but false later). Examples can be constructed where the semantics of the resulting code depends on the order that modules are passed on the command line. It's not specified anywhere what should happen, and it is not immediately clear. DMD shouldn't accept code like this in the first place. It's very brittle, the result depends on random compiler implementation details. I would argue that this is an entirely different case than my example, but we are getting into compiler implementation details that I know nothing about, so I can't actually say whether it is (or should) be valid code. It's basically the same thing.
Re: Fallback 'catch-all' template functions
On Thursday, 1 September 2016 at 19:32:23 UTC, Timon Gehr wrote: Well, I'd argue that's not quite right and the correct interpretation is "If not the other X then this X", due to the `!__traits(compiles, .f!T)`, explicitly telling the compiler to check if the *other* "overloads" compile. Even if that was the intention of the compiler implementation, the example below demonstrates why it cannot work. I don't actually know whether template constraints are considered to be at module scope or in the template scope, though, so maybe I'm completely wrong on this. ... Template scope, but /nothing/ about '.' says "other". It means to look up the symbol f at module scope, so I guess it depends on whether the compiler excludes the current template from that lookup. template f() if (someCondition) {} template f() if (someOtherCondition) {} template f() if (!__traits(compiles, { alias _ = .f!(); })) {} Does `.f` refer to all symbols named f at module scope, or all symbols named f *other than* the symbol for which the current template constraint is being processed? Actually, I just convinced myself that it's obviously not the latter and so must be the former, and now I see why this shouldn't work.
Re: Why D is not popular enough?
On Thursday, 1 September 2016 at 17:10:00 UTC, Seb wrote: FYI: There's some discussion about it's benefit in comparison to functional language D does have loops and it's a lot easier to write and read them. Some are of that opinion. However, this is D, not Python or Go, so claims about the one true preference is not a valid argument against a particular feature.
Re: colour lib
Am Wed, 31 Aug 2016 15:58:28 +1000 schrieb Manu via Digitalmars-d : > I have this implementation issue, which I'm having trouble applying > good judgement, I'd like to survey opinions... > > So, RGB colours depend on this 'normalised integer' concept, that is: > unsigned: luminance = val / IntType.max > signed: luminance = max(val / IntType.max, -1.0) > > So I introduce NormalizedInt(T), which does that. > > The question is, what should happen when someone does: > NormalisedInt!ubyte nub; > NormalizedInt!byte nb; > auto r = nub + nb; > > What is typeof(r)? > > There are 3 options that stand out, and I have no idea which one is correct. > 1. Compile error, mismatching NormalisedInt type arithmetic shouldn't > work; require explicit user intervention. > 2. 'Correct' result, ie, lossless; is(typeof(r) == > NormalisedInt!short). Promote to type that doesn't lose precision, > type conversion loses efficiency, but results always correct. > 3. Do what normal int types do; is(typeof(r) == NormalisedInt!int) ie, > apply the normal integer arithmetic type promotion rules. Classic > pain-in-the-arse applies when implicitly promoted result is stored to > a lower-precision value. Probably also slow (even slower) than option > #2. > > Are there other options? > I'm tempted by #1, but that will follow right through to the colour > implementation, which will lead to colour type cast's all over the > place. I'd suspect #1 to be the best option, too. However, I don't know when users will deal with these calculations. Surely adding sRGB(22,22,22) + sRGB(11,11,11) gives sRGB(28, 28, 28), with a higher precision while performing the addition and then rounding back. Anything requiring multiple operations on an image should use a higher precision linear color space from the start. -- Marco
Re: Image of D code on Norwegian IT news site
On Thursday, 1 September 2016 at 18:45:14 UTC, deadalnix wrote: On Wednesday, 31 August 2016 at 18:50:58 UTC, simendsjo wrote: An article about how outsourcing reduces the need for Norwegian developers. No links to D other than the image on top though. I wonder what they searched for to find this image. http://www.digi.no/artikler/rader-norske-it-folk-til-a-droppe-programmering/279380 I assume Norwegian jobs are taken away by these annoying Romanians :) Shots fired!
Re: Statistics functions
On Thursday, 1 September 2016 at 16:28:35 UTC, jmh530 wrote: On Thursday, 1 September 2016 at 15:58:38 UTC, Russel Winder wrote: Is there no module in D for statistics functions such as mean, median, mode, standard deviation, linear least squares, etc. There are codes on Rosetta Code but a) they seem a bit inconsistent in style; and b) they are not in a module available for use. Have you tried dstats https://github.com/DlangScience/dstats Now with actually working API docs: https://dlangscience.github.io/dstats/api/
Re: DMD front-end can be used as a library with Dub
On Thu, 01 Sep 2016 18:42:13 +0200, Rory McGuire via Digitalmars-d wrote: > Thanks, for the GC stub, that will be great for playing with whether or > not a little dmd app crashes after gc_annihilate(true). > > Did I understand that right? It sounds like this there's a special function `gc_annihilate` that immediately frees all memory that libdmd has allocated. It doesn't do any reference tracking or mark/sweep. libdmd disables the collector as dmdfe does. You need to keep dmd in its own DLL. Otherwise, symbols between dmd and your application will be deduplicated or something and either you get a linker error or an arbitrary implementation is selected. Another safe way of working is to use the GC as usual, but before you call into libdmd, you call GC.disable, and you wait until you've finished using the data structures it returns before calling GC.enable.
code.dlang.org 500 Internal Server Error
code.dlang.org 500 Internal Server Error Does anyone experience the same probleme?
Re: code.dlang.org 500 Internal Server Error
On Friday, 2 September 2016 at 04:43:46 UTC, Uranuz wrote: code.dlang.org 500 Internal Server Error Does anyone experience the same probleme? Unfortunately yes https://github.com/dlang/dub-registry/issues/174
Re: code.dlang.org 500 Internal Server Error
On Friday, 2 September 2016 at 04:43:46 UTC, Uranuz wrote: code.dlang.org 500 Internal Server Error Does anyone experience the same probleme? Yes, its been like this for a few hours at least. It's causing travis-ci build failures also.
Re: colour lib
On 2 September 2016 at 06:09, Marco Leise via Digitalmars-d wrote: > Am Wed, 31 Aug 2016 15:58:28 +1000 > schrieb Manu via Digitalmars-d : > >> I have this implementation issue, which I'm having trouble applying >> good judgement, I'd like to survey opinions... >> >> So, RGB colours depend on this 'normalised integer' concept, that is: >> unsigned: luminance = val / IntType.max >> signed: luminance = max(val / IntType.max, -1.0) >> >> So I introduce NormalizedInt(T), which does that. >> >> The question is, what should happen when someone does: >> NormalisedInt!ubyte nub; >> NormalizedInt!byte nb; >> auto r = nub + nb; >> >> What is typeof(r)? >> >> There are 3 options that stand out, and I have no idea which one is correct. >> 1. Compile error, mismatching NormalisedInt type arithmetic shouldn't >> work; require explicit user intervention. >> 2. 'Correct' result, ie, lossless; is(typeof(r) == >> NormalisedInt!short). Promote to type that doesn't lose precision, >> type conversion loses efficiency, but results always correct. >> 3. Do what normal int types do; is(typeof(r) == NormalisedInt!int) ie, >> apply the normal integer arithmetic type promotion rules. Classic >> pain-in-the-arse applies when implicitly promoted result is stored to >> a lower-precision value. Probably also slow (even slower) than option >> #2. >> >> Are there other options? >> I'm tempted by #1, but that will follow right through to the colour >> implementation, which will lead to colour type cast's all over the >> place. > > I'd suspect #1 to be the best option, too. However, I don't > know when users will deal with these calculations. Neither do I, it's just that NormalizedInt is a type, it's a dependency, it exists, it needs an api, so it needs to be well defined I guess. I wonder, should NormalizedInt be a module beneath the color package, or should it be a separate module in its own right? I don't know of uses for that type outside packed colours, but it could theoretically be used for anything... > Surely adding sRGB(22,22,22) + sRGB(11,11,11) gives sRGB(28, 28, 28), > with a higher precision while performing the addition and then > rounding back. Umm, no. I think operations should be within their own colourspace, otherwise what's the point of selecting your working colourspace? You need to be able to do operations in gamma space too. If you want to do a linear operation, cast to a linear type before doing the operation. > Anything requiring multiple operations on an > image should use a higher precision linear color space from > the start. Right, I think you would typically cast from the storage type to the working type before doing some work. But there are so many cases, and various levels of tradeoff between efficiency and correct-ness, the lib can't make presumptions. The way it is currently, the operations are done in the typed colourspace. Simple as that. If you want to do linear operations, cast to a linear type first.