www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Isn't `each` too much of a good thing?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
The implementation of each in std.algorithm.iteration sets out a lofty 
goal: whatever can be iterated, must be iterated with each.

Problem is, there are way too many things that can be iterated in D and 
too many ways to iterate them. This leads to a veritable gallop of checks:

     alias BinaryArgs = AliasSeq!(fun, "i", "a");

     enum isRangeUnaryIterable(R) =
         is(typeof(unaryFun!fun(R.init.front)));

     enum isRangeBinaryIterable(R) =
         is(typeof(binaryFun!BinaryArgs(0, R.init.front)));

     enum isRangeIterable(R) =
         isInputRange!R &&
         (isRangeUnaryIterable!R || isRangeBinaryIterable!R);

     enum isForeachUnaryIterable(R) =
         is(typeof((R r) {
             foreach (ref a; r)
                 cast(void) unaryFun!fun(a);
         }));

     enum isForeachUnaryWithIndexIterable(R) =
         is(typeof((R r) {
             foreach (i, ref a; r)
                 cast(void) binaryFun!BinaryArgs(i, a);
         }));

     enum isForeachBinaryIterable(R) =
         is(typeof((R r) {
             foreach (ref a, ref b; r)
                 cast(void) binaryFun!fun(a, b);
         }));

     enum isForeachIterable(R) =
         (!isForwardRange!R || isDynamicArray!R) &&
         (isForeachUnaryIterable!R || isForeachBinaryIterable!R ||
          isForeachUnaryWithIndexIterable!R);

Does this pass the laugh test? How can one explain a colleague "yep, 
here are the conditions under which you can iterate over an object in 
the D language".

I don't contest the correctness of this code. I contest its being 
sensible. There's just too much of a good thing.

For example: static arrays are supported. Why? This creates a dangerous 
precedent whereby we'd need to support static arrays with other 
primitives, such as map or reduce. (We don't, and we shouldn't. Let them 
add a "[]" to the array.) Where do you stop?

We support opApply with one, two, or more arguments. Built-in hashtables 
(when was the last time you were in a place in your life where 
hashtable.each was useful?). You name it - we support it.

This is in the same league with supporting enums that use string as a 
base, as "some kinda sorta string thing".

Too much!

I have no idea how to improve this code because it will break one of the 
suitably overspecialized unittests. But this kind of stuff has no place 
in stdv2021.
Sep 17 2020
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/17/20 12:18 PM, Andrei Alexandrescu wrote:
[snip]

Can't believe I forgot to mention what would be the ultimate smoking 
gun: all of that crap spills into the user-visible documentation: each 
is constrained on symbols not documented and not available to the user!

https://dlang.org/library/std/algorithm/iteration/each.each.html

Sure, one may have a vague idea what isForeachIterable or 
isRangeIterable are, but these are neither documented, nor accessible to 
user code. The user's only chance is peruse the source code or "build 
and pray".

We really must draw the line at defining constraints in terms of private 
symbols. That's a no-no.
Sep 17 2020
prev sibling next sibling parent reply Seb <seb wilzba.ch> writes:
On Thursday, 17 September 2020 at 16:18:18 UTC, Andrei 
Alexandrescu wrote:
 We support opApply with one, two, or more arguments. Built-in 
 hashtables (when was the last time you were in a place in your 
 life where hashtable.each was useful?). You name it - we 
 support it.
It's a standard library - catering for almost everything is in the job description ;-)
 This is in the same league with supporting enums that use 
 string as a base, as "some kinda sorta string thing".

 Too much!
I don't think anyone argues with you here.
 I have no idea how to improve this code because it will break 
 one of the suitably overspecialized unittests.
Well, more importantly there's a high chance it will break actual code.
 But this kind of stuff has no place in stdv2021.
