discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Which ObjC2.0 features are missing in the latest GCC?


From: Pirmin Braun
Subject: Re: Which ObjC2.0 features are missing in the latest GCC?
Date: Tue, 26 Nov 2019 15:42:30 +0100

ah, what's in a name...

"Next" and "step" are from NeXTSTEP, an ancient Operating System from 1987, 
running on stylish 680030 NeXT Hardware like the NeXTStation, no one knows today

"GNU" is from GNU which is Not Unix so you get asked "what's so bad about Unix?"

what will we have?

a modern Objective-C Ecosystem, comparable to iOS and XCode from Apple, the 
well known market leader, blah blah

making it a perfect porting target for iOS applications to run on any cheap 
laptop with any Linux distribution 

or for rapid development of stunning server applications and deployment on all 
sorts of *ix operating systems and covering all hardware from the Raspberry PI 
up to the AWS or Azure server farms

now, how to put this in a word?

On Tue, 26 Nov 2019 15:15:01 +0100
Andreas Fink <afink@list.fink.org> wrote:

> 
> 
> > On 26 Nov 2019, at 15:06, H. Nikolaus Schaller <hns@goldelico.com> wrote:
> > 
> > 
> >> Am 26.11.2019 um 11:09 schrieb Pirmin Braun <pb@busw.de>:
> >> 
> >> I'd suggest a fork, i.e. "Gnustep2" with LLVM, Clang, libobjc2 
> > 
> > just came to my mind: ClangSTEP?
> 
> 
> what a tong breaker. FreeStep sounds better to me :)
> Drop the "GNU" and break free.
> 
> 
> > 
> >> 
> >> On Tue, 26 Nov 2019 04:55:43 -0500
> >> Gregory Casamento <greg.casamento@gmail.com> 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 <gnustep@theravensnest.org>
> >>> wrote:
> >>> 
> >>>> On 25 Nov 2019, at 14:07, H. Nikolaus Schaller <hns@goldelico.com> 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 pb@pirmin-braun.de +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
> > 
> > 
> 
> 


-- 
Pirmin Braun pb@pirmin-braun.de +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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]