Re: macro expansion time

2009-04-20 Thread Konrad Hinsen

On 21.04.2009, at 00:26, Mark Volkmann wrote:

> Is it correct to say that macros are expanded at read-time?

No. Only reader macros are expanded at read time, standard macros are  
expanded at compile time.

A more subtle point concerns the distinction between compile time and  
run time, because it doesn't really exist, although the distinction  
is still a useful approximation. Compilation happens when a form  
defining a function is evaluated, but other evaluations happen as  
well. Instead of "compile time", I'd say "namespace evaluation time",  
and instead of "run time", I'd say "program evaluation time" or  
something like that.

Example:

(let [x (* 2 3)]
   (defn foo [y] (+ x y)))

After the file containing this piece of code has been read, and thus  
transformed into a list of lists and vectors, it is evaluated. The  
first subexpression to be evaluated is (* 2 3), whose result is bound  
to x. Then the macro form (defn ...) is expanded, resulting in

(def foo (fn [y] (+ x y)))

(fn ...) is a special form (well, not quite, there is another of  
macro but I'll skip that) whose evaluation causes the function to be  
compiled. The result, a "compiled function" object, becomes the value  
of the var foo.

Note that a macro definition like defn is a function, defined in the  
namespace clojure.core which has been evaluated already. Note also  
that the function that defines the defn macro calls other functions,  
such as cons, conj, first, next, etc., for which the evaluation of  
the example code is "run time".

In summary, there are really only two phases in the preparation of a  
namespace, "read time" and "evaluation time".  Macros are called as  
part of the evaluation process. Compilation is really an  
implementation detail in all that. LIke other Lisps, Clojure could be  
implemented as a pure interpreter, a pure compiler, or a mixture of  
the two. It happens to be a pure compiler (even the (* 2 3) in the  
example above is compiled, then executed, and the compiled expression  
is discarded), but you don't need to know that to understand what the  
result of the evaluation is.


--~--~-~--~~~---~--~~
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
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 shutdown only some agents that were sent-off?

2009-04-20 Thread Timothy Pratley

I suppose you could always just use plain old java threads and avoid
the thread-pool, or futures which have the advantage of being cancel-
able?


On Apr 21, 11:57 am, billh04  wrote:
> In my application, I can open several windows. Each window is an
> independent unit and will send-off three agents to do background work.
> When I close a window, I stop the three threads from running, but the
> thread count never goes down when I display it by (println "Thread
> count is" (Thread/activeCount)).
>
> The thread count is always increasing. When I open a new window, the
> thread count goes up by 3 as expected. But, when I close that window
> and open another window, the thread count was not diminished by the
> closing. If I open seveal windows in a row and then close them and
> open one more window, the thread count does not go up. But, if I open
> several more windows and reach the max thread count that I was at
> before, the thread count starts to go up again and will never go below
> that count again.
>
> I think I read that the threads are being retained to be used again
> when needed. So, I am not surprised at this behaviour.
>
> But, to prevent this increasing retention of threads, is there some
> way to release the three threads that I started when the window
> opened? For example, it would be nice to have a function like
> (shutdown agent1 agent2 agent3).
--~--~-~--~~~---~--~~
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
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: shortcut for for comprehension

2009-04-20 Thread Christopher Taylor


On 21.04.2009, at 00:19, Michael Hunger wrote:

>
> Is it possible to use :while to shortcut a for macro when a certain  
> number of yiels have happened?
>
> e.g. (for [x (range 1000) :when (= (rem x) 1) :while (number of  
> yields <= 10)]
>
> so i want only the first 10 results.

you could:
(def zip (partial map vector))

and then use:

user> (for [[i x] (zip (iterate inc 0) (range 10 -10 -1))
 :while (< i 5)]
x)
(10 9 8 7 6)

> Or should I just use (take 10 ) on the for ?

that's probably more readable and works just as well ;).

hth,
   --Chris


--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



priority queue: some results

2009-04-20 Thread e
I've done a little comparing to sorted-set as recommended.  The following
test (in case there is anything bogus about it) is checked in with the java
project:
http://code.google.com/p/jc-pheap/source/browse/trunk/jc-pheap/src/persistent_heap/testing/test.clj?spec=svn8&r=8

deduping 2,000,000 nums
shuffling  1999019  nums
=
inserting into sorted set
"Elapsed time: 39375.887 msecs"

popping from front of sorted set
"Elapsed time: 15189.0 msecs"
=
heap insert
"Elapsed time: 15101.546 msecs"
--
heap pop
"Elapsed time: 59715.796 msecs"
=

What I am finding consistently (again, unless the test is bogus) is pretty
much expected.  *Overall* the excellently implemented sorted-set outperforms
the heap I'm working on if you add the all the "insert" times to all the the
"pop-front" times.

That said, if you want fast inserts, and you're not even sure yet if people
want all the elements in sorted order, the heap has advantages ...
especially if you're not even planning on referencing elements in the middle
of the list (something I do hope to support in some fashion eventually,
note).  It may also be the case that some smart java/algorithm people could
find opportunities to speed up my deleteMin().*

a note on deduping:*

One difference that doesn't seem to matter performance-wise much is that
sorted-set elements are unique.  I'm not sure if clojure currently has a
data structure (other than considering the heap) that works like a sorted
multimap or sorted multiset.  Would it be the same to sort a vector in
between inserts?  That doesn't sound fast, but maybe I should have done that
test, too.

So, anyway, for this test, I inserted unique elements into both structures
so one wouldn't have way more than the other when comparing things like
popping.  I also sampled from a wide range of numbers, so I probably didn't
have to go to such lengths, as it turns out.

--~--~-~--~~~---~--~~
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
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: StackOverflowError Question

2009-04-20 Thread Dimiter "malkia" Stanev

I blindly tried printing out stuff from matrixMultiply, and found out
that if I print matrixA and matrixB it doesn't run out of stack, so I
guess I was "forcing" them to "work", here is a version with (dorun)
that has the same side effect, without printing:

(defn matrixMultiply [matrixA matrixB]
  (dorun matrixA)
  (dorun matrixB)
  (map
   (fn [row]
 (apply map
(fn [& column]
  (apply + (map * row column)))
matrixB))
   matrixA))

user> (main 10)
((0.5 5.5))
user> (main 100)
((0.5 50.5))
user> (time (main 100))
"Elapsed time: 8314.617 msecs"
((0.5 50.5))
user> (time (main 1000))
; Evaluation aborted. ;; Actually not stack overflow, but HEAP
overflow (it took a while though)
user>

Thanks,
Dimiter "malkia" Stanev.

On Apr 20, 10:01 pm, jleehurt  wrote:
> Hi David,
>
> Those two are not recursive, but they call into other functions that
> are. Do I need to make sure that all recursive functions use the loop/
> recur pattern? Or should I not nest recursive calls like this?
>
> Here is the whole source:
>
> ;; Neuron Activation Functions
>
> ;threshold
> (defn threshold [x] (if (>= x 0) 1 0))
>
> ;signum (threshold)
> (defn signum [x] (cond (> x 0) 1 (= x 0) 0 (< x 0) -1))
>
> ;; Matrix Functions
>
> (defn transpose [matrix]
>   (if (not (nil? matrix))
>       (apply map list matrix)))
>
> (defn transpose2 [matrix]
>   (apply map (fn [& column] column) matrix))
>
> (defn matrixMultiply [matrixA matrixB]
>   (map
>     (fn [row] (apply map (fn [& column] (apply + (map * row column)))
> matrixB))
>     matrixA))
>
> (defn matrixAdd [matrixA matrixB]
>   (if (and (not (empty? matrixA)) (not (empty? matrixB)))
>       (conj
>         (matrixAdd (rest matrixA) (rest matrixB))
>         (map + (first matrixA) (first matrixB)
>
> (defn matrixMultiplyScalar [matrixA scalar]
>   (if (not (empty? matrixA))
>       (conj
>         (matrixMultiplyScalar (rest matrixA) scalar)
>         (map (fn [arg] (* arg scalar)) (first matrixA)
>
> ;; Vector Functions
>
> (defn transposeVector [v]
>   (if (not (nil? v))
>       (transpose (vector v
>
> (defn vectorMultiplyScalar [v scalar]
>   (map * v (cycle [ scalar ])))
>
> ;; Binary Logic Input/Output
>
> (def infiniteInputCollection (cycle [[[-1 -1]] [[-1 1]] [[1 -1]] [[1
> 1]]]))
> (def infiniteAndOutputCollection (cycle [-1 -1 -1 1]))
>
> (defn buildInputs [numberOfInputs]
>   (loop [inputVector []
>          binaryInputCollection infiniteInputCollection
>          remainingCount numberOfInputs]
>         (if (> 0 remainingCount)
>             inputVector
>             (recur
>               (conj inputVector (first binaryInputCollection)) (rest
> binaryInputCollection) (dec remainingCount)
>
> (defn buildOutputs [numberOfOutputs outputCollection]
>   (loop [outputVector []
>          andOutputCollection outputCollection
>          remainingCount numberOfOutputs]
>         (if (> 0 remainingCount)
>             outputVector
>             (recur (conj outputVector (first andOutputCollection))
> (rest andOutputCollection) (dec remainingCount)
>
> ;; Main
>
> ;learning rate parameter eta
> (def learningRateParameter 0.5)
>
> ;the weight vector of the perceptron
> (def weightVector (ref nil))
>
> ;multiply the transpose of the weight vector with the input vector
> ;apply the signum function to the scalar result
> (defn computeActualResponse [signumFunction weights inputs]
>   (if (and (not (nil? weights)) (not (nil? inputs)))
>       (signumFunction (first (first (matrixMultiply (transpose
> weights) inputs))
>
> ;return an updated weight vector of the perceptron
> (defn getAdaptedWeightVector [weights inputs desiredResponse
> actualResponse]
>   (let [etaDeltaDesiredActual (* learningRateParameter (-
> desiredResponse actualResponse))]
>        (matrixAdd weights (matrixMultiplyScalar inputs
> etaDeltaDesiredActual
>
> ;train the perceptron with the inputs and corresponding known outputs
> (defn trainPerceptron [beginningWeightVector allInputs allOutputs]
>   (loop [weightVector beginningWeightVector
>          inputs allInputs
>          responses allOutputs]
>         (if (and (not (empty? inputs)) (not (empty? responses)))
>             (let [adaptedWeightVector
>                   (getAdaptedWeightVector
>                     weightVector
>                     (first inputs)
>                     (first responses)
>                     (computeActualResponse signum weightVector (first
> inputs)))]
>                  (recur adaptedWeightVector (rest inputs) (rest
> responses)))
>             weightVector)))
>
> (defn main [sizeOfDataSet]
>   (let [weights [[0 0]]
>         inputs (buildInputs sizeOfDataSet)
>         outputs (buildOutputs sizeOfDataSet
> infiniteAndOutputCollection)]
>        (trainPerceptron weights inputs outputs)))
>
> On Apr 20, 6:32 am, David Nolen  wrote:> You have two 
> other function calls
> > getAdaptedWeightVector
> > computeActualResponse
>
> > Are the

Re: Oracle and Clojure

2009-04-20 Thread Adrian Cuthbertson

There are some precedents - the acquisition of SleepyCat (berkeley db,
et al) - still readily available under GPL compatible licenses.

On Tue, Apr 21, 2009 at 7:47 AM, AlamedaMike  wrote:
>
>>> I can see a lot of technologies that drive the open source world, and this 
>>> group, being compromised
>
> Nothing's going to happen, for the simple reason that the cost to
> Oracle's reputation would far outweigh anything they might gain from
> charging for open-source products. The ultimate effect would be to
> simply route around any attempt to close the sources or to restrict
> changes.
>
> Oracle didn't become the world's third largest software company by
> being stupid.
> >
>

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread AlamedaMike

>> I can see a lot of technologies that drive the open source world, and this 
>> group, being compromised

Nothing's going to happen, for the simple reason that the cost to
Oracle's reputation would far outweigh anything they might gain from
charging for open-source products. The ultimate effect would be to
simply route around any attempt to close the sources or to restrict
changes.

Oracle didn't become the world's third largest software company by
being stupid.
--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Laurent PETIT

Daniel,

I have not followed maven2 concerning this "qualifier" thing.

Would it be corrrect to say that, to further extend you examples, one
the qualifiers could be "slim", since clojure ant already has such a
target.

Or would a "slim" jar of clojure have to had another artifactId ? (I
don't think so, but I ask to be certain of that)

Thanks,

-- 
Laurent

2009/4/21 Daniel Jomphe :
>
> Rich Hickey wrote:
>> I'm unfamiliar with the POM version coordinate system - any hints?
>
> Maven takes the version as whatever-formatted string, but recognizes a
> conventional (.endsWith "1.0.0-SNAPSHOT" "-SNAPSHOT"), like described
> by Laurent PETIT. So "whatever-SNAPSHOT" means we're going someday to
> release version "whatever", and this is our most recent snapshot of
> its edge development.
>
> But that's not all that has been mentioned in this thread re: maven
> conventions.
>
> A release is uniquely identified by a few attributes:
>
>  groupId:artifactId:packaging:classifier:version
>
> The classifier part has alson been mentioned. From maven's doc:
>
> ---
> "The classifier allows to distinguish artifacts that were built from
> the same POM but differ in their content. It is some optional and
> arbitrary string that - if present - is appended to the artifact name
> just after the version number.
>
> As a motivation for this element, consider for example a project that
> offers an artifact targeting JRE 1.5 but at the same time also an
> artifact that still supports JRE 1.4. The first artifact could be
> equipped with the classifier jdk15 and the second one with jdk14 such
> that clients can choose which one to use.
>
> Another common use case for classifiers is the need to attach
> secondary artifacts to the project's main artifact. If you browse the
> Maven central repository, you will notice that the classifiers sources
> and javadoc are used to deploy the project source code and API docs
> along with the packaged class files."
> ---
>
> Lots of java libraries are distributed thusly:
>
> (1)  org.clojure:clojure:jar:1.0.0 (no classifier)
> (2)  org.clojure:clojure:jar:javadoc:1.0.0
> (3)  org.clojure:clojure:jar:sources:1.0.0
>
> So 1 is bytecode release; 2 is only javadoc; 3 is full sources w/o
> bytecode.
> Of course, javadoc is also included in the "sources" release (3).
>
> Hope this answered your question, and more, if needed.
> >
>

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Clojure Library

2009-04-20 Thread Brian Doyle
I posted this a couple of weeks ago and haven't seen it updated on the
clojure
website.  Maybe it got lost in the shuffle.


Name: clj-web-crawler
URL: http://github.com/heyZeus/clj-web-crawler/tree/master
Author: Brian Doyle
Categories: Web, Automation
License: MIT
Dependencies: clojure, clojure-contrib, Apache commons-client 3.1
Description:
clj-web-crawler is a wrapper around the Apache commons-client Java
library that allows you to easily crawl the web in a functional way.

--~--~-~--~~~---~--~~
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
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: StackOverflowError Question

2009-04-20 Thread jleehurt

Hi David,

Those two are not recursive, but they call into other functions that
are. Do I need to make sure that all recursive functions use the loop/
recur pattern? Or should I not nest recursive calls like this?

Here is the whole source:

;; Neuron Activation Functions

;threshold
(defn threshold [x] (if (>= x 0) 1 0))

;signum (threshold)
(defn signum [x] (cond (> x 0) 1 (= x 0) 0 (< x 0) -1))

;; Matrix Functions

(defn transpose [matrix]
  (if (not (nil? matrix))
  (apply map list matrix)))

(defn transpose2 [matrix]
  (apply map (fn [& column] column) matrix))

(defn matrixMultiply [matrixA matrixB]
  (map
(fn [row] (apply map (fn [& column] (apply + (map * row column)))
matrixB))
matrixA))

(defn matrixAdd [matrixA matrixB]
  (if (and (not (empty? matrixA)) (not (empty? matrixB)))
  (conj
(matrixAdd (rest matrixA) (rest matrixB))
(map + (first matrixA) (first matrixB)

(defn matrixMultiplyScalar [matrixA scalar]
  (if (not (empty? matrixA))
  (conj
(matrixMultiplyScalar (rest matrixA) scalar)
(map (fn [arg] (* arg scalar)) (first matrixA)

;; Vector Functions

(defn transposeVector [v]
  (if (not (nil? v))
  (transpose (vector v

(defn vectorMultiplyScalar [v scalar]
  (map * v (cycle [ scalar ])))

;; Binary Logic Input/Output

(def infiniteInputCollection (cycle [[[-1 -1]] [[-1 1]] [[1 -1]] [[1
1]]]))
(def infiniteAndOutputCollection (cycle [-1 -1 -1 1]))

(defn buildInputs [numberOfInputs]
  (loop [inputVector []
 binaryInputCollection infiniteInputCollection
 remainingCount numberOfInputs]
(if (> 0 remainingCount)
inputVector
(recur
  (conj inputVector (first binaryInputCollection)) (rest
binaryInputCollection) (dec remainingCount)

(defn buildOutputs [numberOfOutputs outputCollection]
  (loop [outputVector []
 andOutputCollection outputCollection
 remainingCount numberOfOutputs]
(if (> 0 remainingCount)
outputVector
(recur (conj outputVector (first andOutputCollection))
(rest andOutputCollection) (dec remainingCount)

;; Main

;learning rate parameter eta
(def learningRateParameter 0.5)

;the weight vector of the perceptron
(def weightVector (ref nil))

;multiply the transpose of the weight vector with the input vector
;apply the signum function to the scalar result
(defn computeActualResponse [signumFunction weights inputs]
  (if (and (not (nil? weights)) (not (nil? inputs)))
  (signumFunction (first (first (matrixMultiply (transpose
weights) inputs))

;return an updated weight vector of the perceptron
(defn getAdaptedWeightVector [weights inputs desiredResponse
actualResponse]
  (let [etaDeltaDesiredActual (* learningRateParameter (-
desiredResponse actualResponse))]
   (matrixAdd weights (matrixMultiplyScalar inputs
etaDeltaDesiredActual

;train the perceptron with the inputs and corresponding known outputs
(defn trainPerceptron [beginningWeightVector allInputs allOutputs]
  (loop [weightVector beginningWeightVector
 inputs allInputs
 responses allOutputs]
(if (and (not (empty? inputs)) (not (empty? responses)))
(let [adaptedWeightVector
  (getAdaptedWeightVector
weightVector
(first inputs)
(first responses)
(computeActualResponse signum weightVector (first
inputs)))]
 (recur adaptedWeightVector (rest inputs) (rest
responses)))
weightVector)))

(defn main [sizeOfDataSet]
  (let [weights [[0 0]]
inputs (buildInputs sizeOfDataSet)
outputs (buildOutputs sizeOfDataSet
infiniteAndOutputCollection)]
   (trainPerceptron weights inputs outputs)))


On Apr 20, 6:32 am, David Nolen  wrote:
> You have two other function calls
> getAdaptedWeightVector
> computeActualResponse
>
> Are these recursive as well?
>
> On Sun, Apr 19, 2009 at 11:26 PM, jleehurt  wrote:
>
> > Hi all, I have the following code that trains a perceptron with the
> > given inputs and corresponding desired inputs. For input/output
> > vectors, when the size gets to about 2000, I am getting a
> > java.lang.StackOverflowError in the following function:
>
> > (defn trainPerceptron [beginningWeightVector allInputs allOutputs]
> >  (loop [weightVector beginningWeightVector
> >         inputs allInputs
> >         responses allOutputs]
> >        (if (and (not (empty? inputs)) (not (empty? responses)))
> >            (let [adaptedWeightVector
> >                  (getAdaptedWeightVector
> >                    weightVector
> >                    (first inputs)
> >                    (first responses)
> >                    (computeActualResponse signum weightVector (first
> > inputs)))]
> >                 (recur adaptedWeightVector (rest inputs) (rest
> > responses)))
> >            weightVector)))
>
> > Is not the purpose of loop/recur to avoid stack overflow prob

Re: StackOverflowError Question

2009-04-20 Thread jleehurt

Hi David,

Those two are not recursive, but they call into other recursive
functions. Do I need to make sure all recursive functions use the loop/
recur pattern? Or maybe not nest recursive calls like this?

Here is the whole source:

;threshold
(defn threshold [x] (if (>= x 0) 1 0))

;signum (threshold)
(defn signum [x] (cond (> x 0) 1 (= x 0) 0 (< x 0) -1))

;piecewise linear
(defn piecewise [x] (cond (>= x 0.5) 1 (and (> x -0.5) (< x 0.5)) x
(<= x -0.5) 0))

;logistic (sigmoidal)
(defn sigmoid [x slopeParameter] (/ 1 (+ 1 (Math/exp (* -1 (* x
slopeParameter))

;hyberbolic tangent (sigmoidal)
(defn hyperbolicTangent [x] (Math/tanh x))

;arctangent (sigmoidal)
(defn arcTangent [x] (Math/atan x))

;gompertz curve (sigmoidal)
; a is the upper asymptote
; c is the growth rate
; b, c are negative numbers
(defn gompertzCurve [x a b c] (* a (Math/pow Math/E (* b (Math/pow
Math/E (* c x))

;algebraic sigmoid
(defn algebraicSigmoid [x] (/ x (Math/sqrt (+ 1 (Math/pow x 2)

;; Matrix Functions

(defn transpose [matrix]
  (if (not (nil? matrix))
  (apply map list matrix)))

(defn transpose2 [matrix]
  (apply map (fn [& column] column) matrix))

(defn matrixMultiply [matrixA matrixB]
  (map
(fn [row] (apply map (fn [& column] (apply + (map * row column)))
matrixB))
matrixA))

(defn matrixAdd [matrixA matrixB]
  (if (and (not (empty? matrixA)) (not (empty? matrixB)))
  (conj
(matrixAdd (rest matrixA) (rest matrixB))
(map + (first matrixA) (first matrixB)

(defn matrixMultiplyScalar [matrixA scalar]
  (if (not (empty? matrixA))
  (conj
(matrixMultiplyScalar (rest matrixA) scalar)
(map (fn [arg] (* arg scalar)) (first matrixA)

;; Vector Functions

(defn transposeVector [v]
  (if (not (nil? v))
  (transpose (vector v

(defn vectorMultiplyScalar [v scalar]
  (map * v (cycle [ scalar ])))

;; Binary Logic Input/Output

(def infiniteInputCollection (cycle [[[-1 -1]] [[-1 1]] [[1 -1]] [[1
1]]]))
(def infiniteAndOutputCollection (cycle [-1 -1 -1 1]))

(defn buildInputs [numberOfInputs]
  (loop [inputVector []
 binaryInputCollection infiniteInputCollection
 remainingCount numberOfInputs]
(if (> 0 remainingCount)
inputVector
(recur
  (conj inputVector (first binaryInputCollection)) (rest
binaryInputCollection) (dec remainingCount)

(defn buildOutputs [numberOfOutputs outputCollection]
  (loop [outputVector []
 andOutputCollection outputCollection
 remainingCount numberOfOutputs]
(if (> 0 remainingCount)
outputVector
(recur (conj outputVector (first andOutputCollection))
(rest andOutputCollection) (dec remainingCount)

;; Main

;learning rate parameter eta
(def learningRateParameter 0.5)

;the weight vector of the perceptron
(def weightVector (ref nil))

;multiply the transpose of the weight vector with the input vector
;apply the signum function to the scalar result
(defn computeActualResponse [signumFunction weights inputs]
  (if (and (not (nil? weights)) (not (nil? inputs)))
  ;;TODO create a function that will apply first to a collection
until the inner item is obtained
  (signumFunction (first (first (matrixMultiply (transpose
weights) inputs))

(defn computeActualResponse2 [signumFunction weights inputs]
  ;;(if (and (not (nil? weights)) (not (nil? inputs)))
  ;;(signumFunction (first (first (matrixMultiply (transpose
weights) inputs))
  4)

;return an updated weight vector of the perceptron
(defn getAdaptedWeightVector [weights inputs desiredResponse
actualResponse]
  (let [etaDeltaDesiredActual (* learningRateParameter (-
desiredResponse actualResponse))]
   (matrixAdd weights (matrixMultiplyScalar inputs
etaDeltaDesiredActual
   ;;(dosync (ref-set weightVector newWeights

(defn getAdaptedWeightVector2 [weights inputs desiredResponse
actualResponse]
  (let [etaDeltaDesiredActual (* learningRateParameter (-
desiredResponse actualResponse))
scaledResponses (matrixMultiplyScalar inputs
etaDeltaDesiredActual)]
(matrixAdd weights [[0 0]])))

;train the perceptron with the inputs and corresponding known outputs
(defn trainPerceptron [beginningWeightVector allInputs allOutputs]
  (loop [weightVector beginningWeightVector
 inputs allInputs
 responses allOutputs]
(if (and (not (empty? inputs)) (not (empty? responses)))
(let [adaptedWeightVector
  (getAdaptedWeightVector
weightVector
(first inputs)
(first responses)
(computeActualResponse signum weightVector (first
inputs)))]
 (recur adaptedWeightVector (rest inputs) (rest
responses)))
weightVector)))

(defn trainPerceptron2 [beginningWeightVector allInputs allOutputs]
  (loop [inputs allInputs
 responses allOutputs]
(if (or (empty? inputs) (empty? responses))
  

ICFP 2009

2009-04-20 Thread Andrew Wagner
It would be fun to have a team of clojure programmers work on the ICFP '09
contest. Has this been done previously? Anybody interested? I'm new to
clojure and to lisps in general, but have a pretty good grasp of functional
programming (mostly from haskell). It would be great fun to work with some
more experienced clojure developers. Here's a sample of a previous task,
from 2008: http://smlnj.org/icfp08-contest/task.html

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Bradbev

On Apr 20, 2:17 pm, Mark Engelberg  wrote:
> On Mon, Apr 20, 2009 at 1:27 PM, Bradbev  wrote:
> > If you promise that
> > functions will accept and return maps with certain keys, then you must
> > keep that promise moving forward.
>
> I think you're missing part of the point of the original post.  You
> don't really want to promise that your functions accept and return
> maps with certain keys; you want to promise that your functions accept
> and return objects that *act* like maps with certain keys.  Promising
> a map is too specific.  You merely want to promise something that
> behaves like a map.  Of course, the simplest thing that acts like a
> map is a map, so in early stages of development, you're certainly
> going to use maps.  But does such a thing scale when you decide you
> need something more complex?
Yes, and I'd say that anything that acts exactly like a map
(immutable, constant time lookup, etc) is fine to stand in place of
Clojure's map.  However, I still think that the keys in those maps and
their expected values are part of the public API.  Having a special
map that can fake having certain keys is fine, but perhaps not the way
I'd do it.
If I were to write a public library I would carefully minimize the
information that travels out of my API by not actually exposing the
internal maps.  Initially, that could be as simple as taking an
internal representation & removing non-public keys from it - I am a
big fan of having very small public APIs, & just handing out internal
structures is not a good idea.  Later on when I radically change my
internal data structures my conversion functions might get a little
more complex.
In the case of splitting a single :name into :first-name :second name,
I would need to create a function like
(defn convert-record-v1->v2 [v1-record]
  (let [[first-name last-name] (split-single-name (:name v1-record))
(dissoc (assoc v1-record :first-name first-name :last-name last-
name) :name)))

For every API v1 function that I am preserving I convert my input maps
to the new internal form.  For every outgoing API v1 function I need
to do the reverse.

There may be performance implications for doing this conversion, but
that is a choice the client needs to make - do they stick with v1
features, or go to v2 & try to use the backward compatibility layer.

Of course, clients of the library can probably quite easily hook your
internal maps if they really want to, but at that stage they are on
their own & should not expect to work with new versions of the
library.

>
> In the original example, the data has grown from a map that actually
> contains a :name to something that retrieves a :name indirectly by
> concatenating :first-name and :last-name.  This is a perfectly
> reasonable example of the way that data representations grow and
> change over time.
It is perfectly reasonable, but it is a little much to expect to be
able to mix and match APIs both internally and externally.  In can
imagine consistency problems even in this simple case.  How do you
handle all three keys (:name, :first-name :last-name) having values
that are inconsistent with each other?
I can imagine that code getting ugly.

Cheers,
Brad

>
> Of course, if you had programmed your entire app with getters and
> setters from the outset, making such a modification is relatively
> straightforward (see footnote *).  But most people aren't going to
> program that way from the outset.  They are going to use maps because
> that's the easiest thing, and that means they will get and set things
> using get, assoc, and the syntactic function-like shortcuts for
> retrieving things from maps.
>
> (Footnote * - Well maybe it's not so easy to convert something that
> uses getters and setters from the outset but still uses a map to hold
> the data.  maps are very "leaky abstractions", and even if you provide
> getters and setters, it's entirely possible that users might
> intentionally or unintentionally use something map-specific, rather
> than adhering to the level of indirection that is needed to make a
> conversion easy.)
>
> But then when you eventually want to alter your data representation,
> then what do you do?  It's certainly possible to make your name
> objects some sort of proxy for the associative interface, function
> interface, and anything else relevant to maps, and special case the
> getting of :name, but that's quite cumbersome.  Is there a simple way
> to do this extension?  Not really, and I think this is a legitimate
> concern.
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



How to shutdown only some agents that were sent-off?

2009-04-20 Thread billh04

In my application, I can open several windows. Each window is an
independent unit and will send-off three agents to do background work.
When I close a window, I stop the three threads from running, but the
thread count never goes down when I display it by (println "Thread
count is" (Thread/activeCount)).

The thread count is always increasing. When I open a new window, the
thread count goes up by 3 as expected. But, when I close that window
and open another window, the thread count was not diminished by the
closing. If I open seveal windows in a row and then close them and
open one more window, the thread count does not go up. But, if I open
several more windows and reach the max thread count that I was at
before, the thread count starts to go up again and will never go below
that count again.

I think I read that the threads are being retained to be used again
when needed. So, I am not surprised at this behaviour.

But, to prevent this increasing retention of threads, is there some
way to release the three threads that I started when the window
opened? For example, it would be nice to have a function like
(shutdown agent1 agent2 agent3).
--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Mark Derricutt

For a 1.0 release I'd love to see some support for JDK annotations
somehow, at both the gen-class and method level at least.

Mark

On Fri, Apr 17, 2009 at 4:53 AM, Rich Hickey  wrote:

> This is mostly about - does it work? Is it relatively free of bugs? Is
> it free of gaping holes in core functionality? I think Clojure is in a

--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Daniel Jomphe

Rich Hickey wrote:
> I'm unfamiliar with the POM version coordinate system - any hints?

Maven takes the version as whatever-formatted string, but recognizes a
conventional (.endsWith "1.0.0-SNAPSHOT" "-SNAPSHOT"), like described
by Laurent PETIT. So "whatever-SNAPSHOT" means we're going someday to
release version "whatever", and this is our most recent snapshot of
its edge development.

But that's not all that has been mentioned in this thread re: maven
conventions.

A release is uniquely identified by a few attributes:

  groupId:artifactId:packaging:classifier:version

The classifier part has alson been mentioned. From maven's doc:

---
"The classifier allows to distinguish artifacts that were built from
the same POM but differ in their content. It is some optional and
arbitrary string that - if present - is appended to the artifact name
just after the version number.

As a motivation for this element, consider for example a project that
offers an artifact targeting JRE 1.5 but at the same time also an
artifact that still supports JRE 1.4. The first artifact could be
equipped with the classifier jdk15 and the second one with jdk14 such
that clients can choose which one to use.

Another common use case for classifiers is the need to attach
secondary artifacts to the project's main artifact. If you browse the
Maven central repository, you will notice that the classifiers sources
and javadoc are used to deploy the project source code and API docs
along with the packaged class files."
---

Lots of java libraries are distributed thusly:

(1)  org.clojure:clojure:jar:1.0.0 (no classifier)
(2)  org.clojure:clojure:jar:javadoc:1.0.0
(3)  org.clojure:clojure:jar:sources:1.0.0

So 1 is bytecode release; 2 is only javadoc; 3 is full sources w/o
bytecode.
Of course, javadoc is also included in the "sources" release (3).

Hope this answered your question, and more, if needed.
--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Antony Blakey


On 21/04/2009, at 10:51 AM, Antony Blakey wrote:

> On 21/04/2009, at 10:22 AM, Rich Hickey wrote:
>
>> I'm unfamiliar with the POM version coordinate system - any hints?
>
> My comment was in support of Laurent's proposal. I'm a relative  
> maven newb, but this is my take:
>
> POMs use the concept of a coordinate, which is  
> ::: to identify a  
> particular artifact e.g. library. GroupId + Artifact Id is a  
> qualified name - think java package name. Packaging specifies how  
> the artifact is packaged e.g. jar or war, but it doesn't contribute  
> the id of the project. Version numbers are as you expect, but can be  
> suffixed with '-SNAPSHOT', which effectively creates a distinct  
> subspace of versions ordered by creation date. By depending on a  
> 'a.b.c-SNAPSHOT' version, you get the latest (by date) artifact  
> marked with 'a.b.c-SNAPSHOT'. When you release the artifact you  
> remove the '-SNAPSHOT'. In effect the suffix creates two different  
> versioning spaces, one of which is strictly determined by the  
> hierarchic numeric ordering, and another that allows duplicates  
> ordered by date within a specific hierarchically ordered version.  
> AFAIK, an 'a.b.c-SNAPSHOT' version will not satisfy a request for  
> 'a.b.c' e.g. -SNAPSHOT is not a further qualifier.

This BTW presumes a fairly simplistic dependency selection mechanism.  
In a previous life I did a lot of work with dependency algebras, and a  
far more powerful solution for managing configuration is to allow  
artifacts to be annotated with multidimensional versioning attributes  
organized by feature, using an ordered unification based configuration  
resolution mechanism. Somewhat like versioned requires/provides but  
with richer semantics.

My experience was such systems are too complicated for mass  
deployment, and their use needs to be motivated by a significant  
configuration management requirement, which is why I suggest sticking  
to the far simpler maven/ivy POM model.

Antony Blakey
-
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787

All that is required for evil to triumph is that good men do nothing.



--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Antony Blakey


On 21/04/2009, at 10:22 AM, Rich Hickey wrote:

> I'm unfamiliar with the POM version coordinate system - any hints?

My comment was in support of Laurent's proposal. I'm a relative maven  
newb, but this is my take:

POMs use the concept of a coordinate, which is  
::: to identify a particular  
artifact e.g. library. GroupId + Artifact Id is a qualified name -  
think java package name. Packaging specifies how the artifact is  
packaged e.g. jar or war, but it doesn't contribute the id of the  
project. Version numbers are as you expect, but can be suffixed with '- 
SNAPSHOT', which effectively creates a distinct subspace of versions  
ordered by creation date. By depending on a 'a.b.c-SNAPSHOT' version,  
you get the latest (by date) artifact marked with 'a.b.c-SNAPSHOT'.  
When you release the artifact you remove the '-SNAPSHOT'. In effect  
the suffix creates two different versioning spaces, one of which is  
strictly determined by the hierarchic numeric ordering, and another  
that allows duplicates ordered by date within a specific  
hierarchically ordered version. AFAIK, an 'a.b.c-SNAPSHOT' version  
will not satisfy a request for 'a.b.c' e.g. -SNAPSHOT is not a further  
qualifier.

Antony Blakey
--
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787

The project was so plagued by politics and ego that when the engineers  
requested technical oversight, our manager hired a psychologist instead.
   -- Ron Avitzur


--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Rich Hickey


On Apr 20, 2009, at 7:02 PM, Antony Blakey wrote:

>
>
> On 21/04/2009, at 5:12 AM, Laurent PETIT wrote:
>
>> To give you more ideas, there is a convention in tools like maven/ivy
>> that when you're starting the hack on a branch targeting some version
>> M.m.r , you immediately rename the place in code where you maintain
>> the version number by appending the -SNAPSHOT keyword.
>> So every build that does not remove this -SNAPSHOT suffix can not be
>> mistaken with the real release.
>>
>> Note that such tools are not as "structured" as you suggest and just
>> reserve a single field for version numbering.
>>
>> I think it is a good idea to add this :status attribute. It could be
>> used to mark progression towards a fully featured version, as well :
>>
>> { :major 1 :minor 0 :release 0 :status :SNAPSHOT }
>> then
>> { :major 1 :minor 0 :release 0 :status :RC1 }  (release candidate 1)
>> then
>> { :major 1 :minor 0 :release 0 :status :RC2 }  (release candidate 2)
>> etc.
>> and finally
>> { :major 1 :minor 0 :release 0 :status :GA1 } (Global Availibility 1)
>
>
> Given the likelihood that pom's will be used by some people, with
> maven or ivy, it would be good to have some scheme that maps to and
> from the pom version coordinate system in a transparent fashion,
> particularly in relation to this particular feature of that system.
>

I'm unfamiliar with the POM version coordinate system - any hints?

Rich




--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread Dan
On Mon, Apr 20, 2009 at 6:12 PM, Greg Harman  wrote:

>
> > Has anyone here been able to install Clojure on IcedTea?
>
> For what it's worth, I run Clojure on SoyLatte and have never had a
> problem.


I never had any problem on IcedTea.

--~--~-~--~~~---~--~~
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
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: shortcut for for comprehension

2009-04-20 Thread Timothy Pratley

As far as I know the number of yields is not available for testing, so
you have to use take
user=> (take 10 (for [x (range 1000) :when (= (rem x 2) 1)] x))
(1 3 5 7 9 11 13 15 17 19)

On Apr 21, 8:19 am, Michael Hunger  wrote:
> Is it possible to use :while to shortcut a for macro when a certain number of 
> yiels have happened?
>
> e.g. (for [x (range 1000) :when (= (rem x) 1) :while (number of yields <= 10)]
>
> so i want only the first 10 results.
>
> Or should I just use (take 10 ) on the for ?
>
> Michael
--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Daniel Jomphe

Laurent PETIT wrote:
> > I'd suggest calling :release something else, like :revision
> > or :patch.
> I like the term "service" used in Eclipse terminology:
> "the service segment indicates bug fixes"
>
> (The numbering scheme for Eclipse uses major, minor, service and
> qualifier : "the qualifier segment indicates a particular build").

And let's not forget _feu_ Sun's terminology: "update", as in Java 6
update 14, which really means 1.6.14. :)

Now, personally, what sounds the best in my ears is "revision".

There's of course yet more possibilities: 
http://en.wikipedia.org/wiki/Software_versioning
--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread mikel



On Apr 20, 4:17 pm, Mark Engelberg  wrote:
> On Mon, Apr 20, 2009 at 1:27 PM, Bradbev  wrote:
> > If you promise that
> > functions will accept and return maps with certain keys, then you must
> > keep that promise moving forward.
>
> I think you're missing part of the point of the original post.  You
> don't really want to promise that your functions accept and return
> maps with certain keys; you want to promise that your functions accept
> and return objects that *act* like maps with certain keys.  Promising
> a map is too specific.  You merely want to promise something that
> behaves like a map.  Of course, the simplest thing that acts like a
> map is a map, so in early stages of development, you're certainly
> going to use maps.  But does such a thing scale when you decide you
> need something more complex?
>
> In the original example, the data has grown from a map that actually
> contains a :name to something that retrieves a :name indirectly by
> concatenating :first-name and :last-name.  This is a perfectly
> reasonable example of the way that data representations grow and
> change over time.
>
> Of course, if you had programmed your entire app with getters and
> setters from the outset, making such a modification is relatively
> straightforward (see footnote *).  But most people aren't going to
> program that way from the outset.  They are going to use maps because
> that's the easiest thing, and that means they will get and set things
> using get, assoc, and the syntactic function-like shortcuts for
> retrieving things from maps.
>
> (Footnote * - Well maybe it's not so easy to convert something that
> uses getters and setters from the outset but still uses a map to hold
> the data.  maps are very "leaky abstractions", and even if you provide
> getters and setters, it's entirely possible that users might
> intentionally or unintentionally use something map-specific, rather
> than adhering to the level of indirection that is needed to make a
> conversion easy.)
>
> But then when you eventually want to alter your data representation,
> then what do you do?  It's certainly possible to make your name
> objects some sort of proxy for the associative interface, function
> interface, and anything else relevant to maps, and special case the
> getting of :name, but that's quite cumbersome.  Is there a simple way
> to do this extension?  Not really, and I think this is a legitimate
> concern.

This line of reasoning is one of the reasons for getters and setters.
Smalltalk doesn't give you direct access to an object's data layout
except in the methods of the object. Instead of a data layout, it
gives you a protocol.

Clojure's sequence protocol also provides a protocol in lieu of access
to data fields. That's generally a good way to future-proof your data
structures: divide data design into a public part and a private part.
The layout of the data is private; the public part is the protocol,
which, in Clojure, is made of functions. The more of your data you can
define in terms of functions, the less subject it is to breaking when
you discover that it's a good idea to lay something out differently.

Clojure offers an additional convenience for such abstractions in the
form of polymorphic functions (MultiFns). If you define your data type
in terms of polymorphic functions, you can introduce a new data layout
without even removing the old one. You could even modify the old API
functions to convert data to the new layout when it's encountered.

Is it going to be simpler and more natural to work directly with built-
in data types? Sure. But it's a cliche of development in Lisp that you
cons up some arbitrary data structure, then, in the course of working
with it, discover what the natural API and performance characteristics
are for it, then you write the API in terms of functions and change
the data layout to something that works efficiently with those
functions. To a large extent, that process is what Lisp-hacking *is*.


--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Antony Blakey


On 21/04/2009, at 5:12 AM, Laurent PETIT wrote:

> To give you more ideas, there is a convention in tools like maven/ivy
> that when you're starting the hack on a branch targeting some version
> M.m.r , you immediately rename the place in code where you maintain
> the version number by appending the -SNAPSHOT keyword.
> So every build that does not remove this -SNAPSHOT suffix can not be
> mistaken with the real release.
>
> Note that such tools are not as "structured" as you suggest and just
> reserve a single field for version numbering.
>
> I think it is a good idea to add this :status attribute. It could be
> used to mark progression towards a fully featured version, as well :
>
> { :major 1 :minor 0 :release 0 :status :SNAPSHOT }
> then
> { :major 1 :minor 0 :release 0 :status :RC1 }  (release candidate 1)
> then
> { :major 1 :minor 0 :release 0 :status :RC2 }  (release candidate 2)
> etc.
> and finally
> { :major 1 :minor 0 :release 0 :status :GA1 } (Global Availibility 1)


Given the likelihood that pom's will be used by some people, with  
maven or ivy, it would be good to have some scheme that maps to and  
from the pom version coordinate system in a transparent fashion,  
particularly in relation to this particular feature of that system.

Antony Blakey
--
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787

Always have a vision. Why spend your life making other people’s dreams?
  -- Orson Welles (1915-1985)


--~--~-~--~~~---~--~~
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
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: macro expansion time

2009-04-20 Thread Laurent PETIT

But "reader macros" *are* expanded at read-time (as their name
indicates, BTW) :

1:91 user=> (read-string "'quoted-symbol")
(quote quoted-symbol)
1:92 user=>

HTH,

-- 
Laurent

2009/4/21 Laurent PETIT :
> 2009/4/21 Mark Volkmann :
>>
>> I didn't explain my question well enough. Suppose I define a macro
>> with defmacro and have several calls to it in my code. When are those
>> calls expanded to the code inside the macro? Is that at read-time?
>
> Maybe the example I gave (by using the macro 'defn) was not as clear
> as I intended. But really, defn is a regular macro created via
> defmacro, so the point is proven here as with any user defined macro.
>
> HTH,
>
> --
> Laurent
>>
>> On Mon, Apr 20, 2009 at 5:34 PM, Laurent PETIT  
>> wrote:
>>>
>>> Hello,
>>>
>>> Apparently, no:
>>>
>>> 1:85 user=> (macroexpand-1 '(defn hello [] "world"))
>>> (def hello (clojure.core/fn ([] "world")))
>>> 1:86 user=> (read-string "(defn hello [] \"world\")")
>>> (defn hello [] "world")
>>> 1:87 user=>
>>>
>>> read-string did not expand defn.
>>>
>>> I think it's 'eval that expands macros and compiles forms.
>>>
>>> Regards,
>>>
>>> --
>>> Laurent
>>>
>>> 2009/4/21 Mark Volkmann :

 In my Clojure article at http://ociweb.com/mark/clojure/article.html I say:

 "Clojure code is processed in three phases: read-time, compile-time
 and run-time. At read-time the Reader reads source code and converts
 it to a data structure, mostly a list of lists of lists  At
 compile-time this data structure is converted to Java bytecode. At
 run-time the bytecode is executed. Functions are only invoked at
 run-time. Macros are special constructs that look similar to
 functions, but are expanded into new Clojure code at read-time."

 Is it correct to say that macros are expanded at read-time?
>>
>> --
>> 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
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: macro expansion time

2009-04-20 Thread Laurent PETIT

2009/4/21 Mark Volkmann :
>
> I didn't explain my question well enough. Suppose I define a macro
> with defmacro and have several calls to it in my code. When are those
> calls expanded to the code inside the macro? Is that at read-time?

Maybe the example I gave (by using the macro 'defn) was not as clear
as I intended. But really, defn is a regular macro created via
defmacro, so the point is proven here as with any user defined macro.

HTH,

-- 
Laurent
>
> On Mon, Apr 20, 2009 at 5:34 PM, Laurent PETIT  
> wrote:
>>
>> Hello,
>>
>> Apparently, no:
>>
>> 1:85 user=> (macroexpand-1 '(defn hello [] "world"))
>> (def hello (clojure.core/fn ([] "world")))
>> 1:86 user=> (read-string "(defn hello [] \"world\")")
>> (defn hello [] "world")
>> 1:87 user=>
>>
>> read-string did not expand defn.
>>
>> I think it's 'eval that expands macros and compiles forms.
>>
>> Regards,
>>
>> --
>> Laurent
>>
>> 2009/4/21 Mark Volkmann :
>>>
>>> In my Clojure article at http://ociweb.com/mark/clojure/article.html I say:
>>>
>>> "Clojure code is processed in three phases: read-time, compile-time
>>> and run-time. At read-time the Reader reads source code and converts
>>> it to a data structure, mostly a list of lists of lists  At
>>> compile-time this data structure is converted to Java bytecode. At
>>> run-time the bytecode is executed. Functions are only invoked at
>>> run-time. Macros are special constructs that look similar to
>>> functions, but are expanded into new Clojure code at read-time."
>>>
>>> Is it correct to say that macros are expanded at read-time?
>
> --
> 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
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: macro expansion time

2009-04-20 Thread Meikel Brandmeyer

Hi Mark,

Am 21.04.2009 um 00:40 schrieb Mark Volkmann:


I didn't explain my question well enough. Suppose I define a macro
with defmacro and have several calls to it in my code. When are those
calls expanded to the code inside the macro? Is that at read-time?


As Laurent said: No. Macro expansion happens at compile time.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: macro expansion time

2009-04-20 Thread Mark Volkmann

I didn't explain my question well enough. Suppose I define a macro
with defmacro and have several calls to it in my code. When are those
calls expanded to the code inside the macro? Is that at read-time?

On Mon, Apr 20, 2009 at 5:34 PM, Laurent PETIT  wrote:
>
> Hello,
>
> Apparently, no:
>
> 1:85 user=> (macroexpand-1 '(defn hello [] "world"))
> (def hello (clojure.core/fn ([] "world")))
> 1:86 user=> (read-string "(defn hello [] \"world\")")
> (defn hello [] "world")
> 1:87 user=>
>
> read-string did not expand defn.
>
> I think it's 'eval that expands macros and compiles forms.
>
> Regards,
>
> --
> Laurent
>
> 2009/4/21 Mark Volkmann :
>>
>> In my Clojure article at http://ociweb.com/mark/clojure/article.html I say:
>>
>> "Clojure code is processed in three phases: read-time, compile-time
>> and run-time. At read-time the Reader reads source code and converts
>> it to a data structure, mostly a list of lists of lists  At
>> compile-time this data structure is converted to Java bytecode. At
>> run-time the bytecode is executed. Functions are only invoked at
>> run-time. Macros are special constructs that look similar to
>> functions, but are expanded into new Clojure code at read-time."
>>
>> Is it correct to say that macros are expanded at read-time?

-- 
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
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: macro expansion time

2009-04-20 Thread Laurent PETIT

Hello,

Apparently, no:

1:85 user=> (macroexpand-1 '(defn hello [] "world"))
(def hello (clojure.core/fn ([] "world")))
1:86 user=> (read-string "(defn hello [] \"world\")")
(defn hello [] "world")
1:87 user=>

read-string did not expand defn.

I think it's 'eval that expands macros and compiles forms.

Regards,

-- 
Laurent

2009/4/21 Mark Volkmann :
>
> In my Clojure article at http://ociweb.com/mark/clojure/article.html I say:
>
> "Clojure code is processed in three phases: read-time, compile-time
> and run-time. At read-time the Reader reads source code and converts
> it to a data structure, mostly a list of lists of lists  At
> compile-time this data structure is converted to Java bytecode. At
> run-time the bytecode is executed. Functions are only invoked at
> run-time. Macros are special constructs that look similar to
> functions, but are expanded into new Clojure code at read-time."
>
> Is it correct to say that macros are expanded at read-time?
>
> --
> 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
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
-~--~~~~--~~--~--~---



macro expansion time

2009-04-20 Thread Mark Volkmann

In my Clojure article at http://ociweb.com/mark/clojure/article.html I say:

"Clojure code is processed in three phases: read-time, compile-time
and run-time. At read-time the Reader reads source code and converts
it to a data structure, mostly a list of lists of lists  At
compile-time this data structure is converted to Java bytecode. At
run-time the bytecode is executed. Functions are only invoked at
run-time. Macros are special constructs that look similar to
functions, but are expanded into new Clojure code at read-time."

Is it correct to say that macros are expanded at read-time?

-- 
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
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
-~--~~~~--~~--~--~---



shortcut for for comprehension

2009-04-20 Thread Michael Hunger

Is it possible to use :while to shortcut a for macro when a certain number of 
yiels have happened?

e.g. (for [x (range 1000) :when (= (rem x) 1) :while (number of yields <= 10)]

so i want only the first 10 results.

Or should I just use (take 10 ) on the for ?

Michael

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread Greg Harman

> Has anyone here been able to install Clojure on IcedTea?

For what it's worth, I run Clojure on SoyLatte and have never had a
problem.
--~--~-~--~~~---~--~~
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
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 CLASSPATH

2009-04-20 Thread Adam Blinkinsop

On Apr 5, 1:32 pm, dlb  wrote:
> I have the same problem on my Mac as well, i.e. if clojure.jar is
> loaded from ~/Library/Java/Extensions rather than from the classpath,
> then clojure does not find files on the classpath.  I did some poking
> around and on my Mac OS X 10.5.6 with Java 6.
> ...

It seems like this is something that could be easily fixed during the
installation process.  That is, installing Clojure should create a set
of scripts, "clj" and "cljc" that start up the repl (or load a script,
as in the Wiki) and compile Clojure programs, respectively.  The
Clojure jars could be in some central location (say, /usr/lib/clojure
on a standard *nix system), and these scripts would get all the jars &
classes from there into the classpath somehow.

This way, people new to the system could download, do some "make &&
make install" or "ant install" (?) process, and have an immediately
working system with little to no effort.  Does this sound like it
would be desired and/or 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
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 vs 'nth on maps

2009-04-20 Thread Hugh Winkler

On Mon, Apr 20, 2009 at 1:59 PM, David Nolen  wrote:
> Maps aren't ordered so this isn't a good idea anyway.

It's a good idea if you have a sorted map. My example should have used
sorted-map.

> The reason first/second work is because they call seq on the collection.
> (key (nth (seq {:a 1 :b 2 :c 3}) 1)) -> :b
>

Thanks! I think 'nth ought to behave just like 'first and 'second,
don't you? If it's a good idea for 'first it's a good idea for 'nth.


[Apologies to all for the several redundant posts on this topic. I've
been getting rejection messages from Google Groups for no reason].

> On Mon, Apr 20, 2009 at 2:51 PM, hughw  wrote:
>>
>> Hi all,
>>
>> Why should 'first and 'second work on maps, but not 'nth?
>>
>> user> (key (first {:a 1 :b 2 :c 3}))
>> :a
>> user> (key (nth  {:a 1 :b 2 :c 3} 0))
>> ; Evaluation aborted.
>>
>> java.lang.UnsupportedOperationException: nth not supported on this
>> type: PersistentArrayMap (NO_SOURCE_FILE:0)
>>  [Thrown class clojure.lang.Compiler$CompilerException]
>>
>> Thanks,
>> Hugh
>>
>>
>
>
> >
>



-- 
Hugh Winkler, CEO
Wellstorm Development
31900 Ranch Road 12
Suite 206
Dripping Springs, TX 78620
USA
http://www.wellstorm.com/
+1 512 264 3998 x801

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Mark Engelberg

On Mon, Apr 20, 2009 at 1:27 PM, Bradbev  wrote:
> If you promise that
> functions will accept and return maps with certain keys, then you must
> keep that promise moving forward.

I think you're missing part of the point of the original post.  You
don't really want to promise that your functions accept and return
maps with certain keys; you want to promise that your functions accept
and return objects that *act* like maps with certain keys.  Promising
a map is too specific.  You merely want to promise something that
behaves like a map.  Of course, the simplest thing that acts like a
map is a map, so in early stages of development, you're certainly
going to use maps.  But does such a thing scale when you decide you
need something more complex?

In the original example, the data has grown from a map that actually
contains a :name to something that retrieves a :name indirectly by
concatenating :first-name and :last-name.  This is a perfectly
reasonable example of the way that data representations grow and
change over time.

Of course, if you had programmed your entire app with getters and
setters from the outset, making such a modification is relatively
straightforward (see footnote *).  But most people aren't going to
program that way from the outset.  They are going to use maps because
that's the easiest thing, and that means they will get and set things
using get, assoc, and the syntactic function-like shortcuts for
retrieving things from maps.

(Footnote * - Well maybe it's not so easy to convert something that
uses getters and setters from the outset but still uses a map to hold
the data.  maps are very "leaky abstractions", and even if you provide
getters and setters, it's entirely possible that users might
intentionally or unintentionally use something map-specific, rather
than adhering to the level of indirection that is needed to make a
conversion easy.)

But then when you eventually want to alter your data representation,
then what do you do?  It's certainly possible to make your name
objects some sort of proxy for the associative interface, function
interface, and anything else relevant to maps, and special case the
getting of :name, but that's quite cumbersome.  Is there a simple way
to do this extension?  Not really, and I think this is a legitimate
concern.

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Bradbev

I read the rest of this thread, and thought I'd throw in my two cents.
It seems to me that you are mostly concerned with being able to
provide a stable external API to clients while allowing the internal
data structures to change.  As a library designer you need to choose
which parts of your API are going to be stable.  If you promise that
functions will accept and return maps with certain keys, then you must
keep that promise moving forward.  Let's use your example of :name.
API v1 has functions that accept/return maps of the form {:name ...}.
In API v2 you decide that it is better to actually use {:first-name
"" :last-name ""}.  If you wish to keep API v1 compatibility you need
to also provide the :name key.  So even if you wish to change internal
structures, you need to present old structures to the outside world.
At some layer you must be dealing with functions in your API, at this
level you should marshal between the old map keys & the new map keys.
For cases like this you could even merge the maps & allow both APIs at
the same time.

IMHO the situation is not very different from any other API version
problem, you just have to view the keys in a public access map as part
of your API.

Cheers,
Brad

On Apr 19, 8:00 am, Timo Mihaljov  wrote:
> Hi,
>
> I'm wondering about how to change a data structure without breaking the
> API used to access it. For example, let's assume that I have a library
> for dealing with records of people and I'm storing them in structs.
>
>      (defstruct person :name)
>
> The users of my library access the data stored in the records like any
> other map.
>
>      (:name some-person)
>
> When the library's been in use for a while, I realize that I need to
> make a change to the data structure.
>
>      (defstruct :first-name :last-name)
>
> The problem is that making this change would break all the clients using
> the library.
>
> The obvious and traditional solution, at least for someone used to
> thinking in OO terms, would be to tell the clients of the library to
> treat the records as opaque handles, and only use the library's accessor
> functions to access their contents. However, I don't like this approach
> because it leads to a lot of boilerplate code that's there "just in case
> I'll need it some day". It also prevents my clients from using generic
> map manipulation functions on the records.
>
> In Python, my current go-to language, I can have my cake and eat it too
> by using class properties.
>
>      # A struct-like class whose members can be manipulated directly
>      class Person1(object):
>          name = "full name"
>
>      p1 = Person1()
>      print p1.name
>
>      # Like above, but with three members, one of which is calculated by
>      # a function when it is accessed
>      class Person2(object):
>          first_name = "first"
>          last_name = "last"
>
>          def get_name(self):
>              return self.first_name + " " + self.last_name
>          name = property(get_name)
>
>      p2 = Person2()
>      print p2.name   # The old API still works, even though the data is
>                      # stored in a different way
>
> What's the idiomatic Clojure way of dealing with this issue?
>
> --
> Timo
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Wrapper function for slime

2009-04-20 Thread Craig McDaniel

Using something like this run-slime wrapper to start slime may be
useful to others. It helps me avoid some issues when moving from
project to project without restarting emacs. Assuming jar files reside
in each separate project's own "lib" directory, Clojure source in its
"src" directory, and compiled classes in its "classes" directory, run-
slime does the following:

- changes the classpath used by swank-clojure for each project. This
was tricky because simply setting swank-clojure-extra-classpaths and
restarting slime won't do it. The contents of the slime-lisp-
implementations list must be changed.

- makes sure AOT compiling works by creating the "classes" directory
and setting the classpath to include both the src and classes
directories. Even if you specify the "classes" dir in the classpath,
it won't work unless the directory exists in advance of starting
slime.

- also sets the classpath to include all files in the lib
subdirectory. (Note that the lib/* classpath syntax won't work on Java
5.)

(defun reset-swank ()
  "Because changing swank-clojure-extra-classpaths is not enough
to force a new instance of slime to use it."
  (interactive)
  (assq-delete-all 'clojure slime-lisp-implementations)
  (add-to-list 'slime-lisp-implementations
   `(clojure ,(swank-clojure-cmd) :init swank-clojure-
init) t))

(defun run-slime (dir)
  (interactive "DProject directory: ")
  (cd dir)
  (when (not (file-directory-p "classes"))
(make-directory "classes"))
  (setq swank-clojure-extra-classpaths '("src" "classes" "lib/*"))
  (reset-swank)
  (slime))


--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Laurent PETIT

Hi David,

2009/4/20 David Nolen :
> A couple of things. In your initial example, you conflated some things. One
> issue is simply a matter of convenience- defining a getter so that you can
> use Python object property access (via the dot operator). Personally I don't
> like this idiom at all (you find it in Objective-C 2.0 and Javascript).
>  It's simply syntactic sugar that gets converted into another (hidden) form.
>  Then support for getters/setters is very much a "macro"-like trick, they
> will get converted into the standard form somewhere.

I'm not sure if I understand correctly what you're saying here. Are
you talking about this piece of code provided by Timo :

class Person2(object):
first_name = "first"
last_name = "last"

def get_name(self):
return self.first_name + " " + self.last_name
name = property(get_name)

, the get_name function ?

If so, then I think you may be wrong because get_name is not converted
somewhere into boiler plate code. I rather think this is one of the
dynamic strengthes of python being able to intercept calls on the fly.
Different langage, different way of handling problems (no macros
here).

Or is it really just syntactic sugar ?

Maybe I understand what you stated wrong, but I think here the
syntactic sugar not only has the value of saving some characters (not
having to type getName but just name), but also is an implementation
example of what Bertrand Meyer calls "the principle of uniform access"
in his "Object Oriented Software construction" book.


> So all that's
> happening here is that you are saving on typing. The correct answer for this
> is write the syntactic sugar yourself with some macros.
> Data encapsulation is another issue. Functions provide a well-defined
> interface. If the underlying representation is going to change provide a
> function. I would like to point out that in Smalltalk (the OO grandaddy) I
> am pretty sure there is no such thing as property access, you must provide a
> method.

"Property", in the OO world (at least java and C#), is often used to
mean access to a "property" via a function (or not, but the client
does not have to know about). "Attribute" or "Field", in the other
hand, are generally used to refer to implementation specific physical
storage.

As far as I know, Smalltalk does not *at all* provide access to
fields/attributes. So it is quite natural to then have to define
getters :-).

> Data encapsulation in Clojure is far less of an issue than it is with most
> OO languages, as data is immutable anyway. Encapsulation support in a
> language that that don't truly protect instance variables is pretty
> pointless anyway as well as being overrated IMO. For example, JavaScript has
> no such encapsulation, yet large programs can be written/scripted with it
> (FireFox).
> Again if you want the convenience of setters/getters write a macro to save
> you some typing.
>
> On Mon, Apr 20, 2009 at 12:13 PM, Timo Mihaljov  wrote:
>>
>> Matt Clark wrote:
>> > Maybe I'm missing something, but what is wrong with Stuart Sierra's
>> > solution?  I quite like it, and it would probably be more appealing if
>> > it were encapsulated into a macro.
>>
>> Frankly, it seemed like a good answer to the wrong question [1] instead
>> of being a recurring and widely known idiom in the Clojure community.
>> Stuart's disclaimer ("I won't claim this is an elegant solution, but
>> it's similar in spirit to your Python example") left me feeling that his
>> answer was what I asked for, not what I need, if that makes any sense.
>>
>> To put it another way, any answer involving custom support code (new
>> macros or the like) is not the one I'm looking for. Being able to modify
>> the language is very cool, but not being able to solve a simple problem
>> with a language that thousands of people use all the time suggests to me
>> that I'm trying to solve a problem that everyone else sidesteps
>> altogether.
>>
>> Thanks to everyone for your replies. An don't worry, I'll stop with the
>> newbie questions someday :)
>>
>> [1]
>>
>> http://blogs.msdn.com/ericlippert/archive/2009/04/13/restating-the-problem.aspx
>>
>> --
>> Timo
>>
>>
>
>
> >
>

--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Laurent PETIT

2009/4/20 Rich Hickey :

> If there is just a (def *version* {:major 1 :minor 0 :release 0})
>
> my questions are:
>
> What happens after release to keep subsequent interim versions from
> having the same 'version' as a release? Should we have a :status
> attribute that is :release for releases and :interim for non?

To give you more ideas, there is a convention in tools like maven/ivy
that when you're starting the hack on a branch targeting some version
M.m.r , you immediately rename the place in code where you maintain
the version number by appending the -SNAPSHOT keyword.
So every build that does not remove this -SNAPSHOT suffix can not be
mistaken with the real release.

Note that such tools are not as "structured" as you suggest and just
reserve a single field for version numbering.

I think it is a good idea to add this :status attribute. It could be
used to mark progression towards a fully featured version, as well :

{ :major 1 :minor 0 :release 0 :status :SNAPSHOT }
then
{ :major 1 :minor 0 :release 0 :status :RC1 }  (release candidate 1)
then
{ :major 1 :minor 0 :release 0 :status :RC2 }  (release candidate 2)
etc.
and finally
{ :major 1 :minor 0 :release 0 :status :GA1 } (Global Availibility 1)

One thing to be considered, also, would be a :qualifier attribute that
could say : "this is the version packaged with sources", "this is the
slim version", ...).

HTH,

-- 
Laurent

--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Laurent PETIT

2009/4/20 Stuart Sierra 
>
> On Apr 20, 1:48 pm, Rich Hickey  wrote:
> > I imagine a (clojure-version) function returning:
> >
> > {:major 1 :minor 0 :release 0}
>
> I'd suggest calling :release something else, like :revision
> or :patch.  "release" sounds like a bigger number than major/minor.
> Other than that, makes sense to me.

I like the term "service" used in Eclipse terminology:
"the service segment indicates bug fixes"

(The numbering scheme for Eclipse uses major, minor, service and
qualifier : "the qualifier segment indicates a particular build").

(http://wiki.eclipse.org/Version_Numbering#Guidelines_on_versioning_plug-ins)

-- 
Laurent Petit

--~--~-~--~~~---~--~~
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
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: Abstract data types in functional languages

2009-04-20 Thread Konrad Hinsen

On 20.04.2009, at 20:00, Timo Mihaljov wrote:

> Is the concept of Abstract Data Types [1] useful in Clojure?

Yes, although the abstraction is necessarily leaky in that you cannot  
enforce it in the absence of static typing.

> If yes, how would you implement one?

Like in any other language: by implementing an API without making any  
promises about the data structure being used. You can find an example  
in clojure.core.zip, which defines a zipper structure without  
exposing the internal representation in its interface.

Konrad.

--~--~-~--~~~---~--~~
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
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: Abstract data types in functional languages

2009-04-20 Thread David Nolen
Konrad added an early implementation of abstract data types to
clojure-contrib (types.clj) you might want to check that out.
I also did some work on supporting more traditional style OO with Spinoza
(structural+behavioral inheritance), but I've sidelined it for the time
being until I find that I actually need it.

Also Mikel has done some work with generic-functions and models which covers
some of this ground and more.

Search the mailing list for fairly long threads on these subjects ;)

On Mon, Apr 20, 2009 at 2:00 PM, Timo Mihaljov  wrote:

>
> I think Konrad's and David's replies confirm my suspicion that I'm
> trying to find a solution to a problem that one does not encounter in
> Clojure. This makes my example irrelevant and a poor context for the
> discussion, so I'm changing the subject and bombard you with a new set
> of newbie questions.
>
> Is the concept of Abstract Data Types [1] useful in Clojure?
>
> If yes, how would you implement one?
>
> If no, why don't the problems that ADTs are invented to solve occur in
> Clojure?
>
> If "yes or no, it depends", could you give an example of both cases and
> Clojure code to handle them?
>
> [1] http://en.wikipedia.org/wiki/Abstract_data_type
>
> Thanks,
> --
> Timo
>
> >
>

--~--~-~--~~~---~--~~
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
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 vs 'nth on maps

2009-04-20 Thread David Nolen
Maps aren't ordered so this isn't a good idea anyway.
The reason first/second work is because they call seq on the collection.

(key (nth (seq {:a 1 :b 2 :c 3}) 1)) -> :b

On Mon, Apr 20, 2009 at 2:51 PM, hughw  wrote:

>
> Hi all,
>
> Why should 'first and 'second work on maps, but not 'nth?
>
> user> (key (first {:a 1 :b 2 :c 3}))
> :a
> user> (key (nth  {:a 1 :b 2 :c 3} 0))
> ; Evaluation aborted.
>
> java.lang.UnsupportedOperationException: nth not supported on this
> type: PersistentArrayMap (NO_SOURCE_FILE:0)
>  [Thrown class clojure.lang.Compiler$CompilerException]
>
> Thanks,
> Hugh
>
> >
>

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



'first vs 'nth on maps

2009-04-20 Thread hughw

Hi all,

Why should 'first and 'second work on maps, but not 'nth?

user> (key (first {:a 1 :b 2 :c 3}))
:a
user> (key (nth  {:a 1 :b 2 :c 3} 0))
; Evaluation aborted.

java.lang.UnsupportedOperationException: nth not supported on this
type: PersistentArrayMap (NO_SOURCE_FILE:0)
 [Thrown class clojure.lang.Compiler$CompilerException]

Thanks,
Hugh

--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Phil Hagelberg

Stuart Sierra  writes:

> On Apr 20, 1:48 pm, Rich Hickey  wrote:
>> I imagine a (clojure-version) function returning:
>>
>> {:major 1 :minor 0 :release 0}
>
> I'd suggest calling :release something else, like :revision
> or :patch.  "release" sounds like a bigger number than major/minor.
> Other than that, makes sense to me.

The term I've often seen is :bugfix for the least-significant version segment.

-Phil

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Stuart Sierra

On Apr 20, 12:32 pm, Laurent PETIT  wrote:
> I think you Timo ask here a very interesting and important question.
>
> It's not just about having encapsulation or not. It's really about designing
> the code so that the library internals can evolve without impact on the user
> part.

In general, Lisp-derived languages don't try to enforce good
programming.  They assume that programmers are smart.  You're on your
own, even if that means shooting yourself in the foot.

If you know that your library needs to accommodate changing
implementations without breaking the API, then you need to factor that
into your design, by using accessor functions, macros, or some other
technique.

True, you cannot prevent someone from manipulating the implementation
directly.  Bullet, meet foot.  You just have to take it on faith that
your users are smart enough not to do that.  If they're programming in
Lisp, then they probably are.

-Stuart Sierra
--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Stuart Sierra

On Apr 20, 1:48 pm, Rich Hickey  wrote:
> I imagine a (clojure-version) function returning:
>
> {:major 1 :minor 0 :release 0}

I'd suggest calling :release something else, like :revision
or :patch.  "release" sounds like a bigger number than major/minor.
Other than that, makes sense to me.

Maybe a ns flag like :clojure-version could indicate what Clojure
version a lib was developed for.  I'm assuming this will be used only
for information/warning purposes, NOT a hard constraint that prevents
the lib from being loaded on any other version.

-Stuart Sierra
--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Phil Hagelberg

Rich Hickey  writes:

> If there is just a (def *version* {:major 1 :minor 0 :release 0})
>
> my questions are:
>
> What happens after release to keep subsequent interim versions from
> having the same 'version' as a release? Should we have a :status
> attribute that is :release for releases and :interim for non?

I like how that sounds. Either that or having a :prerelease key that
maps to true in interim releases.

Additionally release candidates should have a :release-candidate key if
we end up going down that path.

-Phil

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Abstract data types in functional languages

2009-04-20 Thread Timo Mihaljov

I think Konrad's and David's replies confirm my suspicion that I'm
trying to find a solution to a problem that one does not encounter in
Clojure. This makes my example irrelevant and a poor context for the
discussion, so I'm changing the subject and bombard you with a new set
of newbie questions.

Is the concept of Abstract Data Types [1] useful in Clojure?

If yes, how would you implement one?

If no, why don't the problems that ADTs are invented to solve occur in
Clojure?

If "yes or no, it depends", could you give an example of both cases and
Clojure code to handle them?

[1] http://en.wikipedia.org/wiki/Abstract_data_type

Thanks,
--
Timo

--~--~-~--~~~---~--~~
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
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: The Path to 1.0

2009-04-20 Thread Rich Hickey



On Apr 17, 5:21 pm, Tom Faulhaber  wrote:
> Tom's 2 cents:
>
> I think Clojure is basically ready to go to 1.0. I like the idea of
> having a book about Clojure 1.0 go hand in hand with the release.
>
> While I agree that the library management problem is too hard for a
> 1.0 release (and also largely separable), it would be nice to see the
> software version number (e.g. 1.0.0) and the subversion number (e.g.
> r1352) in the built clojure.jar somewhere that's easily accessible to
> tools that are trying to do library management. My solution to this
> would probably just be to generate a couple of (def *clojure-version-
> number* "1.0.0") things as part of the build. Do any Java/Maven heads
> have more sophisticated ideas that we should consider here? I've just
> started hacking on some svn manipulation stuff (and a little bit of
> jar manipulation) in the process of doing my contrib autodoc robot, so
> I'd be happy to help here too.

I'd like some proposals for doing the version numbers.

I imagine a (clojure-version) function returning:

{:major 1 :minor 0 :release 0}

or something. We've had some prior discussions about how to do the svn
rev with no conclusion - most things seemed incredibly hackish, didn't
work for people building with different tools or from a git mirror
etc.

If there is just a (def *version* {:major 1 :minor 0 :release 0})

my questions are:

What happens after release to keep subsequent interim versions from
having the same 'version' as a release? Should we have a :status
attribute that is :release for releases and :interim for non?

I'd like to move forward on 1.0 with what we have now, and take the
most pressing wish list items raised in this discussion under
consideration for 1.1.

Rich

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread David Nolen
A couple of things. In your initial example, you conflated some things. One
issue is simply a matter of convenience- defining a getter so that you can
use Python object property access (via the dot operator). Personally I don't
like this idiom at all (you find it in Objective-C 2.0 and Javascript).
 It's simply syntactic sugar that gets converted into another (hidden) form.
 Then support for getters/setters is very much a "macro"-like trick, they
will get converted into the standard form somewhere.  So all that's
happening here is that you are saving on typing. The correct answer for this
is write the syntactic sugar yourself with some macros.
Data encapsulation is another issue. Functions provide a well-defined
interface. If the underlying representation is going to change provide a
function. I would like to point out that in Smalltalk (the OO grandaddy) I
am pretty sure there is no such thing as property access, you must provide a
method.

Data encapsulation in Clojure is far less of an issue than it is with most
OO languages, as data is immutable anyway. Encapsulation support in a
language that that don't truly protect instance variables is pretty
pointless anyway as well as being overrated IMO. For example, JavaScript has
no such encapsulation, yet large programs can be written/scripted with it
(FireFox).

Again if you want the convenience of setters/getters write a macro to save
you some typing.

On Mon, Apr 20, 2009 at 12:13 PM, Timo Mihaljov  wrote:

>
> Matt Clark wrote:
> > Maybe I'm missing something, but what is wrong with Stuart Sierra's
> > solution?  I quite like it, and it would probably be more appealing if
> > it were encapsulated into a macro.
>
> Frankly, it seemed like a good answer to the wrong question [1] instead
> of being a recurring and widely known idiom in the Clojure community.
> Stuart's disclaimer ("I won't claim this is an elegant solution, but
> it's similar in spirit to your Python example") left me feeling that his
> answer was what I asked for, not what I need, if that makes any sense.
>
> To put it another way, any answer involving custom support code (new
> macros or the like) is not the one I'm looking for. Being able to modify
> the language is very cool, but not being able to solve a simple problem
> with a language that thousands of people use all the time suggests to me
> that I'm trying to solve a problem that everyone else sidesteps
> altogether.
>
> Thanks to everyone for your replies. An don't worry, I'll stop with the
> newbie questions someday :)
>
> [1]
>
> http://blogs.msdn.com/ericlippert/archive/2009/04/13/restating-the-problem.aspx
>
> --
> Timo
>
> >
>

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread Luc Prefontaine
You can bet that regulatory agencies will look at this deal closely. Not
only in the US and not
only at the deal itself but also how Oracle will behave in the near
future.

Luc

On Mon, 2009-04-20 at 09:09 -0700, Phil Hagelberg wrote:

> Sean Devlin  writes:
> 
> > *Will Java continue to be open source?
> 
> It is simply not possible for this to go away. Future development on
> Java _could_ be released under developer-hostile licenses, but this
> would probably be a good thing if the license were bad enough since it
> would make it obvious that the OpenJDK is the future, and folks with any
> sense would just give up on the official Sun version.
> 
> Probably the worst that could happen is that the license stays the same,
> (meaning a community-driven fork doesn't happen) but the bureaucracy
> around the project increases to the point of stagnation.
> 
> -Phil
> 
> > 
> 

Luc Préfontaine

Armageddon was yesterday, today we have a real problem...

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Konrad Hinsen

On Apr 20, 2009, at 18:13, Timo Mihaljov wrote:

> To put it another way, any answer involving custom support code (new
> macros or the like) is not the one I'm looking for. Being able to  
> modify
> the language is very cool, but not being able to solve a simple  
> problem

Macros are not "modifying the language", they are an essential aspect  
of any language of the Lisp family.

> with a language that thousands of people use all the time suggests  
> to me
> that I'm trying to solve a problem that everyone else sidesteps
> altogether.

Or perhaps a problem that doesn't happen in real life with Clojure,  
for whatever reason, including that the language is perhaps too new.

However, my feeling is that your problem is too hypothetical to have  
an obvious solution. You state your problem in terms suitable for an  
OO language, but Clojure is not really an OO language, even though it  
shares some aspects of OO languages. Clojure adopts a mostly  
functional point of view to programming, so if you want to discuss  
idiomatic Clojure, you should describe your hypothetical application  
in terms of functional abstractions and associated data structures,  
and then describe what problem you ran into. An essential question  
would then be how access to the "name" field of the data structure  
happens in the framework of your functional abstractions, and why  
exactly it needs to be modified to suit a change in requirements.

Konrad.

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Laurent PETIT
I think you Timo ask here a very interesting and important question.

It's not just about having encapsulation or not. It's really about designing
the code so that the library internals can evolve without impact on the user
part.

Given that no "here is the standard clojure way" was called :

 * either it is too early in the day, and the answer will come in a few
hours
 * either it is not neither in core nor contrib, and it could reveal that
not so much clojure users have this need ? ! Maybe clojure is not yet used
in the kind of application where the definition of the datastructures and
hierarchies is used by other teams. But still it seems odd to me, because
even in my own code, I would like to separate different parts for easing
maintenance ?
 * either there is a totally different way of handling the problem, and
indeed, as in the URL you pointed, you (and I will learn something along the
process) have to think about it differently in clojure.

Looking forward to other's insightfull comments on this,

Regards,

-- 
Laurent

2009/4/20 Timo Mihaljov 

>
> Matt Clark wrote:
> > Maybe I'm missing something, but what is wrong with Stuart Sierra's
> > solution?  I quite like it, and it would probably be more appealing if
> > it were encapsulated into a macro.
>
> Frankly, it seemed like a good answer to the wrong question [1] instead
> of being a recurring and widely known idiom in the Clojure community.
> Stuart's disclaimer ("I won't claim this is an elegant solution, but
> it's similar in spirit to your Python example") left me feeling that his
> answer was what I asked for, not what I need, if that makes any sense.
>
> To put it another way, any answer involving custom support code (new
> macros or the like) is not the one I'm looking for. Being able to modify
> the language is very cool, but not being able to solve a simple problem
> with a language that thousands of people use all the time suggests to me
> that I'm trying to solve a problem that everyone else sidesteps
> altogether.
>
> Thanks to everyone for your replies. An don't worry, I'll stop with the
> newbie questions someday :)
>
> [1]
>
> http://blogs.msdn.com/ericlippert/archive/2009/04/13/restating-the-problem.aspx
>
> --
> Timo
>
> >
>

--~--~-~--~~~---~--~~
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
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: ATTN contrib authors: Automatic documentation for clojure.contib

2009-04-20 Thread Tom Faulhaber

Hey Sean,

Thanks for the pointer here. There's a lot of commonality, but mostly
I think the products end up being different for two reasons:

1) For the moment, the contrib-autodoc stuff is targeting the
googlecode wiki, which is a weird and gross thing of its own. I've
been thinking of making some kind of builder syntax for it, but for
the moment I'm just using formats.
2) Most of the work is in dealing with subversion and the like to
check, get, build, etc.

But looking at what the compojure guys are doing is interesting and
educational. I think we have a ways to go in thinking about the amount
of stuff we can do to leverage doc-oriented metadata in Clojure in a
more flexible way.

Tom

On Apr 15, 7:07 am, Sean Devlin  wrote:
> Check out the thread below in the Compojure group.  Specifically, look
> for the comment by Brain Carper
>
> http://groups.google.com/group/compojure/browse_thread/thread/67d92ce...
>
> Brian's code:
>
> http://briancarper.net/clojure/compojure-doc.clj
>
> This might be an alternate approach to the problem.
>
> On Apr 14, 5:59 pm, Tom Faulhaber  wrote:
>
> > Jason,
>
> > Thanks for the offer. I may take you up on it as I get this into
> > "production" such as it is.
>
> > Sean,
>
> > Nothing that I found in contrib (but who knows, there's no
> > documentation :-)). Rich posted some code (which I'm using in a
> > modified version in the center of things) for doing the API paage for
> > clojure.org here:http://paste.lisp.org/display/77339
>
> > When I get my code looking anything other than nasty (and anyone who's
> > looked at pprint knows that's a low bar!), I'll at least put it up on
> > github. Eventually I may add it to contrib, too, if the community
> > feels it should go (but let's solve the problem ahead of us).
>
> > Laurent,
>
> > You seem to be going in the opposite direction from Konrad and I would
> > worry about the duplication. I would be more inclined to think about a
> > single markup format for :doc strings that could be converted for the
> > various uses. But that's really a language change at some level, so
> > I'd rather defer that until we see how this stuff is used.
>
> > But to be honest, I haven't read your comments that closely because
> > today has been a long day. Maybe later tonight...
>
> > Thanks for all the feedback, guys!
>
> > Tom
--~--~-~--~~~---~--~~
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
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: Monad mod

2009-04-20 Thread jim

I see the point about being able to add new functions. If you do
something like this, you still have defmonadfn available.

I also think that m-lift can be written so that you don't need to pass
it an argument count, which is another burr under my saddle.

Jim
--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Timo Mihaljov

Matt Clark wrote:
> Maybe I'm missing something, but what is wrong with Stuart Sierra's
> solution?  I quite like it, and it would probably be more appealing if
> it were encapsulated into a macro.

Frankly, it seemed like a good answer to the wrong question [1] instead
of being a recurring and widely known idiom in the Clojure community.
Stuart's disclaimer ("I won't claim this is an elegant solution, but
it's similar in spirit to your Python example") left me feeling that his
answer was what I asked for, not what I need, if that makes any sense.

To put it another way, any answer involving custom support code (new
macros or the like) is not the one I'm looking for. Being able to modify
the language is very cool, but not being able to solve a simple problem
with a language that thousands of people use all the time suggests to me
that I'm trying to solve a problem that everyone else sidesteps
altogether.

Thanks to everyone for your replies. An don't worry, I'll stop with the
newbie questions someday :)

[1] 
http://blogs.msdn.com/ericlippert/archive/2009/04/13/restating-the-problem.aspx

--
Timo

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread Phil Hagelberg

Sean Devlin  writes:

> *Will Java continue to be open source?

It is simply not possible for this to go away. Future development on
Java _could_ be released under developer-hostile licenses, but this
would probably be a good thing if the license were bad enough since it
would make it obvious that the OpenJDK is the future, and folks with any
sense would just give up on the official Sun version.

Probably the worst that could happen is that the license stays the same,
(meaning a community-driven fork doesn't happen) but the bureaucracy
around the project increases to the point of stagnation.

-Phil

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Timo Mihaljov

Laurent PETIT wrote:
> To simplify a little bit (both from a library implementor and user 
> perspective), why not get rid of the appended dash - ?
> 
> Indeed, having an appended dash suggests to me (so it's not apparent 
> from the examples) that the user will have to access, for a same object, 
> data sometimes from key accessors, and sometimes from specific function 
> accessors.

Here's my line of thought that lead to adding the suffixes.

In order to encapsulate access to a data type, it must only be used via
the designated accessor functions. The dash in the key name is there to
act as a reminder of that. If you use the symbol to get a field's value
anywhere outside the field's accessor function, it means you're doing
something you're not supposed to do.

I thought that I'd mark all the fields in the struct as "private" like
that to make the clients think twice before circumventing an accessor
function.

 ; A regular struct, so this is OK
 (do-something (my-own-struct :foobar))

 ; Circumventing an accessor - this is risky (and looks wrong)!
 (do-something-else (encapsulated-struct :foobar-))

A Java analog in a parallel universe where there's no "private" keyword:

 // Circumventing an accessor - this is risky (and looks wrong)!
 doSomethingElse(anotherObject.m_foobar);

> I don't know if the whole common lisp "structs" library has been ported 
> to clojure.
> And, as you asked, I'm not sure whether this would be a good think to 
> port it, and if there's another idiomatic way to solve the same problems.

Unfortunately I have no prior experience with Lisp. That's probably why
I'm so at loss with something this elementary! Frankly, I'm a bit afraid
that I might be looking for a solution to a problem that doesn't even
come up in proper Lisp programs. I need a book called "Clojure for OO
Programmers"... :)

--
Timo

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread hank williams

I believe there is 0% chance that the JVM will be charged for. I don't
think there has ever been an example of an open source thing becoming
closed source. The JVM is a generic language spec that many people
have implemented. I dont see any changes to "JDBC". First it is not a
product but a spec. Each database vendor implements their own JDBC
drivers. In short I don't think there is anything to worry about.

I cant say much about netbeans. I have never used it but many people
say it is better than eclipse, though I haven't tried. I would doubt
they would discontinue it but given the market leading position of
eclipse, its hard to believe it would, big picture, make that much
difference.

Hank

On Mon, Apr 20, 2009 at 9:50 AM, Sean Devlin  wrote:
>
> I guess I should have stated my initial concern better.  I've had to
> use several Oracle products in the past (PL/SQL & 9i), and they
> weren't developer friendly.  I'm worried about the JVM becoming less
> open than it currently is.  I can see a lot of technologies that drive
> the open source world, and this group, being compromised
>
> *Java language documentation
> *Will NetBeans be developed any longer?  Oracle has their own Java
> IDE, and it sucks royally.
> *Will Oracle stop providing the JVM and JDK for free?  This will have
> a HUGE affect on continued JVM adoption and WORA in ten years.
> *Will Java continue to be open source?
> *What the hell is going to happen to JDBC?
>
> Of course, I won't even begin to get into MySQL issues.  Time to
> install Postgres...
>
> Has anyone here been able to install Clojure on IcedTea?
>
> On Apr 20, 9:22 am, hank williams  wrote:
>> On Mon, Apr 20, 2009 at 9:13 AM, Sean Devlin  
>> wrote:
>>
>> > Okay, I'm willing to bet this crowd has already seen this:
>>
>> >http://www.sun.com/third-party/global/oracle/index.jsp
>>
>> > Any thoughts on how this affects Clojure?
>>
>> No effect.
>>
>>
>>
>> --
>> blog: whydoeseverythingsuck.com
> >
>



-- 
blog: whydoeseverythingsuck.com

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Matt Clark

Maybe I'm missing something, but what is wrong with Stuart Sierra's
solution?  I quite like it, and it would probably be more appealing if
it were encapsulated into a macro.

(def-propholder person)

(def me (person {:name "Matt Clark"}))

(def-propholder person2
  :name
{:getter (fn [record] (str (:first-name record) " " (:last-name
record)))
 :setter (fn [record val] (throw (Exception. ":name cannot be set
any more")))})

(def me (person2 {:first-name "Matt" :last-name "Clark"}))

I'll be the first to admit my pseudo code is far from elegant, but it
wouldn't be that big of a challenge to write something like this that
fits your needs.  The even numbered argument indices following the
structure's name have the keys that have overrides, the odd numbered
contain the functions that do the overriding.  In the above example
the exception could be replaced with a split on the space in the full
name instead.
If I wanted to avoid macros however, I'd go with something like your
solution, I just don't like the trailing dashes for private data :(

Matt


On Apr 20, 8:52 am, Timo Mihaljov  wrote:
> Laurent PETIT wrote:
> > What do others think about these 2 above statements ?
>
> >     The standard OO approach to information hiding would be private fields
> >     and accessor methods. Any suggestions for the One True Clojure Pattern
> >     that addresses the same problem?
>
> > I think accessor methods.
>
> Based on our discussion so far, I would use the following approach. In
> the spirit of defn-, I appended a dash after field names that should be
> accessed via accessor functions. This is similar to the Python idiom of
> prefixing "private" members with an underscore to prevent _accidental_
> direct modification. The symbols are also used as the initial versions
> of the getter functions. This way there's so little code that no macros
> are needed.
>
>      ;;; Initial version
>
>      ;; Library
>      (defstruct person :full-name-)
>
>      (defn new-person [full-name]
>        (struct person full-name))
>
>      (def full-name :full-name-)
>
>      ;; Client
>      (def p (new-person "James Bond"))
>      (println (full-name p))
>
>      ;;; Modified version
>
>      ;; Library
>      (defstruct person :first-name- :last-name-)
>
>      (defn new-person [full-name]
>        (let [[first-name last-name] (.split full-name " ")]
>          (struct person first-name last-name)))
>
>      (def first-name :first-name-)
>      (def last-name :last-name-)
>
>      (defn full-name [the-person]
>        (str (first-name the-person) " " (last-name the-person)))
>
>      ;; Client
>      (def p (new-person "James Bond"))
>      (println (last-name p))
>      (println (full-name p))
>
> How does this code look like to a experienced Clojure programmer? Does
> it seem to be in the spirit of the language?
>
> --
> Timo
--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Laurent PETIT
Hi again,

2009/4/20 Timo Mihaljov 

>
> Laurent PETIT wrote:
> > What do others think about these 2 above statements ?
> >
> > The standard OO approach to information hiding would be private
> fields
> > and accessor methods. Any suggestions for the One True Clojure
> Pattern
> > that addresses the same problem?
> >
> >
> > I think accessor methods.
>
> Based on our discussion so far, I would use the following approach. In
> the spirit of defn-, I appended a dash after field names that should be
> accessed via accessor functions.


To simplify a little bit (both from a library implementor and user
perspective), why not get rid of the appended dash - ?

Indeed, having an appended dash suggests to me (so it's not apparent from
the examples) that the user will have to access, for a same object, data
sometimes from key accessors, and sometimes from specific function
accessors.

I would suggest to keep it simpler for the user : either the lib states it
is safe for him to use key accessors, either the lib states the user must
use the function accessors provided.
With this logic, either all keys are public (first case) or private (second
case).



> This is similar to the Python idiom of
> prefixing "private" members with an underscore to prevent _accidental_
> direct modification. The symbols are also used as the initial versions
> of the getter functions. This way there's so little code that no macros
> are needed.


I'm pretty sure this has been done gazillons of time before (and maybe it's
already in clojure-contrib and I don't know about it), but here is a little
macro that would still get rid of the duplications in your code:

(defn defstruct-type-fn
  [name public-key-names-coll private-key-names-coll]
`(do
(defstruct ~name
   ~@(map (comp keyword str) public-key-names-coll)
   ~@(map (comp keyword str)  private-key-names-coll))
~@(into ()
(map (fn [k] `(defn ~k [st#] (~(keyword (str k)) st#)))
 public-key-names-coll

(defmacro defstruct-type ; sorry, no better name at the time of writing
  "creates a struct via defstruct named name and whose keys a constructed
from key-names
  (names of the keys without the prefix column). Creates as well accessor
functions named after
  public-key-names-coll.
  Optionally a sequence of private keys can also be passed"
 ([name public-key-names-coll]
   (defstruct-type-fn name public-key-names-coll nil))
([name public-key-names-coll private-key-names-coll]
   (defstruct-type-fn name public-key-names-coll private-key-names-coll)))

This way, you can rewrite your code :
;;  OLD =
;; Library
(defstruct person :first-name- :last-name-)

(defn new-person [full-name]
  (let [[first-name last-name] (.split full-name " ")]
(struct person first-name last-name)))

(def first-name :first-name-)
(def last-name :last-name-)

(defn full-name [the-person]
  (str (first-name the-person) " " (last-name the-person)))

;;  NEW =
;; Library
(defstruct-type person [first-name last-name])

(defn new-person [full-name]
  (let [[first-name last-name] (.split full-name " ")]
(struct person first-name last-name)))

(defn full-name [the-person]
  (str (first-name the-person) " " (last-name the-person)))



I don't know if the whole common lisp "structs" library has been ported to
clojure.
And, as you asked, I'm not sure whether this would be a good think to port
it, and if there's another idiomatic way to solve the same problems.

Regards,

-- 
Laurent



>
> ;;; Initial version
>
> ;; Library
> (defstruct person :full-name-)
>
> (defn new-person [full-name]
>   (struct person full-name))
>
> (def full-name :full-name-)
>
> ;; Client
> (def p (new-person "James Bond"))
> (println (full-name p))
>
>
> ;;; Modified version
>
> ;; Library
> (defstruct person :first-name- :last-name-)
>
> (defn new-person [full-name]
>   (let [[first-name last-name] (.split full-name " ")]
> (struct person first-name last-name)))
>
> (def first-name :first-name-)
> (def last-name :last-name-)
>
> (defn full-name [the-person]
>   (str (first-name the-person) " " (last-name the-person)))
>
> ;; Client
> (def p (new-person "James Bond"))
> (println (last-name p))
> (println (full-name p))
>
> How does this code look like to a experienced Clojure programmer? Does
> it seem to be in the spirit of the language?
>
> --
> Timo
>
> >
>

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread Sean Devlin

I guess I should have stated my initial concern better.  I've had to
use several Oracle products in the past (PL/SQL & 9i), and they
weren't developer friendly.  I'm worried about the JVM becoming less
open than it currently is.  I can see a lot of technologies that drive
the open source world, and this group, being compromised

*Java language documentation
*Will NetBeans be developed any longer?  Oracle has their own Java
IDE, and it sucks royally.
*Will Oracle stop providing the JVM and JDK for free?  This will have
a HUGE affect on continued JVM adoption and WORA in ten years.
*Will Java continue to be open source?
*What the hell is going to happen to JDBC?

Of course, I won't even begin to get into MySQL issues.  Time to
install Postgres...

Has anyone here been able to install Clojure on IcedTea?

On Apr 20, 9:22 am, hank williams  wrote:
> On Mon, Apr 20, 2009 at 9:13 AM, Sean Devlin  wrote:
>
> > Okay, I'm willing to bet this crowd has already seen this:
>
> >http://www.sun.com/third-party/global/oracle/index.jsp
>
> > Any thoughts on how this affects Clojure?
>
> No effect.
>
>
>
> --
> blog: whydoeseverythingsuck.com
--~--~-~--~~~---~--~~
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
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: StackOverflowError Question

2009-04-20 Thread David Nolen
You have two other function calls
getAdaptedWeightVector
computeActualResponse

Are these recursive as well?

On Sun, Apr 19, 2009 at 11:26 PM, jleehurt  wrote:

>
> Hi all, I have the following code that trains a perceptron with the
> given inputs and corresponding desired inputs. For input/output
> vectors, when the size gets to about 2000, I am getting a
> java.lang.StackOverflowError in the following function:
>
> (defn trainPerceptron [beginningWeightVector allInputs allOutputs]
>  (loop [weightVector beginningWeightVector
> inputs allInputs
> responses allOutputs]
>(if (and (not (empty? inputs)) (not (empty? responses)))
>(let [adaptedWeightVector
>  (getAdaptedWeightVector
>weightVector
>(first inputs)
>(first responses)
>(computeActualResponse signum weightVector (first
> inputs)))]
> (recur adaptedWeightVector (rest inputs) (rest
> responses)))
>weightVector)))
>
> Is not the purpose of loop/recur to avoid stack overflow problems?
> What am I doing wrong?
>
> >
>

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



StackOverflowError Question

2009-04-20 Thread jleehurt

Hi all, I have the following code that trains a perceptron with the
given inputs and corresponding desired inputs. For input/output
vectors, when the size gets to about 2000, I am getting a
java.lang.StackOverflowError in the following function:

(defn trainPerceptron [beginningWeightVector allInputs allOutputs]
  (loop [weightVector beginningWeightVector
 inputs allInputs
 responses allOutputs]
(if (and (not (empty? inputs)) (not (empty? responses)))
(let [adaptedWeightVector
  (getAdaptedWeightVector
weightVector
(first inputs)
(first responses)
(computeActualResponse signum weightVector (first
inputs)))]
 (recur adaptedWeightVector (rest inputs) (rest
responses)))
weightVector)))

Is not the purpose of loop/recur to avoid stack overflow problems?
What am I doing wrong?

--~--~-~--~~~---~--~~
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
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: Oracle and Clojure

2009-04-20 Thread hank williams

On Mon, Apr 20, 2009 at 9:13 AM, Sean Devlin  wrote:
>
> Okay, I'm willing to bet this crowd has already seen this:
>
> http://www.sun.com/third-party/global/oracle/index.jsp
>
> Any thoughts on how this affects Clojure?

No effect.
> >
>



-- 
blog: whydoeseverythingsuck.com

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



Oracle and Clojure

2009-04-20 Thread Sean Devlin

Okay, I'm willing to bet this crowd has already seen this:

http://www.sun.com/third-party/global/oracle/index.jsp

Any thoughts on how this affects Clojure?
--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Timo Mihaljov

Laurent PETIT wrote:
> What do others think about these 2 above statements ?
> 
> The standard OO approach to information hiding would be private fields
> and accessor methods. Any suggestions for the One True Clojure Pattern
> that addresses the same problem?
> 
> 
> I think accessor methods.

Based on our discussion so far, I would use the following approach. In
the spirit of defn-, I appended a dash after field names that should be
accessed via accessor functions. This is similar to the Python idiom of
prefixing "private" members with an underscore to prevent _accidental_
direct modification. The symbols are also used as the initial versions
of the getter functions. This way there's so little code that no macros
are needed.

 ;;; Initial version

 ;; Library
 (defstruct person :full-name-)

 (defn new-person [full-name]
   (struct person full-name))

 (def full-name :full-name-)

 ;; Client
 (def p (new-person "James Bond"))
 (println (full-name p))


 ;;; Modified version

 ;; Library
 (defstruct person :first-name- :last-name-)

 (defn new-person [full-name]
   (let [[first-name last-name] (.split full-name " ")]
 (struct person first-name last-name)))

 (def first-name :first-name-)
 (def last-name :last-name-)

 (defn full-name [the-person]
   (str (first-name the-person) " " (last-name the-person)))

 ;; Client
 (def p (new-person "James Bond"))
 (println (last-name p))
 (println (full-name p))

How does this code look like to a experienced Clojure programmer? Does
it seem to be in the spirit of the language?

--
Timo

--~--~-~--~~~---~--~~
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
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: On Stuart's Book

2009-04-20 Thread Antony Blakey


On 20/04/2009, at 6:13 PM, fft1976 wrote:

> On Apr 19, 3:20 am, Antony Blakey  wrote:
>
>> If I use Clojure commercially, I'll certainly pay for it.
>
> Please do not forget to pay for JVM, Java, Linux, tar and others.

When they start asking for donations, and don't use a GPL license  
(which is a form of license that in effect requires that I  
reciprocally donate my labour, which is fine), then maybe I'll  
consider it. Specifically, I don't personally use Linux (I'm on OSX),  
Sun owns the JVM/Java brand and makes money from it, and none of the  
things you list are exactly niche products like Clojure.

Or are you suggesting I shouldn't donate to Clojure? This is not the  
place for an o/s flamewar, so lets take this offlist.

Antony Blakey
--
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787

75% of statistics are made up on the spot.



--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Laurent PETIT
Hi,

2009/4/20 Timo Mihaljov 

>
> Laurent PETIT wrote:
> > While interesting, this approach seems to me limited to simple cases :
> >  * limited in possibilities: you are not able to directly use values of
> > other fields. So in more complex cases, you won't be able to combine
> > calculated values without code repetition or prepraration via lets ..
> >  * limited in extensibility: in a live system, you won't be able to
> > change the function that displays a name because it's "hard-coded" once
> > and for all at the same time the data is entered in the system.
> > Depending on your use cases, it may or may not be a problem, though.
> >  * limited for persistence: when you want to persist a lazy-struct-map,
> > the computed value is fixed and stored, where it should not be used I
> think.
> >  * limited for equality tests (in relation with "limited in
> > extensibility"): you will not be able to succesfully compare for
> > equality 2 persons with the exact same essential data, if the way to
> > represent names has been even slightly enhanced, since the :name value
> > will always be used for the comparison as well. So it's not just a
> > problem for performance (very minor in that case, though it may not be
> > that minor in other cases), but also a problem of correctness, in the
> > long run (for systems you want to keep "live", and without having to do
> > weird things when you have to marshall / unmarshall your data).
>
> Thanks for your insightful reply, Laurent. You are right, lazyseq is
> indeed too limited to be used in the way I proposed. It's still very
> cool, though, and I'm sure I'll find some other use for it :)


No doubt, Meikel made a very interesting addition to Maps with that !


>
>
> > I would like to offer another possibility. Not ideal, maybe, but that
> > may answer your needs.
> > Basically, the idea is that with a language like clojure that has higher
> > order functions and macros, writing "boiler plate" code should be a code
> > smell. The good news being that in Java, this "boiler plate" code smell
> > has no solution in some cases (think about design patterns), while with
> > a lisp, you can do something for that.
> >
> > By using a macro, you could generate "boiler plate" getters for your
> > structure. And just "override" with new definitions those getter/setters
> > that need computations.
>
> The thing that bothers me is that AFAIK there's no standard macro to do
> this in Clojure.


AFAIK too.


> Combined with the facts that spelling out each accessor
> by hand would be a code smell, and all APIs -- internal or external --
> need some form of information hiding to remain stable, I'm left feeling
> that information hiding should be done in some other way in Clojure.


Well, I don't know how others do. I think we should indeed consider that the
macro creating the "getters" accept a :private modifier to not create
getters for certain fields.
As for information hiding, I don't think that's the philosophy of clojure to
prevent users from mistakes in this area ?


>
> That's why I asked for the idiomatic way to solve the problem in my
> example. One can write FORTRAN in any language, and I could write any
> language in Clojure, but I'd rather learn Clojure :)
>
> Another issue I have with the accessor function approach is that it can
> be circumvented very easily by accident because the data structure is
> exposed to the users of the API. All it takes is typing (:first-name
> some-person) instead of (first-name some-person), and you get a map
> lookup instead of a call to a getter.


Yes, but I think that in the spirit of clojure, data should indeed be
considered as black boxes, even if it is so easy to do introspection on
them.

When Rich said in another thread that maps should certainly deserve to be
used as the primary data structures for a vast number of cases, I think he
suggested that they be used as the underlying memory data storage.

And then, there are different kinds of usages:
 * manipulation of a piece of data in "end user code". Here, the code should
not try to rely on a particular storage implementation (unless if clearly
specified in the doc), and rely on functions for manipulating the data.
 * manipulation of a piece of data in the library code: here the library
creator can leverage all the facilities of clojure data structures
manipulation.
 * manipulation of a piece of data by a third party orthogonal library :
e.g. a library for storing information in a database. The library can work
with the map and store information in a very generic way, without having to
know any business detail on the data. Here again, having used a regular map
is a big win.

Please note that it's my own interpretation, and I also would like to hear
here from users using clojure in a more day to day basis than me.



> Both forms work as long as the
> records are maps containing the key :first-name, but the former breaks
> when the data structure changes. This is especially problemati

Re: Modifying data structures without changing their interface

2009-04-20 Thread Timo Mihaljov

Laurent PETIT wrote:
> While interesting, this approach seems to me limited to simple cases :
>  * limited in possibilities: you are not able to directly use values of 
> other fields. So in more complex cases, you won't be able to combine 
> calculated values without code repetition or prepraration via lets ..
>  * limited in extensibility: in a live system, you won't be able to 
> change the function that displays a name because it's "hard-coded" once 
> and for all at the same time the data is entered in the system. 
> Depending on your use cases, it may or may not be a problem, though.
>  * limited for persistence: when you want to persist a lazy-struct-map, 
> the computed value is fixed and stored, where it should not be used I think.
>  * limited for equality tests (in relation with "limited in 
> extensibility"): you will not be able to succesfully compare for 
> equality 2 persons with the exact same essential data, if the way to 
> represent names has been even slightly enhanced, since the :name value 
> will always be used for the comparison as well. So it's not just a 
> problem for performance (very minor in that case, though it may not be 
> that minor in other cases), but also a problem of correctness, in the 
> long run (for systems you want to keep "live", and without having to do 
> weird things when you have to marshall / unmarshall your data).

Thanks for your insightful reply, Laurent. You are right, lazyseq is
indeed too limited to be used in the way I proposed. It's still very
cool, though, and I'm sure I'll find some other use for it :)

> I would like to offer another possibility. Not ideal, maybe, but that 
> may answer your needs.
> Basically, the idea is that with a language like clojure that has higher 
> order functions and macros, writing "boiler plate" code should be a code 
> smell. The good news being that in Java, this "boiler plate" code smell 
> has no solution in some cases (think about design patterns), while with 
> a lisp, you can do something for that.
> 
> By using a macro, you could generate "boiler plate" getters for your 
> structure. And just "override" with new definitions those getter/setters 
> that need computations.

The thing that bothers me is that AFAIK there's no standard macro to do
this in Clojure. Combined with the facts that spelling out each accessor
by hand would be a code smell, and all APIs -- internal or external --
need some form of information hiding to remain stable, I'm left feeling
that information hiding should be done in some other way in Clojure.
That's why I asked for the idiomatic way to solve the problem in my
example. One can write FORTRAN in any language, and I could write any
language in Clojure, but I'd rather learn Clojure :)

Another issue I have with the accessor function approach is that it can
be circumvented very easily by accident because the data structure is
exposed to the users of the API. All it takes is typing (:first-name
some-person) instead of (first-name some-person), and you get a map
lookup instead of a call to a getter. Both forms work as long as the
records are maps containing the key :first-name, but the former breaks
when the data structure changes. This is especially problematic when
wrapping an existing map with accessors -- how can you be sure that you
converted each and every key lookup to a getter call?

The standard OO approach to information hiding would be private fields
and accessor methods. Any suggestions for the One True Clojure Pattern
that addresses the same problem?

Now that I've read Programming Clojure I know the capabilities of the
language. My problem is that I have no idea how to apply them to solve
real-world problems, such as the contrived example in my first message.
I hope Mr. Halloway starts writing the sequel soon :)

--
Timo

--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Meikel Brandmeyer

Hi,

Am 20.04.2009 um 08:32 schrieb Timo Mihaljov:


After a bit of googling I found what seems to be the perfect solution:
http://kotka.de/projects/clojure/lazy-map.html

(defn new-person [first-name last-name]
  (lazy-struct-map person
   :first-name first-name :last-name last-name
   :name (str first-name " " last-name)))


Huh? Wow. I hadn't thought of such a use for lazy-map. Very nice. :)

Now I only wish that de.kotka.lazymap would become a part of Clojure  
core.


Vincent Foley suggest lazy-map as a candidate for contrib.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: On Stuart's Book

2009-04-20 Thread fft1976

On Apr 19, 3:20 am, Antony Blakey  wrote:

> If I use Clojure commercially, I'll certainly pay for it.

Please do not forget to pay for JVM, Java, Linux, tar and others.
--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---



European Lisp Symposium 2009: Call for participation

2009-04-20 Thread Marco Antoniotti

Apologies for multiple postings




 2nd European Lisp Symposium (ELS 2009)

 Milan, Italy, May 27-29, 2009
 Universita` degli Studi di Milano-Bicocca

 www.european-lisp-symposium.org



CALL FOR PARTECIPATION
**

REGISTRATION IS NOW OPEN AT www.european-lisp-symposium.org.
Take advantage of the early bird registration fee.

Registration Fees:
**

 * Early registration before April 25, 2008: Students EU60, regular
EU120.
 * Late registration before May 16, 2008: Students EU80, regular
EU160.
 * Onsite registration: Students EU100, regular EU220.

Registration will include the proceedings, coffee breaks,
the symposium dinner and other amenities.
Accommodation is not included.



Scope and Program Highlights:
*

The purpose of the European Lisp Symposium is to provide a forum for
the discussion of all aspects of the design, implementation and
application of any of the Lisp dialects.  We encourage everyone
interested in Lisp to participate.

The European Lisp Symposium 2009 program includes presentations of
high quality papers about novel research results, insights and lessons
learned from practical applications, and educational perspectives, all
involving Lisp dialects, including Common Lisp, Scheme, Emacs Lisp,
AutoLisp, ISLISP, Dylan, Clojure, and so on.


Kent Pitman will give the keynote address on Thursday, May 28.

The presentations will be divided into two categories.

* Original contributions.

* Work in progress describing ongoing work that will be discussed in
the form of a "writers' workshop". The writers' workshops will take
place at the symposium in Milan on May 28, 2008.

Social Events:
**

Friday 29th evening, Conference Banquet

Saturday 30th morning, Guided tour to the "Futurismo" Exhibit in
the center of Milan; 2009 marks the 100th anniversary of the Futurism
Manifesto; stretching it, the harbinger of Lisp 50 years later.


Program Chair:
**

 * Antonio Leitao, Technical University of Lisbon, Portugal


Local Chair:


 * Marco Antoniotti, DISCo, Universita`† Milano Bicocca, Italy


Program committee:
**

 * Giuseppe Attardi, Universita`† di Pisa , Italy
 * Pascal Costanza, Vrije Universiteit Brussel, Belgium
 * Irene Durand, Universite` Bordeaux 1, France
 * Marc Feeley, Universit` de Montreal, Canada
 * Ron Garret, Amalgamated Widgets Unlimited, USA
 * Gregor Kiczales, University of British Columbia, Canada
 * Scott McKay, ITA Software, Inc., USA
 * Peter Norvig, Google Inc., USA
 * Julian Padget, University of Bath, UK
 * Kent Pitman, PTC, USA
 * Christian Queinnec, Universite` Pierre et Marie Curie, France
 * Christophe Rhodes, Goldsmiths College, University of London, UK
 * Robert Strandh, Universite` Bordeaux 1, France
 * Mark Tarver, Lambda Associates, UK
 * Didier Verna, EPITA Research and Development Laboratory, France
 * JonL White, TheGingerIceCreamFactory of Palo Alto, USA
 * Taiichi Yuasa, Kyoto University, Japan



--~--~-~--~~~---~--~~
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
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: Modifying data structures without changing their interface

2009-04-20 Thread Laurent PETIT
Hi,

2009/4/20 Timo Mihaljov 

>
> Timo Mihaljov wrote:
> > I'm wondering about how to change a data structure without breaking the
> > API used to access it. For example, let's assume that I have a library
> > for dealing with records of people and I'm storing them in structs.
> >
> > (defstruct person :name)
> >
> > The users of my library access the data stored in the records like any
> > other map.
> >
> > (:name some-person)
> >
> > When the library's been in use for a while, I realize that I need to
> > make a change to the data structure.
> >
> > (defstruct :first-name :last-name)
> >
> > The problem is that making this change would break all the clients using
> > the library.
>
> After a bit of googling I found what seems to be the perfect solution:
> http://kotka.de/projects/clojure/lazy-map.html
>
> (defn new-person [first-name last-name]
>   (lazy-struct-map person
>:first-name first-name :last-name last-name
>:name (str first-name " " last-name)))
>

While interesting, this approach seems to me limited to simple cases :
 * limited in possibilities: you are not able to directly use values of
other fields. So in more complex cases, you won't be able to combine
calculated values without code repetition or prepraration via lets ..
 * limited in extensibility: in a live system, you won't be able to change
the function that displays a name because it's "hard-coded" once and for all
at the same time the data is entered in the system. Depending on your use
cases, it may or may not be a problem, though.
 * limited for persistence: when you want to persist a lazy-struct-map, the
computed value is fixed and stored, where it should not be used I think.
 * limited for equality tests (in relation with "limited in extensibility"):
you will not be able to succesfully compare for equality 2 persons with the
exact same essential data, if the way to represent names has been even
slightly enhanced, since the :name value will always be used for the
comparison as well. So it's not just a problem for performance (very minor
in that case, though it may not be that minor in other cases), but also a
problem of correctness, in the long run (for systems you want to keep
"live", and without having to do weird things when you have to marshall /
unmarshall your data).


I would like to offer another possibility. Not ideal, maybe, but that may
answer your needs.
Basically, the idea is that with a language like clojure that has higher
order functions and macros, writing "boiler plate" code should be a code
smell. The good news being that in Java, this "boiler plate" code smell has
no solution in some cases (think about design patterns), while with a lisp,
you can do something for that.

By using a macro, you could generate "boiler plate" getters for your
structure. And just "override" with new definitions those getter/setters
that need computations.

Of course, this does not solve the problem of evaluating a derived value
only once, but it does not appear to me that it was the original question of
your post :-)

--~--~-~--~~~---~--~~
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
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
-~--~~~~--~~--~--~---