digitalmars.D.announce - My Meeting C++ Keynote video is now available
- Andrei Alexandrescu (6/6) Jan 12 2019 https://youtube.com/watch?v=tcyb1lpEHm0
- Walter Bright (2/3) Jan 12 2019 Wonderful talk! The questions asked at the end were great, too.
- Bastiaan Veelo (6/12) Jan 12 2019 Top notch, as usual.
- Andrei Alexandrescu (2/20) Jan 12 2019 Glad you noticed. It was deliberate.
- Jon Degenhardt (6/12) Jan 12 2019 Very nice. I especially liked how design by introspection was
- Walter Bright (8/9) Jan 12 2019 One major takeaway is that the bugs/line are the same regardless of the ...
- Tony (7/11) Jan 17 2019 Is the data to support this conclusion freely available on the
- H. S. Teoh (6/20) Jan 17 2019 No, if the number of bugs is truly proportional to the number of lines,
- Mike Franklin (18/19) Jan 13 2019 I especially like how design by introspection was contrasted with
- Paul Backus (16/28) Jan 13 2019 Scheme is probably the language that takes this idea of a minimal
- Walter Bright (5/19) Jan 13 2019 Interesting cites, which provide a basis for why I've opposed AST macros...
- Martin Tschierschke (12/36) Jan 14 2019 This is exactly the argument to get a database driver
- Steven Schveighoffer (23/61) Jan 14 2019 I don't like the idea of it, because there are so many approaches. Even
- Jacob Carlborg (4/6) Jan 14 2019 Exactly, and I don't need five minutes for that. Five seconds is enough ...
- Martin Tschierschke (4/9) Jan 15 2019 Ok, bad example, but let's say you want ORM mapping, too and to
- Steven Schveighoffer (13/23) Jan 16 2019 I should have said that your point is mostly correct, just that this is
- Paolo Invernizzi (5/22) Jan 16 2019 +1
- Steven Schveighoffer (5/6) Jan 16 2019 We're working on it...
- Paolo Invernizzi (9/15) Jan 16 2019 I was exactly referring to that two... they are great, and I've
- Steven Schveighoffer (14/28) Jan 16 2019 Slowly... Sorry, it's not my day job to improve these :)
- Dejan Lekic (14/16) Jan 16 2019 Absolutely not! Please...
- JN (6/18) Jan 16 2019 Depends on what you consider core stuff. I don't think webserver
- Jacob Carlborg (4/6) Jan 14 2019 But Ddoc has macros ;)
- Walter Bright (3/4) Jan 14 2019 Indeed it does. But the macros cannot be used to create syntax, and ther...
- Jacob Carlborg (5/11) Jan 15 2019 The AST macros I've been talking about have never been able to create
- Walter Bright (4/5) Jan 15 2019 Template expressions can't, either, but what they do is hijack the synta...
- Jacob Carlborg (13/16) Jan 15 2019 Ah, you mean like this:
- Walter Bright (13/14) Jan 15 2019 You deliberately wrote that, and I'm confident you'd never try to pass t...
- Nicholas Wilson (8/24) Jan 15 2019 I'm pretty sure Jacob is talking about a completely different
- Walter Bright (5/10) Jan 16 2019 I understand he means AST macros, but they aren't fundamentally differen...
- Jacob Carlborg (6/8) Jan 16 2019 Yeah, I should come up with a new name than "macro". A soon as Walter
- Jacob Carlborg (25/41) Jan 16 2019 Yes. I'm showing it's possible to write bad code in all programming
- Mike Franklin (13/23) Jan 14 2019 I think D's structs are a sufficient object system for such a
- aberba (6/23) Jan 14 2019 Do people really use Rust in production beyond the safety die
- JN (5/10) Jan 14 2019 Actually, a lot of people do. Many big companies are getting
- 12345swordy (3/27) Jan 14 2019 Killing classes will kill my interest and investment in D.
- Atila Neves (4/25) Jan 15 2019 He's not saying "kill classes in D", he's saying an OOP system in
- Neia Neutuladh (3/6) Jan 15 2019 As long as the syntax and behavior don't change, the error messages are
- welkam (2/5) Jan 15 2019 For some people writing OOP means writing keyword class.
- 12345swordy (5/10) Jan 15 2019 I am not interested in OOP as a library feature rather then a
- Walter Bright (2/4) Jan 16 2019 I wouldn't worry about that getting very far :-)
- JN (21/22) Jan 14 2019 This part always feels familiar to me in D (just replace Lisp
- bachmeier (25/30) Jan 14 2019 Much as I hate to disagree with folks on the internet, this is an
- bachmeier (4/9) Jan 14 2019 Only a small sliver of programming involves anything where
- Adam D. Ruppe (6/9) Jan 14 2019 Real D is the true better C. These improvements can improve in
- Steven Schveighoffer (4/15) Jan 14 2019 Some of the old crufty features of classes can be jettisoned like
- H. S. Teoh (16/28) Jan 14 2019 Yeah, much as I'm a big promoter of struct-based range-based template
- Guillaume Piolat (20/26) Jan 14 2019 About the adoption and success of DbI libraries:
- H. S. Teoh (11/19) Jan 14 2019 I think another angle of attack that AFAICT has been mostly overlooked
- Ben Jones (13/19) Jan 14 2019 A lot of the questions were about documenting the hook API and
- Paul Backus (2/4) Jan 14 2019 Yes, if you do it with a string mixin.
- Neia Neutuladh (3/8) Jan 14 2019 And more simply, you can declare a function with a hard-coded name, then...
- Andre Pany (10/33) Jan 14 2019 For ranges there are concepts like Input Range. A struct/class
- Ben Jones (6/43) Jan 14 2019 I don't think that's quite sufficient because a hook may/may not
- aliak (28/34) Jan 14 2019 Awesome talk! As usual.
- Paul Backus (5/12) Jan 14 2019 Does this take into account the experience of the programmers
- aliak (2/15) Jan 14 2019 Not that I saw in the paper no. But that is a good point.
- John Carter (17/19) Jan 16 2019 Somebody on the C++ side has written a reply....
- H. S. Teoh (28/37) Jan 16 2019 Yes, that's one of the outstanding qualities of D, and one that I was
- Walter Bright (10/18) Jan 16 2019 Bartosz Milewski is a C++ programmer and a Haskell fan. He once gave a
- Meta (5/16) Jan 16 2019 It was an article on Bartosz's blog where I first found out about
- H. S. Teoh (9/19) Jan 17 2019 [...]
- bpr (5/24) Jan 17 2019 Was that a pre C++11 version of C++, or a more modern one?
- Paul Backus (13/29) Jan 17 2019 The presentation was given at BoostCon 2011, and is (at least
- Steven Schveighoffer (4/4) Jan 17 2019 FYI, this whole subthread of B Revzin is NOT in my newsgroup reader. I
- H. S. Teoh (156/158) Jan 17 2019 [...]
- Steven Schveighoffer (27/53) Jan 17 2019 well, there was no static foreach for that article (which I admit I
- Mark (18/47) Jan 18 2019 Why not do away with AliasSeq and use strings all the way?
- H. S. Teoh (17/35) Jan 18 2019 That would work, but it would also suffer from all the same problems as
- Mark (6/20) Jan 19 2019 Well, it's the approach Andrei laid out in his DConf 2018 talk:
- Paul Backus (6/10) Jan 18 2019 Two problems:
- Stefan Koch (29/47) Jan 17 2019 For 2 years I have pondered this problem, and I did come up with
- H. S. Teoh (26/65) Jan 17 2019 YES! This is the way it should be. Type-tuples become first class
- Stefan Koch (28/52) Jan 17 2019 No this is not possible, a symbol which is only used at
- Jacob Carlborg (21/24) Jan 18 2019 No no no, not only type-tuples, you want types to be first class
- H. S. Teoh (18/41) Jan 18 2019 Yes, that would be the next level of symmetry. :-D Types as first class
- Stefan Koch (17/42) Jan 18 2019 Yes, you will be able to do exactly what you describe above.
- Jacob Carlborg (4/6) Jan 18 2019 You're using "alias" instead of my "type" keyword?
- Stefan Koch (4/8) Jan 18 2019 yes. After all what type-functions do when returning types, is
- Jacob Carlborg (6/10) Jan 18 2019 Not sure that would be possible. I tries to a support for pragma(mangle)...
- Johannes Loher (2/34) Jan 17 2019 This is one of the most exciting things i have read in recent times!
- Walter Bright (13/14) Jan 17 2019 Thanks for the thoughtful and well-written piece.
- H. S. Teoh (74/94) Jan 18 2019 Alas, it's true, it's true, 100% symmetry is, in the general case,
- Walter Bright (2/3) Jan 17 2019 pre C++11
- Walter Bright (31/34) Jan 16 2019 From the article:
https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... Andrei
Jan 12 2019
On 1/12/2019 7:51 AM, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0Wonderful talk! The questions asked at the end were great, too.
Jan 12 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiTop notch, as usual. Nice progression from “another language” through “the other language”, “d (other) language” to finally just “D language“ :-) Bastiaan.
Jan 12 2019
On 1/12/19 7:21 PM, Bastiaan Veelo wrote:On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:Glad you noticed. It was deliberate.https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiTop notch, as usual. Nice progression from “another language” through “the other language”, “d (other) language” to finally just “D language“ :-) Bastiaan.
Jan 12 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiVery nice. I especially liked how design by introspection was contrasted with other approaches and how the constexpr discussion fit into the overall theme. --Jon
Jan 12 2019
On 1/12/2019 7:51 AM, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0One major takeaway is that the bugs/line are the same regardless of the language used. This means that languages that enable more expression in fewer lines of code result in fewer bugs for the same functionality. Another way to look at that is when refactoring code, look for ways of reducing the line count. It does not mean deleting comment lines, or putting several statements on one line. :-)
Jan 12 2019
On Sunday, 13 January 2019 at 04:04:14 UTC, Walter Bright wrote:One major takeaway is that the bugs/line are the same regardless of the language used. This means that languages that enable more expression in fewer lines of code result in fewer bugs for the same functionality.Is the data to support this conclusion freely available on the web somewhere? My impression is that Python is considered the easiest language to use. If it has no more bugs per line than a statically typed program that seems to suggest that non-speed-critical work should be done in Python.
Jan 17 2019
On Thu, Jan 17, 2019 at 11:17:18AM +0000, Tony via Digitalmars-d-announce wrote:On Sunday, 13 January 2019 at 04:04:14 UTC, Walter Bright wrote:No, if the number of bugs is truly proportional to the number of lines, then we should all ditch D and write APL instead. :-P T -- Leather is waterproof. Ever see a cow with an umbrella?One major takeaway is that the bugs/line are the same regardless of the language used. This means that languages that enable more expression in fewer lines of code result in fewer bugs for the same functionality.Is the data to support this conclusion freely available on the web somewhere? My impression is that Python is considered the easiest language to use. If it has no more bugs per line than a statically typed program that seems to suggest that non-speed-critical work should be done in Python.
Jan 17 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0I especially like how design by introspection was contrasted with concepts and metaclasses, culminating in "We want to generate more smart code, not more boilerplate. We want to generate code that matters." Indeed. But what language features do we already have that are as "bo-riing" as concepts and metaclasses? What I wonder is, with design by introspection and the right mix of other language features (e.g. `alias`, `alias this`, mixins, etc...), what traditional language features can be removed from the compiler and delegated to library facilities? For example, https://theartofmachinery.com/2018/08/13/inheritance_and_polymorphism_2.html Because design by introspection allows us to "assemble programs atomically", perhaps high-level language features like classes and interfaces can become obsolete, and the language itself can be reduced simpler primitives that don't require the overhead of a runtime. Mike
Jan 13 2019
On Monday, 14 January 2019 at 03:58:37 UTC, Mike Franklin wrote:What I wonder is, with design by introspection and the right mix of other language features (e.g. `alias`, `alias this`, mixins, etc...), what traditional language features can be removed from the compiler and delegated to library facilities? For example, https://theartofmachinery.com/2018/08/13/inheritance_and_polymorphism_2.html Because design by introspection allows us to "assemble programs atomically", perhaps high-level language features like classes and interfaces can become obsolete, and the language itself can be reduced simpler primitives that don't require the overhead of a runtime. MikeScheme is probably the language that takes this idea of a minimal "core language" with powerful metaprogramming facilities the furthest, and the result is a fragmented ecosystem that makes writing portable, non-trivial programs close to impossible. (See "The Lisp Curse" [1].) When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)
Jan 13 2019
On 1/13/2019 9:31 PM, Paul Backus wrote:Scheme is probably the language that takes this idea of a minimal "core language" with powerful metaprogramming facilities the furthest, and the result is a fragmented ecosystem that makes writing portable, non-trivial programs close to impossible. (See "The Lisp Curse" [1].) When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)Interesting cites, which provide a basis for why I've opposed AST macros, and why Ddoc and unittest are builtin (and a few other things). Also, before std::string came along in C++, everyone invented their own string class, and as a result, nobody could share code.
Jan 13 2019
On Monday, 14 January 2019 at 07:50:32 UTC, Walter Bright wrote:On 1/13/2019 9:31 PM, Paul Backus wrote:This is exactly the argument to get a database driver (mysql,postgres...) and probably a webserver in std. But to avoid getting std.lib to big, the D Foundation might adopt some third party libs as core libraries, so they get maintained within the D Foundation Git account to make them somehow official. We are now approaching the 1500 Dub package, and the ecosystem becomes more and more complex. (https://code.dlang.org/ 1482 packages: The search for mysql now returns 23 packages. Please tell me which to use for the back end, of your own vibe.d app. I give you 5 minutes...:-) Regards mt.Scheme is probably the language that takes this idea of a minimal "core language" with powerful metaprogramming facilities the furthest, and the result is a fragmented ecosystem that makes writing portable, non-trivial programs close to impossible. (See "The Lisp Curse" [1].) When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)Interesting cites, which provide a basis for why I've opposed AST macros, and why Ddoc and unittest are builtin (and a few other things). Also, before std::string came along in C++, everyone invented their own string class, and as a result, nobody could share code.
Jan 14 2019
On 1/14/19 5:18 AM, Martin Tschierschke wrote:On Monday, 14 January 2019 at 07:50:32 UTC, Walter Bright wrote:I don't like the idea of it, because there are so many approaches. Even different approaches among one server protocol.On 1/13/2019 9:31 PM, Paul Backus wrote:This is exactly the argument to get a database driver (mysql,postgres...) and probably a webserver in std.Scheme is probably the language that takes this idea of a minimal "core language" with powerful metaprogramming facilities the furthest, and the result is a fragmented ecosystem that makes writing portable, non-trivial programs close to impossible. (See "The Lisp Curse" [1].) When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)Interesting cites, which provide a basis for why I've opposed AST macros, and why Ddoc and unittest are builtin (and a few other things). Also, before std::string came along in C++, everyone invented their own string class, and as a result, nobody could share code.But to avoid getting std.lib to big, the D Foundation might adopt some third party libs as core libraries, so they get maintained within the D Foundation Git account to make them somehow official. We are now approaching the 1500 Dub package, and the ecosystem becomes more and more complex.This is true, I searched yesterday for a decimal package that fits my use case (I'm getting decimal numbers as strings in a JSON library, with no limits as to what number of decimal places are supported). There were probably 4 or 5 that implement the general concept of a decimal type, but I was faced with a couple issues: 1. Is it maintained? Some of them are really old, some are old-ish, but could potentially be pretty stable 2. Does it have all the features I want? I am hesitant at this point to select something that has overflow problems, because I don't actually know how much would be too much. With one central package, I can be sure that 1 is answered, but then I don't actually have any choices for whether it works for me or not. If it doesn't implement the features I want (basically, I want completely arbitrary precision AND number of digits), then I still have to roll my own. Some packages are hard to solve every, if not most, requirements. Really that should be the defining feature of whether it goes into the standard library.(https://code.dlang.org/ 1482 packages: The search for mysql now returns 23 packages. Please tell me which to use for the back end, of your own vibe.d app. I give you 5 minutes...:-) Regards mt.That's a bad example :) The clear answer is mysql-native, which is what vibe.d recommends. -Steve
Jan 14 2019
On 2019-01-14 15:42, Steven Schveighoffer wrote:That's a bad example :) The clear answer is mysql-native, which is what vibe.d recommends.Exactly, and I don't need five minutes for that. Five seconds is enough :) -- /Jacob Carlborg
Jan 14 2019
On Monday, 14 January 2019 at 18:52:02 UTC, Jacob Carlborg wrote:On 2019-01-14 15:42, Steven Schveighoffer wrote:Ok, bad example, but let's say you want ORM mapping, too and to have the ability to switch to Postgres later? So what would you recommend?That's a bad example :) The clear answer is mysql-native, which is what vibe.d recommends.Exactly, and I don't need five minutes for that. Five seconds is enough :)
Jan 15 2019
On 1/15/19 4:37 AM, Martin Tschierschke wrote:On Monday, 14 January 2019 at 18:52:02 UTC, Jacob Carlborg wrote:I should have said that your point is mostly correct, just that this is a bad example :) I've looked for ORM on code.dlang.org, and never found one yet that I liked. So the answer would take infinite seconds to complete. But let's say we put ORM into Phobos. Certainly, it would get heavy use, but I would be likely to believe that it would not cover the problem space completely, and leave quite a bit to be desired. I think that there are some things that can go into the standard library and live there happily. There are other things that should be left to the community, even though they are essential, simply because locking into one implementation/API/idea is too restrictive. -SteveOn 2019-01-14 15:42, Steven Schveighoffer wrote:Ok, bad example, but let's say you want ORM mapping, too and to have the ability to switch to Postgres later? So what would you recommend?That's a bad example :) The clear answer is mysql-native, which is what vibe.d recommends.Exactly, and I don't need five minutes for that. Five seconds is enough :)
Jan 16 2019
On Wednesday, 16 January 2019 at 14:59:20 UTC, Steven Schveighoffer wrote:On 1/15/19 4:37 AM, Martin Tschierschke wrote:+1 I'm waiting, for example, for a revamp of IO, just to start... --- Paolo[...]I should have said that your point is mostly correct, just that this is a bad example :) I've looked for ORM on code.dlang.org, and never found one yet that I liked. So the answer would take infinite seconds to complete. But let's say we put ORM into Phobos. Certainly, it would get heavy use, but I would be likely to believe that it would not cover the problem space completely, and leave quite a bit to be desired. I think that there are some things that can go into the standard library and live there happily. There are other things that should be left to the community, even though they are essential, simply because locking into one implementation/API/idea is too restrictive. -Steve
Jan 16 2019
On 1/16/19 10:06 AM, Paolo Invernizzi wrote:I'm waiting, for example, for a revamp of IO, just to start...We're working on it... https://github.com/schveiguy/iopipe https://github.com/MartinNowak/io -Steve
Jan 16 2019
On Wednesday, 16 January 2019 at 16:30:17 UTC, Steven Schveighoffer wrote:On 1/16/19 10:06 AM, Paolo Invernizzi wrote:I was exactly referring to that two... they are great, and I've used both! Despite that, they seem stalled: any plan to go ahead in the medium term? Thanks for your work (and to Martin too) --- PaoloI'm waiting, for example, for a revamp of IO, just to start...We're working on it... https://github.com/schveiguy/iopipe https://github.com/MartinNowak/io -Steve
Jan 16 2019
On 1/16/19 11:43 AM, Paolo Invernizzi wrote:On Wednesday, 16 January 2019 at 16:30:17 UTC, Steven Schveighoffer wrote:Slowly... Sorry, it's not my day job to improve these :) But I am working currently on an http client using iopipe (https://github.com/schveiguy/httpiopipe) and improving/releasing the json parser that I wrote for my talk 2 years ago (https://github.com/schveiguy/jsoniopipe). Hint: I hope to have a working REST client soon. I also have a library that's stalled, but I have to pick it up again in order to deal with parsing using ranges (not yet published). I think in order to make this more palatable, though, we really do need to focus on the io base with some sort of async fiber-based driver.On 1/16/19 10:06 AM, Paolo Invernizzi wrote:I was exactly referring to that two... they are great, and I've used both! Despite that, they seem stalled: any plan to go ahead in the medium term?I'm waiting, for example, for a revamp of IO, just to start...We're working on it... https://github.com/schveiguy/iopipe https://github.com/MartinNowak/ioThanks for your work (and to Martin too)You're welcome! Thanks for the kind words. It's actually one of the more fun projects I have worked on. -Steve
Jan 16 2019
On Monday, 14 January 2019 at 10:18:34 UTC, Martin Tschierschke wrote:This is exactly the argument to get a database driver (mysql,postgres...) and probably a webserver in std.Absolutely not! Please... IMHO, what needs to be in std are just APIs (modules, interfaces, declarations)... Leave the implementations elsewhere please. Standard library is already too large for my taste! What should be in std are just core stuff that is needed everywhere. However, the REFERENCE IMPLEMENTATIONS of these APIs could be, and in fact SHOULD be, in a set of higher-level implementation libraries that should be developed by the D Foundation, and available on the dlang.org for downloads. (part of some kind of Standard Library Suite)
Jan 16 2019
On Wednesday, 16 January 2019 at 11:35:15 UTC, Dejan Lekic wrote:On Monday, 14 January 2019 at 10:18:34 UTC, Martin Tschierschke wrote:Depends on what you consider core stuff. I don't think webserver should be a part of the standard library, but I think stuff like sockets, XML and JSON should. Serialization? Debatable. Database driver? Maybe not specific backends, but there could be a generic driver interface.This is exactly the argument to get a database driver (mysql,postgres...) and probably a webserver in std.Absolutely not! Please... IMHO, what needs to be in std are just APIs (modules, interfaces, declarations)... Leave the implementations elsewhere please. Standard library is already too large for my taste! What should be in std are just core stuff that is needed everywhere.
Jan 16 2019
On 2019-01-14 08:50, Walter Bright wrote:Interesting cites, which provide a basis for why I've opposed AST macros, and why Ddoc and unittest are builtin (and a few other things).But Ddoc has macros ;) -- /Jacob Carlborg
Jan 14 2019
On 1/14/2019 10:49 AM, Jacob Carlborg wrote:But Ddoc has macros ;)Indeed it does. But the macros cannot be used to create syntax, and there is no token concatenation. Macros cannot define other macros.
Jan 14 2019
On 2019-01-14 23:52, Walter Bright wrote:On 1/14/2019 10:49 AM, Jacob Carlborg wrote:The AST macros I've been talking about have never been able to create new syntax. -- /Jacob CarlborgBut Ddoc has macros ;)Indeed it does. But the macros cannot be used to create syntax, and there is no token concatenation. Macros cannot define other macros.
Jan 15 2019
On 1/15/2019 1:10 AM, Jacob Carlborg wrote:The AST macros I've been talking about have never been able to create new syntax.Template expressions can't, either, but what they do is hijack the syntax for completely different purposes. The poor reader will be looking at code, and it will behave nothing like the syntax suggests.
Jan 15 2019
On 2019-01-15 12:53, Walter Bright wrote:Template expressions can't, either, but what they do is hijack the syntax for completely different purposes. The poor reader will be looking at code, and it will behave nothing like the syntax suggests.Ah, you mean like this: struct MyInt { private int value; MyInt add(MyInt other) { return MyInt(value - other.value); } } Perhaps we shouldn't support user defined types or functions either ;) -- /Jacob Carlborg
Jan 15 2019
On 1/15/2019 10:39 AM, Jacob Carlborg wrote:Perhaps we shouldn't support user defined types or functions either ;)You deliberately wrote that, and I'm confident you'd never try to pass that off as good work. With macros, however, programmers are convinced they are creating models of clarity. I've seen programmers truly believe: #define BEGIN { #define END } improves their C code. Fortunately, that was ridiculed out of existence in the 1980s, but the more subtle abuses persist with their ardent defenders. I used to use a lot of macros in my C code, and a few years back made an effort to remove them all from the dmd source code. The result was very satisfactory. I've seen entire code bases abandoned because of macros after the original developer left.
Jan 15 2019
On Wednesday, 16 January 2019 at 05:32:51 UTC, Walter Bright wrote:On 1/15/2019 10:39 AM, Jacob Carlborg wrote:I'm pretty sure Jacob is talking about a completely different type of macro (i.e. not textual substitution), AST macros. I'd be interested to see how close we could get if we allowed mixin template to contain expression as well as declarations (obviously these could only be instantiated in function contexts). Anyway something to play around with at DConf.Perhaps we shouldn't support user defined types or functions either ;)You deliberately wrote that, and I'm confident you'd never try to pass that off as good work. With macros, however, programmers are convinced they are creating models of clarity. I've seen programmers truly believe: #define BEGIN { #define END } improves their C code. Fortunately, that was ridiculed out of existence in the 1980s, but the more subtle abuses persist with their ardent defenders. I used to use a lot of macros in my C code, and a few years back made an effort to remove them all from the dmd source code. The result was very satisfactory. I've seen entire code bases abandoned because of macros after the original developer left.
Jan 15 2019
On 1/15/2019 11:08 PM, Nicholas Wilson wrote:I'm pretty sure Jacob is talking about a completely different type of macro (i.e. not textual substitution), AST macros.I understand he means AST macros, but they aren't fundamentally different in the characteristic I'm talking about.I'd be interested to see how close we could get if we allowed mixin template to contain expression as well as declarations (obviously these could only be instantiated in function contexts). Anyway something to play around with at DConf.I won't discourage you to play around with it, but I don't think it's what D needs in the near future.
Jan 16 2019
On 2019-01-16 08:08, Nicholas Wilson wrote:I'm pretty sure Jacob is talking about a completely different type of macro (i.e. not textual substitution), AST macros.Yeah, I should come up with a new name than "macro". A soon as Walter sees the word "macro", regardless of its meaning in the context, he will throw his hands in the air and run the other way. -- /Jacob Carlborg
Jan 16 2019
On 2019-01-16 06:32, Walter Bright wrote:You deliberately wrote that, and I'm confident you'd never try to pass that off as good work.Yes. I'm showing it's possible to write bad code in all programming languages with all (most) features. Macros are not required for that.With macros, however, programmers are convinced they are creating models of clarity. I've seen programmers truly believe: #define BEGIN { #define END } improves their C code. Fortunately, that was ridiculed out of existence in the 1980s, but the more subtle abuses persist with their ardent defenders. I used to use a lot of macros in my C code, and a few years back made an effort to remove them all from the dmd source code. The result was very satisfactory. I've seen entire code bases abandoned because of macros after the original developer left.D has done a great job of replacing the C preprocessor with alternative features. These include: "import", "debug" and "version". These features are great and don't need much improvement. They take care of the stuff that is really difficult to avoid the preprocessor in C for. Then we have the other stuff: macros. To insert code at the instantiation point. For this, D has string mixins and template mixins. This is where D is lacking some features. For example, it's not possible to insert a symbol with a string mixin that the surrounding scope at the instantiation point cannot access. For example, you want to insert two symbols, but the surrounding code should only have access to one of the symbols, the other one is a helper symbol to the first one. This is not possible today. Unfortunately that doesn't stop anyone from trying to come up with there own workarounds and solutions, like generating some obfuscated symbol name. It's not gonna make it less accessible, just less likely to collide with an existing symbol. It's also not possible to insert a symbol that refers to another symbol in another module without risking a symbol conflict in the local scope. There's a word for this, mixins are not hygienic. While D improves a lot on the C preprocessor it didn't reach all the way to cross the finish line. -- /Jacob Carlborg
Jan 16 2019
On Monday, 14 January 2019 at 05:31:27 UTC, Paul Backus wrote:When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)I think D's structs are a sufficient object system for such a focal point. With design by introspection, `alias`, templates, `alias this`, `static if`, CTFE, mixins, and a few new D features, classes would be unnecessary. Rust and Zig are pretty good examples of this. D's implementation could even be improved to keep its runtime, yet still allow D to be used as I'm suggesting, without introducing any breakage for anyone. I made some significant progress in that direction when I was working on the compiler in the 2017~2018 timeframe, but my abilities ultimately fell short, and I couldn't see a way forward without support. Mike
Jan 14 2019
On Monday, 14 January 2019 at 10:06:48 UTC, Mike Franklin wrote:On Monday, 14 January 2019 at 05:31:27 UTC, Paul Backus wrote:Do people really use Rust in production beyond the safety die hards (of course Mozilla and few uses here and there, mostly C guys...lowlevel purists)? Its such a weird,complicated and academic lang... doubt it'll ever be mainstream like D is supposed to be.When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)I think D's structs are a sufficient object system for such a focal point. With design by introspection, `alias`, templates, `alias this`, `static if`, CTFE, mixins, and a few new D features, classes would be unnecessary. Rust and Zig are pretty good examples of this.
Jan 14 2019
On Monday, 14 January 2019 at 13:07:35 UTC, aberba wrote:Do people really use Rust in production beyond the safety die hards (of course Mozilla and few uses here and there, mostly C guys...lowlevel purists)? Its such a weird,complicated and academic lang... doubt it'll ever be mainstream like D is supposed to be.Actually, a lot of people do. Many big companies are getting interested in Rust and many game developers are investigating its capabilities. Rust seems to be mostly appealing to C/C++ programmers who are looking for an alternative.
Jan 14 2019
On Monday, 14 January 2019 at 10:06:48 UTC, Mike Franklin wrote:On Monday, 14 January 2019 at 05:31:27 UTC, Paul Backus wrote:Killing classes will kill my interest and investment in D. Alex.When something like an object system is made part of the language (or at the very least, the standard library), it becomes a focal point [2] that the community can coordinate around. Due to the diverse, distributed nature of any programming-language community, trying to coordinate through explicit communication is not really a viable option, so having these kinds of focal points is very important if we want to be able to work together on anything. [1] http://winestockwebdesign.com/Essays/Lisp_Curse.html [2] https://en.wikipedia.org/wiki/Focal_point_(game_theory)I think D's structs are a sufficient object system for such a focal point. With design by introspection, `alias`, templates, `alias this`, `static if`, CTFE, mixins, and a few new D features, classes would be unnecessary. Rust and Zig are pretty good examples of this. D's implementation could even be improved to keep its runtime, yet still allow D to be used as I'm suggesting, without introducing any breakage for anyone. I made some significant progress in that direction when I was working on the compiler in the 2017~2018 timeframe, but my abilities ultimately fell short, and I couldn't see a way forward without support. Mike
Jan 14 2019
On Monday, 14 January 2019 at 14:59:03 UTC, 12345swordy wrote:On Monday, 14 January 2019 at 10:06:48 UTC, Mike Franklin wrote:He's not saying "kill classes in D", he's saying an OOP system in D could be implemented from primitives and classes don't need to be a language feature, similar to CLOS in Common Lisp.On Monday, 14 January 2019 at 05:31:27 UTC, Paul Backus wrote:Killing classes will kill my interest and investment in D. Alex.[...]I think D's structs are a sufficient object system for such a focal point. With design by introspection, `alias`, templates, `alias this`, `static if`, CTFE, mixins, and a few new D features, classes would be unnecessary. Rust and Zig are pretty good examples of this. D's implementation could even be improved to keep its runtime, yet still allow D to be used as I'm suggesting, without introducing any breakage for anyone. I made some significant progress in that direction when I was working on the compiler in the 2017~2018 timeframe, but my abilities ultimately fell short, and I couldn't see a way forward without support. Mike
Jan 15 2019
On Tue, 15 Jan 2019 11:59:58 +0000, Atila Neves wrote:He's not saying "kill classes in D", he's saying an OOP system in D could be implemented from primitives and classes don't need to be a language feature, similar to CLOS in Common Lisp.As long as the syntax and behavior don't change, the error messages are good, and the compile-time overhead is similar, I won't complain.
Jan 15 2019
On Tuesday, 15 January 2019 at 11:59:58 UTC, Atila Neves wrote:He's not saying "kill classes in D", he's saying an OOP system in D could be implemented from primitives and classes don't need to be a language feature, similar to CLOS in Common Lisp.For some people writing OOP means writing keyword class.
Jan 15 2019
On Tuesday, 15 January 2019 at 17:29:12 UTC, welkam wrote:On Tuesday, 15 January 2019 at 11:59:58 UTC, Atila Neves wrote:I am not interested in OOP as a library feature rather then a built in feature. Let not repeat the same mistakes as c++. If there were a dip that involves deprecating class, expect me to be very vocal in regards to opposing it.He's not saying "kill classes in D", he's saying an OOP system in D could be implemented from primitives and classes don't need to be a language feature, similar to CLOS in Common Lisp.For some people writing OOP means writing keyword class.
Jan 15 2019
On 1/15/2019 11:39 AM, 12345swordy wrote:If there were a dip that involves deprecating class,I wouldn't worry about that getting very far :-)
Jan 16 2019
On Monday, 14 January 2019 at 05:31:27 UTC, Paul Backus wrote:[1] http://winestockwebdesign.com/Essays/Lisp_Curse.htmlThis part always feels familiar to me in D (just replace Lisp with D and Haskell with say Rust): Answer: The Lisp Curse kicks in. Every second or third serious Lisp hacker will roll his own implementation of lazy evaluation, functional purity, arrows, pattern matching, type inferencing, and the rest. Most of these projects will be lone-wolf operations. Thus, they will have eighty percent of the features that most people need (a different eighty percent in each case). They will be poorly documented. They will not be portable across Lisp systems. Some will show great promise before being abandoned while the project maintainer goes off to pay his bills. Several will beat Haskell along this or that dimension (again, a different one in each case), but their acceptance will be hampered by flame wars on the comp.lang.lisp Usenet group. also this one: I saw this 10 years ago when looking for a GUI to my Lisp. No problem, there were 9 different offerings. The trouble was that none of the 9 were properly documented and none were bug free. Basically each person had implemented his own solution and it worked for him so that was fine.
Jan 14 2019
On Monday, 14 January 2019 at 05:31:27 UTC, Paul Backus wrote:Scheme is probably the language that takes this idea of a minimal "core language" with powerful metaprogramming facilities the furthest, and the result is a fragmented ecosystem that makes writing portable, non-trivial programs close to impossible. (See "The Lisp Curse" [1].)Much as I hate to disagree with folks on the internet, this is an explanation in search of an example. Scheme was originally created as a toy language so Steele and Sussman could have an object oriented language with actors.[1] It later turned out to be a good language for SICP. Macros did not even appear in the Scheme standard until R4RS, and they were not part of the standard until R5RS in 1998, 23 years after initial work started on Scheme. That's not to say that individual implementations didn't have Common Lisp macros prior to R5RS, but the metaprogramming thing was more of a Common Lisp thing than a Scheme thing. To me, it's obvious why Scheme has never taken off. It wasn't created as a language for widespread commercial usage. That was the realm of Common Lisp, and to some extent Common Lisp succeeded. CL was not killed by excessive use of macros. I'll also note that R started as a dialect of Scheme, but it was designed for practical use from the start, and it has millions of users. D has little hope of ever achieving the popularity of R. You can do all kinds of metaprogramming with R. I got tired of R's lack of proper tail call support, so added a working implementation of Clojure's recur in a couple of hours. Extrapolating from Scheme to D is simply not the best use of one's time. [1] See page 33 of https://dreamsongs.com/Files/HOPL2-Uncut.pdf
Jan 14 2019
On Monday, 14 January 2019 at 03:58:37 UTC, Mike Franklin wrote:Because design by introspection allows us to "assemble programs atomically", perhaps high-level language features like classes and interfaces can become obsolete, and the language itself can be reduced simpler primitives that don't require the overhead of a runtime.Only a small sliver of programming involves anything where "overhead of a runtime" is an issue. I hope you intend this comment as pertaining to Better C usage.
Jan 14 2019
On Monday, 14 January 2019 at 14:56:00 UTC, bachmeier wrote:Only a small sliver of programming involves anything where "overhead of a runtime" is an issue. I hope you intend this comment as pertaining to Better C usage.Real D is the true better C. These improvements can improve in various situations. That said though, I'd be against removing built-in classes and interfaces. They are useful in a lot of places built in... though I kinda wish the runtime code was a bit thinner and lighter too.
Jan 14 2019
On 1/14/19 10:57 AM, Adam D. Ruppe wrote:On Monday, 14 January 2019 at 14:56:00 UTC, bachmeier wrote:Some of the old crufty features of classes can be jettisoned like toString and toHash, and object.factory. -SteveOnly a small sliver of programming involves anything where "overhead of a runtime" is an issue. I hope you intend this comment as pertaining to Better C usage.Real D is the true better C. These improvements can improve in various situations. That said though, I'd be against removing built-in classes and interfaces. They are useful in a lot of places built in... though I kinda wish the runtime code was a bit thinner and lighter too.
Jan 14 2019
On Mon, Jan 14, 2019 at 03:57:36PM +0000, Adam D. Ruppe via Digitalmars-d-announce wrote:On Monday, 14 January 2019 at 14:56:00 UTC, bachmeier wrote:Yeah, much as I'm a big promoter of struct-based range-based template style D code, classes and interfaces do still have their place. When you need runtime dynamic polymorphism, it just makes sense to use classes and interfaces instead of trying to bandage your way around structs and CT introspection. I'm still searching for a theoretical model that would bridge the gap between the two and make one unified model, but for now, they each still have their place.Only a small sliver of programming involves anything where "overhead of a runtime" is an issue. I hope you intend this comment as pertaining to Better C usage.Real D is the true better C. These improvements can improve in various situations. That said though, I'd be against removing built-in classes and interfaces. They are useful in a lot of places built in...though I kinda wish the runtime code was a bit thinner and lighter too.Yeah, the whole thing about the monitor field IMO is an unnecessary burden on a use case that isn't always needed. If synchronized classes or whatever needs it, then it should be an ABI specific to synchronized classes. Everybody else shouldn't need to pay tax on it if they never actually need to use it. T -- Shin: (n.) A device for finding furniture in the dark.
Jan 14 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiAbout the adoption and success of DbI libraries: - Buried inside your talks there are lots of hard-earned principles: "What's missing is as important as what's here" "Big interfaces are good" etc... We have a lack of DbI designers such as yourself or Vladimir so a short text that teach how to design with DbI could be in order. I redirect people to "std::allocator is to allocation what std::vector is to vexation" because it seems to be the only tutorial on this. Other people often lack interest because of real or perceived template bloat, and it's critical. - I think it's important to emphasize CTFE over template instantiations because (per Stefan's measurements) template instantiations are a lot slower and CTFE is already surprisingly faster than template meta-programming, and on the road to become even faster with the superbly needed newCTFE.
Jan 14 2019
On Mon, Jan 14, 2019 at 08:38:39PM +0000, Guillaume Piolat via Digitalmars-d-announce wrote: [...]Other people often lack interest because of real or perceived template bloat, and it's critical. - I think it's important to emphasize CTFE over template instantiations because (per Stefan's measurements) template instantiations are a lot slower and CTFE is already surprisingly faster than template meta-programming, and on the road to become even faster with the superbly needed newCTFE.I think another angle of attack that AFAICT has been mostly overlooked is for the compiler to recognize certain common template patterns, and optimize away intermediate template instantiations that are not actually necessary. Not every template instantiation requires wholesale copying of the AST. I surmise certain patterns of templates could be profitably turned into some kind of compile-time executed code. T -- Без труда не выловишь и рыбку из пруда.
Jan 14 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiA lot of the questions were about documenting the hook API and catching misspelling errors when defining a hook. It seems like it would be nice if you could list the hook method names a static array or dictionary or struct containing a field for each method, etc. One each for the required and optional methods. The hook author could grab the name/signature of the method they're intending to implement from that data structure and any misspellings would be caught immediately. Is it possible to declare a function whose name is a CTFE computed string?
Jan 14 2019
On Monday, 14 January 2019 at 21:08:50 UTC, Ben Jones wrote:Is it possible to declare a function whose name is a CTFE computed string?Yes, if you do it with a string mixin.
Jan 14 2019
On Mon, 14 Jan 2019 21:12:48 +0000, Paul Backus wrote:On Monday, 14 January 2019 at 21:08:50 UTC, Ben Jones wrote:And more simply, you can declare a function with a hard-coded name, then use an alias to expose it under a different name.Is it possible to declare a function whose name is a CTFE computed string?Yes, if you do it with a string mixin.
Jan 14 2019
On Monday, 14 January 2019 at 21:08:50 UTC, Ben Jones wrote:On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:For ranges there are concepts like Input Range. A struct/class must have several methods to be compliant. You can check the compliance using function isInputRange https://dlang.org/library/std/range/primitives/is_input_range.html Maybe something similiar can be done here. Not checking individual methods, but concepts... Kind regards Andrehttps://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiA lot of the questions were about documenting the hook API and catching misspelling errors when defining a hook. It seems like it would be nice if you could list the hook method names a static array or dictionary or struct containing a field for each method, etc. One each for the required and optional methods. The hook author could grab the name/signature of the method they're intending to implement from that data structure and any misspellings would be caught immediately. Is it possible to declare a function whose name is a CTFE computed string?
Jan 14 2019
On Monday, 14 January 2019 at 21:22:32 UTC, Andre Pany wrote:On Monday, 14 January 2019 at 21:08:50 UTC, Ben Jones wrote:I don't think that's quite sufficient because a hook may/may not have the optional methods, and could have extra stuff. What you want is to specify per method "this method is part of the hook interface," which as I type it kind of sounds like the job of an annotation...On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:For ranges there are concepts like Input Range. A struct/class must have several methods to be compliant. You can check the compliance using function isInputRange https://dlang.org/library/std/range/primitives/is_input_range.html Maybe something similiar can be done here. Not checking individual methods, but concepts... Kind regards Andrehttps://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiA lot of the questions were about documenting the hook API and catching misspelling errors when defining a hook. It seems like it would be nice if you could list the hook method names a static array or dictionary or struct containing a field for each method, etc. One each for the required and optional methods. The hook author could grab the name/signature of the method they're intending to implement from that data structure and any misspellings would be caught immediately. Is it possible to declare a function whose name is a CTFE computed string?
Jan 14 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0 If nothing else please watch the opening story, it's true and quite funny :o). Now as to the talk, as you could imagine, it touches on another language as well... AndreiAwesome talk! As usual. Regarding this quote: "The ruby guy next to you is writing just as crappy code..." I don't think that's really correct. The reference is code complete, which is published in 93 (i.e. no java, no ruby, before the stl even?) and i believe (just googled this so may be wrong) the reference in that book is from a 1977 paper on programmer quality and productivity and the 2004 edition of code complete changes the number form 15 to 50 / 1000 to 1 .. 25 / 1000, but references the same paper afaik. Here's a more recent study: http://rayb.info/uploads/cacm2017-lang.pdf Here's an article that summarizes it -> https://www.i-programmer.info/news/98-languages/11184-which-languages-are-bug-prone.html Quote from article: "The languages with the strongest positive coefficients - meaning associated with a greater number of defect fixes are C++, C, and Objective-C, also PHP and Python. On the other hand, Clojure, Haskell, Ruby and Scala all have significant negative coefficients implying that these languages are less likely than average to result in defect fixing commits." Also this is more anecdotal, but for example going from objective-c to swift, the number of non-application-specific bugs per line (regardless of whether or not that's even a good measure 🤷♂️), i feel, has gone down by an exaggerated order of magnitude. Cheers, - Ali
Jan 14 2019
On Tuesday, 15 January 2019 at 05:18:45 UTC, aliak wrote:Quote from article: "The languages with the strongest positive coefficients - meaning associated with a greater number of defect fixes are C++, C, and Objective-C, also PHP and Python. On the other hand, Clojure, Haskell, Ruby and Scala all have significant negative coefficients implying that these languages are less likely than average to result in defect fixing commits."Does this take into account the experience of the programmers writing in each language? Given their relative popularity, I imagine PHP and Python have many more beginning programmers writing code in them than Haskell and Clojure.
Jan 14 2019
On Tuesday, 15 January 2019 at 06:57:28 UTC, Paul Backus wrote:On Tuesday, 15 January 2019 at 05:18:45 UTC, aliak wrote:Not that I saw in the paper no. But that is a good point.Quote from article: "The languages with the strongest positive coefficients - meaning associated with a greater number of defect fixes are C++, C, and Objective-C, also PHP and Python. On the other hand, Clojure, Haskell, Ruby and Scala all have significant negative coefficients implying that these languages are less likely than average to result in defect fixing commits."Does this take into account the experience of the programmers writing in each language? Given their relative popularity, I imagine PHP and Python have many more beginning programmers writing code in them than Haskell and Clojure.
Jan 14 2019
On Saturday, 12 January 2019 at 15:51:03 UTC, Andrei Alexandrescu wrote:https://youtube.com/watch?v=tcyb1lpEHm0Now as to the talk, as you could imagine, it touches on anotherSomebody on the C++ side has written a reply.... https://brevzin.github.io/c++/2019/01/15/if-constexpr-isnt-broken/ Although looking at the implementation of std::conditional in the type_traits header makes me sad... I would love to see the whole checkedint thing in C++ side by side with the d code (and generated -Os object code). Conversely I'd love to see a Rust implementation too :-) Given that I have probably written a lot more C++ code in my life than d... ...I do find it remarkable that I can read the d code quite easily without reaching for the reference manual, but to make sense of his C++, it sends me trawling around cppreference.com I find Andrei's claim that checkint with a void hook reverts to int is amazing, and would love to verify that at the assembly level for both the C++ and d implementations.
Jan 16 2019
On Wed, Jan 16, 2019 at 11:43:19PM +0000, John Carter via Digitalmars-d-announce wrote: [...]Given that I have probably written a lot more C++ code in my life than d... ...I do find it remarkable that I can read the d code quite easily without reaching for the reference manual, but to make sense of his C++, it sends me trawling around cppreference.comYes, that's one of the outstanding qualities of D, and one that I was immensely impressed with when I perused the Phobos source code for the first time. After having (tried to) read glibc's source code (if you never have, I advise you not to unless you're a jaded, hardened, hardcore C professional -- it's *not* for the faint of heart), it was like a breath of fresh air. D does have its warts and dark corners, but I think on the readability front it has scored a home run compared to the equivalent C/C++ code.I find Andrei's claim that checkint with a void hook reverts to int is amazing, and would love to verify that at the assembly level for both the C++ and d implementations.This is actually quite trivial in D. I'm too lazy to actually check the checkedint source code, but I'd surmise it's something as simple as: template CheckedInt(alias hook) { static if (is(typeof(hook) == void)) alias CheckedInt = int; else { struct CheckedInt { ... // actual CheckedInt implementation here } } } or something along these lines. Standard D practice. (I daren't even try to imagine what I'd have to do to make this work in C++. After having worked with C++ for about 2 decades or so, I don't have many good things to say about it, nor do I expect very much from it anymore.) T -- Windows 95 was a joke, and Windows 98 was the punchline.
Jan 16 2019
On 1/16/2019 4:19 PM, H. S. Teoh wrote:On Wed, Jan 16, 2019 at 11:43:19PM +0000, John Carter via Digitalmars-d-announce wrote:Bartosz Milewski is a C++ programmer and a Haskell fan. He once gave a presentation at NWCPP where he wrote a few lines of Haskell code. Then, he showed the same code written using C++ template metaprogramming. The Haskell bits in the C++ code were highlighted in red. It was like a sea of grass with a shrubbery here and there. Interestingly, by comparing the red dots in the C++ code with the Haskell code, you could understand what the C++ was doing. Without the red highlighting, it was a hopeless wall of < > :-) Since I mention Bartosz, I should link to his blog: https://bartoszmilewski.com/...I do find it remarkable that I can read the d code quite easily without reaching for the reference manual, but to make sense of his C++, it sends me trawling around cppreference.comYes, that's one of the outstanding qualities of D, and one that I was immensely impressed with when I perused the Phobos source code for the first time.
Jan 16 2019
On Thursday, 17 January 2019 at 01:59:29 UTC, Walter Bright wrote:Bartosz Milewski is a C++ programmer and a Haskell fan. He once gave a presentation at NWCPP where he wrote a few lines of Haskell code. Then, he showed the same code written using C++ template metaprogramming. The Haskell bits in the C++ code were highlighted in red. It was like a sea of grass with a shrubbery here and there. Interestingly, by comparing the red dots in the C++ code with the Haskell code, you could understand what the C++ was doing. Without the red highlighting, it was a hopeless wall of < > :-) Since I mention Bartosz, I should link to his blog: https://bartoszmilewski.com/It was an article on Bartosz's blog where I first found out about D. I think this was the first one: "The more things change, the more we need “immutable”" https://bartoszmilewski.com/2009/01/
Jan 16 2019
On Wed, Jan 16, 2019 at 05:59:29PM -0800, Walter Bright via Digitalmars-d-announce wrote: [...]Bartosz Milewski is a C++ programmer and a Haskell fan. He once gave a presentation at NWCPP where he wrote a few lines of Haskell code. Then, he showed the same code written using C++ template metaprogramming. The Haskell bits in the C++ code were highlighted in red. It was like a sea of grass with a shrubbery here and there. Interestingly, by comparing the red dots in the C++ code with the Haskell code, you could understand what the C++ was doing. Without the red highlighting, it was a hopeless wall of < > :-)[...] I don't know Haskell, but I've worked with Scheme (another Lisp dialect / derivative) a little, and sometimes I feel like the core of my logic is little bits of shrubbery lost in an ocean of parentheses. :-P T -- I don't trust computers, I've spent too long programming to think that they can get anything right. -- James Miller
Jan 17 2019
On Thursday, 17 January 2019 at 01:59:29 UTC, Walter Bright wrote:On 1/16/2019 4:19 PM, H. S. Teoh wrote:Was that a pre C++11 version of C++, or a more modern one? It would be instructive to see that example with C++17 or even 20 and D next to each other.On Wed, Jan 16, 2019 at 11:43:19PM +0000, John Carter via Digitalmars-d-announce wrote:Bartosz Milewski is a C++ programmer and a Haskell fan. He once gave a presentation at NWCPP where he wrote a few lines of Haskell code. Then, he showed the same code written using C++ template metaprogramming. The Haskell bits in the C++ code were highlighted in red. It was like a sea of grass with a shrubbery here and there. Interestingly, by comparing the red dots in the C++ code with the Haskell code, you could understand what the C++ was doing. Without the red highlighting, it was a hopeless wall of < > :-)[...]Yes, that's one of the outstanding qualities of D, and one that I was immensely impressed with when I perused the Phobos source code for the first time.
Jan 17 2019
On Thursday, 17 January 2019 at 16:06:39 UTC, bpr wrote:On Thursday, 17 January 2019 at 01:59:29 UTC, Walter Bright wrote:The presentation was given at BoostCon 2011, and is (at least partially) available on youtube [1]. There is also a blog post from 2009, "What Does Haskell Have to Do with C++?" [2] that uses the same format, and presumably covers the same material. The examples in the blog post were tested with "the GNU C++ compiler v. 4.4.1 with the special switch -std=c++0x", which according to the GCC documentation [3] includes many (but not all) features from C++11. [1] https://www.youtube.com/watch?v=GjhsSzRtTGY [2] https://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/ [3] https://gcc.gnu.org/gcc-4.4/cxx0x_status.htmlBartosz Milewski is a C++ programmer and a Haskell fan. He once gave a presentation at NWCPP where he wrote a few lines of Haskell code. Then, he showed the same code written using C++ template metaprogramming. The Haskell bits in the C++ code were highlighted in red. It was like a sea of grass with a shrubbery here and there. Interestingly, by comparing the red dots in the C++ code with the Haskell code, you could understand what the C++ was doing. Without the red highlighting, it was a hopeless wall of < > :-)Was that a pre C++11 version of C++, or a more modern one? It would be instructive to see that example with C++17 or even 20 and D next to each other.
Jan 17 2019
FYI, this whole subthread of B Revzin is NOT in my newsgroup reader. I only saw it because I was browsing the forum web page. What happened? -Steve
Jan 17 2019
On Thu, Jan 17, 2019 at 06:03:07PM +0000, Paul Backus via Digitalmars-d-announce wrote: [...][2] https://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/[...] Haha, seems D did better than C++ in this respect, but not quite at the level of Haskell. The C++ example of a template that takes templates and arguments and declares another template is a perfect example of why C++ template syntax is utterly horrible for doing these sorts of things. Coming back to the D example at the end, I totally agree with the sentiment that D templates, in spite of their significant improvements over C++ syntax, ultimately still follow the same recursive model. Yes, you can use CTFE to achieve the same thing at runtime, but it's not the same thing, and CTFE cannot manipulate template argument lists (aka AliasSeq aka whatever it is you call them). This lack of symmetry percolates down the entire template system, leading to the necessity of the hack that Bartosz refers to. Had template argument lists / AliasSeq been symmetric w.r.t. runtime list manipulation, we would've been able to write a foreach loop that manipulates the AliasSeq in the most readable way without needing to resort to hacks or recursive templates. // Lately, as I've been pondering over these fundamental language design issues, I've become more and more convinced that symmetry is the way to go. And by symmetry, I mean the mathematical sense of being "the same under some given mapping (i.e., transformation or substitution)". Why is C++ template syntax such a mess to work with? Because it's a separate set of syntax and idioms grafted onto the original core language with little or no symmetry between them. Where the core language uses < and > as comparison operators, template syntax uses < and > as delimiters. This asymmetry leads to all kinds of nastiness, like earlier versions of C++ being unable to parse `templateA<templateB<int>>` properly (the >> gets wrongly lexed as a bitshift operator). An intervening space is required to work around this asymmetry. This is just one trivial example. A more fundamental example, which also afflicts D, is that the template instantiation mechanism is inherently recursive rather than iterative, so when you need to write a loop, you have to paraphrase it as a recursive template. This is asymmetric with the runtime part of the language, where constructs like `foreach` are readily available to express the desired semantics. On a different note, the same principle of symmetry applies to built-in types vs. user-defined types. In TDPL Andrei alludes to programmers disliking built-in types having "magic" behaviour that's different from user-defined types. Why the dislike? Because of asymmetry. Built-in types have special behaviour that cannot be duplicated by user-defined types, so when you want the special behaviour but built-in types don't quite meet your needs, you find yourself without any recourse. It is frustrating because the reasoning goes "if built-in type X can have magic behaviour B, why can't user-defined type Y have behaviour B too?" The desire for behaviour B to be possible both for built-in types and user-defined types stems from the desire for symmetry. Why is alias this so powerful? Because it lets a new type Y behave as if it were an existing type X -- it's symmetry. Similarly, the Liskov Substitution Principle is essentially a statement of symmetry in the universe of OO polymorphism. Why is the Unix "everything is a file" abstraction so useful? Because of symmetry: whether it's a physical file, a network socket, or pipe, it exposes the same API. Code that works with the data don't have to care about what kind of object it is; it can simply use the API that is symmetric across different types of objects. Similarly, why are D ranges so powerful? Because they make containers, data sources, data generators, etc., symmetric under the range API operations. It allows code to be decoupled from the details of the concrete types, and focus directly on the problem domain. Why does the GC simplify many programming tasks so much? Because it makes every memory-allocated object symmetric w.r.t. memory management: you stop worrying about whether something is stack-allocated or heap-allocated, whether it has cycles, or whether somebody else still holds a reference to it -- you focus on the problem domain and let the GC do its job. At a higher level: in the old days, programming languages used to distinguish between functions and procedures (and maybe some languages still do, but they seem rare these days). But eventually this distinction was ditched in favor of things like returning `void` (C, C++, Java, D), or some other equivalent construct. Why? So that instead of having two similar but asymmetric units of code encapsulation, everything is just a "function" (it just so happens some functions don't return a meaningful value). IOW, introduce symmetry, get rid of the asymmetry. On the flip side, when there is lack of symmetry, many problems arise. I already mentioned C++ template syntax and how it's asymmetric w.r.t. the imperative part of the language. The recursive nature of templates in both C++ and D, as opposed to iterative runtime constructs like foreach, is another example of asymmetry that leads to ugly / convoluted code where the corresponding runtime code has no such issue. Auto-decoding is another prime example of asymmetry causing problems: all other arrays are ranges of their element type, but narrow strings are not. While it still does support the range API (and is symmetric in that sense with other ranges), this internal asymmetry causes all sorts of trouble: performance troubles, tons of special-case code (just look at Phobos range algorithms and see how many special cases pertain to narrow strings -- and how many bugs were caused in the interim), introducing a difference between .count and .indexOf (it's the reason for the very existence of .indexOf where .count would have sufficed, had narrow strings been symmetric in range element type w.r.t. other ranges). There's also APIs that are hard to use because they are asymmetric to other APIs that you happen to be using. For example, if a hypothetical D library sported an API that used .next and .empty instead of the standard .empty, .front, .popFront, then the asymmetry with the range API common throughout D code would cause all sorts of impedance mismatch problems. And one would naturally gravitate towards writing a wrapper around this incompatible API that replicated the range API. IOW, you fix the problem by *introducing symmetry* where there was asymmetry. A more minor point is the overloading of keywords to mean different things, like `void` meaning "does not return" in one context, yet in a different context `void*` means "can point to anything". Or the various overloaded meanings of `static` in D, which is a rat's nest of strange exceptions and ad hoc semantics that have no real pattern, you just have to separately learn what it means in each context. Also, the asymmetry of function attributes (there is `pure`, but no `impure`; there's `nothrow` but not `throwing`, you write safe with a but pure doesn't have a ). A mostly minor syntactical point, but it seems to keep coming up every time somebody new encounters them, and the complaints seem disproportionate to the actual importance of the issue. Why? Asymmetry. And in some cases, it leads to not-so-trivial issues (which I won't repeat here). And the oft-proposed solution? Introduce symmetry. And operator overloading. In spite of all the problems associated with operator overloading, it's still practically a necessity when you're implementing arithmetical types. A matrix library in C requires very ugly syntax to work with; in C++ and D, we naturally gravitate towards operator overloading. Why? Because we desire symmetry with built-in arithmetic types. Sure I could write: result = prod(matrix1, sub(matrix2, matrix3)); but I would much rather write: result = matrix1 * (matrix2 - matrix3); And why UFCS? Because of symmetry: every subsequent operation on a range can be written as syntactically top-level function call, rather than the asymmetry of nesting every operation inside the previous one: myrange.map!(...) .filter!(...) .joiner .array; vs. array(joiner(filter!(...)(map!(...)(myrange)))); I could go on and on. But this principle of symmetry seems to me to underlie many fundamental language design issues. There seems to be a general trend where the more symmetry there is, the smoother a language feature will be and the less problems will be caused; whereas the less symmetry there is, the more troubles, ugly workarounds, tendency towards bugs, or just general unhappiness there will be. I don't know if it's possible for a programming language to be *completely* symmetrical -- maybe Lisp and Haskell come pretty close -- but the further you deviate from symmetry, the more troubles you can expect. As a corollary, with every new language change, it would be worthwhile to evaluate how it affects the overall symmetry of the language. Does it add more symmetry, or does it introduce asymmetry (syntactic, semantic, etc.) w.r.t. existing features? It seems to me that people rarely consider this aspect of language design, esp. when they are trying to fix what they perceive to be an important oversight in the language, but IMO the issue of symmetry is certainly worth careful consideration alongside the other usual factors. T -- English has the lovely word "defenestrate", meaning "to execute by throwing someone out a window", or more recently "to remove Windows from a computer and replace it with something useful". :-) -- John Cowan
Jan 17 2019
On 1/17/19 2:31 PM, H. S. Teoh wrote:On Thu, Jan 17, 2019 at 06:03:07PM +0000, Paul Backus via Digitalmars-d-announce wrote: [...]well, there was no static foreach for that article (which I admit I didn't read, but I know what you mean). But it's DEFINITELY not as easy as it could be: import std.conv; alias AliasSeq(P...) = P; template staticMap(alias Transform, Params...) { alias seq0 = Transform!(Params[0]); static foreach(i; 1 .. Params.length) { mixin("alias seq" ~ i.to!string ~ " = AliasSeq!(seq" ~ (i-1).to!string ~ ", Transform!(Params[" ~ i.to!string ~ "]));"); } mixin("alias staticMap = seq" ~ (Params.length-1).to!string ~ ";"); } alias Constify(T) = const(T); void main() { alias someTypes = AliasSeq!(int, char, bool); pragma(msg, staticMap!(Constify, someTypes)); // (const(int), const(char), const(bool)) } Note, that this would be a LOT easier with string interpolation... mixin("alias seq${i} = AliasSeq!(seq${i-1}, Transform!(Params[${i}]));".text); -Steve[2] https://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/[...] Haha, seems D did better than C++ in this respect, but not quite at the level of Haskell. The C++ example of a template that takes templates and arguments and declares another template is a perfect example of why C++ template syntax is utterly horrible for doing these sorts of things. Coming back to the D example at the end, I totally agree with the sentiment that D templates, in spite of their significant improvements over C++ syntax, ultimately still follow the same recursive model. Yes, you can use CTFE to achieve the same thing at runtime, but it's not the same thing, and CTFE cannot manipulate template argument lists (aka AliasSeq aka whatever it is you call them). This lack of symmetry percolates down the entire template system, leading to the necessity of the hack that Bartosz refers to. Had template argument lists / AliasSeq been symmetric w.r.t. runtime list manipulation, we would've been able to write a foreach loop that manipulates the AliasSeq in the most readable way without needing to resort to hacks or recursive templates.
Jan 17 2019
On Thursday, 17 January 2019 at 20:47:38 UTC, Steven Schveighoffer wrote:well, there was no static foreach for that article (which I admit I didn't read, but I know what you mean). But it's DEFINITELY not as easy as it could be: import std.conv; alias AliasSeq(P...) = P; template staticMap(alias Transform, Params...) { alias seq0 = Transform!(Params[0]); static foreach(i; 1 .. Params.length) { mixin("alias seq" ~ i.to!string ~ " = AliasSeq!(seq" ~ (i-1).to!string ~ ", Transform!(Params[" ~ i.to!string ~ "]));"); } mixin("alias staticMap = seq" ~ (Params.length-1).to!string ~ ";"); } alias Constify(T) = const(T); void main() { alias someTypes = AliasSeq!(int, char, bool); pragma(msg, staticMap!(Constify, someTypes)); // (const(int), const(char), const(bool)) } Note, that this would be a LOT easier with string interpolation... mixin("alias seq${i} = AliasSeq!(seq${i-1}, Transform!(Params[${i}]));".text); -SteveWhy not do away with AliasSeq and use strings all the way? string Constify(string type) { // can add input checks here return "const(" ~ type ~ ")"; } void main() { import std.algorithm : map; enum someTypes = ["int", "char", "bool"]; enum constTypes = map!Constify(someTypes); mixin(constTypes[0] ~ "myConstInt = 42;"); // int myConstInt = 42; } Represent types as strings, CTFE them as you see fit, and output a string that can then be mixin'ed to use the actual type. :)
Jan 18 2019
On Fri, Jan 18, 2019 at 08:03:48PM +0000, Mark via Digitalmars-d-announce wrote: [...]Why not do away with AliasSeq and use strings all the way? string Constify(string type) { // can add input checks here return "const(" ~ type ~ ")"; } void main() { import std.algorithm : map; enum someTypes = ["int", "char", "bool"]; enum constTypes = map!Constify(someTypes); mixin(constTypes[0] ~ "myConstInt = 42;"); // int myConstInt = 42; } Represent types as strings, CTFE them as you see fit, and output a string that can then be mixin'ed to use the actual type. :)That would work, but it would also suffer from all the same problems as macro-based programming in C. The compiler would be unable to detect when you accidentally pasted type names together where you intended to be separate, the strings may not actually represent real types, and generating code from pasting / manipulating strings is very error-prone. And you could write very unmaintainable code like pasting partial tokens together as strings, etc., which makes it hard for anyone else (including yourself after 3 months) to understand just what the code is trying to do. Generally, you want some level of syntactic / semantic enforcement by the compiler when you manipulate lists (or whatever other structures) of types. T -- INTEL = Only half of "intelligence".
Jan 18 2019
On Friday, 18 January 2019 at 20:29:08 UTC, H. S. Teoh wrote:That would work, but it would also suffer from all the same problems as macro-based programming in C. The compiler would be unable to detect when you accidentally pasted type names together where you intended to be separate, the strings may not actually represent real types, and generating code from pasting / manipulating strings is very error-prone. And you could write very unmaintainable code like pasting partial tokens together as strings, etc., which makes it hard for anyone else (including yourself after 3 months) to understand just what the code is trying to do. Generally, you want some level of syntactic / semantic enforcement by the compiler when you manipulate lists (or whatever other structures) of types. TWell, it's the approach Andrei laid out in his DConf 2018 talk: https://youtu.be/-0jcE9B5kjs?t=2641 The advantage is how simple it is, and that it only uses existing language constructs. But, indeed, the problems you mention are not insignificant.
Jan 19 2019
On Friday, 18 January 2019 at 20:03:48 UTC, Mark wrote:[...] Represent types as strings, CTFE them as you see fit, and output a string that can then be mixin'ed to use the actual type. :)Two problems: 1) Mixing in a string is unhygienic. If two modules (or two scopes in the same module) define types with the same name, you might get the wrong one. 2) You can't mixin the name of a Voldemort type.
Jan 18 2019
On Thursday, 17 January 2019 at 19:31:24 UTC, H. S. Teoh wrote:On Thu, Jan 17, 2019 at 06:03:07PM +0000, Paul Backus via Digitalmars-d-announce wrote: [...]For 2 years I have pondered this problem, and I did come up with a solution. It's actually not that hard to have CTFE interact with type-tuples. You can pass them as function parameters, or return them if you wish. Of course a type-tuple returning ctfe function, is compile-time only. This solved one more problem that ctfe has: helper functions required for ctfe can only be omitted from the binary, if you use the trick of putting them into a module which is the import path but never explicitly given on the command line. newCTFE has the facility to be extended for this, and implementing type-functions is at least on my personal roadmap. At Dconf 2018 Andrei and Walter said, a DIP which is substantiated enough might make it. However due to lack of time, (and productivity-reducing internal changes) it will take some time until I can get started on this. Also I plan for newCTFE to be in shape before I add type-manipulation abilities. Cheers, Stefan P.S. There is one caveat: because of how type-functions work they cannot, you cannot create a non-anonymous symbol inside a type-function, because there is no way to infer a mangle. You can however create an anonymous symbol and alias it inside a template body, which gives it a mangle and it can behave like a regular symbol.[2] https://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/[...] Coming back to the D example at the end, I totally agree with the sentiment that D templates, in spite of their significant improvements over C++ syntax, ultimately still follow the same recursive model. Yes, you can use CTFE to achieve the same thing at runtime, but it's not the same thing, and CTFE cannot manipulate template argument lists (aka AliasSeq aka whatever it is you call them). This lack of symmetry percolates down the entire template system, leading to the necessity of the hack that Bartosz refers to. Had template argument lists / AliasSeq been symmetric w.r.t. runtime list manipulation, we would've been able to write a foreach loop that manipulates the AliasSeq in the most readable way without needing to resort to hacks or recursive templates.
Jan 17 2019
On Thu, Jan 17, 2019 at 10:20:24PM +0000, Stefan Koch via Digitalmars-d-announce wrote:On Thursday, 17 January 2019 at 19:31:24 UTC, H. S. Teoh wrote:[...]YES! This is the way it should be. Type-tuples become first class citizens, and you can pass them around to functions and return them from functions, the only stipulation being that they can only exist at compile-time, so it's an error to use them at runtime. In other words, they become symmetric to other built-in language types, and can be manipulated by conventional means, instead of being an oddball exception with special-case behaviour that requires special-case syntax dedicated to manipulating them. Again, the root of the problem is asymmetry, and the solution is to make it symmetric.Coming back to the D example at the end, I totally agree with the sentiment that D templates, in spite of their significant improvements over C++ syntax, ultimately still follow the same recursive model. Yes, you can use CTFE to achieve the same thing at runtime, but it's not the same thing, and CTFE cannot manipulate template argument lists (aka AliasSeq aka whatever it is you call them). This lack of symmetry percolates down the entire template system, leading to the necessity of the hack that Bartosz refers to. Had template argument lists / AliasSeq been symmetric w.r.t. runtime list manipulation, we would've been able to write a foreach loop that manipulates the AliasSeq in the most readable way without needing to resort to hacks or recursive templates.For 2 years I have pondered this problem, and I did come up with a solution. It's actually not that hard to have CTFE interact with type-tuples. You can pass them as function parameters, or return them if you wish. Of course a type-tuple returning ctfe function, is compile-time only.This solved one more problem that ctfe has: helper functions required for ctfe can only be omitted from the binary, if you use the trick of putting them into a module which is the import path but never explicitly given on the command line.Exactly. Yet another problem caused by the asymmetry of type-tuples w.r.t. other built-in types, and naturally solved by making them symmetric.newCTFE has the facility to be extended for this, and implementing type-functions is at least on my personal roadmap.Awesome.At Dconf 2018 Andrei and Walter said, a DIP which is substantiated enough might make it. However due to lack of time, (and productivity-reducing internal changes) it will take some time until I can get started on this. Also I plan for newCTFE to be in shape before I add type-manipulation abilities.Yes, let's please get the Minimum Viable Product of newCTFE merged into master first, before we expand the scope (and delay the schedule :-P) yet again! [...]P.S. There is one caveat: because of how type-functions work they cannot, you cannot create a non-anonymous symbol inside a type-function, because there is no way to infer a mangle. You can however create an anonymous symbol and alias it inside a template body, which gives it a mangle and it can behave like a regular symbol.Interesting. Is it possible to assign a "fake" mangle to type functions that never actually gets emitted into the object code, but just enough to make various internal compiler stuff that needs to know the mangle work properly? T -- Why do conspiracy theories always come from the same people??
Jan 17 2019
On Thursday, 17 January 2019 at 22:44:08 UTC, H. S. Teoh wrote:On Thu, Jan 17, 2019 at 10:20:24PM +0000, Stefan Koch via Digitalmars-d-announce wrote:No this is not possible, a symbol which is only used at compile-time is actually really rare. Actually If the symbol is constrained to a compile-time only context (e.g. inside is() or taking the .sizeof) this problem does not arise, and it could be allowed. Imagine you want to return a struct type which has all the fields of a given base struct but adds a member.P.S. There is one caveat: because of how type-functions work they cannot, you cannot create a non-anonymous symbol inside a type-function, because there is no way to infer a mangle. You can however create an anonymous symbol and alias it inside a template body, which gives it a mangle and it can behave like a regular symbol.Interesting. Is it possible to assign a "fake" mangle to type functions that never actually gets emitted into the object code, but just enough to make various internal compiler stuff that needs to know the mangle work properly?------module ct_helper;alias f(alias baseT, alias newMemberType, string newMember_name) { struct Extended { baseT base; mixin("newMemberType " ~ newMemberName); } return typeof(Extended.init); }struct S1 { int x; } alias S2 = f!(S1, float, "y") // looks like a template-instantiation but it's not!, I am just reusing it, to not confuse the parser to much. which mangle should this get? S2 ? - doesn't work there is no mangle for an alias. ct_helper.f.Extended? doesn't work if we call the type-function again with diffrent arguments make it an anonymous type ? - If we do that than this means that the type-function is no longer pure as two anonymous types can never Equal each other include the arguments to the type-function and it's parameters in the mangle? - that's possible but type-functions are not meant to leave any sign of their existence in order to not introduce ABI issues. In short for now I'd rather side-step the problem by not allowing freshly minted types to escape into a runtime context without going through a template wrapper (which also handles caching and has proper behavior in is-expressions).module user
Jan 17 2019
On 2019-01-17 23:44, H. S. Teoh wrote:YES! This is the way it should be. Type-tuples become first class citizens, and you can pass them around to functions and return them from functionsNo no no, not only type-tuples, you want types to be first class citizens. This makes it possible to store a type in a variable, pass it to and return from functions. Instead of a type-tuple, you want a regular array of types. Then it would be possible to use the algorithms in std.algorithm to manipulate the arrays. I really hate that today one needs to resort to things like staticMap and staticIndexOf. Of course, if we both get tuples and types as first class citizens it would be possible to store types in these tuples as well. But a tuple is usually immutable and I'm not sure if it would be possible to use std.algorithm on that. It would be awesome to be able to do things like this: type foo = int; type bar(type t) { return t; } auto u = [byte, short, int, long].map!(t => t.unsigned).array; assert(u == [ubyte, ushort, uint, ulong]; -- /Jacob Carlborg
Jan 18 2019
On Fri, Jan 18, 2019 at 11:23:11AM +0100, Jacob Carlborg via Digitalmars-d-announce wrote:On 2019-01-17 23:44, H. S. Teoh wrote:Yes, that would be the next level of symmetry. :-D Types as first class citizens would eliminate another level of distinctions that leads to the necessity of staticMap, et al. But it will also require changing the language in a much more fundamental, invasive way. So I'd say, let's take it one step at a time. Start with first-class type-tuples, then once that's ironed out and working well, take it to the next level and have first-class types. Trying to leap from here to there in one shot is probably a little too ambitious, with too high a chance of failure. [...]YES! This is the way it should be. Type-tuples become first class citizens, and you can pass them around to functions and return them from functionsNo no no, not only type-tuples, you want types to be first class citizens. This makes it possible to store a type in a variable, pass it to and return from functions. Instead of a type-tuple, you want a regular array of types. Then it would be possible to use the algorithms in std.algorithm to manipulate the arrays. I really hate that today one needs to resort to things like staticMap and staticIndexOf.It would be awesome to be able to do things like this: type foo = int; type bar(type t) { return t; } auto u = [byte, short, int, long].map!(t => t.unsigned).array; assert(u == [ubyte, ushort, uint, ulong];[...] Yes this would be awesome. But in order to avoid unmanageable complexity of implementation, all of this would have to be compile-time only constructs. T -- Your inconsistency is the only consistent thing about you! -- KD
Jan 18 2019
On Friday, 18 January 2019 at 10:23:11 UTC, Jacob Carlborg wrote:On 2019-01-17 23:44, H. S. Teoh wrote:Yes, you will be able to do exactly what you describe above. type-tuples are strictly a superset of types; which also include true compile-time constants. (e.g. things you can use to instantiate a template with.) Within type functions you are able to create `alias[]` which is in some ways equivalent to type-tuple (and will be converted to one upon being returned outside of compile-functions),which you can append to if you own it and type functions can also take other type-functions as parameters. Therefore it's perfectly possible to implement staticMap in terms of type functions. I already did the semantic sanity checks, and it shows promise. The only difference that type-functions have from what you describe is that it does not need to occupy a keyword 'type'. Cheers, StefanYES! This is the way it should be. Type-tuples become first class citizens, and you can pass them around to functions and return them from functionsNo no no, not only type-tuples, you want types to be first class citizens. This makes it possible to store a type in a variable, pass it to and return from functions. Instead of a type-tuple, you want a regular array of types. Then it would be possible to use the algorithms in std.algorithm to manipulate the arrays. I really hate that today one needs to resort to things like staticMap and staticIndexOf. Of course, if we both get tuples and types as first class citizens it would be possible to store types in these tuples as well. But a tuple is usually immutable and I'm not sure if it would be possible to use std.algorithm on that. It would be awesome to be able to do things like this: type foo = int; type bar(type t) { return t; } auto u = [byte, short, int, long].map!(t => t.unsigned).array; assert(u == [ubyte, ushort, uint, ulong];
Jan 18 2019
On 2019-01-18 20:28, Stefan Koch wrote:The only difference that type-functions have from what you describe is that it does not need to occupy a keyword 'type'.You're using "alias" instead of my "type" keyword? -- /Jacob Carlborg
Jan 18 2019
On Friday, 18 January 2019 at 20:32:35 UTC, Jacob Carlborg wrote:On 2019-01-18 20:28, Stefan Koch wrote:yes. After all what type-functions do when returning types, is to return an alias. Since it's unable to create types this is all it can do.The only difference that type-functions have from what you describe is that it does not need to occupy a keyword 'type'.You're using "alias" instead of my "type" keyword?
Jan 18 2019
On 2019-01-17 23:44, H. S. Teoh wrote:Interesting. Is it possible to assign a "fake" mangle to type functions that never actually gets emitted into the object code, but just enough to make various internal compiler stuff that needs to know the mangle work properly?Not sure that would be possible. I tries to a support for pragma(mangle) on alias declarations. That opened a can of worms. It turns out that the compiler is using the mangling of a type to compare types internally. -- /Jacob Carlborg
Jan 18 2019
Am 17.01.19 um 23:20 schrieb Stefan Koch:For 2 years I have pondered this problem, and I did come up with a solution. It's actually not that hard to have CTFE interact with type-tuples. You can pass them as function parameters, or return them if you wish. Of course a type-tuple returning ctfe function, is compile-time only. This solved one more problem that ctfe has: helper functions required for ctfe can only be omitted from the binary, if you use the trick of putting them into a module which is the import path but never explicitly given on the command line. newCTFE has the facility to be extended for this, and implementing type-functions is at least on my personal roadmap. At Dconf 2018 Andrei and Walter said, a DIP which is substantiated enough might make it. However due to lack of time, (and productivity-reducing internal changes) it will take some time until I can get started on this. Also I plan for newCTFE to be in shape before I add type-manipulation abilities. Cheers, Stefan P.S. There is one caveat: because of how type-functions work they cannot, you cannot create a non-anonymous symbol inside a type-function, because there is no way to infer a mangle. You can however create an anonymous symbol and alias it inside a template body, which gives it a mangle and it can behave like a regular symbol.This is one of the most exciting things i have read in recent times!
Jan 17 2019
On 1/17/2019 11:31 AM, H. S. Teoh wrote:[...]Thanks for the thoughtful and well-written piece. But there is a counterpoint: symmetry in mathematics is one thing, but symmetry in human intuition is not. Anytime one is dealing in human interfaces, one runs into this. I certainly did with the way imports worked in D. The lookups worked exactly the same for any sort of symbol lookup. I thought it was great. But I was unable to explain it to others. Nobody could understand it when I said imported symbol lookup worked exactly like any lookup in a name space. They universally said it was "unintuitive", filed bug reports, etc. Eventually, I had to give it up. Now import lookup follows special different rules, people are happy, and I learned (again) that symmetry doesn't always produce the best outcomes. User interfaces (and programming languages certainly are user interfaces) are hard and (ironically) are anything but intuitive to design.
Jan 17 2019
On Thu, Jan 17, 2019 at 05:32:52PM -0800, Walter Bright via Digitalmars-d-announce wrote:On 1/17/2019 11:31 AM, H. S. Teoh wrote:Alas, it's true, it's true, 100% symmetry is, in the general case, impossible to achieve. If we wanted 100% mathematical symmetry, one could argue lambda calculus is the best programming language ever, because it's Turing complete, the syntax is completely uniform with no quirky exceptions, and the semantics are very clearly defined with no ambiguity anywhere. Unfortunately, these very characteristics are also what makes lambda calculus impossible to work with for anything but the most trivial of programs. It's completely unmaintainable, extremely hard to read, and has non-trivial semantics that vary wildly from the smallest changes to the code. For a human-friendly programming language, any symmetry must necessarily be based on human expectations. Unfortunately, as you learned, human intuition varies from person to person, and indeed, is often inconsistent even with the same person, so trying to maximise symmetry in a way that doesn't become "counterintuitive" is a pretty tall order. As somebody (perhaps you) said once, in Boeing's experience with designing intuitive UIs, they discovered that what people consider "intuitive" is partly colored by their experience, and their experience is in turn shaped by the UIs they interact with. So it's a feedback loop, which means what's "intuitive" is not some static set of rules (even allowing for arbitrarily complex rules), but it's a *moving target*, the hardest thing to design for. What's considered "intuitive" today may be considered "totally counter-intuitive" 10 years from now. In the case of imports, I'd argue that the problem is with how people understand the word "import". From a compiler's POV, the simplest, most straightforward (and most symmetric!) definition is "pull in the symbols into the local scope". Unfortunately, that's not the understanding most programmers have. Perhaps in an older, bygone era people might have been more open to that sort of definition, but in this day and age of encapsulation and modularity, "pull in symbols into the local scope" does not adequately capture people's expectations: it violates encapsulation, in the following sense: symbols from the imported module shadow local symbols, which goes against the expectation that the local module is an encapsulated thing, inviolate from outside interference. It breaks the expectation of encapsulation. It breaks the symmetry that everywhere else, outside code cannot interfere with local symbols. Consequently, the expectation is that imported symbols are somehow "second class" relative to local symbols -- imported symbols don't shadow local symbols (unless you explicitly ask for it), and thus encapsulation is preserved (in some sense). So we have here a conflict between different axes of symmetry: the symmetry of every module being an inviolate, self-contained unit (encapsulation), and the symmetry of having the same rules for symbol lookup no matter where the symbol came from. It's a toss-up which axis of symmetry one should strive for, and which one should be compromised. I'd say the general principle ought to be that the higher-level symmetry (encapsulation of modules) should override the lower-level symmetry (the mechanics of symbol lookup). But this is easy to say because hindsight is 20/20; it's not so simple at the time of decision-making because it's not obvious which symmetries are in effect and what their relative importance should be. And there's always the bugbear that symmetry from the implementor's (compiler writer's) POV does not necessarily translate to symmetry from the user's (language user's) POV. Still, I'd say that in a general sense, symmetry ought to be a relatively high priority as far as designing language features or adding/changing features are concerned. Adding a new feature with little regard for how it interacts with existing features, what new corner cases it might introduce, etc., is generally a bad idea. Striving for maximal symmetry should at least give you a ballpark idea for where things should be headed, even if working out the details is generally not so straightforward. It may be that you will discover mutually-exclusive symmetries that, no matter which way you take, will lead to trouble later on. Conflicts of this sort usually cannot be fully resolved without essentially gutting the entire system to the core and rebuilding from scratch, which usually is not a practical thing to do. So we're stuck with imperfection. Nevertheless, IMO we should still strive for perfection, even if it's ultimately unattainable. Being slightly closer to perfection is better than being far off.[...]Thanks for the thoughtful and well-written piece. But there is a counterpoint: symmetry in mathematics is one thing, but symmetry in human intuition is not. Anytime one is dealing in human interfaces, one runs into this. I certainly did with the way imports worked in D. The lookups worked exactly the same for any sort of symbol lookup. I thought it was great. But I was unable to explain it to others. Nobody could understand it when I said imported symbol lookup worked exactly like any lookup in a name space. They universally said it was "unintuitive", filed bug reports, etc. Eventually, I had to give it up. Now import lookup follows special different rules, people are happy, and I learned (again) that symmetry doesn't always produce the best outcomes.User interfaces (and programming languages certainly are user interfaces) are hard and (ironically) are anything but intuitive to design.Yes, it's very unintuitive to design intuitive interfaces. :-D It's the paradox of user-interface design. T -- Life is too short to run proprietary software. -- Bdale Garbee
Jan 18 2019
On 1/17/2019 8:06 AM, bpr wrote:Was that a pre C++11 version of C++, or a more modern one?pre C++11
Jan 17 2019
On 1/16/2019 3:43 PM, John Carter wrote:Somebody on the C++ side has written a reply.... https://brevzin.github.io/c++/2019/01/15/if-constexpr-isnt-broken/From the article: D (with corrections): static if (maxLength < 0xFFFE) { alias CellIdx = uint16_t; } else { alias CellIdx = uint32_t; } C++: static constexpr auto get_type() { if constexpr (maxLength < 0xFFFE) { return type<uint16_t>; } else { return type<uint32_t>; } } using CellIdx = decltype(get_type())::type; 1. you've got to write a function separately for every declaration you want to declare in a conditional. Imagine doing 4 or 5 of these. 2. imagine this: static if (condition) int x; ... static if (condition) ++x; The C++ idiom would require (along with creating another function) creating a dummy x declaration for the (omitted) else branch of the static if. Doable, but ugly. It kinda reminds me of the C diehards who showed you can write virtual function dispatch in C. It's remarkable that these things can be done in C++, but the amount of "noise" and "boilerplate" in the solutions make them pretty hard to read.
Jan 16 2019