Everywhere: Abandon Swift adoption
After making no progress on this for a very long time, let's acknowledge
it's not going anywhere and remove it from the codebase.
https://github.com/LadybirdBrowser/ladybird/commit/e87f889e3...And this was me trying to use Swift for a data access layer + backend web API. There's barely any guidance or existing knowledge on using Swift for backend APIs, let alone a web browser of all projects.
There's no precedent or existing implementation you can look at for reference; known best practices in Swift are geared almost entirely towards using it with Apple platform APIs, so tons of knowledge about using the language itself simply cannot be applied outside the domain of building client-running apps for Apple hardware.
To use swift outside its usual domain is to become a pioneer, and try something truly untested. It was always a longshot.
But there's a lot of hokey, amateurish stuff in there... with more added all the time. Let's start with the arbitrary "structs are passed by value, classes by reference." And along with that: "Prefer structs over classes."
But then: "Have one source of truth." Um... you can't do that when every data structure is COPIED on every function call. So now what? I spent so much time dicking around trying to conform to Swift's contradictory "best practices" that developing became a joyless trudge with glacial progress. I finally realized that a lot of the sources I was reading didn't know WTF they were talking about and shitcanned their edicts.
A lot of the crap in Swift and SwiftUI remind me of object orientation, and how experienced programmers arrived at a distilled version of it that kept the useful parts and rejected dumb or utterly impractical ideas that were preached in the early days.
You can do classic OOP, FP, Protocol-Oriented Programming, etc., or mix them all (like I do).
A lot of purists get salty that it doesn’t force implementation of their choice, but I’m actually fine with it. I tend to have a “chimeric” approach, so it suits me.
Been using it since 2014 (the day it was announced). I enjoy it.
There are plenty of valid reasons to use classes in Swift. For example if you want to have shared state you will need to use a class so that each client has the same reference instead of a copy.
This is the same way that C# works and C and C++ why is this a surprise?
Swift structs use copy on write, so they aren’t actually copied on every function call.
You can also look at the source code for the language if any it’s confusing. It’s very readable.
Computer languages are the opposite of natural languages - they are for formalising and limiting thought, the exact opposite of literature. These two things are not comparable.
If natural language was so good for programs, we’d be using it - many many people have tried from literate programming onward.
It's exactly the opposite. Writing and reading are asymmetrical, and that's why it's important to write code that is as simple as possible.
It's easy to introduce a lot of complexity and clever hacks, because as the author you understand it. But good code is readable for people, and that's why very expressive languages like perl are abhorred.
> Get into a rut early: Do the same process the same way. Accumulate idioms. Standardize. The only difference(!) between Shakespeare and you was the size of his idiom list - not the size of his vocabulary.
I wanted to try using a native language other than C++ and Swift ostensibly seemed easier to pick up. I continue to use Swift for iOS app development though where it is much easier to use; but that has its own share of compromises and trade-offs - but not centred around Swift, around SwiftUI vs UIKit.
For the record, I don't have a dog in this fight. As long as it runs on Linux, I'm willing to test drive it when it's ready.
It's a shame, I think swift is an underappreciated language, however I understand their reasoning. I think if they tried to just use swift from the beginning it would have been too ambitious, and trying to add swift to a fragile, massive project was probably too complex.
https://github.com/LadybirdBrowser/ladybird/tree/master/UI/A...
It's frustrating to discuss. It is a wonderful case study in how not to make engineering management decisions, and yet, they've occurred over enough time, and the cause is appealing enough, that it's hard to talk about out loud in toto without sounding like a dismissive jerk.
From what I can tell they're pretty laser focused on making a browser (even in this issue, they're abandoning Swift).
Swift is a poorly designed language, slow to compile, visibly not on path to be major system language, and they had no expert on the team.
I am glad they are cutting their losses.
Edit: I explained my position better below.
What are other projects trying something similar that deserve attention?
But you should perhaps give your attention to Servo. They were founded as a project to write a modern browser in Rust. So, no hand-waving there.
No hand-waving on the Ladybird team either in my opinion. They have very strong technical leadership. The idea that building a massive application designed to process untrusted user input at scale might need a better language than C++ seems like a pretty solid technical suggestion. Making incedible progress month after month using the language you started with seems pretty good too. And deciding, given the progress buidling and the lack of progress exploring the new language, that perhaps it would be best to formally abandon the idea of a language switch...well, that seems like a pretty solid decision as well.
At least, that is my view.
Oh, and I was a massive Servo fan before the Ladybird project even began. But, given how much further Ladybird has gotten than Servo has, despite being at it for less time and taking on a larger scope...well, I am giving my attention to Ladybird these days.
This comment was written in Ladybird.
Carefully making decisions and then reassessing those choices later on when they prove to be problematic is the opposite of handwavey...
Why not D?
Fascinating.
They've shown the idea it is better on C++ interop is wrong.
I don't know enough to say Rust has same OO support as Swift, but I'm pretty sure it does. (my guess as a former Swift dev: "protocol oriented programming" was a buzzy thing that would have sounded novel, but amounted to "use traits" in rust parlance)
EDIT: Happy to hear a reply re: why downvotes, -3 is a little wild, given current replies don't raise any issues.
Probably the same reason why Rust is problematic in game development. The borrow checker and idiomatic Rust do not go well together with things that demand cyclic dependencies/references. Obviously there are ways around it but they're not very ergonomic/productive.
Said differently: the C++ interop did not support calling the C++ library I wanted to use, so I wrote a C wrapper.
He even made an attempt at creating his own language, Jakt, under SerenityOS, but perhaps felt that C++ (earlier with, now without Swift) were the pragmatic choice for Ladybird.
20240810 https://news.ycombinator.com/item?id=41208836 Ladybird browser to start using Swift language this fall
- Excellent for short-lived programs that transform input A to output B
- Clunky for long-lived programs that maintain large complex object graphs
- Really impressive ecosystem
- Toxic community
It isn't a _tracing_ GC
Every browser in use is stuck with C++ because they're in way too deep at this point, but Chromium and Firefox are both chipping away at it bit by bit and replacing it with safer alternatives where they feasibly can. Chromium even blocked JPEG-XL adoption until there was a safe implementation because they saw the reference C++ decoder as such a colossal liability.
IMO the takeaway is that although those browsers do use a ton of C++ and probably always will, their hard-won lessons have led them to wish they didn't have to, and to write a brand new browser in C++ is just asking to needlessly repeat all of the same mistakes. Chromium uses C++ because Webkit used C++ because KHTML used C++ in 1998. Today we have the benefit of hindsight.
Quickly followed by several vulnerabilities in that reference library as well; good move
And Andreas Kling already proved the naysayers wrong when he showd that a new operating system and Web browser can be written entirely from scratch, the former not even using any standard libraries; so beware when you are inclined to say 'not feasible'.
What is this mythical subset of C++? Does it include use of contemporary STL features like string_view? (Don’t get me wrong — modern STL is considerably improved, but it’s not even close to being memory-safe.)
Ladybird inherits its C++ from SerenityOS. Ladybird has an almost completely homegrown standard library including their own pointer classes and a couple of different string classes that do some interesting things with memory. But perhaps the most novel stuff are things like TRY and MUST: https://github.com/SerenityOS/serenity/blob/master/Documenta...
You see this reflected all the way back to the main function. Here is the main entry function for the entire browser:
ErrorOr<int> ladybird_main(Main::Arguments arguments).
https://github.com/LadybirdBrowser/ladybird/blob/master/UI/Q...
If Ladybird is successful, I would not be surprised to see its standard library take off with other projects. Again, it is really the SerenityOS standard library but the SerenityOS founder left the project to focus on Ladybird. So, that is where this stuff evolves now.
class FontFeatureValuesMapIterationSource final
: public PairSyncIterable<CSSFontFeatureValuesMap>::IterationSource {
public:
FontFeatureValuesMapIterationSource(const CSSFontFeatureValuesMap& map,
const FontFeatureAliases* aliases)
: map_(map), aliases_(aliases), iterator_(aliases->begin()) {}Also funny enough, all cross platform work is with small work groups, some even looking for funding … anyway.
Apple has been always 'transactional' when it comes to OSS - they open source things only when it serves a strategic purpose. They open-sourced Swift only because they needed the community to build an ecosystem around their platform.
Yeah, well, sure they've done some work around LLVM/Clang, WebKit, CUPS, but it's really not proportional to the size and the influence they still have.
Compare them to Google, with - TensorFlow, k8s, Android (nominally), Golang, Chrome, and a long tail of other shit. Or Meta - PyTorch and the Llama model series. Or even Microsoft, which has dramatically reversed course from its "open source is a cancer" era (yeah, they were openly saying that, can you believe it?) to becoming one of the largest contributors on GitHub.
Apple I've heard even have harshest restrictions about it - some teams are just not permitted to contribute to OSS in any way. Obsessively secretive and for what price? No wonder that Apple's software products are just horrendously bad, if not all the time - well, too often. And on their own hardware too.
I wouldn't mind if Swift dies, I'm glad Objective-C is no longer relevant. In fact, I can't wait for Swift to die sooner.
Apple is (was?) good at hardware design and UX, but they pretty bad at producing software.
LLVM: Pretty much everyone who has created a programming language with it has complained about its design. gingerbill, Jon Blow, and Andrew Kelley have all complained about it. LLVM is a good idea, but it that idea was executed better by Ken Thompson with his C compiler for Plan 9, and then again with his Go compiler design. Ken decided to create his own "architecture agnostic" assembly, which is very similar to the IR idea with LLVM.
Swift: I was very excited with the first release of Swift. But it ultimately did not have a very focused vision outlined for it. Because of this, it has morphed into a mess. It tries to be everything for everyone, like C++, and winds up being mediocre, and slow to compile to top it off.
Mojo isn't doesn't exist for the public yet. I hope it turns out to be awesome, but I'm just not going to get my hopes up this time.
LLVM is
- Slow to compile
- Breaks compilers/doesn't have a stable ABI
- Optimizes poorly (at least, worse than GCC)
Swift I never used but I tried compiling it once and it was the bottom 2 slowest compiler I ever tested. The only thing nearly as bad was kotlin but 1) I don't actually remember which of these are worse 2) Kotlin wasn't meant to be a CLI compiler, it was meant to compile in the background as a language server so it was designed around thatMojo... I have things I could say... But I'll stick to this. I talked to engineers there and I asked one how they expected any python developers to use the planned borrow checker. The engineer said "Don't worry about it" ie they didn't have a plan. The nicest thing I can say is they didn't bullshit me 100% of the time when I directly asked a question privately. That's the only nice or neutral thing I could say
I suggest you ask around to see what the consensus is for which compiler is actually mature. Hint: for all its warts, nobody is writing a seriously optimized language in any of the options you listed besides LLVM.
The latter is definitely a defining capability of Anders Hejlsberg. (C#/Typescript designer)
I don't have an emotional reaction to this, i.e. I don't think you're being mean, but it is wrong and reductive, which people usually will concisely, and perhaps reductively, describe as "mean".
Why is it wrong?
LLVM is great.
Chris Lattner left Apple a *decade* ago, & thus has ~0 impact or responsibility on Swift interop with C++ today.
Swift is a fun language to write, hence, why they shoehorned it in, in the first place.
Mojo is fine, but I wouldn't really know how you or I would judge it. For me, I'm not super-opinionated on Python, and it doesn't diverge heavily from it afaik.
If he's such a horrible engineer then we should have lots of LLVM replacements, right?
They want native, partly as a “moat,” but also as a driver for hardware and services sales. They don’t want folks shrugging and saying “It doesn’t matter what you buy; they’re all the same.”
I hear exactly that, with regard to many hybrid apps.
It’s a common misconception that comes from the standard library data structures, which almost all do implement CoW
I 100% agree with your statement. My case is that a simple language does not necessarily result in simpler and more readable code. You need a language that fits the problem domain and that does not require a lot of boilerplate to handle more complex structures. If you are shoehorning a problem into an overly simplistic language, then you are fighting your tool. OO for OO. FP for FP. and so on.
I fear that the current fashion to very simple languages is a result of confusing these aspects and by way of enforcing certain corporate behaviours on coders. Perhaps that has its place eg Go in Google - but the presumption that one size fits all is quite a big limitation for many areas.
The corollary of this is that richness places an burden of responsibility on the coder not to write code golf. By tbh you can write bad code in any language if you put your mind to it.
Perhaps many find richness and expressivity abhorrent - but to those of us who like Larry's thinking it is a really nice, addictive feeling when the compiler gets out of the way. Don't knock it until you give it a fair try!
Problem is, that makes every small part of the program simple, but it increases the number of parts (and/or their interaction). And ultimately, if you need to understand the whole thing it's suddenly much harder.
Surely you can write the same behaviour in "clever" (when did that become a negative attribute?) or "good" way in assembly. You are correct. But that's a different matter.
I agree with you. I also agree that this decision is an example of that.
SerenityOS had an "everything from scratch in one giant mono-repo" rule. It was, explicitly a hobby project and one rooted in enjoyment and 'idealism from the get go. It was founded by a man looking for something productive to focus on instead of drugs. It was therapy. Hence the name.
Ladybird, as an independent project, was founded with the goal of being the only truly independent web browser (independent from corporate control generally and Google specifically).
They have been very focussed on that, have not had any sacred cows, and have shed A LOT of the home-grown infrastructure they inherited from being part of SerenityOS. Sometimes that saddens me a little but there is no denying that it has sped them up.
Their progress has been incredible. This comment is being written in Ladybird. I have managed GitHub projects in Ladybird. I have sent Gmail messages in Ladybird. It is not "ready" but it blows my mind how close it is.
I think Ladybid will be a "usable" browser before we enter 2027. That is just plain amazing.
Ranges are not memory safe. Sorry.
Having a checklist of "things not to do" is historically a pretty in effectiveway to ensure memory safety, which is why the parent comment was asking for details. The fact that this type of thing gets dismissed as a non-issue is honestly a huge part of the problem in my opinion; it's time to move on from pretending this is a skill issue.
> Swift is strictly better in OO support and C++ interop
So I guess from their point of view that’s why not rust.
I don’t have a horse in the race.
I was genuinely interested in why they didn’t even consider D given they already ruled out rust for those particular reasons, for which it seems D would fulfill nicely.
Hoo boy, wait until you hear about the state of C++'s library "system"
I can totally imagine how a prolific and ambitious developer would create a world of their own, essentially another language with domain-specific vocabulary and primitives. People often talk about using a "subset of C++" to make it manageable for mortals, and I think the somewhat unusual consideration of Swift was related to this desire for an ergonomic language to express and solve the needs of the project.
Personally I wouldn't mind either but my point is that they probably want to cater to the average person, and not just security conscious tech savvy people, and if that's the case, then you really can't exclude FB/IG/YT and others from working properly in your browser.
Why? The average person is well served by large existing players, whereas security conscious tech people are extremely underserved and often actually willing to pay.
Once you have non-trivial network effects, you could continue to influence the ecosystem (see: MSIE, Firefox in its early days, and Google Chrome). There are probably multiple paths to this. This is one.
This kills the internet.
Here's a Python rut:
n = 20 # how many numbers to generate
a, b = 0, 1
for _ in range(n):
print(a, end=" ")
a, b = b, a + b
print()
Here's that rut in Raku: (0,1,*+*...*)[^20]
I am claiming that this is a nicer rut. seq = [0,1]
while len(seq) < 20:
seq.append(sum(seq[-2:]))
print(' '.join(str(x) for x in seq))
> I am claiming that (0,1,+...*)[^20] is a nicer rut.If it's so fantastic, then why on earth do you go out of your way to add extra lines and complexity to the Python?
Even though I barely know Raku (but I do have experience with FP), it took way less time to intuitively grasp what the Raku was doing, vs. both the Python versions. If you're only used to imperative code, then yeah, maybe the Python looks more familiar, though then... how about riding some new bicycles for the mind.
My read is that that this is the main thing that happened here.
The Ladybird team is quite pragmatic. Or, at least their founder is. I think they understood the scale of buidling a browser. They understood that it was a massive undertaking. They also understood the security challenge of building an application so big that processes untrusted input as its main job. So, they thought that perhaps they needed a better language than C++ for these reasons. They evaluated a few options and came away thinking that Swift was the best, so they announced that they expected to move towards Swift in the future.
But the other side of being pragamatic is that, as time passed, they also realized how hard it would be to chagne horses. And they are quite productivity driven. They produce a YouTube video every month detailing their progress including charts and numbers.
Making no progress on the "real" job of building a browser to make progress on the somewhat artificial job of moving to a new programming language just never made sense I guess.
And the final part of being pragmatic is that, after months of not really making any progress on the switch, the founder posted this patch essentially admitting the reality and suggesting they just formalize the lack of progress and move on.
The lack of progress on Swift that is. Their progress on making a browser has been absolutely mind-blowing. This comment is being written in Ladybird.
It's a cool project and I'd consider it for a toy language but it's far from an LLVM replacement.
I don't see a case for "complex" vs "simple" in the comparison with natural languages.
Here's a very simple, lexical declaration made more human friendly by use of the preposition `my` (or `our` if it is packaged scoped)...
my $x = 42;x := 42
Or
let x = 42
Or
x = 42
It seems like a regression from modern languages.
Example 1 and 3 are not declarations, so apples ↔ oranges
Your example is not compelling I’m afraid but you should try building a language to see. Also read literate programming if you haven’t already.
BTW, one side benefit of LP is freedom from arbitrary structure of DSLs. A standard practice in LP is to declare and define objects in the spot in which they are being used; LP tools will parse them out and distribute to the syntactically correct places.
Neither strategy has had much success IMO.
I was hired around Google around the same time, but not nearly as famous :)
AFAICouldT it was a "hire first, figure out what to do later", and it ended up being Swift for TensorFlow. That went ~nowhere, and he left within 2 years.
That's fine and doesn't reflect on him, in general, that's Google for ya. At least that era of Google.
No, he's literally explaining why the guidelines can't be used simultaneously.
It doesn't build a list, rather it dumps it as it goes.
It has an explicit print.
It uses a named constant for 20 rather than a literal.
etc, etc...
I'm struggling to think of a larger factor
Moreover, Servo aims to be embeddable (there are some working examples already), which is where other non-Chrome/ium browsers are failing (and Firefox too). Thanks to this it has much better chance at wider adoption and actually spawning multiple browsers.
Alas not nearly as modularized as it could be. I think it's mainly just Stylo and WebRender (the components that got pulled into Firefox), and html5ever (the HTML parser) that are externally consumable.
Text and layout support are two things that could easily be ecosystem modules but aren't seemingly (from my perspective) because the ambition to be modular has been lost.
And someone will be stuck not to do anything because they are unsatisfied with all languages. :-)
You could imagine creating a modified Go assembler that is more generic and not tied to Go's ABI that could accomplish the same effect as LLVM. However, it'd probably be better to create a project like that from scratch, because most of Go's optimizations happen before reaching the assembler stage.
It would probably be best to have the intermediate language that QBE has and transform that into "intermediate assembly" (IA) very similar to Go's assembly. That way the IL stage could contain nearly all the optimization passes, and the IA stage would focus on code generation that would translate to any OS/arch combo.
I don't think that's true. Zig have a cross-compiler (that also compiles C and C++) based on LLVM. I believe LLVM (unlike gcc) is inherently a cross-compiler, and it's mostly just shipping header files for every platform that `zig cc` is adding.
What I will say is that it seem popular to start with LLVM and then move away from it. Zig is doign that. Rust is heading in the direction perhaps with Cranelift. It feels that, if LLVM had completely nailed its mission, these kinds of projects would be less common.
It is also notable that the Dragonegg project to bring GCC languages to LLVM died but we have multiple projects porting Rust to GCC.
let x = 42
Well, when you add in the '$' and ';' tokens the "let" example is still shorter. Also as another person replied to you, those other two examples are declarations in other languages. So 0 for 3 there.
Lots of people seem really committed to OOP. Rust is definitely a bad fit if you can't imagine writing code without classes and objects. I don't think this makes rust is a bad language for the problem. Its just, perhaps, makes rust a bad language for some programmers.
Traits give you the ability to model typical GUI OO hierarchies, e.g.:
trait Widget {
fn layout(&mut self, constraints: Constraints);
fn paint(&self, ctx: &mut PaintCtx);
fn handle_event(&mut self, event: Event);
}
struct Button { ... }
struct Label { ... }
impl Widget for Button { ... }
impl Widget for Label { ... }
let mut widgets: Vec<Box<dyn Widget>> = Vec::new();
Implementation inheritance can be achieved with good old shared functions that take trait arguments, like this: fn paint_if_visible<W>(widget: &W, ctx: &mut PaintCtx)
where
W: HasBounds + HasVisibility,
{
if widget.is_visible() {
ctx.paint_rect(widget.bounds());
}
}
You can also define default methods at the trait level.This all ends up being much more precise, clear, and strongly typed than the typical OO inheritance model, while still following a similar overall structure.
You can see real world examples of this kind of thing in the various GUI toolkits for Rust, like Iced, gpui, egui, Dioxus, etc.
GTK, Qt, DOM, WinUI 3, Swing, Jetpack Compose, and GWT (to name a few) all provide getters and setters or public properties for GUI state, violating the encapsulation principle [1]. The TextBox/EditBox/Entry control is the perfect example.
The impedance mismatch is that a GUI control is not an object [2]. And yet, all of the object-orient GUI examples listed implement their controls as objects. The objects are not being used for the strengths of OO, it's just an implementation detail for a procedural API. The reason these GUIs don't provide an API like shown in [1] is because it's an impractical design.
"How are you supposed to design an OO TextEdit GUI control if it can't provide a getter/setter for the text that it owns?" Exactly. You're not supposed to. OOP is not the right model for GUIs.
Ironically, SwiftUI doesn't have this problem because it uses the Elm Architecture [3] like React and iced.
[1]: https://www.infoworld.com/article/2163972/building-user-inte...
[2]: From [1], "All the rules in the rule-of-thumb list above essentially say the same thing — that the inner state of an object must be hidden. In fact, the last rule in the list (“All objects must provide their own UI”) really just follows from the others. If access to the inner state of an object is impossible, then the UI, which by necessity must access the state information, must be created by the object whose state is being displayed."
And if the C compiler you use is clang then you're still literally making use of LLVM.
Sort of an exception that proves the rule. Yes, it's great and was released for free. But at least partially that's not a strategic decision from Apple but just a requirement of the LGPLv2 license[1] under which they received it (as KHTML) originally.
And even then, it was Blink and not WebKit that ended up providing better value to the community.
[1] It does bear pointing out that lots of the new work is dual-licensed as 2-clause BSD also. Though no one is really trying to test a BSD-only WebKit derivative, as the resulting "Here's why this is not a derived work of the software's obvious ancestor" argument would be awfully dicey to try to defend. The Ship of Theseus is not a recognized legal principle, and clean rooms have historically been clean for a reason.
My understanding is that by default you are not allowed to contribute to open-source even if its your own project. Exceptions are made for teams whose function is to work on those open-source project e.g. Swift/LLVM/etc...
I can recall one explaining to me in the mid 20 teens that the next iPhone would be literally impossible to jailbreak in any capacity with 100% confidence.
I could not understand how someone that capable(he was truly bright) could be that certain. That is pure 90s security arrogance. The only secure computer is one powered off in a vault, and even then I am not convinced.
Multiple exploits were eventually found anyway.
We never exchanged names. That’s the only way to interact with engineers like that and talk in real terms.
Prefer structs over classes is a universal, if weak, guideline.
It's funny how people can be all hung up on composability of things like type systems, and then completely blow off the desire for composability of guidelines.
Except the only thing that makes OOP OOP: Message passing.
Granted, Swift only just barely supports it, and only for the sake of interop with Objective-C. Still, Swift has better OO support because of it. Rust doesn't even try.
Not that OOP is much of a goal. There is likely good reason why Smalltalk, Objective-C, and Ruby are really the only OOP languages in existence (some esoteric language nobody has ever heard of notwithstanding).
So the approach of having a new language that requires a full rewrite (even with an LLM) is still a bad approach.
Fil-C likely can do the job without a massive rewrite and achieving safety for C and C++.
Job done.
EDIT: The authors of Ladybird have already dismissed using Rust, and with Servo progressing at a slow pace it clearly shows that Ladybird authors do not want something like that to happen to the project.
Igalia had five engineers working full time who turned that science project into v0.0.1 in less than two years.
So long as you don't mind a 2-4x performance & memory usage cost.
> Job done.
Seems like you forgot a few stops in your train of thought, Speed Racer.
Really? In the other Python version the author went out of his way to keep two variables, and shit out intermediate results as you went. The raku version generates a sequence that doesn't even actually get output if you're executing inside a program, but that can be used later as a sequence, if you bind it to something.
I kept my version to the same behavior as that Python version, but that's different than the raku version, and not in a good way.
You should actually ignore the print in the python, since the raku wasn't doing it anyway. So how is "create a sequence, then while it is not as long as you like, append the sum of the last two elements" a terrible mix of styles and paradigms, anyway? Where do you get off writing that?
> Lines of code don't matter anyway, cognitive load does.
I agree, and the raku line of code imposes a fairly large cognitive load.
If you prefer "for" to "while" for whatever reason, here's a similar Python to the raku.
seq = [0,1]
seq.extend(sum(seq[-2:]) for _ in range(18))
The differences are that it's a named sequence, and it doesn't go on forever and then take a slice. No asterisks that don't mean multiply, no carets that don't mean bitwise exclusive or.> If you're only used to imperative code, then yeah, maybe the Python looks more familiar, though then... how about riding some new bicycles for the mind.
It's not (in my case, anyway) actually about imperative vs functional. It's about twisty stupid special symbol meanings.
Raku is perl 6 and it shows. Some people like it and that's fine. Some people don't and that's fine, too. What's not fine is to make up bogus comparisons and bogus implications about the people who don't like it.
Here are the mixed paradigms/styles in these Python snippets:
- Statements vs. expressions
- Eager list comprehensions vs. lazy generator expressions
- Mutable vs. immutable data structures / imperative reference vs. functional semantics
(note that the Raku version only picks _one_ side of those)
> seq.extend(sum(seq[-2:]) for _ in range(18))
I mean, this is the worst Python code yet. To explain what this does to a beginner, or even intermediate programmer.... oooooh boy.
You have the hidden inner iteration loop inside the `.extend` standard library method driving the lazy generator expression with _unspecified_ one-step-at-a-time semantics, which causes `seq[-2:]` to be evaluated at exactly the right time, and then `seq` is extended even _before_ the `.extend` finishes (which is very surprising!), causing the next generator iteration to read a _partially_ updated `seq`...
This is almost all the footguns of standard imperative programming condensed into a single expression. Like ~half of the "programming"-type bugs I see in code reviews are related to tricky temporal (execution order) logic, combined with mutability, that depend on unclearly specified semantics.
> It's about twisty stupid special symbol meanings.
Some people program in APL/J/K/Q just fine, and they prefer their symbols. Calling it "stupid" is showing your prejudice. (I don't and can't write APL but still respect it)
> What's not fine is to make up bogus comparisons and bogus implications about the people who don't like it.
That's a quite irrational take. I didn't make any bogus comparisons. I justified or can justify all my points. I did not imply anything about people who don't like Raku. I don't even use Raku myself...
That's why it wasn't the first thing I wrote.
> To explain what this does to a beginner, or even intermediate programmer.... oooooh boy.
As if the raku were better in that respect, lol.
> Some people program in APL/J/K/Q just fine, and they prefer their symbols.
APL originally had a lot of its own symbols with very little reuse, and clear rules. Learning the symbols was one thing, but the usage rules were minimal and simple. I'm not a major fan of too many different symbols, but I really hate reuse in any context where how things will be parsed is unclear. In the raku example, what if the elements were to be multiplied?
> Calling it "stupid" is showing your prejudice. (I don't and can't write APL but still respect it) > Reminds me a bit of the fish anecdote told by DFW...
Yeah, for some reason, it's not OK for me to insult a language, but it's OK for you to insult a person.
But you apparently missed that the "twisty" part was about the multiple meanings. Because both those symbols are used in Python (the * in multiple contexts even) but the rules on parsing them are very simple.
perl and its successor raku are not about simple parsing. You are right to worry about the semantics of execution, but that starts with the semantics of how the language is parsed.
In any case, sure, if you want to be anal about paradigm purity, take my first example, and (1) ignore the print statement because the raku version wasn't doing that anyway, although the OP's python version was, and (2) change the accumulation.
seq = [0,1]
while len(seq) < 20:
seq = seq + [seq[-2] + seq[-1]]
But that won't get you very far in a shop that cares about pythonicity and coding standards.And...
You can claim all you want that the original was "pure" but that's literally because it did nothing. Not only did it have no side effects, but, unless it was assigned or had something else done with it, the result was null and void.
Purity only gets you so far.
Rust was born at Mozilla, sort of. It was created by a Mozilla employee. The first "real" project to put it into action was Servo of which parts were adopted into Firefox. While Rust may not have been developed "specifically" to create a browser, it is a fair comment.
That said, Ladybird was started as part of the SerenityOS project. That entire project was built using C++. If the original goal of Serenity was to build an opeerating system, C++ would have felt like a reasonable choice at the time.
By the time Ladybird was looking for "better" languages than C++, Ladybird was already a large project and was making very heavy use of traditional OOP. Rust was evaluated but rejected because it did not support OOP well. Or, at least, it did not support integration into a large, C++ based, OOP project.
Perhaps, if Ladybird had first selected a languge to write a browser from scratch, they would have gone with Rust. We will never know,
We do know that Mozilla, despite being the de facto stewards of Rust at the time, and having a prototype web browser written in Rust (Servo), decided to drop both Rust and Servo. So, perhaps using Rust for browsers is not as open and shut as you imply.
I think you are conflating the development of Servo with the design and development of Rust.
Tools to do X better are often designed by people who get paid a lot to do X and worry about losing their job if they are not good enough at X.
If he were to tell me that he didn't imagine Rust's helping with browser dev when he designed Rust, then I'd believe him, but the "circumstantial" evidence points strongly in the other direction.
Here's the nut from the relevant comment: "There's no way to say this without sounding mean: Everything Chris Lattner has done has been a "successful mess". He's obviously smart, but a horrible engineer. No one should allow him to design anything."
I can't support a take like this (the commenter's, not yours) it is not helpful or informative. That original comment was edited too, or added onto. On the face of it, the sentiment that Swift and Mojo and LLVM are these awful abominations is beyond the pale for me from an engineering standpoint. I think there are some FOSS feelings in play that stir up strongly held ideologies.
I won't say never, but it would take an exceedingly large comp plan for me to sign paperwork forbidding me from working on hobby projects. That's pretty orwellian. I'm not allowed to work on hobby projects on company time, but that seems fair, since I also can't spend work hours doing non-programming hobbies either.
I suspect it's not just Apple, I have "lost" so many good GitHub friends - incredible artisans and contributors, they've gotten well-payed jobs and then suddenly... not a single green dot on the wall since. That's sad. I hope they're getting paid more than enough.
I've been programming in Rust for 5 years and I could barely understand the code in their repo. Not because it was somehow advanced but because it didn't make any sense. It felt like that with every decision they could make, they always chose the hardest way.
On the other hand, I have never done any C++ (besides few tutorials) in my life and yet I found both Serenity/Ladybird and also WebKit to be very readable and understandable.
BTW: If anyone wants to reply that Rust is different then yes, of course it is - but that's the point, if there is a language that maps nicely to your problem domain, it's also very fast, and well-understood then why the hell you'd use a language that is well-known to NOT map to OOP?
So, yes it is still pre-historic.
> Once it gets embedding stabilized that will be the time for a full blown browser developement.
Servo development began in 2012. [0] 14 years later we get a v0.0.1.
At this point, Ladybird will likely reach 1.0 faster than Servo could, and the latter is not even remotely close to being usable even in 14 years of waiting.
When Servo is done, it's going to be a beast.
It's getting hundreds of commits per week:
And no, they're not being disingenuous.
> Especially because there's no GC.
This is the only real issue I can think of. However, for implementing something like a UI, automatic GC isn't really necessary because the lifetime of widgets etc. maps very well to the lexical/RAII model. Windows own widgets, etc. Again, see all the UI toolkits implemented in Rust.
Not so sure about not needing GC. Many times a problem seems easy without GC until you get into the weeds. Like why did ObjC feel the need to add ARC (not GC but similar goal)?
> it's OK for you to insult a person.
I made an analogy which just means that it's hard to understand what the different styles and paradigms are when those are the things you constantly use.
You're apparently taking that as an insult...
> But you apparently missed that the "twisty" part
I didn't miss anything. You just didn't explain it. "twisty" does not mean "ambiguous" or "hard to parse". Can't miss what you don't write.
$ raku -e 'say (0, 1, 2, * × * ... )[^10]' # for readability (0 1 2 2 4 8 32 256 8192 2097152)
$ raku -e 'say (0, 1, 2, * * ... *)[^10]' # for typeability (0 1 2 2 4 8 32 256 8192 2097152)
My instincts about raku were always that perl was too fiddly, so why would I want perl 6, and this isn't doing anything to dissuade me from that position.
I didn't say there was. Saying use C instead of LLVM is fine for a language designer.
But that doesn't make it a replacement for LLVM as a piece of infrastructure. C compilers still need an optimizing backend like LLVM.
The conversation is about whether or not LLVM is a shit piece of engineering, not whether you should target C or IR as a language designer. Avoiding using LLVM directly isn't a replacement lol.
You could say "GCC" is a replacement which at least isn't completely false, but GCC's backend is far more annoying to use for different languages.
(source: iOS dev from jailbreak days, so like 8 years before Swift, till 2019. He did not mean dynamic dispatch and Swift has dynamic dispatch by way of "you can annotate a Swift method with @objc and we'll emit it as an ObjC method instead of Swift", not Smalltalk-ish, like, at all. if you're the poster who originally said "because of dynamic dispatch", I understand why you're frustrated but I have 0 idea why you think dynamic dispatch in Swift would matter, much less say it makes Swift much better at OOP than Rust. It's impolite to say "utterly baffling engineering decision" in public, so there's subtext in the conversation. Namely that both claims made 0 sense if you had practical familiarity with either)
But that's the thing, there is: It supports message passing.
Like we already discussed long ago, it supports it poorly, and only for the sake of compatibility with Objective-C, but still that makes its OOP support better than Rust's. Rust has no OOP support at all. It is not an OOP language and never would want to be. OOP goes completely against its core principles (statically-typed, performance-minded).
Realistically, nobody would consider Swift an OOP language either. However, on the spectrum, it is unquestionably closer to being an OOP language. It at least gets an honourable mention in the short list of OOP languages. It is undeniable that Swift has "better" OOP support; not to be confused with good OOP support.
> He did not mean dynamic dispatch
Of course not. Dynamic dispatch is for function calling. OOP doesn't use dynamic dispatch. That's literally why we call it object-oriented rather than function-oriented (or functional, as the kids say). This is also why Objective-C, quite brilliantly, uses [foo bar] syntax (hint: it kind of looks like an ASCII-art envelope for a reason): To make it clear that conceptually you are not calling a function.
> I understand why you're frustrated
I don't. Fill us in.
I haven’t used it in a couple decades, but I do remember it fondly. I also suspect I’d hate it nowadays. Its roots are in a language that seemed revolutionary in the 80s and 90s - Smalltalk - and the melding of it with C also seemed revolutionary at the time. But the very same features that made it great then probably (just speculating - again I haven’t used it in a couple decades) aren’t so great now because a different evolutionary tree leapfrogged ahead of it. So most investment went into developing different solutions to the same problems, and ObjC, like Smalltalk, ends up being a weird anachronism that doesn’t play so nicely with modern tooling.
I think it's a great language! As long as you can tolerate dynamic dispatch, you really do get the best of C/C++ combined with its run-time manipulable object type system. I have no reason to use it for more code than I have to, but I never grimace if I know I'm going to have to deal with it. Method swizzling is such a neat trick!
And, much like what happened to GOTO 40 years ago, language designers have invented less powerful language features that are perfectly acceptable 90% solutions. e.g. nowadays I’d generally pick higher order functions or the strategy pattern over method swizzling because they’re more amenable to static analysis and easier to trace with typical IDE tooling.
What has had the staying power is the API because that API is for an operating system that has had that staying power. As you hint, the macOS of today is simply the evolution of NeXTSTEP (released in 1989). And iOS is just a light version of it.
But 1989 is not all that remarkable. The Linux API (POSIX) was introduced in 1988 but started in 1984 and based on an API that emerged in the 70s. And the Windows API goes back to 1985. Apple is the newest API of the three.
As far as languages go, the Ladybird team is abandoning Swift to stick with C++ which was released back in 1979. And of course C++ is just an evolution of C which goes back to 1972 and which almost all of Linux is still written in.
And what is Ladybird even? It is an HTML interpretter. HTML was introduced in 1993. Guess what operating system HTML and the first web browser was created on. That is right...NeXTSTEP.
The constantly moving target fetish coming from the javascript camp may be misguided, you know...
Objective-C was actually created by a company called Stepstone that wanted what they saw as the productivity benefits of Smalltalk (OOP) with the performance and portability of C. Originally, Objective-C was seen as a C "pre-compiler".
One of the companies that licensed Objective-C was NeXT. They also saw pervasive OOP as a more productive way to build GUI applications. That was the core value proposition of NeXT.
NeXT ended up basically taking over Objective-C and then it became of a core part of Apple when Apple bought NeXT to create the next-generation of macOS (the one we have now).
So, Objective-C was actually born attempting to "use standards" (C instead of Smalltalk) and really has nothing to do with Apple culture. Of course, Apple and NeXT were brought into the world by Steve Jobs
What language would you have suggested for that mission and that era? Self or Smalltalk and give up on performance on 25-MHz-class processors? C or Pascal and give up an excellent object system with dynamic dispatch?
I haven’t used it in Apple’s ecosystem, so maybe I am way off base here. But it seems to me that it was Apple’s effort to evolve the language away from its systems roots into a more suitable applications language that caused all the ugliness.
So they already got what they wanted without inventing a new language. There must be some other reason.
[0] https://atp.fm/205-chris-lattner-interview-transcript#swiftc...
On the second part, I think the big thing was that they needed something that would interop with Objective-C well and that's not something that any language was going to do if Apple didn't make it. Swift gave Apple something that software engineers would like a ton more than Objective-C.
I think it's also important to remember that in 2010/2014 (when swift started and when it was released), the ecosystem was a lot different. Oracle v Google was still going on and wasn't finished until 2021. So Java really wasn't on the table. Kotlin hit 1.0 in 2016 and really wasn't at a stage to be used when Apple was creating Swift. Rust was still undergoing massive changes.
And a big part of it was simply that they wanted something that would be an easy transition from Objective-C without requiring a lot of bridging or wrappers. Swift accomplished that, but it also meant that a lot of decisions around Swift were made to accommodate Apple, not things that might be generally useful to the lager community.
All languages have this to an extent. For example, Go uses a non-copying GC because Google wanted it to work with their existing C++ code more easily. Copying GCs are hard to get 100% correct when you're dealing with an outside runtime that doesn't expect things to be moved around in memory. This decision probably isn't what would be the best for most of the non-Google community, but it's also something that could be reconsidered in the future since it's an implementation detail rather than a language detail.
I'm not sure any non-Apple language would have bent over backwards to accommodate Objective-C. But also, what would Apple have chosen circa-2010 when work on Swift started? Go was (and to an extent still is) "we only do things these three Googlers think is a good idea", Go was basically brand-new at the time, and even today Go doesn't really have a UI framework. Kotlin hadn't been released when work started on Swift. C# was still closed source. Rust hadn't appeared yet and was still undergoing a lot of big changes through Swift's release. Python and other dynamic languages weren't going to fit the bill. There really wasn't anything that existed then which could have been used instead of Swift. Maybe D could have been used.
But also, is Swift bad? I think that some of the type inference stuff that makes compiles slow is genuinely a bad choice and I think the language could have used a little more editing, but it's pretty good. What's better that doesn't come with a garbage collector? I think Rust's borrow checker would have pissed off way too many people. I think Apple needed a language without a garbage collector for their desktop OS and it's also meant better battery life and lower RAM usage on mobile.
If you're looking for a language that doesn't have a garbage collector, what's better? Heck, what's even available? Zig is nice, but you're kinda doing manual memory management. I like Rust, but it's a much steeper learning curve than most languages. There's Nim, but its ARC-style system came 5+ years after Swift's introduction.
So even today and even without Objective-C, it's hard to see a language that would fit what Apple wants: a safe, non-GC language that doesn't require Rust-style stuff.
Do you have a source for this?
C# has a copying GC, and easy interop with C has always been one of its strengths. From the perspective of the user, all you need to do is to "pin" a pointer to a GC-allocated object before you access it from C so that the collector avoids moving it.
I always thought it had more to do with making the implementation simpler during the early stages of development, with the possibility of making it a copying GC some time in the feature (mentioned somewhere in stdlib's sources I think) but it never came to fruition because Go's non-copying GC was fast enough and a lot of code has since been written with the assumption that memory never moves. Adding a copying GC today would probaby break a lot of existing code.
It sounds like you're speculating. But this doesn't match the reality of actual Rust code. For example, here's the complete, actual code for the `Widget` trait implementation for the `Button` struct in the egui framework:
impl Widget for Button<'_> {
fn ui(self, ui: &mut Ui) -> Response {
self.atom_ui(ui).response
}
}
(From: https://github.com/emilk/egui/blob/main/crates/egui/src/widg... , bottom of page.)This is OO code. It's just that it's trait-oriented, not class-oriented. But that's a good thing, not a drawback. Traits are more precise, more flexible, more type-safe, and don't conflate multiple unrelated concerns in a single feature the way class inheritance does. OO languages like Java support a very similar approach, via interfaces.
You can find similar code in any Rust GUI library, and indeed in almost any non-trivial Rust program.
> Otherwise, there'd be no difference and everyone would call Rust an OO language.
Rust is not a class-based OO language. But the fact that one of its core features, traits, have "methods", and those methods have a first argument traditionally named `self` should be a clue. Trait-based OO is very much OO. Whether "Rust is an OO language" depends on how strictly you want to define "OO" to match the rather obsolete 1970s conception of it.
This is why the first question I asked you was "What OO features are you thinking of that Rust doesn't have?" Because "OO" is a broad label that covers a wide range of different features.
Rust doesn't have "classes", but classes are a 1970s-era mish-mash of a whole bunch of different concerns munged together into a single poorly-factored construct. Now, half a century later, that's well understood, and better solutions exist in the form of traits and interfaces, and related capabilities.
> Like why did ObjC feel the need to add ARC (not GC but similar goal)?
Same reason Rust includes `Rc` and `Arc`. A general-purpose language has to provide some solution to memory management based on reachability. Reference counting and tracing GC are common solutions to that. Rust's static memory management plus RC is plenty good enough for GUI applications.
I like monkey patching for testing legacy code. I like it less as a thing in production code because it can become a security and reliability problem.
I actually suspect that ObjC and the NeXT APIs played a big part in that success. I know they’ve fallen out of favor now, and for reasons I have to assume are good. But back in the early 2000s, the difference in how quickly I could develop a good GUI for OS X compared to what I was used to on Windows and GNOME was life changing. It attracted a bunch of developers to the platform, not just me, which spurred an accumulation of applications with noticeably better UX that, in turn, helped fuel Apple’s consumer sentiment revival.
You're using a definition of OOP where only Smalltalk-style message passing counts. By that definition, you're right: Swift is closer, because `@objc` exists. But by that definition, neither Swift nor Rust is an OOP language in any meaningful sense, and the delta between them is mass-of-the-electron tiny. Swift's message passing support is an annotation that is a compatibility shim for a 40-year-old runtime, not a design philosophy.
So when you say Swift has "better OO support"... sure, in the same way that my car has better submarine support than yours because I left the windows cracked and water could theoretically get in. Technically true! Not useful!
The Ladybird team are C++ developers evaluating languages for a browser engine. When C++ developers say "OOP" they mean classes, inheritance hierarchies, virtual methods. The DOM is a giant inheritance tree. That's the context. You can tell them they're using the word wrong, but that doesn't change what they meant, and what they meant is the only thing that matters for understanding whether the claim made sense.
And under their definition-which is also the definition used by mass, essentially every working programmer and every university curriculum for the last 30 years-Swift and Rust are actually pretty close, which was my original point. Swift has `class` with inheritance, Rust has traits and composition. Neither is Smalltalk. The claim that Swift is "strictly better" was weird no matter which definition you pick.
(Also, and I say this respectfully: characterizing C++/Java/Rust as "functional programming" because they encapsulate data with functions is... a take. I get the logic chain you're following but that is not a definition that will help anyone communicate with anyone else, which is presumably the point of definitions.)
Okay, but for that to be true in this case then you must explain how Swift has "better OOP support". If there is no rational explanation for now Swift has "better OOP support" by the metrics you are imagining, as you, me, and everyone else has alluded to earlier, then clearly that isn't what they meant.
> I get the logic chain you're following but that is not a definition that will help anyone communicate with anyone else
Won't help communicate with anyone else meaning that you are the only one capable of understanding the logic chain? I'm sure you are a talented guy, but the world isn't exactly lacking in talented people. I'm sorry to say, but most everyone on HN will have absolutely no trouble understanding this.
I did. Swift has `class` types with implementation inheritance. Rust does not. If you're porting a C++ codebase with deep class hierarchies (like, say, a browser DOM), Swift lets you transliterate those hierarchies directly. Rust makes you rethink them into composition and traits. That's a real difference that matters to a team mid-migration, and it's an extremely rational explanation for why a C++ dev would say Swift has "strictly better OOP support."
You don't have to agree it's a large difference (I don't, which was my original point), but "there is no rational explanation" just isn't true. There's a very obvious one, it's just boring.
> If there is no rational explanation, as you, me, and everyone else has alluded to earlier, then clearly that isn't what they meant.
My position was never "there is no rational explanation." My position was "the difference is small enough that 'strictly better' was a weird thing to say." Those are different claims! You're kind of merging me into your argument when we don't actually agree.
> Won't help communicate with anyone else meaning that you are the only one capable of understanding the logic chain?
No, I meant that if you say "C++ is a functional programming language" to mass, any working programmer, they will not understand you, because that is not what those words mean to them. It's not about intelligence, it's about shared vocabulary. You've built a internally-consistent taxonomy where functional = data + functions, OOP = data + message passing, and imperative = data and functions separate. I can follow it fine. But you've redefined three terms that already have widespread, different meanings, and then you're treating disagreement as confusion. That's the communication problem.
Functional programming is not "encapsulating data in 'objects'". Such a model would naturally feature methods like "void Die.roll()", "void list.Add(element)" which are definitely not functional programming (which emphasizes immutability, pure functions, composition, etc.)
They are both OOP like a football can be something that you use in a sport and something that flies you to the moon. Except it is not clear what flies you to the moon goes by "football".
> Such a model would naturally feature methods like "void Die.roll()", "void list.Add(element)" which are definitely not functional programming
Exactly, functional programming. `Die` and `list` encapsulate data and use higher order functions to operate on it, which is what defines functional programming.
> which emphasizes [...] pure functions
Functions without encapsulation is imperative programming. If you introduce encapsulation then, yes, you have functional programming, just like your examples above.
Immutability is a disjoined property that can optionally apply to all of these programming paradigms. OOP, functional, and imperative programs can all be immutable, or not.
Composition and encapsulation go hand in hand, so that one is also functional programming, yes. And certainly composition is core to languages like C++/Java/Rust/etc. Naturally, them being functional languages.
To reiterate:
- Imperative programming: Data and functions are separate.
- Functional programming: Data is grouped with functions.
- Object-oriented programming: Data is grouped with message responders.
If
[aView display];
really, really, really isn't to your liking, you can write objc_msgSend( aView, @selector(display));
or even: objc_msgSend( aView, sel_registerName("display"));
That's pretty much all there is to it. But I have to admit I like the syntax better: [aView display];These definitions are not at odds with the discussion at hand at all. It was clearly stated that Swift has better OO support. Which is obviously true because it tries to be compatible with Objective-C, and therefore needs to have some level of OO support. That is something that Rust has no interest in doing, and rightfully so.
Your redefinition violates the claim, and therefore we can logically determine that it is not what was being used in the rest of the thread. That is, aside from the confused Rust guy that set this tangent in motion, but the remainder of this thread was merely clarifying to him what was originally intended. "He has a different definition for OOP" doesn't really help his understanding. That is what this thread branch has always been about, so it is not clear where you are trying to go with that.
I'm certainly not clever enough to have built it. Not to mention that the person who coined OOP is quite famous for having done so. I am not him, I can assure you. I have merely ingested it from what is out there in widespread circulation.
I can appreciate that you live in a different bubble and what is widespread there is not the same. It's a pretty big world out there. However, it doesn't really matter as if "C++ is a functional programming language" doesn't jive with your understanding, as you'll simply ask: "What ever do you mean?" and which point "functional programming language" will be defined and a shared understanding will be reached.
This isn't the problem you are imagining.
> I did.
Right. Seems we encountered a communication barrier again. "That's the thing man, there isn't anything." in my world would read "That's the thing man, there are things and here they are: ..." However, this highlights again that it doesn't actually harm communication as further clarification follows and eventually everyone will reach a shared understanding. Communication isn't some kind of TV game show where you have to get the right answer on your first try. This is not a problem in any way, shape, or form.
Ha, don't sell yourself short, you're doing a great job defending it.
> However, it doesn't really matter as if "C++ is a functional programming language" doesn't jive with your understanding, you'll simply ask: "What ever do you mean?"
Okay, genuinely, let's try this exercise. You say to me "C++ is a functional programming language." I ask "What ever do you mean?" You say "data is grouped with functions." I say "...that's also true of Python, JavaScript, Kotlin, Scala, Dart, TypeScript, and basically every language designed after 1990. What term do you use for Haskell?" And now we're in another 20-message thread defining terms from scratch instead of talking about the actual thing.
Like, you've got a taxonomy where imperative/functional/OOP is a clean trichotomy based on how data relates to code. That's elegant! But it also means "functional programming" contains both Haskell and Java, which in practice need to be distinguished from each other far more often than they need to be grouped together. The Kay-pure definitions give you clean categories at the cost of useful ones.
*Obj-C doesn't even pass muster of the Kay-pure definition, which renders the whole conversation moot.*
> "That's the thing man, there isn't anything." in my world would read "That's the thing man, there are things and here they are: ..."
Okay, fair hit. :) What I meant was: there's nothing that would make a C++ team say "strictly better." Swift has classes with inheritance, sure. But "strictly better" implies Rust can't even get close, and it can-you just model things differently. The Ladybird team discovered this themselves, which is... kind of the whole story here? They said "strictly better OOP support," tried it, and now have removed Swift. The claim didn't survive contact with their own codebase. That was the entire point of my original comment sitting at -3. (now at +2)
> Communication isn't some kind of TV game show where you have to get the right answer on your first try.
No, but Hacker News comments at -3 do get grayed out and collapsed, so in practice it kind of is, unfortunately.
In the context of the dimension we have been talking about, it is also functional. There is no difference between Haskell, Python, Java, etc. in that particular dimension. All of those languages you list are quite different in other dimensions, of course. Are you under the impression that programming languages are one dimensional? Unfortunately, that is not the case.
> And now we're in another 20-message thread defining terms from scratch instead of talking about the actual thing.
Especially when we find out that what we really wanted to talk about was type systems. Thinking of programming languages as being one dimensional is a fool's errand.
> But it also means "functional programming" contains both Haskell and Java, which in practice need to be distinguished from each other far more often than they need to be grouped together.
Right, there may be a need to separate them, but sensibly you would separate them on the dimension that is relevant to the separation intent, not some other arbitrary quality. For example, perhaps your interest is in separating mutability and immutability. Therefore, something like "Haskell is an immutable-by-default programming language" would be an appropriate statement in that desired context. "Haskell is a statically-typed programming language", not so much.
> No, but Hacker News comments at -3 do get grayed out and collapsed, so in practice it kind of is, unfortunately.
I'll still read your comments if they turn grey. I don't care about what color they are. This isn't a problem.