The only way for this to ever happen is if we start with it. One function at a time. I suggest simply creating a new repository and starting from zero. Apart from the clear mental divide and separation, this has the added advantage that we can just keep druntime and phobos as is and work on a new combined "base" library. There are a few others like being able to immediately ship it via dub or being able to use GitHub's features (issues, projects, roadmaps, ...). Also, as we're almost done with migrating off auto-tester, setting up the same CIs wouldn't be a big hassle and I would be happy to do so ;-)
Sep 17 2020
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 9/17/20 1:41 PM, Seb wrote:
 On Thursday, 17 September 2020 at 16:18:18 UTC, Andrei Alexandrescu wrote:
 We support opApply with one, two, or more arguments. Built-in 
 hashtables (when was the last time you were in a place in your life 
 where hashtable.each was useful?). You name it - we support it.
It's a standard library - catering for almost everything is in the job description ;-)
You know it doesn't quite work like that. By that argument most range algorithms should work on static arrays, and actually beginners ask for such on occasion. We have deemed that too much effort for no good outcome. In that context, each is both an outlier and a dangerous precedent. I recall you and I discussed each in the past. Probably we agreed it should work with everything one could reasonably use a loop with. Maybe you worked on it, too. I didn't check because it's not important; we should dissociate the code from whoever created it, and indeed I found myself critical of code I later discovered I'd written myself. This particular code is finely done, it's the charter we need to revise. The fact that constraints come in form not knowable or verifiable by the user is a deal-breaker as bad as accepts-invalid. That transcends backward compatibility. (Reminds me with a discussion I had with a salesman: "You should really subscribe to X." "What is X?" <vague description> "I don't understand." "Well it's really good, you should really try it out regardless so you get an idea." "How can you advise me to subscribe to something I don't understand?") I created https://issues.dlang.org/show_bug.cgi?id=21260.
Sep 17 2020
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 17, 2020 at 05:41:56PM +0000, Seb via Digitalmars-d wrote:
 On Thursday, 17 September 2020 at 16:18:18 UTC, Andrei Alexandrescu wrote:
[...]
 But this kind of stuff has no place in stdv2021.
The only way for this to ever happen is if we start with it. One function at a time.
Indeed. We've been talking about std.v${next} for what, almost (or already?) a year now? Time to take action.
 I suggest simply creating a new repository and starting from zero.
Yes, yes, yes!
 Apart from the clear mental divide and separation, this has the added
 advantage that we can just keep druntime and phobos as is and work on
 a new combined "base" library. There are a few others like being able
 to immediately ship it via dub or being able to use GitHub's features
 (issues, projects, roadmaps, ...).
[...] This is a good way to start from a clean slate. Say we set it up such that you could use a compiler switch to switch between current-Phobos and new-Phobos. Maybe with a path override or some such. Make it easy to test the new library with existing code, but without the forced commitment and breakage of actually replacing current-Phobos. This would allow us to test the state of the new library against existing code and gauge how well we're doing / determine what kinds of breakages might occur and what migration path(s) are available for people who want to upgrade their code. Also, we should use a disjoint namespace so that when new-Phobos does become official, old code can still continue working as-is (maybe add a path or two so that the compiler can find legacy-Phobos). I propose std.v2.* -- with the anticipation that, a decade or so from now, there will be a std.v3.* which can be added without breaking all prior code. As Andrei has said -- stop changing, start adding. T -- We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
Sep 17 2020
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2020-09-17 19:41, Seb wrote:

 The only way for this to ever happen is if we start with it. One 
 function at a time.
 I suggest simply creating a new repository and starting from zero.
 Apart from the clear mental divide and separation, this has the added 
 advantage that we can just keep druntime and phobos as is and work on a 
 new combined "base" library. There are a few others like being able to 
 immediately ship it via dub or being able to use GitHub's features 
 (issues, projects, roadmaps, ...).
I suggest to have some for of plan. If we start just throwing in stuff it most likely is not going to be any better than the current version. -- /Jacob Carlborg
Sep 18 2020
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/18/20 10:26 AM, Jacob Carlborg wrote:
 On 2020-09-17 19:41, Seb wrote:
 
 The only way for this to ever happen is if we start with it. One 
 function at a time.
 I suggest simply creating a new repository and starting from zero.
 Apart from the clear mental divide and separation, this has the added 
 advantage that we can just keep druntime and phobos as is and work on 
 a new combined "base" library. There are a few others like being able 
 to immediately ship it via dub or being able to use GitHub's features 
 (issues, projects, roadmaps, ...).
