News

Concurrency Talk

On March 20th, I gave a talk  on Clojure and concurrency at a meeting of the Western Mass Developer's Group. The slides,  source code for the demo, and audio from the talk are online. 


4/9/2008 Update: Video of the presentation is now up on Clojure TV.


4/2/2008 Update: The audio for the presentation has been replaced with a glitch-free version, so if you've been suffering through, or abandoned, the first go round, please download the latest.


image

20080329 Release

Many new features, including anonymous fn reader syntax, functional tree zippers, streamlined documentation and metadata in defn/defmacro, first-class sets and set algebra, proxies that can extend classes, comprehensive in-source documentation, and many new library functions. Not all of the new functionality has documentation in the prose part of the site yet, but the new API doc page should be comprehensive.


There is some renaming/removing in this release:


removed implement, use proxy

renamed set to ref-set

renamed ! to send

renamed select to select-keys

renamed to-set to set

renamed scan to dorun

renamed touch to doall


Thanks to all for your feedback and support!


Rich


Changelist:


added dosync
fixed when-first when empty non-seq coll
setup default bindings for smap before/after
tightened smap range
re-enabled clearing locals on tail calls, but track locals used in catch/finally clauses and avoid clearing them
made FnExpr public
added locals clearing on tail calls
added arg clearing on tail calls
host calls - use subsuming method, if any, rather than first found, when overloaded w/same arity
made Repl load files in 'user ns, changed Repl to serve as better example of hosting Clojure in Java using public APIs
made IFn extend Runnable
stricter overload resolution 
accessible macro metadata via *macro-meta* 
more type hints in boot.clj
fixed send, send-off docs
(str false) => "false"
got rid of input purge on exception
changed use of ! to send in await, await-for
added if-let, when-let, replace
made distinct lazy
switched to readLine on input purge in Repl exception handler
added newline on EOF
proxy - filter all considered methods in superclass traverse, to avoid implementing method turned final in derived
intern compiled string literals
repl - added System.exit call
renamed ! to send, added send-off, *agent* is currently running agent
fixed bug with invoke >= MAX_POSITIONAL_ARGS
fixed slurp not closing file
fixed build dep of Keyword on AFn, added throwArity to Keyword
prevent nested #()s
on repl exception, put cause message first
prevent take from advancing coll more than n times
improved error message for bad arity
added flush and read-line
fixed bug in ASeq toArray(Object[])
bind source paths when reading boot scripts from jar 
switched to Clojure's box from ASM's in proxy in order to handle booleans correctly
proxy - make method set union of declared and public methods in order to catch unimplemented interface methods of abstract classes
new metadata/docstrings
fixed ns prefix on fns - now clojure.fns.
fixed fn name propagation, added clojure.fns. namespace segment prefix on all generated fns
moving to new metadata/docstrings
persistent vector - keep tail out of tree, speeding up cons/pop
added new metadata/docstring handling to defn, type hint to defmethod, begin moving to new metadata/docstrings
made munge public, upped SMAP range to 10000
renamed PersistentHashMap.INode.seq to nodeSeq to avoid override of AMapEntry.seq in Leaf
fixed MapEntry.seq to use AMapEntry.seq
fixed hash-set of empty coll/nil
renamed select select-keys
renamed set to ref-set
renamed to-set to set, returns a set now
added set.clj, set operations and 'relational' algebra
fixed bug with nested try blocks
sets - read/print/compile/metadata, hash-set, sorted-set, disj
starting set support
added EnumerationSeq and support for Enumerations in seq
added SeqEnumeration
added destructuring to loop
added slurp, subs, max-key, min-key
doc reformatting
fixed declared method detection
unified map entry and vector equality and hash
support conj of vector pair onto map
made map entries vectors
proxy support 
auto-load xml.clj, zip.clj and proxy.clj from clojure.jar
added (class x), returns getClass
added cast 
cast arg to Number in unary +, *
added var?, special-symbol?
changed resolve to return nil if not found
added tree-seq, file-seq, xml-seq
try using getContextClassLoader in implement
try using getContextClassLoader as default
more examples
added zip.clj generic zipper
added symbol support for ->, so (-> x :a) ==> (:a x)
added RT.var() helper, made CLOJURE_NS and CURRENT_NS public
xml - fix for mixed content, extensible parse accepts parser fn
completed docs
allow use of not-yet-existing names qualified with current namespace when internNew
get now returns nil on non-maps
fixed access on helpers, contains? now returns false on non-maps
avoid unread(-1)
more docs
return false consistently on < <= > >= ==
defined dissoc for no keys
fixed refer NPE on non-existent namespace
command line args can follow '--', in Repl and Script
print doc indicates macro status
find-doc sorts names
renamed scan to dorun, touch to doall 
support for variadic assoc and dissoc
added re-pattern, print-doc, find-doc
more docs
doc formatting
doc macro
added anonymous fn reader syntax #(), and arg literals %, %1 ,%n %&
added rand, rand-int and defn-
changed prstr to pr-str in assert
fixed self-call in defmulti macro

