What are the requirements to make a Swift class and it's members be usable in Obj-C code? - objective-c

Since this is nowhere documented AFAIK and I have seen problems with Swift code that cannot be bridged to Obj-C I'd like to open a thread to collect all informations regarding compatibility, work arounds and other tips here.
Classes must be marked with the #objc() annotation to make them available.
inout as well as var parameters are not supported and will cause the bridging header generation to simply ignore that function.
Tuples are not supported, neither as parameter nor as return value.
Closures are not supported, neither as parameter nor as return value.
Structures are not supported, neither as parameter nor as return value.
Anything more?

Related

Using void structs in Raku via NativeCall

I'm trying to link libzip to Raku, and it uses a void struct or a struct with no body, like this:
struct zip;
typedef struct zip zip_t;
I declare it in my Raku program in the same way:
class zip_t is repr('CStruct'){};
This fails with:
Class zip_t has no attributes, which is illegal with the CStruct representation.
Only reference I have found to that error is in this non-addressed issue in MyHTML. That might make it a regression, but I'm really not sure. Any idea?
A google for "no attributes, which is illegal with the CStruct representation" yields three matches. The third leads to the following recent bug/change for module LibZip:
- class zip is repr('CStruct') is export { }
+ class zip is repr('CPointer') is export { }
Before I publish this I see Curt Tilmes has commented to similar effect.
I know little about C. But I enjoy researching things. This answer is a guess and some notes based on googling.
The error message you've quoted is about NativeCall, which in turn means it's about the Rakudo compiler, not the Raku language. (I presume you know this, and for many folk and situations the distinction isn't typically important, but I think it worth noting in this case.)
The top SO match for a google for "empty struct" is Empty structs in C. The question asks about the semantics of empty structs and using them with a foreign language. The question and its answers seem useful; the next few points are based on excerpts from them.
"Structures with no named members [have undefined behavior]". I'd say this explains why you're getting the NativeCall error message ("no attributes, which is illegal with the CStruct representation".). NativeCall is about having a reliable portable interface to C so it presumably must summarily reject undefined aspects. (Perhaps the error message could hint at what to do instead? Probably not. It's probably better that someone must search for matches to the message, just as you have done. And then presumably they would see this SO.)
I presume you're just trying to bind with libzip's empty struct as part of passing data back and forth without reading or writing it. I suspect that that is the crux of the problem here; how do you bind given that NativeCall (quite reasonably) refuses to do it in the usual manner?
"From the point of view of writing [a foreign language] binding to a C library ... You're never going to do anything with objects of the [empty struct] type except pass them to imported C functions." I presume this is true for your situation and that anything else would be undefined behavior per the C spec and thus at least tied to a specific C compiler for both the C library and the C compiler used to compile Rakudo and quite possibly undefined even then. I presume Curt has asked about your usage in case the binding is doing or requiring something crazy, but I very much doubt that it is.

Is it a good practice to use Nothing in generics?

Like in this example:
sealed class Option<T>
object None : Option<Nothing>() // <-- like this
class Some<T> : Option<T>()
Or, if it's not a good practice, what should I use here instead?
Are there any official response/article on that? Or is there any argumentation that this is a good practice?
I know that Nothing was designed to be used as a type for return value for functions that never returns any value, so I'm not sure if using it as a generic parameter is a valid use.
I know there is an article that says that you can do that, but I'm not sure if I can trust it.
And the author of koptional uses it too, but I don't know if I can trust that either.
Also, it looks like in Scala Option is implemented similar to that, None have type Option[Nothing] and Scala's Nothing is similar to Kotlin's Nothing.
I agree with #zsmb13's comment. Using Nothing in a generic type hierarchy is perfectly valid and even gives benefits over other options:
First, Nothing is embedded in the Kotlin type system as a subtype of any other type, so it plays well with generics variance. For example, Option<Nothing> can be passed where Option<out Foo> is expected.
Second, the compiler will perform control flow checks and detect unreachable code after a Nothing-returning member call when the type is statically known.
See also: A Whirlwind Tour of the Kotlin Type Hierarchy

Precondition functions in Kotlin - good practices

Being a newbie Kotlin coder, I wonder, if there are some good practices or even language constructs for declaring pre-conditions in functions.
In Java I have been using Guava's Preconditions checking utilities:
https://github.com/google/guava/wiki/PreconditionsExplained
After some further investigation I came across the require function:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/require.html
Is this what is generally used for checking preconditions on functions?
Of course. You can find all of the preconditions in Preconditions.kt. In addition to the require function, there are requireNotNull, check & checkNotNull functions.
Since the documentation describes it poorly in Kotlin, but you can see the Objects#requireNonNull documentation in jdk as further.
Checks that the specified object reference is not null. This method is designed primarily for doing parameter validation in methods and constructors.
I use assert() and require() from the stdlib.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/assert.html
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/require.html
Actually, 'require' appears to not be inherited - that is, if a subclass overrides a function that has a 'require' statement, the 'require' in the parent function is not enforced. A true precondition would also apply in the case of a redefinition of the inherited function, so (IMO) 'require' does not truly provide full precondition-checking functionality.
(I say "appears" because, being new to kotlin, I've learned this by a simple experiment using inheritance - and it's possible I'm wrong - e.g., there's a bug in the compiler causing incorrect behavior, or I've done something wrong in compiling/setup. I don't think this possibility is likely, though.)
Yes, it seems that toolforger is right about 'require'. I just searched for "require" as a keyword at https://kotlinlang.org and couldn't find it, nor as a documented function. It appears to be undocumented (unless the doc for require is hidden somewhere I couldn't find); and, of course, that means we cannot count on it to implement the standard DBC "require" behavior, and so the logical assumption is that it is simply the equivalent to "assert" in C.

Is overriding Objective-C framework methods ever a good idea?

ObjC has a very unique way of overriding methods. Specifically, that you can override functions in OSX's own framework. Via "categories" or "Swizzling". You can even override "buried" functions only used internally.
Can someone provide me with an example where there was a good reason to do this? Something you would use in released commercial software and not just some hacked up tool for internal use?
For example, maybe you wanted to improve on some built in method, or maybe there was a bug in a framework method you wanted to fix.
Also, can you explain why this can best be done with features in ObjC, and not in C++ / Java and the like. I mean, I've heard of the ability to load a C library, but allow certain functions to be replaced, with functions of the same name that were previously loaded. How is ObjC better at modifying library behaviour than that?
If you're extending the question from mere swizzling to actual library modification then I can think of useful examples.
As of iOS 5, NSURLConnection provides sendAsynchronousRequest:queue:completionHandler:, which is a block (/closure) driven way to perform an asynchronous load from any resource identifiable with a URL (local or remote). It's a very useful way to be able to proceed as it makes your code cleaner and smaller than the classical delegate alternative and is much more likely to keep the related parts of your code close to one another.
That method isn't supplied in iOS 4. So what I've done in my project is that, when the application is launched (via a suitable + (void)load), I check whether the method is defined. If not I patch an implementation of it onto the class. Henceforth every other part of the program can be written to the iOS 5 specification without performing any sort of version or availability check exactly as if I was targeting iOS 5 only, except that it'll also run on iOS 4.
In Java or C++ I guess the same sort of thing would be achieved by creating your own class to issue URL connections that performs a runtime check each time it is called. That's a worse solution because it's more difficult to step back from. This way around if I decide one day to support iOS 5 only I simply delete the source file that adds my implementation of sendAsynchronousRequest:.... Nothing else changes.
As for method swizzling, the only times I see it suggested are where somebody wants to change the functionality of an existing class and doesn't have access to the code in which the class is created. So you're usually talking about trying to modify logically opaque code from the outside by making assumptions about its implementation. I wouldn't really support that as an idea on any language. I guess it gets recommended more in Objective-C because Apple are more prone to making things opaque (see, e.g. every app that wanted to show a customised camera view prior to iOS 3.1, every app that wanted to perform custom processing on camera input prior to iOS 4.0, etc), rather than because it's a good idea in Objective-C. It isn't.
EDIT: so, in further exposition — I can't post full code because I wrote it as part of my job, but I have a class named NSURLConnectionAsyncForiOS4 with an implementation of sendAsynchronousRequest:queue:completionHandler:. That implementation is actually quite trivial, just dispatching an operation to the nominated queue that does a synchronous load via the old sendSynchronousRequest:... interface and then posts the results from that on to the handler.
That class has a + (void)load, which is the class method you add to a class that will be issued immediately after that class has been loaded into memory, effectively as a global constructor for the metaclass and with all the usual caveats.
In my +load I use the Objective-C runtime directly via its C interface to check whether sendAsynchronousRequest:... is defined on NSURLConnection. If it isn't then I add my implementation to NSURLConnection, so from henceforth it is defined. This explicitly isn't swizzling — I'm not adjusting the existing implementation of anything, I'm just adding a user-supplied implementation of something if Apple's isn't available. Relevant runtime calls are objc_getClass, class_getClassMethod and class_addMethod.
In the rest of the code, whenever I want to perform an asynchronous URL connection I just write e.g.
[NSURLConnection sendAsynchronousRequest:request
queue:[self anyBackgroundOperationQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *blockError)
{
if(blockError)
{
// oh dear; was it fatal?
}
if(data)
{
// hooray! You know, unless this was an HTTP request, in
// which case I should check the response code, etc.
}
/* etc */
}
So the rest of my code is just written to the iOS 5 API and neither knows nor cares that I have a shim somewhere else to provide that one microscopic part of the iOS 5 changes on iOS 4. And, as I say, when I stop supporting iOS 4 I'll just delete the shim from the project and all the rest of my code will continue not to know or to care.
I had similar code to supply an alternative partial implementation of NSJSONSerialization (which dynamically created a new class in the runtime and copied methods to it); the one adjustment you need to make is that references to NSJSONSerialization elsewhere will be resolved once at load time by the linker, which you don't really want. So I added a quick #define of NSJSONSerialization to NSClassFromString(#"NSJSONSerialization") in my precompiled header. Which is less functionally neat but a similar line of action in terms of finding a way to keep iOS 4 support for the time being while just writing the rest of the project to the iOS 5 standards.
There are both good and bad cases. Since you didn't mention anything in particular these examples will be all-over-the-place.
It's perfectly normal (good idea) to override framework methods when subclassing:
When subclassing NSView (from the AppKit.framework), it's expected that you override drawRect:(NSRect). It's the mechanism used for drawing views.
When creating a custom NSMenu, you could override insertItemWithTitle:action:keyEquivalent:atIndex: and any other methods...
The main thing when subclassing is whether or not your behaviour completes re-defines the old behaviour... or extends it (in which case your override eventually calls [super ...];)
That said, however, you should always stand clear of using (and overriding) any private API methods (those normally have an underscore prefix in their name). This is a bad idea.
You also should not override existing methods via categories. That's also bad. It has undefined behaviour.
If you're talking about categories, you don't override methods with them (because there is no way to call original method, like calling super when subclassing), but only completely replace with your own ones, which makes the whole idea mostly pointless. Categories are only useful for safely extending functionality, and that's the only use I have even seen (and which is a very good, an excellent idea), although indeed they can be used for dangerous things.
If you mean overriding by subclassing, that is not unique. But in Obj-C you can override everything, even private undocumented methods, not just what was declared 'overridable' like in other languages. Personally, I think it's nice, as I remember in Delphi and C++ I used to “hack” access to private and protected members to workaround an internal bug in framework. This is not a good idea, but at some moments it can be a life saver.
There is also method swizzling, but that's not standard language feature, that's a hack. Hacking undocumented internals is rarely a good idea.
And regarding “how can you explain why this can best be done with features in ObjC”, the answer is simple — Obj-C is dynamic, and this freedom is common to almost all dynamic languages (Javascript, Python, Ruby, Io, a lot more). Unless artificially disabled, every dynamic language has it.
Refer to the wikipedia page on dynamic languages for longer explanation and more examples. For example, an even more miraculous things possible in Obj-C and other dynamic languages is that an object can change it's type (class) in place, without recreation.

What OCaml standard library types cannot be marshalled?

I have a failure Marshaling a data structure (error abstract type (Custom)). There is one known abstract type in use, namely Big_int. However that Marshals fine. There is no custom C code in the application. Apart from Nums, Unix library is also used (however I don't believe there are any active objects of that type). We're Marshal'ing with Closures.
Two (only) third party libraries are in use: OCS Scheme (Scheme interpreter, pure Ocaml) and Dypgen (extensible GLR parser, also pure Ocaml). The problem is with a new feature of Dypgen, saving a dynamically extended parser.
The Ocaml error message is next to useless (it doesn't identify which abstract type with Custom tag is the culprit).
We suspected Lexbuf as the culprit because it contains a closure over an Ocaml channel, and can't be Marshal'ed, but it seems this isn't the problem. So my question is:
Which standard library components can't be Marshall'd?
Weak arrays cannot be marshaled. I am not familiar with OCS Scheme, but I would expect an interpreter for a garbage-collected language written in OCaml to use weak pointers (they let you piggy-back on OCaml's memory management).
In OCaml's defense, I do not think that the Custom method block contains the name of the type (retrospectively, that seems like a good thing to have).
EDIT: Yep:
$ grep Weak ~/Downloads/ocs-1.0.3/src/*.ml
/Users/pascal/Downloads/ocs-1.0.3/src/ocs_sym.ml:module SymTable = Weak.Make (HashSymbol)
EDIT2:
As pointed out by ygrek, there is room for a name in the custom method block. I should also clarify that weak arrays are not custom values, since my answer seemed to imply that. Weak arrays have the Abstract tag and are chained using the first word of data so that the garbage collector can traverse them in special weak-pointer-related phases of the collection cycle.