On 29 November 2012 00:38, Ciprian Teodorov <ciprian.teodorov@gmail.com> wrote:
Hi Igor,
While I can clearly see your points, I don't quite agree with all of them, probably because I don't have as much experience as you do. See bellow some of my thoughts on the matter. At the end I like very much NativeBoost today, and I think discussing these things helps us move forward and assume the choices that are made.
On Wed, Nov 28, 2012 at 11:04 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 28 November 2012 22:24, Ciprian Teodorov <ciprian.teodorov@gmail.com> wrote:
Hi guys,
Looking at NB methods extending Object I am wandering if it won't be better to put them in a Trait to be used by any class needing them?
i don't see what you will gain from that, except that you will end up using that trait all over the places?
What do you understand about all over the places? In my opinion FFI calls should be very well isolated in specific modules that are meant for that. I think we might have different views on this issue... I see using external libraries as a limited number of classes (maybe just one in most cases) doing the native calls, and then writing a library that relies on these classes only for calling the external library. This way the external interfaces are well defined, and we don't run the risk of having the whole image full of FFI calls...
In Athens Cairo backend we're using trait TCairoLibrary, which implements single method: #nbLibraryNameOrHandle and still its implementation delegates things to concrete class: nbLibraryNameOrHandle ^ CairoLibraryLoader getLibraryHandle Now there's like 10 or more classes which using this trait. If i put all FFI calls into single class then a) i will not need trait anymore b) i will not need a NB trait as well, because i could just implement own convenience methods in that class and its over but once i will do that, i will produce a god-class which will know everything about cairo and its interfaces. more than that, a certain and convenient uses of FFI callouts will be no longer possible: AthensCairoCanvas>>setSourceR: red g: green b: blue a: alpha <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void cairo_set_source_rgba ( self , double red, double green, double blue, double alpha) ) instead you will be forced to write it like: AthensCairoCanvas>>setSourceR: red g: green b: blue a: alpha ^ CairoCentral canvas: self setSourceR: red g: green b: blue a: alpha so, instead of single method, which implements given interface (and often it is just enough), you'll have to implement it in central and then in delegate classes. Which basically means doubling number of methods per single FFI call. More code -> more time -> more effort to maintain (and a lot of other 'more's )... second , you cannot use 'self' in function signature, and instead you will be forced to use AthensCairoCanvas * canvas (or similar).. which implies type-check in generated code while for 'self' its not, because if method belongs to certain class it is guaranteed that receiver is always of same type , so you can avoid type check. There's of course many other reasons why i do not like putting everything into single basket: - classes with 100000 methods just stinking badly. Because you can no longer reason & quickly decide whether you need all 100000 or can live with 99999 of them or maybe even 99998. So, i just shown what lies on surface: sure you can isolate all FFI callouts into single module/class.. but separating concerns is much more helpful for development and maintaining code. that's why i love using smalltalk and browser to code instead of C and text editor with single file which holds multi-million lines of source code. -- Best regards, Igor Stasenko.