[HN Gopher] (Yet Another) Lisp in Go
___________________________________________________________________
(Yet Another) Lisp in Go
Author : tosh
Score : 74 points
Date : 2022-05-08 07:46 UTC (15 hours ago)
(HTM) web link (johnj.com)
(TXT) w3m dump (johnj.com)
| didibus wrote:
| For some reason, the benchmark done in this post has so much bad
| faith, that it turned me off completely from the actual project.
| It seems just too naive or disingenuous and it kind of loses my
| trust.
| sebastianconcpt wrote:
| Your minimalist core feature and flexible extension strategy
| sounds very appealing.
|
| I can identify having this impulse after doing things with Rust
| but fantasizing about a LISP cousin: Smalltalk.
|
| Now that you mentioned Go it is a more natural thing to try due
| to its garbage collection already done there. Thanks por pointing
| that out.
|
| What restrains me a bit of starting any effort in this direction
| is Pharo's current performance: Time
| microsecondsToRun: [ 100 factorial ]. "86"
| igouy wrote:
| Please spell-out whether you are restrained by how-good or how-
| bad you consider current performance to be.
| chakkepolja wrote:
| > You may have noticed the lack of character strings in the
| feature table, above. Many interesting Lisp programs don't use
| traditional strings (arrays of characters encoded as bytes)
|
| Is this true?
| BaculumMeumEst wrote:
| They're referring to using symbols instead of strings
| aasasd wrote:
| Sounds like another Lisp interpreter. While everyone is on
| transpilers.
| sebastianconcpt wrote:
| I was thinking about transpilers lately. Can you point me to
| examples?
| aasasd wrote:
| IIRC https://github.com/jcla1/gisp generates an AST and then
| spits out Go code that equals the same AST.
| [deleted]
| prakashgp wrote:
| Great!
| kkfx wrote:
| While prizing any FLOSS project I'm curious why... I can
| understand Clojure, giving Lisp on top of the enormous Java
| codebase have some practical reasons, but Go so far have a
| relatively small public set of libs so why instead of a Lisp
| written in Lisp, like SBCL?
| marcrosoft wrote:
| Huh? Go has an enormous and high quality std lib and even
| larger set of community libs. On top of that its popularity is
| exploading. I've never seen a language rise in popularity as
| much as Go.
| kkfx wrote:
| Have a high quality stdlib, but nothing other languages do
| not have. There are many community libs, but again nothing
| that special, also the popularity rise for a language
| transpiled on top is not much a thing...
|
| Java exists today in many places where change codebase is a
| nightmare and keep up software is no less a nightmare so
| having a more manageable language able to insert itself in
| the old ecosystem is valuable, but on a moderately new
| language with nothing so big to be in a state of needing a
| nightmarish replacement why?
|
| It's like Hy for Python: it's nice, a programming exercise
| but for what more than the technical piece? How many Python
| programs need a new language while remain on their own python
| VM? How many Python programmers want lisp with Python
| underneath?
| samhw wrote:
| I think the real issue is that Go is its runtime, including
| garbage collection but also coroutine scheduling, syscall
| management (syscalls effectively enter 'gospace' before
| kernelspace), etc. Go's docs liken it to crt0, which is
| entirely dishonest. You can't have verifiable deterministic
| programs with a runtime like this which extends way beyond
| a small setup routine. That's generally 'fine in practice'
| for application development - especially the Python-level
| programs which are generally written in Go - but for
| building _another_ language (interpreter) atop it, it
| strikes me as madness.
| comfrey11 wrote:
| I propose a name change to Aligory. Great read, thanks for
| sharing !
| kitd wrote:
| _Without strings, one will probably want to manipulate atoms in
| various ways. As a start, l1 introduces the notion of "splitting"
| (creating a list from an atom or number) and "fusing" (joining
| such a list back together again)_
|
| "Fission" better than "splitting" surely? ;)
| SeanLuke wrote:
| The speed tests appear to include the startup time of the virtual
| machine. We all know Java is slow to start up and Go is fast in
| this respect. That's not useful information.
|
| Rather than bias the results this way, much more interesting
| would be to test what the speeds are (1) after the VMs have
| launched, and also (2) when the VMs are hot, that is, Java has
| compiled your Lisp classes.
| iampims wrote:
| startup time is key to being able to write one-off
| programs/tasks and use them in workflows. It doesn't matter as
| much for long lived programs, but I don't think it's fair to
| frame this as "bias the results"
| tmountain wrote:
| Yup, once hotspot kicks in on the JVM, a toy language is going
| to have a hard time competing with that performance. It's
| definitely disingenuous to include JVM start up time in any
| benchmark. I used to run clojure benchmarks in a REPL and I
| would watch as the functions I was testing dramatically
| increased in performance over a few invocations. JIT
| compilation is pretty incredible.
| DeathArrow wrote:
| >JIT compilation is pretty incredible.
|
| Not if you compare to AOT for languages who lack garbage
| collectors. C, C++, Fortran would still be quite faster.
| pjmlp wrote:
| JIT cache is the answer, or one of the AOT compilers that
| exist for ages.
| tsimionescu wrote:
| There are some workloads where Java's JIT can beat C, C++,
| Fortran AOT compilation. They are probably not very common,
| but stuff like un-inlining can really save on instruction
| cache misses in workloads where the most likely path is
| consistent for fixed periods of time, but changes
| relatively often (for something like `if COND { foo(); }
| else { bar(); }` in a hot loop, where COND is sometimes
| true for a while than false for another while).
|
| Of course, Java also has a lot of overhead from the
| language and implementation level, because of things like
| no generic lists of integers, no struct embedding leading
| to lots of pointer-chasing, a tendency for over-allocation,
| and direct overhead of the advanced JIT itself -
| performance counters, dummy instructions to support de/re-
| optimizations on the fly etc.
| kaba0 wrote:
| Given sufficient time and a sufficiently expert programmer.
| It is not that easy to beat Java for complex programs where
| your workload is really variable and can't use the usual
| tools like arenas.
| dunefox wrote:
| > It's definitely disingenuous to include JVM start up time
| in any benchmark.
|
| It's not since startup time matters for CLI applications.
| pjmlp wrote:
| Easy, use JIT caches.
| Jach wrote:
| Eh, the JVM startup time is much less these days (read: these
| last several years), however loading Clojure is quite slow
| comparatively and that's what ends up dominating. On my
| machine, here's a hastily written Fact.java:
| import java.math.BigInteger; public class Fact {
| public static BigInteger fact(BigInteger n) { if
| (n.equals(BigInteger.valueOf(1))) { return
| BigInteger.valueOf(1); } else {
| return n.multiply(fact(n.subtract(BigInteger.valueOf(1))));
| } } public static void main(String args[])
| {
| System.out.println(fact(BigInteger.valueOf(100))); }
| }
|
| With OpenJDK 11.0.14, `time java Fact.java` gives real/user/sys
| of 0.267s/0.654s/0.033s. But that's not compiling the file
| first which some programmers aren't even aware is a thing Java
| can do now, if I do the usual thing of compiling with javac
| then on the class file `time java Fact` I instead get
| 0.050s/0.043s/0.010s. For Clojure, `time java -jar
| /usr/share/clojure-1.10/lib/clojure.jar fact.clj` gives
| 0.468s/1.069s/0.056s.
|
| Edit: for fun since the author mentioned Common Lisp, `time
| sbcl --no-sysinit --no-userinit --script fact.lisp` gives
| 0.005s/0.003s/0.002s. If I make a binary out of this instead,
| `time ./fact` gives 0.003s/0.002s/0.001s`. Since even a time of
| an empty C program's a.out can sometimes give numbers like
| 0.001s/0.000s/0.001s I'm clearly running into precision limits
| of the time command. (CL itself has a time macro that will
| helpfully give you a processor cycles count, about 290,000 on
| my machine for this.) I think the author is overestimating the
| difficulty of adding features to Common Lisp relative to what
| they plan to do with this toy; CL for scripting works great
| too.
| pjmlp wrote:
| You can also compile it with JIT cache and try a couple of
| times afterwards,
|
| For Java 11, the docs are on
| https://docs.oracle.com/en/java/javase/11/vm/class-data-
| shar...
|
| Latest versions have other improvements like PGO info as
| well.
| the_duke wrote:
| Or use Graal to compile to native.
| pjmlp wrote:
| Sure, for basic stuff maybe even the now unmaintained gjc
| would have worked.
| lawl wrote:
| I can just as well claim that ignoring startup with a small hot
| loop would unfairly favor a JIT compiler, since it ignores
| problems that would crop up in real world scenarios such as
| poor code locality.
|
| Basically what you're suggesting would be the absolute best-
| case for JIT.
| ledgerdev wrote:
| He does mention that he is looking for language to use for cli
| with fast startup. For cli and serverless cold start times
| become important so much so that clojure (non Graal complied)
| isn't usable for those scenarios.
| [deleted]
| pjmlp wrote:
| We all know that Java is slow to start up, because many don't
| learn how to use JIT caches or AOT solutions that exist for
| ages.
| lanstin wrote:
| Nice use of Greenspun as example data.
___________________________________________________________________
(page generated 2022-05-08 23:01 UTC)