I suggest to have some for of plan. If we start just throwing in stuff it most likely is not going to be any better than the current version.
At DConf 2019 I discussed a new version of std separately with a handful of folks. Two things that all discussions had in common: 1. They were incredibly excited by the perspective. 2. They had wildly different (and in parts conflicting) views on what that should look like.
Sep 18 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Sep 18, 2020 at 10:40:08AM -0400, Andrei Alexandrescu via Digitalmars-d
wrote:
[...]
 At DConf 2019 I discussed a new version of std separately with a
 handful of folks. Two things that all discussions had in common:
 
 1. They were incredibly excited by the perspective.
 
 2. They had wildly different (and in parts conflicting) views on what
 that should look like.
So where do we go from here? What about we make itemized lists of the wildly different views and see if we can find some common ground that we can build on? T -- "Real programmers can write assembly code in any language. :-)" -- Larry Wall
Sep 18 2020
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 9/18/20 11:02 AM, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 10:40:08AM -0400, Andrei Alexandrescu via
Digitalmars-d wrote:
 [...]
 At DConf 2019 I discussed a new version of std separately with a
 handful of folks. Two things that all discussions had in common:

 1. They were incredibly excited by the perspective.

 2. They had wildly different (and in parts conflicting) views on what
 that should look like.
So where do we go from here? What about we make itemized lists of the wildly different views and see if we can find some common ground that we can build on?
A strong leader needs to emerge. A vague list-driven community effort is doomed to shuffle the rubble once again with a 2% increase in overall quality of the library. A good leader would have a powerful overall vision and at least one big specific idea.
Sep 18 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Sep 18, 2020 at 02:02:17PM -0400, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 9/18/20 11:02 AM, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 10:40:08AM -0400, Andrei Alexandrescu via
Digitalmars-d wrote:
 [...]
 At DConf 2019 I discussed a new version of std separately with a
 handful of folks. Two things that all discussions had in common:
[...]
 So where do we go from here?  What about we make itemized lists of
 the wildly different views and see if we can find some common ground
 that we can build on?
A strong leader needs to emerge. A vague list-driven community effort is doomed to shuffle the rubble once again with a 2% increase in overall quality of the library. A good leader would have a powerful overall vision and at least one big specific idea.
So who will this person be? If there are no candidates, then I'm just going to bow out, since it will just be another vacuous hypothetical discussion that leads to no action and no change. <offtopic> Perhaps this is the underlying problem with D and its community. We're all looking for revolutionary change, neglecting that sometimes progress is made incrementally. If we reject the incremental while waiting for the revolutionary that never arrives, that's just letting the perfect become the enemy of the good. This would explain a lot of our problems. Like revolutionary features that are not quite finished, features that have gaping holes for years, and the like. We have an awesome language that has huge potential, but it's being let down by rough edges and lack of polish, because good is not good enough for us, and the perfect hasn't arrived yet, and nobody knows when (or if) it will. </offtopic> T -- Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't.
Sep 18 2020
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 9/18/20 2:24 PM, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 02:02:17PM -0400, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 9/18/20 11:02 AM, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 10:40:08AM -0400, Andrei Alexandrescu via
Digitalmars-d wrote:
 [...]
 At DConf 2019 I discussed a new version of std separately with a
 handful of folks. Two things that all discussions had in common:
[...]
 So where do we go from here?  What about we make itemized lists of
 the wildly different views and see if we can find some common ground
 that we can build on?
