digitalmars.D.announce - Printing shortest decimal form of floating point number with Mir
- 9il (68/68) Dec 13 2020 Hi all,
- 9il (5/9) Dec 20 2020 Default formatting has been reworked to be more human-friendly:
- Walter Bright (2/5) Dec 20 2020 Can the improved parsing be added to D? (It would need to be Boost licen...
- 9il (5/12) Dec 20 2020 If I am correct there is open PR that set DMD to use C’s
- Walter Bright (3/8) Dec 21 2020 These functions in Phobos would make a great advertisement for Mir.
- 9il (6/18) Dec 21 2020 I thought that DMD is compiled with LDC for release builds, isn't
- 9il (5/26) Dec 21 2020 ... I just have thought maybe I have missed something and DLF
- Walter Bright (3/6) Dec 22 2020 I thought anything in D.announce got automatically tweeted. Anyhow, if y...
- Walter Bright (9/12) Dec 22 2020 A lot more people will have Phobos than Phobos+Mir. If they are perusing...
- 9il (13/30) Dec 22 2020 "If, If Is Good" (Disney Company). From the marketing point of
- Walter Bright (1/1) Dec 22 2020 If you don't want the formatting code to be part of Phobos, I respect yo...
- 9il (9/11) Dec 22 2020 Why did you think I may want it?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/5) Dec 23 2020 Out of curiosity, which language features would improve Mir?
- Timon Gehr (5/11) Dec 23 2020 https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md
- 9il (2/14) Dec 23 2020 Thanks, that is a more detailed list.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/15) Dec 23 2020 This looks like a bug?
- 9il (12/28) Dec 23 2020 https://issues.dlang.org/show_bug.cgi?id=16486
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/25) Dec 23 2020 Yes, if something is perceived as bug it becomes a burden to
- 9il (15/42) Dec 23 2020 Hi is disappeared from the Dlang after that.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/11) Dec 23 2020 I am not sure if I read the same one, I didn't perceive it as
- 9il (6/18) Dec 23 2020 Or that was just a very good mockery. But as was said that
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (11/13) Dec 23 2020 True. Other languages try to iron out perceived flaws. I am quite
- Paolo Invernizzi (7/38) Dec 23 2020 Franky speaking, I don't see any mockery, but I'm not a native
- welkam (2/3) Dec 24 2020 Read the all comments and didnt saw any mockery
- 9il (3/6) Dec 24 2020 Yes, it wasn't explicit. He didn't write bad words, he did a bad
- John Colvin (4/10) Dec 24 2020 Big difference between bad decision and mockery. It's very
- Atila Neves (4/10) Dec 29 2020 I apologise if what I wrote came across as mockery; it certainly
- Andre Pany (12/23) Dec 29 2020 From my day to day experience as developer, some topics you
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (14/25) Dec 29 2020 I am not speaking for Ilya, but from skimming through the
- 9il (3/30) Jan 02 2021 +1
- welkam (27/61) Jan 03 2021 I don't want to be the guy that comes and just takes a missive
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/15) Jan 03 2021 This is just silly. You don't have to accept a specific
- 9il (10/25) Jan 03 2021 I suppose the answer would be that D doesn't pretend to support
- Ola Fosheim Grostad (4/12) Jan 03 2021 But it is a bug even if there was no C++... An alias should work
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/16) Jan 04 2021 Here is an even simpler example that does not work:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/27) Jan 04 2021 Oh, now wait, it does:
- John Colvin (12/43) Jan 04 2021 What's the simplest example that doesn't work and is that simple
- Petar Kirov [ZombineDev] (7/52) Jan 04 2021 I don't have time to post an example, but x-ray vision is far
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (15/25) Jan 04 2021 Indirection through a parametric alias. This is the simplest I
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/12) Jan 04 2021 Typo: "discriminate between". An alias should be
- ag0aep6g (9/25) Jan 04 2021 `Bar!int` is an alias. It's indistinguishable from `Foo!int`. The code
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/11) Jan 04 2021 Wrong. This succeeds:
- ag0aep6g (3/19) Jan 04 2021 You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/9) Jan 04 2021 No, it isn't. When it is instantiated you get "Bar!int" and then
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/15) Jan 04 2021 Also, keep in mind that the type isn't "Foo", that is also just a
- ag0aep6g (15/24) Jan 04 2021 Of course it is. Replacing foo with bar is not the same as replacing baz...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/9) Jan 04 2021 Unification is what you do with parametric types, even if it
- jmh530 (9/29) Jan 04 2021 IMO, this is a better example, even if it's a little more verbose.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/41) Jan 04 2021 Also, the typesystem clearly sees the same type with two names,
- ag0aep6g (6/18) Jan 04 2021 To be sure that I'm not missing anything: You just added the temporary
- jmh530 (20/39) Jan 04 2021 Ah, I see your point above now (mixing up my Bar!ints and
- ag0aep6g (13/29) Jan 04 2021 Well, `x` is both a `Foo!int` and a `Bar!int`. They're the same
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/15) Jan 05 2021 So, does that mean that you agree that having better unification
- ag0aep6g (44/52) Jan 05 2021 Sure. I've said in my first post in this thread that "issue 1807 is well...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (25/38) Jan 05 2021 Ok, I can't argue if that is the definition.
- ag0aep6g (8/20) Jan 05 2021 I don't have that background myself, so I don't think I can
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/32) Jan 05 2021 Well, what I mean is that it is not so bad if D is perceived as
- John Colvin (13/38) Jan 04 2021 I have a longer reply I'm trying to write, but just to make sure
- John Colvin (4/18) Jan 04 2021 and presumably the same for
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/7) Jan 04 2021 It does match:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/13) Jan 04 2021 Please also note that it is completely acceptable to put limits
- jmh530 (7/31) Jan 04 2021 Would this also imply:
- Walter Bright (13/16) Jan 03 2021 The "extended precision bug" is how all x87 code works, C to C++ to Java...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/24) Jan 04 2021 But you still have to deal with things like ARM, so maybe the
- 9il (17/28) Jan 04 2021 Since C99 the default x87 behavior is precise.
- Walter Bright (37/39) Jan 04 2021 The reason those switches are provided is because the write/read is a
- 9il (43/83) Jan 04 2021 I can't reproduce the same DMD output as you.
- Walter Bright (14/23) Jan 05 2021 I did it on Windows 32 bit. I tried it on Linux 32, which does indeed sh...
- 9il (5/14) Jan 05 2021 Does this mean that DMD Linux 32-bit executables should compile
- Walter Bright (3/21) Jan 05 2021 Example, please?
- 9il (20/45) Jan 06 2021 DMD with flag -m32 generates
- Walter Bright (5/8) Jan 07 2021 In general, I strongly reiterate that posting bugs to the n.g. means the...
- Jacob Carlborg (5/6) Jan 06 2021 Other compilers solve this by having a flag to specify the minimum
- Walter Bright (2/8) Jan 07 2021 DMD has flags for that, too.
- Jacob Carlborg (5/6) Jan 09 2021 What about this changelog entry:
- Walter Bright (2/8) Jan 10 2021 Eh, you're right. It's FreeBSD32
- Guillaume Piolat (10/15) Jan 05 2021 It would be nice if no excess precision was ever used. It can
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/12) Jan 05 2021 Fun fact: in AIFF files the samplingrate is stored as a 80 bit
- Walter Bright (5/11) Jan 05 2021 That same argument could be use to always use float instead of double. I...
- Timon Gehr (17/26) Jan 05 2021 Evidence that supports some proposition may well fail to support a
- Walter Bright (14/26) Jan 05 2021 As far as I can tell, the only algorithms that are incorrect with extend...
- Imperatorn (14/17) Jan 06 2021 Yes, this is how it's different from communicating natural
- Timon Gehr (17/27) Jan 06 2021 The language semantics right now are defined to not work, so people are
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/11) Jan 06 2021 It becomes impossible to write good unit-tests for floating point
- Guillaume Piolat (15/22) Jan 06 2021 If I use float, and the compiler use real instead, it might mask
- Guillaume Piolat (3/4) Jan 06 2021 The other upside being denormals.
- Guillaume Piolat (5/6) Jan 06 2021 What has also been true though is that with LDC I've not been
- Guillaume Piolat (4/5) Jan 06 2021 Proof:
- welkam (48/52) Jan 04 2021 Different people have different definitions of words. It's clear
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/13) Jan 04 2021 It is a name, e.g.:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (13/16) Jan 04 2021 If the terminology is difficult, let' call them "signifiers". If
- welkam (60/69) Jan 05 2021 Bar!int is not a name. It's declaration. Bar is the name.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/3) Jan 05 2021 I don't think I should reply to this…
- welkam (19/22) Jan 05 2021 Then dont replay to this sentence. My post had more than one
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/13) Jan 05 2021 This code has no relation to what we discuss in this thread…
- jmh530 (41/61) Jan 03 2021 What happened was more that Atila said why not use template
- welkam (21/27) Jan 04 2021 Just because a feature makes something simpler is not enough of
- jmh530 (2/5) Jan 04 2021 Thanks for reading it.
- Atila Neves (2/9) Jan 05 2021 Yes.
- Atila Neves (5/20) Jan 04 2021 Your two #1 points aren't the same - understanding/acknowledging
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/19) Jan 04 2021 In this case, maybe #1 and #2 are the same. But sometimes people
- Atila Neves (6/27) Jan 04 2021 I wasn't a process-oriented answer, nor do I think it should have
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/12) Jan 04 2021 All management communication about conclusions have a process
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/6) Jan 07 2021 For those who read the above comment but do not want to read the rest of...
- Imperatorn (2/9) Jan 12 2021 Agreed, just suboptimal communication.
- 9il (9/11) Dec 23 2020 Safe optimizations. Mir uses unsafe ugly workarounds somehow in
- aberba (17/29) Dec 23 2020 That would take someone
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (17/23) Dec 23 2020 Indeed, if it is ignored and does not lead to a new and improved
- 9il (10/15) Dec 23 2020 1.
- aberba (2/15) Dec 23 2020 Read through the thread. That sucks.
- jmh530 (61/66) Dec 23 2020 I gave some thought to potential alternatives, but this is really
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (22/74) Dec 23 2020 I don't have time to dig into what you are trying to do, but
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/8) Dec 23 2020 argh, forget that... I am tired... Sorry.
-
Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?=
(20/28)
Dec 23 2020
template
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (16/16) Dec 23 2020 The big picture that the DIP suggested was that when stuff like
- welkam (10/21) Jan 05 2021 Replace alias Bar(T) = Foo!T; with alias Bar = Foo;
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/15) Jan 05 2021 The example was a reduced case. One can trivially construct
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (14/18) Jan 05 2021 Example:
- welkam (18/37) Jan 05 2021 I reread the whole thread. You want something like this except
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (15/24) Dec 24 2020 I don't use concepts yet as it is a very new C++ feature. The
- jmh530 (6/21) Dec 24 2020 That Foo-ish reminds me of something in D like
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/12) Dec 24 2020 Yes, it is similar in spirit. It is pretty much the same as the
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (18/25) Dec 24 2020 Non-concept version is more verbose, but yeah, works fine in
- 9il (3/22) Dec 24 2020 Thank you for the examples. They make sense.
- James Blachly (5/19) Dec 21 2020 Great work!
Hi all, Generic version of Ryu algorithm [1] was ported to D, well optimized, and adopted to mir packages. It allows printing the shortest (scientific) decimal form of a floating-point number that if it is converted back would produce the same floating-point number. The update requires mir-algorithm [2] >=3.10.13 safe pure nothrow unittest { import mir.conv: to; assert(12.3.to!string == "1.23e1"); assert(12.3456789.to!string == "1.23456789e1"); // CTFE-able static assert(12.3456789.to!string == "1.23456789e1"); } safe pure nogc unittest { // nogc import mir.conv: to; import mir.small_string; assert(12.3.to!(SmallString!32) == "1.23e1"); assert(12.3456789.to!(SmallString!32) == "1.23456789e1"); } safe pure nogc nothrow unittest { // nogc import mir.format; stringBuf buffer; auto data = buffer << 12.3 << ", " << 12.3456789 << getData; assert(data == "1.23e1, 1.23456789e1"); } Floating-point numbers can be converted to stack-allocated decimal numbers. safe pure nothrow nogc unittest { // float and double can be used to construct Decimal of any length auto decimal64 = Decimal!1(-1.235e-7); assert(decimal64.exponent == -10); assert(decimal64.coefficient == -1235); // real number may need Decimal at least length of 2 auto decimal128 = Decimal!2(-1.235e-7L); assert(decimal128.exponent == -10); assert(decimal128.coefficient == -1235); decimal128 = Decimal!2(1234e3f); assert(decimal128.exponent == 3); assert(decimal128.coefficient == 1234); } Recent releases of ASDF [3] and Mir Ion [4] use this formatting by default. It allows performing JSON serialization without loss of precision. Note that D's compiler floating-point literals parsing and Phobos floating-point literals parsing are not precise [5,6,7,8]. It is recommended to use Mir's to!double/float/real to convert floating-point numbers from a string. The work has been sponsored by Symmetry Investments and Kaleidic Associates. Kind regards, Ilya [1] https://github.com/ulfjack/ryu [2] http://mir-algorithm.libmir.org/ [3] http://asdf.libmir.org/ [4] http://mir-ion.libmir.org/ [5] https://issues.dlang.org/show_bug.cgi?id=20951 [6] https://issues.dlang.org/show_bug.cgi?id=20952 [7] https://issues.dlang.org/show_bug.cgi?id=20953 [8] https://issues.dlang.org/show_bug.cgi?id=20967
Dec 13 2020
On Monday, 14 December 2020 at 06:47:32 UTC, 9il wrote:Hi all, Generic version of Ryu algorithm [1] was ported to D, well optimized, and adopted to mir packages. [...]Default formatting has been reworked to be more human-friendly: 1.23e1 -> 1.23 https://github.com/ulfjack/ryu/tree/master/ryu Microsoft, Clang++, and others are adopting Ryu as well.
Dec 20 2020
On 12/13/2020 10:47 PM, 9il wrote:Note that D's compiler floating-point literals parsing and Phobos floating-point literals parsing are not precise [5,6,7,8]. It is recommended to use Mir's to!double/float/real to convert floating-point numbers from a string.Can the improved parsing be added to D? (It would need to be Boost licensed.)
Dec 20 2020
On Sunday, 20 December 2020 at 22:21:56 UTC, Walter Bright wrote:On 12/13/2020 10:47 PM, 9il wrote:If I am correct there is open PR that set DMD to use C’s primitives for literals parsing. So, for compiler itself we don’t need Mir. If you mean Phobos - one can use Mir instead.Note that D's compiler floating-point literals parsing and Phobos floating-point literals parsing are not precise [5,6,7,8]. It is recommended to use Mir's to!double/float/real to convert floating-point numbers from a string.Can the improved parsing be added to D? (It would need to be Boost licensed.)
Dec 20 2020
On 12/20/2020 9:42 PM, 9il wrote:On Sunday, 20 December 2020 at 22:21:56 UTC, Walter Bright wrote:That's not correct for the targets that use Digital Mars C.Can the improved parsing be added to D? (It would need to be Boost licensed.)If I am correct there is open PR that set DMD to use C’s primitives for literals parsing. So, for compiler itself we don’t need Mir.If you mean Phobos - one can use Mir instead.These functions in Phobos would make a great advertisement for Mir.
Dec 21 2020
On Tuesday, 22 December 2020 at 02:02:24 UTC, Walter Bright wrote:On 12/20/2020 9:42 PM, 9il wrote:I thought that DMD is compiled with LDC for release builds, isn't it?On Sunday, 20 December 2020 at 22:21:56 UTC, Walter Bright wrote:That's not correct for the targets that use Digital Mars C.Can the improved parsing be added to D? (It would need to be Boost licensed.)If I am correct there is open PR that set DMD to use C’s primitives for literals parsing. So, for compiler itself we don’t need Mir.How this possible? Having them in Mir is already a great advertisement for Mir and not having them in Phobos is an even more great advertisement for Mir.If you mean Phobos - one can use Mir instead.These functions in Phobos would make a great advertisement for Mir.
Dec 21 2020
On Tuesday, 22 December 2020 at 04:33:55 UTC, 9il wrote:On Tuesday, 22 December 2020 at 02:02:24 UTC, Walter Bright wrote:... I just have thought maybe I have missed something and DLF helps Mir with advertising at least a bit, maybe at least with two-three tweets per year? The last time D_Programming tweeted something about Mir was in 2016.On 12/20/2020 9:42 PM, 9il wrote:I thought that DMD is compiled with LDC for release builds, isn't it?On Sunday, 20 December 2020 at 22:21:56 UTC, Walter Bright wrote:That's not correct for the targets that use Digital Mars C.Can the improved parsing be added to D? (It would need to be Boost licensed.)If I am correct there is open PR that set DMD to use C’s primitives for literals parsing. So, for compiler itself we don’t need Mir.How this possible? Having them in Mir is already a great advertisement for Mir and not having them in Phobos is an even more great advertisement for Mir.If you mean Phobos - one can use Mir instead.These functions in Phobos would make a great advertisement for Mir.
Dec 21 2020
On 12/21/2020 8:51 PM, 9il wrote:... I just have thought maybe I have missed something and DLF helps Mir with advertising at least a bit, maybe at least with two-three tweets per year? The last time D_Programming tweeted something about Mir was in 2016.I thought anything in D.announce got automatically tweeted. Anyhow, if you have a message that you'd like D_Programming to tweet, please send it to Mike Parker.
Dec 22 2020
On 12/21/2020 8:33 PM, 9il wrote:A lot more people will have Phobos than Phobos+Mir. If they are perusing the source code and see Mir contributed excellent floating point formatting code, they may have never heard of Mir but have now. Then they'll be likely to be positively disposed towards using Mir because of the high quality code. It's the same idea as HBO offering the first episode for free in a miniseries. People watch the first episode, like it, and then subscribe to HBO.These functions in Phobos would make a great advertisement for Mir.How this possible?Having them in Mir is already a great advertisement for MirSince they exist in the C standard library (except for DMC :-( ) they by themselves aren't a compelling reason for someone to use Mir.
Dec 22 2020
On Tuesday, 22 December 2020 at 09:18:25 UTC, Walter Bright wrote:On 12/21/2020 8:33 PM, 9il wrote:"If, If Is Good" (Disney Company). From the marketing point of view, this doesn't make real sense.A lot more people will have Phobos than Phobos+Mir. If they are perusing the source code and see Mir contributed excellent floating point formatting code, they may have never heard of Mir but have now.These functions in Phobos would make a great advertisement for Mir.How this possible?Then they'll be likely to be positively disposed towards using Mir because of the high quality code.Mir doesn't need a Phobos conformity mark. In many designs and implementation questions, Phobos is far behind Mir. The reality is that Phobos asks for 6K+ LOC Mir's code, while Phobos legacy in Mir's codebase is less than a quite well reworked few percentages.It's the same idea as HBO offering the first episode for free in a miniseries. People watch the first episode, like it, and then subscribe to HBO.I don't take payments from people to use Mir. They don't need to dig in Phobos source code to find it. Likely they will search GitHub or code.dlang.org to find a solution they need.They are, Mir comes with a CTFE/ nogc/nothrow formatting API and these functions are play well inside.Having them in Mir is already a great advertisement for MirSince they exist in the C standard library (except for DMC :-( ) they by themselves aren't a compelling reason for someone to use Mir.
Dec 22 2020
If you don't want the formatting code to be part of Phobos, I respect your choice.
Dec 22 2020
On Tuesday, 22 December 2020 at 21:53:20 UTC, Walter Bright wrote:If you don't want the formatting code to be part of Phobos, I respect your choice.Why did you think I may want it? Phobos is almost not used in my work. You, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason. Why should I care about something important for you while you act like three tsars that care only about their party for years? How come?
Dec 22 2020
On Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:You, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?
Dec 23 2020
On 23.12.20 16:37, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md https://forum.dlang.org/post/kvcrsoqozrflxibgxtlo forum.dlang.org https://forum.dlang.org/thread/gungkvmtrkzcahhijtqt forum.dlang.org?page=1 https://forum.dlang.org/post/jwtygeybvfgbosxsbntk forum.dlang.orgYou, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?
Dec 23 2020
On Wednesday, 23 December 2020 at 16:20:37 UTC, Timon Gehr wrote:On 23.12.20 16:37, Ola Fosheim Grøstad wrote:Thanks, that is a more detailed list.On Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md https://forum.dlang.org/post/kvcrsoqozrflxibgxtlo forum.dlang.org https://forum.dlang.org/thread/gungkvmtrkzcahhijtqt forum.dlang.org?page=1 https://forum.dlang.org/post/jwtygeybvfgbosxsbntk forum.dlang.orgYou, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?
Dec 23 2020
On Wednesday, 23 December 2020 at 16:20:37 UTC, Timon Gehr wrote:On 23.12.20 16:37, Ola Fosheim Grøstad wrote:This looks like a bug? I see how builtin tuples could be useful for a linalg library. I like how Python allows just using ",". Makes code easier on the eyes x,y = y,xOn Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.mdYou, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?
Dec 23 2020
On Wednesday, 23 December 2020 at 16:51:33 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 16:20:37 UTC, Timon Gehr wrote:https://issues.dlang.org/show_bug.cgi?id=16486 https://issues.dlang.org/show_bug.cgi?id=16465 https://issues.dlang.org/show_bug.cgi?id=10884 and the oldest one reported in 2008 https://issues.dlang.org/show_bug.cgi?id=1807 C++ templates can be resolved, at least at the level Mir needs this. So, it is a bug in my opinion. But it was said the DIP is required. I can't write DIP well and was very happy that Stefanos wrote the DIP and even the druft.On 23.12.20 16:37, Ola Fosheim Grøstad wrote:This looks like a bug?On Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.mdYou, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?I see how builtin tuples could be useful for a linalg library. I like how Python allows just using ",". Makes code easier on the eyes x,y = y,xIt is also very desired for lazy zipped tensors.
Dec 23 2020
On Wednesday, 23 December 2020 at 17:08:26 UTC, 9il wrote:https://issues.dlang.org/show_bug.cgi?id=16486 https://issues.dlang.org/show_bug.cgi?id=16465 https://issues.dlang.org/show_bug.cgi?id=10884 and the oldest one reported in 2008 https://issues.dlang.org/show_bug.cgi?id=1807 C++ templates can be resolved, at least at the level Mir needs this. So, it is a bug in my opinion. But it was said the DIP is required. I can't write DIP well and was very happy that Stefanos wrote the DIP and even the druft.Yes, if something is perceived as bug it becomes a burden to remember that it is isn't. Not sure why anyone resist this improvement. Hm, he seems to be a compiler consultant now, but no longer interested in D? Maybe the DIP should have pushed harder on what other languages support (might be viewed as a stronger political argument).I don't use tensors much, how does it help zipping? I sometimes wonder if linalg primitives should be builtin too. Seems like that could allow for better compiler optimization.I see how builtin tuples could be useful for a linalg library. I like how Python allows just using ",". Makes code easier on the eyes x,y = y,xIt is also very desired for lazy zipped tensors.
Dec 23 2020
On Wednesday, 23 December 2020 at 17:22:28 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 17:08:26 UTC, 9il wrote:Hi is disappeared from the Dlang after that.https://issues.dlang.org/show_bug.cgi?id=16486 https://issues.dlang.org/show_bug.cgi?id=16465 https://issues.dlang.org/show_bug.cgi?id=10884 and the oldest one reported in 2008 https://issues.dlang.org/show_bug.cgi?id=1807 C++ templates can be resolved, at least at the level Mir needs this. So, it is a bug in my opinion. But it was said the DIP is required. I can't write DIP well and was very happy that Stefanos wrote the DIP and even the druft.Yes, if something is perceived as bug it becomes a burden to remember that it is isn't. Not sure why anyone resist this improvement. Hm, he seems to be a compiler consultant now, but no longer interested in D?Maybe the DIP should have pushed harder on what other languages support (might be viewed as a stronger political argument).Have you read the DMD PR thread (not the DIP itself)? It was a mockery executed by Atila accompanied by silent Walter's and Andrei's ignoring. I know Atila in person. However, it doesn't really matter if Atila really didn't understand the DIP reasons or it was a real mockery. The fact that this behavior including real or seeming mockery and real ignoring is a red flag for any professional cooperation. Atila had been already declared as "new Andrei". Which was noted right in the DIP to define Atila's privileges to make decisions. https://github.com/dlang/dmd/pull/9778#issuecomment-498700369I don't use tensors much, how does it help zipping? I sometimes wonder if linalg primitives should be builtin too. Seems like that could allow for better compiler optimization.I see how builtin tuples could be useful for a linalg library. I like how Python allows just using ",". Makes code easier on the eyes x,y = y,xIt is also very desired for lazy zipped tensors.
Dec 23 2020
On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Have you read the DMD PR thread (not the DIP itself)? It was a mockery executed by Atila accompanied by silent Walter's and Andrei's ignoring.I am not sure if I read the same one, I didn't perceive it as mockery. Atila seemed to imply that a bigger language change is needed and that this DIP would only fix one bit of what has to change? Then he tried to suggest alternatives. Maybe he did not understand that it makes the compiler look buggy. The communication was not very clear though… Looked more like people talking past each other than mockery.
Dec 23 2020
On Wednesday, 23 December 2020 at 18:23:25 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Or that was just a very good mockery. But as was said that doesn't really matter for the result we have. I am using D last 11-12 years. This case wasn't an exception, it was a Dlang failure among consequent others.Have you read the DMD PR thread (not the DIP itself)? It was a mockery executed by Atila accompanied by silent Walter's and Andrei's ignoring.I am not sure if I read the same one, I didn't perceive it as mockery. Atila seemed to imply that a bigger language change is needed and that this DIP would only fix one bit of what has to change? Then he tried to suggest alternatives. Maybe he did not understand that it makes the compiler look buggy. The communication was not very clear though… Looked more like people talking past each other than mockery.
Dec 23 2020
On Wednesday, 23 December 2020 at 18:38:01 UTC, 9il wrote:Or that was just a very good mockery. But as was said that doesn't really matter for the result we have.True. Other languages try to iron out perceived flaws. I am quite impressed by how C++ has managed to move, even though it is stuck with its flaws because of the huge installed base (many users). D does not a large installed base so it can move and remove those "perceived bugs". C++ is stuck with the "perceived bugs" and that is what people dislike the most about C++. Any language that wants to take on C++ has to streamline and make the language easy to master. That and a lack of a clear vision on memory management/memory model is D's biggest challenges. Those two aspects are float or sink dimensions, IMHO.
Dec 23 2020
On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:On Wednesday, 23 December 2020 at 17:22:28 UTC, Ola Fosheim Grøstad wrote:Franky speaking, I don't see any mockery, but I'm not a native English speaker, so I could have missed it. Said that, if you really see value in the DIP, can I suggest to keep explaining your reason? I'm totally sure everybody here is engaged in discussion with the goal to understand. ... my 2cOn Wednesday, 23 December 2020 at 17:08:26 UTC, 9il wrote:Hi is disappeared from the Dlang after that.[...]Yes, if something is perceived as bug it becomes a burden to remember that it is isn't. Not sure why anyone resist this improvement. Hm, he seems to be a compiler consultant now, but no longer interested in D?Maybe the DIP should have pushed harder on what other languages support (might be viewed as a stronger political argument).Have you read the DMD PR thread (not the DIP itself)? It was a mockery executed by Atila accompanied by silent Walter's and Andrei's ignoring. I know Atila in person. However, it doesn't really matter if Atila really didn't understand the DIP reasons or it was a real mockery. The fact that this behavior including real or seeming mockery and real ignoring is a red flag for any professional cooperation. Atila had been already declared as "new Andrei". Which was noted right in the DIP to define Atila's privileges to make decisions. https://github.com/dlang/dmd/pull/9778#issuecomment-498700369[...]I don't use tensors much, how does it help zipping? I sometimes wonder if linalg primitives should be builtin too. Seems like that could allow for better compiler optimization.
Dec 23 2020
On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Dec 24 2020
On Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Dec 24 2020
On Thursday, 24 December 2020 at 14:14:33 UTC, 9il wrote:On Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:Big difference between bad decision and mockery. It's very possible he was wrong, but I don't think he wasn't taking it seriously.On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Dec 24 2020
On Thursday, 24 December 2020 at 14:14:33 UTC, 9il wrote:On Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:I apologise if what I wrote came across as mockery; it certainly wasn't intended that way. How would you have liked for me to have handled it better?On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Dec 29 2020
On Tuesday, 29 December 2020 at 16:14:59 UTC, Atila Neves wrote:On Thursday, 24 December 2020 at 14:14:33 UTC, 9il wrote:From my day to day experience as developer, some topics you cannot discuss using mail / forum posts/ github pr. Face to face communication is best and phone communication is second best. If a pr is in a stuck situation, you may think of having a phone call if possible. (Maybe slack/discord supporting this). In many cases this will help to have a better understanding of of the pov of the other developer. Kind regards AndreOn Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:I apologise if what I wrote came across as mockery; it certainly wasn't intended that way. How would you have liked for me to have handled it better?On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Dec 29 2020
On Tuesday, 29 December 2020 at 16:14:59 UTC, Atila Neves wrote:On Thursday, 24 December 2020 at 14:14:33 UTC, 9il wrote:I am not speaking for Ilya, but from skimming through the dialogue it struck me that you didn't respond from the perspective of managing the process, but from a pure engineer mindset of providing alternatives. It would've been better if you started by 1. understanding the issue 2. acknowledging that the type system has an obvious bug 3. looking at the issue from the perspective of the person bringing attention to the issue. I don't think anyone was looking for workarounds, but looking for 1. acknowledgment of the issue 2. acknowledgment of what the issue leads to in terms of inconvenience 3. a forward looking vision for future improvementsOn Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:I apologise if what I wrote came across as mockery; it certainly wasn't intended that way. How would you have liked for me to have handled it better?On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Dec 29 2020
On Tuesday, 29 December 2020 at 19:59:56 UTC, Ola Fosheim Grøstad wrote:On Tuesday, 29 December 2020 at 16:14:59 UTC, Atila Neves wrote:+1On Thursday, 24 December 2020 at 14:14:33 UTC, 9il wrote:I am not speaking for Ilya, but from skimming through the dialogue it struck me that you didn't respond from the perspective of managing the process, but from a pure engineer mindset of providing alternatives. It would've been better if you started by 1. understanding the issue 2. acknowledging that the type system has an obvious bug 3. looking at the issue from the perspective of the person bringing attention to the issue. I don't think anyone was looking for workarounds, but looking for 1. acknowledgment of the issue 2. acknowledgment of what the issue leads to in terms of inconvenience 3. a forward looking vision for future improvementsOn Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:I apologise if what I wrote came across as mockery; it certainly wasn't intended that way. How would you have liked for me to have handled it better?On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Jan 02 2021
On Sunday, 3 January 2021 at 06:35:23 UTC, 9il wrote:On Tuesday, 29 December 2020 at 19:59:56 UTC, Ola Fosheim Grøstad wrote:I don't want to be the guy that comes and just takes a missive dump in the middle of the room but I feel like I have to. The whole language change process is not a place to get tribe`s validation or get emotional support for your boo boos. Its like looking for a virgin partner in a brothel. Makes no sense. You should view it more like this https://images.theconversation.com/files/31778/original/zhrxbdsm-1379916057.jpg?ixlib=rb-1.1.0&q=45&auto=format&w=926&fit=clip The way I saw it the whole argumentation for a language change went like this: 9il: This would be helpful for my lib Atila: Im not convinced this is good addition to the language Thats it. No more good arguments came later. If proposal has only this kind of argument then ofcourse it will be rejected. Even if the idea is good. You should put yourself in the boots of Atila. If you accept a change that later turns out to be bad idea you cant just take it out. We all would have to be with it for 10 or more years. So to avoid situation that I described a proposal needs to have solid argumentation and cost/benefit ratio needs to be clear to make good decision. And for the end I want to point out that your proposal is not in the same category as ast macros. If you or some one else comes up with solid arguments then the outcome might be different. As for me. Im do not know ins and outs of templates to make a judgment if your proposal is good or not. No one showed how it would benefit the code I write.On Tuesday, 29 December 2020 at 16:14:59 UTC, Atila Neves wrote:+1On Thursday, 24 December 2020 at 14:14:33 UTC, 9il wrote:I am not speaking for Ilya, but from skimming through the dialogue it struck me that you didn't respond from the perspective of managing the process, but from a pure engineer mindset of providing alternatives. It would've been better if you started by 1. understanding the issue 2. acknowledging that the type system has an obvious bug 3. looking at the issue from the perspective of the person bringing attention to the issue. I don't think anyone was looking for workarounds, but looking for 1. acknowledgment of the issue 2. acknowledgment of what the issue leads to in terms of inconvenience 3. a forward looking vision for future improvementsOn Thursday, 24 December 2020 at 14:08:32 UTC, welkam wrote:I apologise if what I wrote came across as mockery; it certainly wasn't intended that way. How would you have liked for me to have handled it better?On Wednesday, 23 December 2020 at 18:05:40 UTC, 9il wrote:Yes, it wasn't explicit. He didn't write bad words, he did a bad decision. Bad for D.It was a mockery executed by AtilaRead the all comments and didnt saw any mockery
Jan 03 2021
On Sunday, 3 January 2021 at 20:31:41 UTC, welkam wrote:You should put yourself in the boots of Atila. If you accept a change that later turns out to be bad idea you cant just take it out.This is just silly. You don't have to accept a specific solution... ...but... YOU DO HAVE TO ACKNOWLEDGE A TYPE SYSTEM BUG! If an indirection through an alias causes type unification to fail then that is a serious type system failure. No excuses please... "workarounds" are indeed just excuses, telling people "workarounds" they already know about is borderline offensive. I wouldn't call it mocking, but I certainly see why it can be perceived as such.
Jan 03 2021
On Sunday, 3 January 2021 at 22:50:16 UTC, Ola Fosheim Grøstad wrote:On Sunday, 3 January 2021 at 20:31:41 UTC, welkam wrote:I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years. I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature. I suppose we shouldn't expect D to pretend to be a robust language for large business projects.You should put yourself in the boots of Atila. If you accept a change that later turns out to be bad idea you cant just take it out.This is just silly. You don't have to accept a specific solution... ...but... YOU DO HAVE TO ACKNOWLEDGE A TYPE SYSTEM BUG! If an indirection through an alias causes type unification to fail then that is a serious type system failure. No excuses please... "workarounds" are indeed just excuses, telling people "workarounds" they already know about is borderline offensive. I wouldn't call it mocking, but I certainly see why it can be perceived as such.
Jan 03 2021
On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature. I suppose we shouldn't expect D to pretend to be a robust language for large business projects.I think this is up to the compiler?
Jan 03 2021
On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:Here is an even simpler example that does not work: struct Foo(T){} void foo(T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); }I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
Jan 04 2021
On Monday, 4 January 2021 at 09:18:50 UTC, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:Oh, now wait, it does: struct Foo(T){} void foo(alias T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); } My mistake.On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:Here is an even simpler example that does not work: struct Foo(T){} void foo(T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); }I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
Jan 04 2021
On Monday, 4 January 2021 at 09:21:02 UTC, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 09:18:50 UTC, Ola Fosheim Grøstad wrote:What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias? I have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong? To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:Oh, now wait, it does: struct Foo(T){} void foo(alias T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); } My mistake.On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:Here is an even simpler example that does not work: struct Foo(T){} void foo(T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); }I suppose the answer would be that D doesn't pretend to support all C++ template features and the bug is not a bug because we live with this somehow for years.But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
Jan 04 2021
On Monday, 4 January 2021 at 12:35:12 UTC, John Colvin wrote:On Monday, 4 January 2021 at 09:21:02 UTC, Ola Fosheim Grøstad wrote:I don't have time to post an example, but x-ray vision is far from what is asked for, just following basic rules established in type system theory decades ago. In practice I've had many instances where TypeScript would correctly perform generic type unification while dmd gives up at the first bump in the road.On Monday, 4 January 2021 at 09:18:50 UTC, Ola Fosheim Grøstad wrote:What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias? I have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong? To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.On Monday, 4 January 2021 at 05:55:37 UTC, Ola Fosheim Grostad wrote:Oh, now wait, it does: struct Foo(T){} void foo(alias T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); } My mistake.On Monday, 4 January 2021 at 04:37:22 UTC, 9il wrote:Here is an even simpler example that does not work: struct Foo(T){} void foo(T)(T!int x) {} alias FooInt = Foo!int; void main() { foo(FooInt()); }[...]But it is a bug even if there was no C++... An alias should work by simple substitution, if it does not, then it is no alias...
Jan 04 2021
On Monday, 4 January 2021 at 12:35:12 UTC, John Colvin wrote:What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias?Indirection through a parametric alias. This is the simplest I have come up with so far: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { f(Bar!int()); } I created a thread for it: https://forum.dlang.org/post/nxrfrizqdmhzhivxptsb forum.dlang.orgI have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong?No, just substitute: "Bar!int" with "Foo!int".To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.Why are you not convinced? An alias is a short hand. If it is possible to discriminate by the alias and the actual object then that it a semantic problem.
Jan 04 2021
On Monday, 4 January 2021 at 13:47:17 UTC, Ola Fosheim Grøstad wrote:An alias is a short hand. If it is possible to discriminate by the alias and the actual object then that it a semantic problem.Typo: "discriminate between". An alias should be indistinguishable from the object, you are only naming something. You should be able to use whatever names you fancy without that having semantic implications, that's the core PL design principle. (The stupid example that didn't work out was just me forgetting that I had played around with in higher kinded template parameters in run.dlang.io, I thought it was the code above... forgot. :-)
Jan 04 2021
On 04.01.21 14:47, Ola Fosheim Grøstad wrote:Indirection through a parametric alias. This is the simplest I have come up with so far: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { f(Bar!int()); }On 04.01.21 14:54, Ola Fosheim Grøstad wrote:Typo: "discriminate between". An alias should be indistinguishable from the object, you are only naming something. You should be able to use whatever names you fancy without that having semantic implications, that's the core PL design principle.`Bar!int` is an alias. It's indistinguishable from `Foo!int`. The code fails in the same manner when you replace "Bar!int" with "Foo!int". `Bar!T` is not yet an alias. You're asking the compiler to find a `T` so that `Bar!T` becomes an alias to `Foo!int`. The compiler doesn't know how to do that. Issue 1807 is well worth fixing/implementing. But it's not a case of DMD making a difference between an alias and its source.
Jan 04 2021
On Monday, 4 January 2021 at 14:11:28 UTC, ag0aep6g wrote:`Bar!int` is an alias. It's indistinguishable from `Foo!int`. The code fails in the same manner when you replace "Bar!int" with "Foo!int".Wrong. This succeeds: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Foo!T x) {} void main() { f(Bar!int()); }
Jan 04 2021
On 04.01.21 15:37, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 14:11:28 UTC, ag0aep6g wrote:You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with "Foo!T". That's something else entirely.`Bar!int` is an alias. It's indistinguishable from `Foo!int`. The code fails in the same manner when you replace "Bar!int" with "Foo!int".Wrong. This succeeds: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Foo!T x) {} void main() { f(Bar!int()); }
Jan 04 2021
On Monday, 4 January 2021 at 14:40:31 UTC, ag0aep6g wrote:You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with "Foo!T". That's something else entirely.No, it isn't. When it is instantiated you get "Bar!int" and then the unification would substitute that with "Foo!int". This is basic type system design. Nothing advanced. Just plain regular unification. This should even be worth discussing... the fact that it is being debated isn't promising for D's future...
Jan 04 2021
On Monday, 4 January 2021 at 14:44:00 UTC, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 14:40:31 UTC, ag0aep6g wrote:Also, keep in mind that the type isn't "Foo", that is also just a name! The true type would be a nominal "struct _ {}". If you through alias say that an object has two equivalent names, then the type system better behave accordingly.You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with "Foo!T". That's something else entirely.No, it isn't. When it is instantiated you get "Bar!int" and then the unification would substitute that with "Foo!int". This is basic type system design. Nothing advanced. Just plain regular unification. This should even be worth discussing... the fact that it is being debated isn't promising for D's future...
Jan 04 2021
On 04.01.21 15:44, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 14:40:31 UTC, ag0aep6g wrote:Of course it is. Replacing foo with bar is not the same as replacing baz with qux. The resulting code is different. The compiler output is different. My original post stands.You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with "Foo!T". That's something else entirely.No, it isn't.When it is instantiated you get "Bar!int" and then the unification would substitute that with "Foo!int".In `f(Bar!int());`, `Bar!int` is expanded to `Foo!int` before IFTI is attempted. When `f` is instantiated, any mention of `Bar` is long forgotten. The compiler sees the argument type as `Foo!int` (the type, not the string "Foo!int"). From there it deduces `T` = `int` when the parameter is `Foo!T x`, or it fails the instantiation when the parameter is `Bar!T x`. Either way, there's no "Bar!int" anymore that would be replaced by anything.This is basic type system design. Nothing advanced. Just plain regular unification.As far as I understand, describing what DMD does as "unification" would be a stretch. You might have a point saying that DMD should do "plain regular unification" instead of the ad hoc, undocumented hacks it does right now.
Jan 04 2021
On Monday, 4 January 2021 at 15:15:50 UTC, ag0aep6g wrote:As far as I understand, describing what DMD does as "unification" would be a stretch. You might have a point saying that DMD should do "plain regular unification" instead of the ad hoc, undocumented hacks it does right now.Unification is what you do with parametric types, even if it implemented in an ad hoc manner that turns out to not work... The funny thing is that this would have worked with regular macro expansion.
Jan 04 2021
On Monday, 4 January 2021 at 14:40:31 UTC, ag0aep6g wrote:On 04.01.21 15:37, Ola Fosheim Grøstad wrote:IMO, this is a better example, even if it's a little more verbose. struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { auto x = Bar!int(); f(x); }On Monday, 4 January 2021 at 14:11:28 UTC, ag0aep6g wrote:You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with "Foo!T". That's something else entirely.`Bar!int` is an alias. It's indistinguishable from `Foo!int`. The code fails in the same manner when you replace "Bar!int" with "Foo!int".Wrong. This succeeds: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Foo!T x) {} void main() { f(Bar!int()); }
Jan 04 2021
On Monday, 4 January 2021 at 15:03:05 UTC, jmh530 wrote:On Monday, 4 January 2021 at 14:40:31 UTC, ag0aep6g wrote:Also, the typesystem clearly sees the same type with two names, so there is no new nominal type (obviously): struct Foo(T) {} alias Bar(T) = Foo!T; static assert(is(Bar!int==Foo!int)); We are talking unification over complete types, unification over incomplete types would be more advanced... but this isn't that. We don't start unification until we have a concrete complete type to start working with.On 04.01.21 15:37, Ola Fosheim Grøstad wrote:IMO, this is a better example, even if it's a little more verbose. struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { auto x = Bar!int(); f(x); }On Monday, 4 January 2021 at 14:11:28 UTC, ag0aep6g wrote:You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with "Foo!T". That's something else entirely.`Bar!int` is an alias. It's indistinguishable from `Foo!int`. The code fails in the same manner when you replace "Bar!int" with "Foo!int".Wrong. This succeeds: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Foo!T x) {} void main() { f(Bar!int()); }
Jan 04 2021
On 04.01.21 16:03, jmh530 wrote:IMO, this is a better example, even if it's a little more verbose. struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { auto x = Bar!int(); f(x); }To be sure that I'm not missing anything: You just added the temporary `x`, right? I don't think that changes anything. The type of the argument is `Foo!int` in all variations of the code we've seen, including this one. And that type is all that DMD sees when it attempts IFTI of `f`.
Jan 04 2021
On Monday, 4 January 2021 at 15:31:02 UTC, ag0aep6g wrote:On 04.01.21 16:03, jmh530 wrote:Ah, I see your point above now (mixing up my Bar!ints and Bar!Ts). Yes, that was the only change and not really a substantive change (just my ease of reading). Your point is basically that a template alias only becomes an actual alias when it has been instantiated. You then note that the deduction process operates in terms of Bar (in that you have to find a T that fits Bar!T to get to an alias of Foo!T). I think part of what is confusing is that the temporary x in my example is a Foo!int and not a Bar!int, which is why the Foo!int can't be passed into f(T)(Bar!T). I think part of the issue is that many people's mental model would be for f(T)(Bar!T) to get re-writtn as f(T)(Foo!T), which is related to Ola's point with respect to type unification. But the compiler isn't really doing any re-writing, so much as it sees the Foo!int and does not have the information necessary to determine that a Foo!int should satisfy Bar!T (as you point out). It would need to extract int from Foo!int, then instantiate Bar!T to get Foo!int (which I believe is what the implementation was doing, or something similar).IMO, this is a better example, even if it's a little more verbose. struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { auto x = Bar!int(); f(x); }To be sure that I'm not missing anything: You just added the temporary `x`, right? I don't think that changes anything. The type of the argument is `Foo!int` in all variations of the code we've seen, including this one. And that type is all that DMD sees when it attempts IFTI of `f`.
Jan 04 2021
On Monday, 4 January 2021 at 17:24:53 UTC, jmh530 wrote:Your point is basically that a template alias only becomes an actual alias when it has been instantiated. You then note that the deduction process operates in terms of Bar (in that you have to find a T that fits Bar!T to get to an alias of Foo!T).Right.I think part of what is confusing is that the temporary x in my example is a Foo!int and not a Bar!int, which is why the Foo!int can't be passed into f(T)(Bar!T).Well, `x` is both a `Foo!int` and a `Bar!int`. They're the same type. `f(Bar!int())` fails in the same way as `f(Foo!int())` does.I think part of the issue is that many people's mental model would be for f(T)(Bar!T) to get re-writtn as f(T)(Foo!T), which is related to Ola's point with respect to type unification.I think you're hitting the nail on the head here regarding the confusion. Such a rewrite makes intuitive sense, and it would be nice, but it doesn't happen.But the compiler isn't really doing any re-writing, so much as it sees the Foo!int and does not have the information necessary to determine that a Foo!int should satisfy Bar!T (as you point out). It would need to extract int from Foo!int, then instantiate Bar!T to get Foo!int (which I believe is what the implementation was doing, or something similar).The compiler can and does extract `Foo` and `int` from `Foo!int`. Then it compares `Foo` to `Bar` and sees that they're not the same template. Then it gives up. The compiler would need to inspect the template `Bar`, see that it's an alias template that expands to `Foo!T` and then continue with that. I.e., it would need to do the rewrite as you say.
Jan 04 2021
On Monday, 4 January 2021 at 17:48:50 UTC, ag0aep6g wrote:I think you're hitting the nail on the head here regarding the confusion. Such a rewrite makes intuitive sense, and it would be nice, but it doesn't happen.So, does that mean that you agree that having better unification would be a worthwhile item to have on a wish list for 2021? So, if somebody want to do a full implementation that performs well, then it would be an interesting option? Quite frankly, it is much better to just say "oh, this is a deficiency in the implementation" than to say that the language spec is fubar... Also, the whole idea of writing the language spec to match the implementation is not a good approach. I think D could become competitive if the existing feature set is streamlined and polished.
Jan 05 2021
On 05.01.21 11:44, Ola Fosheim Grøstad wrote:So, does that mean that you agree that having better unification would be a worthwhile item to have on a wish list for 2021? So, if somebody want to do a full implementation that performs well, then it would be an interesting option?Sure. I've said in my first post in this thread that "issue 1807 is well worth fixing/implementing".Quite frankly, it is much better to just say "oh, this is a deficiency in the implementation" than to say that the language spec is fubar...It's not either or. The spec on IFTI is lacking. That's true whether we we call issue 1807 a bug or an enhancement. I don't think it's a productive use of our time, but if you'd like to argue semantics, here's why I don't consider issue 1807 a "bug": (PS: This turned out longer than planned. Please feel free to ignore.) A program has a bug when it doesn't behave as intended by its author. I think that's a pretty permissive definition of bug. So, DMD has a bug when it doesn't behave as Walter intended when he wrote or accepted the code. I see no evidence that IFTI's type deduction was ever intended to behave as requested in issue 1807. The spec doesn't say it should work. Walter has not come forward to say that he made a mistake in the implementation. I do see evidence that the existing deduction works as intended: Walter has called issue 1807 a "good idea for an enhancement request"[2], i.e. not a bug. Maybe most importantly, the existing behavior just feels like the kind of thing Walter does. Start with trivial deduction, allowing this: void f(T)(T p) {} int x; f(x); Then also allow derived types (e.g. pointers), because all the needed info is readily available in the type (DMD can get `int` from the type `int*`): void f(T)(T* p) {} int* x; f(x); Then realize that types created from templates also keep the needed info around for name mangling (DMD can get `S` and `int` from the type `S!int`). Use that to allow: struct S(T) {} void f(S!T p) {} S!int x; f(x); Done. Incremental improvements lead to a system that works pretty well a lot of the time. That's Walter's signature, isn't it?Also, the whole idea of writing the language spec to match the implementation is not a good approach.I don't disagree. But we have to work with what we got. The implementation exists. The spec doesn't. Documenting the existing system has merit, even when you or someone else eventually finds the time and motivation to design a better one. [1] https://dlang.org/spec/template.html#function-templates [2] https://issues.dlang.org/show_bug.cgi?id=1807#c1
Jan 05 2021
On Tuesday, 5 January 2021 at 17:13:01 UTC, ag0aep6g wrote:Sure. I've said in my first post in this thread that "issue 1807 is well worth fixing/implementing".Ok, if we have a majority for this, then all is good.A program has a bug when it doesn't behave as intended by its author. I think that's a pretty permissive definition of bug. So, DMD has a bug when it doesn't behave as Walter intended when he wrote or accepted the code.Ok, I can't argue if that is the definition. My main concern is that we need to attract more people with a strong comp.sci. background because as a language grow it becomes more tricky to improve and the most difficult topics are the ones that remain unresolved (like we see with live, shared and GC). I agree that there are more important topics than streamlining parametric types. Like shared and memory management. But it is still important to have an idea of which areas are worth picking up, if someone comes along with an interest in writing solvers, then this could be something he/she could tinker with.should work. Walter has not come forward to say that he made a mistake in the implementation.Ok, but that is not important. What is important is that if someone comes along with an interest in this area, then we can encourage them to work on it.Done. Incremental improvements lead to a system that works pretty well a lot of the time. That's Walter's signature, isn't it?That happens in many compiler development cycles. Of course, D has also added a lot of features... perhaps at the expense of bringing what is to perfection.I don't disagree. But we have to work with what we got. The implementation exists. The spec doesn't.It probably would be a good idea to focus on one subsystem at a time. Refactor, document, make a list of priority improvements for that subsystem, and then improve/reimplement, document, then move on to the next subsystem. If memory management is in the center now, then that is great, but then maybe the next cycle could take another look at the type system as a whole.
Jan 05 2021
On Tuesday, 5 January 2021 at 18:06:32 UTC, Ola Fosheim Grøstad wrote:My main concern is that we need to attract more people with a strong comp.sci. background because as a language grow it becomes more tricky to improve and the most difficult topics are the ones that remain unresolved (like we see with live, shared and GC).I don't have that background myself, so I don't think I can provide any insight here. [...]It probably would be a good idea to focus on one subsystem at a time. Refactor, document, make a list of priority improvements for that subsystem, and then improve/reimplement, document, then move on to the next subsystem. If memory management is in the center now, then that is great, but then maybe the next cycle could take another look at the type system as a whole.I'm afraid I don't have anything profound to contribute here either. I have no idea how to manage a group of volunteers (including Walter).
Jan 05 2021
On Tuesday, 5 January 2021 at 18:48:06 UTC, ag0aep6g wrote:On Tuesday, 5 January 2021 at 18:06:32 UTC, Ola Fosheim Grøstad wrote:Well, what I mean is that it is not so bad if D is perceived as an "enthusiast language", then you don't expect a flawless implementation. If the language spec outline something that is "beautiful" (also in a theoretical sense) and show where the implementation needs some love then people can contribute in areas they are interested in. If the spec is so-so, then it will be a revolving door...My main concern is that we need to attract more people with a strong comp.sci. background because as a language grow it becomes more tricky to improve and the most difficult topics are the ones that remain unresolved (like we see with live, shared and GC).I don't have that background myself, so I don't think I can provide any insight here.Most people will shy away from the difficult, tedious or boring bits, so by keeping focus on one subsystem at a time, one could hope that the difficult/tedious/boring bits receive more attention... (Nothing specific for D, just human behaviour.)It probably would be a good idea to focus on one subsystem at a time. Refactor, document, make a list of priority improvements for that subsystem, and then improve/reimplement, document, then move on to the next subsystem. If memory management is in the center now, then that is great, but then maybe the next cycle could take another look at the type system as a whole.I'm afraid I don't have anything profound to contribute here either. I have no idea how to manage a group of volunteers (including Walter).
Jan 05 2021
On Monday, 4 January 2021 at 13:47:17 UTC, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 12:35:12 UTC, John Colvin wrote:I have a longer reply I'm trying to write, but just to make sure I'm on the right track: template Foo(T) { alias Foo = T; } template Q(A : Foo!T, T) { pragma(msg, A.stringof, " ", T.stringof); } alias X = Q!(Foo!int); in your opinion, this should compile and msg `int int`, yes? I'm trying to make a really concise example without using IFTI.What's the simplest example that doesn't work and is that simple example just indirection through an alias or is it actually indirection through a template that *when instantiated* turns out to be just an alias?Indirection through a parametric alias. This is the simplest I have come up with so far: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { f(Bar!int()); } I created a thread for it: https://forum.dlang.org/post/nxrfrizqdmhzhivxptsb forum.dlang.orgI have a suspicion that what you're asking for here is the type-inference to have x-ray vision in to uninstantiated templates that works for a few simple cases. Am I wrong?No, just substitute: "Bar!int" with "Foo!int".To be clear, a really useful special case can be really useful and worthwhile, but I'm not convinced this is the principled "type system bug" you are saying it is.Why are you not convinced? An alias is a short hand. If it is possible to discriminate by the alias and the actual object then that it a semantic problem.
Jan 04 2021
On Monday, 4 January 2021 at 17:22:55 UTC, John Colvin wrote:On Monday, 4 January 2021 at 13:47:17 UTC, Ola Fosheim Grøstad wrote:and presumably the same for alias X = Q!(int); yes?[...]I have a longer reply I'm trying to write, but just to make sure I'm on the right track: template Foo(T) { alias Foo = T; } template Q(A : Foo!T, T) { pragma(msg, A.stringof, " ", T.stringof); } alias X = Q!(Foo!int); in your opinion, this should compile and msg `int int`, yes? I'm trying to make a really concise example without using IFTI.
Jan 04 2021
On Monday, 4 January 2021 at 17:24:42 UTC, John Colvin wrote:It does match: template Q(A : Foo!int) { pragma(msg, A.stringof); } So in then it should also match Foo!T, yes?in your opinion, this should compile and msg `int int`, yes?
Jan 04 2021
On Monday, 4 January 2021 at 17:58:35 UTC, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 17:24:42 UTC, John Colvin wrote:Please also note that it is completely acceptable to put limits on the constraints you are allowed to use on matching in order to get good performance, but it should work for the constraints you do allow.It does match: template Q(A : Foo!int) { pragma(msg, A.stringof); } So in then it should also match Foo!T, yes?in your opinion, this should compile and msg `int int`, yes?
Jan 04 2021
On Monday, 4 January 2021 at 17:24:42 UTC, John Colvin wrote:On Monday, 4 January 2021 at 17:22:55 UTC, John Colvin wrote:Would this also imply: enum bool Bar(A) = is(A : Foo!T, T); void main() { static assert(Bar!(Foo!int)); static assert(Bar!(int)); }On Monday, 4 January 2021 at 13:47:17 UTC, Ola Fosheim Grøstad wrote:and presumably the same for alias X = Q!(int); yes?[...]I have a longer reply I'm trying to write, but just to make sure I'm on the right track: template Foo(T) { alias Foo = T; } template Q(A : Foo!T, T) { pragma(msg, A.stringof, " ", T.stringof); } alias X = Q!(Foo!int); in your opinion, this should compile and msg `int int`, yes? I'm trying to make a really concise example without using IFTI.
Jan 04 2021
On 1/3/2021 8:37 PM, 9il wrote:I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature.The "extended precision bug" is how all x87 code works, C to C++ to Java. The reason is simple - to remove the problem requires all intermediate results to be written to memory and read back in, which is a terrible performance problem. Early Java implementations did this write/read, and were forced to change it. The advent of the XMM registers resolved this issue, and all the x86 D compilers now use XMM for 32 and 64 bit floating point math, when compiled for a CPU that has XMM registers. Extended precision only happens when the `real` 80 bit type is used, and that is IEEE conformant. If you are aware of an FP bug in the XMM code generation, please file an issue on bugzilla, and I'll be happy to take care of it. The SIMD buglist is now down to one issue (32 byte stack alignment) which is something else. The conversion to and from strings is a different problem.
Jan 03 2021
On Monday, 4 January 2021 at 05:58:09 UTC, Walter Bright wrote:On 1/3/2021 8:37 PM, 9il wrote:But you still have to deal with things like ARM, so maybe the better option is to figure out what the differences are between various hardware and define "floating point conformance levels" that library can test for, including what SIMD instructions are available. For instance, the accuracy of functions like log/exp/sin/cos/arcsin/… can vary between implementations. It would be useful for libraries to know.I didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature.The "extended precision bug" is how all x87 code works, C to C++ to Java. The reason is simple - to remove the problem requires all intermediate results to be written to memory and read back in, which is a terrible performance problem. Early Java implementations did this write/read, and were forced to change it. The advent of the XMM registers resolved this issue, and all the x86 D compilers now use XMM for 32 and 64 bit floating point math, when compiled for a CPU that has XMM registers. Extended precision only happens when the `real` 80 bit type is used, and that is IEEE conformant.
Jan 04 2021
On Monday, 4 January 2021 at 05:58:09 UTC, Walter Bright wrote:On 1/3/2021 8:37 PM, 9il wrote:Since C99 the default x87 behavior is precise. https://cpp.godbolt.org/z/7sa8dP For older C versions GCC provides -fexcess-precision=standard flag. Java is going to restore the original behavior. https://bugs.openjdk.java.net/browse/JDK-8175916 https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/control87-controlfp-control87-2?view=msvc-160 Finally, x87 is a deprecated architecture. It likely will be supported for a few decades. From the business's point of view, no one expects the best performance from the code compiled for x87. Instead of speed, numeric correctness is much more important here. I wouldn't explain why extended precision is inaccurate, because Kahan and Darcy already wrote an 80-page essay about it: "How Java’s Floating-Point Hurts Everyone Everywhere" https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdfI didn't believe it when I got a similar answer about IEEE floating-point numbers: D doesn't pertinent to be IEEE 754 compatible language and the extended precision bug is declared to be a language feature.The "extended precision bug" is how all x87 code works, C to C++ to Java. The reason is simple - to remove the problem requires all intermediate results to be written to memory and read back in, which is a terrible performance problem. Early Java implementations did this write/read, and were forced to change it.
Jan 04 2021
On 1/4/2021 4:11 AM, 9il wrote:[...]The reason those switches are provided is because the write/read is a performance hog. D provides a couple functions in druntime which guarantee rounding intermediate values to float/double precision. Those can be used as required. This is better than a compiler switch because having compiler switches that influence floating point results is poor design.Since C99 the default x87 behavior is precise.Not entirely: float f(float a, float b) { float d = (a + b) - b; return d; } f: sub esp, 4 fld DWORD PTR [esp+12] fld st(0) fadd DWORD PTR [esp+8] [no write/read to memory here, so no round to float] fsubrp st(1), st fstp DWORD PTR [esp] fld DWORD PTR [esp] add esp, 4 ret In any case, let's try your example https://cpp.godbolt.org/z/7sa8dP with dmd for 32 bits: push EAX push EAX fld float ptr 010h[ESP] fadd float ptr 0Ch[ESP] fstp float ptr [ESP] // there's the write fld float ptr [ESP] // there's the read! fsub float ptr 0Ch[ESP] fstp float ptr 4[ESP] // the write fld float ptr 4[ESP] // the read add ESP,8 ret 8 It's semantically equivalent to the godbolt asm you posted.
Jan 04 2021
On Tuesday, 5 January 2021 at 03:20:16 UTC, Walter Bright wrote:On 1/4/2021 4:11 AM, 9il wrote:I can't reproduce the same DMD output as you. DMD with flags -m32 -O generates https://cpp.godbolt.org/z/9b4e9K assume CS:.text._D7example1fFffZf push EBP mov EBP,ESP fld float ptr 0Ch[ESP] fadd float ptr 8[EBP] fsub float ptr 8[EBP] pop EBP ret 8 add [EAX],AL add [EAX],AL As you can see there are no write-read op codes. DMD with flag -m32 generates https://cpp.godbolt.org/z/GMGMra assume CS:.text._D7example1fFffZf push EBP mov EBP,ESP sub ESP,018h movss XMM0,0Ch[EBP] movss XMM1,8[EBP] addss XMM0,XMM1 movss -8[EBP],XMM0 subss XMM0,XMM1 movss -4[EBP],XMM0 movss -018h[EBP],XMM0 fld float ptr -018h[EBP] leave ret 8 add [EAX],AL It just uses SSE, which I think a good way to go, haha. Probably if no one has raised this bug then all real-world DMD targets have at least SSE support. The only D compiler that uses excess precision is DMD and only if -O flag is passed. The same example compiled with GDC uses write-read codes. LDC uses SSE codes. As for C, it allows an intuitive built-in way to work with exact precision when an assignment works like a directive to use exact precision for the expression result, unlike D. It doesn't cover all cases but an intuitive and very easy way to do things the right way.[...]The reason those switches are provided is because the write/read is a performance hog. D provides a couple functions in druntime which guarantee rounding intermediate values to float/double precision. Those can be used as required. This is better than a compiler switch because having compiler switches that influence floating point results is poor design.Since C99 the default x87 behavior is precise.Not entirely: float f(float a, float b) { float d = (a + b) - b; return d; } f: sub esp, 4 fld DWORD PTR [esp+12] fld st(0) fadd DWORD PTR [esp+8] [no write/read to memory here, so no round to float] fsubrp st(1), st fstp DWORD PTR [esp] fld DWORD PTR [esp] add esp, 4 ret In any case, let's try your example https://cpp.godbolt.org/z/7sa8dP with dmd for 32 bits: push EAX push EAX fld float ptr 010h[ESP] fadd float ptr 0Ch[ESP] fstp float ptr [ESP] // there's the write fld float ptr [ESP] // there's the read! fsub float ptr 0Ch[ESP] fstp float ptr 4[ESP] // the write fld float ptr 4[ESP] // the read add ESP,8 ret 8 It's semantically equivalent to the godbolt asm you posted.
Jan 04 2021
On 1/4/2021 11:22 PM, 9il wrote:I can't reproduce the same DMD output as you.I did it on Windows 32 bit. I tried it on Linux 32, which does indeed show the behavior you mentioned. At the moment I don't know why the different behaviors. https://issues.dlang.org/show_bug.cgi?id=21526It just uses SSE, which I think a good way to go, haha.As I mentioned upthread, it will use SSE when SSE is baseline on the CPU target, and it will always round to precision.The only D compiler that uses excess precision is DMD and only if -O flag is passed. The same example compiled with GDC uses write-read codes. LDC uses SSE codes.DMD still supports baseline 32 bit Windows that does not have XMM registers.As for C, it allows an intuitive built-in way to work with exact precision when an assignment works like a directive to use exact precision for the expression result, unlike D. It doesn't cover all cases but an intuitive and very easy way to do things the right way.It's a rarity of cases that require the rounding, and DMD does have the functions in druntime to do it for those cases. It's what people doing numerics have asked for. It means the write/read penalty is only there when it is actually required. In any case, this is an issue for the past. The future is XMM code, and DMD does the round-to-precision in all XMM code generation. If you find a case where it isn't, please file a bugzilla and let me know so I can fix it.
Jan 05 2021
On Tuesday, 5 January 2021 at 09:47:41 UTC, Walter Bright wrote:On 1/4/2021 11:22 PM, 9il wrote:Does this mean that DMD Linux 32-bit executables should compile with SSE codes? I ask because DMD compiles Linux 32-bit executables with x87 codes when -O is passed and with SSE if no -O is passed. That is very weird.I can't reproduce the same DMD output as you.I did it on Windows 32 bit. I tried it on Linux 32, which does indeed show the behavior you mentioned. At the moment I don't know why the different behaviors. https://issues.dlang.org/show_bug.cgi?id=21526It just uses SSE, which I think a good way to go, haha.As I mentioned upthread, it will use SSE when SSE is baseline on the CPU target, and it will always round to precision.
Jan 05 2021
On 1/5/2021 2:42 AM, 9il wrote:On Tuesday, 5 January 2021 at 09:47:41 UTC, Walter Bright wrote:The baseline Linux target does not have SSE.On 1/4/2021 11:22 PM, 9il wrote:Does this mean that DMD Linux 32-bit executables should compile with SSE codes?I can't reproduce the same DMD output as you.I did it on Windows 32 bit. I tried it on Linux 32, which does indeed show the behavior you mentioned. At the moment I don't know why the different behaviors. https://issues.dlang.org/show_bug.cgi?id=21526It just uses SSE, which I think a good way to go, haha.As I mentioned upthread, it will use SSE when SSE is baseline on the CPU target, and it will always round to precision.I ask because DMD compiles Linux 32-bit executables with x87 codes when -O is passed and with SSE if no -O is passed. That is very weird.Example, please?
Jan 05 2021
On Wednesday, 6 January 2021 at 02:30:30 UTC, Walter Bright wrote:On 1/5/2021 2:42 AM, 9il wrote:DMD with flag -m32 generates https://cpp.godbolt.org/z/GMGMra assume CS:.text._D7example1fFffZf push EBP mov EBP,ESP sub ESP,018h movss XMM0,0Ch[EBP] movss XMM1,8[EBP] addss XMM0,XMM1 movss -8[EBP],XMM0 subss XMM0,XMM1 movss -4[EBP],XMM0 movss -018h[EBP],XMM0 fld float ptr -018h[EBP] leave ret 8 add [EAX],AL It has been provided in the thread https://forum.dlang.org/post/gqzdiicrvtlicurxyvby forum.dlang.orgOn Tuesday, 5 January 2021 at 09:47:41 UTC, Walter Bright wrote:The baseline Linux target does not have SSE.On 1/4/2021 11:22 PM, 9il wrote:Does this mean that DMD Linux 32-bit executables should compile with SSE codes?I can't reproduce the same DMD output as you.I did it on Windows 32 bit. I tried it on Linux 32, which does indeed show the behavior you mentioned. At the moment I don't know why the different behaviors. https://issues.dlang.org/show_bug.cgi?id=21526It just uses SSE, which I think a good way to go, haha.As I mentioned upthread, it will use SSE when SSE is baseline on the CPU target, and it will always round to precision.I ask because DMD compiles Linux 32-bit executables with x87 codes when -O is passed and with SSE if no -O is passed. That is very weird.Example, please?
Jan 06 2021
On 1/6/2021 1:31 AM, 9il wrote:[...]This is the same problem as https://issues.dlang.org/show_bug.cgi?id=21526It has been provided in the thread https://forum.dlang.org/post/gqzdiicrvtlicurxyvby forum.dlang.orgIn general, I strongly reiterate that posting bugs to the n.g. means they likely won't get fixed. They have to go into bugzilla, that's why we have bugzilla. The n.g. is not a bug tracking system.
Jan 07 2021
On 2021-01-06 03:30, Walter Bright wrote:The baseline Linux target does not have SSE.Other compilers solve this by having a flag to specify the minimum target CPU. -- /Jacob Carlborg
Jan 06 2021
On 1/6/2021 4:26 AM, Jacob Carlborg wrote:On 2021-01-06 03:30, Walter Bright wrote:DMD has flags for that, too.The baseline Linux target does not have SSE.Other compilers solve this by having a flag to specify the minimum target CPU.
Jan 07 2021
On 2021-01-06 03:30, Walter Bright wrote:The baseline Linux target does not have SSE.What about this changelog entry: https://dlang.org/changelog/2.087.0.html#xmm-linux-changelog ? -- /Jacob Carlborg
Jan 09 2021
On 1/9/2021 11:18 PM, Jacob Carlborg wrote:On 2021-01-06 03:30, Walter Bright wrote:Eh, you're right. It's FreeBSD32The baseline Linux target does not have SSE.What about this changelog entry: https://dlang.org/changelog/2.087.0.html#xmm-linux-changelog ?
Jan 10 2021
On Tuesday, 5 January 2021 at 09:47:41 UTC, Walter Bright wrote:It would be nice if no excess precision was ever used. It can sometimes gives a false sense of correctness. It has no upside except accidental correctness that can break when compiled for a different platform. Accidental correctness of say, C integer promotion, doesn't break on another system - it's OK ; it's a different ilk. What about this plan? - use SSE all the time in DMD - drop real :)The only D compiler that uses excess precision is DMD and only if -O flag is passed. The same example compiled with GDC uses write-read codes. LDC uses SSE codes.DMD still supports baseline 32 bit Windows that does not have XMM registers.
Jan 05 2021
On Tuesday, 5 January 2021 at 13:30:50 UTC, Guillaume Piolat wrote:On Tuesday, 5 January 2021 at 09:47:41 UTC, Walter Bright wrote:Fun fact: in AIFF files the samplingrate is stored as a 80 bit IEEE Standard 754 floating point. ;)It would be nice if no excess precision was ever used.The only D compiler that uses excess precision is DMD and only if -O flag is passed. The same example compiled with GDC uses write-read codes. LDC uses SSE codes.DMD still supports baseline 32 bit Windows that does not have XMM registers.
Jan 05 2021
On 1/5/2021 5:30 AM, Guillaume Piolat wrote:It would be nice if no excess precision was ever used. It can sometimes gives a false sense of correctness. It has no upside except accidental correctness that can break when compiled for a different platform.That same argument could be use to always use float instead of double. I hope you see it's fallacious <g>What about this plan? - use SSE all the time in DMDThat was done for OSX because their baseline CPU had SSE.- drop real :)No.
Jan 05 2021
On 06.01.21 03:27, Walter Bright wrote:On 1/5/2021 5:30 AM, Guillaume Piolat wrote:Evidence that supports some proposition may well fail to support a completely different proposition. An analogy for your exchange: G: Birds can fly because they have wings. W: That same argument could be used to show mice can fly. I hope you see it's fallacious <g> Anyway, I wouldn't necessarily say occasional accidental correctness is the only upside, you also get better performance and simpler code generation on the deprecated x87. I don't see any further upsides though, and for me, it's a terrible trade-off, because possibility of incorrectness and lack of portability are among the downsides. I want to execute the code that I wrote, not what you think I should have instead written, because sometimes you will be wrong. There are algorithms in Phobos that can break when certain operations are computed at a higher precision than specified. Higher does not mean better; not all adjectives specify locations on some good/bad axis.It would be nice if no excess precision was ever used. It can sometimes gives a false sense of correctness. It has no upside except accidental correctness that can break when compiled for a different platform.That same argument could be use to always use float instead of double. I hope you see it's fallacious <g> ...
Jan 05 2021
On 1/5/2021 9:57 PM, Timon Gehr wrote:Anyway, I wouldn't necessarily say occasional accidental correctness is the only upside, you also get better performance and simpler code generation on the deprecated x87. I don't see any further upsides though, and for me, it's a terrible trade-off, because possibility of incorrectness and lack of portability are among the downsides. There are algorithms in Phobos that can break when certain operations are computed at a higher precision than specified. Higher does not mean better; not all adjectives specify locations on some good/bad axis.As far as I can tell, the only algorithms that are incorrect with extended precision intermediate values are ones specifically designed to tease out the roundoff to the reduced precision. I don't know of straightforward algorithms, which is what most people write, being worse off because of more precision. For example, if you're summing values in an array, the straightforward approach of simply summing them will not become incorrect with extended precision. In fact, it is likely to be more correct.I want to execute the code that I wrote, not what you think I should have instead written, because sometimes you will be wrong.With programming languages, it does not matter what you think you wrote. What matters is how the language semantics are defined to work. In writing professional numerical code, one must carefully understand it, knowing that it does *not* work like 7th grade algebra. Different languages can and do behave differently, too.
Jan 05 2021
On Wednesday, 6 January 2021 at 06:50:34 UTC, Walter Bright wrote:With programming languages, it does not matter what you think you wrote. What matters is how the language semantics are defined to work.Yes, this is how it's different from communicating natural languages where the receiver of the message can interpret things "the wrong way", or at least not the way you intended. It's a nice metaphor for may have happened with that DIP. Sometimes things are just hard to communicate, so please guys, try to give the benefit of the doubt. It's 2021, the year of D! 😉 I have a proposal though, even before writing a DIP, would it be a good idea to have a summary with concise examples and then do a quick poll? That way you don't waste time, and have the opportunity to improve your thoughts even before doing too much work? Just an idea. What do you think? 🤔
Jan 06 2021
On 06.01.21 07:50, Walter Bright wrote:> I want to execute the code that I wrote, not what you think I should have > instead written, because sometimes you will be wrong. With programming languages, it does not matter what you think you wrote. What matters is how the language semantics are defined to work.The language semantics right now are defined to not work, so people are going to rely on the common sense and/or additional promises of specific backend authors. People are going to prefer that route to the alternative of forking every dependency and adding explicit rounding to every single floating-point operation. (Which most likely does not even solve the problem as you'd still get double-rounding issues.)In writing professional numerical code, one must carefully understand it, knowing that it does *not* work like 7th grade algebra.That's why it's important to have precise control. Besides, a lot of contemporary applications of floating-point computations are not your traditional numerically stable fixed-point iterations. Reproducibility even of explicitly chaotic behavior is sometimes a big deal, for example for artificial intelligence research or multiplayer games. Also, maybe you don't want your code to change behavior randomly between compiler updates. Some applications need to have a certain amount of backwards compatibility.Different languages can and do behave differently, too.Or different implementations. I'm not going to switch languages due to an issue that's fixed by not using DMD.
Jan 06 2021
On Wednesday, 6 January 2021 at 06:50:34 UTC, Walter Bright wrote:As far as I can tell, the only algorithms that are incorrect with extended precision intermediate values are ones specifically designed to tease out the roundoff to the reduced precision.It becomes impossible to write good unit-tests for floating point if you don't know what the exact results should be. Anyway, it is ok if this is up to the compiler vendor if you can test a flag for it. Just get rid of implicit conversion for floating point. Nobody interested in numerics would want that.
Jan 06 2021
On Wednesday, 6 January 2021 at 02:27:25 UTC, Walter Bright wrote:On 1/5/2021 5:30 AM, Guillaume Piolat wrote:If I use float, and the compiler use real instead, it might mask precision problems that will be seen when using SSE instead of FPU. Happened to me once 21 oct 2015 according to my log. 2-pole IIR filters had a different sound in 32-bit and 64-bit Windows with DMD. The biquad delayline was float and should have been double. But the 32-bit DMD was using real for intermediate values, masking the fact I should have been using double. Going double lowered that quantization noise. It's really not a problem anymore since using LDC that uses SSE in 32-bit too. So the benefits of accidental precision haven't really materialized. I understand that the issue really is minor nowadays.It would be nice if no excess precision was ever used. It can sometimes gives a false sense of correctness. It has no upside except accidental correctness that can break when compiled for a different platform.That same argument could be use to always use float instead of double. I hope you see it's fallacious <g>
Jan 06 2021
On Wednesday, 6 January 2021 at 12:12:31 UTC, Guillaume Piolat wrote:It's really not a problem anymore since using LDC that uses SSEThe other upside being denormals.
Jan 06 2021
On Wednesday, 6 January 2021 at 12:15:25 UTC, Guillaume Piolat wrote:The other upside being denormals.What has also been true though is that with LDC I've not been able to actually have 80-bit precision with FPU instructions ; no matter what its FPU control word was. Really not understood why.
Jan 06 2021
On Wednesday, 6 January 2021 at 12:12:31 UTC, Guillaume Piolat wrote:Happened to me once 21 oct 2015 according to my log.Proof: https://github.com/AuburnSounds/Dplug/commit/c9a76e024cca4fe7bc94f14c7c1185d854d87947
Jan 06 2021
On Sunday, 3 January 2021 at 22:50:16 UTC, Ola Fosheim Grøstad wrote:YOU DO HAVE TO ACKNOWLEDGE A TYPE SYSTEM BUG! If an indirection through an alias causes type unification to fail then that is a serious type system failure. No excuses please...Different people have different definitions of words. It's clear that your definition of bug does not match other people definition so instead of forcing other people to conform to your definition it would be beneficial if you could express your ideas using other words. Secondly lets talk about alias Bar!int = Foo!int; or is it alias Bar(T) = Foo!T; Whatever. You want to alias template and assign a new name and then use the new name. Because you were not able to do that you say its obvious type system bug. I mean "You should be able to use whatever names you fancy without that having semantic implications". I guess type checking occurs during semantic analysis so its connected. Anyway you want assign template name. Spoiler alert Bar!int is not a name. It's also not a type or even an object. You might used another term for how alias should work but I cant track them all. Its template instantiation. Instead of alias Bar!int = Foo!int; use alias Bar = Foo; //or alias Bar = foo!int; for more read [1] What you tried before was an attempt to assign template instantiation to another template instantiation or function call. If you want to assign name to name then write it that way. When I got into personality types and typed myself I found out that my type doesnt respect physical world and details. And its true. I struggle with who where when. I some times get out of home without clipping my nails because I forgot to clip them. And I forgot because I was lost in my thoughts. Analyzing patterns is more important than being physically in the world. But what you displayed here is criminal neglect of details. There is difference between types, objects, names and symbols. There is difference between template declaration and initialization. There are differences between type system and language semantics. If you wont pay attention to these details ofcourse you will have problems communicating with people. And you failure to effectively communicate to others is not indication that its bad for D's future. People say that you notice in others what you dont like in yourself. 1. https://dlang.org/spec/template.html#aliasparameters
Jan 04 2021
On Monday, 4 January 2021 at 22:14:12 UTC, welkam wrote:Anyway you want assign template name. Spoiler alert Bar!int is not a name. It's also not a type or even an object. You might used another term for how alias should work but I cant track them all. Its template instantiation.It is a name, e.g.: alias BarInt = Bar!int; "BarInt", "Bar!int" and "Foo!int" are all names, or labels, if you wish. And they all refer to the same object: the nominal type. Which you can test easily by using "is(BarInt==Foo!int)".When I got into personality types and typed myself I found out that my type doesnt respect physical world and details.Drop ad hominem. Argue the case.
Jan 04 2021
On Monday, 4 January 2021 at 22:55:28 UTC, Ola Fosheim Grøstad wrote:"BarInt", "Bar!int" and "Foo!int" are all names, or labels, if you wish. And they all refer to the same object: the nominal type. Which you can test easily by using "is(BarInt==Foo!int)".If the terminology is difficult, let' call them "signifiers". If D add type-functions, then another signifier for the same type could be "Combine(Foo,int)". It should not matter which signifier you use, if they all yield the exact same object (in the mathematical sense): the same nominal type "struct _ {}", then they should be interchangeable with no semantic impact. This is a very basic concept in PL design. If you name the same thing several ways (any way you like), then the effect should be the same if you swap one for another. It should be indistiguishable.
Jan 04 2021
On Monday, 4 January 2021 at 22:55:28 UTC, Ola Fosheim Grøstad wrote:It is a name, e.g.: alias BarInt = Bar!int; "BarInt", "Bar!int" and "Foo!int" are all names, or labels, if you wish. And they all refer to the same object: the nominal type. Which you can test easily by using "is(BarInt==Foo!int)".Bar!int is not a name. It's declaration. Bar is the name. https://github.com/dlang/dmd/blob/master/src/dmd/dtemplate.d#L5754 Labels are myLabel: and are used with goto, break, continue. Objects are class instances. On Monday, 4 January 2021 at 23:08:31 UTC, Ola Fosheim Grøstad wrote:If the terminology is difficult, <...>The main problem here is that you use words/definitions interchangeably that refer to similar concepts but are different. As if they are the same. They are not! I got the concept from the first post and I believe most here got it too. What we have trouble here is getting it from abstract realm to reality. And reality demands it to be specific.<other names> and type "struct _ {}" <...> should be interchangeable with no semantic impact.What you want is to reference template thingy by name and assign it to thing so when you use the thing it should be interchangeable with template thingy and should be semantically equivalent. So what is a thing? From your posts its either/or: 1. identifier 2. declaration. And from your posts the template thingy is either/or: 1. template instantiation 2. template definition Since you cant get specific we will talk about all 4 possibilities. For a template declaration of myStruct lets see how we can go about creating an alias to it. struct myStruct(T) {} For assigning template instantiation to a identifier(1,1) its simple. alias myS11 = myStruct!int; For assigning template definition to a identifier(1,2) you write like this alias myS12 = myStruct; For assigning template instantiation to a declaration(2,1) well you cant. The language does not permit that. For assigning template definition to a declaration(2,2). You cant do that too. And in practice it looks like this [code] struct myStruct(T) {} void f(T)(myStruct!T x) {} void main() { alias myS11 = myStruct!int; alias myS12 = myStruct; myStruct!int x; f(x); myS11 x11; f(x11); myS12!int x12; f(x12); } [/code] Now there are also function templates but I will leave it as homework assignment. So the million dollar question is. What do you want to do with alias assignment to declaration that you cant do by assignment to identifier?Drop ad hominem. Argue the case.Ad hominem is when you use insult INSTEAD of argument. A detail that most people miss. Also how "i'm like you" is an insult?
Jan 05 2021
On Tuesday, 5 January 2021 at 15:04:34 UTC, welkam wrote:Also how "i'm like you" is an insult?I don't think I should reply to this…
Jan 05 2021
On Tuesday, 5 January 2021 at 15:10:29 UTC, Ola Fosheim Grøstad wrote:On Tuesday, 5 January 2021 at 15:04:34 UTC, welkam wrote:Then dont replay to this sentence. My post had more than one sentence. Also the thing where I showed that what you said for days is not possible and is a bug is actually possible if you followed D's syntax and semantics. I guess it had nothing to do with your loss of motivation to discuss this topic further. This code compiles struct bar(T) {} void f(T)(bar!T x) {} void main() { alias fooInt = bar!int; alias foo = bar; assert(is(fooInt == bar!int)); assert(is(foo!int == bar!int)); assert(is(fooInt == foo!int)); }Also how "i'm like you" is an insult?I don't think I should reply to this…
Jan 05 2021
On Tuesday, 5 January 2021 at 21:03:40 UTC, welkam wrote:This code compiles struct bar(T) {} void f(T)(bar!T x) {} void main() { alias fooInt = bar!int; alias foo = bar; assert(is(fooInt == bar!int)); assert(is(foo!int == bar!int)); assert(is(fooInt == foo!int)); }This code has no relation to what we discuss in this thread…
Jan 05 2021
On Sunday, 3 January 2021 at 20:31:41 UTC, welkam wrote:[snip] The way I saw it the whole argumentation for a language change went like this: 9il: This would be helpful for my lib Atila: Im not convinced this is good addition to the language Thats it. No more good arguments came later. If proposal has only this kind of argument then ofcourse it will be rejected. Even if the idea is good. You should put yourself in the boots of Atila. If you accept a change that later turns out to be bad idea you cant just take it out. We all would have to be with it for 10 or more years. So to avoid situation that I described a proposal needs to have solid argumentation and cost/benefit ratio needs to be clear to make good decision.What happened was more that Atila said why not use template constraints and Ilya replied it makes things overly complicated and Atila responded about a workaround existing and he didn't see why to add. Obviously, if Atila or Walter is not in favor of something, it's usually better to know that sooner rather than later. However, it is a bit unfortunate that this never made its way farther through the DIP process. There was a first round review, but I think it was postponed before formal assessment.And for the end I want to point out that your proposal is not in the same category as ast macros. If you or some one else comes up with solid arguments then the outcome might be different. As for me. Im do not know ins and outs of templates to make a judgment if your proposal is good or not. No one showed how it would benefit the code I write.If you aren't writing templates, then it wouldn't affect you. However, it was deemed beneficial enough that a form of it was added to C++ as part of C++ 11 (was news to me as I rarely write C++). The paper on it is here [1], though it doesn't really get into the benefits of it. I'm sure there is a lot of C++ 11 and later code out there that uses the C++11 version of the idea. Nevertheless, there are some differences between the C++11 template aliases and these. C++11 adds the using syntax in addition to the typedef syntax. D already has the alias syntax, which is like using. The difference is that D's template alias syntax works when defining variables. It only doesn't work the same with type deduction in functions. In addition, one reason the DIP was postponed because it really had only addressed the short form template alias, not the long form. However, the C++ version only seems to support the equivalent of the short form. Regardless, the DIP likely could have been improved by mentioning its inclusion in C++ 11 (and perhaps focused a bit less on implementation). I wonder if the inability to do this would inhibit the ability of D code to interact with C++ code bases. For instance, what if you have a C++ function that takes a template alias and try to call it in D. Would you have to write out the target of the alias to get it to work? This kind of thing could be important. You wouldn't be able to use the same template aliases in D the way you use them in C++. If the DIP remained focused on C++ compatibility (if that is an actual issue), then it would only need to support the short form syntax (though that may raise questions as to why not support both). [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1489.pdf
Jan 03 2021
On Monday, 4 January 2021 at 01:19:12 UTC, jmh530 wrote:it makes things overly complicatedJust because a feature makes something simpler is not enough of an argument of why it should be added. Case and point C, lua and Go languages. They are popular in part because they are simple. That's why I said that no good arguments came after. This is not a good argument. A good argument would be one that shows that benefit is worth increased complexity.If you aren't writing templates, then it wouldn't affect you.I know how to write simple template. I just dont use them recursively. I find it hard to reason about. Also I'm concerned about compilation speed and resulting code bloat. Maybe I'm just not experienced enoughHowever, it was deemed beneficial enough that a form of it was added to C++ as part of C++ 11Well D already support that just with different syntax. struct too_long_name(T) {} alias bar = too_long_name; bar!(int);I wonder if the inability to do this would inhibit the ability of D code to interact with C++ code bases.The way interop between D and C++ works is that you need to match function signatures and struct/class data layout on binary level. Then you just link. There is no cross language template instantiation and there will never be one. So it will not affect interop. P.s. Thank you for a well written post with a link to useful read.
Jan 04 2021
On Monday, 4 January 2021 at 21:07:49 UTC, welkam wrote:[snip] P.s. Thank you for a well written post with a link to useful read.Thanks for reading it.
Jan 04 2021
On Monday, 4 January 2021 at 01:19:12 UTC, jmh530 wrote:On Sunday, 3 January 2021 at 20:31:41 UTC, welkam wrote:Yes.[snip][snip[ Regardless, the DIP likely could have been improved by mentioning its inclusion in C++ 11 (and perhaps focused a bit less on implementation).
Jan 05 2021
On Tuesday, 29 December 2020 at 19:59:56 UTC, Ola Fosheim Grøstad wrote:On Tuesday, 29 December 2020 at 16:14:59 UTC, Atila Neves wrote:the issue. I think I could have done more to acknowledge it now that you brought it up.[...]I am not speaking for Ilya, but from skimming through the dialogue it struck me that you didn't respond from the perspective of managing the process, but from a pure engineer mindset of providing alternatives. It would've been better if you started by 1. understanding the issue 2. acknowledging that the type system has an obvious bug 3. looking at the issue from the perspective of the person bringing attention to the issue. I don't think anyone was looking for workarounds, but looking for 1. acknowledgment of the issue 2. acknowledgment of what the issue leads to in terms of inconvenience 3. a forward looking vision for future improvements
Jan 04 2021
On Monday, 4 January 2021 at 15:25:13 UTC, Atila Neves wrote:On Tuesday, 29 December 2020 at 19:59:56 UTC, Ola Fosheim Grøstad wrote:will complain about the "inconvenience" and not drill it down to the real cause in terms of language-mechanics. A valid response could be "I will look and see if I can find the source of this problem, but I totally see the inconvenience you are experiencing. We will look at this more closely when planning for release X.Y.Z where we do an overhaul of subsystem Q.". I don't think a process oriented response has to be more concrete than that?1. acknowledgment of the issue 2. acknowledgment of what the issue leads to in terms of inconvenience 3. a forward looking vision for future improvementsunderstanding/acknowledging the issue. I think I could have done more to acknowledge it now that you brought it up.
Jan 04 2021
On Monday, 4 January 2021 at 15:42:05 UTC, Ola Fosheim Grøstad wrote:On Monday, 4 January 2021 at 15:25:13 UTC, Atila Neves wrote:I wasn't a process-oriented answer, nor do I think it should have been. The PR was a change to the compiler with an accompanying DIP. I'm a fan of giving an opinion early to save everyone a lot of work and bother.On Tuesday, 29 December 2020 at 19:59:56 UTC, Ola Fosheim Grøstad wrote:people will complain about the "inconvenience" and not drill it down to the real cause in terms of language-mechanics. A valid response could be "I will look and see if I can find the source of this problem, but I totally see the inconvenience you are experiencing. We will look at this more closely when planning for release X.Y.Z where we do an overhaul of subsystem Q.". I don't think a process oriented response has to be more concrete than that?1. acknowledgment of the issue 2. acknowledgment of what the issue leads to in terms of inconvenience 3. a forward looking vision for future improvementsunderstanding/acknowledging the issue. I think I could have done more to acknowledge it now that you brought it up.
Jan 04 2021
On Monday, 4 January 2021 at 15:53:44 UTC, Atila Neves wrote:I wasn't a process-oriented answer, nor do I think it should have been. The PR was a change to the compiler with an accompanying DIP. I'm a fan of giving an opinion early to save everyone a lot of work and bother.All management communication about conclusions have a process oriented aspect to them. Do you just want to quickly shut the door completely, or do you want to give people a feeling that their ideas will be remembered in the continuing process of improving the product? If you cannot grow that feeling, then the incentive to try will be reduce significantly...
Jan 04 2021
On 12/23/20 10:05 AM, 9il wrote:It was a mockery executed by AtilaFor those who read the above comment but do not want to read the rest of this long thread, the linked PR discussion does not contain mockery:https://github.com/dlang/dmd/pull/9778#issuecomment-498700369Ali
Jan 07 2021
On Thursday, 7 January 2021 at 22:15:07 UTC, Ali Çehreli wrote:On 12/23/20 10:05 AM, 9il wrote:Agreed, just suboptimal communication.It was a mockery executed by AtilaFor those who read the above comment but do not want to read the rest of this long thread, the linked PR discussion does not contain mockery:https://github.com/dlang/dmd/pull/9778#issuecomment-498700369Ali
Jan 12 2021
On Wednesday, 23 December 2020 at 17:22:28 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 17:08:26 UTC, 9il wrote:I don't use tensors much, how does it help zipping?Safe optimizations. Mir uses unsafe ugly workarounds somehow in some places and doesn't improve some stuff that can be improved. Lazy tensors are used in https://github.com/typohnebild/numpy-vs-mir which has few kernels. The fastest one is `ndslice`, which uses lazy zipped tensors. Comparing with Phobos zipped ranges, Mir's zipped tensors are mutable.
Dec 23 2020
On Wednesday, 23 December 2020 at 17:22:28 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 17:08:26 UTC, 9il wrote:That would take someone 1) who really really cares and has lot's of time on their hands 2) is paid to do that job so they're motivated to keep pushing politically (Without clear communication) 3) really needs to get that fixed for the job None of which seems to me we're making it easy for people without time of their hands to make contribution. Spending hours-days writing a DIP or pull request that doesn't get the attention it deserves can be very demoralizing (undervalued). Even anything as simple as an idea, especially (or at least) coming from a very technical person, deserves some attention and clear feedback/communication. I've seen people quit their job after such experiences...and that's a PAID job. Looks to me like running away from responsibility or like I've been saying, a missing hand needed to bridge that gap.C++ templates can be resolved, at least at the level Mir needs this. So, it is a bug in my opinion. But it was said the DIP is required. I can't write DIP well and was very happy that Stefanos wrote the DIP and even the druft.Yes, if something is perceived as bug it becomes a burden to remember that it is isn't. Not sure why anyone resist this improvement. Hm, he seems to be a compiler consultant now, but no longer interested in D? Maybe the DIP should have pushed harder on what other languages support (might be viewed as a stronger political argument).
Dec 23 2020
On Wednesday, 23 December 2020 at 19:49:44 UTC, aberba wrote:None of which seems to me we're making it easy for people without time of their hands to make contribution. Spending hours-days writing a DIP or pull request that doesn't get the attention it deserves can be very demoralizing (undervalued).Indeed, if it is ignored and does not lead to a new and improved version, that is demoralizing. But, the value of a DIP isn't that it is implemented, but that it takes part in an iterative process that leads to a better outcome. So, the people who manage a project has to make this visible to those that participate, that they take part in an iterative process that is moving forward. Project management and team motivation are quite challenging topics, but if one ignore those then there will be less progress, stagnation, or regressions.Looks to me like running away from responsibility or like I've been saying, a missing hand needed to bridge that gap.There has to be a clearly mediated feeling of a spiral of progress, and that has to be communicated by those who take on project management responsibilities. So, even if the solution provided by a DIP doesn't lead to something there should at least be a feeling that the ISSUE raised is being acknowledged and noted. Which is what I feel was missing in the example given.
Dec 23 2020
On Wednesday, 23 December 2020 at 15:37:45 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:1. Alias template function parameter resolution https://github.com/dlang/dmd/pull/9778 As a result D and Mir lost Stefanos Baziotis. That is terrible, hi is very talented. 2. Multiple auto ref return values - when function allows returning multiple values.You, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?
Dec 23 2020
On Wednesday, 23 December 2020 at 16:25:58 UTC, 9il wrote:On Wednesday, 23 December 2020 at 15:37:45 UTC, Ola Fosheim Grøstad wrote:Read through the thread. That sucks.On Wednesday, 23 December 2020 at 03:06:51 UTC, 9il wrote:1. Alias template function parameter resolution https://github.com/dlang/dmd/pull/9778 As a result D and Mir lost Stefanos Baziotis. That is terrible, hi is very talented.You, Andrey, and Atila don't care about language features that have been requested for Mir or even more: rejecting DIP draft + DMD partial implementation for no real reason.Out of curiosity, which language features would improve Mir?
Dec 23 2020
On Wednesday, 23 December 2020 at 16:25:58 UTC, 9il wrote:[snip] 1. Alias template function parameter resolution https://github.com/dlang/dmd/pull/9778 [snip]I gave some thought to potential alternatives, but this is really the simplest way to think about it. For instance, I would imagine that something like below would be expected to compile if this is ever resolved. struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Foo!T x) {} void b(T)(Bar!T x) {} void main() { auto foo = Foo!int(); auto bar = Bar!int(); foo.f; foo.b; bar.f; bar.b; } If you instead use template constraints, then you have to rely on helper functions for anything more complicated and you are no longer following DRY. For instance, a function like enum bool isBar(T) = is(T == Foo!U, U); void fb(T)(T x) if(isBar!T) {} will compile (adjusting the calls above), but you are repeating Foo!U. Because of the bugs mentioned in other posts, replacing isBar with below will not. enum bool isBar(T) = is(T == Bar!U, U); Given the similarities between template constraints and concepts, something like below could accomplish something similar concept Bar(T) = is(T == Foo!U, U); but that doesn't help you if you want to also be able to use the template alias, as in auto bar = Bar!int(); This is because Bar(T) in the concept should be passing a Foo!T. You would still need to have the alias for Bar if you want that functionality (and how to name them when they are doing similar things). Abusing C++'s syntax you might have something like concept Bar(T) = requires(U)() { Foo!U; //akin to something like typename T::Foo<U>; } where we would basically be telling the compiler that T has to be a Foo!U, which would mean you would have to use Bar like Bar!U...at least that's the idea. I don't think anything like this would work currently in C++. It's useful to contrast this with implicit conversion. For instance, if instead Bar is something like struct Baz(T) { Foo!T payload alias payload this; } but then you can no longer have foo get passed to the b function (suitably adjusted). So implicit conversion isn't the solution. However, it is interesting. The problem is that Baz is a separate type. Even if it's implicitly convertible to Foo, a Foo isn't convertible to it (every Baz is a Foo but no Foos are Baz's). By contrast, the template alias Bar is still a Foo (every Bar is a Foo and some but not all Foos are Bars). So it can be thought of as a constrained version of Foo, though in this case there are no constraints listed. That's where the similarity with C++ concepts come in.
Dec 23 2020
On Wednesday, 23 December 2020 at 20:56:26 UTC, jmh530 wrote:On Wednesday, 23 December 2020 at 16:25:58 UTC, 9il wrote:I don't have time to dig into what you are trying to do, but you'll be surprised what can be done in C00... but I think the original point is that your example unifies fine with C++ : template<class T> struct Foo { int f,b; }; template<class T> using Bar = Foo<T>; template<class T> void f(Foo<T> x) {}; template<class T> void b(Bar<T> x) {} int main() { auto foo = Foo<int>(); auto bar = Bar<int>(); foo.f; foo.b; bar.f; bar.b; }[snip] 1. Alias template function parameter resolution https://github.com/dlang/dmd/pull/9778 [snip]I gave some thought to potential alternatives, but this is really the simplest way to think about it. For instance, I would imagine that something like below would be expected to compile if this is ever resolved. struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Foo!T x) {} void b(T)(Bar!T x) {} void main() { auto foo = Foo!int(); auto bar = Bar!int(); foo.f; foo.b; bar.f; bar.b; } If you instead use template constraints, then you have to rely on helper functions for anything more complicated and you are no longer following DRY. For instance, a function like enum bool isBar(T) = is(T == Foo!U, U); void fb(T)(T x) if(isBar!T) {} will compile (adjusting the calls above), but you are repeating Foo!U. Because of the bugs mentioned in other posts, replacing isBar with below will not. enum bool isBar(T) = is(T == Bar!U, U); Given the similarities between template constraints and concepts, something like below could accomplish something similar concept Bar(T) = is(T == Foo!U, U); but that doesn't help you if you want to also be able to use the template alias, as in auto bar = Bar!int(); This is because Bar(T) in the concept should be passing a Foo!T. You would still need to have the alias for Bar if you want that functionality (and how to name them when they are doing similar things). Abusing C++'s syntax you might have something like concept Bar(T) = requires(U)() { Foo!U; //akin to something like typename T::Foo<U>; } where we would basically be telling the compiler that T has to be a Foo!U, which would mean you would have to use Bar like Bar!U...at least that's the idea. I don't think anything like this would work currently in C++.
Dec 23 2020
On Wednesday, 23 December 2020 at 21:37:11 UTC, Ola Fosheim Grøstad wrote:foo.f; foo.b; bar.f; bar.b; }argh, forget that... I am tired... Sorry.
Dec 23 2020
On Wednesday, 23 December 2020 at 21:47:32 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 21:37:11 UTC, Ola Fosheim Grøstad wrote:template<class T> struct Foo { }; template<class T> using Bar = Foo<T>; template<class T> void f(Foo<T> x) {}; template<class T> void b(Bar<T> x) {} int main() { auto foo = Foo<int>(); auto bar = Bar<int>(); f(foo); b(foo); f(bar); b(bar); } better...foo.f; foo.b; bar.f; bar.b; }argh, forget that... I am tired... Sorry.
Dec 23 2020
The big picture that the DIP suggested was that when stuff like this fails to compile: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { auto foo = Bar!int(); f(foo); } Then most programmers would just conclude that the compiler is broken beyond repair and move on to another language. I certainly did so with g++ in the 90s. Such issues are deal breakers for any sane professional programmer, only hobbyists would accept that. Most people won't ask for help in the forums if the compiler fails on things that look trivial. They will conclude that the type unification in the compiler is unstable.
Dec 23 2020
On Wednesday, 23 December 2020 at 22:13:09 UTC, Ola Fosheim Grøstad wrote:The big picture that the DIP suggested was that when stuff like this fails to compile: struct Foo(T) {} alias Bar(T) = Foo!T; void f(T)(Bar!T x) {} void main() { auto foo = Bar!int(); f(foo); } Then most programmers would just conclude that the compiler is broken beyond repair and move on to another language.Replace alias Bar(T) = Foo!T; with alias Bar = Foo; struct Foo(T) {} alias Bar = Foo; void f(T)(Bar!T x) {} void main() { auto foo = Bar!int(); f(foo); }
Jan 05 2021
On Tuesday, 5 January 2021 at 21:43:09 UTC, welkam wrote:Replace alias Bar(T) = Foo!T; with alias Bar = Foo; struct Foo(T) {} alias Bar = Foo; void f(T)(Bar!T x) {} void main() { auto foo = Bar!int(); f(foo); }The example was a reduced case. One can trivially construct examples where that won't work. It is very useful to create a simple alias from a complex type for export from a type library, then it breaks when people use that type library to write templated functions. People do this all the time in C++.
Jan 05 2021
On Tuesday, 5 January 2021 at 21:46:34 UTC, Ola Fosheim Grøstad wrote:It is very useful to create a simple alias from a complex type for export from a type library, then it breaks when people use that type library to write templated functions. People do this all the time in C++.Example: // library code struct _config(T){} struct _matrix(T,C){} alias matrix(T) = _matrix!(T,_config!T); // application code void f(T)(matrix!T m){} void main() { f(matrix!float()); f(matrix!double()); }
Jan 05 2021
On Tuesday, 5 January 2021 at 21:46:34 UTC, Ola Fosheim Grøstad wrote:On Tuesday, 5 January 2021 at 21:43:09 UTC, welkam wrote:I reread the whole thread. You want something like this except without mixins and to actually work. struct Foo(T) {} mixin template Bar(T) { Foo!T } void f(T)(Foo!T x) {} void main() { f(mixin Bar!(int)()); } In languages you can pass things by value, by reference or by name. Alias works by the name passing mechanic. You can not use alias or capture by name here because you cant get a name of something that doesn't exist yet. What you want is parametric generation of definition and insertion in place. Now that's something Walter can understand.Replace alias Bar(T) = Foo!T; with alias Bar = Foo; struct Foo(T) {} alias Bar = Foo; void f(T)(Bar!T x) {} void main() { auto foo = Bar!int(); f(foo); }The example was a reduced case. One can trivially construct examples where that won't work. It is very useful to create a simple alias from a complex type for export from a type library, then it breaks when people use that type library to write templated functions. People do this all the time in C++.
Jan 05 2021
On Wednesday, 23 December 2020 at 20:56:26 UTC, jmh530 wrote:doing similar things). Abusing C++'s syntax you might have something like concept Bar(T) = requires(U)() { Foo!U; //akin to something like typename T::Foo<U>; } where we would basically be telling the compiler that T has to be a Foo!U, which would mean you would have to use Bar like Bar!U...at least that's the idea. I don't think anything like this would work currently in C++.I don't use concepts yet as it is a very new C++ feature. The following code does not work in XCode, although it probably should according to cppreference. So take this with a grain of salt (other variations should be possible): namespace detail { template<template<typename> typename F, class U> constexpr void _is_instantiable(F<U> a){} } template<class T> struct Foo{}; template<class T> concept Fooish = requires(T a){ detail::_is_instantiable<Foo>(a); };
Dec 24 2020
On Thursday, 24 December 2020 at 09:56:50 UTC, Ola Fosheim Grøstad wrote:[snip] I don't use concepts yet as it is a very new C++ feature. The following code does not work in XCode, although it probably should according to cppreference. So take this with a grain of salt (other variations should be possible): namespace detail { template<template<typename> typename F, class U> constexpr void _is_instantiable(F<U> a){} } template<class T> struct Foo{}; template<class T> concept Fooish = requires(T a){ detail::_is_instantiable<Foo>(a); };That Foo-ish reminds me of something in D like static if (__traits(compiles, { auto temp = Foo!T.init; }))
Dec 24 2020
On Thursday, 24 December 2020 at 15:00:16 UTC, jmh530 wrote:That Foo-ish reminds me of something in D like static if (__traits(compiles, { auto temp = Foo!T.init; }))Yes, it is similar in spirit. It is pretty much the same as the C++17 version, but easier to write, especially when you require many operators (e.g. "a+b", "a*b" etc). I am not sure if C++20 concepts bring anything truly new, but easier on the eyes and more likely to be used correctly. Which is important. A new feature isn't necessarily about making new things possible, encouraging correct code is just as important.
Dec 24 2020
On Wednesday, 23 December 2020 at 20:56:26 UTC, jmh530 wrote:concept Bar(T) = requires(U)() { Foo!U; //akin to something like typename T::Foo<U>; } where we would basically be telling the compiler that T has to be a Foo!U, which would mean you would have to use Bar like Bar!U...at least that's the idea. I don't think anything like this would work currently in C++.Non-concept version is more verbose, but yeah, works fine in C++17: namespace detail { template<template<typename> class F, class U> static constexpr void _dummy(const F<U> &a); template<class T, template<typename> typename F, class=void> struct has_outer_template : std::false_type {}; template<class T, template<typename> typename F> struct has_outer_template<T,F,std::void_t<decltype(_dummy<F>(std::declval<T&>()))>>: std::true_type {}; }; template <class T, template<typename> typename F> inline constexpr bool has_outer_template = detail::has_outer_template<T,F>::value; template<class T> struct Foo{}; static_assert(has_outer_template<Foo<int>,Foo>);
Dec 24 2020
On Thursday, 24 December 2020 at 11:05:16 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 23 December 2020 at 20:56:26 UTC, jmh530 wrote:Thank you for the examples. They make sense.[...]Non-concept version is more verbose, but yeah, works fine in C++17: namespace detail { template<template<typename> class F, class U> static constexpr void _dummy(const F<U> &a); template<class T, template<typename> typename F, class=void> struct has_outer_template : std::false_type {}; template<class T, template<typename> typename F> struct has_outer_template<T,F,std::void_t<decltype(_dummy<F>(std::declval<T&>()))>>: std::true_type {}; }; template <class T, template<typename> typename F> inline constexpr bool has_outer_template = detail::has_outer_template<T,F>::value; template<class T> struct Foo{}; static_assert(has_outer_template<Foo<int>,Foo>);
Dec 24 2020
On 12/14/20 1:47 AM, 9il wrote:Hi all, Generic version of Ryu algorithm [1] was ported to D, well optimized, and adopted to mir packages. ... [1] https://github.com/ulfjack/ryu [2] http://mir-algorithm.libmir.org/ [3] http://asdf.libmir.org/ [4] http://mir-ion.libmir.org/ [5] https://issues.dlang.org/show_bug.cgi?id=20951 [6] https://issues.dlang.org/show_bug.cgi?id=20952 [7] https://issues.dlang.org/show_bug.cgi?id=20953 [8] https://issues.dlang.org/show_bug.cgi?id=20967Great work! This will be very helpful in our scientific computing. I was going to suggest a PR at repo [1] to add your implementation to their list, but I see you have already done this =)
Dec 21 2020