> A quick Google search tells me the "top 20" includes Python, JavaScript, Java, C#, C, Go, Swift, PHP possibly Ruby/Perl/Kotlin/etc. I can't think of a single one that doesn't have either first-class functions or some form of closures.

Most of them don't have all of these features together and they often have incredibly bad versions of those features that are basically unusable.

> This is an optimization issue for most languages, and they have made the trade-off of keeping a stack trace vs. optimizing it away. Having it in the Scheme spec was incredibly contentious and caused many heated debates.

The JS stack already goes away the second you do anything asynchronous. As this is something you do frequently, stack traces are already incredibly short.

Meanwhile, the alternative for the use cases of PTC is loops and I don't hear complaints that loops don't save your state.

It's in the spec, it should be implemented.

As to Scheme, you won't find anyone today arguing that PTC is bad. The bigger argument would be about how full continuations are a performance disaster.

> I think this really depends on what you mean "ergonomically."

Infix macro systems are terrible to use compared to S-expr macros and I don't think this is anywhere close to controversial. Can you point to a counter-example?

The best infix example I know of is Dylan, but not only is that language barely infix (its S-expr foundations are very apparent) and they still just aren't as easy to use.

> ehhhh. No. And I say this as someone that generally prefers dynamic over static typing. You can easily have objects in your REPL that were the result of previous bugs and get your app in an inconsistent state. You either reload, or spend your entire life cleaning up memory and hoping you get it right. There is no silver bullet here, despite what others have commented on. Because you're talking about schema migrations here. Bad data structures have to be transformed to good data structures. Or you'll see bugs in the REPL that aren't actually bugs in the source. Keeping the REPL and source in sync is also tedious, to put it mildly.

How does this entire bit have anything to do with dynamic vs static typing? You could have a REPL with static typing if you truly wanted.

In any case, reloading data from the code isn't that difficult and most data will be held in closures which means you can decide exactly how far up you want to replace local data (and if you're going about it smartly, you have created a few "mocks" to work with that can be used to refresh data).

The absolute worst case (restarting the REPL) is what other languages would force you to do anyway which still means you have a lot to gain for most development and bugfixing and absolutely nothing to lose.

As to data is held in a database, then you have all the same problems in other languages except that fixing these issues from the REPL is generally easier because you are already connected and ready to start fixing things.

> Look into Erlang does and what is required to get live code swapping correct.

BEAM is an amazing platform, but a REPL for development and live code swapping are two different discussions. Doing REPL work on production systems has a very big chance of catastrophic damage and I wouldn't recommend it.