> What won my heart is just how simple it is to import C code into Swift to bring the type definitions from a header file, and call into the C code transparently from Swift. This really is a gift of the gods to humankind.
If you like creating wrappers around C libraries, perhaps this is the most overlooked feature in Swift, called the 'ClangImporter'. Compared with Rust's bindgen, bindgen looks like a more complicated bindings generator even at the C level with you tweaking the options and other knobs to 'get it right' for your specific wrapper project.
This is before you even start to write a higher-level and more idiomatic wrapper and ClangInporter binds the C part to generate Swift functions for you by default. Similarly, Zig also has this too which is "@cImport" with the path to the header file as the input IIRC.
It also looks like Swift is getting C++ interop for this too. [0]
Well ... He and Xamarin had to due to the iOS ecosystem and the language/library bindings they have to do there for .NET/C#/F# usage.
But aside of that, I think Migual appreciates good language design on high level languages. His original pitch for Mono for usage in GNOME was about productivity I guess not about .NET fandom. And Swift as a productivity language to replace Objective-C is surely an interest for him.
Event as a .NET fanboy (like me) you have to look what other languages are doing. So much good stuff out there.
> Yet, this prevents a bug where the base constructor can
> call a virtual method that you override, and might not
> be ready to handle. So eventually I just learned to
> embrace and love this capability.
But this merely means that sub-classes cannot call functions (virtual or not) of their base class, since the base class is not yet initialized. It's not clear it is a net benefit. I have called base-class non-virtual functions a few times in the past, so this is not purely theoretical.
The correct solution would be for a language to have two-phase initialization. In the first phase you cannot call virtual functions, it would be a compile-time error. In the second phase, you can, as everything has been initialized already.
(You can have a poor-man version of this with static create() or make() functions and private constructors in C++ and similar languages.)
// This is valid swift:
class MyClass: MyBaseClass {
let someVar: Int
init() {
// initialize member vars
self.someVar = 99
// call base constructor
super.init()
// we are now completely initialized
self.anyFunction()
}
}
Looking forward to the text-based UI framework inspired by SwiftUI alluded to at the end of the post.
Python's Urwid is fun to play with but I find it difficult to compose the interface I have in mind. Node's Blessed looks like a great improvement, and React-Blessed brings the declarative, state-driven model to the terminal. But I really prefer to not write system utilities in JavaScript.
Unfortunately Swift's cross-platform support leaves some to be desired, which probably leads me back to Urwid.
I’m curious how the ergonomics of String handling were for this task. Swift’s String does extremely well to enforce correctness, and in isolation it’s really nice to use, but I’ve found it difficult to work with APIs that couldn’t care less about grapheme clusters or encodings. Or perhaps terminals are more Unicode-aware than I thought they were?
Terminals are definitely Unicode-aware. Grapheme clusters are very important to get right because the terminal emulator must be in sync with the app running inside it about where the cursor is located. Basically, this means you have to deal with combining marks properly, including Emoji stuff.
Very few terminal emulators go as far as attempting BiDi support. Egmont Koblinger has done some amazing work speccing this out and implementing it in VTE. More here: https://terminal-wg.pages.freedesktop.org/bidi/
Some day I'd like to support this in iTerm2, but it's a breathtakingly large amount of work.
Thank God for Unicode aware terminals! And with the emoji-heavy command-line tooling of today (yarn for example) I think terminals simply have to support extended grapheme clusters or face issues all the time.
Does swift have a cycle collector? With the whole dance in the language manual of "unowned" and "weak" references, I couldn't figure out if the cycle detection (a) happens at all if all references are strong, and (b) happens deterministically if all references are unowned.
If you like creating wrappers around C libraries, perhaps this is the most overlooked feature in Swift, called the 'ClangImporter'. Compared with Rust's bindgen, bindgen looks like a more complicated bindings generator even at the C level with you tweaking the options and other knobs to 'get it right' for your specific wrapper project.
This is before you even start to write a higher-level and more idiomatic wrapper and ClangInporter binds the C part to generate Swift functions for you by default. Similarly, Zig also has this too which is "@cImport" with the path to the header file as the input IIRC.
It also looks like Swift is getting C++ interop for this too. [0]
[0] https://forums.swift.org/t/manifesto-interoperability-betwee...