Re: Any Clojure users here?



On Sun, 30 Jan 2011 06:13:23 -0800, TheFlyingDutchman wrote:


There isn't a lot of trouble interfacing with Java from Clojure,
actually. Static methods are basically just functions, and instance
methods are just functions with a funny argument syntax of

arg1.function(arg2, arg3, arg4);

vs. C's

function(arg1, arg2, arg3, arg4)

or Lisp's

(function arg1 arg2 arg3 arg4)

and Clojure makes these fairly obvious transformations:

System.nanoTime() => (System/nanoTime)

Collections.sort(foo) => (Collections/sort foo)

stream.print("string") => (.print stream "string")

I would have done it as (print stream "string") and (System.nanotime)
(Collections.sort foo)

One thing I was surprised to see was defn/def instead of defun/ defvar?

Clojure is a Lisp-1, so there is only one fundamental operator (special
form) for interning new global values, whether functions or not, and so
they simply called it def. Clojure's defn is a macro that wraps def; the
simplest sort of use case of

(defn foo [x] (* x x))

basically just expands to

(def foo (fn [x] (* x x)))

that is, the creation of an anonymous function and its assignment to a
global var.

There are actually a few complications to this picture -- first, defn
attaches metadata to the var for various purposes, and lets you include a
documentation string (which goes in that metadata if included); second,
the fn form can be used to make non-anonymous functions:

(fn foo [x] (* x x))

even if these aren't globally bound. The usefulness is that inside that
function "foo" is locally bound to the function itself, so it can be
called recursively, passed to HOFs like map/reduce, etc. (though even
without it "recur" works to do a TCO recursion). The defn macro actually
also binds the name locally inside the function. The main effect is to
make such a use a bit more optimized -- locals are much faster to
dereference (as fast as Java locals) than globals (because globals are
actually fairly complex things under the hood, capable of having thread-
local bindings that shadow their root bindings, etc.). It also means that
if the function calls itself recursively, thread-local rebindings won't
disturb that.
.



Relevant Pages

  • Re: defvar affecting captured closure variables ?
    ... ignore the advice about global lexicals. ... | bind these globals, since otherwise you'll get a lexical foo when you ... | bind foo. ... again distracting as ar esult). ...
    (comp.lang.lisp)
  • using "our" across blocks
    ... I want to double-check that it is correct to use "our" to import globals. ... our $foo = 'foo'; ... ...at this point I can see 'foo' and 'bar' values. ... Global symbol "$foo" requires explicit package name at ./script.pl line xx. ...
    (perl.beginners)
  • Re: Rebindings [was Re: Favorite non-python language trick?]
    ... oops, for below example, needs global declaration ... def foo(): ... So that limits it to the local scope and nested scopes and declared globals not ... preempted by nearer nested scope variable names. ...
    (comp.lang.python)
  • Re: Using an object inside a class
    ... Then you probably should not be using globals. ... But this tells me "global name foo is not defined": ... going on here is that you're assigning foo somewhere inside method1 ...
    (comp.lang.python)