[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)