Re: Binding and temporary global state

2010-09-06 Thread Jarkko Oranen
Cameron Pulsford wrote:

 Is there a way to do this? Besides cleaning up function signatures is
 this a premature optimization to begin with?

 (declare *macros*)

 (defn macro-expand [tokens]
   (map #(get *macros* % %) tokens))

 (defn compile-op [op]
   (macro-expand op))

 (defn assemble [{:keys [macros syms blks fncs]}]
   (binding [*macros* macros] ;; I thought binding would handle this,
 but I must be misusing it
 (let [compiled-ops (map compile-op fncs)]
   compiled-ops)))

Your problem is that compiled-ops is a lazy sequence, and it only gets
realised when it's used, which probably happens after it has exited
the dynamic scope where *macros* is bound.

You can work around the problem by forcing the sequence with doall or
by using bound-fn* to save the dynamic environment (ie. (map (bound-
fn* compile-op) fns), though double check that from the docs)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Basic Lisp Compiler: How to tell which functions to compile?

2010-08-09 Thread Jarkko Oranen


On Aug 9, 7:54 pm, CuppoJava patrickli_2...@hotmail.com wrote:
 Hello everyone,
 Just for educational purposes, I'm writing a simple lisp compiler and
 am stuck on a small problem.

 I'm trying to write a function called (compile-function), which will
 take a function as input and compile it.

 If that function calls other functions, I would like (compile-
 function) to automatically compile the called functions as well.

 But I'm stuck on how to tell whether a function will be called or not.
 Particularly when functions are passed around as objects.

 So the question is this: Given a function f, how can I find all the
 functions that f depends on?

I don't think that's feasible, if it's even possible in the first
place.

Functions that the parent function calls directly you can of course
try to compile whatever you encounter in a function call form; just
check if the operator is a known global function, and compile it.
However, if the operator is a local variable (ie. a function passed as
a parameter) there's no reliable way to find out what function it is.
It might even be a runtime-generated function (by eval)

Since you can't know what functions will be called, the generated code
must somehow verify that it's calling a function in the first place,
perhaps invoke the compiler (if all functions must be compiled), and
then execute it.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: special form vs. macro

2010-05-31 Thread Jarkko Oranen
On May 31, 10:35 am, alux alu...@googlemail.com wrote:

 [  ] A special form is what can be implemented by a macro.

That depends. My understanding is that a special form is something
that is fundamental to the language, that the evaluator handles as a
special case. That is, they need to be implemented in the compiler/
interpreter itself. However, in practice you can't really tell the
difference between a macro and a special form, and in fact some
Clojure special forms are implemented as macros (on top of a real
special form that is an implementation detail)


 [  ] Every macro gives a special form.

Not really. All macros have the same evaluation semantics (macro
expansion).

 [  ] Only a macro that doesn't evaluate some of its arguments gives a
 special form.

I don't think evaluation of arguments matters.


 [  ] A special form is always built in, and cannot be implemented in
 the language itself.

That depends on your point of view, but in general, yes.


 [  ] Special forms are exactly the things that can be called, but dont
 evaluate all of their arguments. (Macros and build-ins, at least for
 eager languages.)

Special forms are special because the evaluator has separate
evaluation rules for each of them. Other than that, they are merely
another kind of operator (the others being macros and functions)


 [  ] The concept of special form doesnt have anything to do with
 eagerness or lazyness.

This is correct.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Transient HashMaps with not more than 8 elements?

2010-05-29 Thread Jarkko Oranen


On May 30, 12:32 am, Daniel Borchmann
daniel.borchm...@googlemail.com wrote:

 The same happens if i goes up to 100, 1000, ... Is this a bug or is
 this a fundamental misconception of mine?

You're using them wrong. Transients are not imperative data
structures. You need to capture the return value of assoc! and use
that as the new transient.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: convert this to loop/recur?

2010-05-17 Thread Jarkko Oranen


On May 18, 2:23 am, Base basselh...@gmail.com wrote:

 (defn lazy-date-seq [d1 d2]
   (let [start (- d1
                 (.dayOfMonth)
                 (.withMinimumValue))]
      (lazy-seq
        (cons start
          (if (joda/before? start d2)
            (lazy-date-seq (.plusMonths start 1) d2))

 The lazy version worked like a champ and appears (to me) to be more in
 the vain of Lisp (with a touch of Haskell).
 Is the author of the blog correct about using lazy seq in this way?
 Assuming that he is correct and I converted date-seq to a loop/recur
 format to use TCO, would one of these be preferable over the other in
 terms of idiomatic clojure?

The lazy version is more idiomatic. By default, you should make
sequences lazy unless there is a compelling reason to do otherwise.

In this case it also avoids the stack building problem that the
recursive version has.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: How to visualise relations, bahavior and so on in functional programming ?

2010-05-11 Thread Jarkko Oranen
On May 11, 11:18 am, Donell Jones alliwantisca...@googlemail.com
wrote:
 Hi Team,
 I am really interested in functional programming. But I am asking
 myself, what if the project get bigger, like the software Runa realise
 with Clojure. In OOP we got diagrams like UML to visualise this. But
 what can we do in FP ? Are there any diagrams that can be used to
 explain things ?

 I think this is very important when it comes to documentation.


I think a flowchart might be useful. In functional programming there
is a tendency to model things as a pipeline of transformations,
instead of as interactions between code modules (classes), so
visualizing how your data flows from its source to its endpoint will
be useful.

On a larger scale you might want to map out the relationships between
namespaces, which procedures deal with state, etc.

Unfortunately I don't know any tools to generate call graphs and such
from clojure code, but hopefully my suggestions will at least inspire
a few ideas.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Using a macro to define a function - nested backquotes?

2010-05-04 Thread Jarkko Oranen


On May 4, 10:40 pm, Bryce fiat.mo...@gmail.com wrote:
 I have a macro, deriv, that produces an expression, and I'd like to
 create another macro that turns this into a function.  So far I have

 (defmacro deriv-fn [fn-args exp v degree]
   `(fn ~fn-args (deriv ~exp ~v ~degree)))

 Which of course doesn't work, since it considers the output of deriv
 as a quoted list.  So for instance

 (def f (deriv-fn [x y]  (+ (* x y) (* 3 y)) y 1))

 results in a function f of two variables which always returns '(+ x
 3) , rather than a function which evaluates (+ x 3).

 I feel like this is a nested backquote thing, where I could get it to
 resolve at the correct point through artful use of ` and ~~, but I've
 not been able to figure it out - am I on the right track?


If deriv is a function that returns an expression, you need to do
 (defmacro deriv-fn [args exp v degree]
   `(fn ~args ~(deriv exp v degree)))

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Funcalls vs. lists (Was: Clojure Concurrency Screencast Available)

2010-05-02 Thread Jarkko Oranen


On May 2, 11:14 pm, Mike Meyer mwm-keyword-googlegroups.
620...@mired.org wrote:
 On Sun, 02 May 2010 13:06:56 +1000

 To get behavior similar to the vector constructs, you want to use
 list, which works like vector, except returning a list instead of a
 vector: (list 1 2 3 (print :hello)). It seems that what's missing here
 is a syntax for (list. I'm not sure it's needed, as it never appeared
 in LISP, but #[ seems to be the logical candidate:

 { - hash-map      #{ - hash-set     [ - vector        #[ - list


Hmmh. I haven't read the discussion very carefully but it seems there
might be a fundamental misunderstanding here somewhere.

The thing is that (foo bar) *is* a list of two symbols, even if not
quoted. It just so happens that when such a list is passed to the
evaluator, it evaluates it as a function call. Similarly, [foo bar] is
*not* a shortcut for (vector foo bar); it *is* a vector of two
symbols, and vectors just have different evaluation semantics. The
same applies to sets and maps.

The best you'd get out of a #[foo bar] is a simple reader macro that
expands to (list foo bar) and that's really just a waste of macro
characters, not to mention confusing. Or you would have to have a list
type that isn't evaluated as a function call. But that path leads to
insanity.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: deftype and final classes

2010-04-28 Thread Jarkko Oranen


On Apr 28, 5:00 am, Richard Newman holyg...@gmail.com wrote:

 Opinions, thoughts, critiques, you're insanes, etc. welcome.

The patches look fine to me and the change is well justified since you
have a real use case. I don't think restricting deftype to final
classes would serve any real purpose. I'd just go ahead and make an
assembla ticket for this, but of course it's safest to wait for Rich's
opinion.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Cannot find juxt in clojure 1.1 (??)

2010-04-23 Thread Jarkko Oranen


  *clojure-version*
 {:interim true, :major 1, :minor 1, :incremental 0, :qualifier
 alpha}


Looks like you have some old version of 1.1 prior to release. The
release version of 1.1 shouldn't have the alpha qualifier.

Try upgrading.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: primitive arrays, am I reading this right?

2010-04-19 Thread Jarkko Oranen
On Apr 19, 1:17 pm, Joel Gluth joel.gl...@gmail.com wrote:

 (def floatarray (make-array Float/TYPE 2))
 (for [i (range (alength floatarray))] (aset floatarray i (float ([1 2]
 i

You can just do (into-array Float/TYPE [1.0 2.0])
There is no need to explicitly cast the vector items as they would be
boxed anyway as vectors currently can't contain primitives.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Problem with Destructuring in A Function Call

2010-04-16 Thread Jarkko Oranen


On Apr 16, 11:59 am, Bytesource stefan.rohlf...@gmail.com wrote:
 Hi,

 I am currently reading Programming Clojure but got stuck at the
 destructuring done in the head-overlaps-body? function call that is
 part of the snake game:

 (defn head-overlaps-body? [{[head  body] :body}]
   (includes? body head))

 ;; page 200 of the pdf version

 I can not figure out what {[head  body] :body} actually means here.

 head-overlaps-body? is called inside lose? which is called with a
 snake object:

 (def lose? head-overlaps-body?)

 (defn create-snake []
   {:body (list [1 1])
    :dir [1 0]
    :type :snake
    :color (Color. 15 160 70)})

 I read the the information about the let binding form on clojure.org/
 special_forms but still have no clue how the above destructuring is
 done.

 Hope someone can give me a hint.


As it is a nested destructuring form, there are two kinds of
destructuring happening: First, there is map destructuring that takes
the value for the key :body from the argument map. That is, ([1 1]),
which is a list.
Normally the value would then be bound to a name on the left-hand
side, but in this case there's the destructuring form [head  body]
instead, which means sequential destructuring is applied to that list.
Thus, in this particular example, head gets bound to [1 1] and body to
nil.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Problem with Destructuring in A Function Call

2010-04-16 Thread Jarkko Oranen


On Apr 16, 5:25 pm, Asim Jalis asimja...@gmail.com wrote:
  It does conform to the pattern that the bound variable precedes the
  value to bind in forms like let. A benefit of this ordering is that
  destructuring patterns like {:keys [a b c]} are unambiguous.

 Hi Per,

 Could you explain the rationale for this swapping? Intuitively it
 seems to me that (let [{ :body x } { :body 42 }] x) should bind x
 to 42 -- it seems intuitive because it is binding :body to :body
 and 42 to x.

 I realize that this doesn't work. I want to understand why. Why
 is (let [{ x :body } { :body 42 }] x) the correct way?

 Asim

I think the paragraph you replied to *is* the rationale: it allows for
features like :keys and :or, and maintains the general ordering of
bindings. It may feel a bit unintuitive at first, but I think that's
only because you're associating the map binding form more closely to a
map (a collection of key–value pairs) than a binding form.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: New clojure support in Polyglot Maven

2010-04-08 Thread Jarkko Oranen

 Hopefully you can see that this syntax falls out of the direct construction 
 of maven Model object, unmediated by intermediate syntax or data structuring. 
 So there's a good reason for the way it looks.


Right. Thanks for the thorough explanation. It's not so bad if you
quote the vectors instead of the individual symbols. However, it seems
to me that defmaven could very well be a plain function in that case
(just (reset! *MODEL* (apply Model args))). :)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: defprotocol's support for variadic arguments seems broken

2010-04-06 Thread Jarkko Oranen

On Apr 6, 8:16 am, Zach Tellman ztell...@gmail.com wrote:
 Possibly this fall out from the latest commit requiring an explicit
 'this' reference (ba6cc3b), I haven't checked any versions but the
 most recent.

 user (defprotocol Protocol (f [a b  c]))
 Protocol
 user (def p (reify Protocol (f [a b  c] [a b c])))
 #'user/p

 user (f p :a :b :c)
 [#user$reify__1503 user$reify__1...@31e2ad :a :c]

Did protocols ever support variadic arguments? It seems to me that in
this case  gets treated as a regular symbol and a gets bound to the
object itself, b to :a,  to :b and c to :c, which would explain the
weird output.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: A syntax question: positional keyword

2010-04-06 Thread Jarkko Oranen
On Apr 7, 12:25 am, Sophie itsme...@hotmail.com wrote:

 Just curious
   - what folks think of fixed-positional-keyword params
   - whether it was considered for Clojure

I don't know for certain whether Rich ever considered smalltalk-style
parameters, but I doubt it.

I do like them, though; in Objective-C and Smalltalk. They're
extremely readable and natural in an object-oriented language (or a
message-oriented one, anyway). However, I don't think they are a very
good fit for a Lisp.

Expressing positionally fixed keyword parameters in terns of lists,
symbols and keywords feels clunky and unnatural to me, but the greater
problem is that they also make some very common functional patterns
cumbersome: most notably function application (ie. apply),
composition, and higher-order functions.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe, reply using remove me as the subject.


Re: copying structures

2010-03-30 Thread Jarkko Oranen

 The def was for legibility (or I was going for legibility).  Speaking
 of redefing, is there a way to block a redef so I or someone else
 doesn't monkey-patch a function?

You can set a validator on the Var to prevent accidents. However,
someone who really wants to redefine a function can just disable the
validator first :/

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Impact of gen-class on clojure-ness

2010-03-29 Thread Jarkko Oranen
 Specifically, I prefer to define the important components of my
 software as Java interfaces. Partly to see myself think, partly
 because it just makes more sense to me. I then want to implement these
 interfaces using gen-class and clojure functions and pass resulting
 objects as function arguments.

 My question is: does this combination of Java interfaces and gen-class
 impact clojure-ness in any way? In other words, would I be living in a
 different world if I would just implement my functions and pass those
 functions around as function arguments without using Java interfaces
 and gen-class?

It sounds like you're thinking of an object-oriented design. Clojure
is not particularly object-oriented.

Interfaces are good, but defining your own is mainly reserved for Java
interop. You should strive to use plain old untyped data structures
for your data, ie. just put things in maps, vectors, sets andl lists.
Write (pure) functions to transform the data, and some logic to handle
program state. Try to keep a clear separation between state-handling
or interactive code and data-handling logic. Also make use of
Clojure's sequence abstraction. The core libraries have many functions
for processing sequences.

The core abstraction in Clojure is a function. There is a feature
called protocols in git master that will become the Clojure way of
defining interfaces, but even if it is a protocol, the interface is
simply a collection of functions. If you're used to object oriented
programming, you need to invert your thought process from What
methods does this object have? to What data can this function
process?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: copying structures

2010-03-29 Thread Jarkko Oranen


On Mar 29, 1:26 am, strattonbrazil strattonbra...@gmail.com wrote:
 Is this the common way to do it?

 (def sister (assoc brother :name Cindy))


Please note that actually def'ing each value is not what you're
supposed to do :) def is reserved for global constants and dynamically
rebindable variables, and redefing an existing variable is considered
bad style.

You might do something like this:

(defn children [father mother  children]
  (let [base {:father father :mother mother}]
(for [c children] (assoc base :name c

;; note, that's not a for loop, but a seq comprehension

which, when called like
  (children John Mary Cindy Gary)
produces a (lazy) sequence of maps representing the children.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Choosing a Clojure build tool

2010-03-26 Thread Jarkko Oranen


On Mar 26, 8:53 am, Per Vognsen per.vogn...@gmail.com wrote:

 It's not semantic nitpicking. There's a clear-cut difference a piece
 of reusable code with a function that can be called to generate a
 bundled Windows installer based on a set of arguments versus something
 that only works as part of a build system like Maven.

I think this is mistaken. Your piece of reusable code still needs to
know enough about the build system used to build the bundled windows
application. Sure, the maven plugins can't be used unless you also use
maven itself, but the advantage is that you don't need to configure
the plugin to work with the build system... That's automatic.

You could always write a maven plugin that invokes your function and
configures it properly for the maven build in question. The point
still remains that anyone using maven need not care about those
details, as they're the plugin's responsibility.

 No, compilation should not be included. You mention make; it is a
 macro language, dependency graph walker, shell executor and
 up-to-dateness checker. It doesn't do any compilation. It's very bare
 bones. It's not at all perfect but it's much closer to what I want
 from a build system than something like Maven.

Again, I think this is mistaken. Make alone, as you describe it, is
*not* a build system. You have to do lots of manual work to make your
application build if you use plain make, most of which a system like
maven can do for you, since it's configured declaratively. With maven,
you don't usually tell it what to do, you need to tell it what you
want; and I think that is how a build system should be.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: ANN: Kanshiki Boom! - Japanese handwriting recognition

2010-03-26 Thread Jarkko Oranen
This looks neat. I probably won't find much use for it though, as my
input method already has this functionality, and even that doesn't get
much use due to the fact that I am horrible at writing kanji with the
mouse (I'm left-handed, but my mouse-hand is right.)

If you have no plans to try to make money with this thing, I you
suggest simply put the thing on github so that interested people can
take a look. I don't think it's worth keeping things like this hidden.
Note that if you do so you should choose a licence other than GPL,
because it's known to be incompatible with EPL which Clojure uses.
(EPL is a slightly weaker copyleft licence, more like LGPL). EPL is
the most common choice, but of course a BSD-style licence is fine as
well.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Beginning Clojure. Recursion

2010-03-25 Thread Jarkko Oranen


jfr wrote:
 Hello,

 I've just started to play a little bit with clojure to get a feel for
 the language. It seems to be quite interesting (and it's a relief to
 leave my clumsy IDE behind and use Emacs). Concerning immutable data:
 Is the following code ok or should (must) I use transients as
 variables for the loop?


Transients are merely a performance optimisation, and they're designed
so that you can use them just like you would use persistent data
structures. Therefore it's good to always start with purely functional
algorithms. The code you wrote is idiomatic, though it could perhaps
be improved by not looping explicitly and instead using eg. reduce.
It's also fairly straightforward to transform to use transients,
should performance turn out to be suboptimal.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Sequential vs. divide and conquer algorithm

2010-03-21 Thread Jarkko Oranen


On Mar 19, 6:53 pm, Andrzej ndrwr...@googlemail.com wrote:
 I've been toying with various implementations of reduce-like
 functions, trying to do something smarter than a simple iteration
 over a collection of data. This hasn't worked out very well, my
 implementation is a lot (~50x) slower than a simple loop. Could anyone
 point out any bottlenecks in this algorithm and advise me on possible
 ways of improving it?

Rich has done some work on using the JDK7 ForkJoin Library to
parallelise map and reduce over vectors, since they are already
internally structured as trees. It hasn't been touched in a while, but
as far as I know the code lives in the 'par' branch of the clojure
repository, and works with JDK6 if you install an additional jar.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: lazy-cons

2010-03-20 Thread Jarkko Oranen
On Mar 20, 1:52 pm, Glen Rubin rubing...@gmail.com wrote:
 Hey all,

 I am working through the problems on project euler.  On question
 number 11 (http://projecteuler.net/index.php?section=problemsid=11),
 I was unable to come up with a solution, so I cheated and looked at
 some other people's answer's here:  
 http://clojure-euler.wikispaces.com/Problem+011

 Unfortunately, I am so dumb I cannot even understand the solutions
 very well...hahhaha.  The first solution on that page  defines the
 following function:

 (defn select-dir [array x y ncol span fnx fny]
   (when (not (zero? span))
     (lazy-cons
       (array-get array x y ncol)
       (select-dir array (fnx x) (fny y) ncol (dec span) fnx fny

 Right off the bat, I am wondering what is lazy-cons?  I could not find
 it in the api.

That's because it has been removed. It became obsoleted by seq
behaviour changes sometime before 1.0 was released.

a more up-to-date version of that would be:

(defn select-dir [array x y ncol span fnx fny]
  (when-not (zero? span)
(lazy-seq
  (cons (array-get array x y ncol)
(select-dir array (fnx x) (fny y) ncol (dec span) fnx
fny)

Another approach that is common when constructing lazy seqs,
forming a closure over the constant parameters:

(defn s-dir [array x y ncol span fnx fny]
  (letfn [(worker [x y span]
  (when-not (zero? span)
(lazy-seq
  (cons (array-get array x y ncol)
(worker (fnx x) (fny y) (dec span))]
(worker x y span)))

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
REMOVE ME as the subject.


Re: Why do functions in the state monad only accept one value?

2010-03-17 Thread Jarkko Oranen


On Mar 17, 1:17 am, Steven E. Harris s...@panix.com wrote:
 Michał Marczyk michal.marc...@gmail.com writes:
  a State-using programme builds up a stateful computation first, then
  uses runState (or perhaps execState / evalState) to run it as a whole;
  only at this final step does the initial state actually get poured
  into the opening of the monadic pipe, as it were.

 That's a good metaphor.

 [...]

  You can use it multiple times, each time injecting a different initial
  value of state.

 Ah, but here's where part of my confusion arises. With this treatment of
 such a built-up computation, it's a kind of a zero-argument function, in
 that there's no way to pass in a basic value to kick it off. Where
 does the first basic value to be fed into the first monadic function
 come from? Presumably it comes from the first monadic value in the
 pipe. In your description above, it sounds like this first monadic
 value must be committed to when buld[ing] up a stateful computation
 first.

Hmm... In Clojure, *values* representing the entire composed
stateful computation are functions of the state. therefore, you can
treat it as a regular function and just call (stateful-computation
init-state) as many times as you like. so the first basic value is
simply the one you pass to the composite operation. In haskell, State
monad values have their own type, so you can't use them as functions
directly and need the runState operation. An *operation* on state
monad values is one that returns such a function of state, and the
whole point of the monadic structure is to allow composing these
operations. After all, it's clear that you can't just use function
composition to compose them, because the arguments they expect and the
values they return are not compatible.

Further, any function that creates state monad values can of course be
created dynamically. eg:

(defn make-adder-to-state [x] ; a function
   (fn [v]  ; that returns a monadic function
(fn [s] ; that returns a state monad value.
  [v (+ x s)])))

which can be used like:

(let [computation (m-bind (m-result 4) (make-adder-to-state 5))]
  (computation 10))
 - [4 15]

Hope this helps

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Why do functions in the state monad only accept one value?

2010-03-16 Thread Jarkko Oranen

 What would be lost by defining Clojure bind operator like this:

   (fn m-bind-state [mv f]
     (fn [s]
       (let [[v ss] (mv s)]
         (f v ss

 Is there more to it than, Monadic functions must return monadic
 values.

My first thought was that it would be problematic for the result
operator, which would have to take two parameters (or at least accept
two parameters, with a default if passed only one)

Perhaps more importantly, the power of the monad abstraction is that
the types of monadic functions and all the operators are similar. ie.
*all* monadic functions, regardless of the monad, have the (haskell)
type a - M b
This way, you can write a function that works under many different
monads, as long as it uses the generic facilities to return monadic
values. eg. a lifted inc:

(defn m-inc [v]
  (m-result (inc v))

which can be used in the state monad as an argument to bind, even
though it doesn't care about the state at all. If you *do* need the
state (add it to the parameter, for example), you would write

(defn add-state [v]
  (fn [s]
[(+ v s) s]))

used like ((m-bind (m-result 4) add-state) 10), giving [14 10]


I hope I got this correct... I'm not an expert on all the mathematical
theory behind monads.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Why do functions in the state monad only accept one value?

2010-03-16 Thread Jarkko Oranen
*facepalm* I should've known GG was just hiding the post from me.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Why do functions in the state monad only accept one value?

2010-03-16 Thread Jarkko Oranen

 Is there more to it than, Monadic functions must return monadic
 values?

 Any clarifying advice would be welcome.


Gah, I already wrote a reply, but looks like I lost it somehow. To
summarise:

I think one of the main benefits of the monad abstraction is the
uniformity of all monads. ie. all monad functions have the type a - m
b

What this means is that you can write functions which work under
arbitrary monads, as long as they use the generic monad functions. For
example, a monadic inc:

(defn minc [v]
  (m-result (inc v))

This function works in any monad, and threads the state properly, even
though it's never mentioned.
A function that actually does care about the state will just access it
by returning a custom state monad value (a function of s).


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: objects, interfaces and library design

2010-03-03 Thread Jarkko Oranen
On Mar 3, 7:47 pm, cageface milese...@gmail.com wrote:
 I've been reading through the examples of OO in clojure using multi-
 methods and they certainly seem very flexible and powerful. I'm
 wondering, however, how people handle interface  library design. If
 people can implement objects as maps, structs, or just about
 anything else you can discriminate on via a dispatch function, how do
 you handle code reuse and sharing of libraries. If we're all using our
 own home-grown OO systems how do we communicate?

 Is this something that the deftype/protocol proposals are meant to
 address or do people just work around it in other ways or is it just
 not a real issue in practice?

Well, it seems to me that the universal interface is the sequence.
Turns out many things can be represented as sequences. :) And since
maps are just collections of key/value pairs, very generic code can be
written to process them, too. As long as the wanted keys are there,
any extra information the map might be carrying can often be ignored.

deftype will allow people to define their own types for data that
would be inefficient to store in a map. They will still (optionally)
expose a map-like interface, so any generic map-processing code is not
necessarily obsoleted by them. Protocols on the other hand allow you
to define interfaces which can be implemented after the fact,
hopefully making interoperability easier.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: newbie question: Please help me stop creating constructors

2010-03-01 Thread Jarkko Oranen


On Mar 1, 9:55 am, Richard Newman holyg...@gmail.com wrote:

    (defn house-sale-profit
      [house-sales-price house-sale-expenses]
      (- house-sales-price house-sale-expenses))

I'd like to note that if you do this, you might just as well use the -
function directly. It's not as flexible if the profit calculation
changes, but until there's a real need, it just feels like
overabstraction.
  (let [profit (- house-sales-price house-sale-expenses)]
 ...)
is perfectly reasonable. The same applies to calculating months-in-
business.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Question about how to write efficient code in functional style

2010-02-28 Thread Jarkko Oranen


On Feb 28, 4:03 pm, Heinz N. Gies he...@licenser.net wrote:
 How about reducing it?

 Something along the limes of: (not tested)

 (reduce (fn [lists number]
         (update-in lists [
           (if (odd? number)
           (if (= 0 (mod number 5) :odd-5 :odd)
           (if (= 0 (mod number 5) :even-5 :even)] (fn [l] (conj l number)) 
 numbers)

 Regards,
 Heinz

I think that's a pretty good solution. However, some things I
noticed:

1) zero? instead of (= 0 ...) is more idiomatic and a bit faster
2) You don't need to wrap the conj in an anonymous function. update-in
accepts optional arguments, so (update-in [...] conj number) works
just fine.
3) The reduce needs an empty map as an init value. Otherwise you get
an exception (You might even want to populate it with empty vectors,
but it's not necessary since conjing to nil produces a list)

Also, the nested ifs are pretty hard to follow, so I think it would be
clearer if you made the key selection a local function, so that you
can write (update-in [(categorize number)] ...)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: functional abstraction

2010-02-28 Thread Jarkko Oranen


On Feb 28, 7:36 pm, reynard atsan...@gmail.com wrote:
 Perhaps my choice of function names (abstract and concrete) for my
 original post is not very appropriate.  I did not mean to apply the OO
 concept of abstract class, abstract methods, etc.  Since it seems that
 my original post did not convey my query clearly, I would try to
 depict it with some concrete :) examples in the following.

 Suppose I want to filter a list '(1 2 3 4 5 6 7 8 9) for all the
 numbers which is less than 5, but I do not want to use the clojure
 filter function.  I decide to roll out my own function using recursion
 and con'sing as follows.

 (defn smaller-than [a-list n]
   (cond (empty? a-list) '()
         'else (if ( (first a-list) n)
                 (cons (first a-list)
                       (smaller-than (rest a-list) n))
                 (smaller-than (rest a-list) n

 Later, I want to filter for all numbers which is more than 7 from the
 list.  I do not want to copy and paste and modify smaller-than.  To
 maintain a single place of control, I introduce a function call
 filter1.  I do a little bit abstraction and define some functions as
 follows.

 (defn filter1 [comparator a-list n]
   (cond (empty? a-list) '()
         'else (if (comparator (first a-list) n)
                   (cons (first a-list)
                       (filter1 comparator (rest a-list) n))
                   (filter1 comparator (rest a-list) n

 (defn smaller-than [a-list n]
   (filter1  a-list n))

 (defn more-than [a-list n]
   (filter1  a-list n))

 Or I can define filter1 as follows:

 (defn filter1 [comparator]
   (fn anonymous [a-list n]
     (cond (empty? a-list) '()
           'else (if (comparator (first a-list) n)
                     (cons (first a-list)
                         (anonymous (rest a-list) n))
                     (anonymous (rest a-list) n)

 and use it the following way

 (def smaller-than (filter1 ))
 (smaller-than '(1 2 3 4 5) 3)

 Or even ((filter1 ) '(1 2 3 4 5) 3)

 I may define filter1 as is, what is now being done, accepting a
 predicate as the parameter. There are just many choices on how to do
 abstraction.

 So back to my query on my original post.  Given that there are many
 choices, how do I choose which way to do and why?  Is there really a
 better way?  Or just by convention?  By preference?  Or is the
 answer it depends?  But depends on what?  I would be glad to hear
 your opinion.  Thanks.

As I said in my previous post, both approaches are valid. Which one
you pick really depends on your intended usage.

Though I think def'ing functions returned by other functions is not
very common in Clojure, it's certainly not bad style. However,
functions are no different from other data, so rather than defining a
global name for them, more often you just pass them into other
functions or store them in a data structure or whatever. If it really
needs a name, a let-bound local one is often enough.


 P.S. a side note on recursion:  I may change the above filter1
 function into tail call by introducing an accumulator parameter and
 modify the function a little bit.  Is it generally a good thing to do
 it?  I would like to hear some comments.  Thanks.

In Clojure the most idiomatic version of filter is the lazy one. It is
recursive like in your implementation, but rather than actually
executing the recursion immediately, you wrap the cons call in lazy-
seq and return a thunk.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: functional abstraction

2010-02-27 Thread Jarkko Oranen
On Feb 27, 9:10 pm, reynard atsan...@gmail.com wrote:
 This may be more about functional programming in general, rather than
 clojure specific.  However, since I mainly use clojure for learning
 functional programming, I would like to discuss it here.

 Basically, I can think of the following 2 ways of doing abstraction.
 I would like to hear some comments or feedback from others.  Which way
 do you think is better?  Does this issue even matter?  Or there are
 better alternative ways?  Thanks.

 (defn abstract-function [f x y]
         (body)
         (f x y)
         (body))

 (defn concrete-function [x y]
         (abstract-function a-fun x y))

 --
 (defn abstract-function [f]
         (fn [x y]
           (body)
           (f x y)
           (body)))

 (def concrete-function (abstract-function a-fun))


I don't think the labels concrete or abstract apply to functions
very well. In both cases, abstract-function is a higher order
function, but that makes it no less concrete. :)

That said, both are valid approaches. The first one is a simple higher-
order function, like for example map or filter in clojure.core. The
second approach is is commonly used when the function returned is a
one-shot function, that gets passed to another. That is, instead of
def'ing concrete-function, you would use it like (map (abstract-
function a-fn) some-seq). Examples from c.core include partial,
constantly and comp.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Prefixed or suffixed symbols?

2010-02-25 Thread Jarkko Oranen
On Feb 25, 12:17 am, joshua-choi rbysam...@gmail.com wrote:
 When it comes to distinguishing certain types of symbols from other
 things, should one use prefixes or suffixes?

Whichever makes more sense, of course. :)


 Example: naming tests with clojure.test/deftest. If you distinguish
 your tests’ symbols at all, do you do “t-addition” or “addition-t”?


Name tests descriptively. Putting them in their own namespace helps
too. If there's absolutely a need to distinguish them from non-tests,
I would prefer '-test'. Abbreviating it just makes it noisy.

 (I need to know what the standard is, if there is any, because I need
 a way to distinguish a certain type of symbol—those that represent
 “rules”— in my libraries. I’m using an underscore suffix right now,
 like “vector_”, which means “vector-rule” But “_rule” might be better,
 or even “_rule_”, though the last one might be overkill. In the past,
 I’ve used “vector-r, but I don’t like that now.)

I personally find underscores offensive, but... Some logic DSLs use ?
foo for variables, maybe you could have something similar for you
rules. Or you could name them using angled brackets (eg. vector).
When it comes to naming, you just need to be consistent. And avoid
underscores, please :P

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: funny (?) str behavior

2010-02-24 Thread Jarkko Oranen


On Feb 23, 10:47 am, Alfred Tarski atar...@gmail.com wrote:
 Hi,

 I have this function:

 (defn wrap [x]
   (str % x %))

 and I do

 bf= (str boo hoo  (map wrap [fdfd ggfs]))
 boo hoo clojure.lang.lazy...@9e050eb0

 This looks odd to me, but if the powers that be consider this to be
 the right behavior of str then my question is: what do I need to do do
 get what I want?

if you really want the seq to be stringified instead of the elements,
just do (str boo hoo  (seq (map (wrap [...]

I suppose lazy seqs are so lazy they won't even bother to provide a
string representation of themselves without coercion :)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Do I need to add dosync when I read the ref in this case

2010-02-21 Thread Jarkko Oranen

 But surely in this case you could do:

 (defn print-info []
   (let [[src dst] (dosync [...@source-account @dest-account])]
     (println src)
     (println dst)))

 or maybe:

 (defn print-info []
   (let [[src dst] (dosync
                     (ensure source-account)
                     (ensure dest-account)
                     [...@source-account @dest-account])]
     (println src)
     (println dst)))

 I suspect the ensures are necessary, but I would appreciate it if
 someone could explain why they are (or are not) necessary in this
 case.

As far as I know, dosync guarantees that the derefs are consistent
with each other. That is, no other transaction can affect the return
value of the deref while the transaction is running. However, deref
doesn't guarantee that the values read are still current when the
transaction finishes. Some other transaction might have been committed
first. If you absolutely need the most recent values, not just
consistent ones, you need to use ensure.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: First program, in case you want to give hints

2010-02-16 Thread Jarkko Oranen


On Feb 16, 12:26 pm, alux alu...@googlemail.com wrote:
 Hello,

 the current state of Conway's Prime Machine is athttp://paste.lisp.org/+21BR

Instead of using a quoted list, a vector is more idiomatic in Clojure.


 I'l go on learning. The next state should be seperation of print and
 produce. Currently (conway-pm) doesnt return stuff. I dont know if
 Clojure can produce infinite lists, like Haskell, and print the items
 as they come.

It can. They're just called infinite sequences. For example, (iterate
inc 0) produces an infinite sequence of integers from 0 onwards. You
can also construct your own infinite sequences using the lazy-seq
macro in a pattern like the following:

(defn count-down [x]
(lazy-seq (cons x (count-down (dec x) ; lazy-seq doesn't
actually evaluate the cons until it's requested

However, often you should start by looking at the core library and see
if there already exists a function to produce a list that you need,
and only afterwards construct things from scratch. For example,
repeatedly and iterate are common seq-producers, and map and
filter are used to transform them. They're all lazy, so infinite
seqs are not problematic.

There is one thing you need to look out for though: Never define a
global reference to an infinite seq. The items in a sequence are
cached, so if you define a global reference to the head, no part of
the seq will ever be garbage collected and its memory usage will be
unbounded.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: newbie question: Please help me stop creating constructors

2010-02-16 Thread Jarkko Oranen


On Feb 16, 8:27 pm, Yaron ygol...@gmail.com wrote:
 Sean and Richard perhaps I can address both of your mails in a single
 go. Here is an example of one of the functions from my calculator:

 (defn tax_deductible_expenses
         The total expenses incurred in business month m that are deductible
 from federal income tax
         [m]
         (let
                 [prepHouse (inflate *Prep_House_0* m)
                  fixedMonthlyCost (if (= m (months_in_business)) 0
 (fixed_monthly_cost m))]
                 (condp = (house_state m)
                         :ForLease (+ fixedMonthlyCost (if (= 
 (month_in_rental_cycle m) 0)
 prepHouse 0))
                         :Leased (+ fixedMonthlyCost (* (rental_income m) (+
 *Management_Fee* (if (= (month_in_rental_cycle m)
 *Months_To_Find_Tenant*) *Tenant_Finding_Fee* 0
                         :ForSale (+ fixedMonthlyCost (if (= m 
 (months_actively_renting))
 prepHouse 0))
                         :Sold (house_sales_expenses m

 Right now the function takes a single argument, m which is the month
 that tax deductible expenses are being calculated for. All the other
 values it needs are constants (e.g. either values provided at the
 start by the user or derived values).

First, a style nitpick: use foo-bar instead of fooBar or foo_bar
secondly, yes, you really should pass in a map of all the relevant
information. It might help to split up your calculator into multiple
functions, each of which deals with only part of the map. It might
even make sense to group the arguments a bit and pass in multiple
maps, or just some args outside of a map. The ideal is that a function
depends only on its parameters. Having many rebindable globals is
certainly *not* the way to go. :) For derived values, you might be
able to use let-bound locals.


 Now please look at a test I wrote to make sure the function does what
 I think it does:

 (deftest tax_deductible_expenses_basic
   (binding
     [*Months_To_Find_Tenant* 5
      *Months_In_Lease* 5
      *Lease_Cycles* 1
      *House_Sales_Price_0* 300
      *Monthly_Inflation_Rate* 0.002
      *Buying_Agent_Fee_Type* :Percentage
      *Buying_Agent_Fee_Number* 0.05
      *Selling_Agent_Fee_Type* :FlatFee
      *Selling_Agent_Fee_Number* 1000
      *Other_Sales_Fee_0* 100
      *Excise_Tax* 0.5
      *Original_Loan_Amount* 1
      *Monthly_Loan_Interest* (/ 0.05 12)
      *Months_In_Loan* (* 10 12)
      *Loan_Month_At_Start* 3
      *Prep_House_0* 100
      *Management_Fee* 2
      *Tenant_Finding_Fee* 0.5
      *Months_To_Sell* 3]
      (is (= (tax_deductible_expenses 0) (+ (fixed_monthly_cost 0)
 100)))
      (is (= (tax_deductible_expenses 1) (fixed_monthly_cost 1)))
      (is (= (tax_deductible_expenses 5) (+ (fixed_monthly_cost 5) (*
 (rental_income 5) 2.5
      (is (= (tax_deductible_expenses 7) (+ (fixed_monthly_cost 7) (*
 (rental_income 7) 2
      (is (= (tax_deductible_expenses 10) (+ (fixed_monthly_cost 10)
 (inflate 100 10
      (is (= (tax_deductible_expenses 12) (fixed_monthly_cost 12)))
      (is (= (tax_deductible_expenses 13) (house_sales_expenses 13)

 For the method tax_deductible_expenses to run it ends up requiring 19
 user defined values. That's a whole lot of arguments to pass into a
 function. Obviously I could wrap them up in a StructMap but then I get
 expressions like (+ 1 (args :B)) which doesn't seem much better than
 (+1 (B)).

 The issue I'm really trying to put my finger on is - these arguments
 really and truly are 'constants' within the context of the calculator.
 But they are constants whose values are not known as compile time but
 rather are known at run time. Does Clojure have a way to express a
 'late bound' constant or is the 'right' solution to pass around 19+
 arguments to functions or passing around StructMaps or making
 everything into thunks?


If you're passing 19 arguments to a function, it's most likely doing
too much. See if you can split up the logic somewhat.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: how to use with-bindings*

2010-02-15 Thread Jarkko Oranen

On Feb 15, 12:03 pm, Аркадий Рост arkr...@gmail.com wrote:
 oh wait...I take a look on binding and with-binding* 
 realesation.http://github.com/richhickey/clojure/blob/f4c58e3500b3668a0941ca21f9a...
 Why with-binding* function wasn't write like this:
 (defn with-bindings*
   [bindings f  args]
   (assert-args binding
     (vector? bindings) a vector for its binding
     (even? (count bindings)) an even number of forms in binding
 vector)
   (let [var-ize (fn [var-vals]
                   (loop [ret [] vvs (seq var-vals)]
                     (if vvs
                       (recur (conj (conj ret `(var ~(first vvs)))
 (second vvs))
                              (next (next vvs)))
                       (seq ret]
   (push-thread-bindings (hash-map ~@(var-ize bindings)))
   (try
     (apply f args)
     (finally
       (pop-thread-bindings

That function is very confused. You're trying to use a splice outside
of a syntax-quote which will not work. Even if you called simply (var-
ize bindings),  you would end up calling something like (push-thread-
bindings (hash-map (quote [(var 3) something, (var blah)
something]))) because the bindings vector is evaluated.

The binding operator is a macro, and it can work with the symbols
passed to it and transform the input to code that uses the var
operator, but the with-bindings* operator is a function, which means
it can't use var on its parameters. If you wanted to pass symbols to
with-bindings*, you would have to do it like (with-bindings* ['a 3, 'b
4]) and the functions would have to use resolve internally to
transform the vector into a map of vars to bindings.

As far as I can tell, binding could be implemented using with-bindings
like so:

(defmacro binding [bindings  body]
  ; var-ize elided; assume it exists
  `(with-bindings*
 ~(apply hash-map (var-ize bindings))
 (fn [] ~...@body)))

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Inheriting from IDeref - good idea or bad practise?

2010-02-08 Thread Jarkko Oranen
On Feb 8, 3:22 am, Stuart Halloway stuart.hallo...@gmail.com wrote:
 IMO Anything that implements IDeref should adhere to Clojure's vision  
 for identity, e.g. reads need to be thread safe, cheap, require no  
 coordination, and block no one.

Dereferencing futures or undelivered promises block the dereferencing
thread though, so potentially blocking derefs should not be a problem.
With side-effects in the deref operation, you would have to ensure
that it's safe from multiple threads, though.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: How to Initiate Clojure Application

2010-02-01 Thread Jarkko Oranen


On Feb 1, 3:16 pm, Timothy Pratley timothyprat...@gmail.com wrote:
 On 1 February 2010 09:32, Wardrop t...@tomwardrop.com wrote:

  Could someone step me through the idea behind the -main function
  (which I've also seen written as just main without the hyphen).

 Is -main special in any way, or is this just a convention that some
 environments select? In the past I think I've used a manifest to
 specify the main entry point... is that really necessary or does -main
 map to the default main entry point regardless of build tool? Just
 curious really!

-main is only special in that it maps to the 'main' method which the
JVM considers the main entry point of a class

The dash is the default gen-class prefix for functions that should be
used as the implementation of a method. You can specify another prefix
in the :gen-class form using the :prefix option.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Suggestion: Get rid of java.lang.Exception: EOF while reading..

2010-01-27 Thread Jarkko Oranen
You should really give paredit.el a go some time. It feels silly to
worry about matching parentheses nowadays.

That aside, I am supportive of any improvement in either compiler or
reader error messages.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: What are Vars supposed to be used for?

2010-01-24 Thread Jarkko Oranen
On Jan 24, 6:40 am, CuppoJava patrickli_2...@hotmail.com wrote:
 Thanks for the reply. That seems to match well with how I thought they
 were supposed to work.

 I'm just a little confused by the
 set!, with-local-vars, functions. What are they supposed to be used
 for?

   -Patrick

Vars are mutable reference types just like atoms and refs, but whereas
atoms and refs are intended to hold data shared across threads, The
most common mutable use for vars is *thread-local* binding, using
the binding macro. Of course, most of the time, they're just
effectively immutable containers for global (def'd) values.

To put it another way, the root binding of a var is supposed to remain
constant, but dynamic binding allows you to affect its value within a
single thread of execution. That's also why set! only works if the var
is thread-locally bound; Threads must not be affected by uncoordinated
change in another thread. (For that, there's the atom type)

alter-var-root is sometimes useful (though dangerous), but I still
haven't found a good use for with-local-vars

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: What's the idiomatic way to parse a binding form

2010-01-12 Thread Jarkko Oranen
On Jan 12, 11:08 am, Gabi bugspy...@gmail.com wrote:
 What's the idiomatic Clojure way for extracting values/keys from a
 binding form vector [key1 val1 key2 val2..] ?

I suppose that depends on what you want, but:

(apply hash-map keyvals) to make a map or
(map first (partition 2 keyvals))  (map second (partition 2 keyvals))

--
Jarkko
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: 1.1.0 *release* of clojure-contrib?

2010-01-05 Thread Jarkko Oranen


On Jan 6, 2:21 am, Mark Derricutt m...@talios.com wrote:
 Is there likely to be a RELEASE version of clojure-contrib 1.1.0 in
 the maven repo to match clojure 1.1.0 at all?

 The lack of a release build prevents using the maven release plugin to
 run with any project using it :(

 Also - if 1.1.0 is released, why is build.clojure.org/snapshots still
 getting NEW SNAPSHOT builds of 1.1.0?  Surely that should be 1.1.1, or
 1.2.0-SNAPSHOT now?


Heh, I guess the answer to the whys is just that no-one has got around
to fixing those things yet. There have been only three releases (or 4?
How many were before 1.0?), and only one after the git transition, so
I guess the whole release process is still in a flux as people are
trying to figure out what works best. I'm sure it'll settle down
eventually :)

It looks like there will indeed be a contrib release matching 1.1.0,
but I'm not sure when exactly.

--
Jarkko
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Code arrangement for understandability

2009-12-11 Thread Jarkko Oranen

On Dec 11, 11:14 am, ngocdaothanh ngocdaoth...@gmail.com wrote:

 Because of indents, my previous Clojure code lied to my eyes that x,
 y, f, g are not at the same block level. This is my difficulty with
 Clojure. In short, I can't see a rough algorithm from any Clojure code
 any more just by seeing the shape (levels) of blocks. To understand a
 Clojure code, I have to look at every bit of code, look closer.


You should come up with a real code example instead of a bunch of (f
x) (y z) expressions... The example you show is not very idiomatic
clojure simply because it has side-effects. (Of course you need side-
effects, but they should be isolated).

If the code structure gets too complicated, simplify it by writing
functions or macros to better express your intent.

  In Clojure we still need to look farther up the screen...

 Things in Erlang are immutable, so I think Clojure has no advantage
 over Erlang here.

  Practice using comp  partial...

 What do you mean by comp  partial? Could you please explain?

comp is function composition, and partial is partial application. eg:

((comp negate inc) 6) - -7

((partial + 1) 5) - 6

using these to create new functions is called point-free style
I'm not so much a fan, and I don't think point-free style is
particularly idiomatic in Clojure (unlike in Haskell for example), but
it's sometimes less noisy than #() or fn expressions, so it's good to
know.

They're usually best used with filter and map.


  (let [x 1
        y (+ x 2)]
    (f x)
    (g y))

 Well, I know my example code can be rewritten like that, but I just
 could not give a better one.

I don't think there's any use for comp or partial in this case. it's
too simple.


 Rearranging like this reminds me of C, in which every variables must
 be listed beforehand. Since all Clojurians say lazy is good, I would
 say I prefer C++ because I can be lazy in it, I only have to declare a
 variable when I actually use it.

Your code examples are a bit pathological. Usually (hopefully), you
would have Clojure code that looks like this:

(if-let [source (get-stuff-from-database)]
  (reduce +
(map somefn
  (filter somepred (extract-data source
  0) ; no data

Which is more functional in style. One thing you can do is to learn to
read these from right to left, which takes a bit of practice, but pays
off in the end, in my opinion. The - and - macros are sometimes
useful for transforming the right-to-left -readable forms into forms
that look more like pipelines:

(- (extract-data source)
(filter somepred)
(map somefn)
(reduce +))

There's no need for temporary names here. If a step needs explanation,
just add comments.

Hope this helps.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Code arrangement for understandability

2009-12-11 Thread Jarkko Oranen


 ((comp negate inc) 6) - -7

Hm, I was sure negate existed... But seems like it doesn't.

Oh well. (comp - inc) works. :)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Where is the Clojure 1.0 API documentation?

2009-12-09 Thread Jarkko Oranen
I just noticed that the API link on the clojure web site brings up
documentation for the master branch of Clojure instead of 1.0.0. I
can't find the 1.0.0 docs anywhere either.

This is obviously a problem for 1.0.0 users, since the docs refer to
features that don't exist.

I think it would be good to have the API page contain links to 1.0.0
docs as well as master and perhaps other branches as well. Also, a
clear indication (preferably in a bold font or something) of which
revision the doc was generated for would be useful.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Question about The whole language is there, all of the time.

2009-12-09 Thread Jarkko Oranen
Jeff Dik wrote:
 The part Running code at read-time lets users reprogram Lisp's
 syntax caught my attention.  Is this talking about reader macros?  I
 believe I read that clojure doesn't have reader macros, so would it be
 more accurate to say The whole language is there, _most_ of the
 time?


Clojure does have reader macros, though they're implemented in Java at
the moment (because the reader is, too.) They're also reserved for the
implementation, though this may change in the future, if someone can
convince Rich that an user-augmentable reader provides enough benefits
to outweigh the potential problems.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Java Class Factory

2009-12-03 Thread Jarkko Oranen


On Dec 3, 6:15 am, lazy1 miki.teb...@gmail.com wrote:
 Hello,

 I'm trying to create a factory method for Java classes, however I'm
 doing something wrong.

 (import '(java.util Dictionary HashMap))

 (def *containers* { :dict Dictionary :hash HashMap})
 (defn new-container
   [type]
   (new (*containers* type)))

 (def d (new-container :dict))
snip

 What is the right way to do this?

As others have stated, you can't use new, but since you're storing
Class objects in a hashmap, you could simply call (.newInstance
(*containers* type))... of course, assuming that the Class is
instantiable.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Suggestion: Add should_cache? flag to lazy-seq

2009-11-20 Thread Jarkko Oranen
On Nov 19, 11:52 am, Gabi bugspy...@gmail.com wrote:
 This would solve the holding to the head problem.
 Many times, lazy-seq would be used without the need to get the same
 cell twice.
 In this case, avoiding cashing would both enhance performance and more
 importantly would avoid OutOfMemoryError Exceptions like in:

 (def r (repeatedly #(rand)))
 (last r)

 So, something like:
 (defn lazy-seq [should_cache? body] ..
 would be beneficial (I think :)

I can see how that would be useful in some cases, but I think it also
would break the contract for seqs. They are supposed to be persistent.
I think a stream abstraction was considered at one point, but scrapped
in favour of chunked seqs.

The solution is simply to avoid defining a global reference to a seq
that might grow without bounds. Instead, define a function and just
create a new seq every time you want fresh values.

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: ExceptionInInitializerError in eval with user defined functions

2009-11-14 Thread Jarkko Oranen


On Nov 14, 8:08 pm, gun43 bg-561...@versanet.de wrote:
 Using r1366 under Win XP.
r1366? From Subversion? That's ancient. Clojure moved to git ages ago;
see
http://github.com/richhickey/clojure


 A user defined function:
 1:27 user= (defn plus2 [x] (+ x 2))
 #'user/plus2
 1:28 user= (plus2 5)
 7

 can only be eval'd
 1:29 user= (list plus2 5)
 (#user$plus2__217 user$plus2__...@4d76b4 5)
 1:30 user= (eval (list plus2 5))
 java.lang.ExceptionInInitializerError (repl-1:30)

 when passed with #'
 1:31 user= (list #'plus2 5)
 (#'user/plus2 5)
 1:32 user= (eval (list #'plus2 5))
 7

 in contrast to a core function
 1:33 user= (inc 5)
 6

 which works without
 1:34 user= (list inc 5)
 (#core$inc__3416 clojure.core$inc__3...@ded0f0 5)
 1:35 user= (eval (list inc 5))
 6

 and with #'.
 1:36 user= (list #'inc 5)
 (#'clojure.core/inc 5)
 1:37 user= (eval (list #'inc 5))
 6

 This is a real problem for anonymous functions.
 1:38 user= (#(+ % 2) 5)
 7
 1:54 user= (list #(+ % 2) 5)
 (#user$eval__277$fn__279 user$eval__277$fn__...@1f99eea 5)
 1:55 user= (eval (list #(+ % 2) 5))
 java.lang.ExceptionInInitializerError (repl-1:55)

 Is this a bug or am I doing something wrong.
 This stuff all worked under r1338.

I had no idea that this worked at all. Usually eval evaluates lists of
symbols and other primitives, eg.
(eval (list 'user2 2 3)). Hm. Anyway, try upgrading your Clojure. :)

--
Jarkko

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Datatypes and Protocols - early experience program

2009-11-13 Thread Jarkko Oranen
On Nov 13, 9:13 am, Krukow karl.kru...@gmail.com wrote:
 I was thinking this may make syntax irregular. I suspect this is a
 deliberate design choice to distinguish clojure protocols from java
 interfaces? Is this the case?


As far as I understand it, in defprotocol's case, I suspect there is
no dot because the specified operations will be available as normal
Clojure functions, whereas in deftype's case you'll need to use Java
interop or keywords. For example, after

(defprotocol Someproto
  (foo [x] do stuff))

you will be able to call (foo something-implementing-someproto), but
with deftype, you need to use (.field instance) or, if the type uses
the default ILookup implementation, (:field instance).

The extend example should just use :seq, as defprotocol will create a
function seq matching the .seq method in the Seqable interface.
(Because no explicit mapping is provided)

I hope I got my details right here. I haven't actually tried these
things yet. :)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Is it possible to implement break or return in Lisp?

2009-11-02 Thread Jarkko Oranen


On Nov 3, 2:03 am, CuppoJava patrickli_2...@hotmail.com wrote:
 Thanks Brian.

 For my own purposes, yes I have no need for a break or return
 statement.

 But I'm writing a DSL for others to use. People that don't have
 experience with functional programming, and for them it's easier to
 have a break/return. And for me, it's easier to implement break/return
 using an exception than it is to transform the DSL into appropriately
 nested if's.

You might find http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive
interesting. It's about making exception-throwing quick.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: clojure / ruby yield comparison

2009-10-25 Thread Jarkko Oranen

 But whilst this is useful, this doesn't really demonstrate why macros
 are so powerful. Macros are useful because they automatically
 rearrange your source code into something else. They're most similar
 to the Ruby 'eval' function, but operate of data structures rather
 than strings.

Nitpick, but... The function closest to ruby's eval would be 'eval'.
Except clojure's eval of course operates on data structures. Macros
are a feature of the Lisp evaluation model that allows you to
intercept the evaluator and run your own code.

Macros have two differences to normal functions:
1) Arguments passed to them are *not* evaluated, and
2) They are run after read-time, but before compile-time, and their
output is evaluated in place of the invocation.

Point 1 means that you don't need a lot of quoting when passing code
literals to macros, and point 2 is what allows these functions to be
used for syntactic abstraction, as a macro form can inspect and
transform its input parameters in any way imaginable, as long as the
output is also valid Clojure code.

The full power of macros takes a while to sink in. Because the entire
language is available, one can for example use macros with Java
reflection to programmatically produce Clojure wrappers for arbitrary
Java methods, at compile time.

Often you can solve a problem using higher order functions instead of
macros, like Daniel did with Ruby, but at times you will be thinking
I wish I could just write... and that's when you'll wish you had
macros. :)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Beginner: java.lang.Integer cannot be cast to clojure.lang.IFn (repl)

2009-10-19 Thread Jarkko Oranen


On Oct 19, 5:52 pm, Peregrine stiebs...@gmail.com wrote:
 Hey I am new to Clojure and I am doing some Project Euler problems to
 help me get started with the language. I've run into a issue I cannot
 seem to get past. I have this code:

 (defn findFib
         Find the sum of all the even-valued terms in the sequence which do
 not exceed four million.
         [e n p]
         (if ( n 100)
                 (if (= (rem n 2) 0)
                         (findFib (+ e n) (+ n p) (n))
                         (findFib (e) (+ n p) (n)))
         (str Value is  e)))

 And I keep getting this error

 1:9 problem2= (findFib 0 1 2)
 1:10 problem2= java.lang.ClassCastException: java.lang.Integer cannot
 be cast to clojure.lang.IFn (repl-1:9)

You're using your integers as functions, leading to this rather
cryptic error.
These two lines are the problem:
 (findFib (+ e n) (+ n p) (n))
 (findFib (e) (+ n p) (n)))
(e) and (n) are function calls, which will fail since e and n are
plain integers. You simply need to remove the parentheses and it'll
work. :)

Furthermore, your naming is nonidiomatic... Lisp code should use
lowercase and dashes instead of camelcase. find-fib is better. The
function also happens to be tail-recursive so you can replace the
findFib calls with the recur special form to avoid growing the stack
needlessly.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: let-while

2009-10-17 Thread Jarkko Oranen

On Oct 17, 10:32 am, Timothy Pratley timothyprat...@gmail.com wrote:
  But name is multiply evaluated. This might be preferable:

 Hi John,

 Could you explain this a bit more for me? I can understand if the
 condition is duplicated that is unnecessary calculation but don't
 appreciate the issue with the binding name... both versions of the
 macro seem to expand to identical code:
 user= (macroexpand-1 '(while-let [a nil] (foo)))
 (clojure.core/loop [] (clojure.core/let [a nil] (clojure.core/when a
 (foo) (recur
 So my naive view was they would have identical behaviour/performance.
 I've heard this come up before but never understood or been able to
 find any reference about this 'issue'.

I don't think the multiple evaluation matters in this case, since it's
the name parameter, which will in all sane cases be a simple symbol.
gensyms are needed when multiple evaluation could cause side-effects
or an expensive function to be computed multiple times, which is not
the case here.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: function names ending with !

2009-10-16 Thread Jarkko Oranen

On Oct 16, 5:44 pm, Mark Volkmann r.mark.volkm...@gmail.com wrote:
 What's the rule of thumb for deciding whether a function name should
 end with an exclamation point? I thought maybe it was when the
 function modifies its first argument, but it seems there are functions
 that do that and do not have such names.

 For example, set-validator! and add-watch. Why don't they either both
 end with ! or both not do that.

add-watch doesn't really affect the object itself, while set-
validator! certainly does, so I think the naming is consistent.
I think it might be a good rule of thumb to add the ! if the operation
either mutates the object (set!) or invalidates old values/references
to it, like persistent! or set-validator!. However, even core.clj
doesn't seem to follow this...

The exceptions seem to be the alter operations for reference types;
alter, commute, alter-var-root, and for some reason, ref-set.

--
Jarkko

 --
 R. Mark Volkmann
 Object Computing, Inc.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: ANN: scriptjure, a library for generating javascript

2009-10-07 Thread Jarkko Oranen


On Oct 8, 5:01 am, Allen Rohner aroh...@gmail.com wrote:
 Hello, I'd like to announce the availability of a new library, called
 Scriptjure. It's a macro that generates javascript strings from
 Clojure s-exprs. My initial use for it is in glue code for Clojure
 webapps. For example:

  (js (fn foo [x]
          (var y 3)
          (return (+ x y
  = function foo (x) {
            var y = 3;
            return (x + y);
         }

 You can get the code and read the documentation 
 athttp://github.com/arohner/scriptjure

 Allen

I took a quick look, and that looks really neat. One thing though:
Instead of the clj form to escape back to clojure, why not just use
unquote (and possibly unquote-splicing)? that would allow you to use
the ~ reader macro as a shortcut, just like in syntax-quote.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Syntax for proxy methods?

2009-10-01 Thread Jarkko Oranen

On Oct 1, 9:18 pm, timc timgcl...@gmail.com wrote:
snip
 (def prx (proxy [IX][]
   (doit
     ([] (doseq [x someSeq] (doit x))
     ([y] (print y

 When I tried something of this form, it looks like the call of the 1-
 arg function from the 0-arg function can't be resolved.

 Thanks in advance

I'm not certain, but since it's a java method, shouldn't you call it
like (.doit this x)?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: how to understand macro in clojure?

2009-09-28 Thread Jarkko Oranen



On Sep 28, 12:13 pm, Michael Wood esiot...@gmail.com wrote:
 Hi

 2009/9/26 gerryx...@gmail.com gerryx...@gmail.com:



  (defn float2 [f a b]
   (f (float a ) (float b)))

  (float2 + 1 2) = 3.0

  (defmacro mfloat2 [f a b]
   (f (float a) (float b)))
  (mfloat2 + 1 2 ) = 2.0  ???   macro expend to last expression in
  list,right?

 This is because (mfloat2 + 1 2) expands to:
 + (float 1) (float 2)

This is wrong. There is no way for a macro to expand to multiple
expressions.

What happens is, when you call (mfloat + 1 2) the macro evaluates ('+
(float 1) (float 2)), ie. it calls the *symbol* + with parameters 1.0
and 2.0. Symbols, when used as functions, look themselves up in
whatever associative thing you give them as the first parameter, OR
return the second parameter in case of lookup failure. So, ('+ 1.0
2.0) evaluates to 2.0, which is the macro expansion. and as 2.0
evaluated is 2.0, it is the actual result.

in the defn case, it works because the f parameter is actually
evaluated, and thus it's the + *function* and not the symbol '+.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Naming structs

2009-09-24 Thread Jarkko Oranen

On Sep 24, 11:01 am, Miron Brezuleanu mbr...@gmail.com wrote:
 Hello,

 I find that I tend to name struct instances like the struct. For instance,

 (defstruct person :name)

 and then

 (let [person (struct person John)]
 )

 which breaks further use of (struct person ...) in that let.

 Is there an established naming convention that I could use? (I'm
 trying to use (let [aperson (struct person John)]...) but I'm not
 completely happy with it.)

You could name the struct base person or something. I vaguely
remember reading somewhere that this is a Scheme convention of some
sort, but regardless of that, it looks good and doesn't interfere with
calling your persons persons. :)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: How to override .toString for a struct?

2009-09-22 Thread Jarkko Oranen



On Sep 22, 2:23 am, Jung Ko koj...@gmail.com wrote:
 Hi,

 Can someone teach me how I can override the toString method for a struct ?

 Here's a code snippet that shows what I'm trying to do:

 user (defstruct bookinfo :book :filename)
 user (struct bookinfo hello world) = {:book hello, :filename world}

 I would like to override the toString method on a struct so that the
 following behavior is true:

 user (struct bookinfo hello world) = hello

 In Common Lisp, I would simply define a method on (print-object). What
 would be the equivalent thing in Clojure?

As Mike said, it's done by adding a method to print-method, but you
will need metadata... structs in clojure are nothing but an
optimisation of maps... That is, in all situations structmaps are (at
least, should be) interchangeable with a regular persistent map. They
do not create their own type or anything, so you can't override their
toString method directly.

However, since print-method uses :type metadata, you can do the
following:

;; using ::foo to get namespace-qualified keywords is good for type
tags, because it avoids collisions
;; typed-book could be a struct-map, or in fact any implementation of
Map that also supports metadata
(def typed-book (with-meta {:book somebook} {:type ::my-book})) ;
the latter map is the metadata
(defmethod print-method ::my-book [thebook writer]
  (print-method (:book thebook) writer)) ; falls back to the string
writer

(print typed-book) ; prints 'somebook'
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: - with anonymous functions

2009-09-22 Thread Jarkko Oranen



On Sep 22, 3:58 pm, Roman Roelofsen roman.roelof...@googlemail.com
wrote:
 Hi there!

 Lets assume I have this map:

 user= (def person {:name Father :childs [{:name Son :age 10}]})

 Testing:

 user= (- person :childs first)
 {:name Son, :age 10}

 Now lets filter the child map:

 user= (def only-name (fn [m] (select-keys m [:name])))
 user= (- person :childs first only-name)
 {:name Son}

 So why does this not work?:

 user= (- person :childs first (fn [m] (select-keys m [:name])))
 java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't
 know how to create ISeq from: Symbol (NO_SOURCE_FILE:59)

 Or this?:

 user= (- person :childs first #(select-keys % [:name]))
 java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
 clojure.lang.IPersistentVector (NO_SOURCE_FILE:60)

You assume more of - than you should :)
- does not take functions as parameters. It only sees a bunch of
symbols, as it is a macro, which means it does a code transformation.
It puts the first form (the symbol person) in the second position of
the following form (the keyword :childs), which must be a sequence, or
if it is not, is wrapped in a list first. This repeats recursively
until there are no more forms left.
Now, the anonymous function example fails because (- person :childs
first (fn [] whatever)) transforms into (fn (first (:childs person)) x
[] y). which is not what you intended, but nonetheless a correct
result.

If you look at the examples that work and macroexpand them, you would
see that (- person :childs first) transforms first into (- (:childs
person) first) and from there to (first (:childs person)) which
happens to be a valid Clojure expression

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Q: dosync semantics

2009-09-21 Thread Jarkko Oranen



On Sep 21, 4:38 pm, Roger Gilliar ro...@gilliar.de wrote:
 I still have some problems to correctly understand the dosync  
 semantic.  What happens exaclty if two threads try to modify the same  
 list:

Nitpick: you're not modifying any lists. :) The only mutating things
are the Refs


 Example

 thread 1:

 (dosync
 append an item to a list
 ...
 )

 thread 2:

 (dosync
 remove an item from a list
 ..
 )

 Is it true that If thread 1 is executed 'before' thread 2 all changes  
 in thread 2 are rollbacked and the dosync in thread 2  is executed  
 until the change can be succesfuly applied (in this example after the  
 dosync of thread 1 is finished )?

In a way, yes. If there are two threads that concurrently try to
change the same ref, then one of them gets retried. As far as I know,
it's not strictly defined which one wins in case of contention...
That depends on the kind of operation you do in your transaction
(commute, for example, may allow conflicting writes without causing
a retry)

In any case, the synchronisation guarantees that if you have a
starting list A, either the remove or the append operation will be
applied to it, producing A', and the remaining operation will be
applied to A', producing the final value of the Ref.

Oh, and rather than changing the discussion subject, please make a new
topic. Changing the subject makes searches more difficult.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: delays are forced by deref too early?

2009-09-21 Thread Jarkko Oranen

On Sep 21, 6:53 pm, patrickdlogan patrickdlo...@gmail.com wrote:
 I expected a delay only to be forced by an explicit call to force.
 instead it looks like, being a kind of IDeref, a delay will be forced
 by the REPL.

 e.g.

 user= (def del (delay (println printed) (+ 2 3)))
 #'user/del
 user= del
 printed
 #de...@8691dee: 5
 user= (force del)
 5

 The documentation seems to imply the only way to force a delay is
 through the force procedure...

I'm pretty sure force is still causing the evaluation... Just
indirectly :)

The delay here is forced by its print method, which, as you can see,
also prints the value. Delays could be changed to print something like
#de...@232aee0: not computed, but I wonder if that's really useful.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: OutOfMemoryError with loop/recur

2009-09-18 Thread Jarkko Oranen

On Sep 18, 10:52 pm, Patrik Fredriksson patri...@gmail.com wrote:
 Hi!

 Could someone please help me understand why the following causes a
 java.lang.OutOfMemoryError: Java heap space for large n:s (10
 works fine, 100 does not).

 (def integers (iterate inc 1))

 (defn limited-reduce [fn coll n]
   (loop [c coll i n result 0]
   (if (zero? i)
     result
   (recur
     (rest c)
     (dec i)
     (fn result (first c))

 (limited-reduce + integers 10)

 Many thanks!

 /Patrik

First a nitpick: fn is a bad name, because it shadows a special form.
Using just 'f' is fine and idiomatic.

your problem is the (def integers ...). You're keeping the entire
sequence of integers in memory :)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Redefining Special Forms

2009-09-17 Thread Jarkko Oranen



On Sep 17, 7:33 pm, Gorsal s...@tewebs.com wrote:
 Basically i need to redefine the meaning of a special form. While i am
 willing to change the name for things like ns to defpackage, i am not
 willing to change the name of forms like apply and defn to achieve my
 goals. Instead, i would like to redefine them for my own needs. Of
 course, i will be using the actual special form but will refer to it
 instead by its full name. So... Is there any way or hack that i can
 redefine a special form like defn as my own macro/function?

As Stuart already said, you can't redefine special forms, and I'm not
sure if dynamically redefining macros makes sense either, since
they're expanded at compile-time—changing them at runtime would be too
late. Furthermore,  as far as I know, you can't even do it directly,
because you can't take the value of a macro to use in a binding form.

Binding *functions* like apply of course works normally using the
'binding macro, and *technically* you can change the underlying
function of a macro too, but... I can't imagine a situation where
you'd want that.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Unwind-protect?

2009-09-15 Thread Jarkko Oranen


On Sep 15, 6:54 pm, Gorsal s...@tewebs.com wrote:
 I was just wondering about the unwind-protect form, I've heard that it
 doesn't protect against certain types of exits, but what exactly are
 these exits? I've heard return, break, and continue statements said
 but i can't seem to find these statements in clojure. Any examples?

Unwind-protect? Isn't that a Common Lisp thing? Sounds like you got
the wrong mailing list :)

It's true though that Clojure has no return, break or continue... They
are imperative constructs, and Clojure is mostly functional. As far as
I know, the closest thing to unwind-protect is probably the finally
clause of a try-catch-finally form, but I don't think there's any way
to break out from inside a try block without executing the finally
code.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Pong!

2009-09-13 Thread Jarkko Oranen


On Sep 13, 2:43 am, jng27 jgran...@gmail.com wrote:
 http://jng.imagine27.com/articles/2009-09-12-122605_pong_in_clojure.html

Neat. I have some suggestions though.

1) I think you use too many refs. the sx, sy, etc. could all be
replaced with a simple
   (defstruct position :x :y)
   (def whatever (ref (struct position nil nil))
It's less granular, but much easier

Also, do the *w and *h refs don't seem to change after the game
starts, so refs are overkill for them. You could at least make them
atoms, though if possible using just regular defs and (binding [...])
or maybe even alter-var-root! would be cleaner (no need to explicitly
deref vars).

 2) write specialised functions for updating the positions, and use
alter instead of ref-set. eg. instead of
(ref-set bx (+ @bx @sx)) (ref-set by (+ @by @sy)) you could have
something like
(alter (partial merge-with +) b-pos @s-pos)

3) Split up the actionPerformed for the pong-frame. it's way too big.
The best way to split it would be to try to move as much of the actual
logic into pure functions and just altering your refs using those
functions. Separating the dosync logic (dealing with refs) from the
actual game logic (calculating the new values from the old ones) makes
the code much more understandable.

4) Prefer (.foo bar) and (Foo/bar) to (. foo bar)  (this is my
personal recommendation)

--
Jarkko

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Fixing production systems on-the-fly

2009-09-04 Thread Jarkko Oranen

On Sep 4, 11:22 am, Krukow karl.kru...@gmail.com wrote:
 I was thinking about the capability of changing production systems on
 the fly. E.g. by having an accessible repl in a running production
 system.

 If you have a bug in a function, you can fix it by re-def'ing it -
 that is great. However, suppose you want to do a system upgrade where
 you want to change several things. Now you could just re-def each var
 one at a time, but this might produce an inconsistent program in the
 interval where you have re-def'ed some but not all vars.

 This first thing you would want is sort-of a atomic update of all
 vars, similarly to what is possible with refs. Is this possible
 somehow? If not are there any techniques or best practices for these
 system upgrades?

 /Karl

Hm, I don't think it's possible to have transactional updates
involving multiple Vars, but you can always keep functions in Refs:
(def foo (ref (fn foo [x] x)))

then, because IRefs forward calls to their values, you can just do
(foo 1) and it works. :)
When you want to update multiple refs, all you should need to do is
(dosync (ref-set foo newfn) (ref-set another-foo anothernewfn)) ...

This approach requires a bit of manual work and discipline, but
probably is worth investigating

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Eval troubles

2009-09-03 Thread Jarkko Oranen

On Sep 3, 9:24 am, Miron Brezuleanu mbr...@gmail.com wrote:
 Hello,

 I'm a Clojure newbie (many thanks to Rich Hickey and everyone involved
 - it's a great programming environment) and I have some trouble with
 'eval'.

 What I'm trying is:
 $ java -cp clojure.jar clojure.lang.Repl
 Clojure 1.1.0-alpha-SNAPSHOT
 user= (let [x 1] (eval '(inc x)))
 java.lang.Exception: Unable to resolve symbol: x in this context
 (NO_SOURCE_FILE:1)

 (on a freshly downloadedcompiled clojure from github)

 According to my understanding ofhttp://clojure.org/evaluation, my
 code should simply return 2.

 What am I missing? :-)

Eval has no access to its lexical environment at runtime; you can only
use global bindings.

The syntax-quote trick Christian showed works because it expands to
something similar to (eval (list 'inc x)), and when eval is called,
the (list 'inc x) is evaluated (as function parameters are), the value
of x in the lexical context is available and the argument to eval
becomes '(inc 2), which works. (nb. eval can evaluate the inc symbol
because it names a global Var.)

I hope I managed to explain this clearly enough. I'm not sure I could
understand this explanation if I didn't already. :)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Lazy binding

2009-09-03 Thread Jarkko Oranen

On Sep 3, 3:42 pm, ngocdaothanh ngocdaoth...@gmail.com wrote:
 Hi,

 In Rails you can create a view like this:

 my_view.erb:
 %= hello + @name %

 I'm new to Clojure. I want to create something like the above like
 this:

 (defn my-view []
   (str hello name))

 The point is:
 * name is not known when my-view is defined
 * I don't want to pass name as a argument of my-view, this is kind of
 ugly boilerplate

If you don't pass the name as an argument, whence does my-view get it,
then?

I suppose you could use a global binding, and do (binding [*name*
whatever] (my-view)), but I'm not sure that's any better than just
passing in the parameter. eg.

(def *name*)

(defn my-view []
  (str hello  *name*))

(binding [*name* world]



Another option would be to pass the view functions a map of keywords
to replacements so that you can have a single data structure that's
easily applied to multiple views.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: with-open should use a close multimethod?

2009-08-28 Thread Jarkko Oranen

 I'll submit a patch if it's wanted.  This would fit in core, or maybe
 contrib.duck-streams with a slightly different name.

This should be in core I think, so that it can work with with-open—
unless we're going to duplicate with-open in contrib. :/

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Symbol to keyword

2009-08-25 Thread Jarkko Oranen


On Aug 25, 1:47 pm, Dragan Djuric draga...@gmail.com wrote:
 I needed a macro if I wanted to avoid ' in calls. It may seem as
 nitpicking but (to-keyword name) is more readable and less error prone
 than (to-keyword 'name) if I need to  use it in lots of places.

If that's all you do, then the easiest approach is to write both the
function and the macro.

Assume you have the function version, called to-keyword* (foo* is a
naming convention for something that is a variant of foo), then the
macro is as easy as:

(defmacro to-keyword [sym]
  `(to-keyword* ~sym))

the driver function idiom is very common and useful, as writing
functions is much less error prone than writing macros. This approach
also has the advantage that if you ever need to transform a collection
of symbols, all you need to do is map the to-keyword* function.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Calculating digits of π (Salamin-Brent)

2009-08-22 Thread Jarkko Oranen



On Aug 22, 5:56 am, jng27 jgran...@gmail.com wrote:
 Took a shot at implementing PI in Clojure using a reasonably fast
 algorithm.
 So why is it so slow ? Is BigDecimal just that bad ? Would fixed point
 arithmetic be better using BigInteger ?

Hmm, my impression is that the java boxed numbers aren't particularly
high-performance, but they shouldn't be slow either. But you're using
too much java in your code...

Why are you using the add method directly? + should work just fine.
Also, I personally do not like . at all. :)
You can set the math context by binding *math-context* to a math
context you need with (binding ...)

Also, nested defns are pointless and REALLY confusing. Do not use
them.
If you need local functions, use letfn or plain (let [foo (fn ...)])

I tried to clean up the thing a bit; it won't work as is because I'm
lazy. I don't set the math context, and it's missing the actual sb-pi
definition because I got confused by your lets. However, if you can
make this version work, it'll be a lot easier to figure out the
slowness.

Note that you don't need to create the bigDec constants yourself; just
use 1M, 2M etc.

(defn big-sqrt-int
  [#^BigDecimal num
   #^BigDecimal x0
   #^BigDecimal x1
   digits]
  (if-not (== x0 x1)
(recur num
   x1
   (/ (+ x1 (/ num x1))
  2M)
   digits)
x1))

(defn big-sqrt[#^BigDecimal num digits]
  Calculates square root using Newton's method.
  (big-sqrt-int
   num 0M (BigDecimal/valueOf
 (Math/sqrt (.doubleValue num)))
   (inc digits)))

(defn sb-pi-int
  [#^BigDecimal a #^BigDecimal b #^BigDecimal x #^BigDecimal p
n]
  (let
  [#^BigDecimal a1 (/ (+ a b) 2M)
   #^BigDecimal b1 (big-sqrt (* a b) digits)
   #^BigDecimal x1 (- x
  (* p
 (* (- a a1)
(- a a1
   #^BigDecimal p1 (* 2M p)]
(if ( n digits)
  (/ (* (+ a1 b1) (+ a1 b1))
 (* 4M x1))
  (recur a1 b1 x1 p1 (* 2 n)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Calculating digits of π (Salamin-Brent)

2009-08-22 Thread Jarkko Oranen



On Aug 22, 1:51 pm, jng27 jgran...@gmail.com wrote:
 This updated version is 2x as fast as the previous version :

 (import 'java.lang.Math)
 (import 'java.math.MathContext)
 (import 'java.math.BigDecimal)

 (defn sb-pi [places]
   Calculates PI digits using the Salamin-Brent algorithm
    and Java's BigDecimal class.

   (let [digits (+ 10 places) ;; add some guard digits
         round-mode BigDecimal/ROUND_DOWN]

     (defn big-sqrt[#^BigDecimal num]
       Calculates square root using Newton's method.

You *really* shouldn't do nested defns. They're misleading, as defns
*always* cause a global change.
Just use separate functions.


       (defn big-sqrt-int
         [#^BigDecimal num
          #^BigDecimal x0
          #^BigDecimal x1]
         (let [x0new x1
               x1new (. num divide x0new digits round-mode)

Hm, I wonder if there's a way to avoid calling java. But if you do, I
think you should use the form
(.divide num x0new digits round-mode) instead of . directly. It's
lispier and easier to read.

               x1tot (. (+ x1new x0new)
                        divide 2M digits round-mode)]
           (if (= x0 x1)
             x1tot
             (recur num x1 x1tot

       (big-sqrt-int
        num 0M (. BigDecimal valueOf (Math/sqrt (. num doubleValue)

     (defn sb-pi-int
       [#^BigDecimal a #^BigDecimal b #^BigDecimal
        t #^BigDecimal x #^BigDecimal y]

       (let
           [#^BigDecimal y1 a
            #^BigDecimal a1 (. (+ a b) divide 2M digits round-mode)
            #^BigDecimal b1 (big-sqrt (* b y1))
            #^BigDecimal t1 (- t
                               (* x
                                  (* (- y1 a1)
                                     (- y1 a1
            #^BigDecimal x1 (* x 2M)]

         (if (. a equals b)
Clojure = calls equals, so just use (= a b)

           (. (. (* (+ a1 b1) (+ a1 b1))
  divide (* t1 4M) digits round-mode)
  setScale places round-mode)
This is why I dislike . -- it's almost impossible to tell what
operation you're applying, and to which operands because the operation
name is not at the head of the list. :/
If you really need to use the .divide methods directly, maybe you
could use the - macro like this:

(- (* (+ a1 b1) (+ a1 b1)) ; would be faster to (let [tmp (+ a1
b1)]  ...) first though.
 (.divide (* t1 4M) digits round-mode)
 (.setScale places round-mode)

Though I think setting the math context would be a better solution.
eg.
(binding
  [*math-context* (java.math.MathContext. 5 java.math.RoundingMode/
HALF_UP)]
  (* 5M 1.105M))
gives 5.5556M

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: what's the appropriate way to process inner nested seqs in clojure?

2009-08-16 Thread Jarkko Oranen

On Aug 16, 12:02 pm, botgerry botge...@gmail.com wrote:
 Hello,all

 I'm new to functional programming,want to know how to address nested
 inner seqs in clojure

 (def a [[1 2 3 4] [ ok metoo] [ 5 8 9 ]])

 1:  searching in a, if find one inner vector includes number 9 then
 append it a number 13
  [[1 2 3 4] [ ok metoo] [ 5 8 9 ]]  = [[1 2 3 4] [ ok metoo]
 [ 5 8 9 13]]

 2: searching in a, if found two or many inner vectors include same
 element the merge them as one inner vector
 others not touch

 (def b ( conj  a  [ 5  10 oops]))  = [[1 2 3 4] [ok metoo] [5 8
 9] [5 10 oops]]
 in b, [5 8 9] and [5 10 oops] both include 5, it should be merge to
 [5 8 9 10 oops] :
 [[1 2 3 4] [ok metoo] [5 8 9] [5 10 oops]]  = [[1 2 3 4] [ok
 metoo] [5 8 9 10 oops]]

 I only found one solution to question 1 using zipper :
 (def dz (zip/vector-zip a))
 (defn append-to-blocks [x y] ;lookup x in blocks,if found then add y
 to inner block
    (loop [loc dz]            ;dz is blocks
      (if (zip/end? loc)
        (zip/root loc)
        (recur
         (zip/next
          (if (and (vector? (zip/node loc)) (includes? (zip/node loc) x))
            (let [new-coll (conj (zip/node loc) y)]
            (zip/replace loc new-coll))
            loc))

 user= (append-to-blocks 9 13)
 [[1 2 3 4] [ok metoo] [5 8 9 13]]

I think using a zipper is a good solution

 but still not figure out one way to question 2, i have tried:
 (defn merge-inner-blocks [x blocks] ;x is element maybe in many inner
 blocks
   (let [with-out-x (for [b blocks :when (not (includes? b x))] b)
         with-x (for [b blocks :when (includes? b x)] b)]
     (def blocks (concat with-out-x (vector (flatten with-x))   ;
 just merge them, not remove the same element

You should never use def inside a function. It's a certain sign that
you're doing something wrong. Why don't you just return the result
normally?

That said, I can't think of a fast solution for this either; but you
can wrap the (concat ...) in (vec (set ...)) to get a vector of
uniques.

 (merge-inner-blocks 5 b)
 #'user/blocks
 user= blocks
 ([1 2 3 4] [ok metoo] (5 8 9 5 10 oops))  ; here how to remove
 one of the 5?  vector has changed to list?

 3, I also found my solutions to this alike problems are not
 concise,and a bit ugly, any libs or appropriate way to process inner
 nested seqs in clojure? i thought those ops maybe frequently
 encountered in practical programming

I have to say I haven't had the need to do much with nested seqs, but
I suppose for that purpose clojure.zip would be worth learning more in
depth. It is designed for traversing and editing data structures,
after all.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: How to have a fast access to a java array of non-primitives?

2009-08-15 Thread Jarkko Oranen

Nicolas Oury wrote:
 Dear all,

 I try to write a program where I access a java array of non  primitive
 and realize aget is very slow.
 (6x slower than the same program with clojure vectors instead of java
 arrays access)

 I tried a few combinations of type hints but can't manage to prevent mty
 program to spend most of its time there:

 99.4% 0  +  8804java.lang.reflect.Array.get

 Does anyone know how to speed that up?
 Is it written somewhere in the java interop documentation?

I don't think it's explicitly mentioned in the docs, but you need to
hint the array using some rather gruesome syntax. See
http://clj-me.blogspot.com/2009/08/what-warn-on-reflection-didnt-tell-you.html

Most likely #^objects will be available in the next version of
Clojure. :)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: Promote clojure.contrib.def to a core lib

2009-08-14 Thread Jarkko Oranen

I'm in favour.

Though, I think that a def- would be redundant if the defvar macros
are promoted. Perhaps it would be sensible to keep def as a the
underlying special form and just move in defvar, defvar- and
defmacro-.

I'm not sure whether defonce is useful enough that it should be moved
to core, so I'll abstain.

The larger macros (eg. defnk) should definitely remain in contrib.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Clojure Golf, episode 1

2009-08-14 Thread Jarkko Oranen



On Aug 14, 10:51 pm, Sean Devlin francoisdev...@gmail.com wrote:
 I'd start with you usage docs

 ;; usage:
 ;; (filter-collecting
 ;;   (fn [x y] ( x y))
 ;;   (fn [x y] (+ x y))
 ;;   [1 7 3 9]
 ;;   [5 5 5 5])
 ;;  == (6 8)

;; usage:
;; (filter-collecting  +
;;   [1 7 3 9]
;;   [5 5 5 5])
;;  == (6 8)

(defn filter-collecting [c f  seqs]
  (remove nil?
(apply map (fn [ args] (when (apply c args)
   (apply f args)))
   seqs)))

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Adding optimizations to Clojure

2009-08-14 Thread Jarkko Oranen

fft1976 wrote:
 On Aug 13, 9:57 pm, Daniel Lyons fus...@storytotell.org wrote:

  the code is open source and the techniques for adding  
  optimizations to compilers are well known. So marshall your impulses  
  for the good and we'll all benefit.

 It does seem that the optimizations Andy Fingernut did by hand are
 pretty braindead, and need to be done automatically. If I did change
 the compiler to do these, what are the chances of my improvements
 getting merged into the main tree? Otherwise, such work would be
 utterly pointless.


I don't think spending too much effort on the compiler at this point
is useful. It will eventually be rewritten in Clojure anyway, and Rich
has stated that he is more interested in architectural improvements
rather than an optimising compiler, for now at least.

Of course, if the optimisations really are simple to implement, I
don't think patches will be outright *rejected* if you do send them.

When it comes to Clojure/java performance comparisons, I think Clojure
code is too different from Java to be directly comparable in most
cases. And yes, I agree that getting the best performance possible is
a chore. Sure, getting an inner loop to produce the same bytecode as
the java equivalent *is* possible, but to do so on whole program level
would require writing Java in Clojure and a lot of macro trickery to
avoid boxing.  No-one wants to do that.

Still, I wouldn't worry too much. Clojure is still young, and
performance is already good enough for many, many applications.

--
Jarkko

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Pure-functional N-body benchmark implementation

2009-08-10 Thread Jarkko Oranen

On Aug 10, 12:41 pm, fft1976 fft1...@gmail.com wrote:
 I just uploaded to the group an implementation of the n-body benchmark
 in Clojure (see nbody_init.clj)

 http://shootout.alioth.debian.org/u32/benchmark.php?test=nbody〈=j...

 My goal was to write a pure-functional version and to avoid any micro-
 optimizations. There are no type declarations and plenty of laziness
 and higher-order functions.

 It seems to be 100 times slower than Java (I was expecting worse) on
 my machine, putting it in the same class as Ruby, Perl and Python
 (which are imperative).

 The obvious things to do next here, in the order of ugliness, are:

 1. switch to 3D vectors instead of arbitrary length functions
 2. add type declarations
 3. avoid maps
 4. experiment with adding/removing (vec ...
 5. get imperative or transient
 6. switch to Java arrays/classes

 I am curious about how much more non-idiomatic Clojure has to become
 here for each step it takes towards Java-like performance in this
 benchmark, and whether the most optimized version will match Java in
 speed.

 I hope others can pick this up and implement the optimizations, or
 post their timings.

I'm not going to start optimising, but I don't think there's a need to
avoid maps. You could use struct maps and
generate accessors for the base keys... but somehow I doubt that is
the bottleneck

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: transient quicksort

2009-08-04 Thread Jarkko Oranen

On Aug 4, 11:08 am, Jonas jonas.enl...@gmail.com wrote:
 Hi

 I'm playing with the new transient/persistent! features in Clojure. I
 have implemented quicksort as described on wikipedia (http://
 en.wikipedia.org/wiki/Quicksort#Algorithm). Here is the code:

 (defn swap-index! [v i j]
   (let [tmp (v i)]
     (assoc! v i (v j))
     (assoc! v j tmp)))

I think Rich mentioned on IRC that you should not reuse the transient
vector binding after an operation; that it works is merely an
implementation detail. The transient documentation page also says
tells to capture return value, use for next call. So:

(defn swap-index! [tv i j]
  (let [tmp (tv i)]
(- tv
  (assoc! i (v j))
  (assoc! j tmp

And similar modifications for the quicksort below.


 (defn partition! [v left-index right-index pivot-index]
     (let [pivot-value (v pivot-index)]
       (swap-index! v pivot-index right-index)
       (loop [i left-index store-index left-index]
         (if ( i right-index)
           (if (= (v i) pivot-value)
             (do (swap-index! v i store-index)
                 (recur  (inc i) (inc store-index)))
             (recur (inc i) store-index))
           (do (swap-index! v store-index right-index)
               store-index)

 (defn qsort! [v left right]
   (when ( right left)
     (let [pivot-index left
           pivot-new-index (partition! v left right pivot-index)]
       (qsort! v left (dec pivot-new-index))
       (qsort! v (inc pivot-new-index) right

 (defn qsort [v]
   (let [tv (transient v)]
     (qsort! tv 0 (dec (count v)))
     (persistent! tv)))

 This sorts a vector of doubles in about 6000-7000 msec on my machine:

 user= (def s (time (qsort (rvector 100
 Elapsed time: 6681.35889 msecs

 This is much faster than the classical functional programming
 quicksort:

 ; Fromhttp://rosettacode.org/wiki/Quicksort#Clojure
 (defn qsort-rs [[pivot  xs]]
   (when pivot
     (let [smaller #( % pivot)]
       (lazy-cat (qsort (filter smaller xs))
                 [pivot]
                 (qsort (remove smaller xs))

 user= (def s (time (doall (qsort-rs (rvector 100)
 Elapsed time: 32565.537389 msecs

 The Java sort however is about 5 times faster then the transient
 version:

 user= (def s (time (sort (rvector 100
 Elapsed time: 1354.427239 msecs

 Can you give any hints on how I can make the transient sort faster? I
 would like to get as close as possible to the native Java speed.

This is partially comparing apples to oranges though: sort returns a
lazy seq, while
the quicksort algorithm produces a proper vector.

Anyway, (nth v i) might be somewhat faster than (v i) because it gets
inlined. I did not try, though.

Below is code that avoids reusing the reference to v:

(defn swap-index! [v i j]
  (let [tmp (nth v i)]
(- v
(assoc! i (nth v j))
(assoc! j tmp

(defn partition! [v left-index right-index pivot-index]
(let [pivot-value (nth v pivot-index)
   new-v (swap-index! v pivot-index right-index)]
  (loop [v new-v, i left-index, store-index left-index]
(if ( i right-index)
  (if (= (nth v i) pivot-value)
(recur (swap-index! v i store-index) (inc i) (inc store-
index))
(recur v (inc i) store-index))
  [(swap-index! v store-index right-index)
   store-index]

(defn qsort! [v left right]
  (if ( right left)
(let [pivot-index left
   [new-v pivot-new-index] (partition! v left right pivot-
index)]
  (- new-v
  (qsort! left (dec pivot-new-index))
  (qsort! (inc pivot-new-index) right
v)

(defn qsort [v]
  (let [tv (transient v)]
(qsort! tv 0 (dec (count v)))
(persistent! tv)))

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Newbie question about anonymous functions

2009-08-02 Thread Jarkko Oranen

Chad Harrington wrote:
 I have a newbie question about anonymous functions.  Why does the first form
 below work and the second form does not?

 user ((fn [] foo))
 foo

 user (#(foo))
 ; Evaluation aborted.

fn and #() are not interchangeable. In the first example, you simply
return foo. However, #(foo) expands to (fn [] (foo)), so you end
up calling a string, which of course fails.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Possible addition to swing-utils?

2009-08-02 Thread Jarkko Oranen

On Aug 2, 2:12 am, Meikel Brandmeyer m...@kotka.de wrote:

 (defmacro with-chosen-file
    Opens a file chooser, binds the result the user chose to the given
    variable name and executes the body. In front of the body there might
    be two options given:

      :directory is the initial directory shown in the chooser
      :label is the label shown on the Ok button of the dialog

    If no directory is given, the dialog will show the parent directory
    of the last chosen file. If no label is given Choose will be used.
    If given, directory must be specified first.
    [file  body]
    (let [directory (when (= (first body) :directory)
                      (second body))
          body      (if directory
                      (nnext body)
                      body)
          label     (if (= (first body) :label)
                      (second body)
                      Choose)
          body      (if (= (first body) :label)
                      (nnext body)
                      body)]
      (if directory
        `(with-chosen-file* (fn [~file] ~...@body) ~directory ~label)
        `(with-chosen-file* (fn [~file] ~...@body) ~label

 Any thoughts? I'm not totally happy with the current form, so  
 discussion appreciated.

Why not just use a map for the options? I think it's easier to
understand and process within the macro.

(defmacro with-chosen-file
  docstring
  {:arglists '([name option-map?  body])}
  [file  [opts  body :as all]]
  (let [have-opts (instance? clojure.lang.IPersistentMap opts)
opts (merge {:label Chooser }
(if have-opts
  opts
  {}))
body (if have-opts
   body
   all)
directory (opts :directory)]
(if directory
  `(with-chosen-file* (fn [~file] ~...@body) ~directory ~(:label
opts))
  `(with-chosen-file* (fn [~file] ~...@body) ~(:label opts)

then call as
(with-chosen-file foo {:directory somedir}
  (dostuff foo))

The option map could even be passed to the driver function as is,
eliminating the need for overloads.
also, file-chooser-last-directory could be made local to the function
by doing the 'defn inside a (let [last-dir (atom ...)] ...)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: let a variable number of bindings

2009-07-18 Thread Jarkko Oranen


 user= (macroexpand-1 '(let-coll [a b c] {:a 1 :b 2 :c 3} (println a b  
 c)))
 (clojure.core/let [val-fn__23 {:a 1, :b 2, :c 3}
                     a          (val-fn__23 :a)
                     b          (val-fn__23 :b)
                     c          (val-fn__23 :c)]
    (println a b c))
 user= (let-coll [a b c] {:a 1 :b 2 :c 3} (println a b c))
 1 2 3

 I actually like this idea. :)

That looks a lot like map destructuring, though:

(let [{:keys [a b c]} {:a 1 :b 2 :c 3}]
  (list a b c))

- (1 2 3)
--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: turn a seq into a list

2009-07-15 Thread Jarkko Oranen

On Jul 15, 1:54 pm, Jan Rychter j...@rychter.com wrote:
 I've been looking for a function that would take a seq and create a list
 (a real clojure.lang.PersistentList), but haven't found one. The closest
 I got was:

 (apply list my-seq)

 Essentially, I'm looking for something similar to (vec) that returns
 lists.

 --J.

Why would you want to do this? Seqs are nearly identical to lists (The
only difference I can think being that lists are Counted, while seqs
are not). If it's about forcing strictness, You can use 'doall.

However, if you really do need a PersistentList, then (apply list the-
seq) is what you need. The vec function is a shortcut for (apply
vector the-seq), provided in the standard library because vectorising
a seq is rather common.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: clojure.test - Test fixtures and ordering

2009-07-14 Thread Jarkko Oranen

On Jul 14, 6:58 pm, Stuart Sierra the.stuart.sie...@gmail.com wrote:
 Namespace-wide fixtures (once-fixtures) are easy -- they should just
 run around the top-level test function.  That's something I can fix,
 and it will be sufficient for your example.

 But per-test fixtures (each-fixtures) present a problem.  If the
 fixtures are run around every test function, then they will be called
 multiple times when test functions are nested.  Should they be called
 just around the top-level test functions, or just around the bottom-
 level test functions?  And how do you determine where the bottom of
 the test function hierarchy is?

I don't think ns-test-hook should really care about this. Perhaps it
would be best to consider test-ns-hook a low-level construct that can
do whatever it wants with the defined tests and fixtures, and provide
some other means for specifying which tests will be run.

Alternatively (or additionally), provide a facility for tagging tests
and defining fixtures that are run around tests with a specific tag.
Then, you could simply use a tag that has no fixtures defined:

; no explicit tag implies each?
(deftest test1 ...)
(deftest test2 ...)

(deftest testgroup {:fixtures 'no-fixtures}
  (test1)
  (test2))

To get the fixtures called, though, deftest probably needs to return
something like:
(def testname
  (fn [] (execute-test test-info-map; we should have the map at
this point so we can form a closure, right?
(fn [] (actual-test-content-here)))

where execute-test would by default be bound to a function that runs
whatever fixtures the test has. A custom test-ns-hook could rebind
execute-test at will.

This could all be done with fixture macros manually too of course, but
wrapping functions are probably somewhat easier to write.

--
Jarkko


PS. For whatever reason, this stuff makes me think of monads. :)

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: another binding issue?

2009-07-14 Thread Jarkko Oranen

On Jul 14, 10:04 pm, bgray graybran...@gmail.com wrote:
 I'm not sure if this is a binding issue or not.

 user= (def a 1)
 #'user/a
 user= (binding [a 3] (filter #(= % a) '(1 2 3)))
 (1)
 user=

 In this case, I was expecting a list with 3 in it.

This is a common gotcha. It's actually a laziness issue: the seq
produced by filter is realised only after it exits the binding scope,
thus producing '(1). You need to use doall to force the seq if you
want the binding to apply.

--
Jarkko

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Using Ref

2009-07-13 Thread Jarkko Oranen

On Jul 13, 1:39 pm, sailormoo...@gmail.com sailormoo...@gmail.com
wrote:
 Hi :

   I would like to simulate a simple database with the STM of clojure.
 The rules are
 1. There can be many rooms, and each room has its own attirbute
 2. One room contains many people, and each person has its own
 attribute
 3. rooms can be created, and deleted, and people can be added into or
 removed from room.

 So I made a globle variable *rooms*,
 where *rooms* is a reference of a sequence of references of rooms,
 where room is a hashmap, with an attribute of reference of a sequence
 of references of people.

 Just like this,
 (def *rooms* (ref {room_1 (ref {:players (ref [(ref
 player)])} ) } ) )

 Ouch, it has 4 refs @@
 I think it's hard to control, but why did I make that many ref?
 If there is fewer refs, the functions that alter might need to see
 outer ref to do an alter.

 Any one got an idea to make the code easier ?? Thanks

You don't need refs for everything you might want to change; having
fewer refs just means you have coarser granularity for updates, thus
*possibly* reducing concurrency or scalability. However, the fewer
refs you have, the easier they are to manipulate. It's a matter of
finding balance.

I would start with a single ref *rooms* which could be a map of room-
name - ref to room, which in turn would contain a set of unique
player IDs.
Note: Having the room wrapped in a ref is enough. Replacing the entire
room map when you need to add to the set of joined players is likely
about as expensive as having to deal with two refs. It might even be
faster.

Then, keep a separate ref to a *players* map which maps a given id
number to the player's information map, which does not have to be a
ref, again because updating the entire player map is not that
expensive.

There are other approaches, but I think when starting to code, it's
good to keep the number of refs to a minimum.

Also, when coding the ref-altering functions, resist having the dosync
blocks inside the smallest functions; that is, instead of a join-room
fn that contains a dosync, have a join-room that takes a room data
structure and a player id/whatever, then returns a new room data
structure, and use that function with alter.

Or, put another way, consider functions containing 'dosync impure, and
as such, try to keep them in one place instead of scattering them
around. :)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Why do Enlive template functions return a seq instead of a str?

2009-07-11 Thread Jarkko Oranen



On Jul 11, 6:01 pm, Robert Campbell rrc...@gmail.com wrote:
 Hey guys,

 I'm just curious why Christophe chose to return seq instead of a str
 for Enlive for his template functions.

 Example:

 (deftemplate my-page-transformation index.html [message style]
   [:style] (content style)
   [:h1] (content message))

 orchid (my-page-transformation my wonderful header h1 { color: blue })
 (html \n\t head \n\t\t style h1 { color: blue }
 /style \n\t /head \n\t body \n\t\t h1 test
 /h1 \n\t /body \n /html)

 It's trivial to call (apply str (my-page..)) but I'm just curious
 about the thinking behind using a seq. Is it related to xml-seq and
 traversing the tree?


Most likely Enlive generates each of those fragments separately;
Forcing them into a single string at the end would wasteful in case
the user intends to write the output into a stream (which can be done
a fragment at a time.) Thus, leaving the choice to the user seems like
a good decision.

Or maybe it's just a lazy seq, in which case using str on it would
force it to be strict. :)

 Thanks,

 Rob

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Questions / guidelines for adopting Clojure

2009-07-07 Thread Jarkko Oranen

snip
Shawn Hoover wrote:
 For example, Java doesn't have language support like C#'s using statement
 for executing some block of code and deterministically cleaning up an object
 at the end. You could implement that as a function (in many languages) and
 call it like this:
 (defn do-and-close [o f]
   (try
     (f)
     (finally (.close o
 (let [file (FileInputStream. todo.txt]
   (do-and-close file
     (fn []
       (do stuff with file

 In Clojure this was made cleaner with a simple macro,
 clojure.core/with-open. Usage:
 (with-open [file (FileInputStream. todo.txt]
   (do stuff with file))

with-open is a good, simple macro, but with a trivial example like
that, I don't think it demonstrates well enough what macros can do for
you that functions can't. So let's make it a bit more complicated.

with-open actually supports binding *multiple* closeables that depend
on each other, just like let:

(with-open [file (FileReader. test.file)
   buffered (BufferedReader. file)]
 (do-stuff-with buffered))

with-open properly closes them in the reverse order, too.

compared to the function approach, which quickly gets unwieldy:
(let [file (FileReader. test.file)]
 (do-close file (fn []
   (let [buffered (BufferedReader. file)]
 (do-close buffered (fn []
   (do-stuff-with buffered)

One might think that it's possible to have do-close accept multiple
files, but there's a problem:
since function arguments are evaluated when the function execution
begins, any errors happening during the creation phase will not be
caught and thus some streams might be left unclosed.

To emulate with-open perfectly, every file would have to be passed
wrapped in an anonymous function! That's a lot of boilerplate, which
would make with-open pointless, as its purpose is to eliminate
boilerplate. :)


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: tests involving threads

2009-07-06 Thread Jarkko Oranen



On Jul 6, 7:51 am, Timothy Pratley timothyprat...@gmail.com wrote:
 Very glad that test is now part of clojure core.

 I've run into 2 strange behaviours when trying to write tests where
 threads are involved. My case is a little complex so here is a minimal
 version which shows what I mean:

 test-test.clj:
 (ns test-test
   (:use clojure.test))

 (deftest testathon
   (let [f1 (future (is (= 1 2)))
         f2 (future (future (/ 1 0)))]
     @f1
     @f2))

 (run-tests)
 (shutdown-agents)

 $ clj test-test.clj

 Testing test-test

 FAIL in clojure.lang.persistentlist$emptyl...@1 (test-test.clj:5)
 expected: (= 1 2)
   actual: (not (= 1 2))

 Ran 1 tests containing 0 assertions.
 0 failures, 0 errors.

 f1 failed, and a FAIL message is printed, but the end report indicates
 0 failures.
 f2 raised an exception silently.

 I guess I'm just not doing it right!


Are you sure you don't want to test something like
(let [v (future (+ 1 2))]
  (is (= @v 3)))
instead? My guess is that having 'is inside a future messes up the per-
thread bindings that clojure.test uses. I don't know if there's a way
around that, but also doubt assertions inside futures are really
useful.

 Regards,
 Tim.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Adding type hint causes compiler error

2009-07-06 Thread Jarkko Oranen



On Jul 6, 1:26 pm, philip.hazel...@gmail.com
philip.hazel...@gmail.com wrote:
 On Jul 5, 10:31 pm, Mark Triggs mark.h.tri...@gmail.com wrote:

  (defn bi-get-pixels
    [#^BufferedImage bi]
    (let [raster (.getData bi)
          pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
                             (cast (Class/forName [I) nil))]
      (vec pixels)))

 This still generates a single reflection warning, but #^ints before
 the cast fixes it. That gave me an idea:

 (defn bi-get-pixels
   [#^BufferedImage bi]
   (vec (.. bi (getData)
            (getPixels 0 0 (.getWidth bi) (.getHeight bi)
                       #^ints (identity nil)

 Which does the right thing with no warnings.

 Thanks for the help,

 -Phil

(ints nil) might also work
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: ANN: libraries promoted from contrib to clojure

2009-06-29 Thread Jarkko Oranen



On Jun 29, 6:14 pm, John D. Hume duelin.mark...@gmail.com wrote:
 There may already have been a discussion about this in IRC, but I
 would have loved to see the 'are' macro continue to support the old
 syntax (maybe with deprecation warnings) as well as the new until
 after 1.1 is released. This change makes it relatively expensive for
 any library with a significant test suite that uses 'are' to keep
 testing with both the current release and the current snapshot of
 clojure and contrib.

You can always checkout the contrib version prior to these breaking
changes for your tests.
(seems to be 3073f0dc0614cb8c95f2debd0b7e6a75c1736ece)
There has been talk on IRC about creating a 1.0-compatible branch, but
so far no-one has taken action. :/

You could also attempt to write a compatibility wrapper that has the
old are syntax, but transforms it into the new are.
If most of your tests are of the form (are (= _1 _2) ...) then it's
only a matter of transforming that to (new-are [_1 _2] (= _1 _2) ...).

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Buggy behavior of recur with primitives

2009-06-28 Thread Jarkko Oranen

On Jun 28, 8:53 am, Handkea fumosa hfum...@gmail.com wrote:
 (defn foo [z-r z-i c-r c-i bailout max-iters]
   (let [G__12819 (double c-r)
         G__12820 (double c-i)
         G__12817 (double -1)
         G__12818 (double 2)
         mi (int max-iters)
         b (double (* bailout bailout))]
     (loop [G__12815 (double z-r)
            G__12816 (double z-i)
            i (int 0)]
       (if ( i mi)
         :iters
         (if ( (+ (* G__12815 G__12815) (* G__12816 G__12816)) b)
           i
           (recur
             (+ (* G__12815 G__12815) (* G__12817 G__12816 G__12816)
 G__12819)
             (+ (* G__12818 G__12815 G__12816) G__12820)
             (unchecked-inc i)))

 #CompilerException java.lang.RuntimeException:
 java.lang.IllegalArgumentException: recur arg for primitive local:
 G__12815 must be matching primitive (foo.clj:391)

 The recur arg in question is  (+ (* G__12815 G__12815) (* G__12817
 G__12816 G__12816) G__12819) all of whose operands are doubles.

 This seems buggy.
snip

This is just a hunch, but maybe it's because you have three operands
on +? it's inlined only for two operands,
and uses reduce for more. Thus, your arguments might be getting boxed.

Try explicitly calling + (and *) with only two arguments at a time.

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Trying to use lazy-seq for the first time, failing.

2009-06-27 Thread Jarkko Oranen

On Jun 27, 3:23 am, _hrrld hhaus...@gmail.com wrote:
 Hi,

 I'm trying to use lazy-seq to implement a cool piece of functionality
 I saw in the Factor programming language. Here is the documentation
 for that 
 functionality:http://docs.factorcode.org/content/word-produce,sequences.html

 I think a lazy version of Factor's produce word would be super-
 powerful for some of the things I'm working on.

 This is the first time I've tried to create my own lazy sequence, so
 don't laugh.

 Here is my attempt:http://gist.github.com/136825

 For some reason, the lazy sequence that is returned is always empty
 (?) or at least seems that way.

 Am I doing something silly? Or perhaps I've misunderstood lazy-seq's
 operation.

You're forgetting to return a value from your lazy seq!
in your case, you will just recursively call produce until it returns
nil, which
causes all the previous calls to produce nil as well, which is an
empty sequence

Try the following:

(when (predicate val)
 (lazy-seq (cons val (produce ...))) ; abridged due to laziness!

lazy-seq may need to be before 'when to clear all locals, but I'm not
sure about that. Should work either way.

eventually, the recursive call to produce will give a nil, which ends
the lazy sequence. You can think each cons operation yielding a rest
sequence. the final rest is (cons val nil), yielding (val)

However, there's probably an easier way to do this, using either
iterate or repeatedly:

(take-while pos? (iterate dec 10))

(take-while #( % 3) (repeatedly #(rand 6))) ; you'll probably need to
run this a few times to get results

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Trying to use lazy-seq for the first time, failing.

2009-06-27 Thread Jarkko Oranen


On Jun 27, 3:23 am, _hrrld hhaus...@gmail.com wrote:
 Hi,

 I'm trying to use lazy-seq to implement a cool piece of functionality
 I saw in the Factor programming language. Here is the documentation
 for that 
 functionality:http://docs.factorcode.org/content/word-produce,sequences.html

 I think a lazy version of Factor's produce word would be super-
 powerful for some of the things I'm working on.

 This is the first time I've tried to create my own lazy sequence, so
 don't laugh.

 Here is my attempt:http://gist.github.com/136825

 For some reason, the lazy sequence that is returned is always empty
 (?) or at least seems that way.

 Am I doing something silly? Or perhaps I've misunderstood lazy-seq's
 operation.

 Thanks in advance for any advice,
 -Harold

Grr, GG apparently swallowed my first reply...
Anyway, your problem is that you're never actually returning anything
besides nil from 'produce.
You'll want something like

(when (pred val)
  (lazy-seq (cons val (produce ...))

Where the point or cons is to return the rest sequence; it's lazy,
but if you consider the last rest, it will be
(cons val (produce ...)) where the last call to produce gives nil, and
the final rest sequence is therefore (val)

However, you can also use a more functional technique to make a
produce. Clojure has two higher-order functions (lazy, of course)
called iterate and repeatedly:

(take-while pos? (iterate dec 10))

(take-while #( % 3) (repeatedly #(rand 6))) ; Might give an empty seq

Hope this helps. :)

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Roadmap of Clojure 1.1

2009-06-25 Thread Jarkko Oranen



On Jun 25, 9:51 am, michael frericks michael-freri...@web.de wrote:
 Hello,

 i am a little bit lost about the roadmap of clojure 1.1. Is there
 anywhere an (evolving) list available of

 a) new features planned,
 b) things that break Clojure 1.0
 c) and maybe removed features?

You could take a look at the Clojure Assembla space at
http://www.assembla.com/spaces/dashboard/index/clojure/

It has milestones and wikipages about several upcoming changes

 Thanks
 Michael

--
Jarkko
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



  1   2   >