February 14, 2010
bearophile wrote:
> - And finally in D2 there are several new features that are sometimes
> only half-implemented, and generally no one has tried them in long
> programs, they seem to come from just the mind of few (intelligent)
> people, they don't seem battle-tested at all. Such new features are a
> dangerous bet, they can hide many traps and problems. Finalizing the
> D2 language before people have actually tried to use such features in
> some larger programs looks dangerous. Recently I have understood that
> this is why Simon Peyton-Jones said "Avoid success at all costs"
> regarding Haskell, that he has slowly developed for about 15 years:
> to give the language the time to be tuned, to remove warts, to
> improve it before people start to use it for rear and it needs to be
> frozen (today we are probably in a phase when Haskell has to be
> frozen, because there is enough software written in it that you can't
> lightly break backward compatibility).

The response of the Haskell community seems to be "avoid avoiding success". Anyway, either slogan shouldn't be taken out of context, and I don't think the situations of the two languages are easily comparable. For example, a few years ago monads weren't around. At that point, a different I/O method was considered "it" for functional programs (I swear I know which, but I forgot). Behind closed doors every functional language designer was scratching their head trying to find a better way. It's good Haskell didn't commit to the now obsolete I/O method - as good as D not committing to yesteryear's threading model.

> So I am a little worried for some of the last features introduced in
> D2. I don't know if D3 can solve this problem (maybe not).

I read the entire post waiting for the punchline. Which features do you have in mind?


Andrei
February 15, 2010
Andrei Alexandrescu wrote:
> Justin Johansson wrote:
>> Andrei Alexandrescu wrote:
>>> ulong x0;
>>> static assert(!__traits(compiles, -x0));
>>> uint x1;
>>> static assert(!__traits(compiles, -x1));
>>> ushort x2;
>>> static assert(!__traits(compiles, -x2));
>>> ubyte x3;
>>> static assert(!__traits(compiles, -x3));
>>>
>>> Sounds good?
>>>
>>> Andrei
>>
>> Sounds excellent.  Who would have thought of that?
>>
>> Cheers
>> Justin Johansson
>>
> 
> Actually Walter just talked me into forgetting about it. -x is conceptually rewritten into ~x + 1 for all types and typed accordingly. 

Oh, okay.  Who would have thought of that? :-)

> I'm dropping this in order to keep focused on more important changes.

This sounds good too.  We are all anxiously awaiting the publication of
TDPL.  What's the latest ETA?

Justin

> Andrei
February 15, 2010
Sun, 14 Feb 2010 17:36:59 -0600, Andrei Alexandrescu wrote:

> bearophile wrote:
>> - And finally in D2 there are several new features that are sometimes only half-implemented, and generally no one has tried them in long programs, they seem to come from just the mind of few (intelligent) people, they don't seem battle-tested at all. Such new features are a dangerous bet, they can hide many traps and problems. Finalizing the D2 language before people have actually tried to use such features in some larger programs looks dangerous. Recently I have understood that this is why Simon Peyton-Jones said "Avoid success at all costs" regarding Haskell, that he has slowly developed for about 15 years: to give the language the time to be tuned, to remove warts, to improve it before people start to use it for rear and it needs to be frozen (today we are probably in a phase when Haskell has to be frozen, because there is enough software written in it that you can't lightly break backward compatibility).
> 
> The response of the Haskell community seems to be "avoid avoiding success". Anyway, either slogan shouldn't be taken out of context, and I don't think the situations of the two languages are easily comparable. For example, a few years ago monads weren't around. At that point, a different I/O method was considered "it" for functional programs (I swear I know which, but I forgot).

