Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is really a massive release with many cool new features

My personal favorite is add-libs

You can now write single file demos or minimal examples for issues. Really lowers the friction to share small runnable snippets with people

You can also actually use it to demo Java libraries as well without all the Java boilerplate. Just poke around in the REPL and paste code into a comment on HN or wherever and anyone can replicate your "setup" and get it running exactly the same. No need to clone a repo or anything



Cool! You should post an example :)


Just tested it:

You run `clj` to get a Clojure REPL

Then you can for instance paste the following into the REPL

    (add-libs {'thi.ng/geom {:mvn/version "1.0.0-RC4"}})
    (use 'thi.ng.geom.viz.core)
    (use 'thi.ng.geom.svg.core)

    (->> {:x-axis (linear-axis
                {:domain [-10 310]
                    :range  [50 550]
                    :major  100
                    :minor  50
                    :pos    150})
        :y-axis (linear-axis
                {:domain  [0 4]
                    :range   [50 150]
                    :visible false})
        :data   [{:values  [[0 100] [10 90] [80 200] [250 300] [150 170] [110 120]
                            [210 280] [180 280] [160 240] [160 170]]
                    :attribs {:stroke-width "10px" :stroke-linecap "round" :stroke "#0af"}
                    :layout  svg-stacked-interval-plot}]}
        (svg-plot2d-cartesian)
        (svg {:width 600 :height 200})
        (serialize)
        symbol)
- the first line downloads a library and adds it to the running session

- the second and third line add the library to the REPL's default namespace

- the rest of the code makes an axis and plots some random values

- the output is then serialized and send out the REPL output

You should get a little SVG plot on the output

PS: Make sure you have version `1.12` by running with `clj --version`. If not, then (re)run the instructions here to get the latest version: https://clojure.org/guides/install_clojure


Using (add-lib 'thi.ng/geom) is sufficient here - it uses the newest version by default.


Parent specified a RC version, does it automatically use the latest RC versions as well? AFAIK, it only uses the latest stable version, but I could be wrong, it happened before.


Here is an example playing with BooFCV's Java API

It'll pop up a little window displaying an image

    (add-libs {'org.boofcv/boofcv-all {:mvn/version "0.35"}})
    (import 'boofcv.alg.color.ColorRgb
            'boofcv.core.image.ConvertImage
            'boofcv.gui.ListDisplayPanel
            'boofcv.gui.image.ShowImages
            'boofcv.io.UtilIO
            'boofcv.io.image.ConvertBufferedImage
            'boofcv.io.image.UtilImageIO
            'boofcv.struct.image.GrayU8
            'boofcv.struct.image.ImageType
            'boofcv.struct.image.Planar
            'java.awt.image.BufferedImage)
    (let [image-url  "https://kxygk.github.io/web/chengdu.jpg"
          color (ConvertBufferedImage/convertFrom (UtilImageIO/loadImage image-url)
                                                  true,
                                                  (ImageType/pl 3 GrayU8))
          weighted (GrayU8. (.width color)
                            (.height color))
          gui (ListDisplayPanel.)]
      (ColorRgb/rgbToGray_Weighted color weighted)
      (.addImage gui
                 weighted
                 (str (.width color)
                      " "
                      (.height color)))
      (ShowImages/showWindow gui
                             "RGB222"
                             true))


Does anyone remember Groovy? It has @Grab annotation which does essentially the same as add-libs you described. Very conventient for writing scripts.



> Does anyone remember Groovy?

I recall that Atlassian had some kind of scripting console where you could run Groovy and interact with its API / objects. It was useful for exploring when writing plugins for bamboo or Jira ...


Yes! Groovy does have quite a few under appreciated cool gems, and it’s a shame that is barely getting any attention nowadays..


Note that Java has a REPL now and scripting support, although something like add-libs is still missing from available meta commands.


Java's REPL is like a kick in the nuts compared to using one in Common Lisp. How does Clojure's REPL feel like in comparison?


Haven't used neither Java's repl nor Common Lisp (just read about both of them) but at a glance Clojure's repl is much closer to CLs repl than Java's.

In fact, I think it's confusing to call the repls of language like Ruby, Java, JavaScript et al "REPL" at all, compared to what lisps offer, as the experience is so different. They're more like "Code evaluators" than anything else.

Typically when using repls outside of lisps, you'd type your code into the actual repl window, while in lisp-land you typically connect your editor to the repl and program like usual, selecting stuff to evaluate and so on.


> Typically when using repls outside of lisps, you'd type your code into the actual repl window, while in lisp-land you typically connect your editor to the repl and program like usual, selecting stuff to evaluate and so on.

I think that's neither typical in the history of Lisp nor in other languages. For example in Mathematica and Jupyter one interacts via a Notebook interface. Smalltalk interacts via an integrated IDE. Many editors connect via LSP to language servers.

In Lisp the idea of an editor connecting to a Lisp is a bit of a historic accident. After the AI winter the Lisp development environments were no longer used.

A typical way to start Lisp from an external editor was via the editor starting a subprocess (the "inferior Lisp") and talking to it. GNU Emacs did that with IDEs for Lisp, like ILISP.

The next generation used GNU Emacs as its external development environment (instead of developing a new one in Lisp) via a network interface. SLIME was the most important one, with SWANK being the component loaded into the external Lisp, which provided a server interface.

Unfortunately the SLIME REPL itself (its read eval print loop) is not great (in general SLIME is okay to use) and other languages sadly copied the SLIME model, failing to copy various other important REPL features of Lisp. For example Clojure lacked the error handling of Lisp REPLs, which typically provide features like break loops, where one can inspect and repair errors. SLIME goes directly into a backtrace window. Thus people copied it, without knowing that there is a tradition of completely different REPL interaction. GNU Emacs is bad at multitasking, thus one REPL buffer could block the editor for a while -> multiple REPL windows were not that useful. Another way of working got lost...


> Unfortunately the SLIME REPL itself (its read eval print loop) is not great

> Another way of working got lost...

You singled out SLIME, but you've mentioned before that you use LispWorks - do you think it's also "not great"? Just curious ...


> You singled out SLIME

Especially the REPL of SLIME / GNU Emacs.

LispWorks provides a better REPL experience.


Do you use LW's built-in editor, or emacs?


The built-in editor. With LispWorks I don't use GNU Emacs. I have GNU Emacs configured, so that I could use it, but I don't... I use SLIME with SBCL, but mostly because of SBCL, which is a great implementation.

I'm faster and more in the flow with the LispWorks IDE.


> In fact, I think it's confusing to call the repls of language like Ruby, Java, JavaScript et al "REPL" at all

Agreed. I always call them “consoles,” since I work largely in JS and that’s what the browser calls it. There’s no way in a console to jump into a module and modify a single function without resetting any state that the module was tracking.


repl as a name kind of describes the requirements for something to be a repl - it has a read-evaluate-print loop. It would be more confusing to say that something with a read-evaluate-print loop isn't a repl.


Yeah, the problem with "REPL" is that it underdescribes what Clojure, Common Lisp, etc. can do, not that it overdescribes Ruby, Python, etc.


> Java's REPL is like a kick in the nuts compared to using one in Common Lisp.

An IDE connected to a running Java process via JDPA/JDI (Java debug interface) is probably a better comparison.

Sure, Common Lisp will allow you to load more substantial code changes into the running process, but using JDI you can "break on specific/ all exceptions" which will allow you to inspect code before the stack is unwound, you can drop frames and re-run stuff possibly after changing values.

What's funny is that I started noticing and using these possibilities at my Java job while learning Common Lisp. Before learning about Common Lisp I was almost exclusively an edit/compile/run guy, now I often take the shorter route of edit/CTRL-SHIFT-F9.


Many tools are like that, unfortunately Common Lisp didn't took off, and we are still catching up, see Python and Machine Learning, instead of using a powerful dynamic language with native compilers.

However that doesn't mean Java REPL is useless.


JBang can grab dependencies for you.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: