Hacker News new | past | comments | ask | show | jobs | submit login
Ammonite: Scala Scripting (lihaoyi.com)
99 points by lihaoyi on May 25, 2017 | hide | past | favorite | 32 comments



On one hand, as big Scala fan, this is great, I love the IO library!

On the other hand, I hate to be that guy, but

1. website is not https, no guarantee it's not modified or any authenticity

2. to install I need to download a file from a shorten URL then make it executable, then run it, no questions asked. I'm sorry but no.

3. no checksum to validate the binary

Great start, but these small security things are going to inhibit adoption, at least in my case.

Still don't let that stop you. Better ship early than never, and it looks very polished and well thought. Good luck!


There is a github repo. Clone it and build it, after all you are a developer, right?

If you want to run Ammonite on Windows the only way is to clone the repo, patch it and build it.

You are right to be careful, even paranoid, but the security issues are not a showstopper.


Not a show stopper, but will make it less likely people will spend the time trying it out. If things like "brew install x" were not important, it wouldn't had 7000 stars on github and used by almost any Mac developer. Yes, we can build all from source... but how many of us prefer doing it over using a trusted package manager? Ammonite is about developer productivity, or so I believe, so having to clone and build it from source is not going to increase the amount of people trying it out... part of shipping is security, and security should be there from the get go, it's not something you just add later.



Its amazing for anything internal,

I import it using sbt/ivy and load the console/run an ssh session!


The website having to be https is a bit too much. It is hosted on gh-pages and there is no way to get https with custom domain (without things like Cloudflare)


Cloudflair https is free, (https://www.cloudflare.com/ssl/) and not such a big of a pain to setup. without https, let's say someone puts a wifi hotspot named JFK_AIRPORT_FREE_WIFI in the airport, and plays with the DNS setting and points to his own version of the internet. https websites are more or less protected from these as the certificates will not be valid. http ones are completely open to manipulation. Do you lock your door at night? even though most likely no one will come in? Do you look who is at the door before opening it? Why is expecting https is a bit too much? Why is security something people see as "we can add it later when needed". It should be part of the checklist before releasing. Most people won't release without documentation, a decent automated build, some unit tests, right? Security should be way up that list as well. Another reason is showing you mind about security. Getting https is just one step, making sure the code is secure is a whole different topic. If you don't care about https, how do I know (without reading the code) that you care about not using DES, that you care about hashing + salting your passwords, that you care about not logging sensitive information, that you don't run as root when not needed, that you take care of my data and not compromise it. It starts with "meh, https is a bit too much" and ends up with Linkedin passwords leaking because they just hashed it. This is not cooking. You can't always add salt later. </rant>


All that is fine - for a simple static site with no user information and hosted on gh-pages - using that as a point to not try a open source project is not right.


Why is it "not right"? Can't I be as paranoid as I want when it comes to what I install on my machine? Of course the OP has no obligation to fix this, but I think the parent was just pointing out a legitimate barrier that is worth considering.


I believe in the value of this project, OP (lihaoyi). Your example of https://github.com/valvesoftware/steam-for-linux/issues/3671 and rm -rf "$STEAMROOT/"* erasing everything when $STEAMROOT is a blank string are spot on.

I remember spending a couple of hours one weekend getting this to work in Cygwin. I lost energy to pursue it further after getting it to work, which is typical with me :-) (Then I revisit things after 6 months or so, with some luck and free time).

Anyway, here are my notes from that attempt, in case someone else runs into the same issues:

a) I fixed the height and width in ammonite/repl/FrontEndUtils.scala so that it doesn’t go down the hell hole of Cygwin tput and tty issues

b) hard-coded repl.frontEnd() = ammonite.repl.FrontEnd.JLineUnix in ammonite/shell/Configure.scala

c) sbt '~shell/test:run' to run the fully-loaded REPL


I like scala too but I have to say, it is a bit on a heavy side when it comes to scripting.

re: the rm -rf "$STEAMROOT/"* there is much simpler way to avoid it:

    set -euo pipefail
    IFS=$'\n\t'
This would prevent this bug and many others. For whole overview on that see: http://redsymbol.net/articles/unofficial-bash-strict-mode/


Thanks, that's a good one!


I use this tool a lot ! When I want to test a new library, I download it from maven using :

import $ivy.`org.typelevel::cats:0.9.0`

And then I play with it. Or when I read a scala book and copy past example/exercise to benefit from the syntax coloration and don't want to recompile everything every time I change something.

The only question I want to ask to @lihaoyi : why does ivy import has such an ugly syntax ? (import $ivy2.`com::lib:version`) rather than the more sbt like (import $ivy2 "org.scalatest" %% "scalatest" % "2.2.6") ?


I'm not a scala dev but I'm curious, what makes scala a good scripting language? Bash has its faults but it's still great for adhoc stuff and when it stops being great you can just move to a more specialized build config tool. Scala seems a bit more verbose and it's unclear what you gain from it.

Is it similar to what's going on the JS world where people just want to use one language for client, server, and build tools? (and for this case, even the terminal shell?)


For anything complex it is better to use a real language, not bash. If you are a Scala developer then Scala is a pretty good choice. However lots of folks use Groovy or Python which have the advantage that a wider group of people can learn how to use them.

The JS everywhere crowd is rather narrowminded and don't seem to be aware that they are reinventing a wheel that others have already done better.

But if you spend most of your day writing JS and you find yourself needing to write complex bash scripts, give your head a shake and use JS instead. It is better to use a real programming language where you have test frameworks, build tools and so on.


Don't forget, on the JVM, you not only have Apache Groovy and JS(Nashorn) for scripting, but also Clojure which is suitable for complex scripts, even providing terse macroing. It's very handy to define a macro to avoid repetition typical in tests.


A big strength of Scala scripting is the availability of the whole JVM ecosystem, and the ivy integration in Ammonite makes this seamless. Check out the "Ammonite Cookbook" section of the site for some examples. The bash equivalent would be use of command-line tools like netcat, sed, etc. Powershell for the JVM (seen in another comment) is a great analogy. Working in REPL mode, testing snippets and exploring library signatures, is very productive. Also, I'd argue that Scala becomes less verbose than Bash as you do more interesting things. No question that it's much slower.

I think you're right about the one language thing. If you're developing a system in Scala, you might as well do scripts in the same language, with API access to your system. (Real world example: server deployment script prompts for initial admin password, computes and persists hash using server API).


Unless you know Scala already well, it doesn't make sense to use it as a script language — there are cleaner alternatives (not Bash, though — Bash is just awful). But if you do, it makes perfect sense. Scala is one of the most expressive languages out there.


I think that about sums it up perfectly: If you don't know Scala, learning it just to script with is extremely inefficient. However, if you already know Scala well, all you need is the right library of functions to have a really nice (and much-safer-than-bash) scripting language (or you would if not for the long waits for compilation and startup JVM startup).


I really enjoy using chains of map.filter.foreach.map in scala, it feels powerful but also simple

I imagine piping in bash feels similar, so there's at least a common problem/solution between them


> I imagine piping in bash feels similar...

It is. Piping is akin to an untyped subset of working with Scala's collections, and there's a similar workflow between the two, e.g.:

In bash, you build up a command line with something like (as a stupid example, the number of unique file sizes in a directory):

    Step 1) $ ls -l
    Step 2) $ ls -l | awk '{print $5}'
    Step 3) $ ls -l | awk '/\d+/ {print $5}'
    Step 4) $ ls -l | awk '/\d+/ {print $5}' | sort -n
    Step 5) $ ls -l | awk '/\d+/ {print $5}' | sort -n | uniq
You can see the correspondence with collections--typically building up in the editor in a similar staged manner ending with something like:

    Process("ls -l").lines   // ls -l part
      .map(_.split("\\s+"))  // awk part {
      .filter(_.length > 4)  //   ...
      .map(_.apply(4).toInt) // }
      .sorted                // sort -n part
      .distinct              // uniq part
The tradeoffs between the two are essentially verbosity versus data safety (perhaps not important with a throwaway inspection, but more important when working on larger programs...).

However, the building process is the same--you don't write the latter all at once, you gradually mold the pipeline until you get the output you want.


I am a scala dev but for scripts I use ruby. With pry, I have a great REPL, and ruby has no problem with those filter chains.

  [1] pry(main)> `ls`
  => "README.md\n" + "_build\n" + "config\n" + "lib\n" + "mix.exs\n" + "test\n"
  [2] pry(main)> `ls`.split
  => ["README.md", "_build", "config", "lib", "mix.exs", "test"]
  [3] pry(main)> `ls`.split.map(&:upcase)
  => ["README.MD", "_BUILD", "CONFIG", "LIB", "MIX.EXS", "TEST"]
  [4] pry(main)> `ls`.split.map(&:upcase).select { |x| x.match(/E/) }
  => ["README.MD", "MIX.EXS", "TEST"]


Building a rest API for a DevOps platform wont be easy in bash.

Scala is also less verbose, easy todo FP with and its very natural to do system/db work with.

Its basically a better java for me.


Scala can be very concise - you can write Scala that looks very much like Python (indeed most Python just translates directly). E.g. it's got quite a low-ceremony syntax, not needing as many brackets or braces as other languages. But yeah wanting to use the same language everywhere is also a factor. Being able to call functions from your main codebase in your scripts is really nice.


Yeah, I agree here. I think each language has it's faults, and I'm not sure if Scala is the best for scripting and that sort of thing.

Personally, I try to use Groovy for any semi-complicated sort of script. It has many features that are similar to Scala, and usually ends up being very concise and readable.


I don't personally agree with the following sentiment although I have certainly gone down this path myself even considering my beliefs. I think for a lot of people they'd rather not context switch into another language, or in many cases simply aren't proficient in a more appropriate language. Many devs are far from polyglots.

Even though I think that's the wrong approach I certainly have had many instances where I've whipped something quick up in language X even though it was wildly inappropriate simply because for me it was going to be faster


Love this. The mess of using Java standard library for filesystem IO always left a bad taste in my mouth. This looks amazing for the filesystem stuff alone.


We use ammonite everyday! Its a great tool!

Li has a patreon I advise anyone using ammonite to checkout!

https://www.patreon.com/lihaoyi


This isn't too far away from "Powershell on the JVM," which is not a bad thing.

  ls.rec! cwd |? (_.ext == "class") |? (_.size > 1024) | (_.last) | println
Compare to (I think this is roughly equivalent Powershell)

  ls -rec |? {$_.Extension -eq ".dll"} |? {$_.Length -gt 1024}


ls with filter flag can be used to get particular extension.


> Create scripts that you can run easily from the command line, without the overhead of setting up a "project" or waiting for SBT's slow startup times.

This is the one thing keeping me away from Scala programming in general, by the way, to be honest.


This looks very nice, but it wont be very usable without vim bindings




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: