The Decade of Swift
swiftbysundell.com
swiftbysundell.com
It was very exiting and promising at first, but it became bogged down due to its sheer run-away complexity and over-academic approach to programming....
To an outsider, or iOS new comer, Swift looks much better than Objective-c, (due to Objective-c weird syntax), but to many insiders, Swift seems like a huge missed opportunity...
The use of Swift, outside Apple's ecosystem is going to be limited.
I wouldn't go quite that far. I agree that Swift's cross-platform story is lacking, but as someone who follows the language closely, the story is improving all the time.
I see it as largely a chicken-and-egg problem: i.e. there's not enough activity outside the Apple ecosystem to improve the situation quickly, but I don't think it's impossible for it to get there.
For instance, it's already possible to use Swift in AWS Lambda, and some support for Azure's alternative offering, as well as Google's work on Swift for Tensorflow. All of these cases involve running Swift code in a very controlled environment, like a container, and this is very tenable even in Swift's current state. So even if it might be a bit of a pain to get Swift up and running on whatever exotic linux distro you run on your workstation, there are already starting to be some "easy" use-cases for Swift outside of Apple platforms. As the scope of these one-off use-cases grows, I think it's likely there will be increased demand to improve the cross-platform story in general.
Personally this is appealing to me, because while I agree that Rust is miles ahead in terms of cross-platform support, I find Swift so much more productive and pleasant to work with that I welcome more opportunities to use it.
Because I just started playing with SwiftUI/Combine without ever using ObjC/UIKit, I don't know what parts of ObjC shined.
I have a Cookbook here:
http://www.h4labs.com/dev/ios/swift_cookbook.html
I’m in the process of putting it on Github.
https://github.com/melling/SwiftCookBook
SwiftUI probably means that millions of apps will eventually move to Swift, making Swift a top 10 language.
Red Monk seems much closer to reality: https://redmonk.com/sogrady/2019/07/18/language-rankings-6-1...
I am sorry to say, you live in a bubble.
Yet I haven’t know anybody who primarily or even occasionally used C in their work for over a decade. I know they exist but the majority of C programmers moved on to C++ a long time ago.
There are areas like kernel and driver development where C is still in widespread use but these jobs represent a tiny fraction of developers.
Any language popularity metric that ranks C as the second most popular language is massively flawed.
Linux is pretty popular.
From their site (https://www.tiobe.com/tiobe-index/):
“The TIOBE Programming Community index is an indicator of the popularity of programming languages. The index is updated once a month. The ratings are based on the number of skilled engineers world-wide, courses and third party vendors. Popular search engines such as Google, Bing, Yahoo!, Wikipedia, Amazon, YouTube and Baidu are used to calculate the ratings. It is important to note that the TIOBE index is not about the best programming language or the language in which most lines of code have been written.”
My world runs on top of C++.
C is only relevant on constrained embedded hardware and FOSS UNIX clones.
What you're saying may be technically true. My issue is with the "if you need it" part. Unfortunately, I don't get to choose what I think I need. The compiler does.
For example, every beginning Swift programmer runs into "Protocol can only be used as a generic constraint because it has Self or associatedType requirements" [1]. You start by thinking, I'm going to write a simple little type!, and then 30 seconds later you're digging through the least-documented parts of the Swift manual trying to figure out if there's a simple fix for this. (There isn't.) It's not like Objective-C where you write an -isEqualTo:(id) method and call it a day.
This happens all over the place. Swift lambdas are weirder than Objective-C blocks. Swift errors are weirder than Objective-C exceptions. Swift strings are weirder than Objective-C strings. Ultimately, there is always a reason for the complexity (often: performance), but the upshot is that for any Swift feature I've wanted to use, I always had to learn a lot of extra details before I was able to use it.
I feel there are a lot of other languages which are both easier to read and write, and do a much better job at progressive disclosure.
Given that you've made the comparison to Objective-C, are you sure you're not just running up against the learning curve of a new language? There are cases where Swift is a bit stricter, and therefore it's harder to type code which will compile on the first try, but in many of those cases it's because the strictness is allowing you to avoid entire categories of runtime bugs, which would give a non-specific error in Objective-C given the dynamic nature of the language.
Swift came out at a time where UTF-8 was already the standard. They talked a lot of talk about grapheme clusters being the most accurate representation, and then failed to deliver a coherent API to back it up. Any chance that has changed?
FWIW it would probably be fairly easy to implement some String extensions which would give you the kind of API it sounds like you are looking for.
If there is some tradeoff between safety, performance, and usability, Rust has prioritized safety and performance, where swift has chosen safety and usability. And that's perfectly fine. I am glad that Rust exists for those use-cases where the performance is important, but there are also cases where it's more important to be able to write a lot of code quickly with less friction.
It doesn't devalue Rust to admit that there are places where it is not the optimal choice.
Perhaps you haven't programmed in Java. Or even C++, for that matter (modern "Core C++" programming can be quite tedious at times).
I'd say the jury is still out when it comes to Rust vs. "higher level languages", yes, even Swift. The point of my comment is that the "friction" you're pointing to need not be an inherent property of something like Rust, any more than it is in C++. It remains to be seen if the 'tradeoff' you mention is a binding one.
I never said Rust was the most tedious language, and I would hope it has learned something from those decades old languages.
I agree that Rust has some usability issues which can be improved upon without sacrificing safety and performance, but I think that trade off will always be there at some level.
For example, Swift’s copy-on-write makes it very easy to reason about value types, but comes at the cost of performance since there will be a lot of copies which aren’t strictly necessary. You can get essentially the same behavior in Rust by cloning everything, but it takes a lot more typing and adds visual noise to your code, because Rust has made the default to be more parsimonious with memory usage.
At some level trade offs have to be made. No one language can be all thing a to all people.
It all boils down to, does it deliver what the customer of an application written in Swift is asking for?
Of course, Rust won’t start taking that path, but if I were to start a new language today, that’s what it would look like.
It really makes me think there must be something like the first law of thermodynamics for logical complexity.
Kotlin?
When I tried Kotlin a couple years ago, it seemed to be marginally behind Swift in terms of the power of the type system and some of the cool things you can do in Swift, and I'm not wild about targeting JVM, but I understand that situation has been evolving so maybe I should give it a second look at some point.
Apple has the best engineering talent of all tech companies.
And a few paragraphs later:
extension Array {
func sorted<T: Comparable>(
by keyPath: KeyPath<Element, T>
) -> Self {
sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }
}
}
I can't say this is lightweight any longer.My greatest gripe with Swift comes not from Swift itself but from its standard library. When most new languages start with their own standard libraries that are usually interfaces towards C APIs or POSIX, Swift's Foundation is half of MacOS and then some.
I recently needed to read some data from a file in Swift, and it took me quite some time to realise there was no fopen equivalent. Read/write files is a function on String? And getting a file handle is an excercise in figuring out proper dir names and user enums? [1]
There are a few other weird things in the language itself like guards which IMO are an entirely unnecessary construct that can be as easily solved with regular ifs. Or Optionals that have no way of working with them except unwrapping them (either with ! or via guards).
SwiftUI, however, is a very interesting approach, and I hope there are more frameworks (especially UI frameworks) like this.
It's not that complicated once you look it up, and like most of this stuff, you can mostly write wrapper classes one time to hide the gnarly bits and call your wrapper class to do what you need to do the way you like to do it.
It's been several years since I've had it read from a file, and I actually thought I would click that twitter link and see something super complicated, but it's actually pretty straight-forward. Not a one-liner like some languages, no, but as soon as you want to open something with options (like the encoding in this one), most other languages start looking more complicated like this as well.
Like python's open looks more like this with options: "open(filename, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)". I've opened many a file in Python scripts, but I'd have to look up buffering, encoding, errors, closefd, and opener right now if I wanted to use them (I haven't really in the past)
And Python has 11 different access modes that I often have to look up to remember what all my options are again: r+,w,wb,w+,wb+,a,ab,a+, and ab+
And that's the main problem with Foundation which hurts Swift as a language: it was made for iPhone apps, and hardly anything else. I was trying to make a CLI app on the desktop. I gave up and used something else.
> It's not that complicated once you look it up, and like most of this stuff
Yeah, I tried to look it up. It's extremely complicated, and it doesn't help that the documentation tends to spread all the knowledge across dozens of pages with very terse documentation and next to zero examples.
> I've opened many a file in Python scripts, but I'd have to look up buffering, encoding, errors, closefd, and opener right now if I wanted to use them
My example doesn't have any buffering, or encoding, or anything. It's just reading a file. There's no chance in hell you can deduce those lines from the documnentation, or find out where to put the files to read from, or find out that it's not the file's job to read/write data, but String type's (wat?) etc.
It doesn't help that the only real example of reading and writing files isn't in the docs, but in a StackOverflow answer (most other examples are either outdated, or use calls to Obj-C libs etc.)
Like part of your complaint above is pathing, and even something as short and pithy as Python (at least in my opinion, that's why I keep going to it to write proof of concepts), in order to do file i/o "right", requires knowing about all sorts of other things.
One thing I forgot to mention in my previous post is paths in Python, which has this whole fun page on it in the Python documentation: https://docs.python.org/3/library/os.path.html. Part of the reason for this in the first place is because pathing is handled differently between Unix and Windows systems, so you're supposed to use this library to navigate (or something completely different, glob, which is another thing to look up and understand) instead of just using a open("c:/blah/blah.txt") so that it can be compatible for either OS.
That's not too much different than having to specify a type of directory for Swift, and has the same types of reasons for why it exists, for safety, but it just doesn't let you do something potentially dumb like open('blah.txt') for something quick and dirty, like Python does, which I admit I do abuse if I'm trying to write something quick and dirty myself.
EDIT: This link here shows how you can write a helper function to basically turn the file i/o into a 2-liner, and I'm sure there's ways to make this even simpler: https://www.hackingwithswift.com/example-code/strings/how-to...
There is pathlib nowadays that allows you to navigate in very complex situations using a quite nice OOP API.
But I assume the old ways are still valid code, so if you're working with Python code you may encounter any of now 3 different systems of just navigating paths for file i/o, what the parent claims should be dirt simple.
I know this because I started a project using only strings and `os.path`, however when testing it started to become complicate to mock the correct paths so in tests I use `pathlib` (with conversions back to string when I finish path manipulation) and the code still works.
The method in my link (which changed rather drastically between versions):
- is very much iOS and MacOS specific
- requires knowledge of quite a few iOS/MacOS-related things (FileManager.SearchPathDirectory is probably 80% Apple-specific)
- even though it's a "FileManager", it doesn't even let you access/open a file. You have to perform additional operations on the resulting Directory type (.appendingPathComponent)
- even that doesn't give you a means of opening a file, because in order to read a file, you have to invoke a String constructor. In order to write to a file, you need to invoke a method on a String type. Talk about coupling entirely unrelated things
That is an example of objectively bad API design.
And it's clear from API evolution that it's not even Swift APIs. These are very thin wrappers for OS's existing Obj-C APIs. I think it's the first among languages: to provide OS APIs and call them a standard library for a language. I don't think even MS did that when they were creating .NET.
It just did not worked out that way, as WinDev tanked Longhorn efforts and now we have UWP (aka COM) instead of .NET for OS APIs.
Which are anyway easily accessible from .NET given its COM support.
let fileContents = try? String(contentsOfFile: "file.txt")
That works perfectly fine.In the context of an iOS or MacOS app, that of course won't work, because apps only have access to certain directories. That is why you typically use the FileManager object to get the path to the directory you'll need.
I would never in my life figure out that
- reading from and writing to a file is not the job of file-related modules, but of a string
- that it would just work like this wothout getting a proper handle to the file (what I assumed what the whole FileManager bruhaha was about)
Swift optimizes for lightness at the call site, but even the definition is quite short for the constraints it imposes.
> I recently needed to read some data from a file in Swift, and it took me quite some time to realise there was no fopen equivalent.
You can import Darwin or Glibc to get direct access to fopen. It’s a bit unergonomic to use, though.
> Read/write files is a function on String?
NSString, as a deprecated holdover from Foundation.
> There are a few other weird things in the language itself like guards which IMO are an entirely unnecessary construct that can be as easily solved with regular ifs.
That’s the whole point of syntactic sugar and constructs which make your intent clear.
> Or Optionals that have no way of working with them except unwrapping them (either with ! or via guards).
There’s also the nil-coalescing operator, but the whole point is that you can’t sweep an Optional under the rug.
I'd have to look up how extension method would look in this case in C#, but my hunch is that it would be more lightweight and readable, with the same contstraints.
> You can import Darwin or Glibc to get direct access to fopen. It’s a bit unergonomic to use, though.
FileManager.default, .appendingPath etc. isn't ergonomic either ;)
> NSString, as a deprecated holdover from Foundation.
1. How is it deprecated if that's clearly the way to read/write files?
2. Foundation is the standard lib for Swift, and the way it's designed hurts Swift-the-language immensely, IMO. If that's deprecated, what's not deprecated and how can anyone figure that out?
> There’s also the nil-coalescing operator, but the whole point is that you can’t sweep an Optional under the rug.
There are several languages with Optionals, and they don't let you sweep them under the rug, and they provide better facilities to handle them.
IMO optionals the way they are (and a few other decisions) come precisely from the constraints of Foundation and original goals of Swift: to be a replacement for Obj-C when creating iPhone apps. That's why the NSStrings, and the awkward APIs, and the astonishingly large number of nullable parameters in API calls and nullable results from API calls.
Compared to what? What this code does can be rather convoluted and/or unsafe in many statically typed languages.
I took a long break from working with Swift and just started diving into it again, and even though there was two major versions since I last messed with it, it was pretty easy to settle into it, and I've only had to look up how to do things on a case by case basis periodically. Maybe that's just my experience, though, and others have a harder time with it.
Where am I wrong?
Such as?
Personally I've taken to using Swift basically in every use-case where I can, largely because it's so nice to work with. It strikes a very nice balance between productivity (lack of tedium) and strong compile-time guarantees of correctness.
From my perspective, there are a few obstacles preventing Swift from achieving wide adoption:
1. Tooling and support outside Apple platforms has a long way to go. The story is better than it was even a year or two ago, but when compared to Rust, for example, Swift is massively lacking in this area.
2. Swift is still viewed as an iOS-only language. Even though there are now mature libraries for things like writing a webserver, and it's quite possible to write software for Linux using Swift, the developer perception is not there, and thus adoption is slow. This contributes to the lack of tooling and support.
3. Performance needs some improvement. ARC and copy-on-write are great for writing correct code easily, but they lead to some serious and sometimes unpredictable performance cliffs with Swift. There is a lot of low-hanging fruit here, but this needs to be addressed before Swift could ever find a place as a systems programming language for example.
So I would not quite say I'm bullish with respect to Swift's chances of breaking out as a general purpose programming language, but objectively speaking I would say that all the problems preventing Swift reaching that state are solvable problems, and Objective-C compatibility has little to do with it.
curl -s <https://packagecloud.io/install/repositories/swift-arm/relea... | sudo bash
sudo apt-get install swift5=5.0.2-v0.4
Since we're talking about the future of programming, can someone sell me on Swift instead of ocaml, SML, or F#?
I don't see a good reason to pick it outside of targeting Apple devices.
I don't think the industry is likely to adopt functional languages. What people in the industry seem to want are safer programs with better null handling (e.g. optionals), friendly handling of async programming (e.g. futures/promises/async await), map/filter/reduce, immutable data types, and similar features that make programs safer and easier to write. Yet, the industry does not want to give up the object-oriented paradigm or the ability to do non-functional-programming stuff.
I think the future of programming languages is going to be hybrid languages rather than functional languages, simply because they are easier to adopt. In some cases, existing languages are absorbing those new features, so many companies are benefitting from them without switching languages.
Of the alternatives you mentioned, F# is the closest to being a hybrid language because of its integration with the .NET platform. Similar languages include Scala, JavaScript, Java since Java 8, Swift, Kotlin, etc. Python now has some of this stuff too.
On the other hand, Go is notable for rejecting functional features and it is also growing in popularity.
Outside of Apple platforms it is pretty much WIP.
+ scala, go, rust, elixir/erlang
Yeah its so much time to learn all this stuff. Its a good reason they probably will all fade, better stick to js/python/java/C#/C++ like everyone else and wait.
I would change Java to Kotlin here, since Kotlin has a 1:1 interop with Java while having goodies like null safety, type inference and functional programming without the academicism of Scala (and its slow compilation time).
If you also account for the smooth learning, Kotlin is probably the safest bet from these 9 mentioned.
A lot of businesses with Java codebases are already messing with it (and not only for Android).
As much as I like OCaml, for example, I don't see it being mass-adopted in the near future, nor its tooling reaching the state of more established languages. All those languages you mentioned are most likely to continue being just niche ones.
The only mostly-functional language I can see being mass-adopted right now is Elixir, and it still has a long way to go.
Although admittedly there's still some bizarre behavior. Like this morning while iterating over a simple for loop, XCode decided it was just going to stay on the final item in the collection and keep looping until my memory ran out, over and over again, and I couldn't find anyone talking about this online, but eventually decided to do a "Clean Build Folder" and then Build, and that fixed it (but why did it happen in the first place? So odd!).
And it still doesn't always think a class I wrote or renamed is valid when referencing it in another class, but a rebuild or quitting and restarting tends to fix that.
Still, I'm liking it a lot, and having a lot of fun with Swift now. SpriteKit is great for making games, except for the lack of cross-platform capability, but if the game somehow manages to take off, I can write some wrapper classes to have the same behavior as most of the SpriteKit classes I use and port it easily enough.
To be more specific about Swift, though, there used to be a ton of things you had to bridge to Objective-C in order to do back then, and now it seems like there's almost nothing you have to bridge to Objective-C to do unless you want to work with your legacy code (all of their libraries now have Swift support, at least those that I use), and there's now a cool new SwiftUI framework that is very easy to use and very powerful.
get/set/didSet introduces ridiculous complications just so we can pretend that a large number of function invocations look like assignment statements. This was a cool idea in C++, briefly, and then we discovered that having arbitrary code hide behind what looks like an ordinary assignment statement was a bad idea.
Extensions also remind me of C++ excesses. It is difficult to look at a piece of code involving a variable some type and be sure that I understand how that type works. The problem is that the code implementing the type is not in one place. There is the type definition, but then there are extensions. Possibly many of them. Defined all over the place.
I really dislike the irregularity surrounding let. In one context in unwraps an Optional. In another context it does not. Why?
I got off the Swift train at the release in which associated types were introduced. I'm sure it solves some actual problem, but it sure wasn't clear at the time. (The project ended -- it's not that I decided to go back to Objective C.)
Reference counting is far too intrusive, and it is easy to get it wrong in subtle ways. I find Java's (!) memory model relatively simple, and that's saying something. I understand why reference counting was chosen over GC. I don't have a good answer, but reference counting is just ugly. I actually think I prefer the C/C++ model of explicitly freeing memory.
I don't understand your comment about reference counting being intrusive. Apple's implementation, ARC, used in Swift and modern ObjC, is essentially invisible to you if you're using native objects.
It's intrusive because you can never really stop thinking about it if you want to write correct code. Here's an example from a very interesting article by Mark Sands [1]:
How quickly can you tell whether or not this piece of code has a reference cycle?
class ServiceLayer {
// ...
private var task: URLSessionDataTask?
func foo(url: URL) {
task = URLSession.shared.dataTask(with: url) { data, response, error in
let result = // process data
DispatchQueue.main.async { [weak self] in
self?.handleResult(result)
}
}
task?.resume()
}
deinit {
task?.cancel()
}
}
In my view, reference counting does not combine very well with heavy use of closures.[1] This is an interesting read: http://marksands.github.io/2018/05/15/an-exhaustive-look-at-...
I'm curious. Does it? I would have guessed the "weak self" would have prevented it.
> In my view, reference counting does not combine very well with heavy use of closures.
It's one of the area where one has to be careful for sure! C++ with smart pointers and callbacks exhibits the same problem. And GC based languages make the pattern easier for sure. However I think this is not even the most critical error source in callback based designs. I think threading issues due to callbacks being executed on different threads cause the most trouble.
Therefore I think languages like Javascript and Dart - which only offer a single thread AND GC - are the the easiest to use for callback based designs.
I agree that threading is another big gotcha, arguably a bigger one. Rust has some mitigations against that sort of thing.
As for reference counting: I'm referring to capture lists, and the "unowned self" hack needed with closures. E.g. https://www.raywenderlich.com/966538-arc-and-memory-manageme.... And it gets more complicated with @escaping. I sure don't view all these subtle interactions of closures and ARC to be invisible. This stuff is subtle. Get it wrong and you have leaks.
http://marksands.github.io/2018/05/15/an-exhaustive-look-at-...
I have pasted the most egregious example here: https://news.ycombinator.com/item?id=21919728
However Objective-C ARC is basically the compiler taking care of Cocoa retain/release patterns.
Swift needed to provide a seemless path forward to integrate with Objective-C libraries so reference counting was the easist way forward.
Microsoft has chosen another way to interoperate with COM from .NET, which requires an additional layer.
https://docs.microsoft.com/en-us/dotnet/standard/native-inte...
https://docs.microsoft.com/en-us/dotnet/standard/native-inte...
Although is is quite alright to use, it adds an additional complexity that most likely Apple wasn't willing to make use of.
If you want to hide circular references from developers, then a cycle collector is required on the runtime.
For example this was the approach taken by Mesa/Cedar, or for a more modern reference CPython.
If you look into C++/CX or C++/WinRT, this issue is also surfaced to the programmer.
Rust makes it even more explicit with its reference counting library types.
At the end of the day, it depends on what Swift designers were optimising for.
Which to me looks like the easiest and less performance impact to integrate with the Objective-C runtime and respective libraries.
Swift's approach is still easier than doing the same from Objective-C, its target audience.
The named parameter handling is one of my favorite features of Swift. It makes Swift code self-documenting in a way most languages aren't.
It's the $n syntax that I think is overkill. Do we really need three different ways to name parameters?
let incremented = myArray.map { $0 + 1 }
the $n syntax just lets you save a little bit of typing. In my opinion it often makes the intent clearer when reading a line of code, since having to explicitly name the variable here adds noise which isn't really meaningful, especially in the case where you have a chain of map/reduce/filter operations.I would put it in the same category as Rust's `?` operator, which saves you from typing a bunch of unwraps or match statements everywhere.
https://trends.google.com/trends/explore?date=all&q=%2Fm%2F0...
Imho There’s definitely an issue in the strategy for this language ( or for ios native development since the two are tied).
My guess is cross platform development is eating mobile, and swift has nothing in that area.
They would need it to interoperate with their existing stack. They chose Kotlin where they reasonably could have chosen Swift and then worked to extend it to work with their existing stack.
Judging by what I would argue has been a lukewarm reception to Swift for Tensorflow, I think it would a very hard sell to convince people within Google to support Swift as a first-class language in the rest of their ecosystem.
They could for example start by adopting Swift for server-side programming for Google cloud and they seem to be putting no effort into that, at least public-facing effort.
May 2017 - https://www.theverge.com/2017/5/17/15654988/google-jet-brain...
You could use Kotlin for years before Google officially endorsed it...given that Android Studio is made by JetBrains and they made it trivial to use. JetBrains did 100% of the heavy lifting, and Google just conceded eventually.
Swift for Tensorflow hasn't gotten much traction because the overlap between programmers who know swift and machine learning engineers is super tiny. Making the core language differentiable sounds very promising though .
There was probably several months or more of debate and work within Google by the time of the announcement, but it seems reasonable that during those 18 months they would have also considered and rejected Swift.
In any case, open source Swift was not ready for prime time at time of release.
I think it's going to be hard to get data-scientists using anything other than Python any time soon, but I'm hopeful it will take off at some point, since it's really painful to work with scripting languages once you get used to a decent type system.
It's also a super interesting project to follow. The stuff they are doing with automatic differentiation, and the stuff they are talking about with metaprogramming is truly fascinating stuff, with all kinds of applications outside of machine learning. I really hope they manage to get it off the ground.
Still given the growth of that industry, it's hard to imagine that Python can bear the burden of the increasingly complex work there forever.
Once you get to the modelling step all of the data is in typed arrays.
Static types start to shine once the project grows and the new type annotation syntax works great for that.
I've tried doing machine learning in C++, Java, Scala and JavaScript and all of them are a pain compared to python.
Python would be perfect if I could annotate parts of my code and compile them. (Pretty much what's commonly done with cython or numba jit.
In my experience, doing this kind of task in an weak-typed or duck-typed language is already tedious. Function signatures don't tell me enough detail to know exactly what I'm working with, so I end up spending a lot of time digging through documentation or print debugging. Why not let the compiler, or the function signatures do this work for you?
If they want to make an Apple only version of Tensorflow, so be it, but don't expect it to take off on Linux and Windows research labs.
Edit: or on Ubuntu just download the toolchain.
But I would assume a lot of people just want a notebook to do their work in. Does it really matter if it’s running in a container or natively? Most python projects run inside a virtual environment anyway, which is comparable if not more poorly encapsulated.
Also the cloud use-case is expanding. Environment basically doesn’t matter at all in that case.
Yes it matters, because many organisations get development stations managed by IT, and there are very strict compliance regulations regarding where data processing takes place.
Kotlin was open sourced around 2012 and people were using it in Android apps before Google officially started supporting it in 2016.
Swift open source 2015/12/3: https://developer.apple.com/swift/blog/?id=34
Objective-C is simply regular C with Smalltalk objects added. If you know Smalltalk and you know C then you're golden.