-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Hello,
Several months ago I forked this repo and started working on it. After some additions, I found myself unable to work with such a large codebase with which I was so unfamiliar, so I decided to try starting from scratch, borrowing some pieces from your project. I expected this to be something I played with for a week then forgot about, but I ended up spending a great deal of my free time working on it, and have made a lot of progress. I had assumed this project was abandoned so I didn't feel the urgent need to contact you, but now that I see you're still maintaining this project I'd like us to collaborate.
Some of the more significant things my version has (not sure which of these are also in yours):
true(distinct fromcl:t),false, and empty list (both distinct fromcl:nil)- persistent lists
- persistent vectors (based on your implementation), and persistent maps and sets (based on cl-hamt)
- all are funcallable
IMeta,IHashEq,IReferenceand many other interfaces from Clojure's java source- Currently all implemented with
cl:defclass, ideally these would be defined withdefprotocol
- Currently all implemented with
- destructuring, both for maps and sequences
loop, but usinglabelsso that TCO is performed by the compiler, and no check is performed to ensure it's used properly- Note: I have toyed with a version using
tagbody, which works fine, but also doesn't confirm thatrecuris in tail position
- Note: I have toyed with a version using
fn, supporting multiple arities, a name, andrecurwithin the bodies- normally a regular function is returned, but using
with-metaon it upgrades it to aFn.
- normally a regular function is returned, but using
for(producing an actual lazy-seq)- A readtable with map, set and vector literals, #_ to discard next sexp, @ to deref, ^ for metadata, #() for functions
- This readtable is a bit hacky, but I'm also testing one that parses forms into clojure data structures, and supports syntax-quote (including ~@ with any
Seq, andauto-gensym#syntax). It seems to work pretty well.
- This readtable is a bit hacky, but I'm also testing one that parses forms into clojure data structures, and supports syntax-quote (including ~@ with any
reduce,transduce, and many, if not most, transducers from Clojure.core implemented- Atoms, Namespaces, Vars
- Not tested in depth. Vars are probably in the most complete state of the three.
- Vars are funcallable, and #' syntax for vars works, because
defsets the symbol's value a lacl:defvar, and sets the symbol's function to a Var. The Var's funcallable-instance-function just applies its value to the arguments.
- A lot of scaffolding for Agents
- If I remember correctly they do work fairly well, but the STM has to be developed before moving forward
Symbols andKeywords, distinct from CL keywords and symbols- this part's really tricky, and my glue code between the two is very shoddy
=(it works okay, still plenty of work to be done)- Pretty printing vectors, sets, maps, namespace qualified
Vars,Symbols andKeywords, etc. - A ton of other clojure.core functions and macros
I think that's most of the major developments. Some major roadblocks I've realized while working on this:
- Atoms. The only free/libre CL implementations that support CAS on struct/object slots are SBCL and ECL. This means that these are probably the only dists that can be targeted
- Additionally, ECL (somehow) seems to not support timeouts in any form (needed for
deref), so it may also not be a viable platform, leaving just SBCL
- Additionally, ECL (somehow) seems to not support timeouts in any form (needed for
- variadic functions. In CL, the
&restarg must be a proper list. In Clojure, an&arg can contain anyISeq(from what I can tell). Converting everyISeqto a proper list won't do either, because in Clojure you can apply functions to infinite lazy sequences. - monitors. every
Objectin java, and consequently all data in Clojure, can function as a monitor, and thelockingmacro can be used to synchronize code around an object. I have no idea how to make(locking 3 ...)work in CL. - thread local bindings. From what I can tell, in SBCL the only way to establish thread local bindings is via a
letin the thread's function, but documentation on this is practically non-existent.push-thread-bindingsand co may need to be manually implemented with hash-tables/maps or similar.
If you'd like to merge the projects then let me know and I can put my repo on GitHub and we can figure out how to fit the pieces together (but I must warn you that I'm very busy and generally suck at responding)
Thanks