A strong leader needs to emerge. A vague list-driven community effort is doomed to shuffle the rubble once again with a 2% increase in overall quality of the library. A good leader would have a powerful overall vision and at least one big specific idea.
So who will this person be? If there are no candidates, then I'm just going to bow out, since it will just be another vacuous hypothetical discussion that leads to no action and no change. <offtopic> Perhaps this is the underlying problem with D and its community. We're all looking for revolutionary change, neglecting that sometimes progress is made incrementally. If we reject the incremental while waiting for the revolutionary that never arrives, that's just letting the perfect become the enemy of the good. This would explain a lot of our problems. Like revolutionary features that are not quite finished, features that have gaping holes for years, and the like. We have an awesome language that has huge potential, but it's being let down by rough edges and lack of polish, because good is not good enough for us, and the perfect hasn't arrived yet, and nobody knows when (or if) it will. </offtopic>
Fair point, and I wanted to write a related post as well. Just FWIW, Walter and Steve Schveighoffer are discussing how to version phobos appropriately. That is important work that qualifies as incremental.
Sep 22 2020
prev sibling next sibling parent reply Avrina <avrina12309412342 gmail.com> writes:
On Thursday, 17 September 2020 at 16:18:18 UTC, Andrei 
Alexandrescu wrote:
 For example: static arrays are supported. Why? This creates a 
 dangerous precedent whereby we'd need to support static arrays 
 with other primitives, such as map or reduce. (We don't, and we 
 shouldn't. Let them add a "[]" to the array.) Where do you stop?
It should support foreach(), which would support static arrays. The problem is there is so many ways to do something, and part of that is on Phobos the way ranges were defined and are used. They aren't very efficient, they create excessive copies, and if you have a type that can't be copied then you pretty much can't use it at all. You have situations like writeln() that uses ranges and doesn't have a path for types that support foreach(), this ends up with bugs where writeln ends up modifying the const object it was passed. Because it has to cast away the constness to be able to iterate through a range. If you only support phobos ranges your are going to be left with a gaping hole that's currently filled with a language feature (that should be supported). `reduce` does support static arrays btw.
Sep 17 2020
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 9/17/20 1:56 PM, Avrina wrote:
 `reduce` does support static arrays btw.
Somebody shoot me.
Sep 17 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 17, 2020 at 02:41:09PM -0400, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 9/17/20 1:56 PM, Avrina wrote:
 `reduce` does support static arrays btw.
Somebody shoot me.
BANG. :-P IMO, we should deprecate static array support on .reduce. (Not that it really matters anymore to me; .reduce has the wrong parameter order from the days before UFCS, and has been supplanted by .fold. I sure hope .fold isn't stupid enough to accept static arrays...) T -- Маленькие детки - маленькие бедки.
Sep 17 2020
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 9/17/20 2:50 PM, H. S. Teoh wrote:
 On Thu, Sep 17, 2020 at 02:41:09PM -0400, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 9/17/20 1:56 PM, Avrina wrote:
 `reduce` does support static arrays btw.
Somebody shoot me.
BANG. :-P IMO, we should deprecate static array support on .reduce. (Not that it really matters anymore to me; .reduce has the wrong parameter order from the days before UFCS, and has been supplanted by .fold. I sure hope .fold isn't stupid enough to accept static arrays...)
Looks like it does: https://run.dlang.io/is/GiStHq
Sep 17 2020
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 17, 2020 at 04:19:38PM -0400, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 9/17/20 2:50 PM, H. S. Teoh wrote:
[...]
 IMO, we should deprecate static array support on .reduce. (Not that
 it really matters anymore to me; .reduce has the wrong parameter
 order from the days before UFCS, and has been supplanted by .fold.
 I sure hope .fold isn't stupid enough to accept static arrays...)
Looks like it does: https://run.dlang.io/is/GiStHq
And a glance at the code reveals why: .fold uses .reduce as its implementation. So yeah, we should deprecate static array support on .reduce. T -- What's an anagram of "BANACH-TARSKI"? BANACH-TARSKI BANACH-TARSKI.
Sep 17 2020
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, September 17, 2020 10:18:18 AM MDT Andrei Alexandrescu via 
Digitalmars-d wrote:
 This is in the same league with supporting enums that use string as a
 base, as "some kinda sorta string thing".

 Too much!

 I have no idea how to improve this code because it will break one of the
 suitably overspecialized unittests. But this kind of stuff has no place
 in stdv2021.
Agreed. I think that it's yet another case of something being added, because someone thought that it would be useful - probably several things over several iterations of the code. Getting stray stuff into Phobos like that doesn't really have a particularly high bar. Pull requests either tend to either sit around for too long and/or just get merged because they don't do anything clearly bad. Sometimes, someone will object to a particular pull request due to something like adding support for static arrays, and the changes won't get in, but I think that it's more likely that it will get in simply because the work was done, and it passes the tests. We've never really had enough people looking at pull requests, and we haven't had clear guidelines for how some stuff should be handled. So, a number of things get handled inconsistently. On some level, I think that our attempts to not PRs sitting around forever have also led to more questionable code getting committed in a number of cases. I don't know what a good way to fix that is. Of course, another part of the calculus here is how changing how we've done stuff over time has caused some fun problems - like templatizing a function that used to explicitly take string. You then get a function that shouldn't accept static arrays or enums with a base type of string but which has to in order to avoid breaking code. isConvertibleToString is one of the big mistakes that came out of that, and we still haven't purged it from Phobos. Regardless, IMHO, we should be avoiding support for static arrays and opApply in range-based code. At most, maybe there should be a way to convert a type with opApply to a range, but static arrays are already solved just by slicing them. In general, by requiring that someone explicitly do a conversion or wrap something in another type in order to make it a range, we can really simplify code. And in general, supporting implicit conversions in templated code just adds complexity and landmines (e.g. you can easily get bugs by testing that a type is implicitly convertible in the constraint but then not explicitly converting the type within the function). IMHO, for the most part, the less we support implicit conversions the better. I honestly wish that static arrays didn't even implicitly convert to dynamic arrays. If we're really going to do another version of Phobos and rework ranges, then I think that as part of that, we should make various rules about how Phobos will handle ranges (and how most code should handle ranges) clear. Even when there's agreement on some of that stuff right now among most of the key developers, it's not necessarily well-documented. We should probably have explicitly documented rules and guidelines about stuff like not supporting static ranges in range-based code. That would then at least allow us to avoid some of the problems like shown here with each - as well as better document how ranges work and are supposed to be used in general. - Jonathan M Davis
Sep 17 2020
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 17, 2020 at 01:41:00PM -0600, Jonathan M Davis via Digitalmars-d
wrote:
[...]
 Regardless, IMHO, we should be avoiding support for static arrays and
 opApply in range-based code. At most, maybe there should be a way to
 convert a type with opApply to a range, but static arrays are already
 solved just by slicing them. In general, by requiring that someone
 explicitly do a conversion or wrap something in another type in order
 to make it a range, we can really simplify code.
Yes, yes, and yes! Separate out the concerns by letting another function take care of adapting {static array, opApply iterable, what have you} to the range API, then delete the non-range code that the implementation currently has. Result: cleaner code, more modular, and each piece is more reusable (the adaptor can be used for other things besides .each). [...]
 I honestly wish that static arrays didn't even implicitly convert to
 dynamic arrays.
That bug has been filed for years, I wish somebody would take it up and push it in. :-/ That has been a bad idea for years and yet it still persists. https://issues.dlang.org/show_bug.cgi?id=15932
 If we're really going to do another version of Phobos and rework
 ranges, then I think that as part of that, we should make various
 rules about how Phobos will handle ranges (and how most code should
 handle ranges) clear.  Even when there's agreement on some of that
 stuff right now among most of the key developers, it's not necessarily
 well-documented. We should probably have explicitly documented rules
 and guidelines about stuff like not supporting static ranges in
 range-based code. That would then at least allow us to avoid some of
 the problems like shown here with each - as well as better document
 how ranges work and are supposed to be used in general.
[...] Yes, and we need water-tight wording in the documentation to leave no ambiguities in things like how things get copied around (or not), what happens after passing a to a function and the function returns, transient .front, ref, const, etc.. All seemingly trivial things, but left unadddressed, they can really become thorns in our sides. T -- An elephant: A mouse built to government specifications. -- Robert Heinlein
Sep 17 2020
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, September 17, 2020 2:07:35 PM MDT H. S. Teoh via Digitalmars-d 
wrote:
 That bug has been filed for years, I wish somebody would take it up and
 push it in. :-/  That has been a bad idea for years and yet it still
 persists.

   https://issues.dlang.org/show_bug.cgi?id=15932
I've brought it up to Walter before. As I understand it, his opinion is that scope solves the problem. And while I agree that it helps, I still think that it would be better to just disallow the implict conversion entirely and require that it be explicit. That being said, I don't expect that we'll ever see such a change in D2, much as I think that it would be worth it. - Jonathan M Davis
Sep 17 2020
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 17, 2020 at 02:23:43PM -0600, Jonathan M Davis via Digitalmars-d
wrote:
 On Thursday, September 17, 2020 2:07:35 PM MDT H. S. Teoh via Digitalmars-d 
 wrote:
 That bug has been filed for years, I wish somebody would take it up
 and push it in. :-/  That has been a bad idea for years and yet it
 still persists.

   https://issues.dlang.org/show_bug.cgi?id=15932
I've brought it up to Walter before. As I understand it, his opinion is that scope solves the problem.
No, it doesn't solve the problem. It fixes the *symptom*, but the underlying problem persists.
 And while I agree that it helps, I still think that it would be better
 to just disallow the implict conversion entirely and require that it
 be explicit. That being said, I don't expect that we'll ever see such
 a change in D2, much as I think that it would be worth it.
[...] Yeah, implicit is bad. I used to be a fan of implicit things, because of the convenience... but more and more, with more experience, I'm starting to be convinced that explicit is always better -- for readability and maintainability. Too many layers of implicit things, and the code becomes obscure, hard to read, or easy to *wrongly* read, and consequently fragile. T -- Just because you survived after you did it, doesn't mean it wasn't stupid!
Sep 17 2020
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 17 September 2020 at 21:03:08 UTC, H. S. Teoh wrote:

 Yeah, implicit is bad.  I used to be a fan of implicit things, 
 because of the convenience... but more and more, with more 
 experience, I'm starting to be convinced that explicit is 
 always better -- for readability and maintainability. Too many 
 layers of implicit things, and the code becomes obscure, hard 
 to read, or easy to *wrongly* read, and consequently fragile.


 T
By implicit I am assuming your talking about c++ here correct? I consider that language to implement implicit conversions poorly. Functions should opt-in implicit conversions, not opt-out. The main case for it is writing: T t = a; Instead of: T t = (t)a That the main benefit of implicit conversion that we should be focusing on.
Sep 18 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Sep 18, 2020 at 02:55:39PM +0000, 12345swordy via Digitalmars-d wrote:
 On Thursday, 17 September 2020 at 21:03:08 UTC, H. S. Teoh wrote:
 
 Yeah, implicit is bad.  I used to be a fan of implicit things,
 because of the convenience... but more and more, with more
 experience, I'm starting to be convinced that explicit is always
 better -- for readability and maintainability. Too many layers of
 implicit things, and the code becomes obscure, hard to read, or easy
 to *wrongly* read, and consequently fragile.
[...]
 By implicit I am assuming your talking about c++ here correct?
I'm speaking in general. It applies to any language, really. [...]
 The main case for it is writing:
 
 T t = a;
 
 Instead of:
 
 T t = (t)a
 
 That the main benefit of implicit conversion that we should be
 focusing on.
Just write: auto t = T(a); Mission accomplished, no need for implicit conversion, and it's clear exactly what's going on. In non-trivial cases, I know it's convenient not to have to write T(a) all the time, but really, it's better to write it out explicitly so that future readers of the code (i.e., you after 3 months :-D) know exactly what conversions are taking place and how. When there are too many implicit conversions, the code may look better superficially, but actually it may be hiding inefficient implicit conversions, or it may look like it's doing something but it's actually doing something else because of the implicit conversions. It's more inconvenient to write things out explicitly, but in the long run it's better. T -- Computers aren't intelligent; they only think they are.
Sep 18 2020
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 18 September 2020 at 15:22:58 UTC, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 02:55:39PM +0000, 12345swordy via 
 Digitalmars-d wrote:
 On Thursday, 17 September 2020 at 21:03:08 UTC, H. S. Teoh 
 wrote:
 
 Yeah, implicit is bad.  I used to be a fan of implicit 
 things, because of the convenience... but more and more, 
 with more experience, I'm starting to be convinced that 
 explicit is always better -- for readability and 
 maintainability. Too many layers of implicit things, and the 
 code becomes obscure, hard to read, or easy to *wrongly* 
 read, and consequently fragile.
[...]
 By implicit I am assuming your talking about c++ here correct?
I'm speaking in general. It applies to any language, really.
Not true, other languages implement implicit conversions in different ways. Seriously what languages are you referring here?
 [...]
 The main case for it is writing:
 
 T t = a;
 
 Instead of:
 
 T t = (t)a
 
 That the main benefit of implicit conversion that we should be 
 focusing on.
Just write: auto t = T(a); Mission accomplished, no need for implicit conversion, and it's clear exactly what's going on.
You are making assertions that you can write: auto t = T(a); That is not necessarily the case.
... future readers of the code know exactly what conversions are 
taking
 place and how.
We have a solution to that already it called comments.
  When there are too many implicit conversions,
What exactly do you mean by this? The implicit conversions that I have in mind is that implicit conversions happen once and only once per statement.
 the code may look better superficially, but actually it may be 
 hiding inefficient implicit conversions,
What do you mean by "Inefficient" here? That sounds like an implementation issue rather than a casting issue.
 or it may look like it's doing something but it's actually 
 doing something else because of the implicit conversions.
That why comments are there for.
Sep 18 2020
next sibling parent reply H. S. Teoh <hsteoh quickfur.ath.cx> writes:
On Friday, 18 September 2020 at 16:21:47 UTC, 12345swordy wrote:
 On Friday, 18 September 2020 at 15:22:58 UTC, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 02:55:39PM +0000, 12345swordy via
[...]
 By implicit I am assuming your talking about c++ here correct?
I'm speaking in general. It applies to any language, really.
Not true, other languages implement implicit conversions in different ways. Seriously what languages are you referring here?
[...] Any language. Implicit conversions have a tendency of reducing code maintainability or quality. Here's a small sampling of issues that may be encountered: 1) Scala: https://www.rallyhealth.com/coding/implicit-implications-part-2-implicit-conversions Quote: "In fact, Scala has deemed that implicit conversions are so dangerous, they require you to import scala.language.implicitConversions to use them" 2) C++: https://docs.microsoft.com/en-us/cpp/cpp/type-conversions-and-type-safety-modern-cpp?view=vs-2019 Quote: "However, even if your program compiles without warnings, it still may contain code that leads to implicit type conversions that produce incorrect results." 3) Javascript: https://blog.acolyer.org/2015/08/04/the-good-the-bad-and-the-ugly-an-empirical-study-of-implicit-type-conversions-in-javascript/ Quote: "A small but non-negligible percentage (1.15%) of all type coercions are potentially harmful. Future language designs or restricted versions of JavaScript may want to forbid them." 4) SQL: https://towardsdatascience.com/how-not-to-kill-your-sql-server-performance-with-implicit-conversion-e754ac2eb134?gi=86749251fcf1 Quote: "In order to resolve inconsistencies between data types, SQL Server must put additional effort and consume more resources. Thus, performance will suffer, leading to inefficient usage of indexes and extensive usage of CPU." https://netvignettes.wordpress.com/2011/04/24/implicit-conversion-operators-are-bad/ Quote: "... certain markers that indicate to me that the coder in question is inexperienced and needs more guidance. / One such marker is the use of implicit conversion operators on reference types." This is just a random sampling I got from Google. There are many more. It also corroborates my own experience working with C, C++, Java, and D. In spite of repeated complaints over the years, I have to say I'm glad that Walter stuck to his guns and refused to add implicit constructors to D. Nevertheless, D still has implicit conversions, some of which seemed like a good idea at the time, but eventually it leads to trouble, one prime example being alias this. (I still use alias this, mind you, but more and more I'm beginning to realize it's not such a good idea. It's convenient, for sure, but leads to hard-to-understand code. Not to mention it interacts poorly with generic code, because you can never be 100% sure exactly what type you're getting out of it.) --T
Sep 18 2020
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Friday, 18 September 2020 at 16:47:40 UTC, H. S. Teoh wrote:
 On Friday, 18 September 2020 at 16:21:47 UTC, 12345swordy wrote:
 On Friday, 18 September 2020 at 15:22:58 UTC, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 02:55:39PM +0000, 12345swordy via
[...]
 By implicit I am assuming your talking about c++ here 
 correct?
I'm speaking in general. It applies to any language, really.
Not true, other languages implement implicit conversions in different ways. Seriously what languages are you referring here?
[...] Any language. Implicit conversions have a tendency of reducing code maintainability or quality.
I noticed that you had ignore my other questions. Stop making weasel words by saying "Implicit conversions have a tendency of reducing code maintainability or quality." without specifying how!
 Here's a small sampling of issues that may be encountered:
You can make the same kind of statement regarding the goto feature.
 This is just a random sampling I got from Google.
https://www.logicallyfallacious.com/logicalfallacies/Biased-Sample-Fallacy (I still use alias this, mind
 you, but more and more I'm beginning to realize it's not such a 
 good idea. It's convenient, for sure, but leads to 
 hard-to-understand code. Not to mention it interacts poorly 
 with generic code, because you can never be 100% sure exactly 
 what type you're getting out of it.)


 --T
The issue with alias this is that it introduces the multiple inheritance promblem, not that introduces implicit conversion.
Sep 18 2020
prev sibling parent DlangUser38 <DlangUser38 nowhere.se> writes:
On Friday, 18 September 2020 at 16:21:47 UTC, 12345swordy wrote:
 On Friday, 18 September 2020 at 15:22:58 UTC, H. S. Teoh wrote:
 On Fri, Sep 18, 2020 at 02:55:39PM +0000, 12345swordy via 
 Digitalmars-d wrote:
  When there are too many implicit conversions,
What exactly do you mean by this? The implicit conversions that I have in mind is that implicit conversions happen once and only once per statement.
No. Generally speaking they happen (or at least are tried) once per binary expression (that includes assignments). In "a = b(c + d);" you have 3: 1. return type of `b(c+d)` to `a` type 2. `c` to `d` type (or the opposite) 3. `c + d` to the type of `c` first param. But those are essential. It's not a question of too much / efficiency. A backend cant do its job without them and a frontend that doesn't do them automatically means that the language is a joke.
Sep 18 2020
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2020-09-17 18:18, Andrei Alexandrescu wrote:

 Does this pass the laugh test? How can one explain a colleague "yep, 
 here are the conditions under which you can iterate over an object in 
 the D language".
Won't you have the same problem with `foreach`? It supports even more ways to iterate. -- /Jacob Carlborg
Sep 18 2020
prev sibling parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 17 September 2020 at 16:18:18 UTC, Andrei 
Alexandrescu wrote:
 The implementation of each in std.algorithm.iteration sets out 
 a lofty goal: whatever can be iterated, must be iterated with 
 each.

 Problem is, there are way too many things that can be iterated 
 in D and too many ways to iterate them. This leads to a 
 veritable gallop of checks:

  [...SNIP...]

 Too much!
Agree! There is a greater sense in which too much effort is placed on some end-user stuff within the base language. An example is the `std.csv` package, even Julia - a language specifically designed for scientific/technical/data science computing does not have a csv reader in its standard library (it has DelimitedFiles which does something different - single type file read), instead it has a separate CSV package. The D language allows you to parse a typical XSV file very easily, so instead of aiming specifically at CSV files, just have better curated and documented a general I/O library. I think a lot of people attracted to D are looking to fish, not to be given fish. If the D community has a smaller standard library footprint, hiving off certain things to DUB, it should free up resources for better curation and documentation.
Sep 20 2020
parent data pulverizer <data.pulverizer gmail.com> writes:
On Sunday, 20 September 2020 at 12:08:05 UTC, data pulverizer 
wrote:

 ...There is a greater sense in which too much effort is placed 
 on some end-user stuff within the base language ...
Correction, I meant within the standard library
Sep 20 2020