The Application Context Pattern

2009-02-27 Thread Itay Maman

Some of the reaction for Waterfront was related to the Application
Context Pattern (ACP) - The pattern that allows most of Waterfront's
code to be purely functional. I'll try to explain the basics in this
post. Let me start with the motivation: the reason why FP is at odds
with GUI code.

(Pure) Functional code has no side effects, which implies immutability
of state. There are no fields nor global variables that can be
assigned to. Thus, one function can affect the computation carried out
by another function only by the passing of parameters. Most GUI
systems are built around the notion of event handlers which are
invoked by a message processing loop. There is no chain of calls from
one event handler to another.
In particular, if handler "A" computed some new value it cannot pass
it on to handler "B" because the system will call "B" only after "A"
returns. That's the predicament.

ACP overcomes this by capturing the applications current state in an
immutable map. All event handlers receive a single parameter which is
the "current" context and compute the "new" context. A typical handler
(henceforth: "context processing function") will carry out these
activities: (a) Examine the current context; (b) Perform some GUI
operations (setSize, setText, etc.); (c) Compute a new context based
on the current context and on information obtained from the GUI
(getText, etc.). The caller (henceforth: "dispatcher") takes the
returned context and will use it as the new current context, the next
time a context processing function is invoked.

This means that when you register event handler with a Swing widget
the handler needs to to call the ACP dispatcher passing it a context
processing function.

The net effect of this approach is that only the dispatcher has to
deal with mutable state. The context processors are functional: they
merely compute the new state from the current.

application-context-pattern.clj (http://groups.google.com/group/
clojure/web/application-context-pattern.clj) shows a concrete example.
It's about 140 LOC (ripped off from the real Waterfront codebase)
structured as follows:
  Lines 1..40: General-purpose helpers.
  Lines 40..90: The ACP infrastructure
  Lines 90..140: A quick sample, built around ACP.

The sample program opens a JFrame with two buttons: Input and Output.
A click on the input button will pop-up an input dialog box. A click
on the output button will pop-up a message box showing the last value
entered into the input box. There's also a JLabel showing the length
of the input, but let's ignore it for the moment.

