Bazel: a way at start a repl

Created on 14 Jun 2016  Â·  17Comments  Â·  Source: bazelbuild/bazel

many programming languages have repls. One thing pants supports is starting a repl with a given target's dependencies on the path.

There is demand for this even in java:
https://www.pgrs.net/2015/09/14/java-repl-with-jshell-and-bazel/

in the scala rules, we circumvent the lack of a bazel repl command by have a two step: we do bazel build to build a script, then manually run the script. We can't use bazel run because we need stdin, which bazel run closes.

two solutions I see:

  1. add a repl command which should give you repl in the appropriate language where the the library path is set up as the target would see.
  2. add the ability to add commands via skylark: so bazel foo target could ask the rule for the target how to dispatch foo.
P4 misc > misc feature request

Most helpful comment

@damienmg I think this is pretty standard for any build tool whose language has a repl:

Clojure: lein repl: https://github.com/technomancy/leiningen#basic-usage
scala: sbt console: http://www.scala-sbt.org/0.13/docs/Hello.html
haskell: stack ghci: http://docs.haskellstack.org/en/stable/GUIDE/#ghci-the-repl

pants, which is similar to bazel, also has a pants repl: http://www.pantsbuild.org/options_reference.html#repl

A main use case of a repl is testing. When you see a test fail you can quickly load the code and the dependencies and try a few examples. You usually see what is going wrong much more quickly than having to get in a loop of making a change, adding more test cases, and re-building the tests. Coupled with the fact that languages with more powerful type systems than java generally take longer to compile, that loop is a lot more painful in scala.

Another use case is simply learning some code: open in the repl and poke around at it (you often see language "playgrounds" on the web that serve this purpose). This is helpful for onboarding new team members to new libraries or languages.

I imagine repls in java may be a bit like lambdas: before java supported them most java programmers didn't see the value, after, all of a sudden it's really useful. I hope we don't have to wait until after java 9 convinces java programmers of the repl value. Reminds me of the Paul Graham quote: "Programming languages teach you not to want what they don't provide". I hope the same is not true of build tools? ;)

All 17 comments

Added labels, feel free to change.

I don't think this is a good idea.

@johnynek: Can you describe a bit more the precise use case you have in head?

I manually do this at this point:

bazel build //repl:repl_deploy.jar && scala -cp
bazel-bin/repl/repl_deploy.jar

I feel like Java folks don't miss a REPL much because they've never had
one. I hear one comes with Java 9 but I don't know much about it.

On Tue, Jun 14, 2016 at 1:52 AM, Damien Martin-Guillerez <
[email protected]> wrote:

I don't think this is a good idea.

@johnynek https://github.com/johnynek: Can you describe a bit more the
precise use case you have in head?

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/bazelbuild/bazel/issues/1394#issuecomment-225819221,
or mute the thread
https://github.com/notifications/unsubscribe/AAAQxK8SI86I4e0ZwUVBPksW5YZI9K0aks5qLmvBgaJpZM4I08jR
.

@damienmg I think this is pretty standard for any build tool whose language has a repl:

Clojure: lein repl: https://github.com/technomancy/leiningen#basic-usage
scala: sbt console: http://www.scala-sbt.org/0.13/docs/Hello.html
haskell: stack ghci: http://docs.haskellstack.org/en/stable/GUIDE/#ghci-the-repl

pants, which is similar to bazel, also has a pants repl: http://www.pantsbuild.org/options_reference.html#repl

A main use case of a repl is testing. When you see a test fail you can quickly load the code and the dependencies and try a few examples. You usually see what is going wrong much more quickly than having to get in a loop of making a change, adding more test cases, and re-building the tests. Coupled with the fact that languages with more powerful type systems than java generally take longer to compile, that loop is a lot more painful in scala.

Another use case is simply learning some code: open in the repl and poke around at it (you often see language "playgrounds" on the web that serve this purpose). This is helpful for onboarding new team members to new libraries or languages.

