Skip to content

Collaborating #1

@SwiftLawnGnome

Description

@SwiftLawnGnome

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 from cl:t), false, and empty list (both distinct from cl:nil)
  • persistent lists
  • persistent vectors (based on your implementation), and persistent maps and sets (based on cl-hamt)
    • all are funcallable
  • IMeta, IHashEq, IReference and many other interfaces from Clojure's java source
    • Currently all implemented with cl:defclass, ideally these would be defined with defprotocol
  • destructuring, both for maps and sequences
  • loop, but using labels so 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 that recur is in tail position
  • fn, supporting multiple arities, a name, and recur within the bodies
    • normally a regular function is returned, but using with-meta on it upgrades it to a Fn.
  • 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, and auto-gensym# syntax). It seems to work pretty well.
  • 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 def sets the symbol's value a la cl: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 and Keywords, 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 and Keywords, 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
  • variadic functions. In CL, the &rest arg must be a proper list. In Clojure, an & arg can contain any ISeq (from what I can tell). Converting every ISeq to a proper list won't do either, because in Clojure you can apply functions to infinite lazy sequences.
  • monitors. every Object in java, and consequently all data in Clojure, can function as a monitor, and the locking macro 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 let in the thread's function, but documentation on this is practically non-existent. push-thread-bindings and 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions