www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D's greatest mistakes

reply "Jack" <jt overlook.biz> writes:
The post "C#'s greatest mistakes" prompts/begs this post. Have at it, 
pick up the ball and run with it, don't be shy. I expect Walter and 
Andrei to answer (if Walter and Andrei so dare!) after others' posts have 
stopped or stagnated into that cesspool of threaded discussion that is 
"the subthread" or "tangential thread" (which surely needs a rock 
anthem). 
Nov 28 2010
next sibling parent reply Gary Whatmore <no spam.sp> writes:
Jack Wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it, 
 pick up the ball and run with it, don't be shy. I expect Walter and 
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have 
 stopped or stagnated into that cesspool of threaded discussion that is 
 "the subthread" or "tangential thread" (which surely needs a rock 
 anthem). 

D's biggest mistake is, it doesn't suck almost at all unlike all other languages. This property attracts all kinds of trolls and haters here to complain and ridicule important discussions. The problem was solved when the internal mailing list outside digitalmars.D was created for the true core developers. And the Boost license brought all famous commercial users. If something could be done better, D should have looked like D2 in the first place.
Nov 28 2010
next sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Gary Whatmore wrote:
 Jack Wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

D's biggest mistake is, it doesn't suck almost at all unlike all other languages.

Hello. You just put the first nail in D's coffin for this thread. (Try to have some substance next time ok?)
 This property attracts all kinds of trolls and
 haters here to complain and ridicule important discussions. The
 problem was solved when the internal mailing list outside
 digitalmars.D was created for the true core developers. And the Boost
 license brought all famous commercial users. If something could be
 done better, D should have looked like D2 in the first place.