There's not much choice here. Probably explicit state passing with a state variable? People also invented other methods, but monads provided an useful abstraction for other kind of use as well.
February 15, 2010
retard wrote:
> Sun, 14 Feb 2010 17:36:59 -0600, Andrei Alexandrescu wrote:
> 
>> bearophile wrote:
>>> - And finally in D2 there are several new features that are sometimes
>>> only half-implemented, and generally no one has tried them in long
>>> programs, they seem to come from just the mind of few (intelligent)
>>> people, they don't seem battle-tested at all. Such new features are a
>>> dangerous bet, they can hide many traps and problems. Finalizing the D2
>>> language before people have actually tried to use such features in some
>>> larger programs looks dangerous. Recently I have understood that this
>>> is why Simon Peyton-Jones said "Avoid success at all costs" regarding
>>> Haskell, that he has slowly developed for about 15 years: to give the
>>> language the time to be tuned, to remove warts, to improve it before
>>> people start to use it for rear and it needs to be frozen (today we are
>>> probably in a phase when Haskell has to be frozen, because there is
>>> enough software written in it that you can't lightly break backward
>>> compatibility).
>> The response of the Haskell community seems to be "avoid avoiding
>> success". Anyway, either slogan shouldn't be taken out of context, and I
>> don't think the situations of the two languages are easily comparable.
>> For example, a few years ago monads weren't around. At that point, a
>> different I/O method was considered "it" for functional programs (I
>> swear I know which, but I forgot).
> 
> There's not much choice here. Probably explicit state passing with a state variable? People also invented other methods, but monads provided an useful abstraction for other kind of use as well.

I'm telling you that pre-monads there was an I/O paradigm that everybody FP swore by. I learned about it in 2001 in my first grad level course, and actually wrote programs using it. The professor stressed how it had been all a fad and that monads may also be one. Since you waste no opportunity to walk us through your vast library, you may as well remind us what it was.

Andrei
February 15, 2010
Justin Johansson wrote:
> Andrei Alexandrescu wrote:
>> Justin Johansson wrote:
>>> Andrei Alexandrescu wrote:
>>>> ulong x0;
>>>> static assert(!__traits(compiles, -x0));
>>>> uint x1;
>>>> static assert(!__traits(compiles, -x1));
>>>> ushort x2;
>>>> static assert(!__traits(compiles, -x2));
>>>> ubyte x3;
>>>> static assert(!__traits(compiles, -x3));
>>>>
>>>> Sounds good?
>>>>
>>>> Andrei
>>>
>>> Sounds excellent.  Who would have thought of that?
>>>
>>> Cheers
>>> Justin Johansson
>>>
>>
>> Actually Walter just talked me into forgetting about it. -x is conceptually rewritten into ~x + 1 for all types and typed accordingly. 
> 
> Oh, okay.  Who would have thought of that? :-)
> 
>> I'm dropping this in order to keep focused on more important changes.
> 
> This sounds good too.  We are all anxiously awaiting the publication of
> TDPL.  What's the latest ETA?

I'm on schedule for late April. With the chapter on concurrency (over 40 pages alone), the size of the book has grown a fair amount. But hey, I even give two lock-free examples.

Andrei
February 15, 2010
retard wrote:
> Basically D just shows how well Walter has read his CS books.

There's a lot more to writing compilers and designing languages than you'll find in CS books. For example, I discovered that the CS textbook optimization algorithms don't actually work. The authors had obviously never implemented them in a production compiler.


> This is not the case in languages designed by language experts such as Guy Steele, Simon Peyton Jones, or John McCarthy.

I'm curious, why are you here, then? Why aren't you using Fortress, Haskell, or Lisp instead?

If you're here to criticize me, that's cool, I don't mind. I'd much prefer it, though, if you were here to help and would step up and contribute code, documentation, articles, etc. D can really use your active help.
February 15, 2010
>The problem I see with D is that Walter has mostly experience with C/C++. The features inherited from those languages tend to work much better in D.
Is it really the problem? I think the original idea was to have better alternative
to C/C++, and D 2.0 looks good in that respect; and D has good chance
to be welcomed by C/C++ folks since (almost) no learning is required.

The "ambitious" features of D sometimes do not look well polished, (I could be wrong),
and other than the talks at Google I could not find any material about
advanced features, directions and design principles (will really
appreciate if someone can give me pointers to such materials, if it exists).

