December 14, 2009
"Kagamin" <spam@here.lot> wrote in message news:hg5bnt$1105$1@digitalmars.com...
> Nick Sabalausky Wrote:
>
>>    - Many GTK apps use the absolute *worst* and most impractical file
>> dialog
>> boxes I've seen in over 15 years. This is never an issue with native
>> apps.
>
> I like how gimp dialog box provides mruds, which is not done by virtually any other windows application, this is extremely useful, which is a practical concern.

(I assume you mean "most recently used (documents|directories)")

That's something I think is much better handled by something other than the individual application. Something like this would be much better: Have a system where it's possible to install add-ons to the system dialog boxes. There would be a utility (accessible via an app and via an API) to manage these add-ons which would allow the user (or an application) to enable/disable/tweak these add-ons on both a universal level and override any of the settings on an application-by-application basis.


December 14, 2009
On 12/13/09 20:44, Eldar Insafutdinov wrote:
> Nick Sabalausky Wrote:
>
>> "Nick Sabalausky"<a@a.a>  wrote in message
>> news:hg394f$mr1$1@digitalmars.com...
>>> "Eldar Insafutdinov"<e.insafutdinov@gmail.com>  wrote in message
>>> news:hg2p87$2ttj$1@digitalmars.com...
>>>>
>>>> 1) You may know the concept of signals and slots in Qt. Consider the
>>>> following snippet:
>>>>
>>>> class Test : QObject
>>>> {
>>>>     mixin Signal!("signal_1(string)");
>>>>
>>>>     mixin Slot!("slot_1(string str)");
>>>>     void slot_1(string str)
>>>>     {
>>>>         writefln("slot_1 invoked with ~ " str);
>>>>     }
>>>>
>>>>     mixin Q_OBJECT;
>>>> }
>>>>
>>>> In Qt objects, that inherit from QObject are capable of having signals
>>>> and slots and participate in connections. In the current scheme mixins of
>>>> Signal and Slot template mix some static information into the class. The
>>>> class is then scanned when Q_OBJECT template is mixed in and the proper
>>>> meta-information is generated to register signals and slots in the Qt
>>>> type system.
>>>> As you see, this declaration is a bit ugly. In particular defining a slot
>>>> requires to duplicate its signature in a mixin. What would really be
>>>> awesome is a mechanism allowing something like:
>>>>
>>>>     @Slot
>>>>     void slot_1(string str)
>>>>     {
>>>>         writefln("slot_1 invoked with " ~ str);
>>>>     }
>>>> I.e we need annotations. But I am not sure how this will work. One of the
>>>> possible solutions will be that @Slot expands into mixin Slot!(symbol,
>>>> AnnotationArg1, ...).
>>>>
>>>
>>
>> Oops, slight typo:
>>
>>> Try string mixins, something like this:
>>>
>>> 1. Rename Slot to _Slot.
>>>
>>> 2. Do this:
>>>
>>
>> // Fixed:
>> template Slot(string decl, string body)
>> {
>>      const string Slot = "
>>          mixin _Slot!("~decl.stringof~");
>>          void slot_1(string str)
>>          {
>>              "~body.stringof~"
>>          }
>>      ";
>> }
>>
>>>
>>> class Test : QObject
>>> {
>>>     mixin Signal!("signal_1(string)");
>>>
>>>     mixin( Slot!("slot_1(string str)", q{
>>>         writefln("slot_1 invoked with ~ " str);
>>>     }) );
>>>
>>>    mixin Q_OBJECT;
>>> }
>>>
>>>
>>
>>
>
> Thank you for suggestion, but while reducing redundancy it became even uglier! I'll better stay with the current syntax.

To make it look a little better you can do like this:

template Slot (ReturnType, alias method, ARGS...)
{
// code
}

template Slot (alias method)
{
	mixin Slot!(ReturnType!(method), method, ParameterTypeTuple!(method));
}

If the method is overloaded, use the first version, otherwise use the second. Use them like this:

class Test : QObject
{	
    mixin Slot!(slot_1);
    void slot_1(string str)
    {
        writefln("slot_1 invoked with ~ " str);
    }

