Regarding Guile, and, mind, I'm on macOS, but I found it not easy to get started with.
I'm looking for a compiled Scheme or Lisp. By that I mean, I want "prog.ext" to create the executable "prog".
I want this because I want to make some command line utilities, and I would like the actual code compiled (vs some p-code bundled with an interpreter).
I had tried to get started with Guile, as all of its packages looked attractive, but was stymied. It's been awhile, so I can't express details. It had to do with a combination of things like packages, modules, and I know I ran into a version issue (I think I wasn't running the latest version from my package manager, so it didn't have something in the documentation).
Anyway, for such an extensive system, I found it surprisingly frustrating.
I've been trying Gambit, which seems like it would be a really nice fit, but it's fighting with my Mac, because macOS doesn't put stuff in /usr/include (wchar.h in this case), and all of my efforts to fix that have failed (save I have not tried upgrading to whatever the latest macOS is).
Maybe I can try ECL, maybe that will work.
But, anyway, Guile, while attractive, just surprised me at how I wasn't really able to make it work for me enough to make me look elsewhere.
What about chicken scheme or chez scheme?
Chicken kind of felt like a dying ecosystem when I tried it, and it's also not very fast. The standard library itself is kind of limited, so if I couldn't find an egg for something I wanted to do, I felt very stuck.
Chez is good because it's supported by Akku, but I'm not sure if it will ever support R7RS. It does have a really nice FFI though, and the docs are very good.
R7RS isn't worth supporting right now.
R5RS is too small for real work unless you add tons of SRFIs, so they created R6RS for people who want to get stuff done. But the the R5RS people got ticked off because "its too big".
R7RS was supposed to be a compromise with a tiny R7RS-small, but later adding most of the R6RS features with R7RS-large. It's now been a decade and R7RS-large seems to be completely dead.
R7RS is very much worth supporting; there'll shortly be a Chicken Scheme 6 with full support for R7RS-Small.
R7RS-Large development is slow, but not at all dead.
It's been 10 years since R7RS launched and I believe around 15 years since R7RS-large began work. That goes a bit beyond "slow".
To put it in perspective, that is the amount of years that have taken C++ to adopt modules and concepts (still ongoing), Java to research and slowly start deploying Valhala, .NET to start having something better than NGEN / .NET Native across all workloads and beyond Windows, migrate an ecosystem to Python 3,....
We're talking the 2008 timeframe. When George Bush reigns and the biggest films are The Dark Knight and Iron Man. Halo 3, CoD4, and Crysis are new. Our latest generation of devs are just toddlers.
Stackoverflow is created.
The world is running on Windows Vista (XP actually, but that's another story).
Github is created.
Facebook pulls ahead of MySpace in user count for the first time.
Blu-ray finally beats HD-DVD.
People think the Large Hadron Collider will end the world when it turns on.
Randy Pausch's book "The Last Lecture" becomes a New York Times best seller.
First Android phone and iPhone 3g release this year with ARM11 CPUs. The App Store is brand new.
JS is still slow and Chrome releases to change that.
Amazon buys Audible.
Rust essentially doesn't exist.
AirBnb is founded.
Bitcoin doesn't exist yet (though the paper drops this year).
Memristor is finally proven to be possible.
The 46th Mersenne Prime is found.
USB-3 spec drops for companies to start working on.
Core i7, and Atom on 45nm are the latest CPUs (AMD also launched Phenom on 65nm). GTX280 and HD4870x2 are the fastest GPUs around and people are discussing how overpriced top-end GPUs are at $450-550 and complaining that these GPUs use 200-250w of power.
Tesla Roadster releases for about $100,000 and Musk launches the first car (promised to the actual founder) into space out of spite.
That wall of text doesn't change the point of my comment.
Not everything evolves at the speed of TL;DR; attention span folks wish for.
We aren't talking about the implementations, we're simply discussing the spec. Can you name another language spec that took over 15 years from conception to completion?
Even Common Lisp which languished for a terribly long time due to infighting didn't take that long despite being a much more comprehensive and difficult spec.
If you read carefully my original comment, you would have understood specs were part of the description.
Just as an example, C++ concepts were originally presented in 2005 [0], dropped in 2009 [1], redesigned as Concepts Lite in 2013 [2], graduated to technical specification in 2015 [3], added to C++20 roadmap in 2020 [4].
Making it 15 years to fully work out a language feature and related library functions, and even what came out 15 years is a subset of the original proposal, not going to bother with specification refinements after C++20.
Everything goes faster if it were us doing it, right?
[0] - https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n17...
[1] - https://isocpp.org/wiki/faq/cpp0x-concepts-history
[2] - https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n37...
[3] - https://en.cppreference.com/w/cpp/experimental/constraints
[4] - https://www.iso.org/standard/79358.html
And in the same time span, we have Elixir, Rust, Go, Julia & Kotlin comes from the void into the mainstay.
Also, Larceny (R7RS, UTF-8, compiles to x86, x64, ARM, C).
I've got similar interests to the OP and the parent comment. I had some fun with both Chicken and Chez, but building standalone/static binaries was a bit of a pain.
The interesting thing for me (a while back) was realizing that even doing something as simple as an HTTPS request would be a bit of a challenge: https://taoofmac.com/space/blog/2019/06/20/2310
I suggest Gauche as an easier-to-use Guile alternative. I had similar annoyances with actually getting Guile to just do what it says it's supposed to be able to do.
I've advertised Gauche frequently here on HN (including in another comment in this thread). I have no affiliation with the project, but I like it a lot and I think it's under-appreciated. Its author hosts its documentation under the domain name "practical-scheme.net" (https://practical-scheme.net/gauche/man/gauche-refe/index.ht...) and I think the name is very well deserved.
Easier to use in what sense?
Easier to just install the interpreter using any package manager, open up the docs, and start writing useful scripts. All of the batteries included in the standard library go a long way towards helping with that as well.
I remember fighting with Guile a bit to achieve the same goal, although I don't remember the details at this point, and my experience might be outdated now. I do remember that some things which are included in Gauche (e.g. JSON) are 3rd-party libraries in Guile. Also I don't understand why some of their libraries are called "ice9". What's with the Cat's Cradle reference? Is it a pun? It it someone's username? Is it a "contrib" library of some kind that was absorbed into the standard library? Why didn't the name get changed?
Guile is really designed with embedding into a program in mind. Gauche is definitely more geared towards their use case, but I think their issues with Gambit can probably be resolved with a few environment variables or command line options
An interpreted lisp could fulfill this requirement. I created one such lisp. I came up with an ELF code embedding method that lets me add lisp code to the interpreter executable itself. I can add lisp modules and they become loadable. I can add a main function and it gets executed automatically.
I wrote about it here:
https://www.matheusmoreira.com/articles/self-contained-lone-...
The lisp itself is not ready to be used for anything serious at the moment. I'd really like to see this ELF embedding show up in other languages though. It's the best solution I found to the perennial self-contained executable problem.
This has nothing to do with interpreted or compiled. SBCL compiles all code to native code - it has optional interpreter functionality, which is not needed most of the time.
Creating an sbcl executable for Linux is simply a call to dump an application, add the runtime and save that to some place. The there is an executable on the disk. The only thing is that the executable is not small or tiny -> but they include the compiler/loader/repl/..., which is useful.
Many other Lisps also can create executables. A LispWorks executable application on my Linux/ARM64 starts with roughly 7MB and it has unused stuff removed by a "treeshaker".
I agree with you. That's what I tried to express in my post. They asked for a compiled lisp but the actual requirement was self contained executables which interpreted languages could also fulfill.
Yes. Many Lisp implementations even can mix it in one executable. One, two or three modes of these: source interpreter, byte code interpreter, native code.
Janet is the perfect lisp for cli tools. https://janet.guide. It is my favorite.
I'm still not sure of what the Janet value proposition is compared to an R7RS Scheme. Not that it shouldn't exist! I just don't quite get the use case either.
Janet’s value proposition is pretty similar to Lua — easy embedding, simple C API, minimalist runtime. But Janet improves on some weird Lua warts (block-scoped variables by default, 0-indexed collections, separate types for sequential and associative arrays). Plus it bundles a pretty nice standard library.
I’ve seen this comparison before, so clearly Janet isn’t doing a good job of explaining itself, but I think the only thing Janet and Scheme have in common are a few parentheses. Different core data structures, different feelings about mutability, completely different macro system…
Guile and Janet share PEGs (sorta) and embeddability but I didn’t think those were standardized at all. (I don’t really know any schemes.)
, should be (unquote) and ,@ should be (unquote-splicing) while ; is for comments, yet Janet completely disregards this convention. It's stupid, but I dislike Janet because of this.
Guile always surprised me not because of anything LISPy, but because of its relationship with TCL
https://vanderburg.org/old_pages/Tcl/war/
In RMS’ message that started that discussion, he stated that the GNU project intended to provide two languages — one Lisp-like (which I assume eventually became Guile), and one with a more algebra-like syntax. Did anything ever come out of the latter?
The current advice from GNU is that Guile is the one true language for the project[0]. There are terms of languages that are currently part of GNU[1] but none that seem to meet the description of algebraic and blessed.
[0] https://www.gnu.org/prep/standards/html_node/Source-Language... [1] https://www.gnu.org/manual/blurbs.html
My understanding is that guile is an extension language. Create a prog.c and link to guile, that's how I think you can create an executable.
I originally got a PAUSE id to upload to CPAN to add support for returning continuations from Guile code to Perl and being able to resume them as a function call on the Perl side later.
That let me write linear async-await-ish logic code in Guile and then have all the I/O and grungy stuff handled by an event driven layer in Perl space.
(this was about 20 years ago, give or take, but I still periodically get accused of writing lisp in whatever language I'm implementing things in at the time ;)
Creating a C program that links to libguile is kind of a legacy use-case at this point. It was the original purpose of Guile back when it was but a simple interpreter. The trajectory for the past decade or so has been to build up Guile as a platform for writing your entire application. Rather than embedding an interpreter in a C program, the recommended approach is to write a Scheme program that uses the C FFI if and when necessary. The interpreter was once written in C but is now written in Scheme (a minimal C interpreter is kept around for bootstrapping purposes.) There's a sophisticated optimizing compiler that emits bytecode for the Guile VM as well as a JIT compiler. A new garbage collector and a Wasm compiler backend are currently being developed. The big missing piece is ahead-of-time native compilation, but the work on the Wasm backend will help that along as it needs to solve a lot of the same problems.
Try Racket. It’s easy to setup (from experience on macOS), easy to learn, batteries included, and a compiled Scheme (create binaries via `raco`, https://docs.racket-lang.org/raco/exe.html).
It’s real highlights are very powerful macros and the ability to override the reader, so you can effectively create arbitrary languages (examples include reimplementations of Java, Lua, and Datalog, and a documentation generator with embedded Racket called Scribble). IMO it’s a research language first and foremost. But it has unusually good production support and online resources (I mean it when I say it’s easy to setup and learn), so I think it fits everything you asked for.
+1 for the Racket on macOS recommendation. It is really easy to make your own local libraries (but different than small local libraries in Common Lisp using Quicklisp) and live nicely on macOS. I wrote a Racket book, which I am still actively adding to that you can read online: https://leanpub.com/racket-ai/read
I can highly recommend Chicken Scheme, it does exactly what you want :) It has also a nice friendly community, and a couple hundred extensions.
chicken is a very pleasant compiled scheme, with a friendly community and a decent set of packages available.
sbcl compiles and generates an executable quite nicely.
The creator of Programming Language Benchmarks 2 is on Apple Silicon, and apparently SBCL compilation works out of the box: <https://github.com/attractivechaos/plb2>.
Guile itself is cool. Its documentation, however, sucks. It's really quite terrible. The manual is a haphazard mix of several reference documents, a half-hearted tutorial, and whole lot of jargon that's not explained.
It seems there was a period where Guile was considered a serious contender for the space now occupied by Python. My impression is that GNU lost mindshare and the opportunity because the Guile documentation takes a simple, elegant language and makes it inaccessible for newcomers. Python was known for being well-documented and easy to approach.
I'm curious what other's take on the history is.
Years ago I used Gambit Scheme heavily on macOS. Back then I always liked to build it from source. The source repo also has examples that are useful to see how to do common things. I found Gambit was really cool for building little command line utilities, but now I get good mileage from just making small text command line utilities in SBCL, or using LispWorks Pro.
I'm not a mac user but I got someone who had never used guile before setup using homebrew to get guile and emacs, and then the guile homebrew tap (https://github.comad/aconchillo/homebrew-guile) for guile libraries.
What's wrong with p-code bundled with an interpreter?
Some libc+cc combos add some code to do things the target architecture doesn't support natively, like ints of certain sizes. From this to the example you said, where in this spectrum do you consider it not to be compiled anymore?
Unless you're debugging the emitted binary instructions, why does the compiled output matter if it reaches the desired CPU and memory requirements?