News for hackers. Stuff that matters.
Re:Swift is a more convenient Rust by noelwelsh on Friday September 06, 2024 @06:09AM (#41464639)
Hmmm...I disagree with a number of statements in the post but I think the following two hypotheses will make for more interesting discussion than some nitpicks:

1. A large part of why many people love Rust is that it's the first time they've used an ML family language. One of the innovations of Rust was to create a community that felt like home to Unix hackers who weren't programming language nerds.

2. Rust is the first language to bring non-GC automatic memory management to the mainstream. It won't be the last and it might well be the worst. Other languages in this space include Swift (as in OP's post), OCaml[1], and Scala[2]. These alternatives take the approach that tracking ownership is not the default, which is fine for the majority of programs and far more ergonomic.

There's also a corollary

3. The age of Smalltalk is over. It's now the age of ML. (Amusingly, going backwards in time, from 1983 to 1975). The languages that dominated the 2000s (Ruby, Python, Javscript, PHP) were all more or less derived from Smalltalk (everything is an object! dynamic types! runtime metaprogramming!) The new languages (Rust, Scala, Swift, Kotlin, etc.) are ML family languages. Similarly, back in the day you could learn, say, Ruby, and still be reasonably proficient in Python or JS. Now you can learn, say, Scala, and pick up Rust or Swift reasonably easily.

[1]: https://blog.janestreet.com/oxidizing-ocaml-locality/

[2]: https://dl.acm.org/doi/full/10.1145/3618003

