digitalmars.D - Am I evil for this?
- solidstate1991 (14/14) Oct 13 2022 So I watched this video:
- Araq (6/20) Oct 13 2022 Before C came along x << y already meant "x is much smaller than
- Mike Parker (9/13) Oct 13 2022 "nonstandard purposes" were the OP's words, not Walter's.
- H. S. Teoh (24/37) Oct 13 2022 Generally, I agree with Walter. Operator overloading should not be
- Walter Bright (18/23) Oct 13 2022 Here it is:
- Max H (8/33) Oct 14 2022 Potentially controversial response: Who cares? The alternative in
- Walter Bright (5/10) Oct 14 2022 With color syntax highlighting, nobody will think the quoted string is o...
- Max Samukha (3/7) Oct 13 2022 Indeed. Even * and + hardly have a standard meaning outside of
- H. S. Teoh (15/32) Oct 13 2022 I've also written set operators for one of my projects. I also
- Atila Neves (20/48) Oct 14 2022 On Thursday, 13 October 2022 at 20:28:52 UTC, solidstate1991
- Walter Bright (6/18) Oct 14 2022 True that documentation often (always?) lies about what the code actuall...
- jmh530 (18/24) Oct 14 2022 What is your opinion about R's custom infix binary operators?
- H. S. Teoh (19/35) Oct 14 2022 IMO, %*% is extremely ugly to read.
- jmh530 (4/11) Oct 15 2022 D's built-in slices already have * as element-wise
- Dennis (29/34) Oct 14 2022 You can actually do that in D with some hacks:
- jmh530 (2/20) Oct 15 2022 That's a new one to me. Very interesting.
- Walter Bright (3/11) Oct 14 2022 I've thought about it many times. It keeps coming back to "it's just too...
- rassoc (10/16) Oct 14 2022 Raku (formerly Perl 6) is very interesting in that regard. They not only...
- Walter Bright (4/7) Oct 14 2022 Doing that means the code cannot be successfully parsed without semantic...
- Timon Gehr (3/12) Oct 15 2022 You can parse it as a single "operator expression" and resolve
- Walter Bright (2/4) Oct 15 2022 The operator precedence drives the parse.
- Timon Gehr (2/7) Oct 15 2022 It does not _have_ to work that way.
- Walter Bright (4/12) Oct 15 2022 I know. The tokens can be "parsed" by just storing them in an array, def...
- Timon Gehr (10/25) Oct 16 2022 You can parse everything except operator precedence, no need to store a
- Walter Bright (6/8) Oct 26 2022 Well, an array of terms.
- solidstate1991 (15/31) Oct 16 2022 At least Σ is perfectly doable in D thanks to its unicode support
- Max H (15/34) Oct 14 2022 A slightly more useful way of thinking about this I think is to
- Walter Bright (3/4) Oct 14 2022 When I was working on that, I could not believe that other languages per...
- Paul Backus (4/10) Oct 14 2022 Perhaps ironically, one of the languages that got this right was
- H. S. Teoh (19/31) Oct 14 2022 In spite of all the hate (and actual flaws), I actually quite like many
- Walter Bright (4/17) Oct 15 2022 You can always use the D1 regexes, which are still around in the unDead ...
- H. S. Teoh (11/31) Oct 15 2022 I find syntax highlighting more distracting than helpful. Especially
- Walter Bright (2/3) Oct 16 2022 It requires someone taking the initiative to improve them.
- Walter Bright (4/10) Oct 16 2022 This is why it's configurable - some people like it, some don't. Persona...
- rassoc (3/4) Oct 15 2022 No takers yet, see: https://forum.dlang.org/post/thzswscbklnndbaeknvv@fo...
- Atila Neves (12/31) Oct 24 2022 It depends. I don't think this is unexpected:
- Paul Backus (8/19) Oct 24 2022 version (Windows) {
- Atila Neves (5/27) Oct 25 2022 Also valid.
- cc (10/22) Oct 14 2022 ```
- kdevel (8/9) Oct 14 2022 Require unicode and break another convention in one go is even
So I watched this video: https://youtu.be/G6b62HmsO6M And Walter talked about using operator overloading for nonstandard purposes. So in my collections library, I used it to implement set operators, but since set operators don't exist in the D standard (and require unicode, which would upset a lot of people, especially those who don't know what Win + '.' does), I had to use operators that have similar function in other spaces. I personally haven't used them yet in my projects (except for the unittests), so it's not too late to remove them, but I don't know if anyone else might be using them or not. Link to my library with an example offense: https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L356
Oct 13 2022
On Thursday, 13 October 2022 at 20:28:52 UTC, solidstate1991 wrote:So I watched this video: https://youtu.be/G6b62HmsO6M And Walter talked about using operator overloading for nonstandard purposes. So in my collections library, I used it to implement set operators, but since set operators don't exist in the D standard (and require unicode, which would upset a lot of people, especially those who don't know what Win + '.' does), I had to use operators that have similar function in other spaces. I personally haven't used them yet in my projects (except for the unittests), so it's not too late to remove them, but I don't know if anyone else might be using them or not. Link to my library with an example offense: https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L356Before C came along x << y already meant "x is much smaller than y" and x || y sometimes meant "run x and y in parallel". "Nonstandard purposes" hardly means anything. Use the operators as you see fit.
Oct 13 2022
On Thursday, 13 October 2022 at 21:01:08 UTC, Araq wrote:Before C came along x << y already meant "x is much smaller than y" and x || y sometimes meant "run x and y in parallel". "Nonstandard purposes" hardly means anything. Use the operators as you see fit."nonstandard purposes" were the OP's words, not Walter's. Walter's was talking about overloading for nonarithmetic purposes. This is not an uncommon criticism. He cited the C++ iostreams library as many who make this criticism do, and also a project he saw in the past that overloaded C++ operators to make a regex DSL. The specific discussion about operator overloading is here: https://youtu.be/G6b62HmsO6M?t=858
Oct 13 2022
On Fri, Oct 14, 2022 at 02:13:34AM +0000, Mike Parker via Digitalmars-d wrote:On Thursday, 13 October 2022 at 21:01:08 UTC, Araq wrote:Generally, I agree with Walter. Operator overloading should not be taken as a free license to bend arithmetic operators to do things alien to their basic arithmetic meaning. That's just a big code smell, and leads to hard-to-read code with poor maintainability.Before C came along x << y already meant "x is much smaller than y" and x || y sometimes meant "run x and y in parallel". "Nonstandard purposes" hardly means anything. Use the operators as you see fit."nonstandard purposes" were the OP's words, not Walter's. Walter's was talking about overloading for nonarithmetic purposes. This is not an uncommon criticism.He cited the C++ iostreams library as many who make this criticism do,Yeah, using << and >> for I/O is a total eyesore. The precedence doesn't make sense for I/O, if you don't parenthesize, the expression could mean something completely different from what you expect. IMO, this a total code smell, and a symptom of C++'s typical overly-clever-yet-still- incomplete style of addressing language design issues.and also a project he saw in the past that overloaded C++ operators to make a regex DSL.[...] That would be Boost.Xpressive, I think. Makes me cringe every time I look at it. In typical C++ hammer-a-nail-with-a-chainsaw fashion, compile-time regexes take operator overloading abuse to a whole new level and the result looks nothing like a regex, introducing a maintenance nightmare (the same regex gets written in two *completely* different ways depending on whether it's runtime or compile-time -- and good like trying to read the compile-time one). Now that constexpr is a thing, here's to hoping that this horrendous operator overload abuse will soon be relegated to the dustbin of history. T -- Caffeine underflow. Brain dumped.
Oct 13 2022
On 10/13/2022 7:44 PM, H. S. Teoh wrote:Here it is: #include <boost/spirit.hpp> using namespace boost; int main() { spirit::rule<> group, fact, term, expr; group = '(' >> expr >> ')'; fact = spirit::int_p | group; term = fact >> *(('*' >> fact) | ('/' >> fact)); expr = term >> *(('+' >> term) | ('-' >> term)); assert( spirit::parse("2*(3+4)", expr).full ); assert( ! spirit::parse("2*(3+4", expr).full ); } https://studylib.net/doc/10029968/text-processing-with-boost---northwest-c---users--group slide 40 It's a technical marvel, but the embedded DSL looks like C++ expressions yet does something completely different. One cannot distinguish the C++ code from the DSL code. It's in the same category as macros, and I can't recommend it.and also a project he saw in the past that overloaded C++ operators to make a regex DSL.[...] That would be Boost.Xpressive, I think.
Oct 13 2022
On Friday, 14 October 2022 at 06:59:43 UTC, Walter Bright wrote:On 10/13/2022 7:44 PM, H. S. Teoh wrote:Potentially controversial response: Who cares? The alternative in D is basically just the same code with some quotes around it (a DSL like pegged). You can do real sin with operating overloading, or just badly chosen operators, but this particular one really isn't that bad. The alternative is preprocessor macros, which are considerably worse.Here it is: #include <boost/spirit.hpp> using namespace boost; int main() { spirit::rule<> group, fact, term, expr; group = '(' >> expr >> ')'; fact = spirit::int_p | group; term = fact >> *(('*' >> fact) | ('/' >> fact)); expr = term >> *(('+' >> term) | ('-' >> term)); assert( spirit::parse("2*(3+4)", expr).full ); assert( ! spirit::parse("2*(3+4", expr).full ); } https://studylib.net/doc/10029968/text-processing-with-boost---northwest-c---users--group slide 40 It's a technical marvel, but the embedded DSL looks like C++ expressions yet does something completely different. One cannot distinguish the C++ code from the DSL code. It's in the same category as macros, and I can't recommend it.and also a project he saw in the past that overloaded C++ operators to make a regex DSL.[...] That would be Boost.Xpressive, I think.
Oct 14 2022
On 10/14/2022 1:49 PM, Max H wrote:Potentially controversial response: Who cares? The alternative in D is basically just the same code with some quotes around it (a DSL like pegged).With color syntax highlighting, nobody will think the quoted string is ordinary D code. It's also why the `mixin` keyword is a keyword - to make it stand out.You can do real sin with operating overloading, or just badly chosen operators, but this particular one really isn't that bad. The alternative is preprocessor macros, which are considerably worse.The best alternative to a proper DSL is to simply use functions instead of operators.
Oct 14 2022
On Thursday, 13 October 2022 at 21:01:08 UTC, Araq wrote:Before C came along x << y already meant "x is much smaller than y" and x || y sometimes meant "run x and y in parallel". "Nonstandard purposes" hardly means anything. Use the operators as you see fit.Indeed. Even * and + hardly have a standard meaning outside of elementary school arithmetic.
Oct 13 2022
On Thu, Oct 13, 2022 at 08:28:52PM +0000, solidstate1991 via Digitalmars-d wrote:So I watched this video: https://youtu.be/G6b62HmsO6M And Walter talked about using operator overloading for nonstandard purposes. So in my collections library, I used it to implement set operators, but since set operators don't exist in the D standard (and require unicode, which would upset a lot of people, especially those who don't know what Win + '.' does), I had to use operators that have similar function in other spaces.I've also written set operators for one of my projects. I also succumbed to the temptation of overloading bit operators (`|` for set union and `&` for set intersection), because of the obvious analogy to bit vectors. Originally I wanted to use `+` and `*`, but on second thoughts that's too remote from the usual meaning of + and *, and would make the resulting code too easy to misread, so I settled on | and & instead. At least the meaning corresponds, if you think of your set in terms of a glorified set of bits indicating the presence/absence of each element. `*` would be too easy to misunderstand as a Cartesian product in the context of sets.I personally haven't used them yet in my projects (except for the unittests), so it's not too late to remove them, but I don't know if anyone else might be using them or not. Link to my library with an example offense: https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L356My personal opinion -- keep | and &, get rid of + and *. T -- It is the quality rather than the quantity that matters. -- Lucius Annaeus Seneca
Oct 13 2022
On Thursday, 13 October 2022 at 20:28:52 UTC, solidstate1991 wrote:So I watched this video: https://youtu.be/G6b62HmsO6M And Walter talked about using operator overloading for nonstandard purposes. So in my collections library, I used it to implement set operators, but since set operators don't exist in the D standard (and require unicode, which would upset a lot of people, especially those who don't know what Win + '.' does), I had to use operators that have similar function in other spaces. I personally haven't used them yet in my projects (except for the unittests), so it's not too late to remove them, but I don't know if anyone else might be using them or not. Link to my library with an example offense: https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L356On Thursday, 13 October 2022 at 20:28:52 UTC, solidstate1991 wrote:So I watched this video: https://youtu.be/G6b62HmsO6M And Walter talked about using operator overloading for nonstandard purposes. So in my collections library, I used it to implement set operators, but since set operators don't exist in the D standard (and require unicode, which would upset a lot of people, especially those who don't know what Win + '.' does), I had to use operators that have similar function in other spaces. I personally haven't used them yet in my projects (except for the unittests), so it's not too late to remove them, but I don't know if anyone else might be using them or not. Link to my library with an example offense: https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L356AFAIC, operators are infix functions with funny names. I think Haskell got it this exactly right syntax-wise, but definitely not culture-wise given their abuse of operators. If you have to tell people that you "pronounce" `>>=` as "shove", well... As Bjarne said once in response to complaints that operator overloading lets people write code that doesn't do what you expect: ``` // notice how the code and the docs lie /** * Adds two numbers */ int sum(int i, int j) { return i - j; // oops } ```
Oct 14 2022
On 10/14/2022 12:54 AM, Atila Neves wrote:As Bjarne said once in response to complaints that operator overloading lets people write code that doesn't do what you expect: ``` // notice how the code and the docs lie /** * Adds two numbers */ int sum(int i, int j) { return i - j; // oops } ```True that documentation often (always?) lies about what the code actually does. But the causes of this are usually because of programmer laziness and/or error in documenting it correctly. But operating overloading for non-arithmetic purposes is *deliberately* doing the unexpected.
Oct 14 2022
On Friday, 14 October 2022 at 18:29:10 UTC, Walter Bright wrote:[snip] True that documentation often (always?) lies about what the code actually does. But the causes of this are usually because of programmer laziness and/or error in documenting it correctly. But operating overloading for non-arithmetic purposes is *deliberately* doing the unexpected.What is your opinion about R's custom infix binary operators? (ignoring that R is dynamically typed) So for instance, you can make a function ``` `%foo%` <- function(x, y) { #does something } ``` and use it like `x %foo% y` The surrounding `%` lets the user know that anything could be happening in there. However, it doesn't have to just be some string, it could be anything. For instance, R comes with %*% built-in for matrix multiplication and a few others. From D's perspective, it doesn't really make sense to use a string since we have UFCS and it is just as easy to use `x.foo(y)` [in R you would have to do foo(x, y) if this feature didn't exist]. However, it is useful when it is some symbol that would otherwise have a longer name. Code that is full of `X.matmul(Y)` is harder to read than `X %*% Y`.
Oct 14 2022
On Fri, Oct 14, 2022 at 08:24:47PM +0000, jmh530 via Digitalmars-d wrote: [...]So for instance, you can make a function ``` `%foo%` <- function(x, y) { #does something } ``` and use it like `x %foo% y` The surrounding `%` lets the user know that anything could be happening in there. However, it doesn't have to just be some string, it could be anything. For instance, R comes with %*% built-in for matrix multiplication and a few others.IMO, %*% is extremely ugly to read.From D's perspective, it doesn't really make sense to use a string since we have UFCS and it is just as easy to use `x.foo(y)` [in R you would have to do foo(x, y) if this feature didn't exist]. However, it is useful when it is some symbol that would otherwise have a longer name. Code that is full of `X.matmul(Y)` is harder to read than `X %*% Y`.It's just a matter of formatting; just write it like this: X .mul (Y) and it will read just fine. The mandatory parentheses are actually a good thing to prevent confusion with operator precedence. (Making operator precedence user-configurable may not be a good idea -- it forces you to do semantic analysis before the syntax can be parsed, and will add far more complexity to the parser than is justifiable by the marginal benefits.) For this specific example, though, I'd say just overload *. Matrix multiplication is called "multiplication" because it generally *does* behave like a multiplicative arithmetic operator. As opposed to like array manipulation or I/O. So I'd call it an appropriate use of operator overloading in this case. T -- One Word to write them all, One Access to find them, One Excel to count them all, And thus to Windows bind them. -- Mike Champion
Oct 14 2022
On Friday, 14 October 2022 at 21:15:12 UTC, H. S. Teoh wrote:[snip] For this specific example, though, I'd say just overload *. Matrix multiplication is called "multiplication" because it generally *does* behave like a multiplicative arithmetic operator. As opposed to like array manipulation or I/O. So I'd call it an appropriate use of operator overloading in this case. TD's built-in slices already have * as element-wise multiplication. It makes things a little more confusing to switch it up.
Oct 15 2022
On Friday, 14 October 2022 at 20:24:47 UTC, jmh530 wrote:So for instance, you can make a function ``` `%foo%` <- function(x, y) { #does something } ``` and use it like `x %foo% y`You can actually do that in D with some hacks: ```D struct Operator(alias fn, string operator = "/") { static auto opBinaryRight(string op : operator, T...)(T value1) { struct Result { auto opBinary(string op : operator, U...)(U value2) if (__traits(compiles, fn(value1, value2))) { return fn(value1, value2); } } Result result; return result; } } void main() { import std.algorithm.comparison; alias min = Operator!(std.algorithm.comparison.min, "%"); assert(1 %min% 3 == 1); } ``` Credit to Simen Kjærås: https://forum.dlang.org/post/ldiwiffdyzeswggytudh forum.dlang.org
Oct 14 2022
On Friday, 14 October 2022 at 21:49:31 UTC, Dennis wrote:On Friday, 14 October 2022 at 20:24:47 UTC, jmh530 wrote:That's a new one to me. Very interesting.[...]You can actually do that in D with some hacks: ```D struct Operator(alias fn, string operator = "/") { static auto opBinaryRight(string op : operator, T...)(T value1) { struct Result { auto opBinary(string op : operator, U...)(U value2) if (__traits(compiles, fn(value1, value2))) { return fn(value1, value2); } } [...]
Oct 15 2022
On 10/14/2022 1:24 PM, jmh530 wrote:What is your opinion about R's custom infix binary operators? (ignoring that R is dynamically typed) So for instance, you can make a function ``` `%foo%` <- function(x, y) { #does something } ``` and use it like `x %foo% y`I've thought about it many times. It keeps coming back to "it's just too ugly." Operator precedence is also a problem.
Oct 14 2022
On 10/15/22 00:44, Walter Bright via Digitalmars-d wrote:I've thought about it many times. It keeps coming back to "it's just too ugly." Operator precedence is also a problem.Raku (formerly Perl 6) is very interesting in that regard. They not only allow you to define custom operators, but also specify their precedence and associativity right in the function signature. sub prefix:<Σ>(...) sub infix:<!!>(...) is tighter(&infix:<+>) sub infix:<§>(...) is assoc<right> sub circumfix:<[ ]>(...) And they go even further and allow you to combine these to form meta operators.my a = 1, 2, 3((1 1) (2 2) (3 3))a Z+ aIf only the language wasn't dog slow. :)
Oct 14 2022
On 10/14/2022 6:11 PM, rassoc wrote:Raku (formerly Perl 6) is very interesting in that regard. They not only allow you to define custom operators, but also specify their precedence and associativity right in the function signature.Doing that means the code cannot be successfully parsed without semantic analysis. One goal of D was to be able to keep the lexing, parsing, and semantic analysis as distinct passes.
Oct 14 2022
On 15.10.22 08:59, Walter Bright wrote:On 10/14/2022 6:11 PM, rassoc wrote:You can parse it as a single "operator expression" and resolve precedence during semantic analysis.Raku (formerly Perl 6) is very interesting in that regard. They not only allow you to define custom operators, but also specify their precedence and associativity right in the function signature.Doing that means the code cannot be successfully parsed without semantic analysis. One goal of D was to be able to keep the lexing, parsing, and semantic analysis as distinct passes.
Oct 15 2022
On 10/15/2022 5:41 AM, Timon Gehr wrote:You can parse it as a single "operator expression" and resolve precedence during semantic analysis.The operator precedence drives the parse.
Oct 15 2022
On 15.10.22 18:45, Walter Bright wrote:On 10/15/2022 5:41 AM, Timon Gehr wrote:It does not _have_ to work that way.You can parse it as a single "operator expression" and resolve precedence during semantic analysis.The operator precedence drives the parse.
Oct 15 2022
On 10/15/2022 10:42 AM, Timon Gehr wrote:On 15.10.22 18:45, Walter Bright wrote:I know. The tokens can be "parsed" by just storing them in an array, deferring constructing the AST until the semantics are known. But that isn't really parsing, and makes 3rd party tools much more complex.On 10/15/2022 5:41 AM, Timon Gehr wrote:It does not _have_ to work that way.You can parse it as a single "operator expression" and resolve precedence during semantic analysis.The operator precedence drives the parse.
Oct 15 2022
On 10/15/22 20:22, Walter Bright wrote:On 10/15/2022 10:42 AM, Timon Gehr wrote:You can parse everything except operator precedence, no need to store a token stream. In general, aspects of the AST that depend on semantic information should be resolved during semantic analysis, and if that is the case for operator precedence that's how you parse it. There's no need to have any feedback from semantic to the parser.On 15.10.22 18:45, Walter Bright wrote:I know. The tokens can be "parsed" by just storing them in an array, deferring constructing the AST until the semantics are known. But that isn't really parsing,On 10/15/2022 5:41 AM, Timon Gehr wrote:It does not _have_ to work that way.You can parse it as a single "operator expression" and resolve precedence during semantic analysis.The operator precedence drives the parse.and makes 3rd party tools much more complex.Depends a bit on the tool. I guess it is true for a tool whose only purpose is to parenthesize expressions according to operator precedence. :) It's not adding much complexity to tools that already need to run full semantic.
Oct 16 2022
On 10/16/2022 12:53 PM, Timon Gehr wrote:You can parse everything except operator precedence, no need to store a token stream.Well, an array of terms. Given a*b*c, is that (a*b)*c or a*(b*c)? You'd have to wait for semantics to not only know precedence, but left and right associativity. I can see how that's possible, but don't like it.
Oct 26 2022
On Saturday, 15 October 2022 at 01:11:02 UTC, rassoc wrote:Raku (formerly Perl 6) is very interesting in that regard. They not only allow you to define custom operators, but also specify their precedence and associativity right in the function signature. sub prefix:<Σ>(...) sub infix:<!!>(...) is tighter(&infix:<+>) sub infix:<§>(...) is assoc<right> sub circumfix:<[ ]>(...) And they go even further and allow you to combine these to form meta operators.At least Σ is perfectly doable in D thanks to its unicode support (if I remember correctly) ```d public double Σ(...) { //code goes here } ``` Languages with custom operators will compile slow and will run even slower if they're scripting languages. My alternative for D would be just expand upon the currently existing number of operators with unicode characters, but also give them some alternative way to access them (e.g. having both an `⋃` operator and an `__opUnion` substitute), so people won't get a heart attack if they don't know how to get them on their keyboards.my a = 1, 2, 3((1 1) (2 2) (3 3))a Z+ aIf only the language wasn't dog slow. :)
Oct 16 2022
On Friday, 14 October 2022 at 18:29:10 UTC, Walter Bright wrote:On 10/14/2022 12:54 AM, Atila Neves wrote:A slightly more useful way of thinking about this I think is to think about it algebraically, i.e. If the nu-operation is confusing algebraically then it is *definitely* wrong versus merely not to taste. You can do useful algebra on things that wouldn't typically be considered arithmetic, that algebra often has an analogue in familiar arithmetic on numbers (we'll gloss over floating point arithmetic...) In the case of `sum`, we'd expect it to be associative - it's not, something has gone wrong. This is a more precise way of expressing that "Go home, you're drunk" feeling from this kind of code. D not using + for strings was something that helped sell me on it early on. Intuitively we all know concatenation isn't commutative anyway, but it doesn't hurt to express it lexically.As Bjarne said once in response to complaints that operator overloading lets people write code that doesn't do what you expect: ``` // notice how the code and the docs lie /** * Adds two numbers */ int sum(int i, int j) { return i - j; // oops } ```True that documentation often (always?) lies about what the code actually does. But the causes of this are usually because of programmer laziness and/or error in documenting it correctly. But operating overloading for non-arithmetic purposes is *deliberately* doing the unexpected.
Oct 14 2022
On 10/14/2022 2:07 PM, Max H wrote:D not using + for strings was something that helped sell me on it early on.When I was working on that, I could not believe that other languages persisted in conflating add with concatenate, which continues to cause confusion.
Oct 14 2022
On Friday, 14 October 2022 at 22:48:51 UTC, Walter Bright wrote:On 10/14/2022 2:07 PM, Max H wrote:Perhaps ironically, one of the languages that got this right was Perl: it used + for numeric addition and . (period) for string concatenation.D not using + for strings was something that helped sell me on it early on.When I was working on that, I could not believe that other languages persisted in conflating add with concatenate, which continues to cause confusion.
Oct 14 2022
On Sat, Oct 15, 2022 at 12:26:17AM +0000, Paul Backus via Digitalmars-d wrote:On Friday, 14 October 2022 at 22:48:51 UTC, Walter Bright wrote:In spite of all the hate (and actual flaws), I actually quite like many aspects of Perl. Built-in AA's is one, which is also a draw for me in D, in spite of the flaws in the current implementation in D. As is built-in regexes. D has std.regex, but not having direct language support does increase the friction a little. And the current implementation is a bit over-heavy on templates and so slows down compilation significantly for shell-script replacements, which detracts from an otherwise perfect niche for D. Sigils is another feature that most people love to hate, but it's actually very useful: the variable namespace will never collide with keywords, and when glancing at code you can immediately tell which identifiers are variables are even if you don't know the definitions of the identifiers. Having said that, though, the quirky use of $ with arrays/hashes when referring to individual elements does detract from Perl's implementation of sigils. T -- The trouble with TCP jokes is that it's like hearing the same joke over and over.On 10/14/2022 2:07 PM, Max H wrote:Perhaps ironically, one of the languages that got this right was Perl: it used + for numeric addition and . (period) for string concatenation.D not using + for strings was something that helped sell me on it early on.When I was working on that, I could not believe that other languages persisted in conflating add with concatenate, which continues to cause confusion.
Oct 14 2022
On 10/14/2022 5:58 PM, H. S. Teoh wrote:Built-in AA's is one, which is also a draw for me in D, in spite of the flaws in the current implementation in D. As is built-in regexes. D has std.regex, but not having direct language support does increase the friction a little. And the current implementation is a bit over-heavy on templates and so slows down compilation significantly for shell-script replacements, which detracts from an otherwise perfect niche for D.You can always use the D1 regexes, which are still around in the unDead library. They don't use templates.Sigils is another feature that most people love to hate, but it's actually very useful: the variable namespace will never collide with keywords, and when glancing at code you can immediately tell which identifiers are variables are even if you don't know the definitions of the identifiers. Having said that, though, the quirky use of $ with arrays/hashes when referring to individual elements does detract from Perl's implementation of sigils.Syntax highlighting works delightfully in distinguishing keywords from identifiers.
Oct 15 2022
On Sat, Oct 15, 2022 at 12:01:54AM -0700, Walter Bright via Digitalmars-d wrote:On 10/14/2022 5:58 PM, H. S. Teoh wrote:But why aren't we improving Phobos regexes then?Built-in AA's is one, which is also a draw for me in D, in spite of the flaws in the current implementation in D. As is built-in regexes. D has std.regex, but not having direct language support does increase the friction a little. And the current implementation is a bit over-heavy on templates and so slows down compilation significantly for shell-script replacements, which detracts from an otherwise perfect niche for D.You can always use the D1 regexes, which are still around in the unDead library. They don't use templates.I find syntax highlighting more distracting than helpful. Especially when they make unfounded assumptions about the background color of my terminal, such that some items end up being unreadable or barely readable. (I know, it's configurable, etc., etc., but then I'm spending time struggling with a problem that didn't need to be there in the first place, rather than focusing on my programming problem.) T -- Life is unfair. Ask too much from it, and it may decide you don't deserve what you have now either.Sigils is another feature that most people love to hate, but it's actually very useful: the variable namespace will never collide with keywords, and when glancing at code you can immediately tell which identifiers are variables are even if you don't know the definitions of the identifiers. Having said that, though, the quirky use of $ with arrays/hashes when referring to individual elements does detract from Perl's implementation of sigils.Syntax highlighting works delightfully in distinguishing keywords from identifiers.
Oct 15 2022
On 10/15/2022 5:56 PM, H. S. Teoh wrote:But why aren't we improving Phobos regexes then?It requires someone taking the initiative to improve them.
Oct 16 2022
On 10/15/2022 5:56 PM, H. S. Teoh wrote:I find syntax highlighting more distracting than helpful. Especially when they make unfounded assumptions about the background color of my terminal, such that some items end up being unreadable or barely readable. (I know, it's configurable, etc., etc., but then I'm spending time struggling with a problem that didn't need to be there in the first place, rather than focusing on my programming problem.)This is why it's configurable - some people like it, some don't. Personally, I prefer to use subtle colors for it. The default is what most people seem to like.
Oct 16 2022
On 10/16/22 02:56, H. S. Teoh via Digitalmars-d wrote:But why aren't we improving Phobos regexes then?No takers yet, see: https://forum.dlang.org/post/thzswscbklnndbaeknvv forum.dlang.org I tried fixing a regex backtracking bug I encountered a while ago, but felt quite a bit lost in that code base. One of these days. :)
Oct 15 2022
On Friday, 14 October 2022 at 18:29:10 UTC, Walter Bright wrote:On 10/14/2022 12:54 AM, Atila Neves wrote:It depends. I don't think this is unexpected: struct Path { string value; Path opBinary(string op)(in string path) if(op == "/") { import std.path : buildPath; return Path(buildPath(value, path)); } } void main() { assert(Path("/foo") / "bar" == Path("/foo/bar")); }As Bjarne said once in response to complaints that operator overloading lets people write code that doesn't do what you expect: ``` // notice how the code and the docs lie /** * Adds two numbers */ int sum(int i, int j) { return i - j; // oops } ```True that documentation often (always?) lies about what the code actually does. But the causes of this are usually because of programmer laziness and/or error in documenting it correctly. But operating overloading for non-arithmetic purposes is *deliberately* doing the unexpected.
Oct 24 2022
On Monday, 24 October 2022 at 11:25:58 UTC, Atila Neves wrote:It depends. I don't think this is unexpected: struct Path { string value; Path opBinary(string op)(in string path) if(op == "/") { import std.path : buildPath; return Path(buildPath(value, path)); } } void main() { assert(Path("/foo") / "bar" == Path("/foo/bar")); }version (Windows) { assert(Path("C:\Users") / "Paul" == Path("C:\Users\Paul")); } Better to just use ~ for concatenation and not try to be cute here, IMO. (Also, if the inverse of division is multiplication, does that mean Path("/foo/bar") * "bar" == Path("/foo")?)
Oct 24 2022
On Monday, 24 October 2022 at 14:16:57 UTC, Paul Backus wrote:On Monday, 24 October 2022 at 11:25:58 UTC, Atila Neves wrote:Yes? That's what I'd expect the result to be.It depends. I don't think this is unexpected: struct Path { string value; Path opBinary(string op)(in string path) if(op == "/") { import std.path : buildPath; return Path(buildPath(value, path)); } } void main() { assert(Path("/foo") / "bar" == Path("/foo/bar")); }version (Windows) { assert(Path("C:\Users") / "Paul" == Path("C:\Users\Paul")); }Better to just use ~ for concatenation and not try to be cute here, IMO.Also valid.(Also, if the inverse of division is multiplication, does that mean Path("/foo/bar") * "bar" == Path("/foo")?)That'd be... horrible. The "it depends" I wrote would definitely be in favour of killing this with fire during code review.
Oct 25 2022
On Friday, 14 October 2022 at 07:54:40 UTC, Atila Neves wrote:As Bjarne said once in response to complaints that operator overloading lets people write code that doesn't do what you expect: ``` // notice how the code and the docs lie /** * Adds two numbers */ int sum(int i, int j) { return i - j; // oops } `````` struct APerfectlyHarmlessDefaultZeroInitializedStruct { int i; long l; string s; Object o; float f; // oops! } ```
Oct 14 2022
On Thursday, 13 October 2022 at 20:28:52 UTC, solidstate1991 wrote:require unicode, which would upset a lot of peopleRequire unicode and break another convention in one go is even more effective: - https://forum.dlang.org/thread/pwotyniksrskdzmeafin forum.dlang.org "1 - 17 ms, 553 ╬╝s, and 1 hnsec" May 16, 2019
Oct 14 2022