I would suggest forking as a last resort. Don't take it easily, however if it can not be resolved in any other way, I am not against it.
As of name, I suggest Linnaeus. First off it does not contain the string GNU so no risk of trademark. Then the name Linnaeus, as in Carl, is a counterpart to Darwin, as in Charles. -----Original Message----- From: Discuss-gnustep <[email protected]> On Behalf Of Pirmin Braun Sent: Tuesday, November 26, 2019 6:10 PM To: Gregory Casamento <[email protected]> Cc: Discuss-gnustep Discuss <[email protected]> Subject: Re: Which ObjC2.0 features are missing in the latest GCC? I'd suggest a fork, i.e. "Gnustep2" with LLVM, Clang, libobjc2 On Tue, 26 Nov 2019 04:55:43 -0500 Gregory Casamento <[email protected]> wrote: > I'd really like some resolution on this topic. There seem to be a lot of > reasons for and against. > > GC > > On Mon, Nov 25, 2019 at 1:04 PM David Chisnall > <[email protected]> > wrote: > > > On 25 Nov 2019, at 14:07, H. Nikolaus Schaller <[email protected]> wrote: > > > I am not sure that this is the only way to implement it. > > > > > > First of all the callMethodOn returns some block which is a data > > structure knowing that it should take the parameter x and do some function. > > > Let's call it NSBlock. NSBlock can be an ordinary object like any > > > other > > so that it can follow the same memory management rules as used otherwise. > > > > That’s shifting the goalposts somewhat. It is not news that objects > > and closures are equivalent. Smalltalk implemented blocks as > > BlockClosure objects, Ian Piumarta’s Composite Object-Lambda > > Architecture, and C++ lambdas (which are just shorthand for C++ > > objects that implement `operator()`). You can always express > > anything that uses blocks with objects. > > > > There are two issues: > > > > 1. If you want to be compatible with existing APIs that use blocks, > > you need to be ABI compatible with blocks. > > 2. The reason that most languages that have objects also have blocks > > is that the shorthand syntax is very convenient. > > > > The following are roughly equivalent: > > > > ``` > > @interface Delegate : NSObject > > - (void)invoke; > > - (instancetype)initWithCapture: (id)someObject; @end > > > > @implementation Delegate > > { > > @private > > id obj; > > } > > - (instancetype)initWithCapture: (id)someObject { > > if ((self = [super init]) == nil) return nil; > > obj = [someObject retain]; > > return self; > > } > > - (void)invoke > > { > > [obj doSomething]; > > } > > - (void)dealloc > > { > > [obj release]; > > [super dealloc]; > > } > > @end > > > > // At construction site: > > > > [[Delegate alloc] initWithCapture: x]; > > > > // At use site: > > > > [delegate invoke]; > > ``` > > > > And this, with blocks: > > > > ``` > > // At construction site: > > > > ^() { [x doSomething]; }; > > > > // At use site: > > > > delegate(); > > ``` > > > > At use, these are similar complexity for the programmer. At the > > point of construction, one is one line of code (two or three if you > > put lambda bodies on their own lines), the other is 26. As a > > programmer, I don’t want to write 26 lines of code for a one-line callback. > > > > In C++98 you could probably template that and provide a generic > > class that took a struct containing the captures and a C function, > > so you’d get a lot less boilerplate. Assuming you had fudged ARC > > like this (as above, this code is typed into a mail client and probably > > doesn’t compile): > > > > ``` > > template<typename T> > > struct ObjCObjectWrapper > > { > > ObjCObjectWrapper(T x) : obj(objc_retain(x)) {} > > ObjCObjectWrapper(const ObjCObjectWrapper &other) : > > obj(objc_retain(other.obj) {} > > ObjCObjectWrapper(ObjCObjectWrapper &&other) : obj(other.obj) > > { > > other.obj = nil; > > } > > ObjCObjectWrapper() > > { > > objc_release(obj); > > } > > operator=(T x) > > { > > objc_storeStrong(&obj, x); > > } > > T operator() > > { > > return obj; > > } > > private: > > T obj; > > > > }; > > ``` > > > > You could then define a generic capture structure and invoke method > > like > > this: > > > > ``` > > template<typename Capture, typename Ret, typename... Args> struct > > BlockImpl { > > using invoke_t = Ret(*)(Capture &, Args...); > > void operator()(Args... args) > > { > > inv(capture, std::forward<Args>(args)…); > > } > > Block(Capture &&c, invoke_t fn) : capture(c), inv(fn) {} > > private: > > Capture capture; > > invoke_t inv; > > }; > > ``` > > > > This is then generic and you could use it as follows: > > > > ``` > > struct CaptureOneObject > > { > > ObjCObjectWrapper<id> o; > > }; > > void invoke(CaptureOneObject &c) > > { > > [(id)c.o doSomething]; > > } > > // At construction site: > > std::function<void(void)> block(BlockImpl<CaptureOneObject, > > void>({x}, invoke)); // At use site: > > block(); > > ``` > > > > I *think* you could get the same ABI as blocks if you worked on the > > generic templated boilerplate a bit. > > > > Of course, if you were using C++ then you could also write it using > > lambdas as: > > > > ``` > > // At construction site > > ObjCObjectWrapper<id> capture(x); > > auto block = [=capture]() { [(id)capture.o doSomething]; }; // At > > use site: > > block(); > > ``` > > > > And with this you don’t need the invoke function or the capture class. > > Again, much less boiler plate for users, though we don’t have ABI > > compatibility with blocks. > > > > If you were using ARC and C++, then this reduces even further to: > > > > ``` > > auto block = [=]() { [x doSomething]; }; ``` > > > > And now we’re back with different syntax for the same thing, though > > with a different ABI (I think Clang has support for implicitly > > converting C++ lambdas to blocks, but it’s been a few years since I > > tried) > > > > David > > > > > > > > -- > Gregory Casamento > GNUstep Lead Developer / OLC, Principal Consultant > http://www.gnustep.org - http://heronsperch.blogspot.com > http://ind.ie/phoenix/ -- Pirmin Braun [email protected] +49 261 92199400 +49 174 9747584 Geschäftsführer der Pirmin Braun GmbH www.pirmin-braun.de Im Palmenstück 4 - 56072 Koblenz - www.facebook.com/PB.ERP.Software Registergericht: Koblenz HRB 26312 UStID: DE319238613 Steuernummer: 22/656/03918
openpgp-digital-signature.asc
Description: PGP signature
