Re: Rant after trying Rust a bit
On Wednesday, 13 July 2016 at 21:33:39 UTC, Ola Fosheim Grøstad wrote: Then if you want to represent a set of alternate sets like a Typo: a set of alternative strings.
Re: Rant after trying Rust a bit
On Monday, 11 July 2016 at 17:02:50 UTC, Max Samukha wrote: BTW, it happens that '+' does not always have to be commutative: https://en.wikipedia.org/wiki/Near-ring https://en.wikipedia.org/wiki/Ordinal_arithmetic#Addition Yes, although concatenations ought to be «*»... and the empty string «""» the identity (1). e.g. a free monoid: "abc" * "d" == "abcd" "abc"*"" == "abc" "abc"*""*"" == "abc" Then if you want to represent a set of alternate sets like a regexp «ab|cd» you could replace the alternative operator «|» with «+» and let the empty set «{}» be zero (0). Thus get a semiring: ( {"a"} + {"b"} ) + {"c"} == {"a"} + ( {"b"} + {"c"} ) == {"a" + "b" + "c"} {} + {"a"} == {"a"} + {} == {"a"} {"a"} + {"b"} == {"b"} + {"a"} == {"a" + "b"} ( {"a"} * {"b"} ) * {"c"} == {"a"} * ( {"b"} * {"c"} ) == {"abc"} {"a"} * ({"b"} + {"c"}) == ({"a"} * {"b"}) + ({"a"} * {"c"}) == { "ab" + "ac" } ({"a"} + {"b"}) * {"c"} == ({"a"} * {"c"}) + ({"b"} * {"c"}) == {"ab + "bc" } {""} * {"a"} == {"a"} * {""} == {"a"} {} * {"a"} == {"a"} * {} == {} Sortof...
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 06:54:45 UTC, Walter Bright wrote: On 8/3/2015 2:19 AM, Max Samukha wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. Sure it is. What if you've got: T add(T)(T a, T b) { return a + b; } and some idiot overloaded + for T to be something other than addition? That is a general problem with structural typing. Why not assume that if a type defines 'length', it must be a range? Then call an idiot everyone who defines it otherwise. I admit that special treatment of '+' is justified by its long history, but 'idiot thing' is obviously out of place. BTW, it happens that '+' does not always have to be commutative: https://en.wikipedia.org/wiki/Near-ring https://en.wikipedia.org/wiki/Ordinal_arithmetic#Addition
Re: Rant after trying Rust a bit
On 26/07/2015 23:58, deadalnix wrote: On Sunday, 26 July 2015 at 18:13:30 UTC, Tobias Müller wrote: Alix Pextonwrote: On 25/07/2015 9:48 PM, Walter Bright wrote: Unfortunately, Bruce Eckel's seminal article on it http://www.mindview.net/Etc/Discussions/CheckedExceptions has disappeared. Eckel is not a Java code monkey, he wrote the book Thinking In Java http://www.amazon.com/gp/product/0131002872/ https://web.archive.org/web/20150515072240/http://www.mindview.net/Etc/Discussions/CheckedExceptions This is article not convincing at all. His argument is basically "Most programmers are sloppy and tend to catch and ignore checked exceptions." No it is that checked Exception encourage this behavior. Ultimately, checked exception are a failure as they completely break encapsulation. Let's say you have a logger interface. Some of its implementation will just send the log to Dave Null, some write it in a file, some will send it over the network to some tailor, and so on. The class of error that arise from each is completely different and cannot be listed exhaustively at the interface level in any meaningful way. Then define the logger interface as throwing a generic Exception class. (a class that sits at the top of the hierarchy of the other Exceptions) -- Bruno Medeiros https://twitter.com/brunodomedeiros
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 06:54:45 UTC, Walter Bright wrote: On 8/3/2015 2:19 AM, Max Samukha wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. Sure it is. What if you've got: T add(T)(T a, T b) { return a + b; } and some idiot overloaded + for T to be something other than addition? Having add(a, b) return ab is not that weird. But consider this: http://pastebin.com/R3csc5Pa I can't put it in dpaste because it doesn't allow threading, but here is an example output: 45 45 45 45 45 45 45 45 45 45 MyString(0361572489) MyString(0379158246) MyString(0369158247) MyString(0582361479) MyString(0482579136) MyString(0369147258) MyString(0371482569) MyString(0469137258) MyString(0369147258) MyString(0561472389)
Re: Rant after trying Rust a bit
On 8/3/2015 2:19 AM, Max Samukha wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. Sure it is. What if you've got: T add(T)(T a, T b) { return a + b; } and some idiot overloaded + for T to be something other than addition?
Re: Rant after trying Rust a bit
On 8/2/2015 8:17 PM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: It's a weird thing to do for a C-decendant as I would expect ~= to do binary negation. If you really felt this way, you'd expect the C != operator a != b to be the same as: a = !b
Re: Rant after trying Rust a bit
On 08/06/2015 07:13 PM, jmh530 wrote: On Thursday, 6 August 2015 at 14:14:30 UTC, Jonathan M Davis wrote: In general, I would have expected it to be a total disaster if a language used any non-ASCII characters in its syntax. I still think it would be...not everyone uses the same editor. I had to look up how to do it in Notepad++. It requires knowing the Unicode key. Not exactly user-friendly. Not a Windows user, but I bet it wouldn't take long to find a better solution. I wouldn't have an issue if the editor had a layout like Lyx. Configuration is an O(1) operation. The constant becomes smaller after the first three users of the hypothetical language have set up their environment.
Re: Rant after trying Rust a bit
On 08/06/2015 07:50 AM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: On Wednesday, 5 August 2015 at 19:56:37 UTC, Timon Gehr wrote: On 08/05/2015 07:32 PM, deadalnix wrote: Mathematical language is geared toward generality and correctness, not practicality. That makes sens in the context of math, that do not in the context of every day programming. I don't see what you are trying to get at here, but I guess it is almost entirely unrelated to choosing a notation for string concatenation. Well, I don't think practicality is the main issue, but the mnemonic aspect of syntax is important. It is not unreasonable to make the identity of operators/functions consist of both name and parameter types like in C++ and D. So you don't have + as the operator name, you have +(int,int) and +(string,string). ... Certainly, but overloading is not always a good idea. It has been argued that functional languages would benefit from teaching functional programming in a less mathematical manner (e.g. talk about callbacks rather than monads etc): https://youtu.be/oYk8CKH7OhE That's not less mathematical. It is less abstract, maybe. Also, I think he is optimizing for people who pick up the language on their own. (i.e. it is not really about teaching in any traditional sense.)
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 11:33:29 UTC, Ola Fosheim Grøstad wrote: DOA. http://www.acronymfinder.com/DOA.html (Degenerate Overclockers Anonymous?)
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 12:33:33 UTC, Kagamin wrote: On Thursday, 6 August 2015 at 11:33:29 UTC, Ola Fosheim Grøstad wrote: DOA. http://www.acronymfinder.com/DOA.html (Degenerate Overclockers Anonymous?) http://www.urbandictionary.com/define.php?term=DOA Without this great site it would often be hard to understand what people from USA are talking about.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 06:50:38 UTC, Walter Bright wrote: On 8/2/2015 8:17 PM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: It's a weird thing to do for a C-decendant as I would expect ~= to do binary negation. If you really felt this way, you'd expect the C != operator a != b to be the same as: a = !b I don't because != is frequently used and usually in a context where expectations points towards comparison and not assignment. But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 12:33:33 UTC, Kagamin wrote: On Thursday, 6 August 2015 at 11:33:29 UTC, Ola Fosheim Grøstad wrote: DOA. http://www.acronymfinder.com/DOA.html (Degenerate Overclockers Anonymous?) Dead on arrival.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 11:30:45 UTC, Idan Arye wrote: On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: On Thursday, 6 August 2015 at 06:50:38 UTC, Walter Bright wrote: On 8/2/2015 8:17 PM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: [...] ~= to do binary [...] If you really felt this way, you'd expect the C != operator a != b to be the same as: a = !b I don't because != is frequently used and usually in a context where expectations points towards comparison and not assignment. But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. I understand your attempt to auction your old APL keyboard didn't go well? Compose keys have existed for a long time. The aversion to unicode is ridiculous.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: On Thursday, 6 August 2015 at 06:50:38 UTC, Walter Bright wrote: On 8/2/2015 8:17 PM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: It's a weird thing to do for a C-decendant as I would expect ~= to do binary negation. If you really felt this way, you'd expect the C != operator a != b to be the same as: a = !b I don't because != is frequently used and usually in a context where expectations points towards comparison and not assignment. But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. I understand your attempt to auction your old APL keyboard didn't go well?
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 11:30:45 UTC, Idan Arye wrote: I understand your attempt to auction your old APL keyboard didn't go well? There is no good reason to avoid unicode operators these days. A language without a dedicated editor-mode is pretty much DOA.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 09:15:25 UTC, Idan Arye wrote: Having add(a, b) return ab is not that weird. But consider this: http://pastebin.com/R3csc5Pa I can't put it in dpaste because it doesn't allow threading, but here is an example output: This would just be an argument for having static typing through and through, or Rust traits… If you wan't to address usability you have to look at what kind of problems people run into, not what they could construct if they tried really hard to create problems.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 14:14:30 UTC, Jonathan M Davis wrote: In general, I would have expected it to be a total disaster if a language used any non-ASCII characters in its syntax. I still think it would be...not everyone uses the same editor. I had to look up how to do it in Notepad++. It requires knowing the Unicode key. Not exactly user-friendly. I wouldn't have an issue if the editor had a layout like Lyx.
Re: Rant after trying Rust a bit
On 08/06/2015 01:30 PM, Idan Arye wrote: On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: On Thursday, 6 August 2015 at 06:50:38 UTC, Walter Bright wrote: On 8/2/2015 8:17 PM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: It's a weird thing to do for a C-decendant as I would expect ~= to do binary negation. If you really felt this way, you'd expect the C != operator a != b to be the same as: a = !b I don't because != is frequently used and usually in a context where expectations points towards comparison and not assignment. But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. I understand your attempt to auction your old APL keyboard didn't go well? I can actually type ≠ and ≤ more quickly than != or = in my editor.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. :=, or ≔
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 13:27:34 UTC, Timon Gehr wrote: I can actually type ≠ and ≤ more quickly than != or = in my editor. Wow. The only way that I'd know how to get those characters would be to copy-paste them from somewhere. I'm sure that there's a far easier way to generate them, but if a symbol isn't actually on my keyboard, I wouldn't have a clue how to type it, and I would have thought that support for typing it would be editor-specific. In general, I would have expected it to be a total disaster if a language used any non-ASCII characters in its syntax. - Jonathan M Davis
Re: Rant after trying Rust a bit
On 08/06/2015 04:14 PM, rsw0x wrote: On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. :=, or ≔ ← or ⇐ are also fine choices.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 12:56:05 UTC, rsw0x wrote: On Thursday, 6 August 2015 at 11:30:45 UTC, Idan Arye wrote: On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: On Thursday, 6 August 2015 at 06:50:38 UTC, Walter Bright wrote: On 8/2/2015 8:17 PM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: [...] ~= to do binary [...] If you really felt this way, you'd expect the C != operator a != b to be the same as: a = !b I don't because != is frequently used and usually in a context where expectations points towards comparison and not assignment. But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. I understand your attempt to auction your old APL keyboard didn't go well? Compose keys have existed for a long time. The aversion to unicode is ridiculous. That's because everything in IT is Anglo-centric (mainly US). To this day we suffer from the fact that nobody in the English speaking world bothered to cater for special characters[1], when computers and programming languages emerged as ever more important. [1] the term special character tells a lot about the attitude. For French or Portuguese speakers ç is not a special character nor is ñ for Spanish speakers (not to mention other writing systems!).
Re: Rant after trying Rust a bit
On Thu, 2015-08-06 at 14:14 +, Jonathan M Davis via Digitalmars-d wrote: On Thursday, 6 August 2015 at 13:27:34 UTC, Timon Gehr wrote: I can actually type ≠ and ≤ more quickly than != or = in my editor. Wow. The only way that I'd know how to get those characters would be to copy-paste them from somewhere. I'm sure that there's a far easier way to generate them, but if a symbol isn't actually on my keyboard, I wouldn't have a clue how to type it, and I would have thought that support for typing it would be editor-specific. In general, I would have expected it to be a total disaster if a language used any non-ASCII characters in its syntax. - Jonathan M Davis As rsw0x said previously, compose keys and construction of non-ASCII Unicode codepoints have been around for decades. The fixation on only ASCII characters is a hang-over from the 1970s I'm afraid and now it is 2015 – supposedly. A neat alternative to the compose key – well actually a strong accompaniment really – is to allow for multiple keyboard bindings. In particular I have Greek set up so I can switch from en (en_UK obviously since that is the only real form of en) to gr very quickly and then I am typing Greek characters on my UK keyboard. Damn useful for all this LaTeX maths (*) and general calculating approximations to π type stuff. More programming languages should get with the Unicode programme. Obviously not to allow the silly emoticon programs that did the rounds on Swift's release, but exactly to allow for ≠ « » ≤ ≥ ¨ etc., etc., etc. All the sensible stuff that would make reading programs easier. (*) NB not math, that is an un-English diminutive :-) -- 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: Rant after trying Rust a bit
On Thu, 2015-08-06 at 16:20 +0200, Timon Gehr via Digitalmars-d wrote: On 08/06/2015 04:14 PM, rsw0x wrote: On Thursday, 6 August 2015 at 11:26:10 UTC, Ola Fosheim Grøstad wrote: But I would prefer =, ≠, and ≤ for comparison and constants... then have something else for variable assignment. :=, or ≔ ← or ⇐ are also fine choices. And indeed ones taken in Scala, - can be ←, which looks so much nicer to read. -- 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: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 14:14:30 UTC, Jonathan M Davis wrote: Wow. The only way that I'd know how to get those characters would be to copy-paste them from somewhere. I'm sure that there's a far easier way to generate them, but if a symbol isn't actually on my keyboard, I wouldn't have a clue how to type it, and I would have thought that support for typing it would be editor-specific. In general, I would have expected it to be a total disaster if a language used any non-ASCII characters in its syntax. I think it is a big advantage if the default editor and syntax is developed in tandem, it can enable less cluttered syntax and a better editing experience. Some syntaxes can improve a lot by having sensible colouring/visual layout. On many non-US keyboards the C-language syntax-characters are put in annoying positions too. To get braces {} I have to type: alt-shift-8 alt-shift-9. To get = I have to type: shift-0 To get ≤ I type: alt-
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 15:09:01 UTC, Russel Winder wrote: More programming languages should get with the Unicode programme. Obviously not to allow the silly emoticon programs that did the rounds on Swift's release, but exactly to allow for ≠ « » ≤ ≥ ¨ etc., etc., etc. All the sensible stuff that would make reading programs easier. A unicode DIP would be nice to see. Haskell offers Unicode support and is completely compatible with ASCII. Would probably be simple to create a tool to quickly shift between the two. It definitely does look much better.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 15:11:59 UTC, Russel Winder wrote: On Thu, 2015-08-06 at 16:20 +0200, Timon Gehr via Digitalmars-d wrote: ← or ⇐ are also fine choices. And indeed ones taken in Scala, - can be ←, which looks so much nicer to read. Yes, probably doesn't matter too much which way the arrow points, you can make up mnemonics for both. I.e. are you transferring a reference/value to the symbol or is the symbol pointing at/pinpointing an object/value. I guess the first one is the more common mnemonic, although for references maybe the latter is more in line with how you draw diagrams (the arrow pointing to the instance). IIRC, in Beta you had this pipeline like assignment/function call notation (s,t,v) = func1 = func2 = ((x,y,z), (a,b,c)) Which would be similar to the more conventional ((x,y,z), (a,b,c)) := func2(func1(s,t,v)) With arrows you can allow both directions. The conventional right to left is easier to read for short expressions. But the pipelining left to right is easier to read for longer expressions that go through multiple stages. I think Rust also allows you to bind elements to a tuple using both let and mut in the same tuple expression, so that you can declare and bind both to variables and constants in a single expression. If you have serveral visually distinct array types you probably could get a coherent and easy to remember syntax for function calls, value assignment, reference assignment, array assignment, ranges/dataflow pipelining etc.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 15:31:25 UTC, Kagamin wrote: On Thursday, 6 August 2015 at 15:09:01 UTC, Russel Winder wrote: Damn useful for all this LaTeX maths (*) and general calculating approximations to π type stuff. \pi ? https://en.wikibooks.org/wiki/LaTeX/Mathematics#Greek_letters Using a compose key or alternate layout is much, *much* faster than the LaTeX notation.
Re: Rant after trying Rust a bit
On Thursday, 6 August 2015 at 15:09:01 UTC, Russel Winder wrote: Damn useful for all this LaTeX maths (*) and general calculating approximations to π type stuff. \pi ? https://en.wikibooks.org/wiki/LaTeX/Mathematics#Greek_letters
Re: Rant after trying Rust a bit
On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote: ... One thing I didn't see mentioned at all is Rust's plugin system. Rust plugin to embed C++ directly in Rust: https://github.com/mystor/rust-cpp Rust plugin to use Rust with whitespace instead of braces: https://github.com/mystor/slag Syntax extensions, lint plugins, etc are all possible via the plugin interface. https://doc.rust-lang.org/book/compiler-plugins.html Honestly, this is pretty cool :/ This thread is really long so I didn't read all the posts. Sorry if this has been mentioned.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 04:10:22 UTC, Jonathan M Davis wrote: To get code coverage in C++, I'd have to go track down a tool to do it. There is none which is used as part of our normal build process at work. As it is, we only have unit tests because I went and added what was needed to write them and have been writing them. I also tend to use the features that can be directly used from the compiler switches more than external programs. I tend to look at --help first. Maybe one should also list programs that are distributed with the compiler in the compiler --help listing.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 06:03:14 UTC, rsw0x wrote: Syntax extensions, lint plugins, etc are all possible via the plugin interface. https://doc.rust-lang.org/book/compiler-plugins.html Honestly, this is pretty cool :/ Yes, it looks very cool. It lowers the threshold for experimentation and testing new ideas.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 06:03:14 UTC, rsw0x wrote: This thread is really long so I didn't read all the posts. Sorry if this has been mentioned. Don't worry, I don't recall anybody talking about it. Nevertheless, plugins aren't unique to Rust: GCC and Clang allow plugins. Nevertheless, I think that the Rust C++ plugin you posted was cool. Reminds me of Rcpp.
Re: Rant after trying Rust a bit
On 08/03/2015 11:19 AM, Max Samukha wrote: On Monday, 3 August 2015 at 06:52:41 UTC, Timon Gehr wrote: On 08/02/2015 09:02 PM, Max Samukha wrote: On Sunday, 26 July 2015 at 23:29:18 UTC, Walter Bright wrote: For example, the '+' operator. Rust traits sez gee, there's a + operator, it's good to go. Ship it! Meanwhile, you thought the function was summing some data, when it actually is creating a giant string, or whatever idiot thing someone decided to use '+' for. Number addition and string concatenation are monoid operations. In this light, '+' for both makes perfect sense. '+' is usually used to denote the operation of an abelian group. The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. My point is that it is. String concatenation is not commutative.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 15:58:28 UTC, Timon Gehr wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. My point is that it is. String concatenation is not commutative. Ok, good point. Except that '+' in a programming language is not the mathematical '+'. Why define '+' as strictly commutative operation and not more generally as an abstract binary operation, considering the middle dot is unavailable? Or, if we want to stick to the math notation, then '*' would be more appropriate than the idiot thing '~'.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 17:12:29 UTC, Max Samukha wrote: On Wednesday, 5 August 2015 at 15:58:28 UTC, Timon Gehr wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. My point is that it is. String concatenation is not commutative. Ok, good point. Except that '+' in a programming language is not the mathematical '+'. Why define '+' as strictly commutative operation and not more generally as an abstract binary operation, considering the middle dot is unavailable? Or, if we want to stick to the math notation, then '*' would be more appropriate than the idiot thing '~'. Nobody want to stay in the math world. Not that math are worthless, but it has this tendency to make simple things absurdly complex by requiring you to learn a whole area of math to understand the introduction. This is commonly referred as the monad curse: once you understand what a monad is, you loose all capacity to explain it. In fact, Most developers have used some sort of monad, but only a very small portion know they were using one or can explain you what it is. Mathematical language is geared toward generality and correctness, not practicality. That makes sens in the context of math, that do not in the context of every day programming.
Re: Rant after trying Rust a bit
On 08/05/2015 07:12 PM, Max Samukha wrote: On Wednesday, 5 August 2015 at 15:58:28 UTC, Timon Gehr wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. My point is that it is. String concatenation is not commutative. Ok, good point. Except that '+' in a programming language is not the mathematical '+'. It's obvious where the notation has been borrowed from. Why define '+' as strictly commutative operation and not more generally as an abstract binary operation, Descriptive names do have some value. considering the middle dot is unavailable? (It isn't.) Or, if we want to stick to the math notation, then '*' would be more appropriate than the idiot thing '~'. That's a different discussion. '*' is certainly more appropriate than '+'. Anyway, I think it is sensible to use distinct names for distinct operations when they are used in the same system.
Re: Rant after trying Rust a bit
On 08/05/2015 07:32 PM, deadalnix wrote: On Wednesday, 5 August 2015 at 17:12:29 UTC, Max Samukha wrote: On Wednesday, 5 August 2015 at 15:58:28 UTC, Timon Gehr wrote: The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'. My point is that it is. String concatenation is not commutative. Ok, good point. Except that '+' in a programming language is not the mathematical '+'. Why define '+' as strictly commutative operation and not more generally as an abstract binary operation, considering the middle dot is unavailable? Or, if we want to stick to the math notation, then '*' would be more appropriate than the idiot thing '~'. Nobody want to stay in the math world. Not that math are worthless, but it has this tendency to make simple things absurdly complex by requiring you to learn a whole area of math to understand the introduction. I assume the set of examples you are generalizing this from has cardinality close to one? Anyway, it seems like an exaggeration. This is commonly referred as the monad curse: once you understand what a monad is, you loose all capacity to explain it. I'm not buying it. In fact, Most developers have used some sort of monad, but only a very small portion know they were using one or can explain you what it is. ... Which isn't surprising. This isn't a very useful name in their (quite specific) use cases. Mathematical language is geared toward generality and correctness, not practicality. That makes sens in the context of math, that do not in the context of every day programming. I don't see what you are trying to get at here, but I guess it is almost entirely unrelated to choosing a notation for string concatenation.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 22:24:34 UTC, Enamex wrote: Oh, it _is_ talked about a lot. Just normally called 'syntax extensions' (the most used aspect of the plugin system), so it _is_ used. Though because it relies on compiler internals everything released as a plugin is only usable on Nightly. I had been talking about this thread. You're right that there are a bunch of mentions on the forums (which I found after searching the term you list), but only two in the past day (including yours) on this thread.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 19:56:37 UTC, Timon Gehr wrote: On 08/05/2015 07:32 PM, deadalnix wrote: Mathematical language is geared toward generality and correctness, not practicality. That makes sens in the context of math, that do not in the context of every day programming. I don't see what you are trying to get at here, but I guess it is almost entirely unrelated to choosing a notation for string concatenation. Well, I don't think practicality is the main issue, but the mnemonic aspect of syntax is important. It is not unreasonable to make the identity of operators/functions consist of both name and parameter types like in C++ and D. So you don't have + as the operator name, you have +(int,int) and +(string,string). If one makes mathematical properties intrinsic to untyped part of the name then a lot of overloading scenarios break down e.g. for non-euclidean types. It has been argued that functional languages would benefit from teaching functional programming in a less mathematical manner (e.g. talk about callbacks rather than monads etc): https://youtu.be/oYk8CKH7OhE
Re: Rant after trying Rust a bit
On Friday, 24 July 2015 at 21:44:42 UTC, Tofu Ninja wrote: But the part that I don't think makes sense for auto a = {return 4;}; to type a to a function pointer. I would expect {return 4;} to be treated as a function(not a function pointer). With it being treated as a function, I would expect it to be called with optional parens and type a to an int. I would expect auto a = {return 4;}; to type a to a function pointer, which makes much more sense to me. But that's not how function literals work right now. Treating {return 4;} as a function(not a function pointer) makes a lot more sense and allows alias a = {return 4;}; to work as well, which is simply a function declaration. Not crazy about your last point, TBH. Personally I really dislike function literals being _just_ `{ ... }` and as a matter of principle only write `(){...}` when I need one. `{}` to me can only mean blocks that are part of the current scope, but they're sometimes that and sometimes lambdas, depending on whether they had any `return`s and are in a place to be assigned a name or immediately called :/ A related thing is having _some way_ to quickly return a value from inside an invoked function literal without `return`. Somme stuff can't be done in a one-liner and need _two_(ish) lines and have to write, say, `{ Type myval, myres; res_by_ref(myval, myres); return myres; }()` instead of `{ Type myval, myres; res_by_ref(myval, myres); myres }` (expression-oriented) or `(){ ...; = myres; }()`(hypothetically). Point is, writing `return` in the middle of a function and having it return _only_ from a lambda breaks the flow, I believe, same as in C++.
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 14:21:13 UTC, jmh530 wrote: On Wednesday, 5 August 2015 at 06:03:14 UTC, rsw0x wrote: This thread is really long so I didn't read all the posts. Sorry if this has been mentioned. Don't worry, I don't recall anybody talking about it. Nevertheless, plugins aren't unique to Rust: GCC and Clang allow plugins. Nevertheless, I think that the Rust C++ plugin you posted was cool. Reminds me of Rcpp. Oh, it _is_ talked about a lot. Just normally called 'syntax extensions' (the most used aspect of the plugin system), so it _is_ used. Though because it relies on compiler internals everything released as a plugin is only usable on Nightly.
Re: Rant after trying Rust a bit
On Tuesday, 4 August 2015 at 22:42:50 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 4 August 2015 at 20:47:00 UTC, Jonathan M Davis wrote: LOL. I finally got some bugs sorted out on the project that I'm working on at work (in C++), which means that I can get back to what I was working on implementing before, and about all I recall for sure is that I was working on the unit tests for it. I don't know where I was with them. I find myself wishing that I had -cov so that I could figure out what I had left to test... :( It often seems like the advantages of some of D's features are more obvious when you have to go back to another language like C++ which doesn't have them. What do you dislike about C++ coverage tooling in comparison with D's? To get code coverage in C++, I'd have to go track down a tool to do it. There is none which is used as part of our normal build process at work. As it is, we only have unit tests because I went and added what was needed to write them and have been writing them. No one else has been writing them, and if I want any kind of code coverage stuff set up, I'd have to go spend the time to figure it out. With D, it's all built-in, and I don't have to figure out which tools to use or write any of them myself - either for unit testing or code coverage. They're just there and ready to go. - Jonathan M Davis
Re: Rant after trying Rust a bit
On Wednesday, 5 August 2015 at 04:10:22 UTC, Jonathan M Davis wrote: On Tuesday, 4 August 2015 at 22:42:50 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 4 August 2015 at 20:47:00 UTC, Jonathan M Davis wrote: [...] What do you dislike about C++ coverage tooling in comparison with D's? To get code coverage in C++, I'd have to go track down a tool to do it. There is none which is used as part of our normal build process at work. As it is, we only have unit tests because I went and added what was needed to write them and have been writing them. No one else has been writing them, and if I want any kind of code coverage stuff set up, I'd have to go spend the time to figure it out. With D, it's all built-in, and I don't have to figure out which tools to use or write any of them myself - either for unit testing or code coverage. They're just there and ready to go. - Jonathan M Davis This is nonsense, what major C++ compiler doesn't provide code coverage? I feel like 99% of C++ vs D arguments on this forum are comparing C++98 to D.
Re: Rant after trying Rust a bit
On Tuesday, 4 August 2015 at 20:47:00 UTC, Jonathan M Davis wrote: LOL. I finally got some bugs sorted out on the project that I'm working on at work (in C++), which means that I can get back to what I was working on implementing before, and about all I recall for sure is that I was working on the unit tests for it. I don't know where I was with them. I find myself wishing that I had -cov so that I could figure out what I had left to test... :( It often seems like the advantages of some of D's features are more obvious when you have to go back to another language like C++ which doesn't have them. What do you dislike about C++ coverage tooling in comparison with D's?
Re: Rant after trying Rust a bit
On Saturday, 25 July 2015 at 08:58:26 UTC, Walter Bright wrote: I would have had a LOT more trouble shipping the Warp project if I hadn't gone with 100% coverage from the ground up. Nearly all the bugs it had in the field were due to my misunderstandings of the peculiarities of gpp - the code had worked as I designed it. This is a huge reason why I want to switch to ddmd. I want to improve the quality of the compiler with unit tests. The various unit tests schemes I've tried for C++ are all ugly, inconvenient, and simply a bitch. It's like trying to use a slide rule after you've been given a calculator. LOL. I finally got some bugs sorted out on the project that I'm working on at work (in C++), which means that I can get back to what I was working on implementing before, and about all I recall for sure is that I was working on the unit tests for it. I don't know where I was with them. I find myself wishing that I had -cov so that I could figure out what I had left to test... :( It often seems like the advantages of some of D's features are more obvious when you have to go back to another language like C++ which doesn't have them. - Jonathan M Davis
Re: Rant after trying Rust a bit
On Sunday, 2 August 2015 at 21:17:10 UTC, Jonathan M Davis wrote: Where distinguishing between + and ~ would likely make a big difference though is dynamic languages that aren't strict with types and allow nonsense like 5 + 2. Using '~' instead of '+' to concatenate strings is just a syntax and says nothing about type system.
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 09:37:10 UTC, Jonathan M Davis wrote: On Friday, 31 July 2015 at 04:47:20 UTC, Enamex wrote: Right now docs say that `delete` is getting deprecated but using it on DMD .067.1 gives no warnings. There are no warnings because it hasn't actually been deprecated yet. [...] - Jonathan M Davis GC and memory management in general are inadequately documented. There're doc-pages and answers on SO and discussions on the forum about stuff that (coming from C++) should be so basic, like how to allocate an instance of a struct on the heap (GC'ed or otherwise) or how to allocate a class on non-managed heap (still don't get how `Unique!` works; does it even register with the GC? How to deep-copy/not-move its contents into another variable?), or on the stack, for that matter (there's `scoped!` but docs again are confusing. It's somehow stack-allocated but can't be copied?). Eventually deprecating it while leaving it now without any warnings (though the docs warn; offer no replacement) seems like it'd be more trouble than it's worth down the line, since it's not a feature addition or even full deprecation but -AFAIU- a replacement of semantics for identical syntax.
Re: Rant after trying Rust a bit
On Monday, 3 August 2015 at 06:52:41 UTC, Timon Gehr wrote: On 08/02/2015 09:02 PM, Max Samukha wrote: On Sunday, 26 July 2015 at 23:29:18 UTC, Walter Bright wrote: For example, the '+' operator. Rust traits sez gee, there's a + operator, it's good to go. Ship it! Meanwhile, you thought the function was summing some data, when it actually is creating a giant string, or whatever idiot thing someone decided to use '+' for. Number addition and string concatenation are monoid operations. In this light, '+' for both makes perfect sense. '+' is usually used to denote the operation of an abelian group. The point is that '+' for string concatenation is no more of an 'idiot thing' than '~'.
Re: Rant after trying Rust a bit
On 08/02/2015 09:02 PM, Max Samukha wrote: On Sunday, 26 July 2015 at 23:29:18 UTC, Walter Bright wrote: For example, the '+' operator. Rust traits sez gee, there's a + operator, it's good to go. Ship it! Meanwhile, you thought the function was summing some data, when it actually is creating a giant string, or whatever idiot thing someone decided to use '+' for. Number addition and string concatenation are monoid operations. In this light, '+' for both makes perfect sense. '+' is usually used to denote the operation of an abelian group.
Re: Rant after trying Rust a bit
On Sunday, 2 August 2015 at 21:17:10 UTC, Jonathan M Davis wrote: types you're dealing with, and it allows user-defined code to have both an addition operator and a concatenation operator on the same type. I assume you mean vectors, though I would prefer binary ++ for that. Where distinguishing between + and ~ would likely make a big difference though is dynamic languages that aren't strict with types and allow nonsense like 5 + 2. And in that case, I expect that Walter is completely right. It's just error-prone to use + for concatenation in cases like that, and providing a separate concatenation operator would reduce bugs. I've never run into such bugs, have you? The ambigious case would be result: + 3 + 8 , but you can solve this by giving numeric plus higher precedence or avoid implicit conversion. Though, these days it is more common to support something like result: {{3+8}}. Regardless, I definitely like the fact that we have ~ and ~= instead of reusing + and += for that. It's a small improvement, but it is an improvement. It's a weird thing to do for a C-decendant as I would expect ~= to do binary negation.
Re: Rant after trying Rust a bit
On Sunday, 26 July 2015 at 23:29:18 UTC, Walter Bright wrote: For example, the '+' operator. Rust traits sez gee, there's a + operator, it's good to go. Ship it! Meanwhile, you thought the function was summing some data, when it actually is creating a giant string, or whatever idiot thing someone decided to use '+' for. Number addition and string concatenation are monoid operations. In this light, '+' for both makes perfect sense.
Re: Rant after trying Rust a bit
On Sunday, 2 August 2015 at 19:02:22 UTC, Max Samukha wrote: On Sunday, 26 July 2015 at 23:29:18 UTC, Walter Bright wrote: For example, the '+' operator. Rust traits sez gee, there's a + operator, it's good to go. Ship it! Meanwhile, you thought the function was summing some data, when it actually is creating a giant string, or whatever idiot thing someone decided to use '+' for. Number addition and string concatenation are monoid operations. In this light, '+' for both makes perfect sense. Well, using + for adding strings together does make sense on some level, which is why it's done in so many languages, and I don't think that it causes as much confusion as Walter sometimes seems to think (at least in C/C++-derived languages). That being said, I think that it's definitely an improvement that D has another operator for it. It makes it clearer when concatenation is occurring without having to figure out what types you're dealing with, and it allows user-defined code to have both an addition operator and a concatenation operator on the same type. Where distinguishing between + and ~ would likely make a big difference though is dynamic languages that aren't strict with types and allow nonsense like 5 + 2. And in that case, I expect that Walter is completely right. It's just error-prone to use + for concatenation in cases like that, and providing a separate concatenation operator would reduce bugs. Regardless, I definitely like the fact that we have ~ and ~= instead of reusing + and += for that. It's a small improvement, but it is an improvement. - Jonathan M Davis
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 09:37:10 UTC, Jonathan M Davis wrote: On Friday, 31 July 2015 at 04:47:20 UTC, Enamex wrote: Right now docs say that `delete` is getting deprecated but using it on DMD .067.1 gives no warnings. There are no warnings because it hasn't actually been deprecated yet. So, the docs are quite correct. They say that it's _going_ to be deprecated, not that it has been deprecated. Ideally, it would have been deprecated quite some time ago, but without the custom allocators, it's a lot harder to do something similar to what delete does. So, if we'd actually deprecated it, we'd have done so without a viable alternative (it's possible without custom allocators, but it's hard to get right). Now, I think that the reality of the matter that it hasn't been deprecated is simply because no one has gotten around to it yet, but there are problems with deprecating it prior getting customer allocators. Fortunately, it looks like we will soon have that in std.experimental, so it will become more reasonable to deprecate delete, and maybe we can finally deprecate it and start moving it out of the language. But it's been planned for ages that delete would be removed from D at some point. - Jonathan M Davis I would much rather delete to stay and rig it up so new and delete call the global allocator(which would be the GC by default).
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 09:08:00 UTC, Ziad Hatahet wrote: On Thu, Jul 30, 2015 at 7:19 AM, Chris via Digitalmars-d digitalmars-d@puremagic.com wrote: My point was that any (new) feature introduces its own problems... As I said, I'll wait and see what Rust users have to say after a year or two. Except, as it was pointed out, this is not a new feature. It has been around in many languages way before Rust. You don't have to wait a year or two, check what the experience of users of languages such as Scala, Haskell, F#, and OCaml has been like. It really doesn't mean much if you're talking about functional languages, because they're fundamentally different from imperative languages in how they're constructed. Almost everything in functional languages is an expression, and it works fine for them, but the way that code is written in those languages is also fundamentally different from how you'd write it in C, C++, Java, C#, D, etc. As I understand it, Rust is much closer to C++ and friends than a functional language, so how it interacts with the rest of the language is going to be quite different. That doesn't mean that it won't work just fine, but it does mean that the fact that it works fine in functional languages doesn't necessarily mean that it'll work well for Rust. Now, there may be other imperative languages which have something similar - be it that all statements are expressions or that a larger subset of them are - so there may already be one or more languages out there which show that it can work just fine with an imperative language, but AFAIK, all of the languages you listed are either outright functional languages or lean heavily in that direction rather than being imperative. So, I don't think that experiences with those languages necessarily says much about how well it will work for Rust. - Jonathan M Davis
Re: Rant after trying Rust a bit
On Thu, Jul 30, 2015 at 7:19 AM, Chris via Digitalmars-d digitalmars-d@puremagic.com wrote: My point was that any (new) feature introduces its own problems... As I said, I'll wait and see what Rust users have to say after a year or two. Except, as it was pointed out, this is not a new feature. It has been around in many languages way before Rust. You don't have to wait a year or two, check what the experience of users of languages such as Scala, Haskell, F#, and OCaml has been like.
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 04:47:20 UTC, Enamex wrote: Right now docs say that `delete` is getting deprecated but using it on DMD .067.1 gives no warnings. There are no warnings because it hasn't actually been deprecated yet. So, the docs are quite correct. They say that it's _going_ to be deprecated, not that it has been deprecated. Ideally, it would have been deprecated quite some time ago, but without the custom allocators, it's a lot harder to do something similar to what delete does. So, if we'd actually deprecated it, we'd have done so without a viable alternative (it's possible without custom allocators, but it's hard to get right). Now, I think that the reality of the matter that it hasn't been deprecated is simply because no one has gotten around to it yet, but there are problems with deprecating it prior getting customer allocators. Fortunately, it looks like we will soon have that in std.experimental, so it will become more reasonable to deprecate delete, and maybe we can finally deprecate it and start moving it out of the language. But it's been planned for ages that delete would be removed from D at some point. - Jonathan M Davis
Re: Rant after trying Rust a bit
On 07/30/2015 11:25 AM, Chris wrote: On Thursday, 30 July 2015 at 02:30:45 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 28 July 2015 at 09:29:28 UTC, Chris wrote: [1] I wonder what kind of bugs will be introduced, when if-else is used as an expression. I believe most Algol-like languages outside the C-family have it... So can you tell me what pitfalls there are? What kind of special pitfall do you envision here? Sure people must have come across some nasty bugs related to this. They are the intersection of nasty bugs involving ?: and nasty bugs involving if/else statements.
Re: Rant after trying Rust a bit
On 22/07/2015 19:47, simendsjo wrote: Long rant ahead - a bit dipsy.. TL;DR: Rust has momentum, manpower and tooling. Tooling matters. Safe defaults. Ergonomics like expressions and deconstructing rocks. Tooling doesn't just matters. Tooling trumps everything else. I've skimmed through this discussion and noticed a lot of discussion about Rust's traits vs. D's template constraints, as well as a few other minor language features. And while there is value in such discussion - as it may bring a better understanding or clarity about language design, or perhaps even a few language or library changes - don't be under the illusion that ultimately it will make any significant difference in language adoption, if the tooling quality differs a lot (and it does). Minor differences, shortcomings even, between languages will only have a big impact for the kind of people that approach language preference with an art appreciator kind of mentality. An almost platonic/voyeristic approach. But for people building non-small, real-world projects (the engineering approach), tooling will trump everything else. Only if the language differences where massive (say between D and Go), would perhaps tooling not trump language design... but even then, it would still be a big fight between the two! -- Bruno Medeiros https://twitter.com/brunodomedeiros
Re: Rant after trying Rust a bit
On Thursday, 30 July 2015 at 14:23:34 UTC, Alex Parrill wrote: On Thursday, 30 July 2015 at 11:46:02 UTC, Bruno Medeiros wrote: Tooling doesn't just matters. Tooling trumps everything else. I don't agree. IMO reducing the need for tools would be a better solution. For example, there's no need for a memory checker if you're writing in Python, but if you're writing in C, you better start learning how to use Valgrind, and that takes time. Also there's Javascript's overabundance of tooling, with varying levels of quality, way too many choices (grunt vs gulp vs ..., hundreds of transpilers), and incompatibilities (want to use JSX and TypeScript together? Good luck). To take it to the extreme, no matter how much tooling you write for BrainFuck, I doubt anyone will use it. I think D goes in the right track by embedding things like unit tests, function contracts, and annotations into the language itself, even if the implementations could capitalize on them better than they do now. It is not matter of agreeing or not. It is matter of fact. Language with good tooling work, language with poor tooling do not. C++ did lose traction compared to java for a while and only came back up recently because Moore law is starting to not yield expected results and tooling dramatically improved. Tooling is king, and beat language solution most of the time.
Re: Rant after trying Rust a bit
On Thursday, 30 July 2015 at 13:32:29 UTC, Timon Gehr wrote: On 07/30/2015 11:25 AM, Chris wrote: On Thursday, 30 July 2015 at 02:30:45 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 28 July 2015 at 09:29:28 UTC, Chris wrote: [1] I wonder what kind of bugs will be introduced, when if-else is used as an expression. I believe most Algol-like languages outside the C-family have it... So can you tell me what pitfalls there are? What kind of special pitfall do you envision here? Sure people must have come across some nasty bugs related to this. They are the intersection of nasty bugs involving ?: and nasty bugs involving if/else statements. My point was that any (new) feature introduces its own problems. Be it everything is a statement or built-in bug prevention (rigid features). While preventing certain types of bugs, new types may be introduced by features that have been introduced to prevent old bugs. It would be foolish to believe that most bugs will be erased, if only a language is rigid enough. As I said, I'll wait and see what Rust users have to say after a year or two.
Re: Rant after trying Rust a bit
On Thursday, 30 July 2015 at 11:46:02 UTC, Bruno Medeiros wrote: Tooling doesn't just matters. Tooling trumps everything else. I don't agree. IMO reducing the need for tools would be a better solution. For example, there's no need for a memory checker if you're writing in Python, but if you're writing in C, you better start learning how to use Valgrind, and that takes time. Also there's Javascript's overabundance of tooling, with varying levels of quality, way too many choices (grunt vs gulp vs ..., hundreds of transpilers), and incompatibilities (want to use JSX and TypeScript together? Good luck). To take it to the extreme, no matter how much tooling you write for BrainFuck, I doubt anyone will use it. I think D goes in the right track by embedding things like unit tests, function contracts, and annotations into the language itself, even if the implementations could capitalize on them better than they do now.
Re: Rant after trying Rust a bit
On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote: Long rant ahead - a bit dipsy.. TL;DR: Rust has momentum, manpower and tooling. Tooling matters. Safe defaults. Ergonomics like expressions and deconstructing rocks. [...] But again... After playing a bit with Rust, I feel it lacks a lot in expressive power. D has templates, template mixins, alias this, string mixins, opDispatch etc. In my little time with Rust, I've seen several pages of generic constrains that is expressible in a couple of lines with D. I've seen copy/pasted code that just isn't necessary when you code in D. Anyways - my little ramblings after trying the Rust programming language while I haven't used D in a long, long while (But I'm still here now, as I'm not sure Rust is able to express everything that is possible with D). Looking forward to following D again :) Mostly my experience, so far. If I have to choose the 'most important' things that Rust has that I'd *definitely* want in D, I'd pick (in order): * A really nicely integrated package manager like Cargo that goes seamlessly hand-in-hand with DMD. * DDMD * An attribute or something that makes it explicit to the compiler that this type is a 'one time use' deal, and /exactly/ one-time-use (or, to be practical, zero-or-one times). Copying instances of objects of that type is done by `.dup`. (Like a non-Copy type in Rust currently.) * Sum Data Types (`enum`s in Rust and `data D = VarA | VarB` in Haskell). As well as: * Pattern matching. `Algebraic!` is okay but pattern-matching that goes with it isn't PM. But maybe that's for D 3.0 in 2030 or maybe another language... (I just want SML with at least D's speed T_T. I already got something /very roughly/ akin to ML's functors from D's template and mixin magic...)
Re: Rant after trying Rust a bit
On Friday, 31 July 2015 at 03:41:35 UTC, Enamex wrote: [...] Mostly my experience, so far. If I have to choose the 'most important' things that Rust has that I'd *definitely* want in D, I'd pick (in order): * A really nicely integrated package manager like Cargo that goes seamlessly hand-in-hand with DMD. * DDMD [...] Ouch. Actually forgot second most important point (right before DDMD): a ~99.99% @nogc Phobos and better documentation for GC stuff. Right now docs say that `delete` is getting deprecated but using it on DMD .067.1 gives no warnings.
Re: Rant after trying Rust a bit
On 30/07/2015 15:23, Alex Parrill wrote: On Thursday, 30 July 2015 at 11:46:02 UTC, Bruno Medeiros wrote: Tooling doesn't just matters. Tooling trumps everything else. I don't agree. IMO reducing the need for tools would be a better solution. For example, there's no need for a memory checker if you're writing in Python, but if you're writing in C, you better start learning how to use Valgrind, and that takes time. That doesn't go against what I said. Not having the need for a tool can be seen as identical to having the perfect tool (a tool you do not need). Imagine I had said it this way: Tooling shortcomings trump all other shortcomings (like language design shortcomings). Not having the need for a particular tool, is like saying that tool has no shortcomings whatsover. -- Bruno Medeiros https://twitter.com/brunodomedeiros
Re: Rant after trying Rust a bit
On Thursday, 30 July 2015 at 02:30:45 UTC, Ola Fosheim Grøstad wrote: On Tuesday, 28 July 2015 at 09:29:28 UTC, Chris wrote: [1] I wonder what kind of bugs will be introduced, when if-else is used as an expression. I believe most Algol-like languages outside the C-family have it... So can you tell me what pitfalls there are? Sure people must have come across some nasty bugs related to this.
Re: Rant after trying Rust a bit
On Tuesday, 28 July 2015 at 15:39:13 UTC, John wrote: I wish all the D related posts go under the sub-reddit https://www.reddit.com/r/dlang dlang is a familiar name due to the dlang.org itself. Also, the pattern is easy to guess, like the golang. You may be having tens of sub-reddits for D but they all look non-standard and confusing at best. To make my point more clear, the other language groups post their announcements to their respective sub-reddits like r/rust, r/golang etc, while D group tries to post *everything* directly to the r/programming. This is what makes them call it a spam.
Re: Rant after trying Rust a bit
On Tuesday, 28 July 2015 at 09:29:28 UTC, Chris wrote: [1] I wonder what kind of bugs will be introduced, when if-else is used as an expression. I believe most Algol-like languages outside the C-family have it...
Re: Rant after trying Rust a bit
On Tuesday, 28 July 2015 at 05:49:40 UTC, Jonathan M Davis wrote: On Monday, 27 July 2015 at 22:47:05 UTC, jmh530 wrote: On Monday, 27 July 2015 at 21:54:23 UTC, Jonathan M Davis wrote: On Monday, 27 July 2015 at 20:49:54 UTC, Andrei Alexandrescu wrote: I'll do my best to limit my participation in emotional debates, and suggest other D luminaries to do the same. LOL. That's why I was originally planning to not say anything in this thread... - Jonathan M Davis Your comments were very clear and much appreciated, but I see the point. Well, I ended up commenting, because there were some very import points relevant to what we do with D that needed clarifying. What I wanted to avoid (and mostly did) was arguing over Rust vs D. For instance, I'd hate to lose the ternary operator in favor of the expression if-else blocks that were being suggested, but there's no point in arguing over it, because we're not going to lose the the ternary operator, and we're not going to make it so that if-else blocks can be used as expressions. Arguing about it at this point just creates contention. And it's far too easy to come at that sort of discussion from an emotional point of view that D is better because I really like it and am invested in it, and what's being suggested is alien to me or doesn't fit with my aesthetics or whatever. Sometimes what another language has _is_ better, but often, it's a trade-off or even completely subjective, and regardless, it generally isn't going to have any effect on D at this point. Rather, it's just going to make emotions flare. So, at this point, I'd prefer to generally avoid discussions of D vs any other language. I got into a really nasty argument about ranges vs iterators the other day on reddit, and I just don't want to be doing that sort of thing anymore. However, what we _do_ stand to learn from is what's work welling for other languages (like Rust) in terms of process and the things that they do that don't necessarily have to do with the language itself which help them succeed, particularly, since even though we're generally pretty strong on the language front (not perfect, but we definitely have a very strong offering), we tend to have problems with marketing, getting folks to contribute, getting those contributions merged in in a timely manner, getting releases out, etc. We've definitely improved on that front, but it's probably our weakest point, whereas the language itself is pretty fantastic. But I would like to avoid arguments over which language is better or which feature in which language is better or anything like that, particularly since we're unlikely to add anything to D at this point because of such discussions. Rather, we need to finish what we have and make it solid. - Jonathan M Davis Very wise. More often than not it is useless and irrelevant to discuss features other languages have. This does not mean that we shouldn't get inspiration from other languages. However, D's reality is different from Rust's or Go's and features don't necessarily translate directly into D (or even make sense in D). Another thing is, as I pointed out earlier, that a lot of new features other languages have are not yet tested well enough to be able to say whether or not they are really that good[1]. After all we are still experimenting with features and fixing things here and there after using them in the real world. There is a tendency to think that any feature we don't have absolutely s has to be incorporated, else D will never take off. I beg to differ. The question should not be Why doesn't D have this feature?, but How do I get the same effect in D?. Often we don't have to introduce a new feature, we merely have to use the tools we have to get the same effect. And we do have a lot of tools. [1] I wonder what kind of bugs will be introduced, when if-else is used as an expression.
Re: Rant after trying Rust a bit
On 2015-07-25 09:08, Jonathan M Davis wrote: I do think that our built-in unit testing facilities are a huge win for us though. It actually seems kind of silly at this point that most other languages don't have something similar given how critical they are to high quality, maintainable code. Most modern languages are capable to implement something similar or better purely in library code. -- /Jacob Carlborg
Re: Rant after trying Rust a bit
On Wednesday, 22 July 2015 at 20:50:53 UTC, simendsjo wrote: If I'm not mistaken, people of the D community have tried to market the language quite heavily. I don't know why more people haven't joined, and it's even more baffeling to see the comments on Reddit calling D related posts spam and speaking negatively of the marketing on a site where upvotes dictates the ranking on the front page. I wish all the D related posts go under the sub-reddit https://www.reddit.com/r/dlang dlang is a familiar name due to the dlang.org itself. Also, the pattern is easy to guess, like the golang. You may be having tens of sub-reddits for D but they all look non-standard and confusing at best.
Re: Rant after trying Rust a bit
Jonathan M Davis jmdavisp...@gmx.com wrote: trait C : A,B { } How is that any different from interfaces? You can do exactly the same thing with them. implT: A+B C for T { } ^^^ That's the important line. You can define *and implement* the trait C for *all types that already implement A and B*. That's definitely not possible with interfaces. The difference between traits and interfaces is, that trait implementation is separate from the type definition. fn myFunction(c: C) {...} [...] But as soon as you have to create a new one that combines two or more interfaces/traits/concepts, then that doesn't scale. interfaces force that. I wouldn't expect traits or concepts to, because they're compile-time constructs, but that would depend on how the language defines them. It might make sense to create combined traits/concepts for the cases where the operations in question are often going to be required together, but in general, it's going to scale far better to require them separately rather than require a combined trait/concept. Otherwise, you get a combinatorial explosion of traits/concepts as you combine them to create new traits/concepts - either that, or you code doesn't end up being very generic, because it's frequently using traits/concepts that require more operations than it actually uses, meaning that it will work with fewer types than it would otherwise. Because you can implement the combined trait directly for all separate subtraits, you can define that new trait just for the use of one function. Tobi
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 22:47:05 UTC, jmh530 wrote: On Monday, 27 July 2015 at 21:54:23 UTC, Jonathan M Davis wrote: On Monday, 27 July 2015 at 20:49:54 UTC, Andrei Alexandrescu wrote: I'll do my best to limit my participation in emotional debates, and suggest other D luminaries to do the same. LOL. That's why I was originally planning to not say anything in this thread... - Jonathan M Davis Your comments were very clear and much appreciated, but I see the point. Well, I ended up commenting, because there were some very import points relevant to what we do with D that needed clarifying. What I wanted to avoid (and mostly did) was arguing over Rust vs D. For instance, I'd hate to lose the ternary operator in favor of the expression if-else blocks that were being suggested, but there's no point in arguing over it, because we're not going to lose the the ternary operator, and we're not going to make it so that if-else blocks can be used as expressions. Arguing about it at this point just creates contention. And it's far too easy to come at that sort of discussion from an emotional point of view that D is better because I really like it and am invested in it, and what's being suggested is alien to me or doesn't fit with my aesthetics or whatever. Sometimes what another language has _is_ better, but often, it's a trade-off or even completely subjective, and regardless, it generally isn't going to have any effect on D at this point. Rather, it's just going to make emotions flare. So, at this point, I'd prefer to generally avoid discussions of D vs any other language. I got into a really nasty argument about ranges vs iterators the other day on reddit, and I just don't want to be doing that sort of thing anymore. However, what we _do_ stand to learn from is what's work welling for other languages (like Rust) in terms of process and the things that they do that don't necessarily have to do with the language itself which help them succeed, particularly, since even though we're generally pretty strong on the language front (not perfect, but we definitely have a very strong offering), we tend to have problems with marketing, getting folks to contribute, getting those contributions merged in in a timely manner, getting releases out, etc. We've definitely improved on that front, but it's probably our weakest point, whereas the language itself is pretty fantastic. But I would like to avoid arguments over which language is better or which feature in which language is better or anything like that, particularly since we're unlikely to add anything to D at this point because of such discussions. Rather, we need to finish what we have and make it solid. - Jonathan M Davis
Re: Rant after trying Rust a bit
On 7/26/2015 12:51 AM, Alix Pexton wrote: On 25/07/2015 9:48 PM, Walter Bright wrote: Unfortunately, Bruce Eckel's seminal article on it http://www.mindview.net/Etc/Discussions/CheckedExceptions has disappeared. Eckel is not a Java code monkey, he wrote the book Thinking In Java http://www.amazon.com/gp/product/0131002872/ https://web.archive.org/web/20150515072240/http://www.mindview.net/Etc/Discussions/CheckedExceptions That's it. Thanks for finding the link.
Re: Rant after trying Rust a bit
On Sunday, 26 July 2015 at 23:21:50 UTC, Walter Bright wrote: If the template constraint is 'isInputRange', and you pass it an 'InputRange' that is nothing beyond an input range, and it compiles, it is JUST AS GOOD as Rust traits, without needing to add 'isInputRange' to every template up the call tree. In fact, I do just this in my D dev projects. I have a set of mock ranges that match each of the range types. That is not enough, it has been covered. It is clear that this is what needs to be done for good testing. It is also clear and explained in this thread that this is not enough. The problem is the exact same as for dynamic typing and unitests. A dynamically typed function that expect a string can be test exhaustively with warious string passed as arguments. Still, none knows what happen when passed an int, float, array, object or whatever. Worse, it is either going to blow up in some unexpected way or not explode and do random stuff. Flatly no, it is not at all the same. Dynamic typing systems do not have constraints. Furthermore, dynamic typed languages tend to do random s**t when presented with the wrong type rather than fail. (Such as concatenating strings when the code was intended to do an arithmetic add.) D does not, it presents the user with a compilation error. That is blatantly false and show more ignorance than anything else. For the precise example, concatenate with + is know to be bad in dynamic typing for this very reason. Even PHP got around that trap and pretty much only javascript got into that road. You'll find noone defneding this outside the Node.js crowd, but once you start thinking that a monothreaded event loop is the definition of scalable, you are already lost for science anyway. But more generally there is a point. Dynamic languages tends to do random shit rather than failing. Hopefully, some won't. For instance python will fail hard rather than do random stuff when passed the wrong type. If that was the problem faced, then using a type system would be pointless. Using something like python is sufficient. The same way, instantiate your template with something it doesn't expect and you get absurdly complex errors (and it is getting worse as phobos get more and more enterprise with Foo forwarding to FooImpl and 25 different helpers). This is incorrect. In my D project development, when I send the wrong thing, I get a list of the template instantiation stack. Which is often 3 pages long. The bottom gives the method not found, and the stack gives how it got there. I find it adequate in that it doesn't take much effort to figure out where things went wrong. That is learned helplessness. This is bad and we should feel bad to propose such a user experience. There are reasons why template are frowned upon by many devs, and this is one of them. I even heard Andrei suggest at a conf to pipe the output of the compiler to head (he was talking about C++, but D suffer from the same problem in that regard). Yes it works, and yes you can eventually make sens of the error, but that is terrible user experience. BTW, when you discover that a constraint is wrong on a Phobos template, please file a bug report on it. It is not just phobos, but everybody's code. Why all this need to be done manually when the compiler could do it for us ? Isn't it why we use computer in the first place ? If I follow your post, one have to maintain a set of minimal mock to test instantiations, a constraint for the template and a body, the 3 of them requiring to be kept in synch over time while nothing checks it is. That is completely unmaintainable. The problem is the same, will it fail at call site/instanciation site with I expected X you gave me Y or will it fail randomly somewhere down the road in some unrelated part of the code, or worse, not fail at all when it should have ? If the constraint is InputRange, and the body assumes ForwardRange, and I pass it a ForwardRange, and it works, how is that 'worse'? Maybe now my complexity is quadratic ? Maybe it doesn't do what it is supposed to do anymore, but else ?
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 01:59:49 UTC, Jonathan M Davis wrote: On Sunday, 26 July 2015 at 22:59:09 UTC, deadalnix wrote: On Sunday, 26 July 2015 at 03:42:22 UTC, Walter Bright wrote: On 7/25/2015 3:28 PM, deadalnix wrote: Also, argument from ignorance is hard to maintain when the thread is an actual feedback from experience. You say that interfaces do the same thing. So please show how it's done with the example I gave: int foo(T: hasPrefix)(T t) { t.prefix();// ok bar(t);// error, hasColor was not specified for T } void bar(T: hasColor)(T t) { t.color(); } I'm not sure what is the problem here. The problem here is that if you're dealing with traits or concepts or whatever that are essentially interfaces, and foo uses the Prefix interface/trait/concept and then wants to use bar which has the Color interface/trait/concept, it has to then require that what it's given implements both the Prefix and Color interfaces/traits/concepts. So, if I translate to regular D, here is what I get : int foo(T)(T t) if (hasPrefix!T) { t.prefix();// ok bar(t);// ok, nothign is checked } void bar(T)(T t) if (hasColor!T) { t.color(); // error, color is not specified on an object of type XXX } It changes nothing. In the case of actual interfaces, this really doesn't work well, because you're forced to basically have an interface that's derived from both - e.g. PrefixAndColor. Otherwise, you'd be forced to do nonsense like have foo take a Prefix and then cast it to Color to pass to bar and throw an exception if the type it was given didn't actually implement both interfaces. And it's downright ugly. In reality, the code would likely simply end up not being that generic and would require some specific type that you were using in your code which implemented both Prefix and Color, and foo just wouldn't work with anything else, making it far less reusable. So, with actual interfaces, it becomes very difficult to write generic code. We do not have to make the same limitation (especially if trait are implicitly implemented). Still, even with this limitation, using type is considered superior and using unitests is not considered to be not sufficient. Also, your message is kind of weird as you seem to assume in that part that what is discussed here is the same as passing argument, when you get back to the checked exception position lower. With traits or concepts, presumably, you could say that foo required a type that implemented both Prefix and Color, which fixes the problem of how you're able to accept something that takes both generically without coming up with something like PrefixAndColor (though if you can only list one trait/concept as required, you're just as screwed as you are with interfaces). But even if you can list multiple traits/concepts as required by a function, you quickly end up with a proliferation of traits/concepts that need to be covered by a higher level function like foo, because not only would foo need to list all of the traits/concepts that the functions it uses directly require, but it has to list all of the traits/concepts that it even indirectly requires (potentially from far down the call stack). So, any change to a function that even gets called indirectly could break foo, because it didn't have the right traits/concepts listed in its requirements. And all of the functions in the call chain would have to have their list of required traits/concepts updated any time there was any tweak to any of the underlying functions, even if those functions would have actually worked fine with most of the code that was calling them, because the types being passed in had the new requirements already (it's just that the functions higher up the stack didn't list the updated requirements yet). By having foo list all of the traits/concepts that would be required anywhere in its call stack, you're doing something very similar to what happens with checked exceptions where the exceptions have to be listed clear up the chain. It's not quite the same, and there's no equivalent to throws Exception (since that would be equivalent to somehow having a trait/concept that said that you didn't care what the type given to foo implemented). Rather, you're basically being forced to list each trait/concept individually up the chain - but it's still a similar problem to checked exceptions. It doesn't scale well. And if a function is required to list all of the traits/concepts that are required - even indirectly - then changing the requirements of a function - even slightly - results in code breakage similar to that of checked exceptions when you change which exceptions a function throws, and throws Exception wasn't being used. And even if you're not worried about breaking other people's code, it's a maintenance problem to maintain that list clear up the chain. I'm
Re: Rant after trying Rust a bit
On Saturday, 25 July 2015 at 20:35:08 UTC, Walter Bright wrote: On 7/25/2015 3:29 AM, Jonathan M Davis wrote: We're essentially using it with ranges already when we're implementing algorithms differently based on what type of range we're given or what extra capabilities the range has, so it obviously is showing its usefulness there, That's right. We've already been doing it in a haphazard manner, what Andrei is doing is recognizing the technique, naming it, and thinking about how to formalize it, organize it, and determine best practices. It's like going from an ad-hoc table of function pointers to recognizing that one is doing OOP. Well, it'll be interesting to see what he comes up with. but the allocators is the only other case that I can think of at the moment where it would make sense to use it heavily. Containers are another fairly obvious use case. Yes. There are definitely places that DbI is going to be huge. I just have a hard time coming up with them. So, while I agree that it's a fantastic tool, I'm just not convinced yet that it's going to be one that's widely applicable. I guess that we'll just have to wait and see what Andrei comes up with and where others take it from there. But it's definitely something that D can do rather easily and most other languages can't do at all, so it's a big win for us in that regard, especially if it does turn out to be widely applicable. On a related note, while I'd noticed it on some level, I don't think that it had ever clicked for me how restrictive interfaces are before this discussion. The simple fact that you can't ask for two of them at once really reduces how reusable your code can be. So, templatizing those checks rather than using interfaces is huge. And DbI is an extension of that. There's likely a lot of unplumbed depth there. - Jonathan M Davis
Re: Rant after trying Rust a bit
Jonathan M Davis jmdavisp...@gmx.com wrote: On a related note, while I'd noticed it on some level, I don't think that it had ever clicked for me how restrictive interfaces are before this discussion. The simple fact that you can't ask for two of them at once really reduces how reusable your code can be. So, templatizing those checks rather than using interfaces is huge. And DbI is an extension of that. There's likely a lot of unplumbed depth there. One big improvement of traits over interfaces is, that you can implement traits for types after they are defined, even for types that you didn't define yourself. So in Rust, if your function needs two unrelated interfaces (trait objects == dynamic polymorphism) A and B, you can easily define a new trait C that depends on A and B and implement C for all types that also implement A and B: trait A {...} trait B {...} trait C : A,B { } implT: A+B C for T { } fn myFunction(c: C) {...} For generics you don't even need that: fn myFunctionT: A+B(t: T) {...} Tobi
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 19:11:53 UTC, deadalnix wrote: That is completely unmaintainable. I really don't get how the mess of unittests, mock data types, template constraints, and type interfaces that are just convention(ranges are just a convention, they don't exist anywhere) is supposed to some how be more maintainable than a single system that can serve the function of all of them and forces them all to be in sync 100% of the time. Seriously...
Re: Rant after trying Rust a bit
On 7/27/15 3:35 PM, Tofu Ninja wrote: On Monday, 27 July 2015 at 19:11:53 UTC, deadalnix wrote: That is completely unmaintainable. I really don't get how the mess of unittests, mock data types, template constraints, and type interfaces that are just convention(ranges are just a convention, they don't exist anywhere) is supposed to some how be more maintainable than a single system that can serve the function of all of them and forces them all to be in sync 100% of the time. Seriously... Clearly adding more language features to D would have certain payoff. But we should not just go ahead and pull today's hot topic, which really does change very often. As the language's main proponents, we should be more inclined toward using the language that we have creatively for solving interesting tasks, instead of keeping on wishing that just one more feature would make it perfect. The lure of the eternally-open design stage is very powerful (I basked in its glow a number of times), but it inevitably becomes an adversary to productivity - instead of getting work done, there's always contemplating how the language design could be tweaked to better accommodate the task at hand. The withdrawal is unpleasant, I know. But we must acknowledge that the design of D is done. The large stones and pillars we have in place are there to stay, and D shall not be radically different five years from now. We need to acknowledge that a lot of grass seems greener on the other side (and some really is), but we need to make do with the gardening tools we got. I'll do my best to limit my participation in emotional debates, and suggest other D luminaries to do the same. We should put strong emphasis on finalizing the definition and implementation of the language we have (those imprecisions and fuzzy corners are really counterproductive), forge forward to do great work with D, and show others how it's done. Thanks, Andrei
Re: Rant after trying Rust a bit
On 07/27/2015 01:29 AM, Walter Bright wrote: On 7/26/2015 3:44 PM, deadalnix wrote: or template code (which will blow up at instanciation time, or worse, do random shit). Um, all Rust traits do is test for a method signature match, so it compiles. It is NOT a defense against a random method that just happens to match and does some other unrelated random shit. You are describing Go interfaces, not Rust traits.
Re: Rant after trying Rust a bit
On 7/27/2015 12:53 PM, deadalnix wrote: So, if I translate to regular D, here is what I get : I asked how you'd solve the problem with interfaces.
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 19:21:10 UTC, Tobias Müller wrote: trait A {...} trait B {...} trait C : A,B { } implT: A+B C for T { } fn myFunction(c: C) {...} Tobi Has to be: fn my_function(c: C) { ... } actually, because trait objects can only be passed by reference/borrowed-pointer.
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 19:21:10 UTC, Tobias Müller wrote: Jonathan M Davis jmdavisp...@gmx.com wrote: On a related note, while I'd noticed it on some level, I don't think that it had ever clicked for me how restrictive interfaces are before this discussion. The simple fact that you can't ask for two of them at once really reduces how reusable your code can be. So, templatizing those checks rather than using interfaces is huge. And DbI is an extension of that. There's likely a lot of unplumbed depth there. One big improvement of traits over interfaces is, that you can implement traits for types after they are defined, even for types that you didn't define yourself. So in Rust, if your function needs two unrelated interfaces (trait objects == dynamic polymorphism) A and B, you can easily define a new trait C that depends on A and B and implement C for all types that also implement A and B: trait A {...} trait B {...} trait C : A,B { } How is that any different from interfaces? You can do exactly the same thing with them. implT: A+B C for T { } fn myFunction(c: C) {...} For generics you don't even need that: fn myFunctionT: A+B(t: T) {...} As long as you can list the two interfaces/traits/concepts that you require separately, then you're okay. But as soon as you have to create a new one that combines two or more interfaces/traits/concepts, then that doesn't scale. interfaces force that. I wouldn't expect traits or concepts to, because they're compile-time constructs, but that would depend on how the language defines them. It might make sense to create combined traits/concepts for the cases where the operations in question are often going to be required together, but in general, it's going to scale far better to require them separately rather than require a combined trait/concept. Otherwise, you get a combinatorial explosion of traits/concepts as you combine them to create new traits/concepts - either that, or you code doesn't end up being very generic, because it's frequently using traits/concepts that require more operations than it actually uses, meaning that it will work with fewer types than it would otherwise. In general, templates shouldn't be requiring more operations than they actually use, or they won't be as reusable as they could/should be. And that implies that the list of required operations should be kept to what's actually required rather than using traits/concepts that require those operations plus others. - Jonathan M Davis
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 21:54:23 UTC, Jonathan M Davis wrote: On Monday, 27 July 2015 at 20:49:54 UTC, Andrei Alexandrescu wrote: I'll do my best to limit my participation in emotional debates, and suggest other D luminaries to do the same. LOL. That's why I was originally planning to not say anything in this thread... - Jonathan M Davis Your comments were very clear and much appreciated, but I see the point.
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 20:49:54 UTC, Andrei Alexandrescu wrote: I'll do my best to limit my participation in emotional debates, and suggest other D luminaries to do the same. LOL. That's why I was originally planning to not say anything in this thread... - Jonathan M Davis
Re: Rant after trying Rust a bit
Walter Bright newshou...@digitalmars.com wrote: On 7/26/2015 3:44 PM, deadalnix wrote: or template code (which will blow up at instanciation time, or worse, do random shit). Um, all Rust traits do is test for a method signature match, so it compiles. It is NOT a defense against a random method that just happens to match and does some other unrelated random shit. Rust traits have to be implemented *explicitly*. It's not just an implicit test for a matching signature. For example, the '+' operator. Rust traits sez gee, there's a + operator, it's good to go. Ship it! Meanwhile, you thought the function was summing some data, when it actually is creating a giant string, or whatever idiot thing someone decided to use '+' for. + operator is somewhat special because it can only be implemented via trait. That doesn't apply for normal methods. Rust still has not obviated the necessity for unit tests, nor is Rust remotely able to guarantee your code doesn't do random shit if it compiles. An example: Rust std lib defines two traits, PartialOrd and Ord. Ord depends on PartialOrd but doesn't provide any new methods. And it's clearly documented when to implement Ord and when PartialOrd. So sure, someone could decide to deliberately ignore that, but then I just don't care anymore. Tobi
Re: Rant after trying Rust a bit
On Monday, 27 July 2015 at 07:21:36 UTC, Tobias Müller wrote: Walter Bright newshou...@digitalmars.com wrote: On 7/26/2015 3:44 PM, deadalnix wrote: or template code (which will blow up at instanciation time, or worse, do random shit). Um, all Rust traits do is test for a method signature match, so it compiles. It is NOT a defense against a random method that just happens to match and does some other unrelated random shit. Rust traits have to be implemented *explicitly*. It's not just an implicit test for a matching signature. Explicit is good, but D's problem is that it already have numerous language concepts covering the same type of semantics: classes, interfaces, alias this, template duck-typing, template constraints… C++ only have classes and template SFINAE duck-typing. Everything else is just idioms or library constructs. Adding yet another langauge level interface mechanism to D would IMO require language redesign. Which is not a bad idea, but not likely in the near term?
Re: Rant after trying Rust a bit
On Saturday, 25 July 2015 at 09:40:52 UTC, Walter Bright wrote: BTW, you might want to remove the UTF-8 characters from your user name. Evidently, NNTP doesn't do well with them. Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= It (or more likely, his user agent) does deal with them well. It's correctly quoted according to RFC2047: http://www.faqs.org/rfcs/rfc2047.html I've opened an enhancement request at DFeed's issue tracker: https://github.com/CyberShadow/DFeed/issues/44
Re: Rant after trying Rust a bit
On Sunday, 26 July 2015 at 01:33:09 UTC, Enamex wrote: On Thursday, 23 July 2015 at 15:03:56 UTC, Dicebot wrote: At the same time one HUGE deal breaker with rust traits that rarely gets mentioned is the fact that they are both constraints and interfaces at the same time: ... It kills all the necessity for hacks like RangeObject and is quite a salvation once you get to defining dynamic shared libraries with stable ABI. This is probably my most loved feature of Rust. Sorry, I don't quite get this. How is the most loved feature of Rust (that interfaces are also constraints for generics), a *deal breaker*? I have just checked the dictionary and it simply a matter of being having terrible English and using this phrase wrong all the time :) It was supposed to mean something like feature that makes crucial (positive) difference
Re: Rant after trying Rust a bit
On 7/25/15 6:54 PM, deadalnix wrote: On Saturday, 25 July 2015 at 10:05:35 UTC, Tofu Ninja wrote: On Saturday, 25 July 2015 at 09:40:52 UTC, Walter Bright wrote: if the template body uses an interface not present in the type and not checked for in the constraint, you will *still* get a compile time error. But only if the template gets instantiated with a bad type. Unit tests don't catch every thing and have to be written properly. A proper type system should catch it. This unitest argument is becoming ridiculous. Unless some strong argument is brought to the table that this differs from the dynamic typing is not a problem if you write unitest we we all should know is bogus at this point, it can't be taken seriously. To me that's self understood. Run time is fundamentally different from everything preceding it. -- Andrei
Re: Rant after trying Rust a bit
On 7/25/15 6:48 PM, deadalnix wrote: On Saturday, 25 July 2015 at 09:40:52 UTC, Walter Bright wrote: On 7/25/2015 12:19 AM, Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= ola.fosheim.grostad+dl...@gmail.com wrote: The point of having a type system is to catch as many mistakes at compile time as possible. The primary purpose of a type system is to reduce flexibility. Again, the D constraint system *is* a compile time system, and if the template body uses an interface not present in the type and not checked for in the constraint, you will *still* get a compile time error. The idea that Rust traits check at compile time and D does not is a total misunderstanding. Obvious, everything is at compile time here. Still, there is 2 steps, compiling the template (equivalent to compile time in the dynamic dispatch case), and instantiating the template (equivalent to runtime in the dynamic dispatch case). That is the exact same problem. Probably that's the root of all disagreement. So we have template writing time, template instantiation time, and just run time. I think template instantiation time is a lot closer to template writing time than run time. -- Andrei
Re: Rant after trying Rust a bit
On 07/25/2015 02:19 PM, Andrei Alexandrescu wrote: On 7/23/15 5:26 PM, Ziad Hatahet via Digitalmars-d wrote: On Thu, Jul 23, 2015 at 2:00 PM, Adam D. Ruppe via Digitalmars-d digitalmars-d@puremagic.com mailto:digitalmars-d@puremagic.com wrote: I think it is actually kinda pretty: What about: int median(int a, int b, int c) { return (ab) ? (bc) ? b : (ac) ? c : a : (ac) ? a : (bc) ? c : b; } vs. def median(a: Int, b: Int, c: Int) = if (a b) { if (b c) b else if (a c) c else a } else if (a c) a else if (b c) c else b This is a wash. If we want to discuss good things in Rust (The quoted bit is Scala code.) we could get inspiration from, we need relevant examples. -- Andrei What do you mean? I think it is pretty obvious that 'if'/'else' is better syntax than '?:'. It e.g. does not leave the separation of context and condition up to operator precedence rules and is hence easier to parse by a human. Not that I'd care much, but it is inconvenient to be asked not to use the ternary operator in team projects just because it has a badly engineered syntax. Also, we have (int x){ return r; }, auto foo(int x){ return r; }, (int x)=r, but not auto foo(int x)=r. It's an arbitrary restriction. (BTW: To all the people who like to put the ternary operator condition into parens in order to imitate if: A convention that makes more sense here is to put the entire (chained) ternary expression in parentheses.)
Re: Rant after trying Rust a bit
On 07/25/2015 02:15 PM, Andrei Alexandrescu wrote: On 7/23/15 4:52 PM, Walter Bright wrote: On 7/23/2015 1:08 PM, Dicebot wrote: I am not sure how it applies. D interfaces (defined with the 'interface' keyword) are simple dispatch types, they don't require an Object. Such interfaces can also have default implementations. Is this new? I agree we should allow it, but I don't think it was added to the language yet. Andrei In any case, the painful thing about the RangeObject interfaces is that they transform value types into reference types.
Re: Rant after trying Rust a bit
On Sunday, 26 July 2015 at 06:12:55 UTC, jmh530 wrote: I appreciate the thorough response. I think I agree with your point about error messages. Nevertheless, with respect to your point about a best effort to putting constraints at the top-level, there might be scope for making this easier for people. For instance, if there were a way to include the constraints from one template in another template. From your example, maybe something like auto foo(T)(T t) if(template_constraints!bar template_constraints!baz) { ... auto b = bar(t); ... auto c = baz(t); ... } Ideally the template_constraints!bar would expand so that in an error message the user sees what the actual constraints are instead of the more nebulous template_constraints!bar. At least something like this would avoid your point with respect to __traits(compiles, x). That's certainly an interesting idea, though if we're going that route, it might be better to simply have the compiler do that automatically for you, since it can see what functions are being called and what they're constraints are. Still, part of the problem is that the constraints for bar or baz may not be directly related to the argument to foo but rather to a result of operating on it. So, bar and baz's constraints can't necessarily be moved up into foo's constraint like that in a meaningful way. It would require the code that generates the arguments to bar and baz as well in order to make that clear. For instance, it might be that T needs to be an input range for the code that's directly in foo. However, if you do something like auto u = t.f1().f2().f3(); auto b = bar(u); u then needs to be a forward range to work with bar. In order for that to happen, t likely needs to have been a forward range, but if you tried to move bar's template constraint into foo's template constraint, it would be trying to require that u was a forward range - because that's what bar needs - whereas that's r really not what needs to be in foo's template constraint. What it needs is to require that t be a forward range instead of just an input range. The connection between the arguments the user is passing to the function that they're calling and the arguments to templated functions that are called within that function aren't necessarily straightforward. So, moving those sub-constraints up into the top-level constraint in a way that's clear to the caller either requires that the writer of that function do it (because they are able to understand how the function's argument relates to the requirements of the functions being called within that function and thus come up with the full requirements of for the function's argument), or it requires that enough context be given to the caller for them to be able to understand how what they're passing in is related to the call inside the template that's failing to compile because that function's argument doesn't pass its constraint. Without having the program who's writing this function translating the sub-constraints into what the requirements then are on the function's argument and need to go in the top-level constraint, I don't see how we can avoid providing at least _some_ of the source in error messages in order to make the context of the failure clear. Simply shoving all of that into the template constraint - even automatically - is just going to get ugly outside of basic cases. And really, even then, what you're trying to do is to take the context of the failure and put it in the template constraint rather than just show that context along with the failure. The more I think about it, the harder it seems to be able to provide enough information to the caller without pretty much just showing them the source code. The compiler should be able to reduce how much of the source code would have to be shown and thus avoid forcing the user to go look at the templates full source, but in anything but the most basic cases, that source code quickly becomes required to understand what's going on. If we're truly dealing with cases where the function's argument is simply passed on to another function call, then the sort of thing that you're suggesting is pretty straightforward and would likely work well. But there are going to be a lot of cases where the constraint failure isn't on the original function argument but on the result of passing it through other functions or on something that was obtained by calling one of that argument's member functions. And as soon as that's what's going on, attempting to push the sub-constraints into the top-level constraint either by automatically inferring them or by having something like template_constraints!baz is not going to work well, if at all. I don't know. I think that we can come up with solutions that fix many of the simple cases, but I also think that a lot of the simple cases are where it's easiest to maintain the top-level
Re: Rant after trying Rust a bit
On Saturday, 25 July 2015 at 21:20:28 UTC, Walter Bright wrote: On 7/25/2015 6:35 AM, Dicebot wrote: If compiler would actually show 0 coverage for non-instantiated lines, than automatic coverage control check in CI would complain and code would never be shipped unless it gets covered with tests (which check the semantics). Your are putting it totally backwards. A good case. https://issues.dlang.org/show_bug.cgi?id=14825 Thanks!
Re: Rant after trying Rust a bit
On 25/07/2015 9:48 PM, Walter Bright wrote: Unfortunately, Bruce Eckel's seminal article on it http://www.mindview.net/Etc/Discussions/CheckedExceptions has disappeared. Eckel is not a Java code monkey, he wrote the book Thinking In Java http://www.amazon.com/gp/product/0131002872/ https://web.archive.org/web/20150515072240/http://www.mindview.net/Etc/Discussions/CheckedExceptions
Re: Rant after trying Rust a bit
I think the ability to express an interface without buying into inheritance is the right move. The alternative in D is specifying the behavior as a template and verifying the contract in a unittest for the type. Rust only has structs. I'm not as familiar with them so it's not as clear how they overlap with D's structs and classes. It seems like you can put Rust structs on the stack or heap. What some people call interface inheritance in Rust is not inheritance in the sense of OOP whewre an inherited method can be overwritten. Rust is here the same as Go. Some people sometimes get confused and don't see that without the possibility of overwriting an inherited method delegation applies and not inheritance. This is also explained in this blog: http://objectscape.blogspot.de/search/label/Go See the section titled Inheritance. -- Bienlein
Re: Rant after trying Rust a bit
On Sunday, 26 July 2015 at 00:18:14 UTC, Walter Bright wrote: On 7/25/2015 3:59 PM, deadalnix wrote: On Saturday, 25 July 2015 at 12:05:12 UTC, Andrei Alexandrescu wrote: Well at least all paths must be compiled. You wouldn't ship templates that were never instantiated just as much as you wouldn't ship any code without compiling it. We've had a few cases in Phobos a while ago of templates that were never instantiated, with simple compilation errors when people tried to use them. -- Andrei That is an instance of happy case testing. You test that what you expect to work work. You can't test that everything that is not supposed to work do not, or that you don't rely on a specific behavior of the thing you are testing. Um, testing all paths is not happy case testing. You test all execution path, not all instantiation path. Consider this, in a dynamically typed language, you can have a function that accept a string and do something with it. You can write unit tests to check it does the right thing with various strings and make sure it execute all path. Yet, what happen when it is passed an int ? a float ? an array ? an object ? Probably random shit. Same here, but at instantiation time.