Clojure is an excellent step forward, and I believe there are many
bright ideas there that are clearly worth pilfering, but complete
Clojure compatibility in L# seems unnecessary from my point of view.
In particular, I believe that the Clojure community is doing good work
in terms of choosing names. To me at least, the names chosen for
everything in Clojure are a definite improvement over the names for
the 'same' things in Scheme or Common Lisp.
Three great ideas I would steal right away:
1) Reader syntax for what Clojure calls Vectors and HashMaps
- It looks like this is partially done, at least for Vectors (Using
.NET Lists). A curly-brace syntax for some kind of map-like data
structure (.NET Dictionary?) would be neat.
2) Seq and Assoc abstractions, which allow algorithms to be written in
a data structure independent way.
- Again, this appears to be partially done, at least. It's been a big
win in a couple of my Clojure programs to be able to so easily switch
a representation of some of my data from a Vector to a HashMap, or
vice versa.
3) Platform inter-op macros.
- doto, ->, .., etc. Clojure makes it as easy as possible to call
into Java code and libraries. The more L# can do this for .NET, the
better.
---
The one big Clojure concept that would make full compatibility really
hard is their concurrency semantics: dosync, refs, agents, vars, and
their persistent immutable data structures.
Clojure is at the forefront of some interesting research in new
concurrent programming models and their system of refs and agents atop
persistent data structures is a huge jump forward in concurrent
programming, but it's far from perfect. Emulating all of those systems
that just for compatibility would be painful. It would be better to
focus on a completely separate niche, perhaps something like
'lightweight scripting'. Or, if you want to attack concurrent
programming models with L#, it could be better to maybe seek
incremental improvement over what Clojure's done in this area (perhaps
through simplification).
> ... this seems messy, but maybe I'm
> just being stupid.
>
> (defn iterator-to-vector [iter]
> (loop [coll (vector)]
> (if (.hasNext iter)
> (recur (conj coll (.next iter)))
> coll)))
>
I've read that Clojure Seqs are Java Iterable, but I don't know how it
works the other way round. There may be a more elegant way to do what
you've done there, but I don't know what it is right off the top of my
head.
> 2. I originally set out to use the Dynamic Language Runtime (DLR) (The
> thing that underpins IronRuby and IronPython), but I found that I didn't
> need all that complexity and the stuff in LINQ expression trees was good
> enough for compiling LISP.
That is super interesting and really great. What luck to have stumbled
upon the LINQ expressions. I wonder if something like L# was
envisioned during the development of LINQ, it's such a good fit.
> BTW, Have you seen my LSharp in the Cloud video? -
> http://www.robblackwell.org.uk/?p=152 I recently managed to get LSharp
> working in Windows Azure, with a publicly accessible REPL. LSharp
> continues to throw up new and fun things for me too!
>
I hadn't seen the video, thanks for the link. I like the 'probing'
that you did right off the bat. (: The .NET security model, especially
concepts like application domains and per-assembly permissions make it
easy for MS to secure something like Azure.
Keep up the good work,
-Harold
Heh, punctuated equilibrium.
Given that, I think the things I said earlier are still good. Pilfer
good ideas from Clojure as applicable, focus on the lightweight .NET
scripting niche, and let others have the glory of revolutionizing
concurrent programming. (:
-Harold