# Language-independent means of exporting program interfaces
A thesis topic proposal by Bulat Khabirov, BS4-SE IU student.
## Introduction
My name is Bulat Khabirov, I am a BS4-SE student at Innopolis University and
an iOS developer. Software that I make is mostly client-server or standalone
native applications. Often, these apps also have Android counterparts.
Generally, every app's architecture can be divided into presentation logic
(UI that the user interacts with) and everything else (that is, business
logic, networking, persistent storage management, etc.). Many things from the
latter part could be potentially shared across platforms, which will result
in a more consistent codebase (one would not have to re-write same things for
every platform), less errors and faster error resolve times (less code to fix
and make errors in). The question is how exactly one would to it.
One of the many ways to do it is to have a platform dependent part, that
uses native platform APIs and is not shared, and platform independent part
in a form of a shared library (or a set of libraries) that is reused across
platforms. This is a technique that many services use, for example [Telegram](https://github.com/tdlib/td).
With such an architecture a problem of programming language interoperability
arises: platform-dependent part has to use a language, which native APIs are
exposed to (Swift or Objective-C for iOS, Kotlin or Java for Android, C# for
Windows, etc.). A shared part can use any language, that can run on desired
platforms, but has to interoperate with other programming langues well, so
that it will be simple enough to import such a library and justify the usage
of such an architecture.
## The problem
From my little overview of the current state of interopertaion of programming
languages I concluded, that the most used means of exporting or importing
an interface of a library are C headers (Rust, Go, Kotlin, Swift, etc.).
And since C is a great but quite old programming language, C headers
can not express many structures that modern languages have, thus limiting
the level of possible interoperability and sometimes requiring to write a lot
of "glue code".
Some languages can use other tools: Kotlin and Swift support Objective-C
headers, JVM languages can use JNI. These tools offer a much better
level of interoperation, but are language dependent: one can not express
more than Objective-C header supports while using it as means of exporting
an interface, and same applies to JNI bindings.
## Proposed solution
The idea is to develop a more expressive alternative to C headers, which will
aim to support lexical constructs that are most common to modern languages:
types, type members, interface declarations, more sophisticated enums, etc.
At runtime, when the caller is in the host language and a callee is in the
guest language, the idea is for the host language runtime to pass the call
to guest langague runtime, just like Swift and Kotlin do it with the ObjC
runtime, where usage of ObjC's `NSString` class:
```swift
// Swift code
let string = NSString(withFormat: "abc")
let isEqual = string.isEqual(to: "def") // calling NSString's method
```
is interpreted as two [objc_msgSend](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend) calls from [libobjc](https://developer.apple.com/documentation/objectivec/objective-c_runtime?language=objc), since `NSString` is implemented in Objective-C and it is its runtime's job to message `initWithFormat` and `isEqualToString`
calls to the correct receiver `string`. This way the interface I am proposing
is kept simple and leaves the hard work to the programming languages
themselves.
### Requirements for a langauge to support the proposed interface
#### 1. Ability to import and export a library interface in a certain format
A language may choose to selectively import and export declarations from and
to the interface file. If a feature is too language specific and can't be
expressed via the interface, it can be ignored. For example, Swift only
exports types and methods marked with `@objc` annotation to Objective-C,
thus making it explicit for the programmers that the method dispatch
will be done using ObjC runtime, and not via Swift's vtables or static
dispatch:
```swift
// --- Swift code
// Structs are value types that are not supported in
// Objective-C and won't be exported to the ObjC header.
// Marking it with @objc will result in a compile time error.
struct MyValueType { ... }
// Since MyClass explicitly inherits NSObject (ObjC) it is
// implicitly @objc
class MyClass: NSObject {
func doSomething() { ... } // won't be visible in ObjC
@objc func doSomethingElse() { ... } // will be exposed to ObjC
}
```
Similarly, when importing the interface a language may choose not to import
unsupported constructs, while successfully importing supported ones, if
possible. When possible, it is preferably a compiler's job to warn that some
features declared in the interface.
#### 2. Open and standartized language runtime APIs that other runtimes could use to forward calls
As described above on the example of usage ObjC types in Swift, a host
language must be able to refer to guest language runtime. Kotlin/Native and
Swift use open ObjC runtime to interoperate with Objective-C. If such
mechanism can be made language independent and standartized, it will allow
any language to talk to any other language without knowing exactly what
language that is.
## Roadmap
1. Attempt to manually import, use and link types and their members from a library, written in language A to a program written in a language B (proof of concept)
2. Develop a very simple but extensible first version of an interface format, that will be used by languages to import and export their interfaces
3. Extend some two existing open source languages to support the developed interface
## Desired outcomes
1. Initial version of the interface format that supports **at least** simple type declarations with support for type members (simple methods and properties)
2. A fork of existing open source language compiler extended to support the aforementioned interface, that is, being able to export and import libraries with the interface exported in the developed format, and then compile into a working binary.