March 07, 2009
Charles Hixson wrote:
> Perhaps there just *ISN'T* a good way to do templates & mixins.  The syntaxes that I have encountered previously, including D's, have caused me to avoid all but the simplest cases of using them.  I admit that they appear quite powerful (not really using them I can't say more than that), but they're UGLY.  Well, habituation can change ones aesthetic sense, so that's not really objective.  They look ugly to me at the present time, as they have for the past year.

templates and mixins were designed fairly independently of each other, without much of any existing practice to see how it should be done, so it's not a big surprise that they may not fit together that nicely.

> As always, these are relatively trivial problems.  The major problem is the lack of libraries, and there doesn't seem to be any way around that except time.  But the division between tango and phobos isn't making solving that any easier.  (I'm afraid that I can't bring myself to trust tangobos.  It always seems to be mentioned with a "you can use this until you really convert to tango" kind of comment.)

Sean Kelly has put together druntime, which provides a common root for phobos and tango so they can work together.
March 07, 2009
Andrei Alexandrescu wrote:
> One improvement from the language could come from dropping the parens requirement for mixin, in which case:
> 
>  mixin bitfields!"
>       uint x :  2,
>       int  y :  3,
>       uint z :  2,
>       bool flag : 1,
>       ";

Have to resolve the ambiguity with template mixins for that to work.
March 07, 2009
Gregor Richards wrote:
> I realize people are going to misuse the term Open Source. However, the term is NOT generic, and DOES have a specific meaning; it is in fact trademarked, and using it to describe software that does not fit the Open Source Definition is in violation of the trademark. But more importantly than that, it's confusing to the loads of people out here who use F/OSS and depend on the freedoms it provides. Without redistribution rights, F/OSS is substantially less valuable, as it doesn't provide any escape if the original creator loses interest, spontaneously combusts, decides he hates giving away his source and closes it again, etc, etc, etc.

I've heard the term 'disclosed source' before, in the context of various Microsoft products where the source code is available but not redistributable. It's as good a choice as any.
March 08, 2009
Walter Bright wrote:
> grauzone wrote:
>> Georg Wrede wrote:
>>> Like a can opener. You can live weeks without needing one, but when you've got a can, it's not nice to open it with the kitchen knife.
>>
>> Creating a can opener on your own is not as trivial as re-implementing bitfields.
> 
> Using a table knife as a chisel should do the job. A kitchen knife is probably too thin and brittle.

Duh! And still I see women use the kitchen knife for such. And of course the "blond thing" (that I see all women do), wrench jobs by default tried with pliers.

My mother in law got herself a cutting board -- made of glass.
March 08, 2009

Walter Bright wrote:
> Andrei Alexandrescu wrote:
>> One improvement from the language could come from dropping the parens requirement for mixin, in which case:
>>
>>  mixin bitfields!"
>>       uint x :  2,
>>       int  y :  3,
>>       uint z :  2,
>>       bool flag : 1,
>>       ";
> 
> Have to resolve the ambiguity with template mixins for that to work.

mixin:blah
mixin.blah
mixin!blah

If you do something like this, I'd just want this to work:

mixin!bitfields("uint x : 2")

I use mixins with CTFE functions WAY MORE than I use them with templates.

Incidentally, writing something that parses the above language for bitfields wouldn't be too hard.  I've done something similar for defining properties.

  -- Daniel
March 08, 2009
Charles Hixson escribió:
> Andrei Alexandrescu wrote:
>> Michel Fortin wrote:
>>> On 2009-03-06 14:35:59 -0500, Walter Bright <newshound1@digitalmars.com> said:
>>>
>>>> Andrei Alexandrescu wrote:
>>>>> "Can't live without bitfields! Give me bitfields and I'll lift the Earth!"
>>>>>
>>>>> "Here they are, std.bitmanip. Well-defined and more portable and flexible than C's."
>>>>>
>>>>> "Meh, don't like the definition syntax."
>>>>
>>>> Classic.
>>>
>>> Well, he certainly has a point. Compare this:
>>>
>>>     mixin(bitfields!(
>>>         uint, "x",    2,
>>>         int,  "y",    3,
>>>         uint, "z",    2,
>>>         bool, "flag", 1));
>>>
>>> With this:
>>>
>>>     uint x : 2;
>>>     int  y : 3;
>>>     uint z : 2;
>>>     bool flag : 1;
>>>
>>> The second is certainly prettier and more readable.
>>
>> (Just to clarify: to me the humor of the situation was that someone who considered bitfields an absolute prerequisite for language adoption subsequently found the syntax excuse to bail out. Essentially the hypothetical user was fabricating one pretext after another to rationalize their pre-made decision to not try D -- an absolute classic attitude when it comes about acquiring new programming languages.)
>>
>> About the syntax itself - definitions are few and uses are many. In addition the D solution:
>>
>> (a) guarantees data layout;
>>
>> (b) offers symbolic limits, e.g. x_max and x_min are automatically added as enums;
>>
>> (c) checks for overflow, which is essential for small bitfields;
>>
>> (d) offers a way to manipulate the fields wholesale by using the concatenation of all their names, e.g. xyzflag;
>>
>> (e) suggests that there are other cool things that can be done within the language, not by adding features to it.
>>
>> Hopefully that makes up for the more loaded syntax.
>>
>>> Does it matter much? Not to me; I rarely use bit fields. If I were using them a lot, perhaps I'd be more concerned.
>>
>> I am using them here and there - even in Phobos - and they work very well.
>>
>>> While I don't care very much about bitfields, that "mixin(tmpl!(...))" syntax is awful. "mixin tmpl!(...)" is better, but has too many limitations, and it isn't always clear for the user which one should be used. Couldn't D2 get a better syntax for mixins?
>>
>> I agree it should.
>>
>>
>> Andrei
> I'm glad that they're there.  And I'm glad that they work.  But I really hate the syntax, and am glad I've never needed to use them.  MUCH better would have been:
> mixin(bitfields!("
>      uint, x,    2,
>      int,  y,    3,
>      uint, z,    2,
>      bool, flag, 1
>      ")
> 
> even better would have been:
> mixin(bitfields!("
>      uint x :  2,
>      int  y :  3,
>      uint z :  2,
>      bool flag : 1
>      ")

Why do the parsing yourself if you can leave that to the compiler? Just read the docs, pass the arguments and that's it. Way much easier. You get standard error messages, if you use an IDE you get autocompletion for the parameters, etc.

I really don't know why everyone is so obsessed with strings... :-P
March 08, 2009
Daniel Keep wrote:
> I use mixins with CTFE functions WAY MORE than I use them with templates.

I'm not surprised. I feel the template mixins were probably a mistake.
March 08, 2009
Walter Bright Wrote:

> Daniel Keep wrote:
> > I use mixins with CTFE functions WAY MORE than I use them with templates.
> 
> I'm not surprised. I feel the template mixins were probably a mistake.

I like template mixins and use them. I don't use them much, but they are very useful for events (signals/slots) at least. The signals in Phobos uses template mixins, and I'm writing a GUI library where I'm using events similarly as a template mixin:

mixin Event!(whenMouseDown) mouseDown;
void whenMouseDown(MouseDownEventArgs e) { }

I don't think there is another way to get as nice a syntax, and events are important in a GUI. Though I still wish I could document the mixed-in templates... (bug #648)

With CTFE and mixins, I'm not thrilled with passing code around as a string (no syntax highlighting), even though it is really powerful. But I don't think I will mind much in D2 with token strings. Still, finding a better syntax for mixin(string) would be great.

March 08, 2009

Walter Bright wrote:
> Daniel Keep wrote:
>> I use mixins with CTFE functions WAY MORE than I use them with templates.
> 
> I'm not surprised. I feel the template mixins were probably a mistake.

Well, there's really a few things at play here:

1. I use templates for simple forward code generation based on types.  I use CTFE for complex code generation that requires parsing or any customisability more involved than specifying what T is.

2. Because of most of this, most of my templates are self-contained while my CTFE is meant to be mixed in to another context.

3. String mixins let me insert functionality and execute it in a single line.  If I use a templated function, it doesn't have access to its context.  If I mix it in first, then I have to have a second line to invoke it.  That is, this:

> mixin(doStuff);

versus

> mixin doStuff;
> _doStuff();

4. An added issue is that there is *no way* to replicate this with templates:

> mixin(`
>   private int _storage_foo;
>   public int foo() { return _storage_foo; }
>   public int foo(int v) { return _storage_foo = v; }
> `);

This is generally an issue where I have a mixin that implements some interface, but needs backend "wiring" exposed in places to the mixin-ing context.

Ideally, I'd be able to do this:

> mixin Foo;
>
> template Foo
> {
>     private int _counter_foo;
>     mixin private int _storage_foo;
>     public int foo() { ++_counter_foo; return _storage_foo; }
>     public int foo(int v) { ++_counter_foo; return _storage_foo = v; }
> }

This way, I can specify that the protection attributes are referring to the mixin-ing context, and not to the template itself.

I think the major issue is that string mixins represent a superset of template mixin functionality.  I wouldn't say they were a mistake: more that they haven't kept pace.

At the end of the day, string mixins are indispensable as a "safe" form of text substitution... but they are a still a hack that should, in most cases, be replaced with better language facilities.

  -- Daniel
March 08, 2009

Ary Borenszweig wrote:
> Charles Hixson escribió:
>> I'm glad that they're there.  And I'm glad that they work.  But I
>> really hate the syntax, and am glad I've never needed to use them.
>> MUCH better would have been:
>> mixin(bitfields!("
>>      uint, x,    2,
>>      int,  y,    3,
>>      uint, z,    2,
>>      bool, flag, 1
>>      ")
>>
>> even better would have been:
>> mixin(bitfields!("
>>      uint x :  2,
>>      int  y :  3,
>>      uint z :  2,
>>      bool flag : 1
>>      ")
> 
> Why do the parsing yourself if you can leave that to the compiler? Just read the docs, pass the arguments and that's it. Way much easier. You get standard error messages, if you use an IDE you get autocompletion for the parameters, etc.
> 
> I really don't know why everyone is so obsessed with strings... :-P

mixin(cvars!
`
    int window.width as width = 640;
    int window.height as height = 480;
`
);

and

mixin(cvars!
(
    int, "window.width, width", 640,
    int, "window.height, height", 480
)
);

are functionally the same, and have almost exactly the same length.

Except the first looks cooler and has a more natural syntax.  Sometimes, that's important.

As for the IDE issue, I'm increasingly of the opinion that this is a shortcoming of IDEs.  For example, I've never seen an IDE that got script in HTML right.  Certainly not if you change the language being used under it's feet.

Maybe it's time IDEs started supporting embedded DSLs as a matter of course.  Dunno how, but that's their problem, not mine.  :P

  -- Daniel