    mixin Q_OBJECT;
}
December 14, 2009
On 12/14/09 20:29, Jacob Carlborg wrote:
> On 12/13/09 20:44, Eldar Insafutdinov wrote:
>> Nick Sabalausky Wrote:
>>
>>> "Nick Sabalausky"<a@a.a> wrote in message
>>> news:hg394f$mr1$1@digitalmars.com...
>>>> "Eldar Insafutdinov"<e.insafutdinov@gmail.com> wrote in message
>>>> news:hg2p87$2ttj$1@digitalmars.com...
>>>>>
>>>>> 1) You may know the concept of signals and slots in Qt. Consider the
>>>>> following snippet:
>>>>>
>>>>> class Test : QObject
>>>>> {
>>>>> mixin Signal!("signal_1(string)");
>>>>>
>>>>> mixin Slot!("slot_1(string str)");
>>>>> void slot_1(string str)
>>>>> {
>>>>> writefln("slot_1 invoked with ~ " str);
>>>>> }
>>>>>
>>>>> mixin Q_OBJECT;
>>>>> }
>>>>>
>>>>> In Qt objects, that inherit from QObject are capable of having signals
>>>>> and slots and participate in connections. In the current scheme
>>>>> mixins of
>>>>> Signal and Slot template mix some static information into the
>>>>> class. The
>>>>> class is then scanned when Q_OBJECT template is mixed in and the
>>>>> proper
>>>>> meta-information is generated to register signals and slots in the Qt
>>>>> type system.
>>>>> As you see, this declaration is a bit ugly. In particular defining
>>>>> a slot
>>>>> requires to duplicate its signature in a mixin. What would really be
>>>>> awesome is a mechanism allowing something like:
>>>>>
>>>>> @Slot
>>>>> void slot_1(string str)
>>>>> {
>>>>> writefln("slot_1 invoked with " ~ str);
>>>>> }
>>>>> I.e we need annotations. But I am not sure how this will work. One
>>>>> of the
>>>>> possible solutions will be that @Slot expands into mixin Slot!(symbol,
>>>>> AnnotationArg1, ...).
>>>>>
>>>>
>>>
>>> Oops, slight typo:
>>>
>>>> Try string mixins, something like this:
>>>>
>>>> 1. Rename Slot to _Slot.
>>>>
>>>> 2. Do this:
>>>>
>>>
>>> // Fixed:
>>> template Slot(string decl, string body)
>>> {
>>> const string Slot = "
>>> mixin _Slot!("~decl.stringof~");
>>> void slot_1(string str)
>>> {
>>> "~body.stringof~"
>>> }
>>> ";
>>> }
>>>
>>>>
>>>> class Test : QObject
>>>> {
>>>> mixin Signal!("signal_1(string)");
>>>>
>>>> mixin( Slot!("slot_1(string str)", q{
>>>> writefln("slot_1 invoked with ~ " str);
>>>> }) );
>>>>
>>>> mixin Q_OBJECT;
>>>> }
>>>>
>>>>
>>>
>>>
>>
>> Thank you for suggestion, but while reducing redundancy it became even
>> uglier! I'll better stay with the current syntax.
>
> To make it look a little better you can do like this:
>
> template Slot (ReturnType, alias method, ARGS...)
> {
> // code
> }
>
> template Slot (alias method)
> {
> mixin Slot!(ReturnType!(method), method, ParameterTypeTuple!(method));
> }
>
> If the method is overloaded, use the first version, otherwise use the
> second. Use them like this:
>
> class Test : QObject
> {
> mixin Slot!(slot_1);
> void slot_1(string str)
> {
> writefln("slot_1 invoked with ~ " str);
> }
>
> mixin Q_OBJECT;
> }

ReturnType and ParameterTypeTuple are available in std.traits, in Tango they're in tango.core.Traits under slightly different names.
December 14, 2009
On 2009-12-14 11:41:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Adam D. Ruppe wrote:
>> On Mon, Dec 14, 2009 at 07:24:11AM -0800, Andrei Alexandrescu wrote:
>>> D2 will include properties that are understood by the compiler. We currently don't have a design for user-defined properties.
>> 
>> Can I suggest something very simple: make them accessible from __traits,
>> and leave the rest to the library. Accept @anything_at_all.
>> 
>> @myprop int a;
>> 
>> assert(__traits(getAnnotations, a) == [ "myprop" ]);
> 
> I just had a little related idea. If you (Eldar) put the property in the naming convention, then you may be able to simplify things by using __traits(allMembers, Type), which works now.
> 
> For example: all signals start with "signal_" and all slots start with "slot_".
> 
> Would that work?

It could work for simple things, but it doesn't scale well. If I wanted to use attributes for my D/Objective-C bridge, I'd need them to be parametrized:

	@objc("sizeWithFont:forWidth:lineBreakMode:")
	CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);

Currently, this would be:

	CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
	mixin ObjcBindMethod(sizeWithFont, CGSize, "sizeWithFont:forWidth:lineBreakMode:", UIFont, CGFloat, UILineBreakMode);

With a naming convention, it'd have to be something like:

	CGSize objc_sizeWithFont_forWidth_lineBreakMode_(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);

