News for hackers. Stuff that matters.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by Waterluvian on Wednesday March 11, 2026 @12:32PM (#47337774)
The worst are methods that both mutate and return values.

I know this gets into a complex land of computer science that I don’t understand well, but I wish I could define in TypeScript “any object passed into this function is now typed _never_. You’ve destroyed it and can’t use it after this.” Because I sometimes want to mutate something in a function and return it for convenience and performance reasons, but I want you to have to reason about the returned type and never again touch the original type, even if they are the same object.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by thayne on Wednesday March 11, 2026 @02:14PM (#47339137)
> any object passed into this function is now typed _never_. You’ve destroyed it and can’t use it after this.

That is basically what affine types are. Once the value is "consumed" it can't be used again.

In rust, this is expressed as passing an "owned" value to a function. Once you pass ownership, you can't use that value anymore.

And having used it in rust, I wish more languages had something like that.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by kibwen on Wednesday March 11, 2026 @02:47PM (#47339556)
> And having used it in rust, I wish more languages had something like that.

Same. I'm at the point where I feel like copy-by-default semantics are one of the ancient original sins of programming languages. Single-ownership is so, so useful, and it's trivial to implement and not at all difficult to understand (especially compared to something like Rust's borrow checker).

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by Aurornis on Wednesday March 11, 2026 @01:19PM (#47338399)
> but I wish I could define in TypeScript “any object passed into this function is now typed _never_.

Having explicit language to differentiate between pass by reference and pass by value avoids this confusion. It requires a little more thought from the programmer but it’s really minimal once you internalize it.

Rust takes this a step further with an explicit ownership and borrowing model. The compiler will refuse your code if you try to write something that that violates the borrow checker. This is endlessly frustrating to beginners but after adapting your mind to ownership safety you find yourself thinking in the same way in other languages.

I always found real-world JavaScript codebases frustrating because there was so much sharing that wasn’t entirely intentionally. It only got fixed when someone recognized a bug as a result.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by Waterluvian on Wednesday March 11, 2026 @01:21PM (#47338426)
Yeah exactly. That's what I've loved about Rust and hated about real-world JS. I end up having to reason about an entire case that might not be real at all: does this function mutate what I'm passing it? Should I eagerly deep copy my object? UGH.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by stephbook on Wednesday March 11, 2026 @01:44PM (#47338747)
Just call "Object.freeze()" before "return" in your function.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by cdmckay on Wednesday March 11, 2026 @03:21PM (#47339974)
That only goes one level deep so it’s not much of a guarantee
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by vimwizard on Wednesday March 11, 2026 @12:48PM (#47337985)
Rust ownership model ("stacked borrows" I believe it's called) is basically this
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by kibwen on Wednesday March 11, 2026 @02:49PM (#47339576)
Single-ownership ("affine types") is a separate concept from a borrow checker. Your language doesn't need a borrow checker (or references at all) to benefit from single-ownership, though it may make some patterns more convenient or efficient.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by ChadNauseam on Wednesday March 11, 2026 @03:38PM (#47340213)
rust would be pretty unusable without references. affine lambda calculus isn’t even turing complete. however, you’re right that a borrow checker is unnecessary, as uniqueness types (the technical term for types that guarantee single ownership) are implemented in clean and idris without a borrow checker. the borrow checker mainly exists because it dramatically increases the number of valid programs.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by kibwen on Wednesday March 11, 2026 @06:13PM (#47342890)
Supporting single-ownership in a language doesn't mean you can't have opt-in copyability and/or multiple-ownership. This is how Rust already works, and is independent of the borrow checker.

If we consider a Rust-like language without the borrow checker, it's obviously still Turing-complete. For functions that take references as parameters, instead you would simply pass ownership of the value back to the caller as part of the return value. And for structs that hold references, you would instead have them hold reference-counted handles. The former case is merely less convenient, and the latter case is merely less efficient.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by NooneAtAll3 on Wednesday March 11, 2026 @01:36PM (#47338635)
I think it's the other way around - he's projecting rust as what he wants
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by LoganDark on Wednesday March 11, 2026 @01:31PM (#47338570)
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by magnio on Wednesday March 11, 2026 @12:46PM (#47337966)
What you are describing is linear (or affine) types in academic parlance, where a value must be used exactly (or at most) once, e.g., being passed to a function or having a method invoked, after which the old value is destroyed and not accessible. Most common examples are prolly move semantics in C++ and Rust.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by z3t4 on Wednesday March 11, 2026 @03:44PM (#47340285)
If you want to upset people on the internet tell them that JavaScript is strongly typed, immutable, and everything is passed by value. Which is true. You can change member values though, which is the footgun.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by ecshafer on Wednesday March 11, 2026 @12:40PM (#47337866)
ruby has the convention of ! for dangerous destructive or mutating methods. This is something that I wish would spread around a bit.

For example:

# Original array

array = [1, 2, 3]

# Using map (non-destructive)

new_array = array.map { |x| x * 2 }

# new_array is [2, 4, 6]

# array is still [1, 2, 3] (unchanged)

# Using map! (destructive)

array.map! { |x| x * 2 }

# array is now [2, 4, 6] (modified in-place)

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by wiseowise on Wednesday March 11, 2026 @12:44PM (#47337942)
> convention

Is the keyword. Anything that should never be broken isn’t a convention. There’s no better convention than compiler error.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by goatlover on Wednesday March 11, 2026 @01:10PM (#47338281)
Because Ruby is a dynamic language which mutates state. That isn't considered wrong or bad in those kinds of languages, just a way to make sure the programmer knows they're doing that. Not every PL tries to live up to the ideals of Haskell.

If you don't want an object mutated in Ruby, you can freeze it.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by idle_zealot on Wednesday March 11, 2026 @01:44PM (#47338740)
I don't think they're saying it shouldn't be possible to mutate arguments, just that the ! convention should be enforced. The Ruby runtime could, for instance, automatically freeze all arguments to a function that doesn't end with a !. That way all code that correctly follows the mutation naming convention will continue to work, and any development who doesn't know about it will quickly learn when they try to mutate an argument and get an error. Ideally a helpful error telling them to add the !.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by xp84 on Wednesday March 11, 2026 @02:31PM (#47339356)
That's really interesting. Although my worry is the freezing having bad effects down the line after the function returns.

  a = [1, 2]
  
  def check_this(arr)
    raise "doesn't start with 1" unless a.first == 1
  end

  check_this(a)
  
  a << 3 # Raises "FrozenError (can't modify frozen Array)" because check_this froze `a`
Now, if you could temporarily freeze, and then unfreeze only the ones you froze, that could be really cool.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by idle_zealot on Wednesday March 11, 2026 @04:35PM (#47341214)
> Now, if you could temporarily freeze, and then unfreeze only the ones you froze, that could be really cool.

Is that a missing feature in Ruby? You can't have a frozen reference to an object while retaining unfrozen ones in another scope? That's too bad.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by xp84 on Wednesday March 11, 2026 @07:43PM (#47344149)
Yeah, in my testing freeze mutates the object itself to a permanent frozen state.
Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by Xenoamorphous on Wednesday March 11, 2026 @02:04PM (#47338999)
> The worst are methods that both mutate and return values

Been bitten a few times by Array.sort().

Luckily there’s Array.toSorted() now.

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by darick on Wednesday March 11, 2026 @01:09PM (#47338269)
This is possible with the asserts x is y pattern no?

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAYg9nKBe...

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by Waterluvian on Wednesday March 11, 2026 @01:16PM (#47338368)
I think the sticking points are:

1. You cannot return anything (say an immutable result that has consumed the input)

Okay, so don't return anything, just mutate the original. Except:

2. You cannot mutate the original, return nothing, but the mutated original isn't a subset of the original. For example: https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABB...

Re:Temporal: The 9-Year Journey to Fix Time in JavaScript by darick on Wednesday March 11, 2026 @01:41PM (#47338694)
Hmm, I see, yes it's quite limited.