Hacker News new | ask | show | jobs
by hamandcheese 3217 days ago
There's a lot of excitement about compiled languages lately, and many seem to wonder if interpreted languages are dying. Unfortunately I don't see the value of a good REPL brought up in those conversations very often.
6 comments

I don't think there's anything fundamental about a compiled language that prevents it from having a REPL. (If anything, you could always have a dedicated interpreter for interactive work—"compiled" and "interpreted" are functions of the implementation, no the language.)

In practice the compiled languages I've used extensively (OCaml and Haskell) do have REPLs, but ones that aren't nearly as powerful as some other languages. I'm not sure exactly why it's the case, but I certainly don't think it's impossible for them to have good REPLs. My guess is that there are some properties of the languages that make a good REPL a bit more difficult to implement, and there simply hasn't been enough community investment to overcome that.

I wish there was because I basically live in GHCi (Haskell's REPL) and sorely wish for a few core improvements like hot loading updated code when possible.

> If anything, you could always have a dedicated interpreter for interactive work

CMUCL does that. There's an interpreter that's used for the REPL and optionally for loading files on the fly, and an optimizing AOT compiler.

SBCL drops the interpreter and just runs the compiler with settings that make it reasonably fast for interactive use as I recall. Clojure, too just uses the compiler interactively and not a separate interpreter.

I wonder how do that. I'm building a language that truly will benefit for a REPL (is for database development) but also do it compiled simplified other things.

Is done on .NET/F#. I wonder how architect the thing so I can have a good repl yet compiled... but how?

Since more than a few language implementations already do things like that, I'm inclined to say that's more or less a solved problem.
Yeah, but I have not find a resource that explain how is done.
I think is probably an RTFS sort of topic, as there may not be a manual.
I hope jetbrain will do something magic on repl
I think the compiled language analog of a REPL is something like LINQPad for C# where you code in the top pane, highlight a snippet to execute, and get the results in the bottom pane. Combined with the more functional-style language features it's very conducive to layering on complexity and analyzing code where you can execute inner layers to see what they do.
Although LINQpad is awesome, the newer versions of Visual Studio have a C# REPL built in -- (https://github.com/dotnet/roslyn/wiki/C%23-Interactive-Walkt...)
I like a good interpreted language as much as the next guy, but there are REPLs for compiled languages. Pretty sure Scala has one and maybe Haskell
Haskell has one - called GHCi. By these criteria:

1) You can define new functions (and values, and types, type classes, instances, etc). You can "redefine" these things only insofar as you can shadow them.

2) I'm not sure whether they mean the ability to persist your state to disk and restore it (which GHCi lacks), the ability to refer to previous results (in GHCi, the previous result is called `it`), or just the ability to bind variables (of course you can do this in GHCi).

3) Usually "Show" instances are meant to be embeddable in code. Sometimes they need a little massaging. Sometimes they're just broken, from this POV. Sometimes they're just broken, period. But it holds for a lot of values.

4) You can run GHCi in the context of your project (see cabal repl and stack repl commands).

5) GHCi very much fails at this - no way to add anything to a module, so far as I'm aware.

6) GHCi more-or-less lacks this kind of functionality. You could run your server's "main" function from the REPL, but there's not much you can do to it.

7) :reload

8) There's an increasing amount of such tooling; only some of it has any particular tie to the REPL, per se.

Yes for (3)! I just plainly hate data types whose Show instances aren't just Haskell syntax. They usually try to add some pretty printing but that just ends such hurting copy-pasting from the REPL to the editor.
Though, they are lacking the magic of a REPL in CL. Hotspot replacement in JVM languages is neat compared to the magic of redefinitions in CL.

And it seems nobody ever tries hooking a REPL up to a running system anymore.

Some of us still do in Clojure land for run-time debugging, though skipping the crazy state mutation stuff I've seen in eg CL.
Java 9 is also bringing one.
I'm curious what makes this superior to Beanshell. Or any other style of REPL that you could do on the JVM.

Not against the idea, per se, but it seems hardly new ground. And unlikely to be nearly as powerful as a REPL in CL. (Though, again, few things are. Not sure that any are, to be honest.)