Shorter to declare, but a pain to use.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 14, 2009
Michel Fortin wrote:
> On 2009-12-14 11:41:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
>> Adam D. Ruppe wrote:
>>> On Mon, Dec 14, 2009 at 07:24:11AM -0800, Andrei Alexandrescu wrote:
>>>> D2 will include properties that are understood by the compiler. We currently don't have a design for user-defined properties.
>>>
>>> Can I suggest something very simple: make them accessible from __traits,
>>> and leave the rest to the library. Accept @anything_at_all.
>>>
>>> @myprop int a;
>>>
>>> assert(__traits(getAnnotations, a) == [ "myprop" ]);
>>
>> I just had a little related idea. If you (Eldar) put the property in the naming convention, then you may be able to simplify things by using __traits(allMembers, Type), which works now.
>>
>> For example: all signals start with "signal_" and all slots start with "slot_".
>>
>> Would that work?
> 
> It could work for simple things, but it doesn't scale well. If I wanted to use attributes for my D/Objective-C bridge, I'd need them to be parametrized:
> 
>     @objc("sizeWithFont:forWidth:lineBreakMode:")
>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
> 
> Currently, this would be:
> 
>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>     mixin ObjcBindMethod(sizeWithFont, CGSize, "sizeWithFont:forWidth:lineBreakMode:", UIFont, CGFloat, UILineBreakMode);
> 
> With a naming convention, it'd have to be something like:
> 
>     CGSize objc_sizeWithFont_forWidth_lineBreakMode_(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
> 
> Shorter to declare, but a pain to use.
> 

Maybe opDispatch could help the use scenario.

Andrei
December 14, 2009
On 2009-12-14 16:04:18 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Michel Fortin wrote:
>> On 2009-12-14 11:41:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
>> 
>>> Adam D. Ruppe wrote:
>>>> On Mon, Dec 14, 2009 at 07:24:11AM -0800, Andrei Alexandrescu wrote:
>>>>> D2 will include properties that are understood by the compiler. We currently don't have a design for user-defined properties.
>>>> 
>>>> Can I suggest something very simple: make them accessible from __traits,
>>>> and leave the rest to the library. Accept @anything_at_all.
>>>> 
>>>> @myprop int a;
>>>> 
>>>> assert(__traits(getAnnotations, a) == [ "myprop" ]);
>>> 
>>> I just had a little related idea. If you (Eldar) put the property in the naming convention, then you may be able to simplify things by using __traits(allMembers, Type), which works now.
>>> 
>>> For example: all signals start with "signal_" and all slots start with "slot_".
>>> 
>>> Would that work?
>> 
>> It could work for simple things, but it doesn't scale well. If I wanted to use attributes for my D/Objective-C bridge, I'd need them to be parametrized:
>> 
>>     @objc("sizeWithFont:forWidth:lineBreakMode:")
>>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>> 
>> Currently, this would be:
>> 
>>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>>     mixin ObjcBindMethod(sizeWithFont, CGSize, "sizeWithFont:forWidth:lineBreakMode:", UIFont, CGFloat, UILineBreakMode);
>> 
>> With a naming convention, it'd have to be something like:
>> 
>>     CGSize objc_sizeWithFont_forWidth_lineBreakMode_(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>> 
>> Shorter to declare, but a pain to use.
> 
> Maybe opDispatch could help the use scenario.

Yeah, perhaps opDispatch could help in the latter case, allowing you to call the function using the first part of the Objective-C name (although that's not sufficient in itself since many methods could have the same first part, the D short name could be "mangled" in the function name too).

The bigger problem is that when you use an API, you don't just call functions: you subclass and override functions too. It's pretty interesting to be able to subclass a bridged Objective-C class (such as, say, NSArray, NSWindow, NSApplication) and write your own subclass in D. Having to override functions with names like objc_sizeWithFont_forWidth_lineBreakMode_ is hardly interesting, and opDispatch can't help you with that.

Also, what is currently lacking in the D/Objective-C bridge is support for protocols (Objective-C's equivalent to interfaces). It'd be easy to support protocols as interfaces if functions in an interface could be annotated with the corresponding Objective-C function name.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 15, 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:hg698i$2rpd$1@digitalmars.com...
> Michel Fortin wrote:
>> On 2009-12-14 11:41:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
>>
>>> Adam D. Ruppe wrote:
>>>> On Mon, Dec 14, 2009 at 07:24:11AM -0800, Andrei Alexandrescu wrote:
>>>>> D2 will include properties that are understood by the compiler. We currently don't have a design for user-defined properties.
>>>>
>>>> Can I suggest something very simple: make them accessible from
>>>> __traits,
>>>> and leave the rest to the library. Accept @anything_at_all.
>>>>
>>>> @myprop int a;
>>>>
>>>> assert(__traits(getAnnotations, a) == [ "myprop" ]);
>>>
>>> I just had a little related idea. If you (Eldar) put the property in the naming convention, then you may be able to simplify things by using __traits(allMembers, Type), which works now.
>>>
>>> For example: all signals start with "signal_" and all slots start with "slot_".
>>>
>>> Would that work?
>>
>> It could work for simple things, but it doesn't scale well. If I wanted to use attributes for my D/Objective-C bridge, I'd need them to be parametrized:
>>
>>     @objc("sizeWithFont:forWidth:lineBreakMode:")
>>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode
>> lineBreakMode);
>>
>> Currently, this would be:
>>
>>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode
>> lineBreakMode);
>>     mixin ObjcBindMethod(sizeWithFont, CGSize,
>> "sizeWithFont:forWidth:lineBreakMode:", UIFont, CGFloat,
>> UILineBreakMode);
>>
>> With a naming convention, it'd have to be something like:
>>
>>     CGSize objc_sizeWithFont_forWidth_lineBreakMode_(UIFont font, CGFloat
>> width, UILineBreakMode lineBreakMode);
>>
>> Shorter to declare, but a pain to use.
>>
>
> Maybe opDispatch could help the use scenario.
>
> Andrei

As opDispatch pushes errors from compile-time to run-time, I don't think we should be encouraging its use for anything that isn't inherently dynamic.


December 15, 2009
Nick Sabalausky wrote:
> "Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:hg698i$2rpd$1@digitalmars.com...
>> Michel Fortin wrote:
>>> On 2009-12-14 11:41:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
>>>
>>>> Adam D. Ruppe wrote:
>>>>> On Mon, Dec 14, 2009 at 07:24:11AM -0800, Andrei Alexandrescu wrote:
>>>>>> D2 will include properties that are understood by the compiler. We currently don't have a design for user-defined properties.
>>>>> Can I suggest something very simple: make them accessible from __traits,
>>>>> and leave the rest to the library. Accept @anything_at_all.
>>>>>
>>>>> @myprop int a;
>>>>>
>>>>> assert(__traits(getAnnotations, a) == [ "myprop" ]);
>>>> I just had a little related idea. If you (Eldar) put the property in the naming convention, then you may be able to simplify things by using __traits(allMembers, Type), which works now.
>>>>
>>>> For example: all signals start with "signal_" and all slots start with "slot_".
>>>>
>>>> Would that work?
>>> It could work for simple things, but it doesn't scale well. If I wanted to use attributes for my D/Objective-C bridge, I'd need them to be parametrized:
>>>
>>>     @objc("sizeWithFont:forWidth:lineBreakMode:")
>>>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>>>
>>> Currently, this would be:
>>>
>>>     CGSize sizeWithFont(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>>>     mixin ObjcBindMethod(sizeWithFont, CGSize, "sizeWithFont:forWidth:lineBreakMode:", UIFont, CGFloat, UILineBreakMode);
>>>
>>> With a naming convention, it'd have to be something like:
>>>
>>>     CGSize objc_sizeWithFont_forWidth_lineBreakMode_(UIFont font, CGFloat width, UILineBreakMode lineBreakMode);
>>>
>>> Shorter to declare, but a pain to use.
>>>
>> Maybe opDispatch could help the use scenario.
>>
>> Andrei
> 
> As opDispatch pushes errors from compile-time to run-time,

We looked to it that it doesn't.

Andrei
December 15, 2009
On 2009-12-14 20:56:12 -0500, "Nick Sabalausky" <a@a.a> said:

> "Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message
> news:hg698i$2rpd$1@digitalmars.com...
>> Maybe opDispatch could help the use scenario.
>> 
>> Andrei
> 
> As opDispatch pushes errors from compile-time to run-time, I don't think we
> should be encouraging its use for anything that isn't inherently dynamic.

First, opDispatch is a template, so it's not dynamic dispatch unless your template effectively do its dispatching at runtime. I don't think Andrei was proposing dynamic dispatch here.

And since we're talking about dynamic dispatch: for the overridden methods to work when you create a D subclass of an Objective-C class, all methods have to be declared at compile time, even though in Objective-C they're dynamically bound. The goal of the bridge is to expose Objective-C objects as D objects, and thus overriding must work. It'd be pretty useless if it didn't.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 15, 2009
"Michel Fortin" <michel.fortin@michelf.com> wrote in message news:hg6she$ubg$1@digitalmars.com...
> On 2009-12-14 20:56:12 -0500, "Nick Sabalausky" <a@a.a> said:
>
>> "Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:hg698i$2rpd$1@digitalmars.com...
>>> Maybe opDispatch could help the use scenario.
>>>
>>> Andrei
>>
>> As opDispatch pushes errors from compile-time to run-time, I don't think
>> we
>> should be encouraging its use for anything that isn't inherently dynamic.
>
> First, opDispatch is a template, so it's not dynamic dispatch unless your template effectively do its dispatching at runtime. I don't think Andrei was proposing dynamic dispatch here.
>

Ahh, I had forgotten that.