Live data from Hacker News

REPL vs CLI: IDE wars

vlaaad.github.io

51–60 of 110 posts

Re: REPL vs CLI: IDE wars

#51
post #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…

> Maybe I'm "holding it wrong" but this causes a lot of friction and lost time. It is a completely non-problem for functional code. It is a big problem for imperative code. You can't just write all of your code in a functional style, but depending on what you are doing the limit gets larger or smaller. So it's normal that this will be a showstopper for some people, and irrelevant to others.

What does this have to do with imperative state?

Take this program:

  compute x = 1 `div` (x - 3)
  map compute [1,2,3,4]
Would seeing that it crashed in `compute` in `map` be enough info to debug, or finding out that `x` was 3 when it did also help?

Edit: fixed to use integer division so we actually crash .

Re: REPL vs CLI: IDE wars

#52

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…

Clojure's sweet spot is very much the "situated program" Hickey likes to talk about. Clojure is a great fit for line of business apps where maps really are the right choice for modeling your domain.

We recently evaluated Clojure vs node for an upcoming project and went with Clojure because while most of the work really is just querying a db and writing JSON, we also do a fair amount of heavy reporting and pdf generation which will bring node to a crawl relatively speaking. Rather than have to take on the operational complexity of microservices for the slower parts of our app we just went with a Clojure monolith. The draw of a single language to work with for both client and server was very tempting, but ultimately the JVM won out on the server.

I'd be amiss if I didn't also say the whole Deno situation has us worried about the long-term implications of spinning up a brand new node project, where the JVM seems far more reliable logistically.

Re: REPL vs CLI: IDE wars

#54
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…

I can do this in Java and C with the right IDE.

Re: REPL vs CLI: IDE wars

#55
post #21
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…

You can do this in IDEA's IDEs too, just place a breakpoint and then you can "evaluate expression" in that context to call functions, read values, etc.

I remember doing this with emacs and C in the 90s

Re: REPL vs CLI: IDE wars

#56
post #19

Earlier quoted context omitted.

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.

Step1: Write a test. Step2, IDE: Right click + Run. Step2, CLI: $ run Bonus: The test is now part of your automated test suite, and will be ran many times to ensure things don't break.

What if you don't know what you want it to do yet? Maybe you have a new API or library you're working with and the documentation is lacking. Maybe you're exploring some dataset trying to figure out what kind of information can be gleaned from it.

Maybe it takes 3 minutes to get it into the state where it failed, so instead of starting over every change you just want to modify the one function over and over.

Doing it in a repl like jupyter has you run the actual code many times as you're writing it so ensure things don't break before you ever save the file. Of course thats not an excuse to skip tests, but if I was going to pick one, I would choose running the code as I write it, instead of testing it after the fact.

Re: REPL vs CLI: IDE wars

#57
post #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…

CIDER ships with a perfectly adequate debugger if you want it. Might require a bit more manual labour than some environments but you’re never stuck just staring at a stack trace if that’s what’s bothering you.

I think using external dev dependencies and rich dev/user.clj files is pretty common on Clojure projects. Your REPL isn’t just somewhere to interact with the current codebase directly, it’s a framework for building that software and managing its environment more generally.

Re: REPL vs CLI: IDE wars

#58
post #55
post #21

Earlier quoted context omitted.

You can do this in IDEA's IDEs too, just place a breakpoint and then you can "evaluate expression" in that context to call functions, read values, etc.

I remember doing this with emacs and C in the 90s

Nice. I definitely want to give emacs a solid try at some point.

Re: REPL vs CLI: IDE wars

#59
post #36

> Don’t forget the set -euo pipefail at the beginning of your script. What does -euo means? I don’t know, I copy-pasted it and man set said there is no manual entry for set. Use "man bash" to find the list of built-in commands. Scroll way down, or search for "SHELL BUILTIN COMMANDS". The "e" command-line switch to the set command tells the script to exit immediately if there is a non-zero return value. The "u" switch…

It's kinda nonsense that `man set` doesn't provide that information. But it's kinda nonsense that those flags aren't the default, anyway.

"man set" can't provide that information trivially without knowing your shell; dash/bash/ksh/zsh will all be subtly different.

However, if you are running bash, "help set" is fine.

FWIW, I really don't like pipefail as a default (e.g. piping to "head" causes random pipefails) and -e also has some confusing semantics. Also either failglob or nullglob are more important than either and -C is useful for some scripts as well.

[edit]

Simple example of confusing "set -e" semantics:

The following does not print "hi" and shows returns error status, as expected:

  (set -e; echo hi); echo $?
But put it in an if statement, and it's suddenly success, and does print hi:

  if (set -e; false; echo hi); then echo hello; fi
The same problem applies to functions. The below function will remove all files in the current directory if it's called from a conditional, but not otherwise!

  foo() {
    set -e
    cd /some_directory # set -e means we exit if this fails
    rm -rf *
  }
I think just defining a die() function and using it after any command that must succeed is more verbose, but less error prone:

  cd /some_directory || die "chdir failed"
  rm -rf *

Re: REPL vs CLI: IDE wars

#60

Earlier quoted context omitted.

Indeed; I do this every day with Vim and its term command, with Julia, Python, bash, Elixir—it works with any language with a REPL of any kind.

I am not familiar with how Julia and Elixir work, but form my experience Python’s REPL is not the same at all as REPL in Clojure or other lisps. In Clojure, you literally built your program in memory while you’re writing the source code file, updating the memory representation of your running program part-by-part without ever stopping it. This experience is absolutely magical, and it’s very hard to go back to edit-co…

[deleted]
Post reply on HN