Well, Beanshell is dead, last update was on 2005.

Then there is a big advantage on having it as standard tool, instead of something done by third parties.

My question in that vein is more of "why will this succeed, where beanshell failed?"

That is, I had REPL style environments for java a long time ago. And literally nobody used it. I can see arguments for having the REPL being in actual Java instead of a shell subset. But, Java has a long way to go from bootstrapping something in a repl and automatically saving it to something that will work as a normal entry point. (Though, again, even JRebel has existed for a long time now.)

Julia has had a good REPL since its inception, (along with the awesome Jupyter notebooks). It also allows live code replacement (eg. Revise.jl).
The language used as an example in the article (and one that fulfills its criteria for a good REPL) is Clojure - which is compiled.
Java is getting one with the upcoming Java 9 release.
I doubt many programmers already using Jython, Beanshell, Apache Groovy, Xtend, Rhino, or Nashorn will change to the Java 9 JShell. I switched from Groovy to Clojure for scripty stuff a few years ago, mainly for the macros. A well-placed macro can avoid a lot of clutter in repetitive testing -- a far better solution than some heavy-weight testing framework.
Scala's REPL is fine. It has a useful paste mode as well.
C# and F# do too.
They aren't really REPLs. A REPL isn't just a prompt that you can put code into.
REPL stands for read-eval-print loop. So yes, it is just a prompt that you can put code into that will print a result.
If you want to be literal about it then sure, it just means read-eval-print loop. But I think that's akin to saying that a functional programming language is a language that has functions in it.

EDIT: To be clear, what I'm saying is that when people say 'I really love using Common Lisp because it has a REPL' they aren't saying 'I really love using Common Lisp because it has a prompt I can write raw strings of code into that executes that code and has no other features'. That's not a lovable feature.

People love Lisp REPLs because there's much more to them than that. In Lisp, the REPL is more like GDB than it is like Python's REPL.

Not really sure why the reaction to my comments here is so viscerally negative. Very few terms that we use are wholly literal. REPL isn't literal either.

Sorry if my comment with the definition of REPL seemed "viscerally negative". I understand that a good REPL has more features that just the bare bones, but you said that programs that read an input, evaluated it, and then printed the result aren't REPLs. You should've said that they aren't good or useful REPLs.

Your argument is the equivalent of saying notepad isn't a text editor because you can't edit multiple lines at once or highlight syntax. Those are features that good text editors have, but it does not mean notepad is not a text editor.

They aren't really REPLs.

>Your argument is the equivalent of saying notepad isn't a text editor because you can't edit multiple lines at once or highlight syntax.

No it's the equivalent of saying that not even programme that can possibly, technically edit a text file is a text editor.

Python's shell thing is not a REPL.

A 'command line interface', for example for bash, does the same. What is the difference to a REPL? Is it just another name for the same concept or are there differences? What do you think?
Yes, it's technically a REPL, just as bash is a scripting language.
It is a subtyping relationship. Bash's command line is a (minimalistic) REPL, but not all REPL are like Bash's command line. In most contexts, talking about REPLs is implicitly talking about REPLs that do more than just read, eval and print, however illogical that may sound.

Note that few languages actually define READ in a user-friendly way (since python 2.6 you have the ast package, Bash's "read" returns strings).

Compilation and a REPL are orthogonal concepts.

Lots of Common Lisp systems have very good REPLs and compile to machine code. A popular example is SBCL.

Anything can have a REPL - I did one for C++ called UnderC. Unfortunately, a technological dead end and some of the worst Bison on the planet. But it was surprisingly pleasant to use C++ in a interactive way and I wrote a C++ book working from the idea that people can learn to program better in such a conversational context. Required some interesting flexibility in the usual grammar.
The compiled or interpreted nature of a language (or its runtime) is a fuzzy concept at best (Java is interpreted on the JVM in the sense that it emits bytecode that is interpreted by the JVM; the main implementation of Clojure JVM compiles Clojure to Java bytecode that eventually gets interpreted). The notion you're looking for is probably that of incremental compilation / running.