API Docs

I've added single-page documentation for all of Clojure's functions and macros, arranged alphabetically within namespace. It is generated from the source and reflects the current (SVN) version.

Clojure Presentation In Northampton, MA

On March 20th, I will be giving a talk  on Clojure at the regular meeting of the Western Mass Developer's Group.


The meeting will be at 243 King Street in Northampton and will start at 6:30.


Rich

Clojure TV

I hope to do a series of screencasts on Clojure. They will be informal (often recorded at think-tank lunches I do with some friends of mine), but hopefully informative. Both halves of the first one are up.


Rich

Dynamic Proxies

Clojure has offered the ability to create instances of interfaces dynamically through its implement macro. This feature was built upon the java.lang.reflect.Proxy system, and, like it, was limited to deriving from interfaces only.


I've added to Clojure (in SVN as of rev. 708, not yet in release) direct dynamic proxy generation through the new proxy macro. It works just like implement with these differences:


  • The first item in the vector of supers can be a non-interface class. (If no class is provided it defaults to Object)


  • The vector of interfaces is followed by a (possibly empty) vector of arguments to the superclass constructor.


  • Each method fn is now implicitly passed an additional first arg called this, whose value is the proxy obect itself.


  • A method fn can have multiple arities.


  • A method fn can override a public or protected method of the superclass.


  • It is possible (using update-proxy) to alter the method/fn map of an existing proxy, and thus change its behavior, without altering its identity.


Proxies supercede implement, and all usage of implement should be changed to proxy, which is likely to offer better performance.


The use of proxy to implement interfaces is still primary. Deriving from concrete classes is not something I encourage generally. But we've all been faced with libraries that unfortunately require concrete derivation in order to interoperate - now with proxy you can.


There are some limitations of proxying vs direct derivation. While method fns can override protected methods, they have no other access to protected members, nor to super, as these capabilities cannot be proxied.


Please switch over your code to use proxy instead of implement, and try it out in situations where you need to derive from non-interface classes, and let me know how it works for you.


Rich


p.s. For those interested in bytecode generation and compiling, the implementation of proxy  is written in Clojure (src/proxy.clj), and provides and example of using the embedded ASM bytecode library from Clojure itself.

Zippers - Functional Tree Editing

I've added (in SVN as of rev. 698, not yet in release) purely functional, generic tree walking and editing, using a technique called a zipper. For background, see the paper by Huet. A zipper is a data structure representing a location in a hierarchical data structure, and the path it took to get there. It provides down/up/left/right navigation, and localized functional 'editing', insertion and removal of nodes. With zippers you can write code that looks like an imperative, destructive walk through a tree, call root when you are done and get a new tree reflecting all the changes, when in fact nothing at all is mutated - it's all thread safe and shareable! The next function does a depth-first walk, making for easy to understand loops:


