|
Stephan Bergmann-2 |
|
|
[adding the ML into the loop; hope you don't mind]
On 06/13/2012 12:08 PM, Noel Grandin wrote: > On 2012-06-12 19:07, Stephan Bergmann wrote: >> On 06/12/2012 06:22 PM, Noel Grandin wrote: >>> I'm looking at converting the various places that call >>> createInstance("com.sun.star.frame.Desktop") >>> to use a factory method. >>> >>> I notice that the Desktop IDL looks like >>> published service Desktop >>> { >>> service Frame; >>> interface XDesktop; >>> interface XComponentLoader; >>> interface com::sun::star::document::XEventBroadcaster; >>> } >>> >>> What is the process here? Do I convert Desktop to extend all of the >>> interfaces? Or just one? Or do I create new factory methods? >> >> Technically, a new interface inheriting from all the other interfaces >> would need to be introduced, and the service would need to be changed >> to implement that single interface instead. But that is considered too >> incompatible to do before LO 4. >> >> > > How about if I introduce a new interface XDesktop2 that implements the > necessary interfaces, and a new service Desktop2 that acts as a service > for XDesktop2. > Then I make the XDesktop2 forward to the old Desktop code for the time > being. > > Does this sound reasonable? I wouldn't introduce the extra noise of an additional Desktop2 service. While technically it would be an incompatibility to change the existing, old-style Desktop service (implementing multiple interfaces) into a new-style one implementing a single new XDesktop2, practically it should have little consequences. (As old-style service definitions are, after all, little more than "glorious documentation." I hope I don't miss any obvious blocker here. Anyway, one would need to try this out to be sure.) That leaves the question whether it would be considered a good idea to introduce XDesktop2 now that inherits exactly the same interfaces that the old Desktop service implements. (The underlying question is whether that exact set of interfaces is actually a good choice there, or happens to be a historic mistake that should be improved upon.) But thinking about it, that approach might just be a good one: We start to do changes incrementally now, based on status quo, improve them over time, and by the time of an all-incompatible LO 4 have something new (but already time-tested) and we can remove any stuff that has become obsolete (and potentially clean up the new stuff, like renaming XDesktop2 back to XDesktop or some such). The only problem is with publishing: Ideally, the new XDesktop2 should remain unpublished for now. However, the existing (published) Desktop service could then not be rewritten to use XDesktop2. Solutions would be to either: A Introduce a new Desktop2 after all. B Make XDesktop2 published. C Temporarily remove the codemaker check that prevents a published new-style service from using an unpublished interface. I could envision going down route C. What do others think, overall? Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Michael Meeks-2 |
|
|
Hi Stephan & Noel,
On Wed, 2012-06-13 at 15:22 +0200, Stephan Bergmann wrote: > I wouldn't introduce the extra noise of an additional Desktop2 service. > While technically it would be an incompatibility to change the > existing, old-style Desktop service (implementing multiple interfaces) > into a new-style one implementing a single new XDesktop2, practically it > should have little consequences. (As old-style service definitions are, > after all, little more than "glorious documentation." I hope I don't > miss any obvious blocker here. Anyway, one would need to try this out > to be sure.) I was amused to read the Desktop service and see: /** @deprecated This interface is a documentation error. It was never thought to be supported by this service. Please use the service <type cope="com::sun::star::frame">GlobalEventBroadcaster</type> instead of this interface. */ interface com::sun::star::document::XEventBroadcaster; :-) What new methods did we want on XDesktop2 out of interest ? > But thinking about it, that approach might just be a good one: We start > to do changes incrementally now, based on status quo, improve them over time, > and by the time of an all-incompatible LO 4 have something new (but > already time-tested) and we can remove any stuff that has become > obsolete (and potentially clean up the new stuff, like renaming > XDesktop2 back to XDesktop or some such). So - to get this clear; we would have a 'Desktop' service that is instantiated all over the show: m_xMSFactory->createInstance( ::rtl::OUString( "com.sun.star.frame.Desktop" ) ) That wraps a load of global state; but of course, we don't really have a 'Desktop' anymore ;-) so any chance of a more friendly & helpful variable name ? say "Application" > The only problem is with publishing: Ideally, the new XDesktop2 should > remain unpublished for now. However, the existing (published) Desktop > service could then not be rewritten to use XDesktop2. Solutions would > be to either: Would the XDesktop2 re-implement same methods as XDesktop - if so, I guess scripting bindings would have some sort of nightmare trying to disambiguate them. If we are creating a monster, easily accessible top-level instance; it might be rather good to fatten / widen our API to make it easier to use for scripters. What do I mean by that ? We currently rely on a lot of service activation by string to get global state, which is fragile, and non-completing for many languages / IDEs but I would -love- to have a lot of this stuff tied into a nice big top-level 'Application' API. So - as an example; I would love a: any getConfigKey([in] string path); void setConfigKey([in] string path, [in] any value); Cheesy, incomplete - if you want more you have to go to the real source - but, at the end of the day it would cover 99% of the simple, extension use-cases I think. IMHO there are a set of objects and features that are rather unpleasant to use & find that we could make much easier in this way. Another example might be opening a stream via the ucb - which could be wrapped with a single, simple 'fopen' style method. Similarly focusing on scripting bindings we have: com::sun::star::lang::XComponent getCurrentComponent(); I would prefer that to be: [property] com::sun::star::lang::XComponent activeDocument; or somesuch - and preferably with a wider / fatter interface than XComponent :-) Perhaps with a getActiveDocument() method for the long suffering C++ users who don't want an any in the way. Of course any purists lurking here will immediately want to fragment what I just wrote into a dozen separate, one method interfaces ;-) but my thesis is that queryInterface destroys usability - particularly from scripting languages wrt. autocompletion, and also makes documentation rather unpleasant. ie. put another way - I'd like to re-focus our UNO interfaces from the bottom up (of which XDesktop is a great starting point) to be -far- more useful, and usable for scripting - IMHO -the- primary use-case for UNO and where it can excel. The VBA compatibility interfaces may provide some useful inspiration here I suspect, and more than that I imagine that going and reading a small number of StarOffice basic macros (and the somewhat shameful VBA migration guide ;-), and working out how we can make scripting more succinct and efficient would be wonderful. > C Temporarily remove the codemaker check that prevents a published > new-style service from using an unpublished interface. > > I could envision going down route C. What do others think, overall? Sounds sensible to me; we might want a hard-to-tweak black-list of such interfaces hard-coded in some horrible way (in the tool? :-) to discourage too much of this ? ;-) Is that too radical ? :-) good bike-shedding fodder anyhow. Thanks for bringing it to the list, Regards, Michael. -- [hidden email] <><, Pseudo Engineer, itinerant idiot _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Noel Grandin |
|
|
Hi
Just some context - this is mostly about the "shiny new UNO" i.e. https://bugs.freedesktop.org/show_bug.cgi?id=46808 and using service factories all over the place i.e. converting from uno::Reference< frame::XDesktop > xDesktop( xFactory->createInstance( ::rtl::OUString( "com.sun.star.frame.Desktop " ) ); to uno::Reference< frame::XDesktop > XDesktop = Desktop::create(xComponentContext) I would prefer to avoid redesigning the factories and interfaces in the process. I believe that should be a separate step, if only so that change can occur in reasonably sized steps. i.e. I am politely informing people that if this turns into a "redesign the whole thing" exercise, it will be beyond my skill level, and someone else will have to perform this janitorial work :-) Regards, Noel Grandin. Disclaimer: http://www.peralex.com/disclaimer.html _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Bjoern Michaelsen |
|
|
In reply to this post by Michael Meeks-2
On Thu, Jun 14, 2012 at 10:22:44AM +0100, Michael Meeks wrote:
> So - as an example; I would love a: > > any getConfigKey([in] string path); > void setConfigKey([in] string path, [in] any value); > > Cheesy, incomplete - if you want more you have to go to the real source > - but, at the end of the day it would cover 99% of the simple, extension > use-cases I think. IMHO there are a set of objects and features that are > rather unpleasant to use & find that we could make much easier in this > way. Another example might be opening a stream via the ucb - which could > be wrapped with a single, simple 'fopen' style method. > > Similarly focusing on scripting bindings we have: > > com::sun::star::lang::XComponent getCurrentComponent(); > > I would prefer that to be: > > [property] com::sun::star::lang::XComponent activeDocument; An even more radical approach would be assuming properties to just be a dynamic string->any map. Python allows mapping those to native attributes with: http://docs.python.org/reference/datamodel.html#object.__getattr__ and friends. Its -- ahem "suboptimal" -- from the performance perspective, but we made contributing to upstream for performance critical tasks easier quite a bit, so maybe we should allow ourselves to simplify the extension/scripting interface too? I wonder how much of our scripting functionality can be made available with no static typed interfaces and essentially only map, sequence and "Any" as as static datatypes in UNO and letting the language bindings provide the syntactic sugar around that with reflection and stuff like python metaclasses(*). That would also mean: - No more idl writing, compiling and throwing around as binding, - No more 'I published a sucky interface, but we are stuck with it for eternity now' The limitations wouldnt hurt for Python as it is dynamic enough. It wouldnt hurt C++ assuming all relevant service implementations are C/C++ and one could use that directly instead of UNO bindings. Java might suffer quite a bit as a static typed language not being the native language of the service implementations. IMHO it is still worth consideration. Just some random ramblings. Best, Bjoern (*) http://www.python.org/doc/essays/metaclasses/ _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Michael Meeks-2 |
|
|
Hi Bjoern,
On Thu, 2012-06-14 at 12:02 +0200, Bjoern Michaelsen wrote: > > [property] com::sun::star::lang::XComponent activeDocument; > > An even more radical approach would be assuming properties to just be a dynamic > string->any map. Python allows mapping those to native attributes with: The problem is - if you use a Java or C# binding that requires types, and can provide intelligent auto-completion in the code (at least until we hit an 'any' or 'queryInterface') - then using this overly-generic: any doIt([in] any); style interface for everything not only robs you of documentation and auto-completion, but also means that you have to go lookup the types carefully to make sure you don't shove an any into a string when it is really an int (or whatever) and thus bust your run-time :-) > letting the language bindings provide the syntactic sugar around > that with reflection and stuff like python metaclasses(*). That > would also mean: So - syntactic sugar sounds good to me ;-) I'd particularly like a built-in UNO, efficient signal/slot mechanism and native language bindings for each language [ but particularly C++ ]. Native sugar for our new "one stream interface" might be good too, to make streaming intuitive. Anyhow ;-) that's my take. ATB, Michael. -- [hidden email] <><, Pseudo Engineer, itinerant idiot _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Michael Meeks-2 |
|
|
In reply to this post by Noel Grandin
On Thu, 2012-06-14 at 11:39 +0200, Noel Grandin wrote: > I would prefer to avoid redesigning the factories and interfaces in the > process. I believe that should be a separate step, if only so that change can > occur in reasonably sized steps. Yep. > i.e. I am politely informing people that if this turns into a "redesign > the whole thing" exercise, it will be beyond my skill level, and someone > else will have to perform this janitorial work :-) Fair enough; in which case - I think Stephan's suggestion C) to enable that makes sense :-) ATB, Michael. -- [hidden email] <><, Pseudo Engineer, itinerant idiot _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
In reply to this post by Michael Meeks-2
On 06/14/2012 11:22 AM, Michael Meeks wrote:
> On Wed, 2012-06-13 at 15:22 +0200, Stephan Bergmann wrote: >> I wouldn't introduce the extra noise of an additional Desktop2 service. >> While technically it would be an incompatibility to change the >> existing, old-style Desktop service (implementing multiple interfaces) >> into a new-style one implementing a single new XDesktop2, practically it >> should have little consequences. (As old-style service definitions are, >> after all, little more than "glorious documentation." I hope I don't >> miss any obvious blocker here. Anyway, one would need to try this out >> to be sure.) > > I was amused to read the Desktop service and see: > > /** @deprecated This interface is a documentation error. It was never thought to be supported > by this service. Please use the service<type cope="com::sun::star::frame">GlobalEventBroadcaster</type> > instead of this interface. > */ > interface com::sun::star::document::XEventBroadcaster; Good point. So one should leave that out of XDesktop2. (When changing Desktop service from old to new style, one should probably keep information about the old structure as documentation, like "Historically, the old-style Desktop service supported the old-style Frame service and the XDesktop, XComponentLoader, and XEventBroadcaster interfaces, where support for XEventBroadcaster had been a documentation error that has been corrected now.") > What new methods did we want on XDesktop2 out of interest ? No idea if we want any new methods there. (For context, see Noel's "How about if I introduce a new interface XDesktop2 that implements the necessary interfaces [to allow Desktop to become a new-style service, which can only implement a single interface].") >> But thinking about it, that approach might just be a good one: We start >> to do changes incrementally now, based on status quo, improve them over time, >> and by the time of an all-incompatible LO 4 have something new (but >> already time-tested) and we can remove any stuff that has become >> obsolete (and potentially clean up the new stuff, like renaming >> XDesktop2 back to XDesktop or some such). > > So - to get this clear; we would have a 'Desktop' service that is > instantiated all over the show: > > m_xMSFactory->createInstance( ::rtl::OUString( "com.sun.star.frame.Desktop" ) ) > > That wraps a load of global state; but of course, we don't really have > a 'Desktop' anymore ;-) so any chance of a more friendly& helpful > variable name ? say "Application" What do you mean with "variable name"? "Service name," rather? Seeing that Desktop is implemented as a one-instance service (meaning that all calls to createInstance return the same instance; see DEFINE_XSERVICEINFO_ONEINSTANCESERVICE in framework/source/services/desktop.cxx), it should rather be replaced with a (new-style) singleton, anyway. That way, at least for this specific case of the Desktop service, we nicely avoid any published-vs.-unpublished problems, anyway: Leave the old Desktop service untouched (just mark it as deprecated in favor of the new), and create a new singleton theDesktop (or even theApplication, I have no big opinion on what is a good name there) that implements the new XDesktop2 (or whatever is deemed the best name there). >> The only problem is with publishing: Ideally, the new XDesktop2 should >> remain unpublished for now. However, the existing (published) Desktop >> service could then not be rewritten to use XDesktop2. Solutions would >> be to either: > > Would the XDesktop2 re-implement same methods as XDesktop - if so, I > guess scripting bindings would have some sort of nightmare trying to > disambiguate them. This should work fine, as scripting would see the given object implement XDesktop2 rather than XDesktop, so would call the appropriate XDesktop2-based methods. But ach, stupid me. (I *knew* I missed something when I wrote "I hope I don't miss any obvious blocker here.") The implementation of the service would need to support both the individual interface of the old-style service (XDesktop, XComponentLoader, etc.) as well as the single new XDesktop2 interface. Thinking about it now, it looks to me like that should still be possible, but I might very well still be missing the obvious blocker... (We did think about stuff like this extensively back in the day, but one keeps forgetting.) -- Anyway, for the new theDesktop-singleton-scenario, a potential way out of any problems (if they do exist) would be to base it on a new implementation (that can internally forward to the old implementation, even though forwarding can be problematic due to "source" parameters of listeners etc.). [...] > Of course any purists lurking here will immediately want to fragment > what I just wrote into a dozen separate, one method interfaces ;-) but > my thesis is that queryInterface destroys usability - particularly from > scripting languages wrt. autocompletion, and also makes documentation > rather unpleasant. queryInterface is largely un-needed with new-style UNO (and not needed from scripting languages, anyway). The fragmentation of the one fat interface effectively is the collection of the (new-style) services and singletons. So, for easier discoverability (autocompletion etc.) one would need to make accessible that set of services and singletons to the relevant tools. Short of writing, say, IDE plugins that make discoverable the dynamic set of services/singletons available in some given UNO environment, one could envision a special "fat master entity" for such (scripting) environments, that consists of accessors for all the statically known services/singletons of udkapi+offapi, say. So, I think improving practical usability of UNO is possible without introducing arbitrary fat helper objects. All it takes is to finally and consistently realize those new-style UNO concepts... Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Bjoern Michaelsen |
|
|
In reply to this post by Michael Meeks-2
On Thu, Jun 14, 2012 at 11:40:20AM +0100, Michael Meeks wrote:
> The problem is - if you use a Java or C# binding that requires types, > and can provide intelligent auto-completion in the code (at least until > we hit an 'any' or 'queryInterface') - then using this overly-generic: > > any doIt([in] any); > > style interface for everything not only robs you of documentation and > auto-completion, but also means that you have to go lookup the types > carefully to make sure you don't shove an any into a string when it is > really an int (or whatever) and thus bust your run-time :-) Right. In theory. In practice queryInterface already is blocking it for all but the most simplistic cases. So the experience in static languages is already ... less then stellar. I guess, my point is: Maybe we should focus on the dynamic typed languages? As they provide something we cant offer with the static typed core development. To let statically typed languages other than C++ (aka Java) not completely left our in the rain, it should be possible to generate static wrappers around the dymanic interface by reflection. E.g. an extension that aquires instances of all the objects/services interesting to to a extension programmer from an instance of the office the developer is coding against and uses reflection to write a static wrapper class offering _all_ the methods and properties of _all_ the interfaces of the service. As this is per-service and not per-interface it will also spare you the queryInterface madness and actually give you a usable autocompletion. This generated wrapper class might not be garantueed to be valid for eternity, but will likely be valid long enough for all practical proposes. And if it indeed becomes invalid, all that is needed is regenerating the wrapper class. This should be "good enough" for RAD -- and if your extension is getting huge, you should simply go to collaborate more directly with core development. Best, Bjoern _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
On 06/14/2012 01:14 PM, Bjoern Michaelsen wrote:
> On Thu, Jun 14, 2012 at 11:40:20AM +0100, Michael Meeks wrote: >> The problem is - if you use a Java or C# binding that requires types, >> and can provide intelligent auto-completion in the code (at least until >> we hit an 'any' or 'queryInterface') - then using this overly-generic: >> >> any doIt([in] any); >> >> style interface for everything not only robs you of documentation and >> auto-completion, but also means that you have to go lookup the types >> carefully to make sure you don't shove an any into a string when it is >> really an int (or whatever) and thus bust your run-time :-) > > Right. In theory. In practice queryInterface already is blocking it for all but > the most simplistic cases. So the experience in static languages is already ... > less then stellar. ...which we are addressing with the new-style stuff (ever since 2004...) > I guess, my point is: Maybe we should focus on the dynamic typed languages? As > they provide something we cant offer with the static typed core development. Not even over my dead body. ;) What exactly do they offer that we cannot provide? > To let statically typed languages other than C++ (aka Java) not completely left > our in the rain, it should be possible to generate static wrappers around the > dymanic interface by reflection. E.g. an extension that aquires instances of > all the objects/services interesting to to a extension programmer from an > instance of the office the developer is coding against and uses reflection to > write a static wrapper class offering _all_ the methods and properties of _all_ > the interfaces of the service. As this is per-service and not per-interface it > will also spare you the queryInterface madness and actually give you a usable > autocompletion. How do you generate a static wrapper around a dynamic entity? You can only generate it for a given snapshot of that dynamic entity's behavior. But then, when you assume the entity's behavior is (largely) static anyway, why not properly codify it in the first place? That UNO is (somewhat) statically typed does not mean that dynamic languages cannot have a binding to it that feels (largely) natural. Just like shortcomings of some common statically typed languages do not mean that "statically typed" implies "verbose" or "awkward." But turning things around, making the foundations of UNO less statically typed than rather making it more so, is a wrong approach IMO. > This generated wrapper class might not be garantueed to be valid for eternity, > but will likely be valid long enough for all practical proposes. And if it > indeed becomes invalid, all that is needed is regenerating the wrapper class. > This should be "good enough" for RAD -- and if your extension is getting huge, > you should simply go to collaborate more directly with core development. This is not about "RAD," this is about "software development." Yay, on to a flamefest! ;) Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Bjoern Michaelsen |
|
|
On Thu, Jun 14, 2012 at 01:44:58PM +0200, Stephan Bergmann wrote:
> This is not about "RAD," this is about "software development." Yay, > on to a flamefest! ;) Taking the flamebait: Was UNO ever used for something else than RAD? "Software development" inside LibreOffice core doesnt count as we could happily just use plain C++ there. Best, Bjoern _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Michael Meeks-2 |
|
|
In reply to this post by Stephan Bergmann-2
On Thu, 2012-06-14 at 12:50 +0200, Stephan Bergmann wrote: > That way, at least for this specific case of the Desktop service, we > nicely avoid any published-vs.-unpublished problems, anyway: Leave the > old Desktop service untouched (just mark it as deprecated in favor of > the new), and create a new singleton theDesktop (or even theApplication, > I have no big opinion on what is a good name there) that implements the > new XDesktop2 (or whatever is deemed the best name there). Sounds good - I'd prefer Application to the anachronistic Desktop or worse 'Desktop2' but ... as you like. > queryInterface is largely un-needed with new-style UNO (and not needed > from scripting languages, anyway). Ah - good :-) if that's so, I'm much less worried. As long as the experience is one of lots of type information that doesn't get hidden behind Any's and turns into a nice deep tree of strongly typed interfaces I'm excessively happy. > Short of writing, say, IDE plugins that make discoverable the dynamic > set of services/singletons available in some given UNO environment Which sounds like a pain. > one could envision a special "fat master entity" for such (scripting) > environments, that consists of accessors for all the statically known > services/singletons of udkapi+offapi, say. Sure sure - of course, I guess there is a load of unwanted cruft there, so we can easily get some wood-for-trees problem; IMHO a single, simple top-level Application object with some easy-to-use methods for simple use-cases is still a good idea, but - this is a lot better already. > So, I think improving practical usability of UNO is possible without > introducing arbitrary fat helper objects. All it takes is to finally > and consistently realize those new-style UNO concepts... :-) At least, now I remember again what you've been doing here it does indeed sound rather nice. ATB, Michael. -- [hidden email] <><, Pseudo Engineer, itinerant idiot _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Bjoern Michaelsen |
|
|
In reply to this post by Stephan Bergmann-2
On Thu, Jun 14, 2012 at 01:44:58PM +0200, Stephan Bergmann wrote:
> How do you generate a static wrapper around a dynamic entity? You > can only generate it for a given snapshot of that dynamic entity's > behavior. Right. Worse is Better. > But then, when you assume the entity's behavior is (largely) static anyway, > why not properly codify it in the first place? Because is lots and lots of bookkeeping and boilerplate for little gain. Best, Bjoern _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
In reply to this post by Michael Meeks-2
On 06/14/2012 01:56 PM, Michael Meeks wrote:
> IMHO a single, simple top-level Application object with some > easy-to-use methods for simple use-cases is still a good idea ...the old idea of having some sort of convenience wrapper around the basic API. Sure, can be done. However, there is that other school of thought that suggests that if your basic API is well designed, there is no room for such a convenience wrapper, as the basic API should be neither more complicated nor more simplistic than necessary. Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
In reply to this post by Bjoern Michaelsen
On 06/14/2012 01:55 PM, Bjoern Michaelsen wrote:
> On Thu, Jun 14, 2012 at 01:44:58PM +0200, Stephan Bergmann wrote: >> This is not about "RAD," this is about "software development." Yay, >> on to a flamefest! ;) > > Taking the flamebait: Was UNO ever used for something else than RAD? "Software > development" inside LibreOffice core doesnt count as we could happily just use > plain C++ there. I think clients do expect LO extensions to be mature and stable. Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
In reply to this post by Bjoern Michaelsen
On 06/14/2012 01:58 PM, Bjoern Michaelsen wrote:
> On Thu, Jun 14, 2012 at 01:44:58PM +0200, Stephan Bergmann wrote: >> But then, when you assume the entity's behavior is (largely) static anyway, >> why not properly codify it in the first place? > > Because is lots and lots of bookkeeping and boilerplate for little gain. Actually writing down the static information can have a huge benefit on maintainability. (Even in static languages with type inference like Haskell, where you would not actually need to write down type signatures, it is common practice to nevertheless do so especially for exported entities, for better documentation.) Witness gbuild: we do run into cases there where a macro is called with more arguments than it expects, and at least I often need to decipher definitions (or worse, use "monkey see, monkey do" copy/paste) to figure out what arguments, and in what order, a macro takes. I would *love* to have a more statically typed machinery there... Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
In reply to this post by Stephan Bergmann-2
On 06/14/2012 12:50 PM, Stephan Bergmann wrote:
> On 06/14/2012 11:22 AM, Michael Meeks wrote: >> On Wed, 2012-06-13 at 15:22 +0200, Stephan Bergmann wrote: >>> I wouldn't introduce the extra noise of an additional Desktop2 service. >>> While technically it would be an incompatibility to change the >>> existing, old-style Desktop service (implementing multiple interfaces) >>> into a new-style one implementing a single new XDesktop2, practically it >>> should have little consequences. (As old-style service definitions are, >>> after all, little more than "glorious documentation." I hope I don't >>> miss any obvious blocker here. Anyway, one would need to try this out >>> to be sure.) >> >> I was amused to read the Desktop service and see: >> >> /** @deprecated This interface is a documentation error. It was never >> thought to be supported >> by this service. Please use the service<type >> cope="com::sun::star::frame">GlobalEventBroadcaster</type> >> instead of this interface. >> */ >> interface com::sun::star::document::XEventBroadcaster; > > Good point. So one should leave that out of XDesktop2. (When changing > Desktop service from old to new style, one should probably keep > information about the old structure as documentation, like > "Historically, the old-style Desktop service supported the old-style > Frame service and the XDesktop, XComponentLoader, and XEventBroadcaster > interfaces, where support for XEventBroadcaster had been a documentation > error that has been corrected now.") > >>> But thinking about it, that approach might just be a good one: We start >>> to do changes incrementally now, based on status quo, improve them >>> over time, >>> and by the time of an all-incompatible LO 4 have something new (but >>> already time-tested) and we can remove any stuff that has become >>> obsolete (and potentially clean up the new stuff, like renaming >>> XDesktop2 back to XDesktop or some such). >> >> So - to get this clear; we would have a 'Desktop' service that is >> instantiated all over the show: >> >> m_xMSFactory->createInstance( ::rtl::OUString( >> "com.sun.star.frame.Desktop" ) ) >> >> That wraps a load of global state; but of course, we don't really have >> a 'Desktop' anymore ;-) so any chance of a more friendly& helpful >> variable name ? say "Application" > > What do you mean with "variable name"? "Service name," rather? > > Seeing that Desktop is implemented as a one-instance service (meaning > that all calls to createInstance return the same instance; see > DEFINE_XSERVICEINFO_ONEINSTANCESERVICE in > framework/source/services/desktop.cxx), it should rather be replaced > with a (new-style) singleton, anyway. > > That way, at least for this specific case of the Desktop service, we > nicely avoid any published-vs.-unpublished problems, anyway: Leave the > old Desktop service untouched (just mark it as deprecated in favor of > the new), and create a new singleton theDesktop (or even theApplication, > I have no big opinion on what is a good name there) that implements the > new XDesktop2 (or whatever is deemed the best name there). > >>> The only problem is with publishing: Ideally, the new XDesktop2 should >>> remain unpublished for now. However, the existing (published) Desktop >>> service could then not be rewritten to use XDesktop2. Solutions would >>> be to either: >> >> Would the XDesktop2 re-implement same methods as XDesktop - if so, I >> guess scripting bindings would have some sort of nightmare trying to >> disambiguate them. > > This should work fine, as scripting would see the given object implement > XDesktop2 rather than XDesktop, so would call the appropriate > XDesktop2-based methods. > > But ach, stupid me. (I *knew* I missed something when I wrote "I hope I > don't miss any obvious blocker here.") The implementation of the service > would need to support both the individual interface of the old-style > service (XDesktop, XComponentLoader, etc.) as well as the single new > XDesktop2 interface. Thinking about it now, it looks to me like that > should still be possible, but I might very well still be missing the > obvious blocker... (We did think about stuff like this extensively back > in the day, but one keeps forgetting.) -- Anyway, for the new > theDesktop-singleton-scenario, a potential way out of any problems (if > they do exist) would be to base it on a new implementation (that can > internally forward to the old implementation, even though forwarding can > be problematic due to "source" parameters of listeners etc.). Noel, After all the flamefests in this thread ;) ---are you still interested in exploring down the route outlined above? I would be interested in getting experimentation done in that direction, to learn how best to move towards an incompatible LO 4. Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Bjoern Michaelsen |
|
|
In reply to this post by Stephan Bergmann-2
On Tue, Jun 19, 2012 at 10:42:39AM +0200, Stephan Bergmann wrote:
> On 06/14/2012 01:58 PM, Bjoern Michaelsen wrote: > Actually writing down the static information can have a huge benefit > on maintainability. (Even in static languages with type inference > like Haskell, where you would not actually need to write down type > signatures, it is common practice to nevertheless do so especially > for exported entities, for better documentation.) Witness gbuild: > we do run into cases there where a macro is called with more > arguments than it expects, and at least I often need to decipher > definitions (or worse, use "monkey see, monkey do" copy/paste) to > figure out what arguments, and in what order, a macro takes. I > would *love* to have a more statically typed machinery there... The problem with gbuild is not that it is dynamic typed, but that it is weakly typed (everything is a string). Weak typing is a whole different issue and not what I am suggesting. Testing an Any to be of a type able to provide what it should at runtime is still a sane thing to do, and is done anyway most of the time. Best, Bjoern _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Michael Stahl-2 |
|
|
In reply to this post by Michael Meeks-2
On 14/06/12 12:40, Michael Meeks wrote:
> Hi Bjoern, > > On Thu, 2012-06-14 at 12:02 +0200, Bjoern Michaelsen wrote: >>> [property] com::sun::star::lang::XComponent activeDocument; >> >> An even more radical approach would be assuming properties to just be a dynamic >> string->any map. Python allows mapping those to native attributes with: > > The problem is - if you use a Java or C# binding that requires types, > and can provide intelligent auto-completion in the code (at least until > we hit an 'any' or 'queryInterface') - then using this overly-generic: > > any doIt([in] any); > > style interface for everything not only robs you of documentation and > auto-completion, but also means that you have to go lookup the types > carefully to make sure you don't shove an any into a string when it is > really an int (or whatever) and thus bust your run-time :-) there are reasons why some methods look like this, it's because you can't have all 3 of: 1. statically typed interface 2. binary backward compatibility of interface 3. ability to extend existing interface with new optional parameters the 2 solutions (you may call them workarounds) to this conflict are: a) the ever popular XFooN interface, for N \elem {2, 3, ...} b) something like "doIt(sequence<any> parameters)", more likely with PropertyValue instead of any (which is in any case essentially dynamic typing in a statically typed language) depending on how often new optional parameters need to be added, either of these is better; a) in the case when it is rare to add new parameters, and b) in the case when it is anticipated that new parameters are likely to be added often. an example for b) is the use of the MediaDescriptor "service", which is really just implemented as a sequence<PropertyValue> that is passed to various loadFromMedium etc. methods; the thing has about 20 or so optional properties, and i cannot imagine an interface with 20 explicit parameters, most of which are not mandatory, and many of which are of type string anyway, to be better (or easier to use) than the current XComponentLoader.loadComponentFromURL. of course it may be the case that there are some interfaces that never actually needed to be extended in this way, and perhaps these could be better off without sequence<any> parameters, but that should be checked on a case by case basis. >> letting the language bindings provide the syntactic sugar around >> that with reflection and stuff like python metaclasses(*). That >> would also mean: > > So - syntactic sugar sounds good to me ;-) I'd particularly like a > built-in UNO, efficient signal/slot mechanism and native language > bindings for each language [ but particularly C++ ]. can you point me to something existing that is like this "signal/slot" thing you want? _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Stephan Bergmann-2 |
|
|
In reply to this post by Bjoern Michaelsen
On 06/19/2012 11:27 AM, Bjoern Michaelsen wrote:
> On Tue, Jun 19, 2012 at 10:42:39AM +0200, Stephan Bergmann wrote: >> On 06/14/2012 01:58 PM, Bjoern Michaelsen wrote: >> Actually writing down the static information can have a huge benefit >> on maintainability. (Even in static languages with type inference >> like Haskell, where you would not actually need to write down type >> signatures, it is common practice to nevertheless do so especially >> for exported entities, for better documentation.) Witness gbuild: >> we do run into cases there where a macro is called with more >> arguments than it expects, and at least I often need to decipher >> definitions (or worse, use "monkey see, monkey do" copy/paste) to >> figure out what arguments, and in what order, a macro takes. I >> would *love* to have a more statically typed machinery there... > > The problem with gbuild is not that it is dynamic typed, but that it is weakly > typed (everything is a string). While gbuild indeed only has a single basic data type (string), it does have the notion of functions (aka macros) that take arguments, so it does have more elaborate types, namely "string* -> string" (i.e., a macro takes an arbitrary number of string arguments and produces a single result string). What I was complaining about is that it does not have more specific types like "(string, string, string) -> string" (i.e., a macro that takes exactly three string arguments). Literature often calls gbuild's "everything is a string" design "type-unsafe" rather than "weakly typed" (then again, nomenclature is certainly inconsistent in this field). > Testing an Any to be of a type able to provide what it > should at runtime is still a sane thing to do, and is done anyway most of the > time. It is the minimum of what one needs to be done, I'd say. ;) (Or I maybe don't get what you want to say here exactly.) What I'm arguing is that having to resort to runtime checking is needed rarely, so I wouldn't make dynamic typing the default. Stephan _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
|
Michael Meeks-2 |
|
|
In reply to this post by Michael Stahl-2
Hi Michael,
On Fri, 2012-06-22 at 11:21 +0200, Michael Stahl wrote: > there are reasons why some methods look like this, it's because you > can't have all 3 of: > > 1. statically typed interface > 2. binary backward compatibility of interface > 3. ability to extend existing interface with new optional parameters I disagree :-) if we allow a hetrodox understanding of type information for the same interface, and we compile that in rather than having it in types.rdb (with all it's performance, size & lookup problems) -and- we forcibly bridge all in-process extensions that are not native: certainly we can have all three - it is mostly a matter of clever bridging, and choosing of good back-compat defaults (that map to zero / whatever we pad with). If we make UNO more powerful in that way, we can improve things quite a bit here. > an example for b) is the use of the MediaDescriptor "service", which is > really just implemented as a sequence<PropertyValue> that is passed to > various loadFromMedium etc. methods; the thing has about 20 or so > optional properties, and i cannot imagine an interface with 20 explicit > parameters, most of which are not mandatory, and many of which are of > type string anyway, to be better (or easier to use) than the current > XComponentLoader.loadComponentFromURL. Sure - if we could have extensible struct (also possible cf. above) - then we could avoid sequence<PropertyValue> and use structs in many of these cases which would be rather nice. > > So - syntactic sugar sounds good to me ;-) I'd particularly like a > > built-in UNO, efficient signal/slot mechanism and native language > > bindings for each language [ but particularly C++ ]. > > can you point me to something existing that is like this "signal/slot" > thing you want? Sure - tools' IMPL_LINK - would be the broken, degenerate, gross case :-) More attractive versions would be g_signal or Qt's signals& slots[1], I've used the rather sweet C# bindings of these too to good effect; boost has a nice implementation as well anyhow checkout: http://en.wikipedia.org/wiki/Signals_and_slots ATB, Michael. [1] - http://qt-project.org/doc/qt-5.0/signalsandslots.html -- [hidden email] <><, Pseudo Engineer, itinerant idiot _______________________________________________ LibreOffice mailing list [hidden email] http://lists.freedesktop.org/mailman/listinfo/libreoffice |
| Powered by Nabble | Edit this page |