Hacker Newsnew | past | comments | ask | show | jobs | submit | slavapestov's commentslogin

> Does anyone know of larger apps built using Factor?

The Factor build farm, the website, and the concatenative wiki are all built in Factor, if that counts.


> In 2025 you can run apps targeting W95 just fine (and many 16-bit apps with some effort)

FWIW, Windows running on a 64-bit host no longer runs 16-bit binaries.


Yes. Still, there are ways to do it anyway, from Dosbox to WineVDM. Unlike MacOS where having even 32 bit app (e.g. half of Steam games that supported Macos to begin with) means you're fucked


You can use dosbox and x86 virtual machines just fine in macOS (with the expected performance loss) right now, without Rosetta. macOS is still Turing complete.


Technically speaking, you can run anything on anything since stuff Turing complete. Practically speaking however....

E.g. i have half of macos games in my steam library as a 32-bit mac binaries. I don't know a way to launch them at any reasonable speed. Best way to do it is to ditch macos version altogether and emulate win32 version of the game (witch will run at reasonable speed via wine forks). Somehow Win32 api is THE most stable ABI layer for linux & mac


> my steam library as a 32-bit mac binaries. I don't know a way to launch them at any reasonable speed.

To be fair, it's the emulation of x86-32 with the new ARM64 architecture that causes the speed problems. That transition is also why MacBooks are the best portables, in terms of efficiency, that you can buy right now.

All ARM chips have crippled x86-32 performance, because they're not x86-32 chips. You'll find the same (generally worse) performance issues trying to run ARM64 code with x86-64.


Rosetta 2 is pretty good at running x86-32. There's more registers on the destination, after all.


>Windows running on a 64-bit host no longer runs 16-bit binaries.

Which isn't an issue since Windows 95 was not a 16-bit OS, that was MS-DOS. For 16-bit DOS apps there's virtualization things like DOSbox or even HW emulators.


So what did you decide to give up on? Overloading functions with the same name, or bidirectional constraint solving? :)

These days though the type checker is not where compile time is mostly spent in Swift; usually it’s the various SIL and LLVM optimization passes. While the front end could take care to generate less redundant IR upfront, this seems like a generally unavoidable issue with “zero cost abstraction” languages, where the obvious implementation strategy is to spit out a ton of IR, inline everything, and then reduce it to nothing by transforming the IR.


Bidirectional constraint solving. It's bad for compile time but even worse for predictable diagnostics. Mojo does contextual resolution, but it works more similar to how C++ resolves initializer lists etc.


> Bidirectional constraint solving. It's bad for compile time but even worse for predictable diagnostics.

That’s really only true if you have overloading though! Without overloading there are no disjunction choices to attempt, and if you also have principal typing it makes the problem of figuring out diagnostics easier, because each expression has a unique most general type in isolation (so your old CSDiag design would actually work in such a language ;-) )

But perhaps a language where you have to rely on generics for everything instead of just overloading a function to take either an Int or a String is a bridge too far for mainstream programmers.


Mojo has overloading, generics and a much more advanced type system than Swift (dependent and linear types etc), and compile time in all phases is very important. The Mojo design seems to be working well - it gives expressive power, good error messages etc.

It feels like a much better design point overall.


I wasn’t trying to start a fight over languages, that would be silly. I also wrote a language once and then moved on from it (to your former language ;-)), so I know the feeling! I wish you luck with your new language, and I wish for many more languages in the future to try different approaches and learn from each other.

My original reply was just to point out that constraint solving, in the abstract, can be a very effective and elegant approach to these problems. There’s always a tradeoff, and it all depends on the combination of other features that go along with it. For example, without bidirectional inference, certain patterns involving closures become more awkward to express. You can have that, without overloading, and it doesn’t lead to intractability.


Sure, I wasn't trying to start a fight either, I was just sharing my experience and opinion on having worked on both. Mojo (and C++) have closures, for example c++ does lambda type inference without a constraint solver.

In my opinion, constraint solving would be a bad design point for Mojo, and I regret Swift using it. I'm not trying to say that constraint solving is bad for all languages and use-cases.


> let a: Double = -(1 + 2) + -(3 + 4) + -(5)

> Still fails on a very recent version of Swift, Swift 6.1.2, if my test works.

FWIW, the situation with this expression (and others like it) has improved recently:

- 6.1 fails to type check in ~4 seconds

- 6.2 fails to type check in ~2 seconds (still bad obviously, but it's doing the same amount of work in less time)

- latest main successfully type checks in 7ms. That's still a bit too slow though, IMO. (edit: it's just first-time deserialization overhead; if you duplicate the expression multiple times, subsequent instances type check in <1ms).


> Any object that is passed into a library function can escape the current thread,

In Swift 6 this is only true if the value’s type is Sendable.


I feel like if the first link in your post is a tweet from a tech CEO the rest is unlikely to be insightful.


i don’t disagree with your main point, but is karpathy a tech ceo right now?


I think they meant Tobi Lutke, CEO of Shopify: https://twitter.com/tobi/status/1935533422589399127


thanks for clarifying!


> This has tradeoffs: increased ABI stability at the cost of longer compile times.

Nah. Slow type checking in Swift is primarily caused by the fact that functions and operators can be overloaded on type.

Separately-compiled generics don't introduce any algorithmic complexity and are actually good for compile time, because you don't have to re-type check every template expansion more than once.


You’re absolutely right. I realized this later but it was too late to edit the post.


Separate compilation also enables easy parallelization of type checking.


> the only-very-recently-stable ABI,

You mean 6 years ago? https://www.swift.org/blog/swift-5-released/


MSVC was laughed at for only providing a stable C++ ABI in 2019. Swift is not immune to the same criticism, and has even fewer excuses for it: we knew for a long time stable ABIs are critical for interop.

(And interop with Swift is still laughably bad)


Swift is one of the very few languages to even have a stable ABI and is leading in terms of interoperability with other languages. What even are you talking about?


Find an area to specialize in that has more depth to it than just gluing APIs together.


You might find Kitten interesting: https://kittenlang.org/


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: