Live data from Hacker News

REPL vs CLI: IDE wars

vlaaad.github.io

11–20 of 110 posts

Re: REPL vs CLI: IDE wars

#11
post #5
post #4

I think you might be missing the main "aha!" of clojure REPLs vs REPLs in non-homoiconic languages: you can very easily execute small parts of the program you're editing without re-typing the code. In emacs, for instance, you often use `eval-last-sexp`, by default bound to C-x C-e. This lets you move your cursor to a particular point in the file, often deep in a function, and get the results of just the form(s) you'r…

When you evaluate a form deep in a function, how do you handle variables that are defined "outside"? How can you evaluate such expressions?

You can use a REPL powered debugger. You can interact with the debugger to a higher degree than with most mainstream languages. It’s not quite as powerful as CL though, from what I’ve read.

Or you pull out expressions and test them in isolation with given (assumed) inputs.

Re: REPL vs CLI: IDE wars

#12
post #4

I think you might be missing the main "aha!" of clojure REPLs vs REPLs in non-homoiconic languages: you can very easily execute small parts of the program you're editing without re-typing the code. In emacs, for instance, you often use `eval-last-sexp`, by default bound to C-x C-e. This lets you move your cursor to a particular point in the file, often deep in a function, and get the results of just the form(s) you'r…

Homoiconicity isn't required for that, all you need is to be able to map between source and AST enough to identify expression boundaries.

Plenty of development environments for non-homoiconic languages provide the ability to evaluate a selected expression (not just the last one) in a linked REPL on demand.

I love the Lisp family, but I don't know why its advocates often sound like they haven't seen a dev environment for a non-Lisp language since the early 1980s when pointing to “unique” advantages of Lisps.

Re: REPL vs CLI: IDE wars

#13
post #5
post #4

I think you might be missing the main "aha!" of clojure REPLs vs REPLs in non-homoiconic languages: you can very easily execute small parts of the program you're editing without re-typing the code. In emacs, for instance, you often use `eval-last-sexp`, by default bound to C-x C-e. This lets you move your cursor to a particular point in the file, often deep in a function, and get the results of just the form(s) you'r…

When you evaluate a form deep in a function, how do you handle variables that are defined "outside"? How can you evaluate such expressions?

By evaluating outer forms first.

Re: REPL vs CLI: IDE wars

#14
Thanks for introducing me to `add-lib` This is going to be a huge time saver :) More info here: https://insideclojure.org/2018/05/04/add-lib/

Hopefully there will be some way to just "reload" your whole `deps.edn` though

"If you get an error, the execution stops by default and you get a stack trace."

I'd say the other missing piece of REPL development is that while you get a stack trace, you don't get a program state like you do with GDB or ELisp. Maybe I'm "holding it wrong" but this causes a lot of friction and lost time. I'd be curious how others approach this. And that all being said, the CLI doesn't relaly offer a better alternative here.

For entirely replacing the CLI I think that since Clojure is a general purpose language there ends up being a tad more boiler plate than you'd like.. It's not at the point where you're gunna just run `clj`, load in some library with `add-lib` and start messing around b/c things are just a tad too clunky.

For instance if you wanna read in a CSV file (I had to look this up)

    (-> "my-csv-file.csv"
    (io/file)
    (.getCanonicalPath)
    (io/reader)
    (csv/read-csv :separator \,)
    (#(into [] %)))))
Uhh.. so you're prolly gunna want to wrap that up in a helper function. I personally end up making a dummy "project" where I keep a bunch of helper functions and then doing my REPL "scripting" and messing around in that. It feels a bit wrong.. but at least to me it looks like a solvable limitation. Given a nice set of helper libraries you could probably get to a point where a bare `clj` REPL would be as ergonomic as a more explicitely interactive language like R/MATLAB/etc.

Re: REPL vs CLI: IDE wars

#15

This post could be summarized as "write as much of your project's tooling as you can in the project's main programming language and the project's main programming language should be Clojure" and I agree wholeheartedly.

I think their point is bigger than that. Historically one of the major points against using Clojure to write your tooling was the slow startup times which are just painful from the CLI. It looks like the clj-exec idea linked to in the article is the secret sauce that makes moving to writing your tooling in Clojure a workable idea, since now you have a unified calling convention for both calling tooling from the REPL…

Also check out https://babashka.org: it offers Clojure scripting with very fast startup time. It also has a task runner (similar to make, just, etc.) that can be used to store long invocations (like clj-exec tends to have).

Re: REPL vs CLI: IDE wars

#16
post #5
post #4

I think you might be missing the main "aha!" of clojure REPLs vs REPLs in non-homoiconic languages: you can very easily execute small parts of the program you're editing without re-typing the code. In emacs, for instance, you often use `eval-last-sexp`, by default bound to C-x C-e. This lets you move your cursor to a particular point in the file, often deep in a function, and get the results of just the form(s) you'r…

When you evaluate a form deep in a function, how do you handle variables that are defined "outside"? How can you evaluate such expressions?

Cursive has a repl powered debugger just put your breakpoint there use the repl to trigger the call then use intellji's debugger to step through

If you want to run expressions in context just use the expression editor like a normal repl

Something I haven't tried yet is redefining functions at debug time can't see why it wouldn't work though

Re: REPL vs CLI: IDE wars

#17
post #4

I think you might be missing the main "aha!" of clojure REPLs vs REPLs in non-homoiconic languages: you can very easily execute small parts of the program you're editing without re-typing the code. In emacs, for instance, you often use `eval-last-sexp`, by default bound to C-x C-e. This lets you move your cursor to a particular point in the file, often deep in a function, and get the results of just the form(s) you'r…

Homoiconicity isn't required for that, all you need is to be able to map between source and AST enough to identify expression boundaries. Plenty of development environments for non-homoiconic languages provide the ability to evaluate a selected expression (not just the last one) in a linked REPL on demand. I love the Lisp family, but I don't know why its advocates often sound like they haven't seen a dev environment…

Homoiconicity is an ill-defined concept. If you take every subjective feature from it, all it implies is that you are able to cut your code into well defined AST structures (what all languages have, but for some it's easier than for others).

So, yeah, anything people do with Lisp could be done for any other language, it only requires more complex tooling. How much more complexity depending on the language, and it varies from "barely perceptibly more" into "that's completely not practical".

Re: REPL vs CLI: IDE wars

#18
post #9
post #7

Earlier quoted context omitted.

Cider (the clojure plugin for emacs) has a variant that prompts you for the the values for those variables.

Oh nice. That's one place where Clojure beats Common Lisp then..

Does it? Asking for a value when encountering an unbound variable is a default restart

    $ sbcl
    This is SBCL 2.1.1.52.HEAD.321-f8a57bcca, an         
    implementation of ANSI Common Lisp.
    More information about SBCL is available at 
    .

    SBCL is free software, provided as is, with absolutely no warranty.
    It is mostly in the public domain; some portions are provided under
    BSD-style licenses.  See the CREDITS and COPYING files in the
    distribution for more information.
    \* (\* x x)

    debugger invoked on a UNBOUND-VARIABLE in thread
    #:
      The variable X is unbound.

    Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

    restarts (invokable by number or by possibly-abbreviated name):
      0: [CONTINUE   ] Retry using X.
      1: [USE-VALUE  ] Use specified value.
      2: [STORE-VALUE] Set specified value and use it.
      3: [ABORT      ] Exit debugger, returning to top level.

    (SB-INT:SIMPLE-EVAL-IN-LEXENV X #)
0] 2

    Enter a form to be evaluated: 3
    9
    \*

Re: REPL vs CLI: IDE wars

#19
post #4

I think you might be missing the main "aha!" of clojure REPLs vs REPLs in non-homoiconic languages: you can very easily execute small parts of the program you're editing without re-typing the code. In emacs, for instance, you often use `eval-last-sexp`, by default bound to C-x C-e. This lets you move your cursor to a particular point in the file, often deep in a function, and get the results of just the form(s) you'r…

This is the draw for Jupyter Notebooks as well. Execute code blocks. I remember when I learned this in Matlab.

REPL are super nice for this!

I've had a hard time in Java, Fortran, etc. in determining the right development patterns that are used in this space to be productive.

Re: REPL vs CLI: IDE wars

#20
Considering its ecosystem, what do most here use Clojure for or what do you think is its sweet spot? I used it in a project with pg/ring/reitit and while some things were nicer it was not better enough to make me switch from pg/nodejs/express for new projects. Used emacs with inf-clojure (found cider too bloated and buggy, was tempted to port some features of cider to a fork of inf-clojure) and macros were helpful in a couple of places, but other than that, you can write JS almost as how most use Clojure. Also found JS to be faster unless you got out of your way to write Javaish Clojure, which reminds that is was a time sink having to deal with Java libs(it's really not as "seamless" as most advertise) because of no Clojure equivalents.
Post reply on HN