I hope TDPL book will cover D's design principles and (if it makes sense) may be compare
D'd advanced/ambitious features to other languages/approaches.
I like the concurrency chapter, it is great that memory model is discussed and
comparison with other languages is presented.



February 15, 2010
retard wrote:
> I'm really sorry I often sound so annoying. I guess I should stop posting at all since there seems to be small value in criticizing things or discussing various programming topics.

I did not intend to chase you away. You're welcome to stay here and criticize all you want.

What I'm trying to say is that there's far more value in contributing to the D project than there is in simply criticizing it. You have the knowledge and ability to, so why not?
February 15, 2010
On Sun, 14 Feb 2010 17:02:12 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> dsimcha wrote:
>> == Quote from Andrei Alexandrescu (SeeWebsiteForEmail@erdani.org)'s article
>>> ulong x0;
>>> static assert(!__traits(compiles, -x0));
>>> uint x1;
>>> static assert(!__traits(compiles, -x1));
>>> ushort x2;
>>> static assert(!__traits(compiles, -x2));
>>> ubyte x3;
>>> static assert(!__traits(compiles, -x3));
>>> Sounds good?
>>> Andrei
>>  The more you bring up features to give the axe to, the more I find it funny that,
>> not being a very good language lawyer, I wasn't aware that half of these features
>> existed in the first place.  This is one of them.  Yes, definitely get rid of it.
>>  It makes absolutely no sense.  If you want to treat your number like a signed
>> int, then it should require an explicit cast.
>
> I said the same. Walter's counter-argument is that 2's complement arithmetic is an inescapable reality that all coders must be aware of in D and its kin. Negation is really taking the two's complement of the thing. The fact that the type was unsigned is not of much import.

I'd say 99% of the cases where assigning a negative number to an unsigned type is the literal -1 (i.e. all bits set).  It's just as easy to type ~0.

In fact, in any case that you are using a literal besides that, it's usually more helpful to type the hex representation, or use ~(n-1) where you compute n-1 yourself (as in the -1 case).

are there any good cases besides this that Walter has?  And even if there are, we are not talking about silently mis-interpreting it.  There is precedent for making valid C code an error because it is error prone.

If no good cases exist, I'd say drop it.

-Steve
February 15, 2010
Steven Schveighoffer wrote:
> are there any good cases besides this that Walter has?  And even if there are, we are not talking about silently mis-interpreting it.  There is precedent for making valid C code an error because it is error prone.


Here's where I'm coming from with this. The problem is that CPU integers are 2's complement and a fixed number of bits. We'd like to pretend they work just like whole numbers we learned about in 2nd grade arithmetic. But they don't, and we can't fix it so they do. I think it's ultimately fruitless to try and make them behave other than what they are: 2's complement fixed arrays of bits.

So, we wind up with oddities like overflow, wrap-around, -int.min==int.min. Heck, we *rely* on these oddities (subtraction depends on wrap-around). Sometimes, we pretend these bit values are signed, sometimes unsigned, and we mix together those notions in the same expression.

There's no way to not mix up signed and unsigned arithmetic.

Trying to build walls between signed and unsigned integer types is an exercise in utter futility. They are both 2-s complement bits, and it's best to treat them that way rather than pretend they aren't.

As for -x in particular, - is not negation. It's complement and increment, and produces exactly the same bit result for signed and unsigned types. If it is disallowed for unsigned integers, then the user is faced with either:

   (~x + 1)

which not only looks weird in an arithmetic expression, but then a special case for it has to be wired into the optimizer to turn it back into a NEG instruction. Or:

   -cast(int)x

That blows when x happens to be a ulong. Whoops. It blows even worse if x turns out to be a struct with overloaded opNeg and opCast, suddenly the opCast gets selected. Oops.

We could use a template:

    -MakeSignedVersionOf(x)

and have to specialize that template for every user defined type, but, really, please no.