Well you thought about the above, how about distilling it and putting it into perspective? (Rhetorical, I know you can't).
Dec 04 2010
prev sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Gary Whatmore wrote:
 Jack Wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

D's biggest mistake is, it doesn't suck almost at all unlike all other languages. This property attracts all kinds of trolls and haters here to complain and ridicule important discussions.

The trolls I can tolerate. The haters, well I iggy them. (Good job at moderating out the "noise" of the room though while still letting in what a car maker site would not, whoever is doing it).
 The
 problem was solved when the internal mailing list outside
 digitalmars.D was created for the true core developers. And the Boost
 license brought all famous commercial users. If something could be
 done better, D should have looked like D2 in the first place. 

Dec 04 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 28 November 2010 20:19:44 Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

It's far too early to declare anything to be "D's greatest mistake." Of course, there are problems with D, and I'm sure that we'll find more as time goes on. No language is perfect. But if you want to be able to really determine which choices were good and which were bad, you need time and a lot of code being written. It's only once you've seen how things work in practice that the biggest flaws will become apparent. - Jonathan M Davis
Nov 28 2010
parent "Json" <whatyagonnado abstractplanet.net> writes:
Jonathan M Davis wrote:
 On Sunday 28 November 2010 20:19:44 Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

It's far too early to declare anything to be "D's greatest mistake."

Really? After more than a decade of a cast of thousands? Wait, are you the same guys who send things to Mars?
 Of course, there are problems with D, and I'm sure that we'll find
 more as time goes on. No language is perfect.

Wait, I get the feeling from it's/his following/followers that is IS perfect. Is it or isn't it, finally?
  But if you want to be
 able to really determine which choices were good and which were bad,
 you need time and a lot of code being written.

Or maybe that little code has been written means something?
  It's only once you've
 seen how things work in practice that the biggest flaws will become
 apparent.

Again, a decade and a cast of thousands and "no work in practice" yet? C'mon.
Dec 04 2010
prev sibling next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 29 Nov 2010 07:19:44 +0300, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

I'd go with omissible parens. There are SO many bugs and stuff that can't be worked around due to this. The second closest is a misdesigned and buggy __traits. It is so useful that you use it so often, yet it's so inconsistent and buggy that I end up hitting my head against wall almost every time I use it. In general, D has a lot of inconsistencies. *A LOT*. I'm not sure it's D's greatest mistake (well, because you can't call an entire language a mistake), but that's something that needs to be worked on.
Nov 28 2010
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Denis Koroskin wrote:
 I'd go with omissible parens. There are SO many bugs and stuff that 
 can't be worked around due to this.

For function calls? Yeah, I fell into that one. Oops. I should have learned my lesson with the problems that C has with implicitly taking the function's address.
Nov 30 2010
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Robert Jacques wrote:
 D's omissible parenthesis strike me as being half-way between C#'s 
 properties and Eiffel's Uniform Access Principle. Given Eiffel's 
 influence on D, was there a reason why you didn't implement the uniform 
 access principal instead of omissible parenthesis?

I haven't studied Eiffel that much, and remember that D came out at the same time as C#, not after it.
Nov 30 2010
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
Robert Jacques wrote:
 On Tue, 30 Nov 2010 23:11:32 -0500, Walter Bright 
 <newshound2 digitalmars.com> wrote:
 
 Robert Jacques wrote:
 D's omissible parenthesis strike me as being half-way between C#'s 
 properties and Eiffel's Uniform Access Principle. Given Eiffel's 
 influence on D, was there a reason why you didn't implement the 
 uniform access principal instead of omissible parenthesis?

I haven't studied Eiffel that much, and remember that D came out at the same time as C#, not after it.

I thought omissible parenthesis were a late addition to the language (cira 2005/2006)

Maybe, I don't remember.
Nov 30 2010
prev sibling next sibling parent reply architect <smürf village.net> writes:
Walter Bright Wrote:

 Robert Jacques wrote:
 D's omissible parenthesis strike me as being half-way between C#'s 
 properties and Eiffel's Uniform Access Principle. Given Eiffel's 
 influence on D, was there a reason why you didn't implement the uniform 
 access principal instead of omissible parenthesis?

I haven't studied Eiffel that much, and remember that D came out at the same time as C#, not after it.

You should study Eiffel that much. I think the answer to Robert's question is that Walter was too busy to study how the feature should have been implemented. This lead to the half-baked nearly useable feature we have now. It's like building a skyscraper without learning any western architecture. Increases the risk of collapse 99,8% in the first weeks after the building has been started.
Dec 01 2010
parent reply Walter Bright <newshound2 digitalmars.com> writes:
architect wrote:
 You should study Eiffel that much.

There are a thousand languages out there. I could spend multiple lifetimes studying them, and then have to start all over with the new crop of languages, and accomplish absolutely nothing.
Dec 02 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

 There are a thousand languages out there. I could spend multiple lifetimes 
 studying them, and then have to start all over with the new crop of languages, 
 and accomplish absolutely nothing.

It's a matter of balance. If you want to design something new you need to keep yourself updated too. Otherwise you miss new trends and you risk repeating the errors already done by other language designers. This means programming a little now and then in new languages is necessary (I mean languages like C#, Scala, etc). Even a surgeon can't waste all the life just studying medicine books, but if she/he doesn't study now and then, such person misses all updates and eventually becomes dangerous at the operating table. So some intermediate solution must be adopted. Bye, bearophile
Dec 02 2010
next sibling parent dolive <dolive89 sina.com> writes:
bearophile Wrote:

 Walter:
 
 There are a thousand languages out there. I could spend multiple lifetimes 
 studying them, and then have to start all over with the new crop of languages, 
 and accomplish absolutely nothing.

It's a matter of balance. If you want to design something new you need to keep yourself updated too. Otherwise you miss new trends and you risk repeating the errors already done by other language designers. This means programming a little now and then in new languages is necessary (I mean languages like C#, Scala, etc). Even a surgeon can't waste all the life just studying medicine books, but if she/he doesn't study now and then, such person misses all updates and eventually becomes dangerous at the operating table. So some intermediate solution must be adopted. Bye, bearophile

Hope to reach more consensus, fail to reach the controversy don't dispute again, into the library to achieve, now the most important bug fixes as soon as possible, efforts to make the dmd2 stability. thank you for all ! dolive
Dec 04 2010
prev sibling parent reply "Json" <whatyagonnado abstractplanet.net> writes:
bearophile wrote:
 Walter:

 There are a thousand languages out there. I could spend multiple
 lifetimes studying them, and then have to start all over with the
 new crop of languages, and accomplish absolutely nothing.

It's a matter of balance.

No it isn't.
 If you want to design something new you
 need to keep yourself updated too.

Do tell what you have created to know such.
 Otherwise you miss new trends and

and <reduced fee for you if you fill this in correctly>
 you risk repeating the errors already done by other language
 designers.

Walter is not a language designer.
 This means programming a little now and then in new
 languages is necessary (I mean languages like C#, Scala, etc).

That's blantant plug for yourself! It's all good. I'm not here to diss you. (You type an awful lot of stuff though. Maybe you should have a focus if you don't which seemingly you don't).
  Even a
 surgeon can't waste all the life just studying medicine books,

"Even"? That sounds like you are learning while posting and that's ok, but don't run for office on that, cuz I will cut you down.
 /he doesn't study now and then, such person misses all updates and
 eventually becomes dangerous at the operating table.

That is sensationalism definitive.
  So some
 intermediate solution must be adopted.

"Throw in the towel" maybe? Quit with your lies and become honest and ... yes, then what.
Dec 04 2010
parent reply trollollol <nope nope.nope> writes:
Sat, 04 Dec 2010 22:52:11 -0600, Json wrote:

 bearophile wrote:
 Walter:

 There are a thousand languages out there. I could spend multiple
 lifetimes studying them, and then have to start all over with the new
 crop of languages, and accomplish absolutely nothing.

It's a matter of balance.

No it isn't.
 If you want to design something new you need to keep yourself updated
 too.

Do tell what you have created to know such.
 Otherwise you miss new trends and

and <reduced fee for you if you fill this in correctly>
 you risk repeating the errors already done by other language designers.

Walter is not a language designer.
 This means programming a little now and then in new languages is
 necessary (I mean languages like C#, Scala, etc).

That's blantant plug for yourself! It's all good. I'm not here to diss you. (You type an awful lot of stuff though. Maybe you should have a focus if you don't which seemingly you don't).
  Even a
 surgeon can't waste all the life just studying medicine books,

"Even"? That sounds like you are learning while posting and that's ok, but don't run for office on that, cuz I will cut you down.
 /he doesn't study now and then, such person misses all updates and
 eventually becomes dangerous at the operating table.

That is sensationalism definitive.
  So some
 intermediate solution must be adopted.

"Throw in the towel" maybe? Quit with your lies and become honest and ... yes, then what.

As a computer engineer my knowledge of human sciences is quite weak, but I've noticed some simple patterns. People mostly ignore the troll posts completely, but I've found they have some value. They often follow a same pattern and get you burned if you take them too personally. Here's one possible scenario how the trolls are born. They hear/read about D, they study a bit more, see the potential in the language, maybe even try it. At some point they run into bugs / unspecified features / missing expressivity. This is the turning point. You see, the community has a lot of manpower (not really sure how to measure this, maybe using relative numbers). For example bearophile single-handedly generates work for maybe 10-50 compiler writers only via bug reports. On top of that come the feature proposals (analysing, refining, specifying, implementing these also requires maybe two orders of magnitude more manpower than is available). This is just bearophile, there are hundreds of other users with small and large issues. Simpler issued get constantly resolved with new compiler updates. The language specification is problematic. Basically, there's only one person who is allowed to dictate how the language is developed. He sometimes delegates work to Don, Andrei, ... But more often, the questions remain unanswered. There are also some other risk factors: lately I've seen that Walter saves his skin with downright lies, arrogance, and ignorance. For example in the thread about Eiffel language he told that he has no time to study Eiffel. This is a major W-T-F. The first priority of a language designer should be the best possible language spec, later comes good implementation and other issues. Once the fucked up design is set in stone, you're screwed. The justification for D in the first place was that older languages were badly screwed. Why the heck do you repeat the same mistakes. The other big problem is the lack of transparency in the development process. How does the critique towards the process affect anything? Usually it doesn't. Maybe a year ago Walter mentioned that a 64-bit port started and will be ready in 2-6 months. People wondered why there aren't any publicly visible milestones set anywhere. Now, 12 months later the 64-bit port still doesn't exist, it will be ready in 2-6 months, people wonder why there aren't any publicly visible milestones set anywhere. Now, what is wrong with this? The process doesn't fix itself. THERE'S CLEARLY A DEFICIENCY. Why isn't it fixed? Admitting that you acted unprofessionally hurts your ego, dear ignorant Walter? Any counter-arguments to this loser talk, oh Messiah? Where's your self reflection, Walter? Talk to other language designers, see how much they study other technologies. Languages come and go, but some of them (C, C++, Java, Eiffel, Erlang, Haskell, Lisp, some JIT/interpreted language, some exotic language such as Factor) are something you're expected to know if you ever become a language designer. You can't even compare the DbC implementations if in all your arrogance you don't have time to study a tiny bit of Eiffel. Same thing with the uniform function invocation foofoo.. If you become guitarist, you're expected to study all kinds of musical genres and use guitars from different manufacturers (Jackson, Gibson, ...), not only one self built instrument. If you become a novelist, you're expected to know/study a large deal of intertextuality, writing styles, have a large active vocabularity etc. As a language designer.. everyone screams about dynamic typing, functional languages and parallel programming. You can't just give a shit about that and focus on creating a better C++ using the experience achieved while writing C/C++ compilers. I want the language to solve the contemporary relevant problems, I don't want a better C++. Does D solve these problems? If not, why the heck it exists. Now, back to trolls. When the users see the social problems with the D's process, they become frustated. Some wish the best and make new improvement proposals (bearophile). The community gets annoyed because the single member puts too much stress on Walter. Some wish the best and wait silently, others start complaining in a constructive or frustated manner. Usually nothing good happens, the posts get ignored. The frustation grows. Some leave the ship, some start developing better complains and finally the frustation gets so big that you start to hate the whole project. You wish that all the negative energy will help to sink the ship and possibly some better project with a better process rises from the ashes. Is this really what you want? This is where it all leads now. You need to have enormous amount of 'faith' to 'believe' in D. Otherwise you get frustated because the broken process won't improve with the critique. This is how human mind works. You want to revenge for the lost time spent fighting the bugs. You want to revenge the arrogance and ignorance coming from the 'great minds' of the community. Revenge is easy and satisfying. You know that you personally don't have the time/energy/skills to build a better language, but you clearly see that this incompetent dickhead fails at stuff even you can do. Thus, trolling. It's so lovely to see the stupidest shitheads in this community fall for the traps. Those sheeple without any independent opinions, head full of marketing lies. You can't shoot them, but you can waste their lifetime with stupid remarks and make them mad. Isn't it lovely to read how stupid you are. That explains why you use D. Walter tries to sidestep the issue by avoiding politic talk and by keeping quiet when going gets tough. Some people accept this, some think his leadership skills are pathetic and the stubbornness (not delegating more work to the community process) highly damaging to the language. As a troll, I suppose I should be most thankful to Walter for ruining the language better than anyone else. As D's follower I wished he was the best compiler writer in the world, now I'm thankful how bad he is. I couldn't wish a more non-charismatic character for the job. Sticking with old C style coding practices and the incompetence with modern development tools also helps this.
Dec 05 2010
next sibling parent dolive <dolive89 sina.com> writes:
trollollol Wrote:

 Sat, 04 Dec 2010 22:52:11 -0600, Json wrote:
 
 bearophile wrote:
 Walter:

 There are a thousand languages out there. I could spend multiple
 lifetimes studying them, and then have to start all over with the new
 crop of languages, and accomplish absolutely nothing.

It's a matter of balance.

No it isn't.
 If you want to design something new you need to keep yourself updated
 too.

Do tell what you have created to know such.
 Otherwise you miss new trends and

and <reduced fee for you if you fill this in correctly>
 you risk repeating the errors already done by other language designers.

Walter is not a language designer.
 This means programming a little now and then in new languages is
 necessary (I mean languages like C#, Scala, etc).

That's blantant plug for yourself! It's all good. I'm not here to diss you. (You type an awful lot of stuff though. Maybe you should have a focus if you don't which seemingly you don't).
  Even a
 surgeon can't waste all the life just studying medicine books,

"Even"? That sounds like you are learning while posting and that's ok, but don't run for office on that, cuz I will cut you down.
 /he doesn't study now and then, such person misses all updates and
 eventually becomes dangerous at the operating table.

That is sensationalism definitive.
  So some
 intermediate solution must be adopted.

"Throw in the towel" maybe? Quit with your lies and become honest and ... yes, then what.

As a computer engineer my knowledge of human sciences is quite weak, but I've noticed some simple patterns. People mostly ignore the troll posts completely, but I've found they have some value. They often follow a same pattern and get you burned if you take them too personally. Here's one possible scenario how the trolls are born. They hear/read about D, they study a bit more, see the potential in the language, maybe even try it. At some point they run into bugs / unspecified features / missing expressivity. This is the turning point. You see, the community has a lot of manpower (not really sure how to measure this, maybe using relative numbers). For example bearophile single-handedly generates work for maybe 10-50 compiler writers only via bug reports. On top of that come the feature proposals (analysing, refining, specifying, implementing these also requires maybe two orders of magnitude more manpower than is available). This is just bearophile, there are hundreds of other users with small and large issues. Simpler issued get constantly resolved with new compiler updates. The language specification is problematic. Basically, there's only one person who is allowed to dictate how the language is developed. He sometimes delegates work to Don, Andrei, ... But more often, the questions remain unanswered. There are also some other risk factors: lately I've seen that Walter saves his skin with downright lies, arrogance, and ignorance. For example in the thread about Eiffel language he told that he has no time to study Eiffel. This is a major W-T-F. The first priority of a language designer should be the best possible language spec, later comes good implementation and other issues. Once the fucked up design is set in stone, you're screwed. The justification for D in the first place was that older languages were badly screwed. Why the heck do you repeat the same mistakes. The other big problem is the lack of transparency in the development process. How does the critique towards the process affect anything? Usually it doesn't. Maybe a year ago Walter mentioned that a 64-bit port started and will be ready in 2-6 months. People wondered why there aren't any publicly visible milestones set anywhere. Now, 12 months later the 64-bit port still doesn't exist, it will be ready in 2-6 months, people wonder why there aren't any publicly visible milestones set anywhere. Now, what is wrong with this? The process doesn't fix itself. THERE'S CLEARLY A DEFICIENCY. Why isn't it fixed? Admitting that you acted unprofessionally hurts your ego, dear ignorant Walter? Any counter-arguments to this loser talk, oh Messiah? Where's your self reflection, Walter? Talk to other language designers, see how much they study other technologies. Languages come and go, but some of them (C, C++, Java, Eiffel, Erlang, Haskell, Lisp, some JIT/interpreted language, some exotic language such as Factor) are something you're expected to know if you ever become a language designer. You can't even compare the DbC implementations if in all your arrogance you don't have time to study a tiny bit of Eiffel. Same thing with the uniform function invocation foofoo.. If you become guitarist, you're expected to study all kinds of musical genres and use guitars from different manufacturers (Jackson, Gibson, ...), not only one self built instrument. If you become a novelist, you're expected to know/study a large deal of intertextuality, writing styles, have a large active vocabularity etc. As a language designer.. everyone screams about dynamic typing, functional languages and parallel programming. You can't just give a shit about that and focus on creating a better C++ using the experience achieved while writing C/C++ compilers. I want the language to solve the contemporary relevant problems, I don't want a better C++. Does D solve these problems? If not, why the heck it exists. Now, back to trolls. When the users see the social problems with the D's process, they become frustated. Some wish the best and make new improvement proposals (bearophile). The community gets annoyed because the single member puts too much stress on Walter. Some wish the best and wait silently, others start complaining in a constructive or frustated manner. Usually nothing good happens, the posts get ignored. The frustation grows. Some leave the ship, some start developing better complains and finally the frustation gets so big that you start to hate the whole project. You wish that all the negative energy will help to sink the ship and possibly some better project with a better process rises from the ashes. Is this really what you want? This is where it all leads now. You need to have enormous amount of 'faith' to 'believe' in D. Otherwise you get frustated because the broken process won't improve with the critique. This is how human mind works. You want to revenge for the lost time spent fighting the bugs. You want to revenge the arrogance and ignorance coming from the 'great minds' of the community. Revenge is easy and satisfying. You know that you personally don't have the time/energy/skills to build a better language, but you clearly see that this incompetent dickhead fails at stuff even you can do. Thus, trolling. It's so lovely to see the stupidest shitheads in this community fall for the traps. Those sheeple without any independent opinions, head full of marketing lies. You can't shoot them, but you can waste their lifetime with stupid remarks and make them mad. Isn't it lovely to read how stupid you are. That explains why you use D. Walter tries to sidestep the issue by avoiding politic talk and by keeping quiet when going gets tough. Some people accept this, some think his leadership skills are pathetic and the stubbornness (not delegating more work to the community process) highly damaging to the language. As a troll, I suppose I should be most thankful to Walter for ruining the language better than anyone else. As D's follower I wished he was the best compiler writer in the world, now I'm thankful how bad he is. I couldn't wish a more non-charismatic character for the job. Sticking with old C style coding practices and the incompetence with modern development tools also helps this.

If these differences can not reach an agreement very quickly and put into practice, it is estimated D language will soon die, be dissipated by the community people. Thanks Walter, Andrei, and all of the D languages who contributed, and hope you will not be too stubborn to listen to more opinions and suggestions of the community,make D language to achieve a balance between the best. dolive
Dec 05 2010
prev sibling next sibling parent ponce <spam spam.org> writes:
 Thus, trolling. It's so lovely to see the stupidest shitheads in this
community fall for the traps. Those sheeple without any independent opinions,
head full of marketing lies. 

It's ok to make the case for D trolls, but consider you have a false understanding of the "sheeple" side. When I first read the D 1.0 manual I was getting tired with programming and seeing a well-designed language fostered a renewed passion for years. It was just incredible that D did so much things right, like a jewel in an ocean of shit. I became the worst kind of fanboy at day 1 just by reading a manual. And by using it I saw with a new eye what I always missed in other languages (and yes I of functional programming "beauty"). Haskell is often quoted as a well-designed, perfect language but the brutal reality is that strings should not represented as a linked list of chars. Such a thing is a very strong signal that designers didn't care about reality. String as linked lists implies a mandatory GC implies general unawareness of real speed issues in the community. And wasteful is ugly. I've been in audio programming and faster means that it just sound better, that you can do more interesting things. Music wouldn't sound the same if all we'd have were Java. I've made some video games and faster means better reactivity, better graphics, better experience. The lie in most other language is that you don't need speed "95% of the time", but I always found myself needing it and D gives you the real power of expressivity and raw speed. Even if I don't use at the moment (lost in Javascript land, figthing the GC), it will always have a special place in my heart and yes I have religious feelings about it, as stupid that it seems. Its success is unavoidable because it's ridiculously better than the alternatives, and language that _might_ be better are in an earlier stage. You and your clones are not doing something useful at all. If you think you are better than Walter consider that he won't ever answer your rant and will win precious minutes to reach his goal, while you are stuck posting useless rants to make you feel better. That's the meaning of "loser talk".
Dec 06 2010
prev sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
trollollol wrote:

[]

Don't fuck with me. I am in no fucking mood. 
Dec 06 2010
prev sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Walter Bright wrote:
 architect wrote:
 You should study Eiffel that much.

There are a thousand languages out there. I could spend multiple lifetimes studying them, and then have to start all over with the new crop of languages, and accomplish absolutely nothing.

Why persist in this? Your language has "design by contract" written all over it. Lawyers biting your tongue Walt? ;)
Dec 04 2010
prev sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Walter Bright wrote:
 Robert Jacques wrote:
 D's omissible parenthesis strike me as being half-way between C#'s
 properties and Eiffel's Uniform Access Principle. Given Eiffel's
 influence on D, was there a reason why you didn't implement the
 uniform access principal instead of omissible parenthesis?

I haven't studied Eiffel that much,

No, not at all! Yet "contract programming" is on the D's brochure! You put something in D that you hadn't investigated? Um, you just dreamt that up?
Dec 04 2010
prev sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Walter Bright wrote:
 Denis Koroskin wrote:
 I'd go with omissible parens. There are SO many bugs and stuff that
 can't be worked around due to this.

For function calls? Yeah, I fell into that one. Oops. I should have learned my lesson with the problems that C has with implicitly taking the function's address.

I relegated his comment about "omissible parens" as minutia, but will you please sum it up here? Thanks. Yes I will give you the correct answer (probably just once though.. freebies don't pay the bills you know).
Dec 04 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 30 Nov 2010 14:36:58 -0500, Walter Bright  
<newshound2 digitalmars.com> wrote:
 Denis Koroskin wrote:
 I'd go with omissible parens. There are SO many bugs and stuff that  
 can't be worked around due to this.

For function calls? Yeah, I fell into that one. Oops. I should have learned my lesson with the problems that C has with implicitly taking the function's address.

D's omissible parenthesis strike me as being half-way between C#'s properties and Eiffel's Uniform Access Principle. Given Eiffel's influence on D, was there a reason why you didn't implement the uniform access principal instead of omissible parenthesis?
Nov 30 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 30 Nov 2010 23:11:32 -0500, Walter Bright  
<newshound2 digitalmars.com> wrote:

 Robert Jacques wrote:
 D's omissible parenthesis strike me as being half-way between C#'s  
 properties and Eiffel's Uniform Access Principle. Given Eiffel's  
 influence on D, was there a reason why you didn't implement the uniform  
 access principal instead of omissible parenthesis?

I haven't studied Eiffel that much, and remember that D came out at the same time as C#, not after it.

I thought omissible parenthesis were a late addition to the language (cira 2005/2006)
Nov 30 2010
prev sibling next sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Denis Koroskin wrote:
 On Mon, 29 Nov 2010 07:19:44 +0300, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

I'd go with omissible parens.

OMG! That is such minutia! I'm sure it's important (to you) but you seem to have missed the word "greatest" in the first post.
 There are SO many bugs

OK, "I know who you are".
 and stuff that
 can't be worked around due to this.

Consider: <fill in this blank and you win something>.
 The second closest is a misdesigned and buggy __traits.

That is "the second GREATEST mistake"? Are you sure?
 It is so
 useful that you use it so often, yet it's so inconsistent and buggy
 that I end up hitting my head against wall almost every time I use it.

 In general, D has a lot of inconsistencies. *A LOT*.

Kind've "all of the map" flavor, you mean? (Not to "lead" you or anything). Follow your heart.
 I'm not sure
 it's D's greatest mistake (well, because you can't call an entire
 language a mistake), but that's something that needs to be worked on.

It was fun reading your post. Keep posting!
Dec 04 2010
prev sibling parent so <so so.do> writes:
 For example in the thread about Eiffel language he told that he has no  
 time to study Eiffel. This is a major W-T-F. The first priority of a  
 language designer should be the best possible language spec, later comes  
 good implementation and other issues. Once the fucked up design is set  
 in stone, you're screwed.

 If you become guitarist, you're expected to study all kinds of musical  
 genres and use guitars from different manufacturers (Jackson, Gibson,  
 ...), not only one self built instrument. If you become a novelist,  
 you're expected to know/study a large deal of intertextuality, writing  
 styles, have a large active vocabularity etc.

You base on these to what exactly? Can we at least get the name of the language you designed?
 As a language designer.. everyone screams about dynamic typing,  
 functional languages and parallel programming.

Now this better be a joke, you are complaining because D is not a dynamic typed language? This is not some random "top down ###" language, wake up you are trolling on the wrong newsgroup.
 You can't just give a shit about that and focus on creating a better C++  
 using the experience achieved while writing C/C++ compilers. I want the  
 language to solve the contemporary relevant problems, I don't want a  
 better C++. Does D solve these problems? If not, why the heck it exists.

If you want "that" language, and "that" is not "D" why the hell you are here wasting your precious trolling time? We are already doomed, leave us behind, save yourself! How many times you have been to a public group that you actually talk to designer or even a programmer of a language implementation? How many times have you had a chance to actually propose something to a language on a public newsgroup? There are many more BS to respond but i just stop it here, seeing that i am approaching the "tone" of yours. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 06 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/28/10 10:19 PM, Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

Hrm, excellent challenge. I can't think of a ranking of mistakes right now, but some that come to mind are: * Not fixing switch * scope variables * delete (generally: an incompletely thought-out approach to garbage collection) * typedef * Escape rules are too lax (e.g. things could be a lot better if ref results couldn't be escaped) * Eponymous templates can't have any members * Template pattern matching is incomplete * Overloading of templates with non-templates is poor I'll think of more annoyance factors in writing D code. I know the last two are an issue but not a very practical one. The rest I'm doing my best to improve or eliminate before the broken behavior becomes too encroached. Andrei
Nov 28 2010
next sibling parent reply "Jack" <jt overlook.biz> writes:
Andrei Alexandrescu wrote:
 On 11/28/10 10:19 PM, Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

Hrm, excellent challenge.

Ah ha! YOU voiced before Walt. ( So, as I am so knowing, can I moderate this discussion? )
 I can't think of a ranking of mistakes right
 now,

Are you a warrior, asked about your commander's "direction"?
 but some that come to mind are:

 * Not fixing switch

detail
 * scope variables

detail
 * delete (generally: an incompletely thought-out approach to garbage
 collection)

detail
 * typedef

detail
 * Escape rules are too lax (e.g. things could be a lot better if ref
 results couldn't be escaped)

 * Eponymous templates can't have any members

 * Template pattern matching is incomplete

 * Overloading of templates with non-templates is poor

All details.
 I'll think of more annoyance factors in writing D code.

But someone else will actually die for what you are learning?
 I know the
 last two are an issue but not a very practical one.

You write about nothing.
 I'm
 doing my best to improve or eliminate before the broken behavior
 becomes too encroached.

That is a lie.
Nov 28 2010
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Jack schrieb:
 Andrei Alexandrescu wrote:
 On 11/28/10 10:19 PM, Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).


Ah ha! YOU voiced before Walt. ( So, as I am so knowing, can I moderate this discussion? )
 I can't think of a ranking of mistakes right
 now,

Are you a warrior, asked about your commander's "direction"?
 but some that come to mind are:

 * Not fixing switch

detail
 * scope variables

detail
 * delete (generally: an incompletely thought-out approach to garbage
 collection)

detail
 * typedef

detail
 * Escape rules are too lax (e.g. things could be a lot better if ref
 results couldn't be escaped)

 * Eponymous templates can't have any members

 * Template pattern matching is incomplete

 * Overloading of templates with non-templates is poor

All details.
 I'll think of more annoyance factors in writing D code.

But someone else will actually die for what you are learning?
 I know the
 last two are an issue but not a very practical one.

You write about nothing.
 I'm
 doing my best to improve or eliminate before the broken behavior
 becomes too encroached.

That is a lie.

Was your intention to start a constructive discussion or are was trolling the whole purpose of this thread?
Nov 28 2010
parent "Jack" <jt overlook.biz> writes:
Daniel Gibson wrote:
 Jack schrieb:
 Andrei Alexandrescu wrote:
 On 11/28/10 10:19 PM, Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at
 it, pick up the ball and run with it, don't be shy. I expect
 Walter and Andrei to answer (if Walter and Andrei so dare!) after
 others' posts have stopped or stagnated into that cesspool of
 threaded discussion that is "the subthread" or "tangential thread"
 (which surely needs a rock anthem).


Ah ha! YOU voiced before Walt. ( So, as I am so knowing, can I moderate this discussion? )
 I can't think of a ranking of mistakes right
 now,

Are you a warrior, asked about your commander's "direction"?
 but some that come to mind are:

 * Not fixing switch

detail
 * scope variables

detail
 * delete (generally: an incompletely thought-out approach to garbage
 collection)

detail
 * typedef

detail
 * Escape rules are too lax (e.g. things could be a lot better if ref
 results couldn't be escaped)

 * Eponymous templates can't have any members

 * Template pattern matching is incomplete

 * Overloading of templates with non-templates is poor

All details.
 I'll think of more annoyance factors in writing D code.

But someone else will actually die for what you are learning?
 I know the
 last two are an issue but not a very practical one.

You write about nothing.
 I'm
 doing my best to improve or eliminate before the broken behavior
 becomes too encroached.

That is a lie.

Was your intention to start a constructive discussion or are was trolling the whole purpose of this thread?

I was serious with my OP. Drink gets the better of me occassionally (yeah, on Sunday even.. oh well). Now I'm afraid to read the rest of the thread! (I am such an ass sometimes, geez).
Nov 29 2010
prev sibling parent Radu <rr foo.bar> writes:
On 11/29/2010 9:06 AM, Jack wrote:
 Andrei Alexandrescu wrote:
 On 11/28/10 10:19 PM, Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

Hrm, excellent challenge.

Ah ha! YOU voiced before Walt. ( So, as I am so knowing, can I moderate this discussion? )
 I can't think of a ranking of mistakes right
 now,

Are you a warrior, asked about your commander's "direction"?
 but some that come to mind are:

 * Not fixing switch

detail
 * scope variables

detail
 * delete (generally: an incompletely thought-out approach to garbage
 collection)

detail
 * typedef

detail
 * Escape rules are too lax (e.g. things could be a lot better if ref
 results couldn't be escaped)

 * Eponymous templates can't have any members

 * Template pattern matching is incomplete

 * Overloading of templates with non-templates is poor

All details.
 I'll think of more annoyance factors in writing D code.

But someone else will actually die for what you are learning?
 I know the
 last two are an issue but not a very practical one.

You write about nothing.
 I'm
 doing my best to improve or eliminate before the broken behavior
 becomes too encroached.

That is a lie.

Nov 29 2010
prev sibling next sibling parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Andrei Alexandrescu wrote:

 but some that come to mind are:

`with' ? -manfred
Nov 29 2010
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Manfred_Nowak schrieb:
 Andrei Alexandrescu wrote:
 
 but some that come to mind are:

`with' ? -manfred

What's wrong with "with"?
Nov 29 2010
next sibling parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Daniel Gibson wrote:

 What's wrong with "with"?

http://www.digitalmars.com/d/archives/digitalmars/D/with_should_be_deprecat ed_with_extreme_prejudice_90375.html#N90375 -manfred
Nov 29 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Manfred_Nowak:

 Daniel Gibson wrote:
 
 What's wrong with "with"?

http://www.digitalmars.com/d/archives/digitalmars/D/with_should_be_deprecat ed_with_extreme_prejudice_90375.html#N90375

Andrei said there:
 I think "with" is a very dangerous feature due to the way it hides 
 symbols. It essentially makes the feeblest attempt at modular reasoning 
 utterly impossible:
 
 int x, y;
 with (whatever)
 {
      y += x;
      ++x;
 }
 
 What can be said about such code? Nothing. If whatever has or will ever 
 have fields x or y or both, the names will bind to them; otherwise, 
 they'll bind to the locals. Non-local code dependency at its finest.

Today "with" is a bit tricky still, but its main problem that Andrei talks about has being patched. So this code: struct Foo { int x, y; } void main() { Foo f; int x, y; with (f) { y += x; ++x; } } Generates: temp.d(6): Error: with symbol temp.Foo.y is shadowing local symbol temp.main.y temp.d(6): Error: with symbol temp.Foo.x is shadowing local symbol temp.main.x temp.d(7): Error: with symbol temp.Foo.x is shadowing local symbol temp.main.x Bye, bearophile
Nov 29 2010
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
bearophile schrieb:
 Manfred_Nowak:
 
 Daniel Gibson wrote:

 What's wrong with "with"?

ed_with_extreme_prejudice_90375.html#N90375


I see
 Andrei said there:
 
 I think "with" is a very dangerous feature due to the way it hides 
 symbols. It essentially makes the feeblest attempt at modular reasoning 
 utterly impossible:

 int x, y;
 with (whatever)
 {
      y += x;
      ++x;
 }

 What can be said about such code? Nothing. If whatever has or will ever 
 have fields x or y or both, the names will bind to them; otherwise, 
 they'll bind to the locals. Non-local code dependency at its finest.

Today "with" is a bit tricky still, but its main problem that Andrei talks about has being patched. So this code: struct Foo { int x, y; } void main() { Foo f; int x, y; with (f) { y += x; ++x; } } Generates: temp.d(6): Error: with symbol temp.Foo.y is shadowing local symbol temp.main.y temp.d(6): Error: with symbol temp.Foo.x is shadowing local symbol temp.main.x temp.d(7): Error: with symbol temp.Foo.x is shadowing local symbol temp.main.x Bye, bearophile

Great, so "with" shouldn't be much of a problem anymore. I find it really handy, e.g. when dealing with enums (like in a switch() statement). Cheers, - Daniel
Nov 29 2010
parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Daniel Gibson wrote:

 "with" shouldn't be much of a problem anymore.

import std.stdio; struct X{ int a, b, c;} struct Y{ int a, b;} void main(){ X x; Y y; with( x){ c= 2; with( y){ c= 1; } } writeln( x.c); } Do you see the not "much of a problem"? -manfred
Nov 29 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 3:25 PM, Manfred_Nowak wrote:
 Daniel Gibson wrote:

 "with" shouldn't be much of a problem anymore.

import std.stdio; struct X{ int a, b, c;} struct Y{ int a, b;} void main(){ X x; Y y; with( x){ c= 2; with( y){ c= 1; } } writeln( x.c); } Do you see the not "much of a problem"? -manfred

Great. Could you please submit this as a bug report? In essence with should work as if this code was written: with (value) statement becomes { auto field1 = value.field1; auto field2 = value.field1; ... auto fieldn = value.fieldn; statement } The rewritten code is not equivalent because the field names are really references, but they must obey the same visibility rules. If the rewritten code has any shadowing errors, the use of with should also be in error. Andrei
Nov 29 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 Great. Could you please submit this as a bug report?

This shadowing is not detected :-( struct X { int a; } struct Y { int a; } void main() { X x; Y y; with (x) { a = 2; with (y) { a = 1; } } assert(x.a == 2); } Bye, bearophile
Nov 29 2010
prev sibling parent "Manfred_Nowak" <svv1999 hotmail.com> writes:
Andrei Alexandrescu wrote:

 please submit this as a bug report

No, thanks. I never liked the semantic of `with'. But a nearly perfect semantic has been choosen for the `import's. Please extend the scope of `import' for the name spaces resulting out of expressions to get rid of `with'. -manfred
Nov 29 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 5:34 AM, Manfred_Nowak wrote:
 Daniel Gibson wrote:

 What's wrong with "with"?

http://www.digitalmars.com/d/archives/digitalmars/D/with_should_be_deprecat ed_with_extreme_prejudice_90375.html#N90375 -manfred

Walter and I came to an understanding regarding symbol visibility that fixes that matter. I'm not sure whether he implemented it. Andrei
Nov 29 2010
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 5:48 AM, Andrej Mitrovic wrote:
 The licensing issues with DMD. I get the feeling we would have many
 more contributors to the reference compiler and have bugs fixed at a
 much faster rate than right now. Walter is already working at 110% of
 his abilities, at least that's the impression I get. I think maybe D2
 has grown beyond anyone's expectations, so now the compiler team
 (Walter&  Don I guess?) has to chase down all the features that D2 is
 supossed to have and implement them.

 I don't think its feasible for such a small team to fix that many bugs
 for a huge language like D2, at least not in a short-term timeline.
 And Bugzilla seems to grow day by day with no end in sight.

One metric I proposed to Walter is the "bug age", i.e. the date of the oldest unfixed bug. If we prioritize bugs by importance first and chronological second, I think we can get into a schedule that systematically reduces the age of the oldest bug and then keep it constant. Right now the process of choosing which bug to fix next is unstructured. Andrei
Nov 29 2010
parent dolive <dolive89 sina.com> writes:
Andrei Alexandrescu Wrote:

 On 11/29/10 5:48 AM, Andrej Mitrovic wrote:
 The licensing issues with DMD. I get the feeling we would have many
 more contributors to the reference compiler and have bugs fixed at a
 much faster rate than right now. Walter is already working at 110% of
 his abilities, at least that's the impression I get. I think maybe D2
 has grown beyond anyone's expectations, so now the compiler team
 (Walter&  Don I guess?) has to chase down all the features that D2 is
 supossed to have and implement them.

 I don't think its feasible for such a small team to fix that many bugs
 for a huge language like D2, at least not in a short-term timeline.
 And Bugzilla seems to grow day by day with no end in sight.

One metric I proposed to Walter is the "bug age", i.e. the date of the oldest unfixed bug. If we prioritize bugs by importance first and chronological second, I think we can get into a schedule that systematically reduces the age of the oldest bug and then keep it constant. Right now the process of choosing which bug to fix next is unstructured. Andrei

bye dolive
Nov 29 2010
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
The licensing issues with DMD. I get the feeling we would have many
more contributors to the reference compiler and have bugs fixed at a
much faster rate than right now. Walter is already working at 110% of
his abilities, at least that's the impression I get. I think maybe D2
has grown beyond anyone's expectations, so now the compiler team
(Walter & Don I guess?) has to chase down all the features that D2 is
supossed to have and implement them.

I don't think its feasible for such a small team to fix that many bugs
for a huge language like D2, at least not in a short-term timeline.
And Bugzilla seems to grow day by day with no end in sight.

On 11/29/10, Daniel Gibson <metalcaedes gmail.com> wrote:
 Manfred_Nowak schrieb:
 Andrei Alexandrescu wrote:

 but some that come to mind are:

`with' ? -manfred

What's wrong with "with"?

Nov 29 2010
parent dolive <dolive89 sina.com> writes:
Andrej Mitrovic Wrote:

 The licensing issues with DMD. I get the feeling we would have many
 more contributors to the reference compiler and have bugs fixed at a
 much faster rate than right now. Walter is already working at 110% of
 his abilities, at least that's the impression I get. I think maybe D2
 has grown beyond anyone's expectations, so now the compiler team
 (Walter & Don I guess?) has to chase down all the features that D2 is
 supossed to have and implement them.
 
 I don't think its feasible for such a small team to fix that many bugs
 for a huge language like D2, at least not in a short-term timeline.
 And Bugzilla seems to grow day by day with no end in sight.
 
 On 11/29/10, Daniel Gibson <metalcaedes gmail.com> wrote:
 Manfred_Nowak schrieb:
 Andrei Alexandrescu wrote:

 but some that come to mind are:

`with' ? -manfred

What's wrong with "with"?


This is a serious problem in the hope as the highest priority . bye dolive
Nov 29 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 * Not fixing switch

Walter has vaguely accepted to somehow fix this, requiring a flow control for each case statement (but other people immediately have asked to special case this again).
 * scope variables

Fixed?
 * delete (generally: an incompletely thought-out approach to garbage 
 collection)

Partially Fixed?
 * typedef

Fixed.
 * Escape rules are too lax (e.g. things could be a lot better if ref 
 results couldn't be escaped)

May be fixed still.
 * Eponymous templates can't have any members

I think this is fixable still.
 * Template pattern matching is incomplete

I don't understand this, please explain better. But I think the syntax of is() is awful and I'd like to shoot it.
 * Overloading of templates with non-templates is poor

Can't this be fixed still? Bye, bearophile
Nov 29 2010
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 6:18 AM, bearophile wrote:
 Andrei:
 * Template pattern matching is incomplete

I don't understand this, please explain better. But I think the syntax of is() is awful and I'd like to shoot it.

is() should do full tree unification on the query type and the pattern. It currently does a partial unification that is inadequate. Andrei
Nov 29 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
spir:

 Andrej Mitrovic:
 
 constraint
 {
     isDynamicArray(a);
     isIterable(a);
 }
 body
 {
     ...
 }


 I like very much the idea of constraint blocks. Much better than expanding
func header line, reuses an existing syntactic construct, and far cleaner.

But I'd like that syntax to allow for an error message for each constraint. So it becomes like contract programming, done at compile-time on types and compile-time constants, and the "in" keyword is enough: in { static assert(isDynamicArray!T, "err msg 1"); static assert(isIterable!T, "err msg 2"); ... } body { ... } Bye, bearophile
Nov 30 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Simen kjaeraas:

 The problem with such a solution is that the compiler needs to evaluate
 the 'in' clause differently from all other code, as code further down in
 the 'in' clause could use parameters in a way that would be illegal at
 compile-time. Hence the new keyword

I see.
 or, for giggles, why not 'static in'?

"static in" sounds acceptable :-) Bye, bearophile
Nov 30 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Simen kjaeraas:

 In my opinion, the syntax for is() is not all that bad.

Every time I have to use is() for something a bit more complex than just type equivalence, I have to go read the D docs, despite I have used it many times. But now I have memorized most other parts of D syntax.
 - It lacks is ( Type : TypeSpecialization , TemplateParameterList ) and
      is ( Type == TypeSpecialization , TemplateParameterList )

I think is() needs less stuff, not more. The functionality needs to be moved to a nicer syntax (and according to Andrei a better semantics too). Bye, bearophile
Nov 30 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
"with" is almost convenient in some cases, but I have to admit every
time I'm inside a with block I'm never absolutely sure which variables
I'm accessing. There's still that situation where I might think I'm
accessing a member variable, but it turns out the member variable
doesn't exist and there just happens to be a local with the same name.
I won't get a warning for that. e.g.:

struct S
{ int r, g; }
void main()
{
    bool b;  // just some state variable..
    // a ton of more code..
    S s;
    with (s)
    {
        writefln("r: %s g: %s b: %s", r, g, b);  // woops, S doesn't
have b but we might get the impression that it does
    }
}

It's tricky to use "with" and be 100% safe.

Here's one older example of using with blocks to create anonymous
objects (Scintilla in this case):
http://pastebin.com/kiXPeQLB

On 11/29/10, bearophile <bearophileHUGS lycos.com> wrote:
 Manfred_Nowak:

 Daniel Gibson wrote:

 What's wrong with "with"?

http://www.digitalmars.com/d/archives/digitalmars/D/with_should_be_deprecat ed_with_extreme_prejudice_90375.html#N90375

Andrei said there:
 I think "with" is a very dangerous feature due to the way it hides
 symbols. It essentially makes the feeblest attempt at modular reasoning
 utterly impossible:

 int x, y;
 with (whatever)
 {
      y += x;
      ++x;
 }

 What can be said about such code? Nothing. If whatever has or will ever
 have fields x or y or both, the names will bind to them; otherwise,
 they'll bind to the locals. Non-local code dependency at its finest.

Today "with" is a bit tricky still, but its main problem that Andrei talks about has being patched. So this code: struct Foo { int x, y; } void main() { Foo f; int x, y; with (f) { y += x; ++x; } } Generates: temp.d(6): Error: with symbol temp.Foo.y is shadowing local symbol temp.main.y temp.d(6): Error: with symbol temp.Foo.x is shadowing local symbol temp.main.x temp.d(7): Error: with symbol temp.Foo.x is shadowing local symbol temp.main.x Bye, bearophile

Nov 29 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 11/29/10, bearophile <bearophileHUGS lycos.com> wrote:
 * Template pattern matching is incomplete

I don't understand this, please explain better. But I think the syntax of is() is awful and I'd like to shoot it.

+1. I'd prefer if we had a constraint block of some kind. I mean we already have in/out contracts which look very nice: void somefunc() in { // ...contract preconditions... } out (result) { // ...contract postconditions... } body { // ...code... } Why not do the same for templates? Something like this: void foo(A, B, C)(A a, B b, C c) constraint { isDynamicArray(a); isIterable(a); } body { ... }
Nov 29 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 11/29/10, bearophile <bearophileHUGS lycos.com> wrote:
 * Template pattern matching is incomplete

I don't understand this, please explain better. But I think the syntax of is() is awful and I'd like to shoot it.

+1. I'd prefer if we had a constraint block of some kind. I mean we already have in/out contracts which look very nice: void somefunc() in { // ...contract preconditions... } out (result) { // ...contract postconditions... } body { // ...code... } Why not do the same for templates? Something like this: void foo(A, B, C)(A a, B b, C c) constraint { isDynamicArray(a); isIterable(a); } body { ... } So maybe every statement would be checked for the return value, and you would get the exact line where a constraint failed when instantiating a template. Just a passing thought anyway..
Nov 29 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Sorry for the repost!

On 11/29/10, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 On 11/29/10, bearophile <bearophileHUGS lycos.com> wrote:
 * Template pattern matching is incomplete

I don't understand this, please explain better. But I think the syntax of is() is awful and I'd like to shoot it.

+1. I'd prefer if we had a constraint block of some kind. I mean we already have in/out contracts which look very nice: void somefunc() in { // ...contract preconditions... } out (result) { // ...contract postconditions... } body { // ...code... } Why not do the same for templates? Something like this: void foo(A, B, C)(A a, B b, C c) constraint { isDynamicArray(a); isIterable(a); } body { ... } So maybe every statement would be checked for the return value, and you would get the exact line where a constraint failed when instantiating a template. Just a passing thought anyway..

Nov 29 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 Why not do the same for templates? Something like this:

 void foo(A, B, C)(A a, B b, C c)
 constraint
 {
     isDynamicArray(a);
     isIterable(a);

 }

Consider: void foo( A )( A a ) constraint { isBar!A; } void foo( B )( B a ) constraint { isQux!B; } Which error message should I show? -- Simen
Nov 29 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 11/29/10, Simen kjaeraas <simen.kjaras gmail.com> wrote:
 Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 Why not do the same for templates? Something like this:

 void foo(A, B, C)(A a, B b, C c)
 constraint
 {
     isDynamicArray(a);
     isIterable(a);

 }

Consider: void foo( A )( A a ) constraint { isBar!A; } void foo( B )( B a ) constraint { isQux!B; } Which error message should I show? -- Simen

I'm not sure what you're getting at. :) What I meant was something like the following example: import std.stdio; import std.range; void myreverse(Range)(Range r) if (isBidirectionalRange!(Range) && hasSwappableElements!(Range) && is(Range == int[])) { } void main() { uint[] x = [4, 5, 6]; myreverse(x); } Here you get 2 very long error messages which don't help you much at all: constraints.d(14): Error: template constraints.myreverse(Range) if (isBidirectio nalRange!(Range) && hasSwappableElements!(Range) && is(Range == int[])) does not match any function template declaration constraints.d(14): Error: template constraints.myreverse(Range) if (isBidirectio nalRange!(Range) && hasSwappableElements!(Range) && is(Range == int[])) cannot d educe template function from argument types !()(uint[]) The compiler never tells you which of the calls in the constraint returned false, whether it was isBidirectionalRange, hasSwappableElements, or the last "is(Range == int[])", since it's all wrapped in a big if block and the compiler only cares if the block evaluates to true or false. What I would prefer is if we had code similar to this: import std.stdio; import std.range; void myreverse(Range)(Range r) constraints { isBidirectionalRange!(Range); hasSwappableElements!(Range); is(Range == int[]); } body { } void main() { uint[] x = [4, 5, 6]; myreverse(x); } And the compiler would check to see that all the statements (expressions?) in the constraint block evaluate to true, otherwise it would show a more informative error message, e.g.: constraints.d(14): Error: template myreverse(Range) failed to instantiate due to the following failed constraints: (45) is(Range == int[]); using argument types !()(uint[]) So a line number and the failed code in the constraint. If there are multiple failed statements then it would list them all. Of course this would mean that a constraint block is a special place, but templates are special enough to have this constraint block, imo. Error messages are the primary reason why I'd want constraint blocks, because otherwise template errors can be quite uninformative. But anyway it's just an idea and I'm probably missing something important, I haven't used D in a while..
Nov 29 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 Which error message should I show?


 But anyway it's just an idea and I'm probably missing something
 important, I haven't used D in a while..

I believe you are missing that more templates could bear the same name, and they could all fail for varying reasons. In such a case, do you print the error messages from 100 templates and let the user sort through them, or do you show the error the compiler currently shows? I admit my example was flawed, or at least incomplete:
 void foo( A )( A a )
 constraint {
    isBar!A;
 }

 void foo( B )( B a )
 constraint {
    isQux!B;
 }

void main( ) { int n; assert( !isBar!int ); assert( !isQux!int ); foo( n ); } The call to foo would match neither template, giving errors akin to this: test.d(15) Error: template instantiation foo!int failed. test.d(3) Error: template constraint failed test.d(6) Error: template constraint failed Seems good for two or three templates, but I fear this would grow quickly out of hand for more templates. -- Simen
Nov 29 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 11/30/10, Simen kjaeraas <simen.kjaras gmail.com> wrote:
 Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 Which error message should I show?


 But anyway it's just an idea and I'm probably missing something
 important, I haven't used D in a while..

I believe you are missing that more templates could bear the same name, and they could all fail for varying reasons. In such a case, do you print the error messages from 100 templates and let the user sort through them, or do you show the error the compiler currently shows? I admit my example was flawed, or at least incomplete:
 void foo( A )( A a )
 constraint {
    isBar!A;
 }

 void foo( B )( B a )
 constraint {
    isQux!B;
 }

void main( ) { int n; assert( !isBar!int ); assert( !isQux!int ); foo( n ); } The call to foo would match neither template, giving errors akin to this: test.d(15) Error: template instantiation foo!int failed. test.d(3) Error: template constraint failed test.d(6) Error: template constraint failed Seems good for two or three templates, but I fear this would grow quickly out of hand for more templates. -- Simen

Ah, yeah you would be right. I'm not sure, maybe the template with the least amount of failed statements would be displayed as a closest-but failed-match, and others would not be shown. Otherwise we would have error message bloat.
Nov 29 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Mon, 29 Nov 2010 16:43:01 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:
 On 11/29/10 3:25 PM, Manfred_Nowak wrote:
 Daniel Gibson wrote:

 "with" shouldn't be much of a problem anymore.

import std.stdio; struct X{ int a, b, c;} struct Y{ int a, b;} void main(){ X x; Y y; with( x){ c= 2; with( y){ c= 1; } } writeln( x.c); } Do you see the not "much of a problem"? -manfred

Great. Could you please submit this as a bug report?

It looks like it's actually an old bug: http://d.puremagic.com/issues/show_bug.cgi?id=1849
Nov 29 2010
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On Mon, 29 Nov 2010 07:18:42 -0500
bearophile <bearophileHUGS lycos.com> wrote:

 * Template pattern matching is incomplete =20

I don't understand this, please explain better. But I think the syntax of=

+++ (I think it is not even fixable; the issue may not be syntactic. Rather we = may watch the point of stating type capabilities from a different pov, like= eg using interfaces.) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 30 2010
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On Mon, 29 Nov 2010 12:31:42 +0000
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 constraint
 {
     isDynamicArray(a);
     isIterable(a);
 }
 body
 {
     ...
 }
=20
 So maybe every statement would be checked for the return value, and
 you would get the exact line where a constraint failed when
 instantiating a template.
=20
 Just a passing thought anyway..

I like very much the idea of constraint blocks. Much better than expanding = func header line, reuses an existing syntactic construct, and far cleaner. But what is wrong with using interfaces (or abstract classes) instead of ha= ving to write custom type-checking funcs? If only as style guidelines: constraint { a isa DynamicArray; a isa Iterable; } The language could provide abstract classes for commonly checked capabiliti= es of builtin types. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 30 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:

 I like very much the idea of constraint blocks. Much better than  
 expanding func header line, reuses an existing syntactic construct, and  
 far cleaner.

But I'd like that syntax to allow for an error message for each constraint. So it becomes like contract programming, done at compile-time on types and compile-time constants, and the "in" keyword is enough: in { static assert(isDynamicArray!T, "err msg 1"); static assert(isIterable!T, "err msg 2"); ... } body { ... }

The problem with such a solution is that the compiler needs to evaluate the 'in' clause differently from all other code, as code further down in the 'in' clause could use parameters in a way that would be illegal at compile-time. Hence the new keyword or, for giggles, why not 'static in'? -- Simen
Nov 30 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:

 I think the syntax of is() is awful and I'd like to shoot it.

In my opinion, the syntax for is() is not all that bad. However: - It lacks is ( Type : TypeSpecialization , TemplateParameterList ) and is ( Type == TypeSpecialization , TemplateParameterList ) - It does not deduce base templates. Given is ( T == U!V, U, V... ), it fails. Given is ( T == MyTemplate!U, U... ), it works. -- Simen
Nov 30 2010
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:

 - It lacks is ( Type : TypeSpecialization , TemplateParameterList ) and
      is ( Type == TypeSpecialization , TemplateParameterList )

I think is() needs less stuff, not more. The functionality needs to be moved to a nicer syntax (and according to Andrei a better semantics too).

The versions I suggest 'is' lacks are simplifications of existing options, and would IMO simplify the feature. I also feel that is() is logical. That is, the parts without the Identifier. is( A : B ) makes sense, as does is( A == B ) and is( A : B!T, T... ). is( A B : C!T*, T... ), on the other hand... -- Simen
Nov 30 2010
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
Jack Wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it, 
 pick up the ball and run with it, don't be shy. I expect Walter and 
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have 
 stopped or stagnated into that cesspool of threaded discussion that is 
 "the subthread" or "tangential thread" (which surely needs a rock 
 anthem).

What I can see now, mistakes are mostly syntactical like switch, auto, const, rebindable, array ops, full slice, arbitrary-code-contracts instead of single bool expression. Choice for round braces for templates leads to slightly unreadable template code: foo!(params params)(yet more params). Omissible parens feel like omissible semicolons :-/ Implicitly nested classes. Versions should be typed variables. C baggage is still around. Extensive use of unsigned ints. Well, I admit, properties are hard to get good. Zealous backward compatibility with baggage, early desing and legacy code: these issues are no more fixable, I'm afraid.
Nov 28 2010
next sibling parent Kagamin <spam here.lot> writes:
Kagamin Wrote:

 Zealous backward compatibility with baggage, early desing and legacy code:
these issues are no more fixable, I'm afraid.

Just look how much pain this caused to java. Even java community is ready for breaking changes, but they can't be done.
Nov 28 2010
prev sibling parent so <so so.do> writes:
 What I can see now, mistakes are mostly syntactical like switch, auto,  
 const, rebindable, array ops, full slice, arbitrary-code-contracts  
 instead of single bool expression. Choice for round braces for templates  
 leads to slightly unreadable template code: foo!(params params)(yet more  
 params). Omissible parens feel like omissible semicolons :-/
 Implicitly nested classes.
 Versions should be typed variables.
 C baggage is still around.
 Extensive use of unsigned ints.
 Well, I admit, properties are hard to get good.

 Zealous backward compatibility with baggage, early desing and legacy  
 code: these issues are no more fixable, I'm afraid.

I agree on switch, version, backwards compatibility and maybe "const" but could you at least give a few examples to others or give some links to your reasoning? For example what is wrong with auto? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 29 2010
prev sibling next sibling parent reply Bane <branimir.milosavljevic gmail.com> writes:
Lot of small things, details, that are not showstoppers but leave impression of
unfinished business.

First thing that come to my mind is lack of "bud" (build) building support
where you point only to main.d file, and all other modules are imported. I
think that is the ting required to bee in compiler itself, not in one of the
numerous third party building scripts (how many are them there?)

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it, 
 pick up the ball and run with it, don't be shy. I expect Walter and 
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have 
 stopped or stagnated into that cesspool of threaded discussion that is 
 "the subthread" or "tangential thread" (which surely needs a rock 
 anthem). 
 
 

Nov 29 2010
parent "Nick Sabalausky" <a a.a> writes:
"Bane" <branimir.milosavljevic gmail.com> wrote in message 
news:icvscq$1epk$1 digitalmars.com...
 Lot of small things, details, that are not showstoppers but leave 
 impression of unfinished business.

 First thing that come to my mind is lack of "bud" (build) building support 
 where you point only to main.d file, and all other modules are imported. I 
 think that is the ting required to bee in compiler itself, not in one of 
 the numerous third party building scripts (how many are them there?)

You can do it just fine with RDMD which comes with DMD (at least with some of the patches I submitted to bugzilla: http://d.puremagic.com/issues/buglist.cgi?quicksearch=rdmd+%5Bpatch%5D )
Nov 29 2010
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it, 
 pick up the ball and run with it, don't be shy. I expect Walter and 
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have 
 stopped or stagnated into that cesspool of threaded discussion that is 
 "the subthread" or "tangential thread" (which surely needs a rock 
 anthem). 

D has been far too ambitious, given the available resources.
Nov 29 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Don:

 D has been far too ambitious, given the available resources.

My opinion is a bit different. The Haskell motto is: "Avoid success at all costs". This because the more complex a language is, the more time it needs to develop its features in a good way. If a language has too much early success, its features can't be changed, because people ask for some backward compatibility, so the design errors can't be fixed. D has had the very unusual chance to fix itself, with the D2 language not backward compatible. But then it was finalized too much early, this is in my opinion the greatest D2 mistake. D2 is a C++-class language, so it's large and complex, so it needs some other years to be designed well. Bye, bearophile
Nov 29 2010
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 3:42 AM, Don wrote:
 Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

D has been far too ambitious, given the available resources.

I agree with this assessment. Well put! Andrei
Nov 29 2010
prev sibling parent spir <denis.spir gmail.com> writes:
On Mon, 29 Nov 2010 07:13:20 -0500
bearophile <bearophileHUGS lycos.com> wrote:

 D has had the very unusual chance to fix itself, with the D2 language not=

my opinion the greatest D2 mistake. D2 is a C++-class language, so it's lar= ge and complex, so it needs some other years to be designed well. I agree with this. This has also to do with the early publication of TDPL. = On one hand, it is great to have it. On the other, using as reference speci= fication the description of not-even implemented features seems at best str= ange. Usually, one would have at least: 0. discussion of semantics 1. trial implementation 2. trial use 3. final adoption Here, steps 1-2-3 are shortcut. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 30 2010
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 28 Nov 2010 23:19:44 -0500, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

As I understand this is a troll post, but still provoked some good discussion, I'll throw in my biggest problem with D: lack of tail-const/immutable for classes. And no, Rebindable doesn't cut it. -Steve
Nov 29 2010
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message 
news:op.vmxqi4kmeav7ka steve-laptop...
 On Sun, 28 Nov 2010 23:19:44 -0500, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

As I understand this is a troll post, but still provoked some good discussion, I'll throw in my biggest problem with D: lack of tail-const/immutable for classes.

I've heard this before, but I'm a little unclear. Can you give an example?
Nov 29 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 10:12 AM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 10:54:04 -0500, Nick Sabalausky <a a.a> wrote:

 "Steven Schveighoffer" <schveiguy yahoo.com> wrote in message
 news:op.vmxqi4kmeav7ka steve-laptop...
 On Sun, 28 Nov 2010 23:19:44 -0500, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

As I understand this is a troll post, but still provoked some good discussion, I'll throw in my biggest problem with D: lack of tail-const/immutable for classes.

I've heard this before, but I'm a little unclear. Can you give an example?

This is a tail-const pointer: const(int)* ptr; I can reassign ptr at will: ptr = &x; ptr = &y; but I can't change what ptr points to: *ptr = 5; // error Because classes are references, just like pointers, I would like a way to have a tail-const class reference. But it's not possible: const(C) myref; myref = a; // error, cannot change const myref You can have a tail-const pointer to a class reference: C myref; const(C) *myrefptr = &myref; But a class is on the heap, and the reference 'myref' is on the stack, so myrefptr is only usable locally. In order to keep the 'infinite' lifetime property, I have to create a class reference on the heap, and then return a pointer to *that*. Just try to create a class reference on the heap. Not only that, but I now have to waste 16 bytes of heap space just to have a tail-const class reference, *just because* the syntax is incomplete. I find this unacceptable. -Steve

Syntax is the main issue in implementing this feature. Due to the implicit nature of reference semantics for classes, there was no syntax to distinguish between the head and the tail when qualifying. FWIW I just thought of this syntax. It might work but it's not intuitive: const()C tailConst; Ultimately I believe we need to make Rebindable palatable. That would have the nice side effect of enabling other proxy types. Andrei
Nov 29 2010
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article

 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.
 Andrei

I've asked before and I'll ask again, what's still wrong with Rebindable? A bunch of alias this issues got fixed in 2.050, and I fixed a bunch of misc. convenience issues a few releases ago. I fail to see the problem with it anymore.
Nov 29 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 1:35 PM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:52:31 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s
 article

 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.
 Andrei

I've asked before and I'll ask again, what's still wrong with Rebindable? A bunch of alias this issues got fixed in 2.050, and I fixed a bunch of misc. convenience issues a few releases ago. I fail to see the problem with it anymore.

Every few months or so, someone finds a problem with it. It seems that it's good enough in theory, but miserably fails in practice when someone tries to use it. I admit I haven't looked at it in a while, but there are implicit casting problems that cannot be solved without compiler help. I just think Rebindable will get more and more convoluted until someone finally admits that this is better served as a builtin feature.

I don't grok this. If people find different issues with it that are fixed, then there is progress, right? (Clearly "escaping" into the language makes things better.)
 One of those issues:

 import std.typecons;

 class C {}

 void foo(Rebindable!(const C) c)
 {
 }

Let me fix that: void foo(const C c) { auto rc = Rebindable!(const C)(c); ... } Andrei
Nov 29 2010
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 1:38 PM, Andrei Alexandrescu wrote:
 On 11/29/10 1:35 PM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:52:31 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s
 article

 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.
 Andrei

I've asked before and I'll ask again, what's still wrong with Rebindable? A bunch of alias this issues got fixed in 2.050, and I fixed a bunch of misc. convenience issues a few releases ago. I fail to see the problem with it anymore.

Every few months or so, someone finds a problem with it. It seems that it's good enough in theory, but miserably fails in practice when someone tries to use it. I admit I haven't looked at it in a while, but there are implicit casting problems that cannot be solved without compiler help. I just think Rebindable will get more and more convoluted until someone finally admits that this is better served as a builtin feature.

I don't grok this. If people find different issues with it that are fixed, then there is progress, right? (Clearly "escaping" into the language makes things better.)
 One of those issues:

 import std.typecons;

 class C {}

 void foo(Rebindable!(const C) c)
 {
 }

Let me fix that: void foo(const C c) { auto rc = Rebindable!(const C)(c); ... }

That also reminds me we need a function: void foo(const C c) { auto rc = rebindable(c); ... } Andrei
Nov 29 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 1:49 PM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 14:38:40 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 11/29/10 1:35 PM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:52:31 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s
 article

 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.
 Andrei

I've asked before and I'll ask again, what's still wrong with Rebindable? A bunch of alias this issues got fixed in 2.050, and I fixed a bunch of misc. convenience issues a few releases ago. I fail to see the problem with it anymore.

Every few months or so, someone finds a problem with it. It seems that it's good enough in theory, but miserably fails in practice when someone tries to use it. I admit I haven't looked at it in a while, but there are implicit casting problems that cannot be solved without compiler help. I just think Rebindable will get more and more convoluted until someone finally admits that this is better served as a builtin feature.

I don't grok this. If people find different issues with it that are fixed, then there is progress, right? (Clearly "escaping" into the language makes things better.)

At some point, Rebindable may be as good as a language feature. But we haven't got there yet. And we haven't got there in years. And I don't see us getting there in the forseeable future -- there are too many implicit casting problems to solve. At the point where it does become useable, how big will it be? How much will it slow down compilation? How specialized do we have to make code? Const is supposed to be a compile-time feature, optimized out at runtime. If Rebindable isn't completely removed from the code generation, then it is not a complete feature.

I don't think compilation speed and runtime speed are the main challenges. All of Rebindable's methods are one-liners. The issue with Rebindable is integration within the type system.
 One of those issues:

 import std.typecons;

 class C {}

 void foo(Rebindable!(const C) c)
 {
 }

Let me fix that: void foo(const C c) { auto rc = Rebindable!(const C)(c); ... }

You missed the point.. completely :) please look at bar.

You're right. bar is the part that alias this needs to take care of. So in a way this is an easier problem to solve. Andrei
Nov 29 2010
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-29 11:19:29 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Syntax is the main issue in implementing this feature. Due to the 
 implicit nature of reference semantics for classes, there was no syntax 
 to distinguish between the head and the tail when qualifying.
 
 FWIW I just thought of this syntax. It might work but it's not intuitive:
 
 const()C tailConst;

I proposed the following a while ago. First allow the class reference to (optionally) be made explicit: C a; // mutable reference to mutable class C ref b; // mutable reference to mutable class And now you can apply tail-const to it: const(C)ref c; // mutable reference to const class const(C ref) d; // const reference to const class const(C) e; // const reference to const class I think it's better.
 Ultimately I believe we need to make Rebindable palatable. That would 
 have the nice side effect of enabling other proxy types.

The biggest problem I see is with generic programming. Say I pass Rebindable!(const C) as a template argument, then the template wants to make it const: should it become const(Rebindable!(const C)), or will this be resolved to const(C)? You don't have this problem with pointers: const(const(int)*) is the same type as const(int*). If 'const' was a template, you could specialize it to do the same for Rebindable. But 'const' is a language thing, and it seems utterly inappropriate to make const aware of Rebindable so that const(Rebindable!...)) would drop the Rebindable, and thus you get the above silliness. I'm all for making proxy types work better, but it'll always feel patchy in this case. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 29 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 10:54 AM, Michel Fortin wrote:
 On 2010-11-29 11:19:29 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 Syntax is the main issue in implementing this feature. Due to the
 implicit nature of reference semantics for classes, there was no
 syntax to distinguish between the head and the tail when qualifying.

 FWIW I just thought of this syntax. It might work but it's not intuitive:

 const()C tailConst;

I proposed the following a while ago. First allow the class reference to (optionally) be made explicit: C a; // mutable reference to mutable class C ref b; // mutable reference to mutable class And now you can apply tail-const to it: const(C)ref c; // mutable reference to const class const(C ref) d; // const reference to const class const(C) e; // const reference to const class I think it's better.
 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.

The biggest problem I see is with generic programming. Say I pass Rebindable!(const C) as a template argument, then the template wants to make it const: should it become const(Rebindable!(const C)), or will this be resolved to const(C)?

const should follow normal logic, and const(Rebindable!(const C)) should behave as expected. Andrei
Nov 29 2010
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-29 13:08:54 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 11/29/10 10:54 AM, Michel Fortin wrote:
 The biggest problem I see is with generic programming. Say I pass
 Rebindable!(const C) as a template argument, then the template wants to
 make it const: should it become const(Rebindable!(const C)), or will
 this be resolved to const(C)?

const should follow normal logic, and const(Rebindable!(const C)) should behave as expected.

I think we agree on that. The problem is that you now have two distinct types to mean a const reference to a const object. You have "const(Rebindable!(const C))" and const "const(C)", whichever you get depends on where the type comes from. Type equality won't work between the two, and you won't be able to concatenate two arrays one containing rebindables and the other (for instance). It's like a special case in the type system where constness is implemented using a template while the rest is a language feature, it it thus behave differently and code that might work for one implementation of constness might break with the other, because the don't play with each other very well. Add immutable to the mix and it becomes even stranger. For instance, here's a tricky question: should Unqual!(const C) give you a const(C), a Rebindable!(const C), or simply C? Now, what should const(Unqual!(immutable C)) give you? I know most of the problems are going to be edge cases most people don't care about. But on the whole, creating a fragile and complex solution to work around the lack of an inspiring syntax seems rather silly. I would immensely prefer having an ugly syntax that works as it should. If it's too ugly, we can still hide that syntax behind Rebindable by defining it as a simple type alias. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 29 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 12:56 PM, Michel Fortin wrote:
 On 2010-11-29 13:08:54 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 11/29/10 10:54 AM, Michel Fortin wrote:
 The biggest problem I see is with generic programming. Say I pass
 Rebindable!(const C) as a template argument, then the template wants to
 make it const: should it become const(Rebindable!(const C)), or will
 this be resolved to const(C)?

const should follow normal logic, and const(Rebindable!(const C)) should behave as expected.

I think we agree on that. The problem is that you now have two distinct types to mean a const reference to a const object. You have "const(Rebindable!(const C))" and const "const(C)", whichever you get depends on where the type comes from. Type equality won't work between the two, and you won't be able to concatenate two arrays one containing rebindables and the other (for instance). It's like a special case in the type system where constness is implemented using a template while the rest is a language feature, it it thus behave differently and code that might work for one implementation of constness might break with the other, because the don't play with each other very well. Add immutable to the mix and it becomes even stranger. For instance, here's a tricky question: should Unqual!(const C) give you a const(C), a Rebindable!(const C), or simply C?

C.
 Now, what should
 const(Unqual!(immutable C)) give you?

const(C).
 I know most of the problems are going to be edge cases most people don't
 care about. But on the whole, creating a fragile and complex solution to
 work around the lack of an inspiring syntax seems rather silly. I would
 immensely prefer having an ugly syntax that works as it should. If it's
 too ugly, we can still hide that syntax behind Rebindable by defining it
 as a simple type alias.

Rebindable, if properly executed, is not fragile and complex. Instead it is a simple solution for a specific problem: I want a class reference that I need to bind to different const class objects. If you apply const to Rebindable, normal rules enter in action. I agree that a built-in component can be made nicer by adding extra short-circuit rules. Andrei
Nov 29 2010
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-29 14:03:27 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 For instance, here's a tricky question: should Unqual!(const C) give you
 a const(C), a Rebindable!(const C), or simply C?

C.
 Now, what should
 const(Unqual!(immutable C)) give you?

const(C).

As I thought. Now consider this generic code that uses Unqual: T[] giveMeASortedArray(alias Predicate, T)(T[] t) { // creating new array of the same length but with assignable elements auto copy = new Unqual!(typeof(t[0]))[t.length]; // using a loop because copy[] = t[] doesn't enforce const properly! foreach (index, value; t) copy[index] = value; // sorting the copy sort!(Predicate)(copy); return copy; } The above algorithm will work for types like const(int*), but it breaks if T is const(C) and C is a class. So it seems we'll need a special cases for generic algorithms to work for classes. That's what I meant when I say Rebindable is a fragile solution. It works in most cases, but it breaks in some others, mostly when you want to be generic. So here's the challenge for you Andrei: find a way to make this code work without special-casing things for classes. The "giveMeASortedArray" function needs to return a new array containing all the elements of the original array, sorted according to the predicate. Here's my test case (the last line is the tricky one): int*[] a = giveMeASortedArray!("a < b")(new int*[12]); Object[] b = giveMeASortedArray!("a < b")(new Object[12]); const(int*)[] c = giveMeASortedArray!("a < b")(new const(int*)[12]); const(Object)[] d = giveMeASortedArray!("a < b")(new const(Object)[12]); Good luck. It's doable using convoluted means and special-casing things for classes, but that'll just prove my point that Rebindable isn't a good solution. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 29 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 7:52 PM, Michel Fortin wrote:
 On 2010-11-29 14:03:27 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 For instance, here's a tricky question: should Unqual!(const C) give you
 a const(C), a Rebindable!(const C), or simply C?

C.
 Now, what should
 const(Unqual!(immutable C)) give you?

const(C).

As I thought. Now consider this generic code that uses Unqual: T[] giveMeASortedArray(alias Predicate, T)(T[] t) { // creating new array of the same length but with assignable elements auto copy = new Unqual!(typeof(t[0]))[t.length]; // using a loop because copy[] = t[] doesn't enforce const properly! foreach (index, value; t) copy[index] = value; // sorting the copy sort!(Predicate)(copy); return copy; } The above algorithm will work for types like const(int*), but it breaks if T is const(C) and C is a class. So it seems we'll need a special cases for generic algorithms to work for classes. That's what I meant when I say Rebindable is a fragile solution. It works in most cases, but it breaks in some others, mostly when you want to be generic. So here's the challenge for you Andrei:

I agree that the problem is difficult but disagree with the angle. This is not the challenge, and it is not only mine to take. To the extent we're interested in making D a successful language, we're all on the same boat, so the challenge belongs to us all. Adding a new type constructor to the language or generally a new feature is always possible, but has a high cost. Half of the community throws their hand in the air with each new feature, and the other half throws them in the air for each feature that could have been. The key is to navigate such that as many good designs are expressible as easily as possible. The real challenge is to solve the problem within the global set of constraints we have, not to prove that a language feature would solve it. I know a language feature would take care of the issue, the same way money would take care of buying a nice house. The challenge is to have a nice house when money _is_ limited. Andrei
Nov 30 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 The key is to navigate such that as many good designs are expressible as
easily as 
 possible.

Very flexible designs are often made of very small parts that need lot of brain to be combined to form something useful (see Scheme language, or certain toys). They become almost puzzles, even when the little parts are designed in a very good and clean way.
 The real challenge is to solve the problem within the global set of 
 constraints we have, not to prove that a language feature would solve 
 it. I know a language feature would take care of the issue, the same way 
 money would take care of buying a nice house. The challenge is to have a 
 nice house when money _is_ limited.

Generally it's positive to avoid useless features, or features that are easy to implement cleanly with few other ones. But a language like C# is much simpler than C++ despite it probably has more features, because in my opinion lot of usage complexity comes from corner cases, traps, dark corners, and so on, while clean features that are able to do one thing well and in a clean way don't add a lot of usage complexity (they may add complexity for the compiler writer). So sometimes not adding a feature you increase the complexity of programs (because the programmer has to implement those things using lower level parts, and because sometimes such implementations are suboptimal). An example are nonnull reference types, that as builtins may have better syntax and much more complete semantics. Bye, bearophile
Nov 30 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/30/10 12:09 PM, bearophile wrote:
 Andrei:

 The key is to navigate such that as many good designs are
 expressible as easily as possible.

Very flexible designs are often made of very small parts that need lot of brain to be combined to form something useful (see Scheme language, or certain toys). They become almost puzzles, even when the little parts are designed in a very good and clean way.

Wonder how the reply is related to the quote.
 The real challenge is to solve the problem within the global set
 of constraints we have, not to prove that a language feature would
  solve it. I know a language feature would take care of the issue,
  the same way money would take care of buying a nice house. The
 challenge is to have a nice house when money _is_ limited.

Generally it's positive to avoid useless features, or features that are easy to implement cleanly with few other ones. But a language like C# is much simpler than C++ despite it probably has more features, because in my opinion lot of usage complexity comes from corner cases, traps, dark corners, and so on, while clean features that are able to do one thing well and in a clean way don't add a lot of usage complexity (they may add complexity for the compiler writer). So sometimes not adding a feature you increase the complexity of programs (because the programmer has to implement those things using lower level parts, and because sometimes such implementations are suboptimal). An example are nonnull reference types, that as builtins may have better syntax and much more complete semantics.

I was about to think "yah, reasonable" till I saw the last sentence... Andrei
Nov 30 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/30/10 12:13 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 10:36:53 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 I agree that the problem is difficult but disagree with the angle.
 This is not the challenge, and it is not only mine to take. To the
 extent we're interested in making D a successful language, we're all
 on the same boat, so the challenge belongs to us all.

 Adding a new type constructor to the language or generally a new
 feature is always possible, but has a high cost. Half of the community
 throws their hand in the air with each new feature, and the other half
 throws them in the air for each feature that could have been. The key
 is to navigate such that as many good designs are expressible as
 easily as possible.

 The real challenge is to solve the problem within the global set of
 constraints we have, not to prove that a language feature would solve
 it. I know a language feature would take care of the issue, the same
 way money would take care of buying a nice house. The challenge is to
 have a nice house when money _is_ limited.

IMO opinion, the cost of modifying the language so that a library solution that half-solves the problem is possible, in order to create a template that handles all sorts of odd cases is far greater than a new keyword that would also enable things like tail-const ranges.

I'm not at all convinced. The general issue at stake is creating smart references. Any inroads into solving that enables entire new classes of designs. You're saying, forget smart references, let's create a special smart reference.
 To go with your analogy, we own the bank (compiler), we can print our
 own money...

And we all know where that takes. Andrei
Nov 30 2010
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 30, 2010 10:38:43 Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 13:24:37 -0500, Andrei Alexandrescu
 
 <SeeWebsiteForEmail erdani.org> wrote:
 On 11/30/10 12:13 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 10:36:53 -0500, Andrei Alexandrescu
 
 <SeeWebsiteForEmail erdani.org> wrote:
 I agree that the problem is difficult but disagree with the angle.
 This is not the challenge, and it is not only mine to take. To the
 extent we're interested in making D a successful language, we're all
 on the same boat, so the challenge belongs to us all.
 
 Adding a new type constructor to the language or generally a new
 feature is always possible, but has a high cost. Half of the community
 throws their hand in the air with each new feature, and the other half
 throws them in the air for each feature that could have been. The key
 is to navigate such that as many good designs are expressible as
 easily as possible.
 
 The real challenge is to solve the problem within the global set of
 constraints we have, not to prove that a language feature would solve
 it. I know a language feature would take care of the issue, the same
 way money would take care of buying a nice house. The challenge is to
 have a nice house when money _is_ limited.

IMO opinion, the cost of modifying the language so that a library solution that half-solves the problem is possible, in order to create a template that handles all sorts of odd cases is far greater than a new keyword that would also enable things like tail-const ranges.

I'm not at all convinced. The general issue at stake is creating smart references. Any inroads into solving that enables entire new classes of designs. You're saying, forget smart references, let's create a special smart reference.

No, that's not what I'm saying. Creating a language-based tail-const solution *unifies* all references, including any smart references you can create. I can say tail-const anything and it always means the same thing. It's another tool to allow creating of smart references. Without this, we have to special case tail-const in all smart reference types. If anything Rebindable is a special case smart reference, it only addresses class tail-const. The language solution addresses general tail-const. E.g. how does Rebindable address tail-const ranges? I see it 100% opposite from what you are saying, a library solution looks to me like "look! we don't have to change the language to add language features, all you need is this template that adds 10k of bloat to your exe! And why do you need to pass them as parameters, just create a new local variable? And why do you need it to work with *all* reference types, there's other syntax for that!" All for the sake of not changing the language, which I think is the more direct and complete solution. I don't really understand the resistance.
 To go with your analogy, we own the bank (compiler), we can print our
 own money...

And we all know where that takes.

Better compiler? Better smart references? Yep, I agree :)

Personally, I think that an in-language solution would definitely be better and more in line with other language features than trying to fix the issue in a library. This really does look like a core language issue which we couldn't solve properly, so we created a bandaid in the standard library to solve it. The problem is that the feature has to be properly designed and that someone has to take the time to actually implement it. And at this point, even if we have a perfect solution for it, Walter is sick of the whole issue and not at all interested in implementing it. Someone else would need to step up to the plate on this one, and we don't exactly have an abundance of dmd developers. It seems like no one has both the inclination and the time to do it. I'd _love_ to see proper tail const as a language feature, and that's where I think that it should be, but it really doesn't look like that's going to happen at this point. - Jonathan M Davis
Nov 30 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 30 Nov 2010 13:46:31 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 Personally, I think that an in-language solution would definitely be  
 better and
 more in line with other language features than trying to fix the issue  
 in a
 library. This really does look like a core language issue which we  
 couldn't
 solve properly, so we created a bandaid in the standard library to solve  
 it.

 The problem is that the feature has to be properly designed and that  
 someone has
 to take the time to actually implement it. And at this point, even if we  
 have a
 perfect solution for it, Walter is sick of the whole issue and not at all
 interested in implementing it. Someone else would need to step up to the  
 plate
 on this one, and we don't exactly have an abundance of dmd developers.  
 It seems
 like no one has both the inclination and the time to do it.

 I'd _love_ to see proper tail const as a language feature, and that's  
 where I
 think that it should be, but it really doesn't look like that's going to  
 happen
 at this point.

I agree with all this except the last phrase. I think someone will eventually do it, but it probably won't be Walter. It's such a blatant omission that someone who has an itch, and good compiler-writing skills will just do it and stick it in a patch. -Steve
Nov 30 2010
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/30/10 12:38 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 13:24:37 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 11/30/10 12:13 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 10:36:53 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 I agree that the problem is difficult but disagree with the angle.
 This is not the challenge, and it is not only mine to take. To the
 extent we're interested in making D a successful language, we're all
 on the same boat, so the challenge belongs to us all.

 Adding a new type constructor to the language or generally a new
 feature is always possible, but has a high cost. Half of the community
 throws their hand in the air with each new feature, and the other half
 throws them in the air for each feature that could have been. The key
 is to navigate such that as many good designs are expressible as
 easily as possible.

 The real challenge is to solve the problem within the global set of
 constraints we have, not to prove that a language feature would solve
 it. I know a language feature would take care of the issue, the same
 way money would take care of buying a nice house. The challenge is to
 have a nice house when money _is_ limited.

IMO opinion, the cost of modifying the language so that a library solution that half-solves the problem is possible, in order to create a template that handles all sorts of odd cases is far greater than a new keyword that would also enable things like tail-const ranges.

I'm not at all convinced. The general issue at stake is creating smart references. Any inroads into solving that enables entire new classes of designs. You're saying, forget smart references, let's create a special smart reference.

No, that's not what I'm saying. Creating a language-based tail-const solution *unifies* all references, including any smart references you can create. I can say tail-const anything and it always means the same thing. It's another tool to allow creating of smart references. Without this, we have to special case tail-const in all smart reference types. If anything Rebindable is a special case smart reference, it only addresses class tail-const. The language solution addresses general tail-const. E.g. how does Rebindable address tail-const ranges? I see it 100% opposite from what you are saying, a library solution looks to me like "look! we don't have to change the language to add language features, all you need is this template that adds 10k of bloat to your exe! And why do you need to pass them as parameters, just create a new local variable? And why do you need it to work with *all* reference types, there's other syntax for that!" All for the sake of not changing the language, which I think is the more direct and complete solution. I don't really understand the resistance.

Understanding the "resistance" is very simple. Right now a lot of current readers cheerily ignore this thread. Also a lot of potential users couldn't care any less. Once the feature will be in the language, it will affect them all. When we defined the const system, we had some goals: guaranteed immutability, simple unification of functional and procedural, economy of means. We were well aware of the tail const issue, and we made the executive decision that we will punt on it on account of it being relatively rare in practice, and partially addressable with Rebindable. As of this time I don't know whether that is true or not. Now say we define tail const or whatever. That serves a case of questionable frequency with an in-language solution that affects anyone learning the language. This is a huge deal. I don't understand your not understanding. So please let's look into what the limitations of library-based solutions are. We shouldn't be triumphantly proclaiming that Rebindable is insufficient or inadequate. We should be looking into ways of making it and other library solutions work, and understand that relying on an in-language solution would be defeat, not victory. Every problem that makes Rebindable not work also invalidates other useful designs. Conversely, relying on a narrow language change that builds Rebindable into the language definition would address the occasional tail-const situation but will miss the train on many other, larger, issues. Same discussion goes about non-nullable. We don't need the compiler to understand non-nullable types, we need to imbue the compiler with the ability to enforce arbitrary user-defined state invariants, non-null being one of them.
 To go with your analogy, we own the bank (compiler), we can print our
 own money...

And we all know where that takes.

Better compiler? Better smart references? Yep, I agree :)

I meant bankruptcy. Andrei
Nov 30 2010
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-30 15:47:22 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 We were well aware of the tail const issue, and we made the executive 
 decision that we will punt on it on account of it being relatively rare 
 in practice, and partially addressable with Rebindable.

I wonder how you determined it was "rare in practice". My attempts at using const and immutable with objects had Rebindable everywhere. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 30 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Michel Fortin:

 I wonder how you determined it was "rare in practice". My attempts at 
 using const and immutable with objects had Rebindable everywhere.

I agree that in my code with many object references that uses const/immutable everywhere possible, the desire to use Rebindable is not rare. If you don't write object oriented code, or if you don't use const/immutable much, then the need to use Rebindable is not common. Bye, bearophile
Nov 30 2010
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/30/10 15:24 CST, Steven Schveighoffer wrote:
 Why is the frequency questionable? Isn't every use of string an example
 of tail-immutable? Isn't string used everywhere?

That's a very good argument. Andrei
Nov 30 2010
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 30/11/2010 20:47, Andrei Alexandrescu wrote:
 Same discussion goes about non-nullable. We don't need the compiler to
 understand non-nullable types, we need to imbue the compiler with the
 ability to enforce arbitrary user-defined state invariants, non-null
 being one of them.

That would be great. That would be *really* great. There are lots of useful invariants one might want to express. (something like Java's wildcards for containers, or numeric ranges, maybe ownership relationships, etc.) However, just as it would be very useful, wouldn't it be an incredibly compex feature set to implement, at least in a sufficiently generic and useful way? Complex enough for it to be something that could not be worked in anytime soon? Because the impression I get from Steven and others, is that this issue is quite critical, and makes writing D code unpleasant in many situations (I myself can't agree or disagree, haven't used D2 enough in pratice, but their arguments and experience seem convincing) -- Bruno Medeiros - Software Engineer
Dec 10 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/10/10 10:41 AM, Bruno Medeiros wrote:
 On 30/11/2010 20:47, Andrei Alexandrescu wrote:
 Same discussion goes about non-nullable. We don't need the compiler to
 understand non-nullable types, we need to imbue the compiler with the
 ability to enforce arbitrary user-defined state invariants, non-null
 being one of them.

That would be great. That would be *really* great. There are lots of useful invariants one might want to express. (something like Java's wildcards for containers, or numeric ranges, maybe ownership relationships, etc.) However, just as it would be very useful, wouldn't it be an incredibly compex feature set to implement, at least in a sufficiently generic and useful way? Complex enough for it to be something that could not be worked in anytime soon?

It's not complex, and the technology is understood. There is only a need to handle flow inside constructors carefully.
 Because the impression I get from Steven and others, is that this issue
 is quite critical, and makes writing D code unpleasant in many
 situations (I myself can't agree or disagree, haven't used D2 enough in
 pratice, but their arguments and experience seem convincing)

Most languages do fine without non-nullable types, so I don't see the urgency. Andrei
Dec 10 2010
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 10/12/2010 20:31, Andrei Alexandrescu wrote:
 On 12/10/10 10:41 AM, Bruno Medeiros wrote:
 On 30/11/2010 20:47, Andrei Alexandrescu wrote:
 Same discussion goes about non-nullable. We don't need the compiler to
 understand non-nullable types, we need to imbue the compiler with the
 ability to enforce arbitrary user-defined state invariants, non-null
 being one of them.

That would be great. That would be *really* great. There are lots of useful invariants one might want to express. (something like Java's wildcards for containers, or numeric ranges, maybe ownership relationships, etc.) However, just as it would be very useful, wouldn't it be an incredibly compex feature set to implement, at least in a sufficiently generic and useful way? Complex enough for it to be something that could not be worked in anytime soon?

It's not complex, and the technology is understood. There is only a need to handle flow inside constructors carefully.

Cool. Looking forward to that then.
 Because the impression I get from Steven and others, is that this issue
 is quite critical, and makes writing D code unpleasant in many
 situations (I myself can't agree or disagree, haven't used D2 enough in
 pratice, but their arguments and experience seem convincing)

Most languages do fine without non-nullable types, so I don't see the urgency.

I wast talking about tailconst/Rebindable, not non-nullable. We can do fine without non-nullable, yeah (I think I've said so recently). -- Bruno Medeiros - Software Engineer
Dec 14 2010
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-30 10:36:53 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 11/29/10 7:52 PM, Michel Fortin wrote:
 Now consider this generic code that uses Unqual:
 
 T[] giveMeASortedArray(alias Predicate, T)(T[] t) {
 // creating new array of the same length but with assignable elements
 auto copy = new Unqual!(typeof(t[0]))[t.length];
 
 // using a loop because copy[] = t[] doesn't enforce const properly!
 foreach (index, value; t)
 copy[index] = value;
 
 // sorting the copy
 sort!(Predicate)(copy);
 return copy;
 }
 
 The above algorithm will work for types like const(int*), but it breaks
 if T is const(C) and C is a class. So it seems we'll need a special
 cases for generic algorithms to work for classes. That's what I meant
 when I say Rebindable is a fragile solution. It works in most cases, but
 it breaks in some others, mostly when you want to be generic.
 
 So here's the challenge for you Andrei:

I agree that the problem is difficult but disagree with the angle. This is not the challenge, and it is not only mine to take. To the extent we're interested in making D a successful language, we're all on the same boat, so the challenge belongs to us all.

The challenge is to make Rebindable, Unqual, and const() play well with generic programming. If you can do that plainly as a library solution, then great. If not, then the library solution is poor. I don't care if someone else than you find the solution, but right now you're the one pushing for Rebindable so I directed the challenge at you. Since you don't seem ready to analyzing the problem at hand, here's a few hints. There's basically two serious blockers in it (in addition to multiple smaller issues): 1. Unqual!(const C) would need to become Rebindable!(const C) 2. Rebindable!(const C)[] would need to be implicitly castable to const(C)[]. Number one is easy to fix, although it might interfere with the intended meaning of Unqual. Number two is the real semantic problem... how can an array of struct be implicitly cast to an array of class references? Also, if you find a solution for arrays, it should apply to other containers too. List!(Rebindable!(const C)) should be implicitly castable to List!(const(C)) and also const(List!(C)). Implementing this is already hard when const is always a type modifier. If constness is sometime expressed as a type modifier and sometime expressed as some kind of smart reference struct, it can only become more difficult. Don't you agree? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 30 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/30/10 1:22 PM, Michel Fortin wrote:
 On 2010-11-30 10:36:53 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:
 Implementing this is already hard when const is always a type modifier.
 If constness is sometime expressed as a type modifier and sometime
 expressed as some kind of smart reference struct, it can only become
 more difficult. Don't you agree?

I do, but that doesn't reduce the weight of many other factors in making a language change decision. Andrei
Nov 30 2010
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 29, 2010 11:03:27 Andrei Alexandrescu wrote:
 On 11/29/10 12:56 PM, Michel Fortin wrote:
 On 2010-11-29 13:08:54 -0500, Andrei Alexandrescu
 
 <SeeWebsiteForEmail erdani.org> said:
 On 11/29/10 10:54 AM, Michel Fortin wrote:
 The biggest problem I see is with generic programming. Say I pass
 Rebindable!(const C) as a template argument, then the template wants to
 make it const: should it become const(Rebindable!(const C)), or will
 this be resolved to const(C)?

const should follow normal logic, and const(Rebindable!(const C)) should behave as expected.

I think we agree on that. The problem is that you now have two distinct types to mean a const reference to a const object. You have "const(Rebindable!(const C))" and const "const(C)", whichever you get depends on where the type comes from. Type equality won't work between the two, and you won't be able to concatenate two arrays one containing rebindables and the other (for instance). It's like a special case in the type system where constness is implemented using a template while the rest is a language feature, it it thus behave differently and code that might work for one implementation of constness might break with the other, because the don't play with each other very well. Add immutable to the mix and it becomes even stranger. For instance, here's a tricky question: should Unqual!(const C) give you a const(C), a Rebindable!(const C), or simply C?

C.
 Now, what should
 const(Unqual!(immutable C)) give you?

const(C).
 I know most of the problems are going to be edge cases most people don't
 care about. But on the whole, creating a fragile and complex solution to
 work around the lack of an inspiring syntax seems rather silly. I would
 immensely prefer having an ugly syntax that works as it should. If it's
 too ugly, we can still hide that syntax behind Rebindable by defining it
 as a simple type alias.

Rebindable, if properly executed, is not fragile and complex. Instead it is a simple solution for a specific problem: I want a class reference that I need to bind to different const class objects. If you apply const to Rebindable, normal rules enter in action. I agree that a built-in component can be made nicer by adding extra short-circuit rules.

For Rebindable to actually be as good as a built in feature, it needs to act like a built in feature as far as its abilities go, and it doesn't - the lack of opImplicitCast() being one of the big problems. - Jonathan M Davis
Nov 29 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 10:59 AM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:19:29 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.

I think if we get to that point, D will be much more adept at doing a lot of const things (such as ranges of const types). The big hurdle is implicit casting IMO. For example C and Rebindable!(immutable C) needs to implicitly cast to Rebindable!(const C). Right now, builtins and arrays are the only type constructions that enjoy implicit casting to their tail-const counterparts. Until we solve this, any library solution is going to be woefully inadequate.

alias this was meant to solve this problem. Andrei
Nov 29 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 1:09 PM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 13:10:14 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 11/29/10 10:59 AM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:19:29 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.

I think if we get to that point, D will be much more adept at doing a lot of const things (such as ranges of const types). The big hurdle is implicit casting IMO. For example C and Rebindable!(immutable C) needs to implicitly cast to Rebindable!(const C). Right now, builtins and arrays are the only type constructions that enjoy implicit casting to their tail-const counterparts. Until we solve this, any library solution is going to be woefully inadequate.

alias this was meant to solve this problem.

My understanding is that it only works if you already have an instance. Will it work for implicit casting from another type? That is, is it planned to have a function foo: foo(Rebindable!(const C) c) callable with a C? What about a Rebindable!(immutable C)? -Steve

I was thinking of the conversion in the opposite direction. For the direct case, there has been discussion of opImplicitCast but it has fallen off the radar... until now I guess. Andrei
Nov 29 2010
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 Syntax is the main issue in implementing this feature. Due to the 
 implicit nature of reference semantics for classes, there was no syntax 
 to distinguish between the head and the tail when qualifying.
 
 FWIW I just thought of this syntax. It might work but it's not intuitive:
 
 const()C tailConst;

Syntax was not the issue. Back when we tried hard to make this work, there were many syntaxes proposed for it. The issue is the semantic conflation between a reference and what it refers to.
Nov 29 2010
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/10 3:02 PM, Walter Bright wrote:
 Andrei Alexandrescu wrote:
 Syntax is the main issue in implementing this feature. Due to the
 implicit nature of reference semantics for classes, there was no
 syntax to distinguish between the head and the tail when qualifying.

 FWIW I just thought of this syntax. It might work but it's not intuitive:

 const()C tailConst;

Syntax was not the issue. Back when we tried hard to make this work, there were many syntaxes proposed for it. The issue is the semantic conflation between a reference and what it refers to.

s/semantic/syntactic/ It was a syntactic issue. Semantically it is self-evident what operation is on the reference itself vs. the referenced data. Andrei
Nov 29 2010
prev sibling next sibling parent Kagamin <spam here.lot> writes:
Walter Bright Wrote:

 Syntax was not the issue. Back when we tried hard to make this work, there
were 
 many syntaxes proposed for it. The issue is the semantic conflation between a 
 reference and what it refers to.

O.o I don't believe, there's even single person in this thread, who will conflate them. Will you?
Nov 29 2010
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.
Nov 29 2010
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 17:53:19 -0500, Walter Bright 
 <newshound2 digitalmars.com> wrote:
 
 Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.

1. I don't blame you, spending months of time on something and failing is not encouraging. 2. I do plan to someday try and understand the source, specifically to fix this issue. Need more hours in the day :)

I know one thing for sure. If there is a solution, it won't be Bob Villa driving by the newsgroup waving his hand saying "just install track lighting!"
Nov 30 2010
parent "Nick Sabalausky" <a a.a> writes:
"Walter Bright" <newshound2 digitalmars.com> wrote in message 
news:id3jmo$s0s$2 digitalmars.com...
 Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 17:53:19 -0500, Walter Bright 
 <newshound2 digitalmars.com> wrote:

 Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.

1. I don't blame you, spending months of time on something and failing is not encouraging. 2. I do plan to someday try and understand the source, specifically to fix this issue. Need more hours in the day :)

I know one thing for sure. If there is a solution, it won't be Bob Villa driving by the newsgroup waving his hand saying "just install track lighting!"

Of course it won't be. Any self-respecting DIYer knows that static typing goes best with wall sconces.
Nov 30 2010
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 29/11/2010 22:53, Walter Bright wrote:
 Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.

Even without knowing anything about DMD internals, I would suspect that to successfully make this change it would require (at least internally in the compiler, but not necessarily in the D language itself) that classes are treated as value types an not as references (similarly to C++, where structs are the same as classes). -- Bruno Medeiros - Software Engineer
Dec 09 2010
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 09/12/2010 18:13, Steven Schveighoffer wrote:
 On Thu, 09 Dec 2010 12:07:28 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 On 29/11/2010 22:53, Walter Bright wrote:
 Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.

Even without knowing anything about DMD internals, I would suspect that to successfully make this change it would require (at least internally in the compiler, but not necessarily in the D language itself) that classes are treated as value types an not as references (similarly to C++, where structs are the same as classes).

Michel Fortin has implemented it in the current compiler, see a later thread (const(Object)ref is here). -Steve

Hum, interesting. Thanks for pointing it out, I'll take a look (and hopefully bring my backlog of unread messages up to date soon). -- Bruno Medeiros - Software Engineer
Dec 10 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 10:54:04 -0500, Nick Sabalausky <a a.a> wrote:

 "Steven Schveighoffer" <schveiguy yahoo.com> wrote in message
 news:op.vmxqi4kmeav7ka steve-laptop...
 On Sun, 28 Nov 2010 23:19:44 -0500, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts  
 have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

As I understand this is a troll post, but still provoked some good discussion, I'll throw in my biggest problem with D: lack of tail-const/immutable for classes.

I've heard this before, but I'm a little unclear. Can you give an example?

This is a tail-const pointer: const(int)* ptr; I can reassign ptr at will: ptr = &x; ptr = &y; but I can't change what ptr points to: *ptr = 5; // error Because classes are references, just like pointers, I would like a way to have a tail-const class reference. But it's not possible: const(C) myref; myref = a; // error, cannot change const myref You can have a tail-const pointer to a class reference: C myref; const(C) *myrefptr = &myref; But a class is on the heap, and the reference 'myref' is on the stack, so myrefptr is only usable locally. In order to keep the 'infinite' lifetime property, I have to create a class reference on the heap, and then return a pointer to *that*. Just try to create a class reference on the heap. Not only that, but I now have to waste 16 bytes of heap space just to have a tail-const class reference, *just because* the syntax is incomplete. I find this unacceptable. -Steve
Nov 29 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 11:19:29 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 11/29/10 10:12 AM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 10:54:04 -0500, Nick Sabalausky <a a.a> wrote:

 "Steven Schveighoffer" <schveiguy yahoo.com> wrote in message
 news:op.vmxqi4kmeav7ka steve-laptop...
 On Sun, 28 Nov 2010 23:19:44 -0500, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have
 stopped or stagnated into that cesspool of threaded discussion that  
 is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

As I understand this is a troll post, but still provoked some good discussion, I'll throw in my biggest problem with D: lack of tail-const/immutable for classes.

I've heard this before, but I'm a little unclear. Can you give an example?

This is a tail-const pointer: const(int)* ptr; I can reassign ptr at will: ptr = &x; ptr = &y; but I can't change what ptr points to: *ptr = 5; // error Because classes are references, just like pointers, I would like a way to have a tail-const class reference. But it's not possible: const(C) myref; myref = a; // error, cannot change const myref You can have a tail-const pointer to a class reference: C myref; const(C) *myrefptr = &myref; But a class is on the heap, and the reference 'myref' is on the stack, so myrefptr is only usable locally. In order to keep the 'infinite' lifetime property, I have to create a class reference on the heap, and then return a pointer to *that*. Just try to create a class reference on the heap. Not only that, but I now have to waste 16 bytes of heap space just to have a tail-const class reference, *just because* the syntax is incomplete. I find this unacceptable. -Steve

Syntax is the main issue in implementing this feature. Due to the implicit nature of reference semantics for classes, there was no syntax to distinguish between the head and the tail when qualifying.

Syntax is the main issue, but another issue is Walter's patience -- he already has stated that he has no interest in entertaining new solutions because he's already wasted enough time on it.
 FWIW I just thought of this syntax. It might work but it's not intuitive:

 const()C tailConst;

I think this fails for the same reason const(C) meaning tail const and const C meaning full const failed -- with parentheses, const applies to whatever is in them, and the C reference is outside the parentheses. I can't see any other way than creating a new 'keyword' to denote tail-const. Whether this be library defined or compiler defined remains to be seen. My favorite in recent times is: tail const(C) tailconst;
 Ultimately I believe we need to make Rebindable palatable. That would  
 have the nice side effect of enabling other proxy types.

I think if we get to that point, D will be much more adept at doing a lot of const things (such as ranges of const types). The big hurdle is implicit casting IMO. For example C and Rebindable!(immutable C) needs to implicitly cast to Rebindable!(const C). Right now, builtins and arrays are the only type constructions that enjoy implicit casting to their tail-const counterparts. Until we solve this, any library solution is going to be woefully inadequate. -Steve
Nov 29 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 13:10:14 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 11/29/10 10:59 AM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:19:29 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.

I think if we get to that point, D will be much more adept at doing a lot of const things (such as ranges of const types). The big hurdle is implicit casting IMO. For example C and Rebindable!(immutable C) needs to implicitly cast to Rebindable!(const C). Right now, builtins and arrays are the only type constructions that enjoy implicit casting to their tail-const counterparts. Until we solve this, any library solution is going to be woefully inadequate.

alias this was meant to solve this problem.

My understanding is that it only works if you already have an instance. Will it work for implicit casting from another type? That is, is it planned to have a function foo: foo(Rebindable!(const C) c) callable with a C? What about a Rebindable!(immutable C)? -Steve
Nov 29 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 11:52:31 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s  
 article

 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.
 Andrei

I've asked before and I'll ask again, what's still wrong with Rebindable? A bunch of alias this issues got fixed in 2.050, and I fixed a bunch of misc. convenience issues a few releases ago. I fail to see the problem with it anymore.

Every few months or so, someone finds a problem with it. It seems that it's good enough in theory, but miserably fails in practice when someone tries to use it. I admit I haven't looked at it in a while, but there are implicit casting problems that cannot be solved without compiler help. I just think Rebindable will get more and more convoluted until someone finally admits that this is better served as a builtin feature. One of those issues: import std.typecons; class C {} void foo(Rebindable!(const C) c) { } void bar(const(C) c) { } void main() { const C x; Rebindable!(const C) y = x; foo(x); // line 17 bar(y); // line 18 } produces: testrebindable.d(17): Error: function testrebindable.foo (Rebindable!(const(C)) c) is not callable using argument types (const(C)) testrebindable.d(17): Error: cannot implicitly convert expression (x) of type const(C) to Rebindable!(const(C)) testrebindable.d(18): Error: function testrebindable.bar (const(C) c) is not callable using argument types (Rebindable!(const(C))) testrebindable.d(18): Error: cannot implicitly convert expression (y) of type Rebindable!(const(C)) to const(C) i.e. there is no way to produce a function that accepts both a Rebindable!(const C) and a const C. -Steve
Nov 29 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 14:38:40 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 11/29/10 1:35 PM, Steven Schveighoffer wrote:
 On Mon, 29 Nov 2010 11:52:31 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s
 article

 Ultimately I believe we need to make Rebindable palatable. That would
 have the nice side effect of enabling other proxy types.
 Andrei

I've asked before and I'll ask again, what's still wrong with Rebindable? A bunch of alias this issues got fixed in 2.050, and I fixed a bunch of misc. convenience issues a few releases ago. I fail to see the problem with it anymore.

Every few months or so, someone finds a problem with it. It seems that it's good enough in theory, but miserably fails in practice when someone tries to use it. I admit I haven't looked at it in a while, but there are implicit casting problems that cannot be solved without compiler help. I just think Rebindable will get more and more convoluted until someone finally admits that this is better served as a builtin feature.

I don't grok this. If people find different issues with it that are fixed, then there is progress, right? (Clearly "escaping" into the language makes things better.)

At some point, Rebindable may be as good as a language feature. But we haven't got there yet. And we haven't got there in years. And I don't see us getting there in the forseeable future -- there are too many implicit casting problems to solve. At the point where it does become useable, how big will it be? How much will it slow down compilation? How specialized do we have to make code? Const is supposed to be a compile-time feature, optimized out at runtime. If Rebindable isn't completely removed from the code generation, then it is not a complete feature.
 One of those issues:

 import std.typecons;

 class C {}

 void foo(Rebindable!(const C) c)
 {
 }

Let me fix that: void foo(const C c) { auto rc = Rebindable!(const C)(c); ... }

You missed the point.. completely :) please look at bar. -Steve
Nov 29 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 16:02:18 -0500, Walter Bright  
<newshound2 digitalmars.com> wrote:

 Andrei Alexandrescu wrote:
 Syntax is the main issue in implementing this feature. Due to the  
 implicit nature of reference semantics for classes, there was no syntax  
 to distinguish between the head and the tail when qualifying.
  FWIW I just thought of this syntax. It might work but it's not  
 intuitive:
  const()C tailConst;

Syntax was not the issue. Back when we tried hard to make this work, there were many syntaxes proposed for it. The issue is the semantic conflation between a reference and what it refers to.

Syntax is the issue. You can do a tail-const pointer without problems because the syntax is intuitive. It can be done, it just needs syntax to do it. Note that in D, class references are rebindable. ref references are not, we are not talking about ref references, we are talking about rebindable references, there is definitely a separation between the reference and the data, it's just invisible. Because we tried hard and failed != it's impossible. -Steve
Nov 29 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 29 Nov 2010 17:53:19 -0500, Walter Bright  
<newshound2 digitalmars.com> wrote:

 Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.

1. I don't blame you, spending months of time on something and failing is not encouraging. 2. I do plan to someday try and understand the source, specifically to fix this issue. Need more hours in the day :) -Steve
Nov 30 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 30 Nov 2010 10:36:53 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 I agree that the problem is difficult but disagree with the angle. This  
 is not the challenge, and it is not only mine to take. To the extent  
 we're interested in making D a successful language, we're all on the  
 same boat, so the challenge belongs to us all.

 Adding a new type constructor to the language or generally a new feature  
 is always possible, but has a high cost. Half of the community throws  
 their hand in the air with each new feature, and the other half throws  
 them in the air for each feature that could have been. The key is to  
 navigate such that as many good designs are expressible as easily as  
 possible.

 The real challenge is to solve the problem within the global set of  
 constraints we have, not to prove that a language feature would solve  
 it. I know a language feature would take care of the issue, the same way  
 money would take care of buying a nice house. The challenge is to have a  
 nice house when money _is_ limited.

IMO opinion, the cost of modifying the language so that a library solution that half-solves the problem is possible, in order to create a template that handles all sorts of odd cases is far greater than a new keyword that would also enable things like tail-const ranges. To go with your analogy, we own the bank (compiler), we can print our own money... -Steve
Nov 30 2010
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 30 Nov 2010 13:13:47 -0500, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 IMO opinion,

IMO opinion? Hm... wonder what that O stands for :D -Steve
Nov 30 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 30, 2010 10:29:57 Simen kjaeraas wrote:
 Steven Schveighoffer <schveiguy yahoo.com> wrote:
 On Tue, 30 Nov 2010 13:13:47 -0500, Steven Schveighoffer
 
 <schveiguy yahoo.com> wrote:
 IMO opinion,

IMO opinion? Hm... wonder what that O stands for :D

Own?

Nah. Other. He's got two opinions. But what's the first one, I wonder... ;) - Jonathan M Davis
Nov 30 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Steven Schveighoffer <schveiguy yahoo.com> wrote:

 On Tue, 30 Nov 2010 13:13:47 -0500, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:

 IMO opinion,

IMO opinion? Hm... wonder what that O stands for :D

Own? -- Simen
Nov 30 2010
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 30 Nov 2010 13:24:37 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 11/30/10 12:13 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 10:36:53 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 I agree that the problem is difficult but disagree with the angle.
 This is not the challenge, and it is not only mine to take. To the
 extent we're interested in making D a successful language, we're all
 on the same boat, so the challenge belongs to us all.

 Adding a new type constructor to the language or generally a new
 feature is always possible, but has a high cost. Half of the community
 throws their hand in the air with each new feature, and the other half
 throws them in the air for each feature that could have been. The key
 is to navigate such that as many good designs are expressible as
 easily as possible.

 The real challenge is to solve the problem within the global set of
 constraints we have, not to prove that a language feature would solve
 it. I know a language feature would take care of the issue, the same
 way money would take care of buying a nice house. The challenge is to
 have a nice house when money _is_ limited.

IMO opinion, the cost of modifying the language so that a library solution that half-solves the problem is possible, in order to create a template that handles all sorts of odd cases is far greater than a new keyword that would also enable things like tail-const ranges.

I'm not at all convinced. The general issue at stake is creating smart references. Any inroads into solving that enables entire new classes of designs. You're saying, forget smart references, let's create a special smart reference.

No, that's not what I'm saying. Creating a language-based tail-const solution *unifies* all references, including any smart references you can create. I can say tail-const anything and it always means the same thing. It's another tool to allow creating of smart references. Without this, we have to special case tail-const in all smart reference types. If anything Rebindable is a special case smart reference, it only addresses class tail-const. The language solution addresses general tail-const. E.g. how does Rebindable address tail-const ranges? I see it 100% opposite from what you are saying, a library solution looks to me like "look! we don't have to change the language to add language features, all you need is this template that adds 10k of bloat to your exe! And why do you need to pass them as parameters, just create a new local variable? And why do you need it to work with *all* reference types, there's other syntax for that!" All for the sake of not changing the language, which I think is the more direct and complete solution. I don't really understand the resistance.
 To go with your analogy, we own the bank (compiler), we can print our
 own money...

And we all know where that takes.

Better compiler? Better smart references? Yep, I agree :) -Steve
Nov 30 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 30, 2010 12:47:22 Andrei Alexandrescu wrote:
 On 11/30/10 12:38 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 13:24:37 -0500, Andrei Alexandrescu
=20
 <SeeWebsiteForEmail erdani.org> wrote:
 On 11/30/10 12:13 PM, Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 10:36:53 -0500, Andrei Alexandrescu
=20
 <SeeWebsiteForEmail erdani.org> wrote:
 I agree that the problem is difficult but disagree with the angle.
 This is not the challenge, and it is not only mine to take. To the
 extent we're interested in making D a successful language, we're all
 on the same boat, so the challenge belongs to us all.
=20
 Adding a new type constructor to the language or generally a new
 feature is always possible, but has a high cost. Half of the communi=





 throws their hand in the air with each new feature, and the other ha=





 throws them in the air for each feature that could have been. The key
 is to navigate such that as many good designs are expressible as
 easily as possible.
=20
 The real challenge is to solve the problem within the global set of
 constraints we have, not to prove that a language feature would solve
 it. I know a language feature would take care of the issue, the same
 way money would take care of buying a nice house. The challenge is to
 have a nice house when money _is_ limited.

IMO opinion, the cost of modifying the language so that a library solution that half-solves the problem is possible, in order to create=




 template that handles all sorts of odd cases is far greater than a new
 keyword that would also enable things like tail-const ranges.

I'm not at all convinced. The general issue at stake is creating smart references. Any inroads into solving that enables entire new classes of designs. You're saying, forget smart references, let's create a special smart reference.

No, that's not what I'm saying. Creating a language-based tail-const solution *unifies* all references, including any smart references you can create. I can say tail-const anything and it always means the same thing. It's another tool to allow creating of smart references. Without this, we have to special case tail-const in all smart reference types. If anything Rebindable is a special case smart reference, it only addresses class tail-const. The language solution addresses general tail-const. E.g. how does Rebindable address tail-const ranges? =20 I see it 100% opposite from what you are saying, a library solution looks to me like "look! we don't have to change the language to add language features, all you need is this template that adds 10k of bloat to your exe! And why do you need to pass them as parameters, just create a new local variable? And why do you need it to work with *all* reference types, there's other syntax for that!" All for the sake of not changing the language, which I think is the more direct and complete solution. I don't really understand the resistance.

Understanding the "resistance" is very simple. Right now a lot of current readers cheerily ignore this thread. Also a lot of potential users couldn't care any less. Once the feature will be in the language, it will affect them all. =20 When we defined the const system, we had some goals: guaranteed immutability, simple unification of functional and procedural, economy of means. We were well aware of the tail const issue, and we made the executive decision that we will punt on it on account of it being relatively rare in practice, and partially addressable with Rebindable. As of this time I don't know whether that is true or not.

Rare? It's _way_ more useful for pointers and references than full const. I= =20 virtually _never_ use const pointers to const - in C++ or in D. Tail const = is=20 almost always the type of const that's useful if you want to pass const any= thing=20 around. Having pointers or references const is rarely useful in comparison.= =20 That's what's so insanely annoying about final in Java. It makes the exact= =20 opposite of what is useful to have const be const (the reference rather tha= n the=20 referent). =46rom a syntactical and typing point of view, having tail const built in w= ould be=20 highly preferable than having to use Rebindable all over the place. Now, if= =20 Rebindable could be made to fully work, then that could be acceptable to. B= ut it=20 doesn't properly convert to full const right now, and definitely comes acro= ss as=20 a hack, whether it really is one or not. Tail const is already in the langu= age=20 for other types. It's just that it's not there for them all, and that cause= s=20 problems.
 Now say we define  tail const or whatever. That serves a case of
 questionable frequency with an in-language solution that affects anyone
 learning the language. This is a huge deal. I don't understand your not
 understanding.
=20
 So please let's look into what the limitations of library-based
 solutions are. We shouldn't be triumphantly proclaiming that Rebindable
 is insufficient or inadequate. We should be looking into ways of making
 it and other library solutions work, and understand that relying on an
 in-language solution would be defeat, not victory. Every problem that
 makes Rebindable not work also invalidates other useful designs.
 Conversely, relying on a narrow language change that builds Rebindable
 into the language definition would address the occasional tail-const
 situation but will miss the train on many other, larger, issues.

=46irst and foremost, we _need_ opImplicitCast() for Rebindable to be a ful= ly=20 viable replacement for a built-in tail const. Unqual would also need to tre= at=20 Rebindable anything as the core type. I'm guessing that it doesn't right no= w=20 (though I'd have to check to be sure). That may or may not be enough to fix= the=20 issue with tail const references, I don't know, but it's a big part of it. = I=20 don't think that it helps at all with tail const and ranges though. =2D Jonathan M Davis
Nov 30 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 30 Nov 2010 15:47:22 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 11/30/10 12:38 PM, Steven Schveighoffer wrote:

 No, that's not what I'm saying. Creating a language-based tail-const
 solution *unifies* all references, including any smart references you
 can create. I can say tail-const anything and it always means the same
 thing. It's another tool to allow creating of smart references. Without
 this, we have to special case tail-const in all smart reference types.
 If anything Rebindable is a special case smart reference, it only
 addresses class tail-const. The language solution addresses general
 tail-const. E.g. how does Rebindable address tail-const ranges?

 I see it 100% opposite from what you are saying, a library solution
 looks to me like "look! we don't have to change the language to add
 language features, all you need is this template that adds 10k of bloat
 to your exe! And why do you need to pass them as parameters, just create
 a new local variable? And why do you need it to work with *all*
 reference types, there's other syntax for that!" All for the sake of not
 changing the language, which I think is the more direct and complete
 solution. I don't really understand the resistance.

Understanding the "resistance" is very simple. Right now a lot of current readers cheerily ignore this thread. Also a lot of potential users couldn't care any less. Once the feature will be in the language, it will affect them all.

It affects them all as much as Rebindable affects them all. Either way, it's something new they have to learn, whether it's a language feature or a library feature. This argument makes no sense. Another way to look at it -- whichever solution is used is really going to affect only library writers, not library users. Whether the user writes: tail const(C); or Rebindable!(const(C)) or something else is really irrelevant to them, what's relevant is what hoops do I as a library writer have to jump through to get this damned thing to work seamlessly.
 When we defined the const system, we had some goals: guaranteed  
 immutability, simple unification of functional and procedural, economy  
 of means. We were well aware of the tail const issue, and we made the  
 executive decision that we will punt on it on account of it being  
 relatively rare in practice, and partially addressable with Rebindable.  
 As of this time I don't know whether that is true or not.

To determine whether tail-const is useful or not, let's examine all uses of tail-const and tail-immutable in phobos that *don't* involve classes. I.e. const(T)[] arrays, and const(T)* pointers. Rebindable does not work, that much I do know. Pointing at lack of use of Rebindable is not proof of anything except that it's a half baked feature. I also don't know that tail-const references will be mainstream useful or just useful on a small scale. I know that it directly affects the project I wrote. As of now, dcollections containers are const-unfriendly because to implement const would require massive duplication of all ranges and functions that accept ranges, plus implicit casting just doesn't work between two different template instantiations that vary only on const. Whether the language is modified so this can work, or the language incorporates tail-const directly, it's a problem that needs to be solved IMO. Which is the right answer, I don't know, but the builtin explanation seems to me to allow more efficient code, and less boilerplate required.
 Now say we define  tail const or whatever. That serves a case of  
 questionable frequency with an in-language solution that affects anyone  
 learning the language. This is a huge deal. I don't understand your not  
 understanding.

Why is the frequency questionable? Isn't every use of string an example of tail-immutable? Isn't string used everywhere?
 So please let's look into what the limitations of library-based  
 solutions are. We shouldn't be triumphantly proclaiming that Rebindable  
 is insufficient or inadequate. We should be looking into ways of making  
 it and other library solutions work, and understand that relying on an  
 in-language solution would be defeat, not victory. Every problem that  
 makes Rebindable not work also invalidates other useful designs.  
 Conversely, relying on a narrow language change that builds Rebindable  
 into the language definition would address the occasional tail-const  
 situation but will miss the train on many other, larger, issues.

I'm not at all proclaiming victory because Rebindable sucks. I think something that allows Rebindable to properly work would be great for something less commonly used than tail-x, but I'd rather have the code be cleaner for a feature that's used everywhere. We could do away with array syntax, or operators, and just go with function calls and elemAt(size_t), but I swear and punch things every time I have to use C#'s arrays, lamenting for how D's syntax works. Syntax is important too. If you can make Rebindable!(T) become tail const for every type of T (including a range), and have it work flawlessly when casting to/from const(T), then I accept that as a valid solution. If Rebindable just solves the tail-const class case, and I have to do something *like* what Rebindable does whenever I want to allow tail-const on any type, then I think the problem is not yet solved.
 Same discussion goes about non-nullable. We don't need the compiler to  
 understand non-nullable types, we need to imbue the compiler with the  
 ability to enforce arbitrary user-defined state invariants, non-null  
 being one of them.

Non-nullable is a different animal. Non-null types do not really exist everywhere in D. Tail-const/shared/immutable types exist everywhere in D. There is no lack of consistency in D for non-nullable types.
 To go with your analogy, we own the bank (compiler), we can print our
 own money...

And we all know where that takes.

Better compiler? Better smart references? Yep, I agree :)

I meant bankruptcy.

How does this translate to the software analogy? What does bankruptcy for dmd mean? Note that we can print our own money and not have to pay it back, it's software :) -Steve
Nov 30 2010
prev sibling next sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 30-nov-10, at 22:24, Steven Schveighoffer wrote:

 On Tue, 30 Nov 2010 15:47:22 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org 
 wrote:

 On 11/30/10 12:38 PM, Steven Schveighoffer wrote:

 No, that's not what I'm saying. Creating a language-based tail-const
 solution *unifies* all references, including any smart references  
 you
 can create. I can say tail-const anything and it always means the  
 same
 thing. It's another tool to allow creating of smart references.  
 Without
 this, we have to special case tail-const in all smart reference  
 types.
 If anything Rebindable is a special case smart reference, it only
 addresses class tail-const. The language solution addresses general
 tail-const. E.g. how does Rebindable address tail-const ranges?

 I see it 100% opposite from what you are saying, a library solution
 looks to me like "look! we don't have to change the language to add
 language features, all you need is this template that adds 10k of  
 bloat
 to your exe! And why do you need to pass them as parameters, just  
 create
 a new local variable? And why do you need it to work with *all*
 reference types, there's other syntax for that!" All for the sake  
 of not
 changing the language, which I think is the more direct and complete
 solution. I don't really understand the resistance.

Understanding the "resistance" is very simple. Right now a lot of current readers cheerily ignore this thread. Also a lot of potential users couldn't care any less. Once the feature will be in the language, it will affect them all.

It affects them all as much as Rebindable affects them all. Either way, it's something new they have to learn, whether it's a language feature or a library feature. This argument makes no sense. Another way to look at it -- whichever solution is used is really going to affect only library writers, not library users. Whether the user writes: tail const(C); or Rebindable!(const(C)) or something else is really irrelevant to them, what's relevant is what hoops do I as a library writer have to jump through to get this damned thing to work seamlessly.

I mostly agree with Steve (I just made it though the thread), I also find tail const very useful. In fact I independently wrote a related post about tail const (but with a different syntax). The fact that tail const can be reasonably extended to any type, and still guarantees purity shows its usefulness. mostly it can be seen as a shortcut to declare a special kind of constness, only for classes one can express something with tail const that cannot be directly expressed with const()

Nov 30 2010
prev sibling next sibling parent "Json" <whatyagonnado abstractplanet.net> writes:
Steven Schveighoffer wrote:
 On Sun, 28 Nov 2010 23:19:44 -0500, Jack <jt overlook.biz> wrote:

 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts
 have stopped or stagnated into that cesspool of threaded discussion
 that is "the subthread" or "tangential thread" (which surely needs a
 rock anthem).

As I understand this is a troll post,

"As I understand"? Are you aspiring to go into politics? If you don't know what "politics" is, it IS "walking the fence" (look it up).
  but still provoked some good
 discussion, I'll throw in my biggest problem with D:

 lack of tail-const/immutable for classes.

 And no, Rebindable doesn't cut it.

Also, look up "can't see the forrest for the trees".
Dec 04 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 09 Dec 2010 12:07:28 -0500, Bruno Medeiros  
<brunodomedeiros+spam com.gmail> wrote:

 On 29/11/2010 22:53, Walter Bright wrote:
 Steven Schveighoffer wrote:
 Because we tried hard and failed != it's impossible.

The source to DMD is there. Feel free to try! I spent months trying to make it work, and I learned my lesson.

Even without knowing anything about DMD internals, I would suspect that to successfully make this change it would require (at least internally in the compiler, but not necessarily in the D language itself) that classes are treated as value types an not as references (similarly to C++, where structs are the same as classes).

Michel Fortin has implemented it in the current compiler, see a later thread (const(Object)ref is here). -Steve
Dec 09 2010
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On Mon, 29 Nov 2010 08:17:23 +0300
"Denis Koroskin" <2korden gmail.com> wrote:

 I'd go with omissible parens. There are SO many bugs and stuff that can't=

 be worked around due to this.

+++ (Once again, allowing a few less key-strokes makes a language uselessly com= plicated, harder to read, harder to parse). Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 30 2010
parent reply "Json" <whatyagonnado abstractplanet.net> writes:
spir wrote:
 On Mon, 29 Nov 2010 08:17:23 +0300
 "Denis Koroskin" <2korden gmail.com> wrote:

 I'd go with omissible parens. There are SO many bugs and stuff that
 can't be worked around due to this.

+++ (Once again, allowing a few less key-strokes makes a language uselessly complicated, harder to read, harder to parse).

Can you please explain WTF you are talking about? Semicolons? Start a new thread and I'll chime in if you are STILL hung up on those issues.
Dec 04 2010
parent FeepingCreature <default_357-line yahoo.de> writes:
On 05.12.2010 05:37, Json wrote:
 spir wrote:
 On Mon, 29 Nov 2010 08:17:23 +0300
 "Denis Koroskin" <2korden gmail.com> wrote:

 I'd go with omissible parens. There are SO many bugs and stuff that
 can't be worked around due to this.

+++ (Once again, allowing a few less key-strokes makes a language uselessly complicated, harder to read, harder to parse).

Can you please explain WTF you are talking about? Semicolons? Start a new thread and I'll chime in if you are STILL hung up on those issues.

He means the ability to write foo; instead of foo();. Property access syntax. Personally, I don't mind it.
Dec 07 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 30, 2010 10:56:41 Steven Schveighoffer wrote:
 On Tue, 30 Nov 2010 13:46:31 -0500, Jonathan M Davis <jmdavisProg gmx.com>
 
 wrote:
 Personally, I think that an in-language solution would definitely be
 better and
 more in line with other language features than trying to fix the issue
 in a
 library. This really does look like a core language issue which we
 couldn't
 solve properly, so we created a bandaid in the standard library to solve
 it.
 
 The problem is that the feature has to be properly designed and that
 someone has
 to take the time to actually implement it. And at this point, even if we
 have a
 perfect solution for it, Walter is sick of the whole issue and not at all
 interested in implementing it. Someone else would need to step up to the
 plate
 on this one, and we don't exactly have an abundance of dmd developers.
 It seems
 like no one has both the inclination and the time to do it.
 
 I'd _love_ to see proper tail const as a language feature, and that's
 where I
 think that it should be, but it really doesn't look like that's going to
 happen
 at this point.

I agree with all this except the last phrase. I think someone will eventually do it, but it probably won't be Walter. It's such a blatant omission that someone who has an itch, and good compiler-writing skills will just do it and stick it in a patch.

That may be, but I think that D2 is currently at the point where it needs to be done _soon_ if it's going to be in the language. D2 as a language is really supposed to be essentially stable at this point. And tail const is a big change. It might be doable in a way which is totally backwards compatible, but it's the kind of thing which could have a serious impact on how const is dealt with in Phobos. So, putting it off does _not_ seem like a good idea to me. So, unless someone actually does it soon, it really starts looking like a feature for D3 if D3 ever happens. - Jonathan M Davis
Nov 30 2010
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 29/11/2010 04:19, Jack wrote:
 The post "C#'s greatest mistakes" prompts/begs this post. Have at it,
 pick up the ball and run with it, don't be shy. I expect Walter and
 Andrei to answer (if Walter and Andrei so dare!) after others' posts have
 stopped or stagnated into that cesspool of threaded discussion that is
 "the subthread" or "tangential thread" (which surely needs a rock
 anthem).

BTW, in my opinion, D's greatest mistake is... foreach_reverse! And I'm only partially joking. -- Bruno Medeiros - Software Engineer
Dec 14 2010