
Ferret – A free software Clojure implementation - greydius
http://ferret-lang.org/
======
nathell
It's very notable in that it's literate Clojure.

[https://github.com/nakkaya/ferret/blob/0.2.8/ferret.org](https://github.com/nakkaya/ferret/blob/0.2.8/ferret.org)

------
penpapersw
Having written Clojure full-time for the past 5 years while writing
cleancoders.com has really spoiled me. Clojure's introspective nature makes
for some amazingly fast productivity because you can hook up your IDE to the
REPL and have a kind of super-REPL, which can really speed up development a
ton if you design your system it right. I'm not sure if this project can keep
that aspect because of how it compiles to C++. But if it does, then it could
really be invaluable in the Clojure ecosystem.

~~~
vturner
Curious what IDE you have set up to do the REPL driven development you
mentioned? I'm just starting out in learning Clojure and am finding various
options out there with vigorous proponents of each. I am wondering what
someone's real-world experience is after 5 years.

It's hard sometimes to find the editors/IDEs that might suite one particularly
well since the vast community is attached to a given platform.

~~~
Oreb
The most mature Clojure development environments right now are Spacemacs/Emacs
with CIDER (free) and IntelliJ IDEA with the Cursive plugin (commercial, but
inexpensive). Both are excellent.

~~~
ohpauleez
I'd also add that support in Vim and Neovim are also very good.

------
christophilus
Discovering this and
[Clojerl]([https://github.com/jfacorro/clojerl](https://github.com/jfacorro/clojerl))
within a week of each other is like Christmas come early.

~~~
patapizza
Just in case you've missed it:
[https://hy.readthedocs.io/en/stable/](https://hy.readthedocs.io/en/stable/)

~~~
didibus
I love Hy, but fyi, it is not as much a Clojure dialect as Ferret or Clojerl.
The latter two share syntax and semantics, while Hy only shares syntax.

------
jwr
This is very interesting. I could really use a good language on
microcontrollers, especially if core.async gets ported. Most microcontroller
code has a huge (and complex) event-driven state machine at its core. Rather
than making all of it explicit, I'd much rather use core.async to make it look
like sequential code. It would really help with reducing complexity.

------
dantiberian
Does anyone have any insight on the legal status of this project? It’s
licensed as BSD 2 Clause, but looks to be heavily derived from Clojure which
is EPL. AFAIK the EPL is copyleft and doesn’t permit relicensing without the
copyright holders’ permission.

~~~
nakkaya
Author here. I am actually curious about this myself. I originally released it
under GPL but then on another HN thread someone said anything compiled with it
also ends up being GPL, so I switched to BSD 2 Clause. I have not copy pasted
code from Clojure compiler BUT in order to keep the Ferret semantics the same
as Clojure semantics algorithms are identical. [1] shows + function in Ferret
and Clojure. As for data structures situation is similar, same semantics
implemented in C++ instead of Java with some differences/tweaks geared towards
embedded systems.

[1]
[https://gist.github.com/nakkaya/7050d5daf2c7034a25bb079658d8...](https://gist.github.com/nakkaya/7050d5daf2c7034a25bb079658d8b2dc)

~~~
e12e
Nothing wrong with BSD - but as for a GPL compiler with a run-time, you could
also look at the GCC/GNU libc licensing (GPL/LGPG). I do think it's important
people are aware that GPL on things with a run-time should probably have an
exception/use something like the LGPL - as you generally don't want
"documents"/artifacts produced with a tool, to forcefully inherit the license
of the tool used for creating them (eg: You don't want the word processor to
force a license on documents produced, or the drawing application apply
license to images - and the same goes for programming languages, IMNHO).

On another note, I'm not sure it would be quite possible to stretch "copyleft"
that far legally anyway - but that's another discussion - and at ending up
with an invalid license isn't really any good either, as that would leave you
with just copyright and no license grant - making the tool illegal to
copy/distribute...

~~~
dkersten
LGPL isn't enough for a runtime unless your entire runtime is dynamically
linked. Either GPL or LGPL with runtime exception works fine though (that's
what libc and others have, I believe).

That is, they added an exception saying that if you use it in a certain way
(unmodified, runtime for compiled code), then it's exempt from many of the
GPL's clauses. Used in any other way, however, and you must comply with the
(L)GPL

------
zaszrespawned
The favicon.ico of this site - looks exactly like half life logo.

[http://ferret-lang.org/ferret-styles/favicon.ico](http://ferret-
lang.org/ferret-styles/favicon.ico)

[https://www.google.co.in/search?q=half+life+logo&oq=half+lif...](https://www.google.co.in/search?q=half+life+logo&oq=half+life+logo)

What is that all about...

~~~
nakkaya
Author here. It is the Half-Life logo. I wanted a lambda symbol for a favicon,
love the game too so I settled on a open licensed logo.

~~~
vertex-four
I'll point out that the Half-Life logo is trademarked in the EU in several
situations related to video games, including the programming of video games.
Be careful attaching it to e.g. a tutorial on using Ferret to write a game, or
an integration with a game engine, etc.

------
vanderZwan
I wonder if it could also somehow lift the reactive synchronous concurrency
bits from Céu[0] in a library. Céu is probably my favourite embeddded language
to program in from a _" thinking about concurrency"_ perspective. I'm not sure
how one would go about it though, since Céu is imperative, and I'm not sure if
that imperative aspect is fundamental to its type of concurrency or if it
clashes with idiomatic Clojure.

If it _would_ be possible you'd probably have everything I could want in one
embedded language.

[0] [http://www.ceu-lang.org/](http://www.ceu-lang.org/)

~~~
nakkaya
Author here. Did not knew about Céu till now, just watched the intro video. I
maintain a behaviour tree [1] library called alter-ego [2] (code needs
cleanup) which already contains some of the constructs. In behaviour tree
terms par/or is parallel selector and watching is a interrupter node. [3] So
it can be done in Ferret on a general purpose PC using C++11 concurrency
constructs, for embedded targets it will require co-operative multitasking
which is on the roadmap.

[1] [https://nakkaya.com/2010/06/29/alter-ego-a-reactive-ai-
libra...](https://nakkaya.com/2010/06/29/alter-ego-a-reactive-ai-library/) [2]
[https://github.com/nakkaya/alter-ego](https://github.com/nakkaya/alter-ego)
[3]
[http://aigamedev.com/open/article/parallel/](http://aigamedev.com/open/article/parallel/)

~~~
vanderZwan
> In behaviour tree terms par/or is parallel selector and watching is a
> interrupter node.

I see the resemblance, but I'm not sure if that's a perfectly right analogue.
The description in your third link says the parallel code truly runs in
parallel. However, Céu is concurrent _but not parallel_ , making the
concurrent code deterministic and easy to reason about: if multiple blocks in
a par/\-- construct await on the same event, they will execute in lexical
order (which is similar to the behaviour described in the first link).

For real parallelism, you'd basically have to have multiple Céu programs
(devices) communicate through external inputs/outputs.

I guess the real question I'm asking is whether the library follows the model
of a synchronous programming language.

[https://en.wikipedia.org/wiki/Synchronous_programming_langua...](https://en.wikipedia.org/wiki/Synchronous_programming_language)

BTW, the intro video is very outdated: on top of the basic par/\--- and await
construct, the "organism" is replaced with cleaner code/tight and code/await
forms to create more complex abstractions:

[http://fsantanna.github.io/ceu/out/manual/v0.20/statements/#...](http://fsantanna.github.io/ceu/out/manual/v0.20/statements/#code)

------
gleenn
Seems like a cool project if you already know Clojure and hate the start up
time, but also seems like it sidesteps one of the main benefits of Clojure
which is Java interop obviously... Which Clojure has to do a fair number of
handsprings to accomplish. Begs the question, why pick Clojure as the lisp to
compile to C++? Why not Racket or Common Lisp etc?

~~~
kazinator
The relationship with Java is both a benefit and a disadvantage of Clojure.

> _Why not Racket or Common Lisp etc?_

These already have solutions in the compilation space.

Kyoto Common Lisp (KCL), a fairly old implementation tracing back to the
1980's, and its descendant GNU Common Lisp (GCL) compile to C.

Embeddable Common Lisp (ECL) also contains a Lisp to C compiler.

Of course, numerous CL implementations compile to native code without the C
route.

~~~
lispm
Btw: ECL is also a descendant of KCL. Like AKCL, MKCL, Delphi CL, Ibuki CL,
GCL.

Other Lisp-to-C compilers like CLICC, mocl, Thinlisp, and a few others are not
descendants of KCL.

~~~
kazinator
I'm looking at CLICC now a bit.

Boy, the implementors made a significant mistake in this one. Though CLICC is
not intended to be a complete Lisp system, but a Lisp application, they
insisted that CLICC has to itself be a CLICC-compiled application. And so what
that means is that, then, programs being compiled with this bootstrapped CLICC
are severely limited as to what they can do _at compile time_ (in macros),
simply because of the crippled run-time environment of the CLICC-compiled
CLICC compiler which has to run without the benefit of an actual CL runtime.
Whereas if CLICC had been kept as a Lisp-compiled program, only the run-time
parts of user code would be restricted to the "CL1" language; macros could be
written in full CL.

------
piotr-yuxuan
Congratulations, it's both very impressive and promising :) Thank you for that
fine example of literate programming :)

I'd suggest you add a way for people to financially support you so you could
keep working on this project.

------
billsix
I've been looking for a language which provides Software-Transactional-Memory
with persistent data structures which fits in 2KB RAM on a microcontroller.

~~~
tomsmeding
I doubt you'll find that quickly. You can't do much in 2kb if you don't want
to mutate your data, I think. I don't know much about STM, but I'd wager that
uses some extra bookkeeping memory as well. So unless your own memory
requirements are really low, this won't work.

~~~
meredydd
Fun fact: Clojure is one of the few languages in which STM is easy!

You're right in the general case - STM incurs significant bookkeeping overhead
(at least a word per mutable location, usually more), which is one of the
reasons it never took off. (The actual reason is the CPU overhead, which slows
down memory accesses so much you've lost all the performance you might gain
from parallelism.)

Clojure sidesteps this by having an _incredibly_ small number of mutable
locations. With a persistent data structures, every mutation operation already
builds its own private version of the structure, and then atomically changes a
pointer to point to the new version. So you've got MVCC built in, and you only
need transactional metadata on one location (the ref).

------
jwhitlark
He wrote about the motivations here: [https://nakkaya.com/2016/06/10/ferret-a-
hard-real-time-cloju...](https://nakkaya.com/2016/06/10/ferret-a-hard-real-
time-clojure-for-lisp-machines/)

------
davidgrenier
Always look at the memory management story when you stumble upon something
like this.

~~~
mtm
It seems well thought out:

* malloc/free (ref counting GC)

* memory pooling (no heap, stack-based for memory constrained systems)

* third party allocators

* third party GC

Details here: [http://ferret-lang.org/#sec-4-2](http://ferret-
lang.org/#sec-4-2)

~~~
tomsmeding
I love the idea of ref counting, but I'm unsure about the handling of memory
cycles. In a plain ref counting implementation, these will not be cleaned up,
resulting in a memory leak.

I didn't find anything on cycles in the linked page, maybe the problem is not
relevant in most real-world clojure code?

~~~
nakkaya
Author here. As derefr said with Clojure semantics you can not create cycles.

~~~
tomsmeding
Thanks, now I think about it, that makes a lot of sense.

------
physicsyogi
Does this have Clojure's persistent data structures? The docs say it has
immutable data structures, which isn't exactly the same thing. (Edit: added
the second sentence)

~~~
chrisseaton
Those persistent data structures are implemented in Clojure aren't they? It's
not a feature of the compiler I believe. So if it can run Clojure code then
that code can be the persistent data structures library if you want.

~~~
venantius
They are a feature of the compiler - Clojure's are implemented in Java.

~~~
marctrem
And Clojurescript's are implemented in Clojurescript!

------
comex
Viewing the site in iOS Safari, I get several pages of what appears to be
random binary gunk rendered as HTML. Something wrong with compression headers?

~~~
pivo
Seems to be working fine for me on iOS. Any particular page that's broken for
you?

~~~
comex
The homepage, but just now I refreshed and it started working. Odd. (I’m
pretty sure I tried refreshing before, and it didn’t work then.)

~~~
ungamed
I smell an infoleak. What version are you on ? See if you can recreate it with
your history. The flaw might be worth something.

------
agumonkey
Ohh embedded friendly, you're spoiling me.

------
StreamBright
This is amazing! I am wondering what was the motivation to implement it.

------
didibus
Would love to see a "Differences with Clojure" section.

------
kbuchanan
Can anybody tell whether it supports multimethods and protocols?

~~~
asragab
[http://ferret-lang.org/#outline-container-sec-7](http://ferret-
lang.org/#outline-container-sec-7)

The last item on the Roadmap underneath the "Core" Section lists multimethods.