(load-file "/Users/rich/dev/clojure/src/zip.clj")
(refer 'zip)
(def data '[[a * b] + [c * d]])
(def dz (vector-zip data))
;find the second *
(-> dz down right right down right node)
-> *

;remove the first 2 terms
(-> dz next remove next remove root)
-> [[c * d]]

;replace * with /
(loop [loc dz]
  (if (end? loc)
    (root loc)
    (recur
     (next (if (= (node loc) '*)
             (replace loc '/)
             loc)))))
-> [[a / b] + [c / d]]

;remove *
(loop [loc dz]
  (if (end? loc)
    (root loc)
    (recur
     (next (if (= (node loc) '*)
             (remove loc)
             loc)))))
-> [[a b] + [c d]]

;original is intact
(root dz)
-> [[a * b] + [c * d]]


Zipper constructors are provided for nested seqs, nested vectors, and the xml elements generated by xml/parse. All it takes is a 4-5 line function to support other data structures. The zipper support is in src/zip.clj.


Try it out and let me know what you think (on the Google Group),


Rich

Docs and more

I've just finished adding (as of SVN 694, not in release yet) in-code documentation for all public functions of Clojure. The documentation strings appear on the metadata of the var holding the function, under the :doc key. There are two new Repl-oriented helpers for accessing docs, (doc varname) and (find-doc "pattern"). doc prints the documentation for a var, including its name, arglist(s), Macro - if it is a macro, and the docstring. find-doc does the same for all vars whose name or documentation matches the supplied string, which is treated as a regex pattern.


Command-line arguments are now supported for Repl and Script. Anything following -- on the command line will be treated as a command-line argument to the application (i.e. not evaluated by Clojure) and will be available as a sequence of strings - *command-line-args*.


assoc and dissoc now support multiple key/vals and keys respectively.


I've renamed scan to dorun, and touch to doall, the idea being that when you need side-effects you should think "do__".


I've also added rand and rand-int. Find out about them by trying (find-doc "rand").


Please try out these new features. I hope to cut a release including them soon.


Rich


Anonymous fn reader syntax

I've added (as of SVN rev 675, not yet in release) anonymous fn and arg literal reader syntax. An anonymous fn expression takes the form #(...) and turns into (fn [args] (...)), where args are determined by the presence of argument literals taking the form %, %n or %&. % is a synonym for %1, %n designates the nth arg (1-based), and %& designates a rest arg:


(map #(* 2 %) [1 2 3])
-> (2 4 6)
(map #(* 2 %1 %2) [1 2 3] [4 5 6])
-> (8 20 36)
;expansion:
(quote #(foo % %2 (bar %&)))
-> (fn* [p1__750 p2__751 & rest__752] (foo p1__750 p2__751 (bar
rest__752)))
(map #(. % (toString)) [1 2 :d])
-> ("1" "2" ":d")
(map #(/ 1 %) [1 2 3 4])
-> (1 1/2 1/3 1/4)

etc. % is reserved for use in fn expressions:
%
-> java.lang.Exception: ReaderError:(9,1) arg literal not in #()

I think you'll find it a concise, powerful and readable way to do mapping, partial binding, turn method calls into first-class fns etc. This is not a replacement for fn - idiomatic used would be for very short one-off mapping/filter fns and the like.

As always, feedback welcome (on the Google Group),

Rich

20080213 Release

Many significant new features, including first-class namespaces, pervasive abstract destructuring binding, list comprehensions, var metadata, regex literals and more! Browse through the site for details.


There is some renaming/removing in this release:


Folded strcat functionality into str

Removed export, *exports*, unintern, unimport

Renamed ns-exports to ns-publics

Made fn and let macros, which, by the end of boot.clj, do destructuring, as do all macros which emit them.

Removed thisfn, use (fn name [] ...)

boot.clj is now loaded from .jar, no longer from command line.

Renamed eql? to =, compares numbers without regard for type.

Renamed struct to struct-map


Changelist:


renamed :sigs to :arglists, added pr*-str fns, with-out-str
added re-find, re-matcher
added :sigs metadata
added field names to error messages
added re-groups and use in re-seq and re-matches
added re-seq, re-matches, nth support for matcher
added compiled regex literals via #"pattern"
renamed fn and let special ops to fn* and let*. Made fn and let macros, which, by the end of boot.clj, do destructuring, as do all macros which emit them.
added nth support for Map.Entry
changed strcat to str
added assoc/dissoc/conj support for beans
folded strcat into str
added :else to collection-tag
removed export
added when-first, lazy-cat
fixed for so bindings can nest, e.g. (for [x xs y (f x)]...
made meta return nil on non-IObjs
added prstr, assert, test
renamed ns-exports ns-publics
var metadata support
added seq support and inspector support for Java Maps
added bean, which creates a live read-only map of an object's javabeans properties
added default handling of equals, toString and hashCode in implement
fixed maybeClass when passed Class
moved boot.clj load to RT.init()
added destructuring
added get and contains support for strings and arrays, treating as associative, keyed by index, like vectors
added string? symbol? map? vector? seq? nthrest
prevent access to non-exported macro from other ns
added count, nth support for strings, Java Collections  and arrays, get and contains? support for Java Maps
added optional anonymous function name binding (fn name [args] ...)
added seq calls to for
added list comprehensions (for)
fixed subvec assoc at end
simplified cycle
got rid of thisfn
simplified, now includes .clj files in jar
simple inspector support
new constant handling
added first-class namespaces
added array-map
rename != not=
added ns- prefix to refers et al
added ns-unmap
made = use equiv for Numbers
added emit to xml.clj
fixed boolean return in proxy handler
coerce all Boolean false returns to Boolean.FALSE
renamed struct to struct-map, construct to struct. Added to-set and distinct
made make-proxy use Compiler's classloader as parent
made DynamicClassLoader no-arg ctor use Compiler's classloader as parent
added construct, resultset-seq, keyword fn, vars in namespace tables
fixed BigNum.equals
added pr support for \r in strings
fixed *warn-on-reflection* access

Thanks to all for your feedback!


Rich

20080106 Release

Featuring boolean literals, improved overload resolution and compilation, as well as fixes:

renamed contains to contains?
added *warn-on-reflection*
made 'and' return the first non-true value
added true/false support
compilation of field access, string tags, array classname resolution, rseq factored into Reversible
boot.clj generates NO reflective calls
reflective/compiled calling unification
arg boxing on eval calls to matched methods
eval creates loader if needed
fixed tag on *out*
flag use of qualified name as fn parameter
fixed issues with overload resolution
same arity overload resolution in ctors and methods
made strcat accept 0 args, switched to StringBuilder in implementation. 
Made pr et al accept 0 args
wrap evals of throw in fn context
enable eval of throw to throw Errors as well as Exceptions

Thanks to all for your feedback!


20071231 Release

Many new features and fixes, but a primary one is not in the code but on the site:


I've documented all Clojure special ops, macros and functions! Please browse around, I've added over 100 new entries, and a new section on Java Interop


In this release:


added try (try/catch/finally all-in-one)
added identical?
added macroexpand-1 and macroexpand
made math ops loops
added min and max
added bit ops from Toralf Wittner - thanks!
fixed bug in concat with empty colls
fixed bug in let generating multiple 'this' locals
added StringSeq
Made ASeq Sequential
load returns value of last expression
load-file returns value of last expression
added (get map key not-found-val) support
all map entries implement Map.Entry, added key and val functions on Map.Entries
disallow let of qualified name
fixed seq on String
AFn implements Comparator
changed param order on reduce with seed val, added sort, sort-by and line-seq
made nth throw on unsupported types
made 3 arg get work with vectors
added with-open
fixed reduce parameter reordering
made apply work with any collection as last arg
lock-free agents
optimized withMeta
added merge-with await await-for scan touch
thread pool tweaking
fixed equals sequential
removed reflective static class pseudo-field
added non-reflective static field read compilation
added ASM to SVN
added PersistentStructMap
made list return a PersistentList, not a seq
added defstruct, struct, accessor
added create-struct
made int coerce Characters
fixed pop when count 2
Made implementing void-returning methods optional in implement
added XMLHandler
added handling of \ \t \n " in string printing
added subvec
added xml.clj
made (str nil) return empty string
added Var type hints
added support for string as arg to class special op
added alength, multidimensional aget aset(s) and make-array, to-array and to-array-2d
fixed search for method in public base
added aset-char
improved try syntax
added Comparable to default imports
added comparator, changed order of args to sort with comparator, added sort-by with comparator
changed doto to return instance
changed load to take Reader
added load
added *print-readably* support to pr, prn, print and println

I owe much to all those who have provided valuable feedback, suggestions and bug reports.

Thanks and Happy New Year!

Rich

20071203 Release

This release adds the Agents system and includes many bug fixes.


Agent system,
fixed bug in concat with empty colls,
made Agent.executor public,
made list* require at least 1 arg,
(list) returns (),
added quot rem,
added char coercion function, removed implicit Number conversion to Character,
made boxing consistent for all Numbers not just Nums,
added *print-meta* - defaults to nil,
fixed unbox Character code gen,
fixed bug in concat when passed one collection,
fixed def at top-level eval context,
made inc dec et al coerce to Num

Thanks to all for your feedback!

LispNYC Talk

I recently gave a talk on Clojure to the LispNYC group. Audio and slides from the talk are now available online.

20071029 Release

added make-array, aget, aset. aset-int, aset-long, aset-float etc
limited wrapping exceptions in compiler to one level
changed primitive return boxing to use Integer, Long etc instead of Num
added java primitive wrapper coersion functions int long etc
added pmap 
made doseq return seq
renamed new-proxy to implement
renamed .-> to doto 
renamed dolist to doseq 
added into, memfn, fnseq 
Made FnSeq not use Delay
added handling of public methods of non-public classes with call via interface method, or failing that, public superclass method
added read
added (non-definitive) ant and maven build scripts

Site additions

I've added a feature tour to give an overview of Clojure in addition to the reference documentation.


There is also a new page in the reference describing Multimethods.

20071020 Release

Featuring:


range function

Multimethods

Any object not explicitly handled by the compiler is self-evaluating 

 

Copyright © Rich Hickey