I imagine repls in java may be a bit like lambdas: before java supported them most java programmers didn't see the value, after, all of a sudden it's really useful. I hope we don't have to wait until after java 9 convinces java programmers of the repl value. Reminds me of the Paul Graham quote: "Programming languages teach you not to want what they don't provide". I hope the same is not true of build tools? ;)

On Tue, Jun 14, 2016 at 10:20 AM, P. Oscar Boykin [email protected]
wrote:

I hope we don't have to wait until after java 9 convinces java programmers

of the repl value.

FWIW, I and several people I know have been using the scala repl to work
with pure java for quite some time. Have to learn some scala but it's
better than nothing (and scala has a more repl-friendly syntax ...)

I imagine this could also be useful for trying out bazel query commands.

I just realized that you would like a repl at the command level not at the language level. Am I wrong? You want something like:

> build //foo:bar
> run //foo:bar
> exit

Is it correct? In which case this should be easy to do as an outside script, with the bazel server not having to restart it should be straightforward.

yeah, I would like bazel repl //foo:bar ideally.

The reason why bazel run //foo:bar won't work is that repls use stdin, which for some reason bazel closes immediately (it is mentioned in the docs, so I guess this is intended). Can you say why bazel run closes stdin immediately? If it did not, I think it would work. I can also think of lots of cases where I would like to send stdin to a program running with bazel run.

Sorry I am not following, what kind of expression you would like the repl loop to evaluate?

I think we're conflating a bazel repl verb with a language repl verb.

It seems like Damien is thinking of a bazel repl were you can specify bazel
verb/targets in a bazel loop.

Oscar's use case, which pants has, is a language repl verb. It's not a repl
for bazel commands/targets, it invokes a target-dependent repl for that
target. This is common in scala but also makes sense for ruby and python
(some day java?) if it puts the target contents on the search/class path
before invoking the language-specific interactive repl.

The difference, using scala as an example, is that run calls main in the
target-specified class. repl would load all the target's contents onto the
classpath but then call the scala interactive interpret/repl (this is
normally done with the scala command but is not much different than loading
the interpreter on the classpath and calling its main.)

On Thu, Jun 16, 2016 at 5:07 AM, Damien Martin-Guillerez <
[email protected]> wrote:

Sorry I am not following, what kind of expression you would like the repl
loop to evaluate?

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/bazelbuild/bazel/issues/1394#issuecomment-226466307,
or mute the thread
https://github.com/notifications/unsubscribe/AAAQxET8lYrHqBHZ7jrLEMMGeMiYTieHks5qMTx1gaJpZM4I08jR
.

Ok I still have a hard time seeing what kind of action is needed from bazel. Is it just a run with attaching stdin from the terminal?

@damienmg yes, it would be great for run to at least have an option to attach stdin.

That would be enough. I think with that, rules could make implicit targets that have repls so bazel does not need to know about it.

sorry, @damienmg, to try to be clearer: I don't want a repl to give bazel commands (as you suggested). I want bazel to start a repl for a target (so start a java repl with some target's classpath, or a scala repl, etc....)

I want the same as pants repl or sbt console or lein repl or stack ghci which is a language level repl for interacting with the code you have written.

Ok I think this is a legit use case but we probably won't work on it which mean contribution welcomed :)

Now that bazel run has been updated and can access stdin, do you still need a new Bazel feature to implement this?

@laurentlb I think the new bazel run is enough.

So the actual way of how to run a repl through bazel for java was unclear to me, but eventually I was able to figure out how to run jshell by hand using the existing bazel support. I'm leaving this comment here for future people who search for "bazel repl" since that's what I was looking for the equivalent of pants support. Anyway, if you have a java_binary named app, you can use the following commands to run jshell with the right classpath directly:

bazel build //:app_deploy.jar
jshell --class-path bazel-bin/app_deploy.jar

This depends on the _deploy.jar functionality described in the java_binary rule which is not built by default unless you specifically request it.

Was this page helpful?
0 / 5 - 0 ratings