The entry point into the ACP world is the bootstrap function. It takes
two parameters: a context processing function and an initial context.
In the example, this is carried out at the bottom of the run-it
function:

  (defn run-it []
(let [build-ui (fn [ctx]
  (let [f (javax.swing.JFrame. "Frame")
b-in (javax.swing.JButton. "Input")
b-out (javax.swing.JButton. "Output")]

(.addActionListener b-in (new-action-listener (fn [event]
  ((ctx :dispatch) get-input

(.addActionListener b-out (new-action-listener (fn [event]
  ((ctx :dispatch) show-output

(.setLayout f (java.awt.FlowLayout.))
(doseq [x [b-in b-out]]
  (.add f x) )

(doto f
  (.setSize 500 300)
  (.setDefaultCloseOperation javax.swing.JFrame/
DISPOSE_ON_CLOSE)
  (.setVisible true))

(assoc ctx :frame f) ))]

(invoke-later #(bootstrap build-ui {})) ))


invoke-later is a utility function that is mapped to SwingUtilities/
invokeLater.

Let's drill down into the build-ui function: It takes the current
context (ctx parameter). Then it creates the frame and the buttons. It
uses new-action-listener (another utility) to register an action
listener with the buttons. The first listener looks like this:
  ((ctx :dispatch) get-input

It uses (ctx :dispatch) to obtain the dispatcher from which ctx was
obtained, and evaluates it passing get-input as the context processing
function. The call to bootstrap initialized this dispatcher and added
the :dispatch mapping to the initial context.

get-input looks like this:
  (defn- get-input [ctx]
(let [reply (javax.swing.JOptionPane/showInputDialog nil "Type in
something")]
  (assoc ctx :user-input reply) ))

It pops-up an input box, and returns a new context which is the same
as the current context except that :user-input is now mapped to value
returned from the input box.

show-output is the context processing function for the output button:
  (defn- show-output [ctx]
(javax.swing.JOptionPane/showMessageDialog nil (ctx :user-
input)) )

Note that show-output returns nil which the dispatcher interprets as
"no change to ctx".

What we have is that get-input communicates with show-output by
returning a new context. There's no assignment into atoms or the
likes. The mutable state is encapsulated within the dispatcher.

It is now t

Re: Please help me get rid of my mutable code.

2009-02-27 Thread Itay Maman

Hi,

I just posted about the application context pattern. I believe it
addresses the issue you're describing.

-Itay


On Feb 27, 4:21 am, CuppoJava  wrote:
> Hi,
> After having used Clojure for a few months now, I'm still having lots
> of trouble separating my mutable code from my immutable code. My use-
> case is pretty typical I think, so I'm wondering what sort of
> structure everyone else is using.
>
> Here's my current structure.
>
> I have an engine that manages a list of sprites. The engine runs in a
> loop and updates all the sprites incrementally sixty times a second.
> When an event occurs, the engine notifies each sprite. When a sprite
> receives an event, it processes it, and then notifies each of it's
> listeners. Typical Java event listener model.
>
> Well this scheme has mutability written all over it.
> I'm currently representing sprites as references of immutable maps. So
> my code is literally littered with (dosync) instructions.
>
> How would I go about separating my mutable code from my immutable
> code? I think I need a completely different angle to attack the
> problem?
>
> Thanks a lot for the help
>   -Patrick
--~--~-~--~~~---~--~~
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: namespace docstrings

2009-02-27 Thread Meikel Brandmeyer

Hi,

Am 27.02.2009 um 08:20 schrieb Konrad Hinsen:



I have been trying in vain to get the namespace docstring of anything
with print-namespace-doc. It doesn't say what exactly it wants as an
argument (a symbol, a string, or  a namespace object), but it calls
ns-name, which wants a symbol, so I give it a symbol. But the symbol
doesn't have any metadata. I went on to look for namespace-related
metadata elsewhere, but the namespace object doesn't have any either.
Of course I looked at namespaces that actually have docstrings in
their source code (for example clojure.contrib.types). So where does
the namespace docstring go?


I suppose where it belongs:

Clojure
1:1 user=> (require 'clojure.contrib.types)
nil
1:2 user=> (doc clojure.contrib.types)
-
clojure.contrib.types
  nil
nil
1:3 user=> (doc clojure.core)
-
clojure.core
  Fundamental library of the Clojure language
nil
1:4 user=> (ns foo.bar "A Foobar namespace")
nil
1:5 foo.bar=> (doc foo.bar)
-
foo.bar
  A Foobar namespace
nil

The only difference between clojure.contrib.types
and foo.bar is, that foo.bar is defined at the Repl.
clojure.contrib.types is defined in a file, which is
then loaded.

The same is true for clojure.core, but here the meta
data is set via alter-meta and it is not loaded the
"usual" way with require.

It seems, the metadata gets lost somehow.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Please explain

2009-02-27 Thread timc

On the page describing Vars, I cannot get the meaning of this sentence
(a typo has made it incomprehensible I think):

"Bindings created with binding can be assigned to, which provides a
means for nested contexts to communicate with code before it the call
stack."

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



Please take mercy on us newbies

2009-02-27 Thread timc

Can I make a small plea for people who submit source code to PLEASE
insert some sort of explanation of what the code is about.

I know it's usual in programming circles to think that if someone
can't understand something it's because they are dumb - but really -
this is a terribly inefficient way of communicating and also rather
arrogant.

Please don't take this as the start of a war!

Best regards
--~--~-~--~~~---~--~~
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: Please take mercy on us newbies

2009-02-27 Thread Laurent PETIT
What are you talking about ? It's really vague.

It seems to me that people in this list have always been kind to help people
discovering the language.
And if you turn it the other way around, maybe people are not always
explaining each line of code because they don't presuppose that readers will
mainly be "dumb" or whatever term you want to use?

And also people are taking time to give hints to the person asking, but each
one's time is precious (most -if not all- people in this list are not paid
for answering questions).

If there's something you don't understand, have no complex and ask for
further explanation !

Regards,
-- 
Laurent

2009/2/27 timc 

>
> Can I make a small plea for people who submit source code to PLEASE
> insert some sort of explanation of what the code is about.
>
> I know it's usual in programming circles to think that if someone
> can't understand something it's because they are dumb - but really -
> this is a terribly inefficient way of communicating and also rather
> arrogant.
>
> Please don't take this as the start of a war!
>
> Best regards
> >
>

--~--~-~--~~~---~--~~
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: Please explain

2009-02-27 Thread Jason Wolfe

Here's an example:

user> (def x)
#'user/x

user> (defn foo [] (set! x 10))
#'user/foo

user> (binding [x 1] [x (binding [x 2] [x (do (foo) x)]) x])
[1 [2 10] 1]

Foo passes information to the calling form by assigning to x, within
the innermost binding only.

It sounds like the quote should say "before it [in] the call stack".

-Jason

On Feb 27, 1:08 am, timc  wrote:
> On the page describing Vars, I cannot get the meaning of this sentence
> (a typo has made it incomprehensible I think):
>
> "Bindings created with binding can be assigned to, which provides a
> means for nested contexts to communicate with code before it the call
> stack."
>
> Thanks
--~--~-~--~~~---~--~~
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: Please take mercy on us newbies

2009-02-27 Thread timc

OK - choosing files at random:

Is it at all obvious what these do?

app.clj
application-context-patter.clj
binary-structure.clj
bookmark-tut.clj
bsptree.clj
chlam-clean-clj

and so on...

On Feb 27, 9:20 am, Laurent PETIT  wrote:
> What are you talking about ? It's really vague.
>
> It seems to me that people in this list have always been kind to help people
> discovering the language.
> And if you turn it the other way around, maybe people are not always
> explaining each line of code because they don't presuppose that readers will
> mainly be "dumb" or whatever term you want to use?
>
> And also people are taking time to give hints to the person asking, but each
> one's time is precious (most -if not all- people in this list are not paid
> for answering questions).
>
> If there's something you don't understand, have no complex and ask for
> further explanation !
>
> Regards,
> --
> Laurent
>
> 2009/2/27 timc 
>
>
>
> > Can I make a small plea for people who submit source code to PLEASE
> > insert some sort of explanation of what the code is about.
>
> > I know it's usual in programming circles to think that if someone
> > can't understand something it's because they are dumb - but really -
> > this is a terribly inefficient way of communicating and also rather
> > arrogant.
>
> > Please don't take this as the start of a war!
>
> > Best regards
--~--~-~--~~~---~--~~
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: Please take mercy on us newbies

2009-02-27 Thread Meikel Brandmeyer

Hi,

Am 27.02.2009 um 10:41 schrieb timc:


OK - choosing files at random:

Is it at all obvious what these do?

app.clj
application-context-patter.clj
binary-structure.clj
bookmark-tut.clj
bsptree.clj
chlam-clean-clj

and so on...


I guess for almost all of these files there is a thread
in the group discussing their content. Or at least
giving some context. I recommend that you search
the group archives for the filename and you will
digg out quite some information.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Mathy operations on non-numerics (was "Adding" strings)

2009-02-27 Thread Christian Vest Hansen

On Fri, Feb 27, 2009 at 12:47 AM, Allen Rohner  wrote:
>
>
>> I agree regarding concatenation as well, but I think the case for
>> comparison of non-numerics is still pretty strong.
>>
>> -Phil
>
> Are you referring to using <, >, =, with objects that implement
> java.lang.Comparable?
>
> i.e. given x.compareTo(y) == -1
> (< x y)
> => true
>
> I would find that useful.

I think having <, >, <=, >= be based on Comparable has been discussed before.

And the conclusion was that it was a bad idea, because in Java:

user=> (.compareTo (Integer. "10") (Long. "10"))
java.lang.ClassCastException: java.lang.Long cannot be cast to
java.lang.Integer (NO_SOURCE_FILE:0)

And:

user=> (.equals (Integer. "10") (Long. "10"))
false

Whereas in Clojure:

user=> (< (Integer. "10") (Long. "10"))
false
user=> (= (Integer. "10") (Long. "10"))
true

Given these consequences, I think the current behavior is the best compromise.

>
> Allen
>
> >
>



-- 
Venlig hilsen / Kind regards,
Christian Vest Hansen.

--~--~-~--~~~---~--~~
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 Application Context Pattern

2009-02-27 Thread linh

thanks, this will be very useful for me

On 27 Feb, 09:05, Itay Maman  wrote:
> Some of the reaction for Waterfront was related to the Application
> Context Pattern (ACP) - The pattern that allows most of Waterfront's
> code to be purely functional. I'll try to explain the basics in this
> post. Let me start with the motivation: the reason why FP is at odds
> with GUI code.
>
> (Pure) Functional code has no side effects, which implies immutability
> of state. There are no fields nor global variables that can be
> assigned to. Thus, one function can affect the computation carried out
> by another function only by the passing of parameters. Most GUI
> systems are built around the notion of event handlers which are
> invoked by a message processing loop. There is no chain of calls from
> one event handler to another.
> In particular, if handler "A" computed some new value it cannot pass
> it on to handler "B" because the system will call "B" only after "A"
> returns. That's the predicament.
>
> ACP overcomes this by capturing the applications current state in an
> immutable map. All event handlers receive a single parameter which is
> the "current" context and compute the "new" context. A typical handler
> (henceforth: "context processing function") will carry out these
> activities: (a) Examine the current context; (b) Perform some GUI
> operations (setSize, setText, etc.); (c) Compute a new context based
> on the current context and on information obtained from the GUI
> (getText, etc.). The caller (henceforth: "dispatcher") takes the
> returned context and will use it as the new current context, the next
> time a context processing function is invoked.
>
> This means that when you register event handler with a Swing widget
> the handler needs to to call the ACP dispatcher passing it a context
> processing function.
>
> The net effect of this approach is that only the dispatcher has to
> deal with mutable state. The context processors are functional: they
> merely compute the new state from the current.
>
> application-context-pattern.clj (http://groups.google.com/group/
> clojure/web/application-context-pattern.clj) shows a concrete example.
> It's about 140 LOC (ripped off from the real Waterfront codebase)
> structured as follows:
>   Lines 1..40: General-purpose helpers.
>   Lines 40..90: The ACP infrastructure
>   Lines 90..140: A quick sample, built around ACP.
>
> The sample program opens a JFrame with two buttons: Input and Output.
> A click on the input button will pop-up an input dialog box. A click
> on the output button will pop-up a message box showing the last value
> entered into the input box. There's also a JLabel showing the length
> of the input, but let's ignore it for the moment.
>
> The entry point into the ACP world is the bootstrap function. It takes
> two parameters: a context processing function and an initial context.
> In the example, this is carried out at the bottom of the run-it
> function:
>
>   (defn run-it []
>     (let [build-ui (fn [ctx]
>       (let [f (javax.swing.JFrame. "Frame")
>             b-in (javax.swing.JButton. "Input")
>             b-out (javax.swing.JButton. "Output")]
>
>         (.addActionListener b-in (new-action-listener (fn [event]
>           ((ctx :dispatch) get-input
>
>         (.addActionListener b-out (new-action-listener (fn [event]
>           ((ctx :dispatch) show-output
>
>         (.setLayout f (java.awt.FlowLayout.))
>         (doseq [x [b-in b-out]]
>           (.add f x) )
>
>         (doto f
>           (.setSize 500 300)
>           (.setDefaultCloseOperation javax.swing.JFrame/
> DISPOSE_ON_CLOSE)
>           (.setVisible true))
>
>         (assoc ctx :frame f) ))]
>
>     (invoke-later #(bootstrap build-ui {})) ))
>
> invoke-later is a utility function that is mapped to SwingUtilities/
> invokeLater.
>
> Let's drill down into the build-ui function: It takes the current
> context (ctx parameter). Then it creates the frame and the buttons. It
> uses new-action-listener (another utility) to register an action
> listener with the buttons. The first listener looks like this:
>           ((ctx :dispatch) get-input
>
> It uses (ctx :dispatch) to obtain the dispatcher from which ctx was
> obtained, and evaluates it passing get-input as the context processing
> function. The call to bootstrap initialized this dispatcher and added
> the :dispatch mapping to the initial context.
>
> get-input looks like this:
>   (defn- get-input [ctx]
>     (let [reply (javax.swing.JOptionPane/showInputDialog nil "Type in
> something")]
>       (assoc ctx :user-input reply) ))
>
> It pops-up an input box, and returns a new context which is the same
> as the current context except that :user-input is now mapped to value
> returned from the input box.
>
> show-output is the context processing function for the output button:
>   (defn- show-output [ctx]
>     (javax.swing.JOptionPane/showMessageDialog nil (ctx :user-
> input)) )
>
> Note that show-ou

Re: Please explain

2009-02-27 Thread Michael Wood

On Fri, Feb 27, 2009 at 11:08 AM, timc  wrote:
>
> On the page describing Vars, I cannot get the meaning of this sentence
> (a typo has made it incomprehensible I think):
>
> "Bindings created with binding can be assigned to, which provides a
> means for nested contexts to communicate with code before it the call
> stack."

I think there's just an "in" missing.  i.e. I think it should be:

Bindings created with binding can be assigned to, which provides a
means for nested contexts to communicate with code before it _in_ the call
stack.

It could be a little clearer as follows:

Bindings created with _the binding macro_ can be assigned to, which[...]

-- 
Michael Wood 

--~--~-~--~~~---~--~~
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: Please explain

2009-02-27 Thread Mark Volkmann

On Fri, Feb 27, 2009 at 4:34 AM, Michael Wood  wrote:
>
> On Fri, Feb 27, 2009 at 11:08 AM, timc  wrote:
>>
>> On the page describing Vars, I cannot get the meaning of this sentence
>> (a typo has made it incomprehensible I think):
>>
>> "Bindings created with binding can be assigned to, which provides a
>> means for nested contexts to communicate with code before it the call
>> stack."
>
> I think there's just an "in" missing.  i.e. I think it should be:
>
> Bindings created with binding can be assigned to, which provides a
> means for nested contexts to communicate with code before it _in_ the call
> stack.
>
> It could be a little clearer as follows:
>
> Bindings created with _the binding macro_ can be assigned to, which[...]

The word "before" is what seems out of place to me. The typically use
of binding that I've seen is for binding a different value to a Var
for the duration of the binding scope which includes calls that occur
*after* the binding keyword, but in its scope. For example, println
normally writes to stdout, but you can changes that for a limited
scope with binding.

(println "This goes to stdout.")

(binding [*out* (java.io.FileWriter. "my.log")]
  (println "This goes to the log file.")
  (foo "bar") ; If the function foo uses println, that output will
also go to the log file.
  (flush))

(println "Now we're back to writing to stdout.")

-- 
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: Patch for print-method

2009-02-27 Thread Rich Hickey



On Feb 27, 2:50 am, Konrad Hinsen  wrote:
> The attached patch to clojure.core fixes the printing problem for
> types that have no implementation of print-method. When such objects
> are printed or converted to strings, an infinite loop leads to a
> stack overflow. The reason is that the :default implementation for
> print-method calls str on the object, which in turn calls print-
> method again.
>
> The path makes two changes:
>
> 1) The current :default implementation becomes the implementation for
> Object, thus remaining the default for everything that does not have
> a type field in the metadata.
>
> 2) A new :default implementation calls print-method recursively after
> having removed the :type field from the object's metadata.
>

Patch applied - svn 1311 - thanks!

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: Please explain

2009-02-27 Thread Michael Wood

On Fri, Feb 27, 2009 at 2:30 PM, Mark Volkmann
 wrote:
>
> On Fri, Feb 27, 2009 at 4:34 AM, Michael Wood  wrote:
[...]
>> Bindings created with binding can be assigned to, which provides a
>> means for nested contexts to communicate with code before it _in_ the call
>> stack.
[...]
>
> The word "before" is what seems out of place to me. The typically use
> of binding that I've seen is for binding a different value to a Var
> for the duration of the binding scope which includes calls that occur
> *after* the binding keyword, but in its scope. For example, println
> normally writes to stdout, but you can changes that for a limited
> scope with binding.
[...]

I actually didn't think too hard about that before your e-mail :) but
I think "before" is right.  Jason's example demonstrates what this
means:

user> (def x)
#'user/x

user> (defn foo [] (set! x 10))
#'user/foo

user> (binding [x 1] ; first binding form
[x (binding [x 2] ; second binding form
  [x (do (foo) x)]) x])
[1 [2 10] 1]

The second binding form is "before" foo in the call stack, yet foo can
influence it by calling (set! x 10).

I'm not sure if doing this sort of thing is a good idea, though.

While reading the description again I noticed a grammatical error.  I
believe it should be:
Bindings created with binding can be assigned to, which provides a
means for a nested context to communicate with code before it in the call
stack.

i.e. "a ... context ... before it" rather than "contexts ... before it"

-- 
Michael Wood 

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



functions and macros in memory

2009-02-27 Thread Mark Volkmann

Is it correct to say that each loaded function is represented by an
AFn object in memory?
Are macros represented in memory in the same way?

-- 
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: unbean

2009-02-27 Thread John D. Hume

On Wed, Feb 25, 2009 at 12:18 AM, .Bill Smith  wrote:
> The map alone is not sufficient to describe the object; you need the
> class too.  That's true both for the bean and any of it's bean-typed
> properties, since a property might be typed with an interface or an
> abstract class for which there is no constructor.

You could gen-class as needed to create concrete interface
implementations or subclasses. This would probably be a terrible idea
if unbean were for general use, but if you're focused on testing it
could keep things cleaner (and prevent you cluttering up tests with
irrelevant details).

I suppose the most communicative approach would be to nest unbean
calls, but make unbean support abstract classes and interfaces as its
first argument. (If unbean inferred the need to gen-class, you
couldn't tell from reading the test code whether a property of the
top-level bean were a PersistentHashMap or some non-Clojure type being
figured out behind the scenes.)

-hume.

-- 
http://elhumidor.blogspot.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: functions and macros in memory

2009-02-27 Thread Konrad Hinsen

On 27.02.2009, at 14:46, Mark Volkmann wrote:

> Is it correct to say that each loaded function is represented by an
> AFn object in memory?

Each compiled function becomes a class that extends AFn. When the  
function is created in the Clojure code, an object is generated from  
this class. If you have a function returning a function (typically a  
closure), there is only one class for the returned function, but  
there will be several instances of that class.

> Are macros represented in memory in the same way?

Yes. Macros are strictly the same as functions. The only difference  
is that the var that stores the reference has a "macro" flag set, so  
that the compiler knows to call it correctly.

In fact, you can obtain a plain function version of a macro:

(def and-as-a-function @(var and))

Of course, this is still a function that expects being called with  
unevaluated forms and returns a modified form. It's just called  
explicitly, rather than implicitly by the compiler.

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



Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)

2009-02-27 Thread Itay Maman

Revision 148 is available for download at
http://sourceforge.net/project/platformdownload.php?group_id=249246
It addresses some of the requests that were raised in this discussion:

* Changed default location of the divider
* Fixed the "command-key" issue on Macs.
* Java 1.5 compilance (prev. 1.6)
* Added a space in the execution time between the digits and "ms".
E.g., "34ms" --> "34 ms"
* Source -> Doc and Source -> Reflect consolidated into a single menu
item triggered by F1
* wf.sh file added
* wf.bat handles spaces in the path

Thanks you Stephen, Tom, Mike and all the other for the feedback.

Also, for those interested in the "application context pattern",
please see a post with that title published earlier today.

-Itay



On Feb 26, 4:25 pm, Itay Maman  wrote:
> > What ? You used Eclipse, and still wanted to get rid of it and of clojuredev
> > ! How sad I am ... ;-)
>
> :))
>
>
>
> > I've taken a look at what you've done, wow !
>
> > How long did it take to realize that ? Were you working on it daily, or
> > nightly ?
>
> I had a couple of weeks off at Dec. Since Jan. it is mostly night-
> time.
>
>
>
> > Keep up the good work !
>
> Thanks.
--~--~-~--~~~---~--~~
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 Application Context Pattern

2009-02-27 Thread Jeffrey Straszheim
I've seen the term "skyhook" used to describe a very similar system.  In any
event, it looks cool.

On Fri, Feb 27, 2009 at 5:24 AM, linh  wrote:

>
> thanks, this will be very useful for me
>
> On 27 Feb, 09:05, Itay Maman  wrote:
> > Some of the reaction for Waterfront was related to the Application
> > Context Pattern (ACP) - The pattern that allows most of Waterfront's
> > code to be purely functional. I'll try to explain the basics in this
> > post. Let me start with the motivation: the reason why FP is at odds
> > with GUI code.
> >
> > (Pure) Functional code has no side effects, which implies immutability
> > of state. There are no fields nor global variables that can be
> > assigned to. Thus, one function can affect the computation carried out
> > by another function only by the passing of parameters. Most GUI
> > systems are built around the notion of event handlers which are
> > invoked by a message processing loop. There is no chain of calls from
> > one event handler to another.
> > In particular, if handler "A" computed some new value it cannot pass
> > it on to handler "B" because the system will call "B" only after "A"
> > returns. That's the predicament.
> >
> > ACP overcomes this by capturing the applications current state in an
> > immutable map. All event handlers receive a single parameter which is
> > the "current" context and compute the "new" context. A typical handler
> > (henceforth: "context processing function") will carry out these
> > activities: (a) Examine the current context; (b) Perform some GUI
> > operations (setSize, setText, etc.); (c) Compute a new context based
> > on the current context and on information obtained from the GUI
> > (getText, etc.). The caller (henceforth: "dispatcher") takes the
> > returned context and will use it as the new current context, the next
> > time a context processing function is invoked.
> >
> > This means that when you register event handler with a Swing widget
> > the handler needs to to call the ACP dispatcher passing it a context
> > processing function.
> >
> > The net effect of this approach is that only the dispatcher has to
> > deal with mutable state. The context processors are functional: they
> > merely compute the new state from the current.
> >
> > application-context-pattern.clj (http://groups.google.com/group/
> > clojure/web/application-context-pattern.clj) shows a concrete example.
> > It's about 140 LOC (ripped off from the real Waterfront codebase)
> > structured as follows:
> >   Lines 1..40: General-purpose helpers.
> >   Lines 40..90: The ACP infrastructure
> >   Lines 90..140: A quick sample, built around ACP.
> >
> > The sample program opens a JFrame with two buttons: Input and Output.
> > A click on the input button will pop-up an input dialog box. A click
> > on the output button will pop-up a message box showing the last value
> > entered into the input box. There's also a JLabel showing the length
> > of the input, but let's ignore it for the moment.
> >
> > The entry point into the ACP world is the bootstrap function. It takes
> > two parameters: a context processing function and an initial context.
> > In the example, this is carried out at the bottom of the run-it
> > function:
> >
> >   (defn run-it []
> > (let [build-ui (fn [ctx]
> >   (let [f (javax.swing.JFrame. "Frame")
> > b-in (javax.swing.JButton. "Input")
> > b-out (javax.swing.JButton. "Output")]
> >
> > (.addActionListener b-in (new-action-listener (fn [event]
> >   ((ctx :dispatch) get-input
> >
> > (.addActionListener b-out (new-action-listener (fn [event]
> >   ((ctx :dispatch) show-output
> >
> > (.setLayout f (java.awt.FlowLayout.))
> > (doseq [x [b-in b-out]]
> >   (.add f x) )
> >
> > (doto f
> >   (.setSize 500 300)
> >   (.setDefaultCloseOperation javax.swing.JFrame/
> > DISPOSE_ON_CLOSE)
> >   (.setVisible true))
> >
> > (assoc ctx :frame f) ))]
> >
> > (invoke-later #(bootstrap build-ui {})) ))
> >
> > invoke-later is a utility function that is mapped to SwingUtilities/
> > invokeLater.
> >
> > Let's drill down into the build-ui function: It takes the current
> > context (ctx parameter). Then it creates the frame and the buttons. It
> > uses new-action-listener (another utility) to register an action
> > listener with the buttons. The first listener looks like this:
> >   ((ctx :dispatch) get-input
> >
> > It uses (ctx :dispatch) to obtain the dispatcher from which ctx was
> > obtained, and evaluates it passing get-input as the context processing
> > function. The call to bootstrap initialized this dispatcher and added
> > the :dispatch mapping to the initial context.
> >
> > get-input looks like this:
> >   (defn- get-input [ctx]
> > (let [reply (javax.swing.JOptionPane/showInputDialog nil "Type in
> > something")]
> >   (assoc ctx :user-input reply) ))
> >
> > It pops-up an in

Re: The Application Context Pattern

2009-02-27 Thread Marko Kocić

Interesting approach, nice explained.

Does anyone have similar example using one of the cells
implementations?
What would be pros/cons between this and cells approach?

Regards,
Marko Kocić

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



Synchronous watches

2009-02-27 Thread Rich Hickey

I've added (back) synchronous watches (svn 1309+), which used to exist
for agents, now for all reference types.

(defn add-watch

  "Experimental.

  Adds a watch function to an agent/atom/var/ref reference. The watch
  fn must be a fn of 4 args: a key, the reference, its old-state, its
  new-state. Whenever the reference's state might have been changed,
  any registered watches will have their functions called. The watch
fn
  will be called synchronously, on the agent's thread if an agent,
  before any pending sends if agent or ref. Note that an atom's or
  ref's state may have changed again prior to the fn call, so use
  old-state rather than derefing the reference. Note also that watch
fns
  may be called from multiple threads simultaneously. Var watchers are
  triggered only by root binding changes, not thread-local set!s"

 [reference key fn] ...)

(defn remove-watch [reference key]...)

I've left in add/remove-watcher for now, in order to avoid disruption.
It is defined in terms of add-watch, demonstrating add-watch is the
more flexible core function. My plan is to remove add-watcher/remove-
watcher, since you can build your own such variants.

Highlights are:

- Deterministic times when callbacks will occur.

- Provision of before/after state - you determine what constitutes an
interesting change.

- Arbitrary key will be passed back to callback.

Please try them out for your latest Cells-like and other reactive
programs. I'd like to move this out of the experimental category.

Feedback and questions welcome,

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: Synchronous watches

2009-02-27 Thread Laurent PETIT
Rich,

I know I could search through clojure source code for this question (and
that this question is not totally related to the current thread), but could
you please tell me if there is a possibility to watch for additions/removals
of vars to a namespace, and additions/removals of namespaces to the "global
set of namespaces".

What I would like to do is being able to maintain, dynamically, a dependency
graph of the files in a project and what they are really doing (thus
correctly handling cases difficult or not possible at all to do via static
analysis such as macros defining vars, multiple ns created per file, ns
decomposed in multiple files ...). And I guess having the above mentioned
facility would help for this.

Are namespaces & global set of namespaces "watchable" things ?

Thanks in advance,

-- 
Laurent

2009/2/27 Rich Hickey 

>
> I've added (back) synchronous watches (svn 1309+), which used to exist
> for agents, now for all reference types.
>
> (defn add-watch
>
>  "Experimental.
>
>  Adds a watch function to an agent/atom/var/ref reference. The watch
>  fn must be a fn of 4 args: a key, the reference, its old-state, its
>  new-state. Whenever the reference's state might have been changed,
>  any registered watches will have their functions called. The watch
> fn
>  will be called synchronously, on the agent's thread if an agent,
>  before any pending sends if agent or ref. Note that an atom's or
>  ref's state may have changed again prior to the fn call, so use
>  old-state rather than derefing the reference. Note also that watch
> fns
>  may be called from multiple threads simultaneously. Var watchers are
>  triggered only by root binding changes, not thread-local set!s"
>
>  [reference key fn] ...)
>
> (defn remove-watch [reference key]...)
>
> I've left in add/remove-watcher for now, in order to avoid disruption.
> It is defined in terms of add-watch, demonstrating add-watch is the
> more flexible core function. My plan is to remove add-watcher/remove-
> watcher, since you can build your own such variants.
>
> Highlights are:
>
> - Deterministic times when callbacks will occur.
>
> - Provision of before/after state - you determine what constitutes an
> interesting change.
>
> - Arbitrary key will be passed back to callback.
>
> Please try them out for your latest Cells-like and other reactive
> programs. I'd like to move this out of the experimental category.
>
> Feedback and questions welcome,
>
> 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: Please take mercy on us newbies

2009-02-27 Thread James Reeves

Just to expand on Meikel's answer: when people upload files, it's
usually as an attachment to an existing thread. Reading though the
file list isn't a very good way of learning Clojure, as it's just a
flat list of every file anyone has ever uploaded to the group. Without
the context of the original thread, the files are naturally not going
to make a lot of sense when studied in isolation.

- James

On Feb 27, 9:50 am, Meikel Brandmeyer  wrote:
> Hi,
>
> Am 27.02.2009 um 10:41 schrieb timc:
>
> > OK - choosing files at random:
>
> > Is it at all obvious what these do?
>
> > app.clj
> > application-context-patter.clj
> > binary-structure.clj
> > bookmark-tut.clj
> > bsptree.clj
> > chlam-clean-clj
>
> > and so on...
>
> I guess for almost all of these files there is a thread
> in the group discussing their content. Or at least
> giving some context. I recommend that you search
> the group archives for the filename and you will
> digg out quite some information.
>
> Sincerely
> Meikel
>
>  smime.p7s
> 5KViewDownload
--~--~-~--~~~---~--~~
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: Synchronous watches

2009-02-27 Thread Rich Hickey



On Feb 27, 10:13 am, Laurent PETIT  wrote:
> Rich,
>
> I know I could search through clojure source code for this question (and
> that this question is not totally related to the current thread), but could
> you please tell me if there is a possibility to watch for additions/removals
> of vars to a namespace, and additions/removals of namespaces to the "global
> set of namespaces".
>
> What I would like to do is being able to maintain, dynamically, a dependency
> graph of the files in a project and what they are really doing (thus
> correctly handling cases difficult or not possible at all to do via static
> analysis such as macros defining vars, multiple ns created per file, ns
> decomposed in multiple files ...). And I guess having the above mentioned
> facility would help for this.
>
> Are namespaces & global set of namespaces "watchable" things ?
>

No they are not.

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: Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)

2009-02-27 Thread Marko Kocić

Nice work.

I have a couple of (mostly cosmetic but important suggestions):
- Set look and feel to NativeLookAndFeel
- Allow user to increase application fonts, not just editor fonts.

Regards,
Marko Kocić

--~--~-~--~~~---~--~~
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: Please take mercy on us newbies

2009-02-27 Thread Chouser

On Fri, Feb 27, 2009 at 10:14 AM, James Reeves
 wrote:
>
> Just to expand on Meikel's answer: when people upload files, it's
> usually as an attachment to an existing thread. Reading though the
> file list isn't a very good way of learning Clojure, as it's just a
> flat list of every file anyone has ever uploaded to the group. Without
> the context of the original thread, the files are naturally not going
> to make a lot of sense when studied in isolation.

It may also be worth noting that the code in the files section of this
group isn't vetted in any way.  Some may be meant for real world use
while other files may be examples of a problem or be in error.  Just
about anyone can upload a file for just about any purpose.

If you're looking for example code to help you learn clojure, there
are many better options.

The first that comes to mind is the several wikis -- the official
wikibook link from clojure.org, a tutorial wiki, a wiki attempting to
show an example of every function in clojure.core, and the clojure
projecteuler wiki.  All of these contain working examples with
specific goals, and several of them have lots of English text
describing what's going on.

Another good place to look is in clojure-contrib.  Code submitted
there goes through a minimal vetting process and is actively
maintained by people who take the time to stay current on Clojure's
growing feature set.

Hope that helps,
--Chouser

--~--~-~--~~~---~--~~
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: Clojure plugin for IntelliJ IDEA published

2009-02-27 Thread AndrewC.



On Feb 26, 7:08 pm, CuppoJava  wrote:
> Hello Ilya,
> Thanks for the workaround.
>
> I'm glad to hear you're working on a "surround with" feature. Some
> other parenthesis commands that I most commonly use is:
>   1) Delete next Sexp.
>   2) Splice Sexp. (Remove the parenthesis around the current sexp).
>   3) Move cursor to next/previous sexp.

Don't forget Barf and Slurp!

Barf - eject an Sexp from this Sexp (front and back):

(a b c) -> (a b) c
(a b c) -> a (b c)

Slurp - incorporate an Sexp into this Sexp (front and back):

(a b) c -> (a b c)
a (b c) -> (a b c)

Also copy this sexp, cut this sexp.

All vital!



--~--~-~--~~~---~--~~
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: Synchronous watches

2009-02-27 Thread Anand Patil

Hi Rich,

On Feb 27, 2:57 pm, Rich Hickey  wrote:
> I've added (back) synchronous watches (svn 1309+), which used to exist
> for agents, now for all reference types.
>
> (defn add-watch
>
>   "Experimental.
>
>   Adds a watch function to an agent/atom/var/ref reference. The watch
>   fn must be a fn of 4 args: a key, the reference, its old-state, its
>   new-state.

Could you say more about the key? Who gets to decide what it is, and
what does it mean?

Thanks,
Anand
--~--~-~--~~~---~--~~
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: Synchronous watches

2009-02-27 Thread Anand Patil

Never mind, I get it now.

Thanks,
Anand

On Feb 27, 4:32 pm, Anand Patil 
wrote:
> Hi Rich,
>
> On Feb 27, 2:57 pm, Rich Hickey  wrote:
>
> > I've added (back) synchronous watches (svn 1309+), which used to exist
> > for agents, now for all reference types.
>
> > (defn add-watch
>
> >   "Experimental.
>
> >   Adds a watch function to an agent/atom/var/ref reference. The watch
> >   fn must be a fn of 4 args: a key, the reference, its old-state, its
> >   new-state.
>
> Could you say more about the key? Who gets to decide what it is, and
> what does it mean?
>
> Thanks,
> Anand
--~--~-~--~~~---~--~~
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: Please help me get rid of my mutable code.

2009-02-27 Thread CuppoJava

Thanks very much Itay,
I'm reading through your post very carefully. I sounds like it's the
answer to all my problems.
  -Patrick
--~--~-~--~~~---~--~~
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: Mathy operations on non-numerics

2009-02-27 Thread Phil Hagelberg

Christian Vest Hansen  writes:

>> Are you referring to using <, >, =, with objects that implement
>> java.lang.Comparable?
>>
>> i.e. given x.compareTo(y) == -1
>> (< x y)
>> => true
>>
>> I would find that useful.
>
> I think having <, >, <=, >= be based on Comparable has been discussed before.
>
> And the conclusion was that it was a bad idea, because in Java:
>
> user=> (.compareTo (Integer. "10") (Long. "10"))
> java.lang.ClassCastException: java.lang.Long cannot be cast to
> java.lang.Integer (NO_SOURCE_FILE:0)
>
> And:
>
> user=> (.equals (Integer. "10") (Long. "10"))
> false

Curses, Java! Foiled again.

> Given these consequences, I think the current behavior is the best compromise.

Agreed. Am curious as to what the idiomatic way to check to see if one
string is alphabetically greater than another is though.

-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: Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)

2009-02-27 Thread Itay Maman



On Feb 27, 5:22 pm, Marko Kocić  wrote:
> Nice work.
>
> I have a couple of (mostly cosmetic but important suggestions):
> - Set look and feel to NativeLookAndFeel

I'm not sure I understand. Are you referring to
UIManager.getSystemLookAndFeelClassName() ?
This is the L&F that Waterfront is using. If you don't get this L&F
then perhaps the call to setLookAndFeel() fails on your machine. I'll
add a piece of code to log the exception.

-Itay


> - Allow user to increase application fonts, not just editor fonts.
>
> Regards,
> Marko Kocić
--~--~-~--~~~---~--~~
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: Please take mercy on us newbies

2009-02-27 Thread timc

Thanks for the responses - very helpful.

On Feb 27, 3:24 pm, Chouser  wrote:
> On Fri, Feb 27, 2009 at 10:14 AM, James Reeves
>
>  wrote:
>
> > Just to expand on Meikel's answer: when people upload files, it's
> > usually as an attachment to an existing thread. Reading though the
> > file list isn't a very good way of learning Clojure, as it's just a
> > flat list of every file anyone has ever uploaded to the group. Without
> > the context of the original thread, the files are naturally not going
> > to make a lot of sense when studied in isolation.
>
> It may also be worth noting that the code in the files section of this
> group isn't vetted in any way.  Some may be meant for real world use
> while other files may be examples of a problem or be in error.  Just
> about anyone can upload a file for just about any purpose.
>
> If you're looking for example code to help you learn clojure, there
> are many better options.
>
> The first that comes to mind is the several wikis -- the official
> wikibook link from clojure.org, a tutorial wiki, a wiki attempting to
> show an example of every function in clojure.core, and the clojure
> projecteuler wiki.  All of these contain working examples with
> specific goals, and several of them have lots of English text
> describing what's going on.
>
> Another good place to look is in clojure-contrib.  Code submitted
> there goes through a minimal vetting process and is actively
> maintained by people who take the time to stay current on Clojure's
> growing feature set.
>
> Hope that helps,
> --Chouser
--~--~-~--~~~---~--~~
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: Mathy operations on non-numerics

2009-02-27 Thread David Nolen
What about something like:

(defn gt [str1 str2]
  (first (sort [str1 str2])))

(gt "Zoe" "Bob") ; -> "Bob"

On Fri, Feb 27, 2009 at 12:03 PM, Phil Hagelberg  wrote:

>
> Christian Vest Hansen  writes:
>
> >> Are you referring to using <, >, =, with objects that implement
> >> java.lang.Comparable?
> >>
> >> i.e. given x.compareTo(y) == -1
> >> (< x y)
> >> => true
> >>
> >> I would find that useful.
> >
> > I think having <, >, <=, >= be based on Comparable has been discussed
> before.
> >
> > And the conclusion was that it was a bad idea, because in Java:
> >
> > user=> (.compareTo (Integer. "10") (Long. "10"))
> > java.lang.ClassCastException: java.lang.Long cannot be cast to
> > java.lang.Integer (NO_SOURCE_FILE:0)
> >
> > And:
> >
> > user=> (.equals (Integer. "10") (Long. "10"))
> > false
>
> Curses, Java! Foiled again.
>
> > Given these consequences, I think the current behavior is the best
> compromise.
>
> Agreed. Am curious as to what the idiomatic way to check to see if one
> string is alphabetically greater than another is though.
>
> -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: Mathy operations on non-numerics

2009-02-27 Thread Achim Passen
Hi!

Am 27.02.2009 um 18:03 schrieb Phil Hagelberg:

> Agreed. Am curious as to what the idiomatic way to check to see if one
> string is alphabetically greater than another is though.

"compare" seems to do the right thing in most cases. You could define  
shorthands if that's too much typing:

user=> (defn << [a b] (neg? (compare a b)))
#'user/<<
user=> (defn >> [a b] (pos? (compare a b)))
#'user/>>
user=> (>> "d" "abc")
true
user=> (<< "d" "abc")
false
user=> (<< (Integer. "3") (Long. "4"))
true
user=> (>> (Integer. "3") (Long. "4"))
false

Kind regards,
achim
--~--~-~--~~~---~--~~
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: Mathy operations on non-numerics

2009-02-27 Thread Phil Hagelberg

David Nolen  writes:

> What about something like:
>
> (defn gt [str1 str2]
>   (first (sort [str1 str2])))
>
> (gt "Zoe" "Bob") ; -> "Bob"

If nothing exists yet, defining <, >, <=, and >= in str-utils might work.

-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: ANN: Preliminary Clojure Support in Buildr

2009-02-27 Thread Daniel Spiewak

I was able to repeat the problem.  I suspect that the issue is the way
in which GitHub is building its gems.  I think Assaf (the lead dev for
Buildr) has implemented a workaround in some of the more recent
commits, but I haven't been able to merge with his master so I really
couldn't say.

For the moment, the solution is to just clone the git repository and
build using rake.  If you were able to get djspiewak-buildr to install
(as you did), then you should be able to just run the following:

  sudo gem uninstall djspiewak-buildr
  git clone g...@github.com:djspiewak/buildr.git
  cd buildr
  rake install

Note that there is no need to run rake under sudo, the install task
will handle that for you.

Daniel

On Feb 26, 7:59 pm, Daniel Spiewak  wrote:
> Crud.  I suspect this is something weird with the way that the GitHib
> gem server works.  I'll try to repeat the problem on Ubuntu as soon as
> I get back to my computer.  In the meantime, you could try these
> commands:
>
>   sudo gem uninstall djspiewak-buildr
>   sudo gem install djspiewak-buildr
>
> Daniel
>
> On Feb 26, 3:59 pm, Christian Vest Hansen 
> wrote:
>
> > rowe:~$ buildr --version
> > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
> > `gem_original_require': no such file to load -- buildr (LoadError)
> >         from 
> > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
> > `require'
> >         from 
> > /opt/local/lib/ruby/gems/1.8/gems/djspiewak-buildr-1.3.4/bin/buildr:18
> >         from /opt/local/bin/buildr:19:in `load'
> >         from /opt/local/bin/buildr:19
> > rowe:~$ gem --version
> > 1.3.1
> > rowe:~$
>
> > On Thu, Feb 26, 2009 at 10:30 PM, Daniel Spiewak  
> > wrote:
>
> > > I'm not sure what the File not found thing is all about, but you
> > > should still be ok (crazy gems).  Try the following:
>
> > >  buildr --version
>
> > > Daniel
>
> > > On Feb 26, 3:16 pm, Christian Vest Hansen 
> > > wrote:
> > >> On Thu, Feb 26, 2009 at 6:17 PM, Daniel Spiewak  
> > >> wrote:
>
> > >> > Odd.  Must be a problem with RubyForge.  If you try again, does it
> > >> > work?
>
> > >> I tried again at home and got quite a bit further. Maybe it was just a
> > >> hiccup at rubyforge.
>
> > >> However, I still see some questionable things in the output, and I
> > >> have yet to actually try it out (this is the first time I'm trying out
> > >> buildr). Here in verbatim:
>
> > >> rowe:~$ sudo gem install djspiewak-buildr
> > >> Building native extensions.  This could take a while...
> > >> Successfully installed builder-2.1.2
> > >> Successfully installed net-ssh-2.0.4
> > >> Successfully installed net-sftp-2.0.1
> > >> Successfully installed rubyzip-0.9.1
> > >> Successfully installed highline-1.5.0
> > >> Successfully installed rubyforge-1.0.1
> > >> Successfully installed hoe-1.7.0
> > >> Successfully installed rjb-1.1.6
> > >> Successfully installed Antwrap-0.7.0
> > >> Successfully installed rspec-1.1.4
> > >> Successfully installed xml-simple-1.0.11
> > >> Successfully installed archive-tar-minitar-0.5.2
> > >> Successfully installed djspiewak-buildr-1.3.4
> > >> 13 gems installed
> > >> Installing ri documentation for builder-2.1.2...
> > >> ERROR:  While generating documentation for builder-2.1.2
> > >> ... MESSAGE:   Unhandled special: Special: type=17, text=""
> > >> ... RDOC args: --ri --op
> > >> /opt/local/lib/ruby/gems/1.8/doc/builder-2.1.2/ri --title Builder --
> > >> Easy XML Building --main README --line-numbers --quiet lib CHANGES
> > >> Rakefile README doc/releases/builder-1.2.4.rdoc
> > >> doc/releases/builder-2.0.0.rdoc doc/releases/builder-2.1.1.rdoc
> > >> (continuing with the rest of the installation)
> > >> Installing ri documentation for net-ssh-2.0.4...
> > >> Installing ri documentation for net-sftp-2.0.1...
> > >> Installing ri documentation for highline-1.5.0...
> > >> Installing ri documentation for rubyforge-1.0.1...
> > >> Installing ri documentation for hoe-1.7.0...
> > >> Installing ri documentation for Antwrap-0.7.0...
> > >> Installing ri documentation for rspec-1.1.4...
> > >> Installing ri documentation for archive-tar-minitar-0.5.2...
> > >> Installing ri documentation for djspiewak-buildr-1.3.4...
> > >> File not found: lib
> > >> rowe:~$ ruby --version
> > >> ruby1.8.7(2008-08-11 patchlevel 72) [i686-darwin8]
> > >> rowe:~$
>
> > >> A failure to generate the docs I can live with, but that "File not
> > >> found" line looks pretty suspect.
>
> > >> > Daniel
>
> > >> > On Feb 26, 10:58 am, Christian Vest Hansen 
> > >> > wrote:
> > >> >> Nice initiative!
>
> > >> >> However, it the net-ssh dependency has problems:
>
> > >> >> [cvh: ~]$ sudo gem install djspiewak-buildr
> > >> >> ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
> > >> >>     timed out (http://gems.rubyforge.org/gems/net-ssh-2.0.4.gem)
>
> > >> >> On Sat, Feb 21, 2009 at 10:33 PM, Daniel Spiewak 
> > >> >>  wrote:
>
> > >> >> > I'm pleased to announce preliminary (and very experimental) sup

Re: ANN: Preliminary Clojure Support in Buildr

2009-02-27 Thread Daniel Spiewak

Correction:

  git clone git://github.com:djspiewak/buildr.git

Daniel

On Feb 27, 11:44 am, Daniel Spiewak  wrote:
> I was able to repeat the problem.  I suspect that the issue is the way
> in which GitHub is building its gems.  I think Assaf (the lead dev for
> Buildr) has implemented a workaround in some of the more recent
> commits, but I haven't been able to merge with his master so I really
> couldn't say.
>
> For the moment, the solution is to just clone the git repository and
> build using rake.  If you were able to get djspiewak-buildr to install
> (as you did), then you should be able to just run the following:
>
>   sudo gem uninstall djspiewak-buildr
>   git clone g...@github.com:djspiewak/buildr.git
>   cd buildr
>   rake install
>
> Note that there is no need to run rake under sudo, the install task
> will handle that for you.
>
> Daniel
>
> On Feb 26, 7:59 pm, Daniel Spiewak  wrote:
>
> > Crud.  I suspect this is something weird with the way that the GitHib
> > gem server works.  I'll try to repeat the problem on Ubuntu as soon as
> > I get back to my computer.  In the meantime, you could try these
> > commands:
>
> >   sudo gem uninstall djspiewak-buildr
> >   sudo gem install djspiewak-buildr
>
> > Daniel
>
> > On Feb 26, 3:59 pm, Christian Vest Hansen 
> > wrote:
>
> > > rowe:~$ buildr --version
> > > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
> > > `gem_original_require': no such file to load -- buildr (LoadError)
> > >         from 
> > > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
> > > `require'
> > >         from 
> > > /opt/local/lib/ruby/gems/1.8/gems/djspiewak-buildr-1.3.4/bin/buildr:18
> > >         from /opt/local/bin/buildr:19:in `load'
> > >         from /opt/local/bin/buildr:19
> > > rowe:~$ gem --version
> > > 1.3.1
> > > rowe:~$
>
> > > On Thu, Feb 26, 2009 at 10:30 PM, Daniel Spiewak  
> > > wrote:
>
> > > > I'm not sure what the File not found thing is all about, but you
> > > > should still be ok (crazy gems).  Try the following:
>
> > > >  buildr --version
>
> > > > Daniel
>
> > > > On Feb 26, 3:16 pm, Christian Vest Hansen 
> > > > wrote:
> > > >> On Thu, Feb 26, 2009 at 6:17 PM, Daniel Spiewak  
> > > >> wrote:
>
> > > >> > Odd.  Must be a problem with RubyForge.  If you try again, does it
> > > >> > work?
>
> > > >> I tried again at home and got quite a bit further. Maybe it was just a
> > > >> hiccup at rubyforge.
>
> > > >> However, I still see some questionable things in the output, and I
> > > >> have yet to actually try it out (this is the first time I'm trying out
> > > >> buildr). Here in verbatim:
>
> > > >> rowe:~$ sudo gem install djspiewak-buildr
> > > >> Building native extensions.  This could take a while...
> > > >> Successfully installed builder-2.1.2
> > > >> Successfully installed net-ssh-2.0.4
> > > >> Successfully installed net-sftp-2.0.1
> > > >> Successfully installed rubyzip-0.9.1
> > > >> Successfully installed highline-1.5.0
> > > >> Successfully installed rubyforge-1.0.1
> > > >> Successfully installed hoe-1.7.0
> > > >> Successfully installed rjb-1.1.6
> > > >> Successfully installed Antwrap-0.7.0
> > > >> Successfully installed rspec-1.1.4
> > > >> Successfully installed xml-simple-1.0.11
> > > >> Successfully installed archive-tar-minitar-0.5.2
> > > >> Successfully installed djspiewak-buildr-1.3.4
> > > >> 13 gems installed
> > > >> Installing ri documentation for builder-2.1.2...
> > > >> ERROR:  While generating documentation for builder-2.1.2
> > > >> ... MESSAGE:   Unhandled special: Special: type=17, text=""
> > > >> ... RDOC args: --ri --op
> > > >> /opt/local/lib/ruby/gems/1.8/doc/builder-2.1.2/ri --title Builder --
> > > >> Easy XML Building --main README --line-numbers --quiet lib CHANGES
> > > >> Rakefile README doc/releases/builder-1.2.4.rdoc
> > > >> doc/releases/builder-2.0.0.rdoc doc/releases/builder-2.1.1.rdoc
> > > >> (continuing with the rest of the installation)
> > > >> Installing ri documentation for net-ssh-2.0.4...
> > > >> Installing ri documentation for net-sftp-2.0.1...
> > > >> Installing ri documentation for highline-1.5.0...
> > > >> Installing ri documentation for rubyforge-1.0.1...
> > > >> Installing ri documentation for hoe-1.7.0...
> > > >> Installing ri documentation for Antwrap-0.7.0...
> > > >> Installing ri documentation for rspec-1.1.4...
> > > >> Installing ri documentation for archive-tar-minitar-0.5.2...
> > > >> Installing ri documentation for djspiewak-buildr-1.3.4...
> > > >> File not found: lib
> > > >> rowe:~$ ruby --version
> > > >> ruby1.8.7(2008-08-11 patchlevel 72) [i686-darwin8]
> > > >> rowe:~$
>
> > > >> A failure to generate the docs I can live with, but that "File not
> > > >> found" line looks pretty suspect.
>
> > > >> > Daniel
>
> > > >> > On Feb 26, 10:58 am, Christian Vest Hansen 
> > > >> > wrote:
> > > >> >> Nice initiative!
>
> > > >> >> However, it the net-ssh dependency has problems:
>
> > > >> >> [cvh: ~]$ sudo gem install

Re: The Application Context Pattern

2009-02-27 Thread Andy Chambers

2009/2/27 Marko Kocić :
>
> Interesting approach, nice explained.
>
> Does anyone have similar example using one of the cells
> implementations?
> What would be pros/cons between this and cells approach?

The cells implementations I've seen posted to this list (in fact pretty much all
cells reimplementations) haven't yet approached the sophistication of
kenny-cells.

It's like editors.  Everyone reckons they can make one better than emacs (or
vi) but underestimate the man-hours that have gone into them over the years
and end up with something that maybe looks as good (or better) superficially
but when you delve into the details, just doesn't cut the mustard.

I'd love to see some kind of clojure-cells but it's still a long way off.

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



Opinions on -> macro? (was Re: Extensive use of let?)

2009-02-27 Thread John D. Hume

On Wed, Feb 25, 2009 at 4:11 PM, Jason Wolfe  wrote:
> (you'll get use to reading inside-out quickly).

As a Java/Ruby guy who is not used to reading inside out, I'm curious
as to whether people who ARE accustomed to LISP find the -> macro
distracting since it flops things around. Are there circumstances
where you prefer it?

--~--~-~--~~~---~--~~
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 Application Context Pattern

2009-02-27 Thread Stuart Sierra

On Feb 27, 12:59 pm, Andy Chambers 
wrote:
> The cells implementations I've seen posted to this list (in fact pretty much 
> all
> cells reimplementations) haven't yet approached the sophistication of
> kenny-cells.

Agreed.  And I wrote two of them.  They're just toy implementations so
far.

-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: Opinions on -> macro?

2009-02-27 Thread Meikel Brandmeyer

Hi,

Am 27.02.2009 um 19:39 schrieb John D. Hume:


As a Java/Ruby guy who is not used to reading inside out, I'm curious
as to whether people who ARE accustomed to LISP find the -> macro
distracting since it flops things around. Are there circumstances
where you prefer it?


I have a Scheme background and I like -> a lot. I would prefer it
always over

  (foo (bar (baz (frobnicate a-thing)) bla)).

Eh? To which function belongs the bla argument? I think

  (-> a-thing frobnicate baz (bar bla) foo)

is much clearer.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Opinions on -> macro? (was Re: Extensive use of let?)

2009-02-27 Thread James Reeves

On Feb 27, 6:39 pm, "John D. Hume"  wrote:
> As a Java/Ruby guy who is not used to reading inside out, I'm curious
> as to whether people who ARE accustomed to LISP find the -> macro
> distracting since it flops things around. Are there circumstances
> where you prefer it?

It's pretty useful for nested keywords:

  (:name (:profile (:user message)))

  (-> message :user :profile :name)

- James
--~--~-~--~~~---~--~~
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: Opinions on -> macro? (was Re: Extensive use of let?)

2009-02-27 Thread Allen Rohner


>
> It's pretty useful for nested keywords:
>
>   (:name (:profile (:user message)))
>
>   (-> message :user :profile :name)
>
> - James

That is really cool. Once again the language and the community impress
me with how elegant the language is.

Allen

--~--~-~--~~~---~--~~
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 + Terracotta = Yeah, Baby!

2009-02-27 Thread Paul Stadig

I've recently done some experimentation with Clojure and Terracotta.
I've detailed my experience at:

http://paul.stadig.name/2009/02/clojure-terracotta-yeah-baby.html

and shared my code at:

http://github.com/pjstadig/terraclojure/tree/master/

I'm the first to admit that I'm not an expert in Terracotta. This is
actually my first time working with it.

I was able to setup a permanent store, and to run a couple of
transactions against some refs shared across multiple JVMs. I ran into
two snags. The first was that Keyword did not implement hashCode,
which was a simple fix. Rich graciously added a hashCode method. :)

The other was how to point Terracotta to a var from the Java side. I
ended up using a simple Java class to hold on to my refs, since then
it was easy to point Terracotta to the right place. It works just
fine, but I'm not sure if there is a better way to do it.

I'd be interested in knowing if anyone else has experience to share
about using Terracotta with Clojure.


Paul Stadig

--~--~-~--~~~---~--~~
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: ANN: Preliminary Clojure Support in Buildr

2009-02-27 Thread Christian Vest Hansen

On Fri, Feb 27, 2009 at 6:47 PM, Daniel Spiewak  wrote:
>
> Correction:
>
>  git clone git://github.com:djspiewak/buildr.git
git clone git://github.com/djspiewak/buildr.git

Excellent. Got it installed.

>
> Daniel
>
> On Feb 27, 11:44 am, Daniel Spiewak  wrote:
>> I was able to repeat the problem.  I suspect that the issue is the way
>> in which GitHub is building its gems.  I think Assaf (the lead dev for
>> Buildr) has implemented a workaround in some of the more recent
>> commits, but I haven't been able to merge with his master so I really
>> couldn't say.
>>
>> For the moment, the solution is to just clone the git repository and
>> build using rake.  If you were able to get djspiewak-buildr to install
>> (as you did), then you should be able to just run the following:
>>
>>   sudo gem uninstall djspiewak-buildr
>>   git clone g...@github.com:djspiewak/buildr.git
>>   cd buildr
>>   rake install
>>
>> Note that there is no need to run rake under sudo, the install task
>> will handle that for you.
>>
>> Daniel
>>
>> On Feb 26, 7:59 pm, Daniel Spiewak  wrote:
>>
>> > Crud.  I suspect this is something weird with the way that the GitHib
>> > gem server works.  I'll try to repeat the problem on Ubuntu as soon as
>> > I get back to my computer.  In the meantime, you could try these
>> > commands:
>>
>> >   sudo gem uninstall djspiewak-buildr
>> >   sudo gem install djspiewak-buildr
>>
>> > Daniel
>>
>> > On Feb 26, 3:59 pm, Christian Vest Hansen 
>> > wrote:
>>
>> > > rowe:~$ buildr --version
>> > > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
>> > > `gem_original_require': no such file to load -- buildr (LoadError)
>> > >         from 
>> > > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
>> > > `require'
>> > >         from 
>> > > /opt/local/lib/ruby/gems/1.8/gems/djspiewak-buildr-1.3.4/bin/buildr:18
>> > >         from /opt/local/bin/buildr:19:in `load'
>> > >         from /opt/local/bin/buildr:19
>> > > rowe:~$ gem --version
>> > > 1.3.1
>> > > rowe:~$
>>
>> > > On Thu, Feb 26, 2009 at 10:30 PM, Daniel Spiewak  
>> > > wrote:
>>
>> > > > I'm not sure what the File not found thing is all about, but you
>> > > > should still be ok (crazy gems).  Try the following:
>>
>> > > >  buildr --version
>>
>> > > > Daniel
>>
>> > > > On Feb 26, 3:16 pm, Christian Vest Hansen 
>> > > > wrote:
>> > > >> On Thu, Feb 26, 2009 at 6:17 PM, Daniel Spiewak  
>> > > >> wrote:
>>
>> > > >> > Odd.  Must be a problem with RubyForge.  If you try again, does it
>> > > >> > work?
>>
>> > > >> I tried again at home and got quite a bit further. Maybe it was just a
>> > > >> hiccup at rubyforge.
>>
>> > > >> However, I still see some questionable things in the output, and I
>> > > >> have yet to actually try it out (this is the first time I'm trying out
>> > > >> buildr). Here in verbatim:
>>
>> > > >> rowe:~$ sudo gem install djspiewak-buildr
>> > > >> Building native extensions.  This could take a while...
>> > > >> Successfully installed builder-2.1.2
>> > > >> Successfully installed net-ssh-2.0.4
>> > > >> Successfully installed net-sftp-2.0.1
>> > > >> Successfully installed rubyzip-0.9.1
>> > > >> Successfully installed highline-1.5.0
>> > > >> Successfully installed rubyforge-1.0.1
>> > > >> Successfully installed hoe-1.7.0
>> > > >> Successfully installed rjb-1.1.6
>> > > >> Successfully installed Antwrap-0.7.0
>> > > >> Successfully installed rspec-1.1.4
>> > > >> Successfully installed xml-simple-1.0.11
>> > > >> Successfully installed archive-tar-minitar-0.5.2
>> > > >> Successfully installed djspiewak-buildr-1.3.4
>> > > >> 13 gems installed
>> > > >> Installing ri documentation for builder-2.1.2...
>> > > >> ERROR:  While generating documentation for builder-2.1.2
>> > > >> ... MESSAGE:   Unhandled special: Special: type=17, text=""
>> > > >> ... RDOC args: --ri --op
>> > > >> /opt/local/lib/ruby/gems/1.8/doc/builder-2.1.2/ri --title Builder --
>> > > >> Easy XML Building --main README --line-numbers --quiet lib CHANGES
>> > > >> Rakefile README doc/releases/builder-1.2.4.rdoc
>> > > >> doc/releases/builder-2.0.0.rdoc doc/releases/builder-2.1.1.rdoc
>> > > >> (continuing with the rest of the installation)
>> > > >> Installing ri documentation for net-ssh-2.0.4...
>> > > >> Installing ri documentation for net-sftp-2.0.1...
>> > > >> Installing ri documentation for highline-1.5.0...
>> > > >> Installing ri documentation for rubyforge-1.0.1...
>> > > >> Installing ri documentation for hoe-1.7.0...
>> > > >> Installing ri documentation for Antwrap-0.7.0...
>> > > >> Installing ri documentation for rspec-1.1.4...
>> > > >> Installing ri documentation for archive-tar-minitar-0.5.2...
>> > > >> Installing ri documentation for djspiewak-buildr-1.3.4...
>> > > >> File not found: lib
>> > > >> rowe:~$ ruby --version
>> > > >> ruby1.8.7(2008-08-11 patchlevel 72) [i686-darwin8]
>> > > >> rowe:~$
>>
>> > > >> A failure to generate the docs I can live with, but that "File not
>> > > >>

Re: The Application Context Pattern

2009-02-27 Thread Marko Kocić

> > The cells implementations I've seen posted to this list (in fact pretty 
> > much all
> > cells reimplementations) haven't yet approached the sophistication of
> > kenny-cells.
>
> Agreed.  And I wrote two of them.  They're just toy implementations so
> far.

I'm still not sure how it should look like given clojure immutablility.
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Getting substrings with negative indices

2009-02-27 Thread Phil Hagelberg


It's a pretty common idiom in other languages for substring functions to
count from the end if given a negative index.

  (substring "hello world!" 6 -1) ;; => "world"

I'd be glad if Clojure's "subs" function could work like this. Should I
create an issue and patch to implement it?

-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: Clojure + Terracotta = Yeah, Baby!

2009-02-27 Thread Luc Prefontaine
We are trying to get Clojure shared over Terracotta, not just specific
things but the whole Clojure object space
(name spaces, root values, ) except stuff that needs to remain local
(streams, ).

We take an all or nothing approach here, we would to see many Clojure
instances work as a single
entity.

We are facing a number of issues, one of them being the lack of support
by Terracotta of AtomicReference.

Terracotta has placed this class in the list of classes they will
eventually support but has of 2.7.3
it's still not supported.

The Sun AtomicReference does peeks and pokes in the heap using internal
routines of the JVM (JNI).
Clearly this cannot be done with multiple JVMs, different object
heaps, 

Terracotta suggest using the oswego library but since Java 5 has been
out, it's in maintenance mode only and 
integrating another library to the puzzle for that single purpose did
not look to us as very efficient.

So we created a SharedAtomicReference implementation that uses standard
locks to control access to
the value with the corresponding Terracotta configuration.

We use a factory to decide at run time which implementation to use based
on a system property.
To preserve the Clojure code base, we implemented an AtomicReference
interface and a delegate to
the AtomicReference class. The Clojure code uses now  interface. 
This allows us to make progress without disturbing the Clojure code base
too much.

This has some performance implications that we do not fully understand
yet since we need a living Clojure implementation
to work with, something we are in the process of creating... what a
catch 22 :)))
We thought about spending time working on this aspect right now but we
prefer to wait for the first alpha release.

As for the rest of the Clojure code, we are working on the classes
implementing vectors, hash maps, 
to get them shared through terracotta.

Our main challenge these days is putting together the terracotta
configuration of the internal classes of Clojure that need to be shared.

We may hit issues that make some classes non portable. 
These will require us to implement an alternative.  We will use then a
slightly different approach,
we need only factories to allocate an alternate version or the "local"
implementation.
The Clojure code already uses interfaces to access the data objects so
this will be almost transparent in the code.

We prefer to re implement an "distributed" implementation side by side
with the original one and easily switch between them
to compare behaviour and performance with the same code base.

When we have a clearer understanding of how it performs we will look at
how to merge this in the code base
that will have changed in between. We may be able then to reduce the
number of alternate implementations
if more where created.

The work is in progress, next week is a school break week here so the
pace will slow down a bit.
We wanted to start earlier on this (before XMas) but we had updates to
put in production , client caring to do, ...
and other mundane tasks to get the bread and butter on the table.

Comments/suggestions are welcomed...

Luc


On Fri, 2009-02-27 at 12:20 -0800, Paul Stadig wrote:

> I've recently done some experimentation with Clojure and Terracotta.
> I've detailed my experience at:
> 
> http://paul.stadig.name/2009/02/clojure-terracotta-yeah-baby.html
> 
> and shared my code at:
> 
> http://github.com/pjstadig/terraclojure/tree/master/
> 
> I'm the first to admit that I'm not an expert in Terracotta. This is
> actually my first time working with it.
> 
> I was able to setup a permanent store, and to run a couple of
> transactions against some refs shared across multiple JVMs. I ran into
> two snags. The first was that Keyword did not implement hashCode,
> which was a simple fix. Rich graciously added a hashCode method. :)
> 
> The other was how to point Terracotta to a var from the Java side. I
> ended up using a simple Java class to hold on to my refs, since then
> it was easy to point Terracotta to the right place. It works just
> fine, but I'm not sure if there is a better way to do it.
> 
> I'd be interested in knowing if anyone else has experience to share
> about using Terracotta with Clojure.
> 
> 
> Paul Stadig
> 
> > 
> 

-- 

Luc Préfontaine

Off.:(514) 993-0320
Fax.:(514) 993-0325

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: Clojure + Terracotta = Yeah, Baby!

2009-02-27 Thread Phil Hagelberg

Paul Stadig  writes:

> I've recently done some experimentation with Clojure and Terracotta.
> I've detailed my experience at:
>
> http://paul.stadig.name/2009/02/clojure-terracotta-yeah-baby.html

Very exciting; I'm looking forward to trying this out! Thanks for posting.

-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: Clojure + Terracotta = Yeah, Baby!

2009-02-27 Thread Paul Stadig

Yeah, after sharing clojure.lang.Keyword.table I tried to share
clojure.lang.Namespace.namespaces, but ran into a problem because
Namespace uses an AtomicReference for its mappings and aliases
members. I thought that not sharing namespaces would be a problem (and
maybe it still is I don't have as much practical experience with this
as you), but I wasn't sure it would be a problem. Looking up a var in
a namespace on different JVMs would find different vars, but since
they are thread local, then I'm not sure its an issue. Having all of
your refs shared without having to specify each specific ref would be
interesting, but since most of the stuff (functions, vars, etc.) are
immutable or thread local, then I'm not sure how much of an issue it
is.

Obviously, if you were going to redefine some functions or something,
then you'd either have to do so on each JVM, or just restart all of
the clients.

And as I said in my article, I didn't do any work with agents, so
maybe there's a lot missing from my part of the puzzle.


Paul

On Fri, Feb 27, 2009 at 4:37 PM, Luc Prefontaine
 wrote:
> We are trying to get Clojure shared over Terracotta, not just specific
> things but the whole Clojure object space
> (name spaces, root values, ) except stuff that needs to remain local
> (streams, ).
>
> We take an all or nothing approach here, we would to see many Clojure
> instances work as a single
> entity.
>
> We are facing a number of issues, one of them being the lack of support by
> Terracotta of AtomicReference.
>
> Terracotta has placed this class in the list of classes they will eventually
> support but has of 2.7.3
> it's still not supported.
>
> The Sun AtomicReference does peeks and pokes in the heap using internal
> routines of the JVM (JNI).
> Clearly this cannot be done with multiple JVMs, different object heaps, 
>
> Terracotta suggest using the oswego library but since Java 5 has been out,
> it's in maintenance mode only and
> integrating another library to the puzzle for that single purpose did not
> look to us as very efficient.
>
> So we created a SharedAtomicReference implementation that uses standard
> locks to control access to
> the value with the corresponding Terracotta configuration.
>
> We use a factory to decide at run time which implementation to use based on
> a system property.
> To preserve the Clojure code base, we implemented an AtomicReference
> interface and a delegate to
> the AtomicReference class. The Clojure code uses now  interface.
> This allows us to make progress without disturbing the Clojure code base too
> much.
>
> This has some performance implications that we do not fully understand yet
> since we need a living Clojure implementation
> to work with, something we are in the process of creating... what a catch 22
> :)))
> We thought about spending time working on this aspect right now but we
> prefer to wait for the first alpha release.
>
> As for the rest of the Clojure code, we are working on the classes
> implementing vectors, hash maps, 
> to get them shared through terracotta.
>
> Our main challenge these days is putting together the terracotta
> configuration of the internal classes of Clojure that need to be shared.
>
> We may hit issues that make some classes non portable.
> These will require us to implement an alternative.  We will use then a
> slightly different approach,
> we need only factories to allocate an alternate version or the "local"
> implementation.
> The Clojure code already uses interfaces to access the data objects so this
> will be almost transparent in the code.
>
> We prefer to re implement an "distributed" implementation side by side with
> the original one and easily switch between them
> to compare behaviour and performance with the same code base.
>
> When we have a clearer understanding of how it performs we will look at how
> to merge this in the code base
> that will have changed in between. We may be able then to reduce the number
> of alternate implementations
> if more where created.
>
> The work is in progress, next week is a school break week here so the pace
> will slow down a bit.
> We wanted to start earlier on this (before XMas) but we had updates to put
> in production , client caring to do, ...
> and other mundane tasks to get the bread and butter on the table.
>
> Comments/suggestions are welcomed...
>
> Luc
>
>
> On Fri, 2009-02-27 at 12:20 -0800, Paul Stadig wrote:
>
> I've recently done some experimentation with Clojure and Terracotta.
> I've detailed my experience at:
>
> http://paul.stadig.name/2009/02/clojure-terracotta-yeah-baby.html
>
> and shared my code at:
>
> http://github.com/pjstadig/terraclojure/tree/master/
>
> I'm the first to admit that I'm not an expert in Terracotta. This is
> actually my first time working with it.
>
> I was able to setup a permanent store, and to run a couple of
> transactions against some refs shared across multiple JVMs. I ran into
> two snags. The first was that Keyword did not

Re: Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)

2009-02-27 Thread Dan

> I'm not sure I understand. Are you referring to
> UIManager.getSystemLookAndFeelClassName() ?
> This is the L&F that Waterfront is using. If you don't get this L&F
> then perhaps the call to setLookAndFeel() fails on your machine. I'll
> add a piece of code to log the exception.
>
> -Itay

It also has the ugly default swing L&F on my machine too. I'm using Linux / KDE.

--~--~-~--~~~---~--~~
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: ANN: Preliminary Clojure Support in Buildr

2009-02-27 Thread Daniel Spiewak

As an aside, "gem install djspiewak-buildr" probably works again.
I've merged Assaf's fixes, and GitHub *claims* to be building things
correctly.  So, I haven't tried it, but I can't think of a reason why
it wouldn't work.

Daniel

On Feb 27, 2:39 pm, Christian Vest Hansen 
wrote:
> On Fri, Feb 27, 2009 at 6:47 PM, Daniel Spiewak  wrote:
>
> > Correction:
>
> >  git clone git://github.com:djspiewak/buildr.git
>
> git clone git://github.com/djspiewak/buildr.git
>
> Excellent. Got it installed.
>
>
>
> > Daniel
>
> > On Feb 27, 11:44 am, Daniel Spiewak  wrote:
> >> I was able to repeat the problem.  I suspect that the issue is the way
> >> in which GitHub is building its gems.  I think Assaf (the lead dev for
> >> Buildr) has implemented a workaround in some of the more recent
> >> commits, but I haven't been able to merge with his master so I really
> >> couldn't say.
>
> >> For the moment, the solution is to just clone the git repository and
> >> build using rake.  If you were able to get djspiewak-buildr to install
> >> (as you did), then you should be able to just run the following:
>
> >>   sudo gem uninstall djspiewak-buildr
> >>   git clone g...@github.com:djspiewak/buildr.git
> >>   cd buildr
> >>   rake install
>
> >> Note that there is no need to run rake under sudo, the install task
> >> will handle that for you.
>
> >> Daniel
>
> >> On Feb 26, 7:59 pm, Daniel Spiewak  wrote:
>
> >> > Crud.  I suspect this is something weird with the way that the GitHib
> >> > gem server works.  I'll try to repeat the problem on Ubuntu as soon as
> >> > I get back to my computer.  In the meantime, you could try these
> >> > commands:
>
> >> >   sudo gem uninstall djspiewak-buildr
> >> >   sudo gem install djspiewak-buildr
>
> >> > Daniel
>
> >> > On Feb 26, 3:59 pm, Christian Vest Hansen 
> >> > wrote:
>
> >> > > rowe:~$ buildr --version
> >> > > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
> >> > > `gem_original_require': no such file to load -- buildr (LoadError)
> >> > >         from 
> >> > > /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in
> >> > > `require'
> >> > >         from 
> >> > > /opt/local/lib/ruby/gems/1.8/gems/djspiewak-buildr-1.3.4/bin/buildr:18
> >> > >         from /opt/local/bin/buildr:19:in `load'
> >> > >         from /opt/local/bin/buildr:19
> >> > > rowe:~$ gem --version
> >> > > 1.3.1
> >> > > rowe:~$
>
> >> > > On Thu, Feb 26, 2009 at 10:30 PM, Daniel Spiewak  
> >> > > wrote:
>
> >> > > > I'm not sure what the File not found thing is all about, but you
> >> > > > should still be ok (crazy gems).  Try the following:
>
> >> > > >  buildr --version
>
> >> > > > Daniel
>
> >> > > > On Feb 26, 3:16 pm, Christian Vest Hansen 
> >> > > > wrote:
> >> > > >> On Thu, Feb 26, 2009 at 6:17 PM, Daniel Spiewak 
> >> > > >>  wrote:
>
> >> > > >> > Odd.  Must be a problem with RubyForge.  If you try again, does it
> >> > > >> > work?
>
> >> > > >> I tried again at home and got quite a bit further. Maybe it was 
> >> > > >> just a
> >> > > >> hiccup at rubyforge.
>
> >> > > >> However, I still see some questionable things in the output, and I
> >> > > >> have yet to actually try it out (this is the first time I'm trying 
> >> > > >> out
> >> > > >> buildr). Here in verbatim:
>
> >> > > >> rowe:~$ sudo gem install djspiewak-buildr
> >> > > >> Building native extensions.  This could take a while...
> >> > > >> Successfully installed builder-2.1.2
> >> > > >> Successfully installed net-ssh-2.0.4
> >> > > >> Successfully installed net-sftp-2.0.1
> >> > > >> Successfully installed rubyzip-0.9.1
> >> > > >> Successfully installed highline-1.5.0
> >> > > >> Successfully installed rubyforge-1.0.1
> >> > > >> Successfully installed hoe-1.7.0
> >> > > >> Successfully installed rjb-1.1.6
> >> > > >> Successfully installed Antwrap-0.7.0
> >> > > >> Successfully installed rspec-1.1.4
> >> > > >> Successfully installed xml-simple-1.0.11
> >> > > >> Successfully installed archive-tar-minitar-0.5.2
> >> > > >> Successfully installed djspiewak-buildr-1.3.4
> >> > > >> 13 gems installed
> >> > > >> Installing ri documentation for builder-2.1.2...
> >> > > >> ERROR:  While generating documentation for builder-2.1.2
> >> > > >> ... MESSAGE:   Unhandled special: Special: type=17, text=""
> >> > > >> ... RDOC args: --ri --op
> >> > > >> /opt/local/lib/ruby/gems/1.8/doc/builder-2.1.2/ri --title Builder --
> >> > > >> Easy XML Building --main README --line-numbers --quiet lib CHANGES
> >> > > >> Rakefile README doc/releases/builder-1.2.4.rdoc
> >> > > >> doc/releases/builder-2.0.0.rdoc doc/releases/builder-2.1.1.rdoc
> >> > > >> (continuing with the rest of the installation)
> >> > > >> Installing ri documentation for net-ssh-2.0.4...
> >> > > >> Installing ri documentation for net-sftp-2.0.1...
> >> > > >> Installing ri documentation for highline-1.5.0...
> >> > > >> Installing ri documentation for rubyforge-1.0.1...
> >> > > >> Installing ri documentation for hoe-1.7.0...
> >> > 

Re: Waterfront - The Clojure-based editor for Clojure

2009-02-27 Thread zoltar

On Feb 25, 6:02 pm, "Stephen C. Gilardi"  wrote:
>
> - When using waterfront on Mac OS X, it appears that the control  
> characters intended to trigger menu selections (e.g. ^E) are being  
> intercepted before they reach the menus. In the specific case of ^E,  
> it is being interpreted by the text input field as "move to end of  
> line" which is a common meaning for it in Mac OS X. I suspect there is  
> a way to trigger menu items using the "command-key" on the Mac (while  
> still using the control key on Windows) and people using waterfront on  
> Mac OS X would benefit from a change to using that mechanism.

Indeed. Instead of hard-coding modifier keys, you should use the
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(). This will
return control for windows and META (or command) for Mac.

Curtis

--~--~-~--~~~---~--~~
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: Clojure + Terracotta = Yeah, Baby!

2009-02-27 Thread Luc Prefontaine
Having the ability to redefine a function once for all instances is
something we really want...
and you need name spaces to be shared for that to happen.
We take the approach of sharing everything that seems to worth it, then
we will see
what we might need to keep private to each JVM.

Sharing var roots and refs also is something we want so we can initiate
STM transactions 
involving  multiple JVMs.

We have much to learn from a prototype and that is what we strive to
achieve the immediate future.
After this step, real fun will begin, right now were having only an
appetizer...

Luc
 
On Fri, 2009-02-27 at 16:51 -0500, Paul Stadig wrote:

> Yeah, after sharing clojure.lang.Keyword.table I tried to share
> clojure.lang.Namespace.namespaces, but ran into a problem because
> Namespace uses an AtomicReference for its mappings and aliases
> members. I thought that not sharing namespaces would be a problem (and
> maybe it still is I don't have as much practical experience with this
> as you), but I wasn't sure it would be a problem. Looking up a var in
> a namespace on different JVMs would find different vars, but since
> they are thread local, then I'm not sure its an issue. Having all of
> your refs shared without having to specify each specific ref would be
> interesting, but since most of the stuff (functions, vars, etc.) are
> immutable or thread local, then I'm not sure how much of an issue it
> is.
> 
> Obviously, if you were going to redefine some functions or something,
> then you'd either have to do so on each JVM, or just restart all of
> the clients.
> 
> And as I said in my article, I didn't do any work with agents, so
> maybe there's a lot missing from my part of the puzzle.
> 
> 
> Paul
> 
> On Fri, Feb 27, 2009 at 4:37 PM, Luc Prefontaine
>  wrote:
> > We are trying to get Clojure shared over Terracotta, not just specific
> > things but the whole Clojure object space
> > (name spaces, root values, ) except stuff that needs to remain local
> > (streams, ).
> >
> > We take an all or nothing approach here, we would to see many Clojure
> > instances work as a single
> > entity.
> >
> > We are facing a number of issues, one of them being the lack of support by
> > Terracotta of AtomicReference.
> >
> > Terracotta has placed this class in the list of classes they will eventually
> > support but has of 2.7.3
> > it's still not supported.
> >
> > The Sun AtomicReference does peeks and pokes in the heap using internal
> > routines of the JVM (JNI).
> > Clearly this cannot be done with multiple JVMs, different object heaps, 
> >
> > Terracotta suggest using the oswego library but since Java 5 has been out,
> > it's in maintenance mode only and
> > integrating another library to the puzzle for that single purpose did not
> > look to us as very efficient.
> >
> > So we created a SharedAtomicReference implementation that uses standard
> > locks to control access to
> > the value with the corresponding Terracotta configuration.
> >
> > We use a factory to decide at run time which implementation to use based on
> > a system property.
> > To preserve the Clojure code base, we implemented an AtomicReference
> > interface and a delegate to
> > the AtomicReference class. The Clojure code uses now  interface.
> > This allows us to make progress without disturbing the Clojure code base too
> > much.
> >
> > This has some performance implications that we do not fully understand yet
> > since we need a living Clojure implementation
> > to work with, something we are in the process of creating... what a catch 22
> > :)))
> > We thought about spending time working on this aspect right now but we
> > prefer to wait for the first alpha release.
> >
> > As for the rest of the Clojure code, we are working on the classes
> > implementing vectors, hash maps, 
> > to get them shared through terracotta.
> >
> > Our main challenge these days is putting together the terracotta
> > configuration of the internal classes of Clojure that need to be shared.
> >
> > We may hit issues that make some classes non portable.
> > These will require us to implement an alternative.  We will use then a
> > slightly different approach,
> > we need only factories to allocate an alternate version or the "local"
> > implementation.
> > The Clojure code already uses interfaces to access the data objects so this
> > will be almost transparent in the code.
> >
> > We prefer to re implement an "distributed" implementation side by side with
> > the original one and easily switch between them
> > to compare behaviour and performance with the same code base.
> >
> > When we have a clearer understanding of how it performs we will look at how
> > to merge this in the code base
> > that will have changed in between. We may be able then to reduce the number
> > of alternate implementations
> > if more where created.
> >
> > The work is in progress, next week is a school break week here so the pace
> > will slow down a bit.
> > We wanted to start

Re: The Application Context Pattern

2009-02-27 Thread samppi

It looks really nice. I have a question about those observers, though--
every time that a context-processing function is called, every
observer is called one by one, no matter what the context-processing
function was. This seems somewhat inefficient, more so than listeners
that listen to only certain functions and are called when the listened
function is activated. In your experience, is this not a big problem?
Or am I missing something?

On Feb 27, 1:05 am, Itay Maman  wrote:
> Some of the reaction for Waterfront was related to the Application
> Context Pattern (ACP) - The pattern that allows most of Waterfront's
> code to be purely functional. I'll try to explain the basics in this
> post. Let me start with the motivation: the reason why FP is at odds
> with GUI code.
>
> (Pure) Functional code has no side effects, which implies immutability
> of state. There are no fields nor global variables that can be
> assigned to. Thus, one function can affect the computation carried out
> by another function only by the passing of parameters. Most GUI
> systems are built around the notion of event handlers which are
> invoked by a message processing loop. There is no chain of calls from
> one event handler to another.
> In particular, if handler "A" computed some new value it cannot pass
> it on to handler "B" because the system will call "B" only after "A"
> returns. That's the predicament.
>
> ACP overcomes this by capturing the applications current state in an
> immutable map. All event handlers receive a single parameter which is
> the "current" context and compute the "new" context. A typical handler
> (henceforth: "context processing function") will carry out these
> activities: (a) Examine the current context; (b) Perform some GUI
> operations (setSize, setText, etc.); (c) Compute a new context based
> on the current context and on information obtained from the GUI
> (getText, etc.). The caller (henceforth: "dispatcher") takes the
> returned context and will use it as the new current context, the next
> time a context processing function is invoked.
>
> This means that when you register event handler with a Swing widget
> the handler needs to to call the ACP dispatcher passing it a context
> processing function.
>
> The net effect of this approach is that only the dispatcher has to
> deal with mutable state. The context processors are functional: they
> merely compute the new state from the current.
>
> application-context-pattern.clj (http://groups.google.com/group/
> clojure/web/application-context-pattern.clj) shows a concrete example.
> It's about 140 LOC (ripped off from the real Waterfront codebase)
> structured as follows:
>   Lines 1..40: General-purpose helpers.
>   Lines 40..90: The ACP infrastructure
>   Lines 90..140: A quick sample, built around ACP.
>
> The sample program opens a JFrame with two buttons: Input and Output.
> A click on the input button will pop-up an input dialog box. A click
> on the output button will pop-up a message box showing the last value
> entered into the input box. There's also a JLabel showing the length
> of the input, but let's ignore it for the moment.
>
> The entry point into the ACP world is the bootstrap function. It takes
> two parameters: a context processing function and an initial context.
> In the example, this is carried out at the bottom of the run-it
> function:
>
>   (defn run-it []
>     (let [build-ui (fn [ctx]
>       (let [f (javax.swing.JFrame. "Frame")
>             b-in (javax.swing.JButton. "Input")
>             b-out (javax.swing.JButton. "Output")]
>
>         (.addActionListener b-in (new-action-listener (fn [event]
>           ((ctx :dispatch) get-input
>
>         (.addActionListener b-out (new-action-listener (fn [event]
>           ((ctx :dispatch) show-output
>
>         (.setLayout f (java.awt.FlowLayout.))
>         (doseq [x [b-in b-out]]
>           (.add f x) )
>
>         (doto f
>           (.setSize 500 300)
>           (.setDefaultCloseOperation javax.swing.JFrame/
> DISPOSE_ON_CLOSE)
>           (.setVisible true))
>
>         (assoc ctx :frame f) ))]
>
>     (invoke-later #(bootstrap build-ui {})) ))
>
> invoke-later is a utility function that is mapped to SwingUtilities/
> invokeLater.
>
> Let's drill down into the build-ui function: It takes the current
> context (ctx parameter). Then it creates the frame and the buttons. It
> uses new-action-listener (another utility) to register an action
> listener with the buttons. The first listener looks like this:
>           ((ctx :dispatch) get-input
>
> It uses (ctx :dispatch) to obtain the dispatcher from which ctx was
> obtained, and evaluates it passing get-input as the context processing
> function. The call to bootstrap initialized this dispatcher and added
> the :dispatch mapping to the initial context.
>
> get-input looks like this:
>   (defn- get-input [ctx]
>     (let [reply (javax.swing.JOptionPane/showInputDialog nil "Type in
> something")]
>       (assoc

Re: Synchronous watches

2009-02-27 Thread Mark Addleman

On Feb 27, 7:17 am, Rich Hickey  wrote:
>
> > Are namespaces & global set of namespaces "watchable" things ?
>
> No they are not.

Is there a deep reason for this?  I'm not familiar with this part of
Clojure but, if the functionality is possible, would you accept a
patch for this?
--~--~-~--~~~---~--~~
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: Synchronous watches

2009-02-27 Thread Rich Hickey


On Feb 27, 2009, at 7:29 PM, Mark Addleman wrote:

>
> On Feb 27, 7:17 am, Rich Hickey  wrote:
>>
>>> Are namespaces & global set of namespaces "watchable" things ?
>>
>> No they are not.
>
> Is there a deep reason for this?  I'm not familiar with this part of
> Clojure but, if the functionality is possible, would you accept a
> patch for this?
>

There's no deep reason, but I want to hold off on pursuing this right  
now. I'm still thinking about the issues of people running in systems  
like OSGi and NetKernel, which may in the end need partitioning of the  
namespace stuff from the rest of Clojure, as well as the needs of  
those trying to use Terracotta.

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



(rest ())

2009-02-27 Thread Mark Engelberg

Maybe it doesn't matter in practice, but does it seem odd to anyone
else that (rest ()) returns () rather than nil?

--~--~-~--~~~---~--~~
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: (rest ())

2009-02-27 Thread Stephen C. Gilardi


On Feb 27, 2009, at 8:27 PM, Mark Engelberg wrote:


Maybe it doesn't matter in practice, but does it seem odd to anyone
else that (rest ()) returns () rather than nil?


I think that's to be expected given the recent changes to how laziness  
works in Clojure. It's consistent with these docs:


Clojure
user=> (doc rest)
-
clojure.core/rest
([coll])
	  Returns a possibly empty seq of the items after the first. Calls  
seq on its

  argument.
nil
user=> (doc next)
-
clojure.core/next
([coll])
  Returns a seq of the items after the first. Calls seq on its
  argument.  If there are no more items, returns nil.
nil

Were you thinking of what's now called "next" and used to be called  
"rest"?


Why did you expect nil from rest in this case?

--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: Clojure + Terracotta = Yeah, Baby!

2009-02-27 Thread Rich Hickey



On Feb 27, 6:54 pm, Luc Prefontaine 
wrote:
> Having the ability to redefine a function once for all instances is
> something we really want...
> and you need name spaces to be shared for that to happen.
> We take the approach of sharing everything that seems to worth it, then
> we will see
> what we might need to keep private to each JVM.
>
> Sharing var roots and refs also is something we want so we can initiate
> STM transactions
> involving  multiple JVMs.
>
> We have much to learn from a prototype and that is what we strive to
> achieve the immediate future.
> After this step, real fun will begin, right now were having only an
> appetizer...
>
> Luc
>

It would be great if you could mention the difficulties you face as
you go, before you spend too much time on workarounds. I am interested
in seeing Clojure on Terracotta and if there are things I can do
easily to support this effort I will.

Rich

>
>
> On Fri, 2009-02-27 at 16:51 -0500, Paul Stadig wrote:
> > Yeah, after sharing clojure.lang.Keyword.table I tried to share
> > clojure.lang.Namespace.namespaces, but ran into a problem because
> > Namespace uses an AtomicReference for its mappings and aliases
> > members. I thought that not sharing namespaces would be a problem (and
> > maybe it still is I don't have as much practical experience with this
> > as you), but I wasn't sure it would be a problem. Looking up a var in
> > a namespace on different JVMs would find different vars, but since
> > they are thread local, then I'm not sure its an issue. Having all of
> > your refs shared without having to specify each specific ref would be
> > interesting, but since most of the stuff (functions, vars, etc.) are
> > immutable or thread local, then I'm not sure how much of an issue it
> > is.
>
> > Obviously, if you were going to redefine some functions or something,
> > then you'd either have to do so on each JVM, or just restart all of
> > the clients.
>
> > And as I said in my article, I didn't do any work with agents, so
> > maybe there's a lot missing from my part of the puzzle.
>
> > Paul
>
> > On Fri, Feb 27, 2009 at 4:37 PM, Luc Prefontaine
> >  wrote:
> > > We are trying to get Clojure shared over Terracotta, not just specific
> > > things but the whole Clojure object space
> > > (name spaces, root values, ) except stuff that needs to remain local
> > > (streams, ).
>
> > > We take an all or nothing approach here, we would to see many Clojure
> > > instances work as a single
> > > entity.
>
> > > We are facing a number of issues, one of them being the lack of support by
> > > Terracotta of AtomicReference.
>
> > > Terracotta has placed this class in the list of classes they will 
> > > eventually
> > > support but has of 2.7.3
> > > it's still not supported.
>
> > > The Sun AtomicReference does peeks and pokes in the heap using internal
> > > routines of the JVM (JNI).
> > > Clearly this cannot be done with multiple JVMs, different object heaps, 
> > > 
>
> > > Terracotta suggest using the oswego library but since Java 5 has been out,
> > > it's in maintenance mode only and
> > > integrating another library to the puzzle for that single purpose did not
> > > look to us as very efficient.
>
> > > So we created a SharedAtomicReference implementation that uses standard
> > > locks to control access to
> > > the value with the corresponding Terracotta configuration.
>
> > > We use a factory to decide at run time which implementation to use based 
> > > on
> > > a system property.
> > > To preserve the Clojure code base, we implemented an AtomicReference
> > > interface and a delegate to
> > > the AtomicReference class. The Clojure code uses now  interface.
> > > This allows us to make progress without disturbing the Clojure code base 
> > > too
> > > much.
>
> > > This has some performance implications that we do not fully understand yet
> > > since we need a living Clojure implementation
> > > to work with, something we are in the process of creating... what a catch 
> > > 22
> > > :)))
> > > We thought about spending time working on this aspect right now but we
> > > prefer to wait for the first alpha release.
>
> > > As for the rest of the Clojure code, we are working on the classes
> > > implementing vectors, hash maps, 
> > > to get them shared through terracotta.
>
> > > Our main challenge these days is putting together the terracotta
> > > configuration of the internal classes of Clojure that need to be shared.
>
> > > We may hit issues that make some classes non portable.
> > > These will require us to implement an alternative.  We will use then a
> > > slightly different approach,
> > > we need only factories to allocate an alternate version or the "local"
> > > implementation.
> > > The Clojure code already uses interfaces to access the data objects so 
> > > this
> > > will be almost transparent in the code.
>
> > > We prefer to re implement an "distributed" implementation side by side 
> > > with
> > > the original one

Re: Clojure + Terracotta = Yeah, Baby!

2009-02-27 Thread Luc Prefontaine
You're right Rich,

We all have to agree on the means used to implement this in the Clojure
runtime.
Any code we throw right now has to be somewhat aligned with these
decisions.

The decision to hide the AtomicReference class was easy to take. It was
an unavoidable
obstacle. Any other issues from the Clojure run time will need more
thinking and
there might be other ways to do work around these issues.

I can post an update each 2 weeks or so or on demand before we spit out
code
if we face an issue.

Right now we are busy writing a tool in Clojure to generate the
terracotta configuration
from a set of classes. Finding each dependent class one by one is too
slow.
We always end up missing one. It will also spit out the locking section
with all these member functions.

This tool will speed us a lot in getting the prototype up. We will get
the master pieces of
the XML configuration. We can them removing unwanted classes from the
configuration
and tune the locking strategy as you test things.

Luc

On Fri, 2009-02-27 at 18:05 -0800, Rich Hickey wrote:

> 
> 
> On Feb 27, 6:54 pm, Luc Prefontaine 
> wrote:
> > Having the ability to redefine a function once for all instances is
> > something we really want...
> > and you need name spaces to be shared for that to happen.
> > We take the approach of sharing everything that seems to worth it, then
> > we will see
> > what we might need to keep private to each JVM.
> >
> > Sharing var roots and refs also is something we want so we can initiate
> > STM transactions
> > involving  multiple JVMs.
> >
> > We have much to learn from a prototype and that is what we strive to
> > achieve the immediate future.
> > After this step, real fun will begin, right now were having only an
> > appetizer...
> >
> > Luc
> >
> 
> It would be great if you could mention the difficulties you face as
> you go, before you spend too much time on workarounds. I am interested
> in seeing Clojure on Terracotta and if there are things I can do
> easily to support this effort I will.
> 
> Rich
> 
> >
> >
> > On Fri, 2009-02-27 at 16:51 -0500, Paul Stadig wrote:
> > > Yeah, after sharing clojure.lang.Keyword.table I tried to share
> > > clojure.lang.Namespace.namespaces, but ran into a problem because
> > > Namespace uses an AtomicReference for its mappings and aliases
> > > members. I thought that not sharing namespaces would be a problem (and
> > > maybe it still is I don't have as much practical experience with this
> > > as you), but I wasn't sure it would be a problem. Looking up a var in
> > > a namespace on different JVMs would find different vars, but since
> > > they are thread local, then I'm not sure its an issue. Having all of
> > > your refs shared without having to specify each specific ref would be
> > > interesting, but since most of the stuff (functions, vars, etc.) are
> > > immutable or thread local, then I'm not sure how much of an issue it
> > > is.
> >
> > > Obviously, if you were going to redefine some functions or something,
> > > then you'd either have to do so on each JVM, or just restart all of
> > > the clients.
> >
> > > And as I said in my article, I didn't do any work with agents, so
> > > maybe there's a lot missing from my part of the puzzle.
> >
> > > Paul
> >
> > > On Fri, Feb 27, 2009 at 4:37 PM, Luc Prefontaine
> > >  wrote:
> > > > We are trying to get Clojure shared over Terracotta, not just specific
> > > > things but the whole Clojure object space
> > > > (name spaces, root values, ) except stuff that needs to remain local
> > > > (streams, ).
> >
> > > > We take an all or nothing approach here, we would to see many Clojure
> > > > instances work as a single
> > > > entity.
> >
> > > > We are facing a number of issues, one of them being the lack of support 
> > > > by
> > > > Terracotta of AtomicReference.
> >
> > > > Terracotta has placed this class in the list of classes they will 
> > > > eventually
> > > > support but has of 2.7.3
> > > > it's still not supported.
> >
> > > > The Sun AtomicReference does peeks and pokes in the heap using internal
> > > > routines of the JVM (JNI).
> > > > Clearly this cannot be done with multiple JVMs, different object heaps, 
> > > > 
> >
> > > > Terracotta suggest using the oswego library but since Java 5 has been 
> > > > out,
> > > > it's in maintenance mode only and
> > > > integrating another library to the puzzle for that single purpose did 
> > > > not
> > > > look to us as very efficient.
> >
> > > > So we created a SharedAtomicReference implementation that uses standard
> > > > locks to control access to
> > > > the value with the corresponding Terracotta configuration.
> >
> > > > We use a factory to decide at run time which implementation to use 
> > > > based on
> > > > a system property.
> > > > To preserve the Clojure code base, we implemented an AtomicReference
> > > > interface and a delegate to
> > > > the AtomicReference class. The Clojure code uses now  interface.
> > > > This allows us to 

Re: (rest ())

2009-02-27 Thread Mark Engelberg

> Were you thinking of what's now called "next" and used to be called "rest"?

No.

>
> Why did you expect nil from rest in this case?

I expect:
(rest [1]) -> ()
(rest []) -> nil

Starting with the new lazier branch, we have a concept of an empty
sequence.  So the rest of a singleton yields an empty sequence.  But
asking for the rest of an empty sequence is very different.  Clojure
should generate a different kind of value to let you know that you
asked for the rest of something that doesn't really have a rest.

Just as (first []) yields nil, so should (rest []), IMO.

I can't offhand think of a way that the current behavior would break
something, but it seems quite illogical to me to say that the rest of
an empty sequence is the empty sequence.

--~--~-~--~~~---~--~~
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: Opinions on -> macro?

2009-02-27 Thread e
I think it's simpler just to have a consistent syntax, personally.
Otherwise, why not python or haskell style syntax for the language?  because
code is data.  So now there's a special case where the data is backwards.

On Fri, Feb 27, 2009 at 1:49 PM, Meikel Brandmeyer  wrote:

> Hi,
>
> Am 27.02.2009 um 19:39 schrieb John D. Hume:
>
>  As a Java/Ruby guy who is not used to reading inside out, I'm curious
>> as to whether people who ARE accustomed to LISP find the -> macro
>> distracting since it flops things around. Are there circumstances
>> where you prefer it?
>>
>
> I have a Scheme background and I like -> a lot. I would prefer it
> always over
>
>  (foo (bar (baz (frobnicate a-thing)) bla)).
>
> Eh? To which function belongs the bla argument? I think
>
>  (-> a-thing frobnicate baz (bar bla) foo)
>
> is much clearer.
>
> Sincerely
> Meikel
>
>

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

2009-02-27 Thread Joshua

I have started looking into Issue 34 and I have some questions.

Link:
http://code.google.com/p/clojure/issues/detail?id=34&colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary

Is the desired syntax to match the CL version?
Should I create a separate reader for the read-only version or just
use an if statement within the EvalReader?

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



Observations about new lazy branch

2009-02-27 Thread Mark Engelberg

I just finished porting my combinatorics code to the new lazy
constructs, and I discovered some subtleties to using lazy-seq that
were not at first apparent.

To begin with, consider the two versions of map:
The old way:

(defn map
  ([f coll]
   (when (seq coll)
 (lazy-cons (f (first coll)) (map f (rest coll)

The new way:

(defn map
  ([f coll]
   (lazy-seq
(when-let [s (seq coll)]
  (cons (f (first s)) (map f (rest s))

Let's imagine that you are using map on a collection for which it is
very computation intensive to generate the rest, but trivial to
generate the first.

I believe that in this case, you'd get more desirable behavior from
the old way than the new way.

That's because the original lazy-cons kept the first and rest thunks
separate.  It would force the first to get the rest, but it would NOT
force the rest to get at the first.  So if you ask for the first, it
wouldn't do all the rest-generating computation.  However, the new
version uses a delayed regular cons.  So when you invoke the first of
the sequence, both arguments of cons are evaluated, so (map f (rest
s)) is called, and therefore (rest s) must be evaluated.

If this is unclear, consider this:
(defn a [] (do (println "a") nil))
(def s (lazy-seq (cons (a) (a
(first s)

If you type this into the REPL, you'll see that the rest gets
evaluated when you ask for the first.

To get the desired separation of first and rest evaluation with the
new lazy-seq function, you'd actually need to do something like this:

(def lazier-map
  (let [step (fn step [f coll]
   (when-let [s (seq coll)]
 (cons (f (first s)) (lazy-seq (step f (rest s))]
(fn [f coll]
  (lazy-seq (step f coll)

Basically, I've made a helper function which uses lazy-seq to delay
the evaluation of the rest, and then wrapped the call to the helper
function in a lazy-seq in order to delay evaluation of the very first
item.

As a challenge, try to similarly fix up the version of filter provided
on the lazy page so that it fully separates the evaluation of first
and rest, thus protecting you against unnecessary evaluation if rest
is a slow operation on coll.  I think you'll find that you end up with
two levels of indirection, and it's extremely difficult to write it
properly.  Post your simplest solution here.

Now in both these examples, you could argue that in all likelihood,
rest will be a fast operation.  But I chose map here because everyone
knows the way we're supposed to write map, so it seemed like a good
choice to illustrate my concerns without having to explain how the
function works, etc.

But this kind of problem does actually occur in practice.  It appeared
in several places in the code I ported, because my code tends to do
most of the work within the arguments to the recursive call.  I found
it difficult to reason about where to place the calls to lazy-seq in
order to achieve the separation I needed for evaluating the first and
the rest.  I think I pulled it off correctly, but I've got to say I'm
not crazy about how, to do the "right thing", the code ends up looking
quite obfuscated.

In summary, the new version gives you the most power to place the
delays where you want, but it's hard to get it right.

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

2009-02-27 Thread Stephen C. Gilardi


On Feb 27, 2009, at 10:59 PM, Joshua wrote:


Is the desired syntax to match the CL version?


Following CL's lead by implementing a *read-eval* var as Stuart  
suggested looks like a good way to do this to me.



Should I create a separate reader for the read-only version or just
use an if statement within the EvalReader?


A solution based on *read-eval* would use if statement.

--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: Observations about new lazy branch

2009-02-27 Thread Jason Wolfe

If lazy-cons makes your life easier, I think you can still have
something very much like it:

(defmacro lazy-cons [x s]
  `(lazy-seq (cons ~x (lazy-seq ~s

If you're interested in perf, you'd just have to write your code a bit
carefully to avoid double lazy-seq'ing the rests:

(defn map [f coll]
(lazy-seq
  (old-map [f coll])))

where old-map is the old version of map (modified to cache the call to
"seq"?).  Does this make sense?

-Jason

P.S. thanks for updating combinatorics, I've been waiting for that.



On Feb 27, 8:10 pm, Mark Engelberg  wrote:
> I just finished porting my combinatorics code to the new lazy
> constructs, and I discovered some subtleties to using lazy-seq that
> were not at first apparent.
>
> To begin with, consider the two versions of map:
> The old way:
>
> (defn map
>   ([f coll]
>    (when (seq coll)
>      (lazy-cons (f (first coll)) (map f (rest coll)
>
> The new way:
>
> (defn map
>   ([f coll]
>    (lazy-seq
>     (when-let [s (seq coll)]
>       (cons (f (first s)) (map f (rest s))
>
> Let's imagine that you are using map on a collection for which it is
> very computation intensive to generate the rest, but trivial to
> generate the first.
>
> I believe that in this case, you'd get more desirable behavior from
> the old way than the new way.
>
> That's because the original lazy-cons kept the first and rest thunks
> separate.  It would force the first to get the rest, but it would NOT
> force the rest to get at the first.  So if you ask for the first, it
> wouldn't do all the rest-generating computation.  However, the new
> version uses a delayed regular cons.  So when you invoke the first of
> the sequence, both arguments of cons are evaluated, so (map f (rest
> s)) is called, and therefore (rest s) must be evaluated.
>
> If this is unclear, consider this:
> (defn a [] (do (println "a") nil))
> (def s (lazy-seq (cons (a) (a
> (first s)
>
> If you type this into the REPL, you'll see that the rest gets
> evaluated when you ask for the first.
>
> To get the desired separation of first and rest evaluation with the
> new lazy-seq function, you'd actually need to do something like this:
>
> (def lazier-map
>   (let [step (fn step [f coll]
>                (when-let [s (seq coll)]
>                  (cons (f (first s)) (lazy-seq (step f (rest s))]
>     (fn [f coll]
>       (lazy-seq (step f coll)
>
> Basically, I've made a helper function which uses lazy-seq to delay
> the evaluation of the rest, and then wrapped the call to the helper
> function in a lazy-seq in order to delay evaluation of the very first
> item.
>
> As a challenge, try to similarly fix up the version of filter provided
> on the lazy page so that it fully separates the evaluation of first
> and rest, thus protecting you against unnecessary evaluation if rest
> is a slow operation on coll.  I think you'll find that you end up with
> two levels of indirection, and it's extremely difficult to write it
> properly.  Post your simplest solution here.
>
> Now in both these examples, you could argue that in all likelihood,
> rest will be a fast operation.  But I chose map here because everyone
> knows the way we're supposed to write map, so it seemed like a good
> choice to illustrate my concerns without having to explain how the
> function works, etc.
>
> But this kind of problem does actually occur in practice.  It appeared
> in several places in the code I ported, because my code tends to do
> most of the work within the arguments to the recursive call.  I found
> it difficult to reason about where to place the calls to lazy-seq in
> order to achieve the separation I needed for evaluating the first and
> the rest.  I think I pulled it off correctly, but I've got to say I'm
> not crazy about how, to do the "right thing", the code ends up looking
> quite obfuscated.
>
> In summary, the new version gives you the most power to place the
> delays where you want, but it's hard to get it right.
--~--~-~--~~~---~--~~
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: Synchronous watches

2009-02-27 Thread Mark Derricutt
Apologies for thread-hijackig but I thought I'd mention that one of the
problems I've had using Clojure under OSGi was fixed with a minor patch
(mentioned in my post at
http://www.talios.com/clojure_running_successfully_under_osgi.htm ) which
had to do with the assumption non jar:// classpath entries were File's.

Mark

...and then Buffy staked Edward.  The End.


On Sat, Feb 28, 2009 at 2:25 PM, Rich Hickey  wrote:

>
> now. I'm still thinking about the issues of people running in systems
> like OSGi and NetKernel, which may in the end need partitioning of the
> namespace stuff from the rest of Clojure, as well as the needs of
> those trying to use Terracotta.
>

--~--~-~--~~~---~--~~
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: Observations about new lazy branch

2009-02-27 Thread Mark Engelberg

On Fri, Feb 27, 2009 at 8:33 PM, Jason Wolfe  wrote:
>
> If lazy-cons makes your life easier, I think you can still have
> something very much like it:
>
> (defmacro lazy-cons [x s]
>  `(lazy-seq (cons ~x (lazy-seq ~s

As you pointed out, in most contexts, this will double the number of
lazy-seq calls, which will really hurt performance.

>
> If you're interested in perf, you'd just have to write your code a bit
> carefully to avoid double lazy-seq'ing the rests:
>
> (defn map [f coll]
>        (lazy-seq
>          (old-map [f coll])))
>
> where old-map is the old version of map (modified to cache the call to
> "seq"?).  Does this make sense?

I'm not sure which old-map you mean here.  If you mean the old
lazy-cons version, using your above macro, this will have too many
lazy-seq calls.

--~--~-~--~~~---~--~~
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: Observations about new lazy branch

2009-02-27 Thread Jason Wolfe


> I'm not sure which old-map you mean here.  If you mean the old
> lazy-cons version, using your above macro, this will have too many
> lazy-seq calls.


Yeah, you're right  ... I managed to confuse myself.

Off the top of my head I can't think of a nicer way to write lazier- 
map than what you've got.  Hmmm...

-Jason



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

2009-02-27 Thread Michael Wood

On Sat, Feb 28, 2009 at 6:13 AM, Stephen C. Gilardi  wrote:
>
> On Feb 27, 2009, at 10:59 PM, Joshua wrote:
>
>> Is the desired syntax to match the CL version?
>
> Following CL's lead by implementing a *read-eval* var as Stuart suggested
> looks like a good way to do this to me.

So, I suppose the "syntax" for this would be something like this:

(binding [*read-eval* false] (read ...))

>> Should I create a separate reader for the read-only version or just
>> use an if statement within the EvalReader?
>
> A solution based on *read-eval* would use if statement.

-- 
Michael Wood 

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