Adding to what others said, I also think that lack of dynamism and the syntax/semantics are reasons why other languages don’t have a REPL.
For a REPL to be useful, it can’t simply execute new code and show you the result. You also need to be able to inspect existing code, and modify existing code to do something else. That’s what I call dynamism. If we take Java for example, adding a method to an existing class at runtime isn’t possible, that’s already a huge barrier to making the Repl useful, since that would be one of the first things you’d want to do when using REPL driven development, you’d want to run the program and slowly modify and add to it’s behavior as it is running, and if you don’t have that level of dynamism available in your language/runtime to do so, then it’s kind of useless to have a REPL, and that’s when I’d call it a simple shell or command line instead.
I mentioned inspecting code already, but let me give an example here as well, you really want the REPL to auto-complete and show you the doc for various functions and global vars, that’s basic introspection, but it means the runtime must have first class doc-string and keep them around along the functions and the global vars, which again, isn’t something all languages do, like in Java, you need access to source files and you have to parse them to get the comment block above the corresponding methods to retrieve their doc, so it’s missing basic REPL introspection. Without that, again, a REPL is much less useful.
Finally, I believe syntax and semantics is a big one as well. The Lisp syntax makes it so every chunk of executable code is nicely bounded so it is easy to select and send to the REPL for evaluation, you don’t have to highlight or do anything else, just form under cursor, or form before cursor and you can send it to the REPL, that’s really nice ergonomics right there. Especially combined with the quick navigation it gives you, moving to the previous or next form, moving up to the parent form or down to child form, its all super quick and easy to navigate. And then the scoping rules, which itself is form bound, and not like at the class or the method level only, so if you want to evaluate a part of a function on its own, you can do that and capture some of the locals within it.
I think those things is what really makes the REPL driven development useful and productive, so the language needs to support these in some fashion.