Re:Swift is a more convenient Rust by Loic on Friday September 06, 2024 @07:43AM (#41465233)
In this context, ML is Meta Language: https://en.wikipedia.org/wiki/ML_(programming_language)
Re:Swift is a more convenient Rust by kingofthehill98 on Friday September 06, 2024 @08:49AM (#41465676)
Thank you!

The whole time I was like "what in the absolute hell is a ML language".

Re:Swift is a more convenient Rust by high_priest on Friday September 06, 2024 @05:52PM (#41469995)
I've heard so much about Machine Learning in recent years, that I couldn't fathom ML be used in any other context & be understood.
Re:Swift is a more convenient Rust by noobr on Friday September 06, 2024 @10:10AM (#41466400)
thanks, i'm bad at abbreviations and don't like when people just throw them like this without first using the whole term at least once
Re:Swift is a more convenient Rust by plorkyeran on Friday September 06, 2024 @11:14AM (#41466942)
Expanding this abbreviation conveys zero information. It’s a programming language named ML, and if you haven’t heard of it then giving the etymology of the name isn’t going to help.
Re:Swift is a more convenient Rust by duckmysick on Friday September 06, 2024 @05:56PM (#41470011)
It clarifies it's not something else I've heard of (markup language, machine learning). The ML abbreviation shares the space with other terms so it can be confusing. Compare it to HTML which is 1) more popular and 2) unique in the context of programming.
Re:Swift is a more convenient Rust by jamwil on Saturday September 07, 2024 @02:54AM (#41472043)
Huh? If I search ‘Meta Language’ I get the exact information I need. If I search ‘ML’ I get less than nothing.
Re:Swift is a more convenient Rust by juneyi on Wednesday September 11, 2024 @08:13AM (#41510596)
> Expanding this abbreviation conveys zero information. It’s a programming language named ML, and if you haven’t heard of it then giving the etymology of the name isn’t going to help.

Honestly kind of shocked to see this type of mentality...wow.

Re:Swift is a more convenient Rust by thiht on Friday September 06, 2024 @02:37PM (#41468635)
This is indeed an abbreviation, but it doesn’t convey meaning. At this point ML is just the name of the thing, it could not expand to anything and still convey the same meaning.

If you don’t know ML, knowing what it stands for won’t help you. It’s like JS, either you know what JS is or you don’t. It’s not about what it means, it’s about what it is.

Re:Swift is a more convenient Rust by BlueTemplar on Saturday September 07, 2024 @12:03AM (#41471361)
You are forgetting that looking up abbreviations of 3 characters is already very hard, and it becomes almost impossible for the 2 character ones.
Re:Swift is a more convenient Rust by thiht on Saturday September 07, 2024 @03:52AM (#41472264)
It’s usually not when there’s some context.

> A large part of why many people love Rust is that it's the first time they've used an ML family language.

You wouldn’t search "ML" but "ML family language".

Or copy paste the whole thing and ask ChatGPT what ML means in this context.

Re:Swift is a more convenient Rust by mlindner on Saturday September 07, 2024 @06:15PM (#41476793)
ML is such an overloaded acronym in software that people really need to stop using it or ALWAYS clarify it.

ML = Machine Learning

ML = Machine Language

ML = Markup Language

ML = Meta Language

And I always see ML in the Meta Language sense to be the biggest culprit where writers assume the reader knows it, even though it's probably the least widely known.

Re:Swift is a more convenient Rust by bad_user on Friday September 06, 2024 @07:40AM (#41465207)
> first language to bring non-GC automatic memory management to the mainstream ... Other languages in this space include Swift

Ugh, “Arc”, aka (automatic) reference counting, is an implementation of GC as well. It may have certain characteristics, like having worse throughput, corner cases, and better predictability/latency characteristics, but it's GC nonetheless. That's not manual memory management. Swift is not a non-GC language.

And that's the big issue that people are missing — Rust tackles some hard problems regarding memory management, and a friendlier alternative exists: garbage collection.

Re:Swift is a more convenient Rust by rcruzeiro on Friday September 06, 2024 @07:53AM (#41465311)
Both ARC and garbage collection are memory management techniques. ARC does not equal garbage collection though. Garbage collection runs at intervals and is triggered by certain signals (memory pressure, etc), pauses all threads and scans for objects that can be deallocated. It is a very different concept than ARC.
Re:Swift is a more convenient Rust by twoodfin on Friday September 06, 2024 @08:07AM (#41465393)
https://courses.cs.washington.edu/courses/cse590p/05au/p50-b...

This paper makes a strong argument that “pure” tracing garbage collection and “rote” reference counting are effectively duals at the opposite ends of a spectrum of implementation choices.

For example, GC’s often optimize differently for young vs. old objects. How do they distinguish these? By “counting” (one bit) their references across one or more traces in a series of sweeps.

Re:Swift is a more convenient Rust by 01HNNWZ0MV43FF on Friday September 06, 2024 @11:22AM (#41467004)
And a hot wheels car is a car, but I would be perplexed to see one offered to me at a car dealership
Re:Swift is a more convenient Rust by Tuna-Fish on Friday September 06, 2024 @08:30AM (#41465546)
ARC is a method of implementing garbage collection, and is discussed as such in academic literature.

What you are equating with "garbage collection" is Mark-Sweep, which is an another way to implement GC, with a very different set of tradeoffs. (Broadly, better throughput at the expense of higher latency.)

Re:Swift is a more convenient Rust by 7jjjjjjj on Friday September 06, 2024 @09:31PM (#41470934)
In common usage everyone understands that GC = tracing GC.
Re:Swift is a more convenient Rust by 112233 on Friday September 06, 2024 @08:47AM (#41465655)
Deleting large hierarchy of objects when the last reference gets decremented also is triggered by a certain signal (reference decrement) and pauses all threads while it collects garbage. There are even tunable GC that become ARC if you set particular parameter to "N=1"
Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @09:39AM (#41466104)
I'm not sure that collecting a large hierarchy of objects requires pausing all threads. What can definitely require pausing threads (other than in specialized concurrent collectors) is the tracing step, which relies on some invariants that in simple GC implementations (not the more specialized concurrent ones mentioned earlier) are only ensured at very specific points in the program (known as GC "safepoints").
Re:Swift is a more convenient Rust by 112233 on Friday September 06, 2024 @11:38AM (#41467132)
My bad, thanks for correcting! Of course single thread freeing a lot of heap allocations will not pause other threads by itsel. What I had to write was: calling destructor of an object that in turn calls destructors of other objects (because a large tree of reference counted objects loses last reference to it's root) stops that thread, until all deallocation is done.
Re:Swift is a more convenient Rust by pessimizer on Friday September 06, 2024 @09:14AM (#41465893)
> There are even tunable GC that become ARC if you set particular parameter to "N=1"

You can call a pointer to a value a "one-element static array."

Re:Swift is a more convenient Rust by pessimizer on Friday September 06, 2024 @09:10AM (#41465853)
It's not "automatic" reference counting, it's "atomic" reference counting. And it's not automatic, it's entirely manual and implemented with traits as a fat pointer. Reference counting types in Rust are just defaults that give certain guarantees.

This feels like people arguing that atheism is a kind of religion. Borrow checking and a library of safe default primitives make it so you don't really have to think about memory management; except to the extent that you generally stick to those primitives, and that you have to install the borrow checker into your own head to write Rust comfortably (although the compiler will help.)

Rust doesn't have any garbage collection, but it can just assume how you would want to deal with memory by forcing you to be very specific about when values should be created or destroyed.

Re:Swift is a more convenient Rust by Ontonator on Friday September 06, 2024 @09:27AM (#41465996)
In the context of Swift, ARC is automatic reference counting: https://docs.swift.org/swift-book/documentation/the-swift-pr...
Re:Swift is a more convenient Rust by arghwhat on Friday September 06, 2024 @06:19AM (#41464697)
> Rust is the first language to bring non-GC automatic memory management to the mainstream

To nitpick, the first language to bring non-GC automatic memory management to the mainstream would be either Forth or C through stack memory.

For heaps, we have reference counting, often handled automatically through the stack (e.g., C++ smart pointers).

The thing Rust brought to mainstream is not automatic memory management - they're a dime a dozen with and without GC. It's an ownership model that is strict about whether you have read or write access within the type system. At the same time, this is also where most developer friction stems from, as it's quite unique, and you're often faced with a trade-off between explaining exactly what you want at compile-time at higher design cost, or bailing out more to runtime checks with e.g. RefCell while getting fewer guarantees about code correctness from the compiler.

Re:Swift is a more convenient Rust by pjmlp on Friday September 06, 2024 @06:30AM (#41464766)
Not at all, considering the decade of high level systems programming languages that predated the very thought of C coming into life.

All with stack allocation.

Re:Swift is a more convenient Rust by arghwhat on Friday September 06, 2024 @11:27AM (#41467036)
Keyword is mainstream, so it’s not when the idea was invented - I think Forth popularized it?

I can’t really comment on what counted as mainstream before C though. Not old enough for that.

Re:Swift is a more convenient Rust by pjmlp on Friday September 06, 2024 @12:00PM (#41467315)
Mainstream is whatever people could use between 1958 and 1969, as high level programming language, in whatever computers, universities and companies could afford.

Goggle, Bing, DuckDuckGo, ChatGPT,... will gladly provide a list.

Re:Swift is a more convenient Rust by arghwhat on Friday September 06, 2024 @12:43PM (#41467684)
What people could use is not at all what mainstream is. You can use D, OCaml, F# and brainfuck, but they are not mainstream.

To define what was mainstream we'd need to talk to people coding at the time and ask them about popularity, adoption, tooling availability, etc. and what languages people were likely to use rather than what was available.

And no, I have no need for researching that as I have no use of the information - the point is to say that automatic memory management in mainstream languages predate rust by decades and is present in most languages, not "this specific language should get credit".

Re:Swift is a more convenient Rust by pjmlp on Saturday September 07, 2024 @04:43AM (#41472504)
Then you should not have mentioned Forth or C at all, only to show not having a clue about programming languages history.

Besides, any Assembly programmer is well aware of what stack memory is all about, bring us even further back than 1958.

Re:Swift is a more convenient Rust by arghwhat on Monday September 09, 2024 @03:57AM (#41486379)
> Then you should not have mentioned Forth or C at all, only to show not having a clue about programming languages history.

The whole point was that these well-known mainstream languages provided the feature claimed to first have arrived in Rust, to make it clear that it was not just theoretical or some obscure language.

It's not my fault that you misunderstood the topic or the idea of what makes something mainstream, and instead read this as an elaborate history class stating the absolute first discovery of the idea.

> Besides, any Assembly programmer is well aware of what stack memory is all about, bring us even further back than 1958.

The instructions you refer to were designed to support stack-based languages, not the other way around.

Re:Swift is a more convenient Rust by shakow on Friday September 06, 2024 @07:36AM (#41465181)
> C through stack memory.

Stack memory is decades older than C.

Re:Swift is a more convenient Rust by Ygg2 on Friday September 06, 2024 @08:47AM (#41465660)
> non-GC *automatic memory* management to the mainstream would be either Forth or C

Emphasis mine.

It's not C. You do manual memory management there. You have to call malloc/free.

Didn't use Forth, so I can't say anything about it.

Re:Swift is a more convenient Rust by xolox on Friday September 06, 2024 @08:57AM (#41465748)
malloc/free are for heap based allocations. The grand parent explicitly mentioned he was referring to stack based allocations, which are kind of automatic (implicit).
Re:Swift is a more convenient Rust by Ygg2 on Friday September 06, 2024 @10:08AM (#41466378)
Sure, however you still have to do them manually. That's what manual in manual memory management stands for.

Stack based allocation are essentially registers, right?

Re:Swift is a more convenient Rust by arghwhat on Friday September 06, 2024 @11:30AM (#41467057)
The stack is fully automatic arbitrary memory and has nothing to do with registers. You can allocate as much as you want (including e.g. bytearrays), until you run into the allocated stack limit. That limit can be arbitrary, and some languages even dynamically scale the stack.

That you also have access to manual memory on the heap doesn’t matter. You can also do manual memory management in Rust if you want, as one has to do at times.

Re:Swift is a more convenient Rust by Ygg2 on Friday September 06, 2024 @03:26PM (#41468982)
Ok. Then manual memory applies to just heap memory management.

It's not rocket science. If you are calling malloc/free to maintain your memory you're doing manual memory management.

Re:Swift is a more convenient Rust by arghwhat on Friday September 06, 2024 @07:13PM (#41470365)
> It's not rocket science. If you are calling malloc/free to maintain your memory you're doing manual memory management.

Sure, and when I do the same in Rust I'm also doing manual memory management. So by your definition, both Rust and C are manual memory languages.

> You're confusing default memory management with what's possible.

Ah, so we care about the default, which I pressume is what the language semantics themselves provide, rather than focusing on what the standard libraries can provide you?

In that case C is an automatic memory language, because the language semantics only provide you stack memory. malloc/free are just random functions in the standard library after all, just like Rust's `Box::new` and `std::alloc`.

See, the point is that you're opting into manual memory management in C from an automatic model. We are so used to the stack that we forget that it's the OG fully automatic zero-cost memory management system, and in case of C++, can be used to implement fully automatic heap memory as well - in which case you never need to call malloc/free/new/delete.

(And no, it doesn't count that your smart pointer calls new/delete, because then you also need to count Box::new calling std::alloc)

> By your logic, Arena allocators can be used in many different languages, including GC ones like Java.

Uh, even in bog standard Java without any shenanigans you are using an "arena allocator". A GC doesn't change how allocators work, it just responsible for calling free.

(Caveat about moving vs. non-moving garbage collectors and ones that have multiple arenas, but that's not relevant here and an entire topic of its own.)

Re:Swift is a more convenient Rust by Ygg2 on Saturday September 07, 2024 @04:10AM (#41472347)
> Sure, and when I do the same in Rust I'm also doing manual memory management. So by your definition, both Rust and C are manual memory languages.

You're being very thick on purpose. In Rust you need to reach for foreign functions to implement malloc/free.

> So by your definition, both Rust and C are manual memory languages.

No. By my definition what is the default semantics determines if it's manual or automatic.

But if you want to play these semantics game, you just admitted C is GC language and thus unsuitable for kernel development.

> Uh, even in bog standard Java without any shenanigans you are using an "arena allocator".

No, no you aren't. At least not explicitly. I assume you mean GC, if it has or doesn't have arenas is implementation detail.

Re:Swift is a more convenient Rust by arghwhat on Monday September 09, 2024 @04:18AM (#41486478)
> You're being very thick on purpose. In Rust you need to reach for foreign functions to implement malloc/free.

I think you're mistakenly thinking of calling out to the (rust-lang maintained) libc crate's malloc/free functions. That's not the case - the standard library provides `std::alloc`, which is the allocator also backing Box and Vec.

> No. By my definition what is the default semantics determines if it's manual or automatic. It's CS 101.

Your definition of default semantics - "in C it's not what the language does but what happens when you call random library functions, while in Rust it's the opposite" - makes no sense at all.

C isn't considered a manual language because of default semantics, but because people have chosen to mainly rely on such paradigm.

> No, no you aren't. At least not explicitly. I assume you mean GC, if it has or doesn't have arenas is implementation detail.

Yes, whether any allocator has an arena is an implementation detail.

Whether you call `malloc` or `new`, or you have Go or Java do a heap allocation for you (which, to nitpick, is not actually the job of the garbage collector), the use of an arena is an implementation detail. In case of GC, the availability of optimizations also depend heavily on whether it's a moving GC.

Re:Swift is a more convenient Rust by Ygg2 on Monday September 09, 2024 @05:26AM (#41486777)
> That's not the case - the standard library provides `std::alloc`, which is the allocator also backing Box and Vec.

Again, emphasis on the word, default. How are you using Box and Vec. Are you by default encouraged to drop them manually via Allocator?

No, you aren't. You're heavily discouraged via usage of `unsafe`, you are discouraged because the compiler does automatic `alloc`/`drop`.

You have to go out of your way to do manual memory management.

> Your definition of default semantics

I showed you what happens when you apply the non-default semantics of a language to C. You end up with nonsensical statements like C is a GC language. Just because a style is possible in language X doesn't mean language X is of that style.

> C isn't considered a manual language because of default semantics, but because people have chosen to mainly rely on such paradigm.

And why is that? Because the default affordance of the language makes it so that way of usage is the most natural to most users. You could put everything in the stack, but that would be extremely torturous for most users, so they use malloc/free.

You give people a knife, of course they will grab it by the handle.

Re:Swift is a more convenient Rust by eska on Friday September 06, 2024 @02:03PM (#41468360)

  {
    int8_t x = 1;
  }
allocates a byte on the stack, binds it to a variable named x, sets it to 1, then deallocates it from the stack. There is no explicit allocation or deallocation.

As an optimization it can be put into a register instead of the stack, again without explicit allocation and deallocation (this is done by the compiler playing musical chairs with registers).

I would not consider this manual. Manual would instead be something like in embedded programming

  int8_t* y = (int8_t*)0xB4DC0FF3;
  *y = 1;
because one needs to keep track of used memory locations (do allocation management)
Re:Swift is a more convenient Rust by est31 on Friday September 06, 2024 @06:21AM (#41464710)
> Rust is the first language to bring non-GC automatic memory management to the mainstream. It won't be the last and it might well be the worst. Other languages in this space include Swift

Rust's memory management is not automatic, you have to explicitly manage memory. It's just made extremely easy for you by the language thanks to stuff like RAII, and there is checks that prevent memory safety violations like double free. But those checks won't prevent leaks, although the many lints do make it harder to forget about a value.

Also, Swift's refcounting can be seen as a form of gc.

Re:Swift is a more convenient Rust by lolinder on Friday September 06, 2024 @07:47AM (#41465262)
> Rust's memory management is not automatic, you have to explicitly manage memory. It's just made extremely easy for you by the language thanks to stuff like RAII, and there is checks that prevent memory safety violations like double free. But those checks won't prevent leaks, although the many lints do make it harder to forget about a value.

By this logic no language on earth has automatic memory management. I've spent time troubleshooting a memory leak in JavaScript in the past month, caused by someone keeping a pointer around longer than necessary.

Rust's memory management is automatic in that you can write entire Rust programs without once calling `free` manually. I'm not sure what definition of automatic you're working off of, but if it excludes JavaScript it doesn't seem especially useful.

Re:Swift is a more convenient Rust by est31 on Friday September 06, 2024 @11:41AM (#41467168)
> Rust's memory management is automatic in that you can write entire Rust programs without once calling `free` manually.

Personally I'd put the bar around not requiring people to distinguish different pointer types (owned vs shared). Languages like Java, JS, Python, Swift, Go, etc all have this "everything is a smart pointer" paradigm, (or at least the strong and widely used default). I'd say Rust is manually managed because you need to think about which pointer type to use and using gc'd pointer types like Arc has a syntax overhead (like say when a pointer is cloned).

Re:Swift is a more convenient Rust by iknowstuff on Friday September 06, 2024 @11:58AM (#41467300)
Swift has „weak” references for when you don’t want to bump the reference count. Does that make it manual?
Re:Swift is a more convenient Rust by consteval on Friday September 06, 2024 @12:53PM (#41467764)
Most GC langs have these features too they're just not in your face. Technically C# has true value types like C++.

Rust makes the distinction between stack and heap references, like C++. Other, more high-level languages don't - there's only one kind of reference, you can't take a reference to a stack object. Maybe you implement that by making all objects heap allocating (Java) or you just say they have to be copied every time (C# struct). That's really where the difference is.

There's a lot of juicy, juicy performance there. The problem is taking references to stack variables is problematic. Tracking heap objects with a GC or a ref counter is really trivial in comparison IMO, at least when you try to combine the systems.

Re:Swift is a more convenient Rust by est31 on Friday September 06, 2024 @03:12PM (#41468887)
> Most GC langs have these features too they're just not in your face.

That's what I meant by "strong and widely used default". Defaults and syntactic sugar do matter and influence the type of code written.

Re:Swift is a more convenient Rust by neonsunset on Friday September 06, 2024 @02:15PM (#41468480)
The assessment on C# does not match language spec at all.

Not only instance methods on C# structs are implicitly byref, you can easily pass structs by reference via ref, out and in keywords. On top of that, ref structs can hold `byref` pointers aka 'ref' keyword which can point to arbitrary memory, or have references to other structs/variables/anything.

There is also regular C syntax with &T and T* for unmanaged references/pointers. On top of that, .NET's compiler has gotten very good at struct optimizations and pretty much ensures they stay in registers all the time unless address-taken, including SIMD registers for Vector<T> and Vector128/256/512<T> even their "deconstructed" form when specified width is not supported so they get handled as e.g. 256x2. There was a big jump in codegen quality in .NET 8 which can now sometimes trade blows with GCC and Clang around struct optimizations.

All these features are first-class and are heavily used by all kinds of performance-sensitive code.

Also, structs can implement interfaces and can be generic arguments that satisfy interface constraints, which works exactly like generics with trait bounds in Rust - you get a generic instantiation aka monomorphized function body, making the abstraction zero-cost.

Re:Swift is a more convenient Rust by consteval on Friday September 06, 2024 @04:26PM (#41469475)
Wow, I was not aware of the monomorphization of structs in C#. That's very interesting, I wonder how you're able to mix generic structs and generic classes seamlessly.

> you can easily pass structs by reference via ref, out and in keywords. On top of that, ref structs can hold `byref` pointers aka 'ref' keyword which can point to arbitrary memory

These are not features I've encountered. I wonder how you solve dangling references when those references could point to automatic stack variables.

Re:Swift is a more convenient Rust by neonsunset on Friday September 06, 2024 @04:58PM (#41469674)
> Wow, I was not aware of the monomorphization of structs in C#. That's very interesting, I wonder how you're able to mix generic structs and generic classes seamlessly.

The handling is transparent, in a way. As implemented by CoreCLR, class-type generic arguments have shared representation named __Canon. This means that, for example, a `Dictionary<int, string>` has a generic instantiation indicated as `Dictionary<int, __Canon>` where __Canon is an implicit generic type argument passed alongside relevant calls. Statics referencing that do get exact address, and there is quite a bit of complexity regarding runtime handling of this as far as virtual calls and other edge cases are involved, but as a programmer you are never exposed to that directly. It's an implementation detail, and even un-monomorphized cases work rather fast in most situations, like standard data containers.

> These are not features I've encountered. I wonder how you solve dangling references when those references could point to automatic stack variables.

Not sure what you mean by automatic stack variables, but the idea behind byref pointers\managed references\'ref's is that they are not allowed to be boxed or otherwise placed on the heap.

This lifetime restriction enables key scenarios:

- byrefs can point to object interiors without hindering GC throughput

- byrefs can point to stack memory, allowing `var span = (stackalloc byte[32]);` and more

- byrefs can point to any unmanaged memory without requiring excessive range checks by GC

This way you can use `ref T` to represent any memory location and `Span<T>` to represent any contiguous memory range up to 2B elements, without having to carry around bespoke overloads and types that disambiguate between containers and memory sources, much like you would usually see in most other GC-based languages.

There is also additional lifetime analysis in Roslyn to prevent you from returning 'scoped' 'ref's to an outer scope, like having a ref point to an integer in the current method body and returning it to the caller - this will not compile, unless you override it with unsafe [UnscopedRef] which you should never do unless you are absolutely certain (every time I used it and was absolutely certain, the compiler was right and I was not :D). This also works "through" ref structs and other tricky scenarios, which means you can return a ref that points to a middle of heap-allocated array - the scope of object exceeds current method, and byref can keep the array rooted even if no other reference to it exists. The main restriction is byrefs can mostly flow "downward" as not to escape the scope they originate from, but that's a given in most scenarios in Rust just as much.

There is a basic walkthrough about byrefs here: https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

C# is good at systems programming - it also has portable SIMD and intrinsics, static linking, native compilation and zero-cost FFI. Engineers getting surprised by this fact rather than upset is the happier but unfortunately less frequent outcome :)

Re:Swift is a more convenient Rust by afdbcreid on Saturday September 07, 2024 @07:05PM (#41476984)
> I wonder how you solve dangling references when those references could point to automatic stack variables.

By restricting them, to, essentially, disallow storing `ref`s on the heap.

Re:Swift is a more convenient Rust by Measter on Friday September 06, 2024 @08:38AM (#41465590)
I've found it's kinda helpful to think of Rust/modern C++ style management as semi-automatic memory management. You control when things are allocated and freed, but you don't bother with the minutia of it unless you're writing a low-level container type.

This is contrast to something like C/Zig, where things are fully manual, or something like Python or Javascript where things are fully handled for you.

Re:Swift is a more convenient Rust by bryancoxwell on Friday September 06, 2024 @08:05AM (#41465385)
Pointers in JavaScript? I’m far from a JS expert, but didn’t think the language had pointers. Could you explain what you mean here?
Re:Swift is a more convenient Rust by lolinder on Friday September 06, 2024 @08:13AM (#41465444)
I'm not aware of any mainstream language that doesn't have pointers, the question is whether they expose pointers as a first-class language construct (i.e. you can choose to not dereference them or to do pointer arithmetic) or use them as an implementation detail.

In JavaScript's case it's an implementation detail, but one that is extremely relevant when maintaining something in production.

Re:Swift is a more convenient Rust by bobajeff on Friday September 06, 2024 @08:31AM (#41465552)
Correction about JavaScript: All non-primitive data types are pass by reference. So not just implementation detail as no valid js interpreter will pass those by value.
Re:Swift is a more convenient Rust by lolinder on Friday September 06, 2024 @08:41AM (#41465618)
It's not up to the implementation to decide whether to pass by reference or not, but it is up to the implementation whether to use pointers under the hood to model passing by reference. Since there's no pointer arithmetic, other models could theoretically be used to accomplish the same semantics [0], it just happens to be that pointers are by far the most logical choice.

[0] As a silly example: a JavaScript implementation could technically store object references as a URL of an API that allows interacting with the object, as long as this is transparent to the user and the program behaves the same as a pointer implementation (minus non-functional characteristics like performance).

Re:Swift is a more convenient Rust by bryancoxwell on Friday September 06, 2024 @08:23AM (#41465506)
Makes sense, thanks!
Re:Swift is a more convenient Rust by mind-blight on Friday September 06, 2024 @08:20AM (#41465494)
Most variables on JavaScript are (essentially) pointers. A common mistake people make in the language is keeping references to objects in a global map, which prevents them from being garbage collected (often a bad caching implementation).

You can use things like WeakMap or WeakRef as one solution, but there are usually better options

Re:Swift is a more convenient Rust by pessimizer on Friday September 06, 2024 @09:21AM (#41465950)
> you can write entire Rust programs without once calling `free` manually.

If you mean "drop," it's just syntactic sugar for calling a trait that manually deallocates the memory and that you're free to reimplement.

It feels like people are equating "manual memory management" with "onerous memory management." People are usually going to want to do the boring thing with memory, and everything in the standard library by default does the boring thing with memory. If you write boring structs and enums, you'll derive boring memory management. But it's not part of the language, it's part of the library.

Re:Swift is a more convenient Rust by lolinder on Friday September 06, 2024 @09:29AM (#41466014)
> If you mean "drop," it's just syntactic sugar for calling a trait that manually deallocates the memory and that you're free to reimplement.

I meant `free` because I'm contrasting with C.

> It feels like people are equating "manual memory management" with "onerous memory management."

Manual memory management is onerous, but I'm very specifically talking about manual. If I can write a whole program without thinking about memory, the language does not require manual memory management. It may support it, but it doesn't require it the way that C or Zig do. You do not "have to explicitly manage memory" as OP claimed.

Re:Swift is a more convenient Rust by tialaramex on Friday September 06, 2024 @10:09AM (#41466382)
You can't call Drop::drop for type T at all. Try it if you don't believe me.

It would be unacceptable to allow this because Drop::drop says it only takes a mutable reference &mut T (and indeed it does) but now the thing is destroyed, so, that wasn't just a mutable reference at all!

You can call core::mem::drop<T> but well, look at it, here's the code:

pub fn drop<T>(_x: T) {}

Like, duh, we give it a T and then it doesn't give anything, the T is gone. That's not magic library code by the way, if we make our own:

pub fn vanish<T>(_x: T) {}

Now we can call our vanish function and the same happens.

So yeah, automatic memory management.

Re:Swift is a more convenient Rust by consteval on Friday September 06, 2024 @12:55PM (#41467779)
To be fair I don't think this is enough to say automatic memory management, otherwise C++ would be automatic memory management too (and maybe it is, just poorly implemented?)
Re:Swift is a more convenient Rust by tialaramex on Friday September 06, 2024 @01:08PM (#41467881)
Yes, C++ has automatic memory management.

As with the rest of the language, the automatic memory mangement requires that your program has no mistakes - which requires inhuman amounts of care during implementation and testing. So, that's obviously a spectacularly bad idea, but it's still automatic memory management.

Re:Swift is a more convenient Rust by kaba0 on Friday September 06, 2024 @07:03AM (#41464975)
Yeah, the correct statement would be ‘Rust is the first mainstream language without GC, that guarantees memory safety’ (with obviously the caveat of unsafe blocks, but than you can also sun.misc.unsafe yourself into segfault in java).
Re:Swift is a more convenient Rust by lucideer on Friday September 06, 2024 @08:09AM (#41465413)
> The age of Smalltalk is over. It's now the age of ML [...] The languages that dominated the 2000s (Ruby, Python, Javscript, PHP) were all more or less derived from Smalltalk [...] The new languages (Rust, Scala, Swift, Kotlin, etc.) are ML family languages.

What drew people to a lot of your examples (Javascript, PHP especially) was the runtimes rather than the language features. Your example sets aren't just demarcated by Smalltalk-ishness/ML-ness but more by runtime type (Scala & Kotlin are odd examples given the VM but for the most part your latter examples have build-time compilation while the former have plaintext interpreters).

We're definitely in a tools-heavy era of programming where, unless you're writing bash scripts, even very basic applications in interpreted languages are layered with a slew of transpilation/compilation/etc., but generally speaking I still don't see the majority of people moving wholesale away from plaintext runtime interpreters. Where are the ML-ish competitors in that space?

Re:Swift is a more convenient Rust by noelwelsh on Friday September 06, 2024 @09:29AM (#41466015)
Good point.

The nitpicky take: a lot of these languages come with a repl / console. E.g. the most recent version of Scala builds Scala CLI[1] into the language. You can run `scala repl` and just type code into it, or run `scala SomeFile.scala` and it will compile and run `SomeFile.scala`. There is special syntax for writing dependencies so that a single file can pull in the libraries it needs.

The 5head thought leader take: the traditional model for typed languages has two phases: compile time and run time. Types exist at compile time. This is inadequate for many applications, particularly interactive ones. E.g. a data scientist doesn't know the shape (type) of the data until it is loaded. It should be possible to infer the type from the data once it is loaded and make that type available to the rest of the program. We know how to do this (it's called staging) but it's just not available in the vast majority of languages. Staging, and metaprogramming in general, is perhaps the next great innovation in programming languages (which will take us from ML to Lisp).

In general, the challenge for these new languages is to reach "down" into the simpler scriptier applications, instead of the "serious" programming they are usually built for.

[1]: https://scala-cli.virtuslab.org/

Re:Swift is a more convenient Rust by tgv on Friday September 06, 2024 @06:52AM (#41464905)
Rust is not really an ML language, is it? &mut is a very noticeable difference. Calling Rust, Scala, Swift and Kotlin ML seems to be taking it too far. Scala and Kotlin even have all the traditional OOP features. You might just as well put C++ in the ML list.
Re:Swift is a more convenient Rust by tialaramex on Friday September 06, 2024 @07:57AM (#41465335)
It's not the Standard ML of New Jersey of course, like I was taught last century, but it looks like an ML to me. Rust has a sound type system, whereas a language like C++ inherits C's YOLO approach to typing.

In Rust Vec<Option<Infallible>> is just a counter. Really, that's not theory that'll just happen by default because of how type arithmetic works.

In C++ you can't even write down an equivalent type, let alone say how it would be represented, the type system blows up long before we get there.

Re:Swift is a more convenient Rust by wsabihi on Friday September 06, 2024 @11:48AM (#41467220)
I've looked for this optimisation, and while it makes sense to me (Infallible is unhabitable ==> s: Option<Infallible> can only exist if s = None ==> all values in vector must be of the same value None that is known ahead of time ==> store a counter of how many Nones are in the vector instead of each None as an entry into a traditional vec), I cannot find any trace of such optimisation, whether by reading into the bytes backing the vector (with rustc -O / -C opt-level=3 to ensure this opt is triggered), or by calling `mem::size_of::<Vec<Option<std::convert::Infallible>>>()`.
Re:Swift is a more convenient Rust by Measter on Friday September 06, 2024 @03:29PM (#41469010)
What's happening is that `Infallible` has no values, and cannot be instantiated. This results in `Option<Infallible>` only having one possible variant (None) which has no payload, and therefore being a zero-sized type.

Separately `Vec<T>`, if `T` is a zero-sized type, never allocates and has a capacity of usize::MAX. Then, when you push into the Vec, because the value you push is zero-sized, there's no allocation and no data to write anywhere. Therefore the only effect is to increment the length counter.

Re:Swift is a more convenient Rust by koverstreet on Friday September 06, 2024 @09:09AM (#41465841)
Could you elaborate? I would think Vec<Option<Infallible>> would have to be a bit vector.
Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @09:28AM (#41466006)
Infallible is a clunky name for the Never type in Rust, i.e. a type that has no values and cannot be instantiated. Thus, Option<Infallible> only has a single value, viz. None. Then Vec<Option<Infallible>> is isomorphic to Vec<()> which reduces to a length field - there's no other data associated with it.
Re:Swift is a more convenient Rust by jpc0 on Friday September 06, 2024 @07:52PM (#41470555)
Could you explain the semantics of Vec<Option<Infallible>>? What would exist in the memory pointed to by the Vec? What would be the use case for this type?
Re:Swift is a more convenient Rust by tialaramex on Saturday September 07, 2024 @06:25AM (#41472956)
The Vec itself carries four items, a unique pointer to T, a capacity, an Allocator A, and a current length. It is a generic type, generic over the type T and the allocator A.

1) lets dispense with the Allocator, for a typical Vec the global Allocator is used, so this type has no size, every Vec is talking about the same global Allocator, its state is tracked internally to itself. We need not consider this object further†

2) now lets dispense with that unique pointer. Its semantics are crucial if T had non zero size because this is why Rust knows the associated memory which is pointed to is "owned" by the Vec. However, for a zero size T this pointer is entirely unused.

3) Capacity at last actually is used, it's a machine word sized integer, so on a modern computer that's 64-bits, 8 bytes to store the capacity of the Vec, which will be the maximum possible unsigned integer of that kind, usize::MAX. It is set to this value when the Vec is created (because the size of T was zero) and never changes.

4) Length is also used, despite not needing to store any data for T the Vec is finite and this tracks how many of the zero size item are in the Vec. Thus, it's a counter.

† In C++ they use the "Empty Base Optimisation" to avoid needing space for such things, in Rust their size is just Zero and so they won't be stored.

What is the use case? Vec<T> is a generic type (Rust's generic growable array of T) so although Vec<Option<Infallible>> seems somewhat useless as a concrete type, it is likely to sometimes occur in generic code.

Example: generic code to do a bunch of potentially fallible operations and remember whether and how they failed for later summarisation may make a type Vec<Option<E>> where E is the failure type. When the operation wasn't actually fallible E is Infallible and instead of an actual growable array type we're just making a trivial counter, our summary is going to inevitably say that all N operations were successful, any code for the "List of failures" summary should even get trimmed as dead code in this case since it depends on an Infallible object and the compiler knows Infallible cannot exist.

Re:Swift is a more convenient Rust by jpc0 on Saturday September 07, 2024 @06:53AM (#41473108)
So from what I've played with Option<Infallible> in rust would be directly equivalent to std::nullopt_t and has similar semantics in vectors, ie it just increments length.

There seems to be slightly more compile time work done in Rust but using the use case you described the concept of a Vec<Option<Infallible>> can just as easily be represented as std::vector<std::nullopt_t> with very similar semantics although possibly slightly less optimisation, although I would think if it was actually used in the language extensively I would see library implementors makeing it entirely compile time just like in rust.

I don't disagree that algebraic data types are nice and that Rust has an interesting implementation of them, however this specific example doesn't seem unrepresentable in C++ using std::option and std::variant although the actual semantics relating to usage is easier in Rust.

Re:Swift is a more convenient Rust by Measter on Saturday September 07, 2024 @09:11AM (#41473748)
Bear in mind that the optimization on `Option<Infallible>` isn't specific to that type; it applies to anything that results in one possible value. For example, `Foo` in this example is also zero-sized:

    pub enum Foo {
        Foo,
        Bar(A),
        Baz(B),
        Qux(C),
    }

    pub enum A {}
    pub enum B {}
    pub enum C {}
The optimization applied to Vec also applies to any zero-sized type.
Re:Swift is a more convenient Rust by tialaramex on Saturday September 07, 2024 @07:59PM (#41477210)
How do you get to the idea that std::vector<std::nullopt_t> "just increments length" ?

I spent some time trying this out in Godbolt†, and then by hand, and then reading the Microsoft STL, and exactly as I'd assumed before I read your comment it was a growable array of one byte objects, with the type std::nullopt_t, 400 objects? 400 bytes. 4 million objects? 4 million bytes.

† Including longer than I'd like to admit forgetting that C++ silently copies large objects without telling you and so my diagnostic was actually making a new std::vector because I forgot to write an ampersand to make it a reference...

It is still possible I missed something and so I invite you to tell me what that was. But overall my thought is that you've missed the whole point and are in the same place as when C++ programmers get confused and think Empty types (like Infallible) and Zero Size Types (like Option<Infallible>) are somehow the same, which is like confusing zero (The additive identity) with one (the multiplicative identity).

Re:Swift is a more convenient Rust by pornel on Friday September 06, 2024 @08:00AM (#41465359)
Rust is its own thing, but use of algebraic data types + pattern matching and type inference makes it feel closer to OCaml than C++. The original Rust compiler has been written in OCaml, so that's definitely an influence.
Re:Swift is a more convenient Rust by lolinder on Friday September 06, 2024 @07:50AM (#41465289)
If &mut makes Rust not in the ML family then none of the languages they list are in the Smalltalk family either—there's no concept of an image, everything is in files!

It's pretty clear that we're talking about very broad families, which is okay—Rust has more in common with ML than it does with Smalltalk or ALGOL (though the ALGOL heritage is definitely present).

Re:Swift is a more convenient Rust by foldr on Friday September 06, 2024 @07:41AM (#41465219)
ML has mutable references:

https://saityi.github.io/sml-tour/tour/02-09-mutable-refs.ht...

(OCaml has something similar too.)

Re:Swift is a more convenient Rust by pjmlp on Saturday September 07, 2024 @05:03AM (#41472595)
O in OCaml is for Objective aka Objects, and ML languages do support mutable types, aka ref cells.
Re:Swift is a more convenient Rust by hyperbrainer on Friday September 06, 2024 @10:33AM (#41466602)
About the time travel to past aspect, I wonder if we will have an age of lisp now? I know Lisp is very popular in some niches(zB Emacs), but I really want to see innovations in syntax from the current standard of too many brackets. (M-expressions?)
Re:Swift is a more convenient Rust by hollerith on Friday September 06, 2024 @11:06AM (#41466877)
You seem to assert that OCaml doesn't use a run-time garbage collector:

>Rust is the first language to bring non-GC automatic memory management to the mainstream. . . . Other languages in this space include . . . OCaml[1]

But your own link[1] says,

>The OCaml compiler does not statically track lifetimes. Instead, it relies on a garbage collector to figure out a suitable lifespan for each value at runtime. Values are collected only after they become unreferenced, so OCaml programs are memory-safe. To a first approximation, this model requires allocating all values on the heap. Fortunately, OCaml’s generational GC can efficiently handle . . .

Scala does run-time garbage collecting, too (or rather the JVM does, which Scala depends on at run-time) unless I'm very much mistaken.

Re:Swift is a more convenient Rust by the_duke on Friday September 06, 2024 @06:17AM (#41464683)
Ad 3)

Scala is quite a bit older than the others, I'd put it in a previous generation.

I always saw Kotlin as a more convenient Java, without Scalas heavy tilt towards FP.

Java also added the equivalent of sum types with sealed interfaces and exhaustive pattern matching, does that make Java an ML language?

Many older languages by now have incorporated valuable parts of FP/ML (including Javascript, Java, C++, ...)

Borrowing some concepts from ML doesn't put these languages in the ML family.

Re:Swift is a more convenient Rust by valenterry on Friday September 06, 2024 @06:40AM (#41464836)
OCaml is older than Scala though.

> Java also added the equivalent of sum types with sealed interfaces and exhaustive pattern matching, does that make Java an ML language?

I don't think so. Java heavily relies on mutation and you can see this throughout the whole ecosystem and even the JVM whereas OCaml doesn't. Kotlin also relies on mutation (it relies on Java's stdlib after all) whereas Scala has its own stdlib with both mutable and immutable classes but defaulting to immutability almost everywhere.

So if anything, Scala can be called an ML language imho.

Re:Swift is a more convenient Rust by SSLy on Friday September 06, 2024 @06:33AM (#41464782)
> does that make Java an ML language?

not really, the type-system-sublanguage is still modelled like classy OOP, not more like MLy modules.

Re:Swift is a more convenient Rust by nextaccountic on Friday September 06, 2024 @06:42AM (#41464845)
But Kotlin is like this too.
Re:Swift is a more convenient Rust by SSLy on Friday September 06, 2024 @06:52AM (#41464904)
Indeed, and Scala (at least the version I've tried 10 years ago) tries to do both, somewhat poorly. shrug
Re:Swift is a more convenient Rust by valenterry on Friday September 06, 2024 @07:01AM (#41464957)
Personally I found Scala's module/import system to be really really good. There are some annoying things with it, but they mostly come from JVM/Java compatibility.
Re:Swift is a more convenient Rust by SSLy on Friday September 06, 2024 @07:10AM (#41465016)
Yeah, it's the compat that I vaguely recall being kludgy.
Re:Swift is a more convenient Rust by dgellow on Friday September 06, 2024 @06:26AM (#41464742)
Swift does have garbage collection via reference counting
Re:Swift is a more convenient Rust by zerr on Friday September 06, 2024 @09:21AM (#41465951)
Yes, usually GC vs non-GC discussion is actually about deterministic vs non-deterministic memory management. Swift's ref-counting is deterministic.
Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @06:31AM (#41464771)
I think if Linear/Affine typing was a default anyone wanted, Haskell hackers (who are usually pretty concerned with performance) would regard it as more than a research oddity.

When people bitch about the borrow checker, what they usually mean is “std::move is a great wristwatch but god damn does it chafe as a chastity belt”.

Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @06:44AM (#41464855)
The whole point of Haskell as a programming language is to have lazy evaluation be the default. This comes with boxing data objects everywhere, which is the opposite of a focus on low-level performance. Haskell does support using strict, unboxed data but it's clunky and not the default. (Also, recent versions of Rust have now added support for "plug-in" laziness via the type constructors LazyCell<> and LazyLock<>.)
Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @06:50AM (#41464889)
I’m aware of how boxing works in GHC, I learned it from Simon Marlowe.

I don’t mean to be obtuse but I don’t see what that has to do with linear typing as a fucking weird mandatory default?

Re:Swift is a more convenient Rust by the_duke on Friday September 06, 2024 @07:12AM (#41465030)
Why should every language occupy the same design space?

Rust was shaped by Mozilla wanting a language to replace parts of Firefox with. A language that is low-level enough to give very high performance, enforces correctness through the type system, and yet has many abstractions so it feels modern and convenient to use.

Rust doesn't have any automatic allocations. You can wrap every type in `Arc<Mutex<T>>` and treat it like a very verbose Python, but that's the programmers choice.

The design decisions have been validated by the success of Rust in certain domains.

There is a reason why more than one programming language exists...

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @07:18AM (#41465057)
I think Rust is cool!

If it wasn’t actively seeking world domination I’d be like, cool let’s use that sometimes.

Rust is so hell bent on a Rust monoculture ranging from stuff like TRACTOR to actively opposing interop that a few of us who know our shit have to be like “easy now” once in a while.

I’m trying to decide between tiktoken and sentencepiece for a new vocabulary at the moment, and it would be easier in some ways to go with tiktoken.

But I want it to run faster than a fart at inference time, which means I’m linking libtorch, which means I’m writing C++.

And fuck, link to Rust from C++? Let’s take another look at the Google stuff.

Re:Swift is a more convenient Rust by tialaramex on Friday September 06, 2024 @08:13AM (#41465443)
> If it wasn’t actively seeking world domination I’d be like, cool let’s use that sometimes.

Hylo specifically says it intends "world domination" (next year in fact, having apparently completed all the delayed 2023 goals and also all its 2024 goals this year, I guess maybe they're going to do it all in December?)

But I don't really see this from Rust. I'm sure Hylo's "world domination" is a joke, but, so is the "Rust Evangelism Strike Force". Rust people I've interacted with strike me as very much more accepting of the "better tool" theory than of some weird cult or panacea. When somebody in a Rust forum says (e.g. about JPEG XL) "Ooh we should use Rust" and I say "No, WUFFS. This problem is what WUFFS is for" the responses tend to be a mix of "Yeah, I guess" and "I didn't know that existed. Thanks for the link" rather than cultist denial.

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @08:24AM (#41465514)
Haha we’ve tangled before and in my experience when the Rust evangelism strike force is on the case discretion is the better part of valor.

I admire both the technical sophistication and passion you folks bring to the table, the one true language thing just isn’t my bag. I pine for the Halcyon days when HN was run by the Rust people rather than the LLM idiots.

Keep doing what you’re doing, one hacker to another.

Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @07:36AM (#41465178)
> to actively opposing interop

Rust just uses the C ABI for interop (including interop with Rust code that might not be part of the same build, such as dynamically-linked program objects). So you just have to come up with a plain C API for the interface and write wrappers on both sides of the divide that reference the C API. There are crates that will help with this, even achieving something like a "stable ABI" for Rust interop.

(And we'll probably see some work into interop with Swift itself (which has a stable ABI of its own) once there's enough interest in that as a memory safe language.)

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @07:53AM (#41465307)
It’s doable!

But bindgen/cbindgen/cxx/etc exist for a reason: it hurts like a root canal.

In my particular case, tiktoken is substantially like 600 lines of Rust. If I have a deadline do I fuck with the linker or just write it again? I’m marshaling std::string here, fuck let’s just write it.

What I’m not going to re-write because I’m not a magnificent maniac like geohotz? I’m not going to rewrite libtorch. Which is written in C++ like all the software you can’t really live without.

Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @07:00AM (#41464950)
I'm not sure what's supposed to be especially weird about linear typing (or rather, uniqueness typing which is what Rust ultimately relies on). If you want to see the use of such types in a language that's clearly even less "convenient" and more principled than Rust, you can look at Austral https://austral-lang.org/
Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @07:04AM (#41464981)
I think I’m going to be a hard pass on a language more militant about BDSM type system level memory management than Rust.
Re:Swift is a more convenient Rust by farmeroy on Friday September 06, 2024 @02:57PM (#41468789)
Is their code linter called whippy?
Re:Swift is a more convenient Rust by bananapub on Friday September 06, 2024 @06:51AM (#41464893)
perhaps a dumb question, but why does laziness imply boxing? or does 'boxing' in haskell mean something other than 'embed a simple bit of data in a fancy thing on the heap'?
Re:Swift is a more convenient Rust by throwaway17_17 on Friday September 06, 2024 @09:14AM (#41465897)
I seem to be missing the implication as well. I am under the impression that Haskell relies on boxed values primarily due to its parametric polymorphism. There is a Simon Peyton Jones talk somewhere discussing the acrobatic GHC requires for the type theory to deal with unboxed types and their implicit requirement for an alternative Kind at the type level.

The laziness as a default just makes boxing closure values a sensible default, when the type system requires the boxing of everything in general.

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @10:51AM (#41466758)
On everything from the JVM to GHC to v8 there is a critical distinction between the semantics of a boxed type and the practical outcome on the gear. Every managed language runtime done by pros (and those all are, I should have said the CLR too) will quietly unbox in all the easy cases and some of the hard ones.

Parametric polymorphism is kind of orthogonal to that. It’s related I guess. It can involve some kind of runtime dispatch, but usually that gets JITed or inlined or whatever unless you really insult the compiler.

And even full frontal invokedynamic it’s still like, is it in the BTB and the I-cache? Ok well we’re still doing business.

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @06:54AM (#41464920)
A dramatic over-simplification is that a lazy value referenced by some continuation/thunk is hard to stack allocate in-situ.

Now GHC does stack allocate, but it’s hard to count on without really aggressive hinting.

Re:Swift is a more convenient Rust by the_duke on Friday September 06, 2024 @07:19AM (#41465066)
Funnily enough Rust supports exactly that pretty well with async.

An `async {}` block is not evaluated, but converted into a generator/state machine that lives on the stack, and that has to be advanced by calling a poll method. You can move it to the heap , but that does not happen automatically.

Sharing of values is obviously much more awkward due to mutability and no automatic cloning though.

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @07:32AM (#41465149)
I know how it works though I remain unconvinced that rustc is dealing with the same scope of problem as GHC in the general case.

But to be clear, anyone with the username the_duke is probably really cool, and you clearly know your stuff as well as having style, so count me as a fan.

Re:Swift is a more convenient Rust by bananapub on Friday September 06, 2024 @07:33AM (#41465159)
ah, right, laziness can cause the control flow to become extremely complicated - makes sense, thanks!
Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @07:44AM (#41465237)
Also true! And in very real sense literally what I meant.

But not so much in the conditional branch sense of the phrase “control flow”.

More like, I’ve got a bunch of references and one of them is a reference to a function I might evaluate, damn, I need that reference and the transitive closure of everything it knows about, all of which are probably on the heap.

Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @07:55AM (#41465319)
The proper name for this is a "space leak". Also known as: "you wanted a banana, but what you got was a gorilla holding the banana and the entire jungle". This is of course pretty much the opposite of low-level "performance" - and it's also the kind of problem that tracing garbage collection was actually designed to address when first developed.
Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @08:10AM (#41465416)
Fake news and FUD and other balderdash.

A space leak, much like any memory leak is when you or the compiler or the runtime or whoever misplaces such reference.

GHC having a closure in scope in no way immediately means there is a space leak. Plenty of Haskell code that compiles to thunks will run all day in an amortized fixed-size heap.

Much like Erlang, which is what Joe Armstrong had designed before he said the thing about jungles you’ve quoted.

And it is in no way difficult or even really rare to drop an Arc in a table and leak all over the place.

Rust has all the same computer science problems as anything else. Full stop.

Re:Swift is a more convenient Rust by mananaysiempre on Friday September 06, 2024 @06:38AM (#41464819)
GHC Haskell is a fairly large language with a considerable legacy already, so integrating linear or affine types into it may well be a very different question from making a language centered around them. That language exists in the form of Clean[1,2]. Admittedly it’s not really well-known.

[1] https://clean.cs.ru.nl/

[2] https://clean-lang.org/

Re:Swift is a more convenient Rust by benreesman on Friday September 06, 2024 @06:46AM (#41464867)
Thank you for making me aware of Clean, on quick glance it looks cool.

I like a lot of things about Rust: it’s got compiler checked exhaustive pattern match and a good initialization syntax and Either baked in and fucking correct package management and a ton of other things.

I’ll look at Clean to see if linear-only memory management can be done gracefully. Rust is a lot of cool things but not the language that demonstrated that.

Re:Swift is a more convenient Rust by MarcusE1W on Friday September 06, 2024 @09:53AM (#41466222)
There is also Austral, which has linear types as a main capability: https://austral-lang.org/
Re:Swift is a more convenient Rust by IsTom on Friday September 06, 2024 @07:56AM (#41465328)
> (Ruby, Python, Javscript, PHP) were all more or less derived from Smalltalk

I'd argue that Erlang (with gen_servers being "objects") has more in common with Smalltalk than these.

Re:Swift is a more convenient Rust by alex_smart on Friday September 06, 2024 @07:22AM (#41465087)
> The languages that dominated the 2000s (Ruby, Python, Javscript, PHP) were all more or less derived from Smalltalk

One of these is not like the others. Javascript derives from Lisp (first-class functions, lambdas, closures), not Smalltalk.

Re:Swift is a more convenient Rust by robertkrahn01 on Friday September 06, 2024 @07:28AM (#41465129)
Brendan Eich used both Scheme and Self as inspirations. Self is a dialect of Smalltalk.

https://en.wikipedia.org/wiki/Brendan_Eich

Re:Swift is a more convenient Rust by pessimizer on Friday September 06, 2024 @09:27AM (#41465998)
Did you link his biography? The claim is that he used Self as an inspiration, not that there was once a man named Brendan Eich.
Re:Swift is a more convenient Rust by astrobe_ on Friday September 06, 2024 @07:35AM (#41465169)
More than features, JS derives from Lisp because its author was a Scheme implementor. Otherwise function pointers are trivially done even in assembly language, and Smalltalk does have closures.

Or maybe you think of the fact that JS uses prototype-based OOP, which makes it closer to what one would do with Scheme (something inspired from CLOS I guess) than Smalltalk ?

Re:Swift is a more convenient Rust by pjmlp on Saturday September 07, 2024 @05:08AM (#41472621)
Prototype-based OOP came first in SELF, a Smalltalk dialect.

CLOS is an evolution from Flavors and similar Lisp packages, and outside Lisp, Julia would be the closest to it, in modern times, not counting Dylan.

Re:Swift is a more convenient Rust by lispm on Saturday September 07, 2024 @08:18AM (#41473498)
> Prototype-based OOP came first in SELF

Isn't prototype-based OOP roughly a decade older? -> for example "Director" from Ken Kahn is from 1976.

Re:Swift is a more convenient Rust by pjmlp on Sunday September 08, 2024 @02:57AM (#41478688)
Maybe, I never heard of "Director", its documentation seems hard to come by in digital world.

Although Wikipedia also points out that, https://en.wikipedia.org/wiki/Prototype-based_programming

Actually your remark has made me dive into alternative prototype based languages.

Re:Swift is a more convenient Rust by lispm on Sunday September 08, 2024 @05:39AM (#41479293)
Check the resume of Ken Kahn: http://toontalk.com/resume.pdf

Director Guide: https://dspace.mit.edu/bitstream/handle/1721.1/6302/AIM-482b...

Creation of Computer Animation from Story Descriptions: https://dspace.mit.edu/bitstream/handle/1721.1/16012/0720063...

The other mentioned tool was Thinglab, by Alan Borning

https://www.ijcai.org/Proceedings/77-1/Papers/085.pdf

"The Smalltalk notion of an object has been modified and extended in a number of ways. In ThingLab, objects are constructed interactively by editing and making descendants of prototypes. An abstraction hierarchy is used that allows arbitrarily many levels of both parents and descendants, with the problem of objects with several parents being handled by the technique of merging. There is no distinction between classes and instances."

"The Programming Language Aspects of ThingLab, a Constraint-Oriented Simulation Laboratory" https://dl.acm.org/doi/pdf/10.1145/357146.357147

"CLASSES VERSUS PROTOTYPES IN OBJECT-ORIENTED LANGUAGES" https://dl.acm.org/doi/pdf/10.5555/324493.324538

Available in the Browser, running in Smalltalk: https://constraints.cs.washington.edu/thinglab/

Re:Swift is a more convenient Rust by pjmlp on Sunday September 08, 2024 @06:09AM (#41479441)
Thanks for the overview.
Re:Swift is a more convenient Rust by panzi on Friday September 06, 2024 @07:28AM (#41465125)
Python has those too, although with less convenient syntax (multiline functions (closures) can only be at statement locations).
Re:Swift is a more convenient Rust by alex_smart on Saturday September 07, 2024 @12:00AM (#41471351)
Sure, but use of those patterns is not idiomatic in Python.
Re:Swift is a more convenient Rust by timeon on Friday September 06, 2024 @06:32AM (#41464780)
> These alternatives take the approach that tracking ownership is not the default, which is fine for the majority of programs and far more ergonomic.

If you want non-default safety you do not need to leave C++. That is why unlike all these new languages, Rust makes difference.

Re:Swift is a more convenient Rust by zozbot234 on Friday September 06, 2024 @07:09AM (#41465011)
Swift 6 is expected to be memory safe, including for concurrent programs. That's a lot more than you can say about C/C++. (This is achieved by tracking ownership at runtime when required. Rust allows for this via library types such as Rc<> and RefCell<>, which is more principled but obviously adds some boilerplate compared to Swift.)