July 11, 2012
Marco Leise:

> Phobos:
>
>    (boxer.d):
>    assert (box(1) == box(cast(byte)1));
> => assert (box(1) == box(1b));
>
>    (algorithm.d):
>    assert(b == [ cast(ubyte) 0, cast(ubyte)2, cast(ubyte)1, cast(ubyte)6, cast(ubyte)5], text(b));
> => assert(b == [ 0ub, 2ub, 1ub, 6ub, 5ub], text(b));

Here b is an ubyte[] of length 5. I think this works:

assert(b == [0, 2, 1, 6, 5], text(b));

Because this works:

void main() {
    ubyte[] a = [1, 2];
    assert(a == [1, 2]);
}



> => a = 5s;

I read that as "5 seconds" :-(



> GtkD:
>
>    (Color.d and several other occurences):
>    _black = new Color(cast(ubyte)0,cast(ubyte)0,cast(ubyte)0);
> => _black = new Color(0ub,0ub,0ub);

This is a reduction of the Color class of GtkD:

public class Color {
    this(ubyte red, ubyte green, ubyte blue) {}
}

There is no need to use those casts:

void main() {
    auto _black = new Color(0, 0, 0);
}


> ScintillaD:
>
>    (SciTEWin.d):
>    SendMessage(HwndOf(wText), CB_SETEDITSEL, 0, MAKELPARAM(0, cast(ushort)-1));
> => SendMessage(HwndOf(wText), CB_SETEDITSEL, 0, MAKELPARAM(0, -1us));

"cast(ushort)-1" isn't a good idiom in D. Better to write "ushort.max".


I don't think your examples justify the increased language complexity.

Bye,
bearophile
July 11, 2012
On 07/11/12 20:32, Walter Bright wrote:
> On 7/11/2012 9:45 AM, David Piepgrass wrote:
>> I still type "reutrn" and "retrun" all the damn time!
> 
> I keep finding myself typing "redrum" !

Good one :D
July 11, 2012
Marco Leise:

> Then again it also has 'begin' and 'end' instead of { and }. Masochists...

Between APL/Ursala and Ada extremes there is a wide happy middle, D, Pascal and probably Rust too are all usable.

The 'begin' and 'end' of Pascal are not bad, they are short lowercase words written with common letters. I need to press 3 not easy keys at the same time to print a single { in a text file. So probably writing "end" is about as fast or faster for me :-)

Bye,
bearophile
July 12, 2012
On 11/07/2012 21:50, Walter Bright wrote:
> On 7/11/2012 11:54 AM, David Piepgrass wrote:
>> That reminds me, I was so happy the first two times I got an undefined
>> symbol
>> error in D. The compiler said: "Did you mean '<correct variable
>> name>'?" LOL,
>> don't tell me how it works... it's magic, right? I love a good error
>> message.
>
> I added a spelling checker to the undefined identifier code, using the
> variables in scope as the dictionary. It's a fun little nicety.
>

Yeah, that one is really nice and usually useful. However, you can get really weird stuff if you forget an import for instance.
July 12, 2012
On 07/11/2012 02:00 PM, David Piepgrass wrote:
>
> I am particularly a fan of structural typing. I don't know if Rust uses
> it but Opa and other functional languages often do. You see, there's a
> problem that pops up in .NET all the time, and probably the same problem
> exists in D.
>
> Any time two libraries want to use the same concept, but the concept is
> not in the standard library, they need to define it. For instance if
> there is no "Point" type in the standard library, but two unrelated
> libraries need points, they will both define their own (amazingly,
> Points are poorly thought out in .NET and tightly bound to GUI
> libraries, so people define their own in some cases):
>
> // JoesLibrary
> struct Point!T { T x, y; /* followed by some manipulation functions */ }
>
> // FunkyLibrary
> struct Point!T { T x, y; /* followed by other manipulation functions */ }
>
> Sadly, the two point types are not compatible with each other. A client
> that wants to use both libraries now has an interoperability problem
> when he wants to pass data between the.
>
> Even a client that uses only one of the library, let's call it
> "JoesLibrary" has to import Point from "JoesLibrary", even if its
> functionality is not quite what the client wants. It would be much nicer
> if the client could define his own Point struct that seamlessly
> interoperates with Joes'. In D this is currently impractical, but I
> would enjoy designing a way to make it work (before you point out that
> "what if x and y are in a different order in the two structs" and "it
> could be T X,Y in one and T x,y in the other", yes, I know, It's on my
> list of problems to cleverly solve)
>
> A similar problem exists with interfaces, where two unrelated libraries
> expose two similar classes with some common functions, but you can't
> cast them to a common type in D. This is a solved problem in Go
> (http://www.airs.com/blog/archives/277) and it's actually pretty easy
> for a compiler to magically cast a class to an interface that the class
> did not declare--if the underlying language is designed for that, anyway.
>
> In fact, in .NET at least, the same problem exists even if the libraries
> DO know about each other and are even written by the same person and use
> identical interfaces. The problem is, if I write two libraries A and B,
> and I want them to be interoperable, then I need to factor out the
> common structs and interfaces to a microscopic third library, I. But
> from the client's perspective, if a client only knows about A or B, he
> will think it's stupid that I require him to use and deploy two
> DLLs/so's (A and I, or B and I) instead of one. In D I guess it's not
> the same, though.
>

I'm pretty sure this interoperability thing is solved in D, at least at compile time.

Example:

import std.traits;

/// Returns true if T is a Point type.
template isPoint(T)
{
    enum bool isPoint = is(typeof(
    {
        T point;

        // (x,y) should be numeric.
        static assert ( isNumeric!(typeof(point.x)) );
        static assert ( isNumeric!(typeof(point.y)) );

        auto x = point.x; // x is readable
        point.x = x;      // x is writable

        auto y = point.y; // y is readable
        point.y = y;      // y is writable
    }));
}

struct MyPointType
{
    float x;
    float y;
}

struct AnotherPointType
{
    int x;
    int y;
}

struct NotAPoint
{
    char[] x;
    char[] y;
}

// TODO: are x and y allowed to have differing types?
static assert(isPoint!MyPointType);
static assert(isPoint!AnotherPointType);
static assert(!isPoint!NotAPoint);

auto myPointCalculation(P1,P2)( P1 p1, P2 p2 ) if ( isPoint!P1 && isPoint!P2 )
{
    p1.x += p2.x;
    p1.y += p2.y;
    return p1;
}

import std.stdio;
void main()
{
    MyPointType p1;
    AnotherPointType p2;
    p1.x = 3.5;
    p1.y = 5.0;
    p2.x = 2;
    p2.y = 2;
    writefln("(before) p1 == (%s, %s)",p1.x,p1.y);
    p1 = myPointCalculation(p1,p2);
    writefln("(after)  p1 == (%s, %s)",p1.x,p1.y);
}



At the command line:
chad@Hugin ~/dprojects/dtesting/points $ dmd points.d
chad@Hugin ~/dprojects/dtesting/points $ ./points
(before) p1 == (3.5, 5)
(after)  p1 == (5.5, 7)
July 12, 2012
>"David Piepgrass"  wrote in message news:jdyhfsxgucfglqgajezn@forum.dlang.org...
>> Rust has type classes from Haskell (with some simplifications for higher kinds), uniqueness typing, and typestates.
>
>As nice as kinds, typestates, typeclasses and several pointer types may be, I was in the Rust mailing list and felt unable to participate because they kept using terminology that only PhD in type systems understand. And googling for "kind" doesn't tell me a darn thing ;)

I always find these type of comments strange due to my background.

In most Portuguese universities, functional and logic programming, type systems,
theory of computation and compiler design are part of the normal curriculum. You
don't need to do a Phd for them.

--
Paulo 

July 12, 2012
Am Wed, 11 Jul 2012 22:58:07 +0200
schrieb "bearophile" <bearophileHUGS@lycos.com>:

> > => a = 5s;
> 
> I read that as "5 seconds" :-(

Me too, but then again "5l" could be read as 5 liters. I guess that is why the move is towards uppercase suffixes. 5S and 5L are not likely misread.

> I don't think your examples justify the increased language complexity.
> 
> Bye,
> bearophile

I understand that some of the examples have better alternatives. What I don't understand is why you term this as increased language complexity. This is not one of the "why not add" kind of requests. From my point of view the complexity is already there through U, UL, I and UI. So completing the set with B, UB, S and US seems only logical and solves an existing (attention: buzzword ahead) ... *inconsistency*. ;)

To cut a long story short; if I added those suffixes and made a pull request would anyone be objected?

-- 
Marco

July 12, 2012
Am Thu, 12 Jul 2012 11:42:13 +0200
schrieb Marco Leise <Marco.Leise@gmx.de>:

> Am Wed, 11 Jul 2012 22:58:07 +0200
> schrieb "bearophile" <bearophileHUGS@lycos.com>:
> 
> > > => a = 5s;
> > 
> > I read that as "5 seconds" :-(
> 
> Me too, but then again "5l" could be read as 5 liters. I guess that is why the move is towards uppercase suffixes. 5S and 5L are not likely misread.
> 
> > I don't think your examples justify the increased language complexity.
> > 
> > Bye,
> > bearophile
> 
> I understand that some of the examples have better alternatives. What I don't understand is why you term this as increased language complexity. This is not one of the "why not add" kind of requests. From my point of view the complexity is already there through U, UL, I and UI. So completing the set with B, UB, S and US seems only logical and solves an existing (attention: buzzword ahead) ... *inconsistency*. ;)
> 
> To cut a long story short; if I added those suffixes and made a pull request would anyone be objected?

P.S.: There is no I or UI, just L and UL. Sorry for the confusion.

-- 
Marco

July 12, 2012
On 07/11/2012 03:50 PM, Walter Bright wrote:
> On 7/11/2012 11:54 AM, David Piepgrass wrote:
>> That reminds me, I was so happy the first two times I got an undefined
>> symbol
>> error in D. The compiler said: "Did you mean '<correct variable
>> name>'?" LOL,
>> don't tell me how it works... it's magic, right? I love a good error
>> message.
>
> I added a spelling checker to the undefined identifier code, using the
> variables in scope as the dictionary. It's a fun little nicety.
>

I remember you took some heat for this because of compiler slowdowns, as well as a public admonishment from Andrei because it wasn't a priority. Must be nice to get some positive feedback on it :)
July 12, 2012
Am Thu, 12 Jul 2012 08:22:59 -0400
schrieb Jeff Nowakowski <jeff@dilacero.org>:

> On 07/11/2012 03:50 PM, Walter Bright wrote:
> > On 7/11/2012 11:54 AM, David Piepgrass wrote:
> >> That reminds me, I was so happy the first two times I got an undefined
> >> symbol
> >> error in D. The compiler said: "Did you mean '<correct variable
> >> name>'?" LOL,
> >> don't tell me how it works... it's magic, right? I love a good error
> >> message.
> >
> > I added a spelling checker to the undefined identifier code, using the variables in scope as the dictionary. It's a fun little nicety.
> >
> 
> I remember you took some heat for this because of compiler slowdowns, as well as a public admonishment from Andrei because it wasn't a priority. Must be nice to get some positive feedback on it :)

I don't know the implementation, but compile time should not be a problem. The dictionary is only needed one time and when the build fails anyway. This is indeed a cool feature ;). If Walter ever wants to refine it, it could try any proposal until valid code is created; unless code correctness is only checked at a later state (semantic analysis or what compiler gurus call it).

-- 
Marco