Re: Capitalize string

2009-03-08 Thread Itay Maman

I am not particularly fond of idiomatic style. In production code I
want something clear and explicit even if it is a bit longer. That
said, your question triggered this challenge: What's the shortest way
for capitalizing the first letter of every word, i.e.: (assert (=
(capitalize "ab cd") "Ab Cd")) ?

Here's my take:

(defn capitalize [s]
  (apply str (map (fn [prev curr]
(or (and (= prev \space) (Character/toUpperCase curr)) curr))
(cons \space s) s)))


--
Itay Maman
http://javadots.blogspot.com

On Mar 8, 3:20 pm, David Sletten  wrote:
> On Mar 8, 2009, at 2:45 AM, Joshua Fox wrote:
>
>
>
> > How about this?
> > user=> (defn upper-first [s] (apply str (Character/toUpperCase (first
> > s)) (rest s)))
> > #'user/upper-first
> > user=> (upper-first "a")
> > "A"
>
> That certainly qualifies as less idiotic. :)
>
> Mahalo,
> David Sletten
--~--~-~--~~~---~--~~
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: Modular composition/plugin architecture

2009-03-05 Thread Itay Maman

Here's how plugin support is implemented in Waterfront:

The last expression in each plugin is the "plguin init function": a
function (can be anonymous) that takes a single parameter (a map) and
returns new map.
The load-plugin function takes a strings (specifying the path to
a .clj file), and performs load-file on each string. Then, load-plugin
evals the value returned by load-file (which, in fact, is the plugin
init function) passing a map as a parameter. If you're loading several
plugins the result returned from the init function will be used as the
new map passed to the next plugin.

Anyway, enough talking, let's go coding:

; say myutil/ut1.clj contains
(ns 'myutil.ut1)
(defn foo [] :foo-ut1)

; init function of ut1
(fn [m] (assoc m :foo foo))


; and myutil/ut2.clj contains
(ns 'myutil.ut2)
(defn foo [] :foo-ut2)

; init function of ut2
(fn [m] (assoc m :foo foo))


(defn load-plugin [path]
  ((load-file path) {}) )

;mylib/lib1.clj
(defn libfoo []
  (((load-plugin (if some-condition "myutil/ut1.clj" "myutil/
ut2.clj")) :foo)) )



That's it. In Waterfront this design is integrated with the context
pattern which I described here a few days ago.

Hope that helps.

--
Itay Maman
http://javadots.blogspot.com

On Mar 5, 6:48 am, Adrian Cuthbertson 
wrote:
> Hi,
>
> How would one create a "plugin" modular composition using clojure
> functions/modules only (i.e without resorting to java interface/
> plugin class implementations)?
>
> For example;
> ; say myutil/ut1.clj contains
> (ns 'myutil.ut1)
> (defn foo [] :foo-ut1)
>
> ; and myutil/ut2.clj contains
> (ns 'myutil.ut2)
> (defn foo [] :foo-ut2)
>
> ;and mylib/lib1.clj contains
> (defn libfoo [] (foo))
>
> Then from my app, I'd like to tell mylib.lib1 which ut to use when it
> loads, before calling libfoo.
> Is this possible, or is there some other clojure way of doing this?
>
> Thanks,
> Adrian.
--~--~-~--~~~---~--~~
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: Accessing ASM?

2009-03-04 Thread Itay Maman

I guess my response is "why not?". ASM is a Java library. Clojure
works with Java.
Where's the catch? (or maybe I am missing something)

--
Itay Maman
http://javadots.blogspot.com


On Mar 4, 11:09 pm, Robert Feldt  wrote:
> Can we access the ASM used by clojure internally from clojure code?
> Anyone has an example? I need to write a bytecode transformer to trace
> the execution of a Java class. Would be great to be able to work with
> asm from within clojure.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: JavaWorld article

2009-03-04 Thread Itay Maman

Sorry, this was supposed to be offline

On Mar 4, 8:29 pm, Itay Maman  wrote:
> On Mar 4, 7:33 pm, Joshua Fox  wrote:
>
> > I am working on a short article to appear in JavaWorld sometime this
> > spring.
> > Its goal is to encourage senior Java developers to learn more about Clojure.
> > The audience is experienced and knowledgeable about Java, but LISP to them
> > is a distant memory from college. So, rather than present a tutorial, or an
> > advanced study of language features, I focus  on comparing language
> > constructs in  Clojure to similar (often inferior) ones in Java
>
> > If anyone would like to comment on a draft, please contact me offline. I'd
> > appreciate the input.
>
> Count me in.
> -Itay
>
>
>
> > 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
-~--~~~~--~~--~--~---



Re: JavaWorld article

2009-03-04 Thread Itay Maman



On Mar 4, 7:33 pm, Joshua Fox  wrote:
> I am working on a short article to appear in JavaWorld sometime this
> spring.
> Its goal is to encourage senior Java developers to learn more about Clojure.
> The audience is experienced and knowledgeable about Java, but LISP to them
> is a distant memory from college. So, rather than present a tutorial, or an
> advanced study of language features, I focus  on comparing language
> constructs in  Clojure to similar (often inferior) ones in Java
>
> If anyone would like to comment on a draft, please contact me offline. I'd
> appreciate the input.

Count me in.
-Itay


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



Re: Inclusive-exclusive range

2009-03-04 Thread Itay Maman

(+1 for Konrad's point regarding concat).

Two points, in favor of 0-based indexing (as opposed to 1-based)

When you look at a piece of code and see zero used as an index into
some custom-made collection, you immediately know that this is a
reference to the first item. Except for the rare cases of collections
with negative indexes, it is clear that 0 is the first element. An
index of 1 is ambiguous: It means either the first or the second
element, depending on the convention of the language as well as
whether the programmer who wrote the collection decided to follow the
convention.

The second point is somewhat less significant but it does have a
point: With 1-based you need to write (<= i n) instead of (< i n). It
seems that programmers prefer to write less, hence  making 0-based
indexing more popular.

Just my 2c

--
Itay Maman
http://javadots.blogspot.com/


On Mar 4, 3:40 pm, Konrad Hinsen  wrote:
> On Mar 4, 2009, at 14:06, Mibu wrote:
>
> > On Mar 4, 2:46 pm, Michael Wood  wrote:
> >> On Wed, Mar 4, 2009 at 2:07 PM, Mibu  wrote:
> >>> Why does range in Clojure use an inclusive-exclusive range?
> >> For what it's worth, Python's range function works the same way.
>
> > I think Clojure's design leans towards what's right more than what's
> > custom even if it breaks old habits, so I am curious why wasn't this
> > bad habit broken as well. Is it just convention, bad as it is? Or
> > maybe I'm missing some hidden good reason for using this confusing (to
> > me) range over an inclusive range.
>
> I wouldn't call it a bad habit just because it's not what you expected.
>
> The definition of range used in Clojure (and elsewhere) has some nice  
> properties:
>
>         (=  n  (count (range n)))
>
>         (=  (- b a)  (count (range a b)))
>
>         (=  (concat (range a b) (range b c))  (range a c))
>
> Their utility may not be obvious immediately, but if you write code  
> that works a lot on indices, you will learn to appreciate them.
>
> Konrad.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: The Application Context Pattern

2009-03-04 Thread Itay Maman

Suppose you have three observers: o1, o2, o3. run-observers evaluates
them in this order.
Let's assume we don't have run-observers-till-fixpoint. Thus, after
the evaluation of a processor we will use run-observers to run these
observers.
Under this scenario, what will happen if o3 will return a new context?
o1 and o2 were already evaluated so they will not be able to react to
the updates in the context issued by o3.

run-observers-till-fixpoint takes care of that by repeatedly looping
thru all observers until the context stabilizes. This has the
disadvantage of a possible infinite loop, but the advantage of making
the context pattern indifferent of the order of the observers. My
experience shows that observers ordering issues are more complicated
to solve than infinite loops among observers.

--
Itay Maman
http://javadots.blogspot.com/



On Mar 4, 8:45 am, Glen Stampoultzis  wrote:
> Hi Itay,
> Thanks for posting this example.  Being new to Clojure it's a nice example
> to study since it solves a very realistic problem that many new to
> functional programming will face.
>
> I think I've unraveled most of how the code is working but there's one
> function I'm not particularly clear about.
>
> (defn- run-observers-till-fixpoint [prev next]
>   (let [observers (next :observers)
>        new-next (run-observers prev next observers)]
>     (if (= new-next next)
>       new-next
>       (recur next new-next) )))
>
> While I understand run-observers, run-observers-till-fixpoint has be
> baffled.  Why is this required?
>
> 2009/2/27 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 exa

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

2009-03-03 Thread Itay Maman

Adler, Konard:

Thank you guys for the patches.
-Itay


On Mar 3, 9:14 pm, aperotte  wrote:
> Hi,
>
> I'm using linux (Ubuntu) and none of the above scripts worked for me.
> I added the ${DP}/bin directory to the classpath list to get it to
> work.
>
> #!/bin/sh
> DP="${0%/*}"
> java -cp ~/src/clojure/clojure.jar:${DP}/clj:${DP}/java -
> Dnet.sourceforge.waterfront.plugins=${DP}/clj/net/sourceforge/
> waterfront/ide/plugins clojure.main ${DP}/clj/net/sourceforge/
> waterfront/ide/main.clj $*
>
> P.S. - The text editor you are using for the shell script is encoding
> DOS style newlines and doesn't work on linux.  I copied the text to a
> new file to get around it.
>
> -Adler
>
> On Feb 25, 4:32 am, Itay Maman  wrote:
>
> > On Feb 25, 11:08 am, bOR_  wrote:
>
> > > I'm trying to rewrite the wf.bat to a linux version, but I was a bit
> > > puzzled what all the ;%~dp0 's mean.
>
> > In .bat files %~dp0 specifies the directory where the .bat file is
> > located.
> > In sh scripts, it should be `dirname $0`.
>
> > >Apparently the bash version of it
> > > is ${0%/*}
>
> > > java -cp ~/src/clojure/clojure.jar;${0%/*}clj;${0%/*}java -
> > > Dnet.sourceforge.waterfront.plugins=${0%/*}clj/net/sourceforge/
> > > waterfront/ide/plugins clojure.main ${0%/*}clj/net/sourceforge/
> > > waterfront/ide/main.clj %*
>
> > > It seems like you're also assuming 'clj' to exist?
>
> > clj and java are the subdirectories in the Waterfront installation
> > directory. So if the zip was unzipped
> > successfully, it is safe to assume they exist.
>
> > I don't have a Linux machine. Could you send me this script (one it is
> > up and running)
> > so that I will put it inside the .zip file?
>
> > Thanks,
> > -Itay
>
> > > On Feb 25, 2:57 am, Kevin Albrecht  wrote:
>
> > > > Itay,
>
> > > > I took a look at Waterfront and it seems to have a lot of potential.
> > > > Keep me and the group updated on your future work.
>
> > > > I have also been working on a GUI application in Clojure and I share
> > > > your perspective on the challenges of designing a functional GUI.  I
> > > > am definitely intrigued by the application context pattern and I am
> > > > going to take a look at it for incorporation in my design.
>
> > > > Thanks,
> > > > Kevin Albrecht
>
> > > > On Feb 24, 6:04 am, Itay Maman  wrote:
>
> > > > > I've been silently following Clojure (and this group) for several
> > > > > months now.Somewhere around December I started working on a Clojure
> > > > > editor/REPL written in Clojure. This effort evolved into the
> > > > > Waterfront project which is now available on sourceforge (http://
> > > > > sourceforge.net/project/showfiles.php?group_id=249246).
>
> > > > > Waterfront's Highlights:
>
> > > > > * CTRL+E: Eval current selection, or the whole file if the selection
> > > > > is empty
> > > > > * Edit -> Eval as you type: When turned on (default) periodically
> > > > > evaluates your code. Boosts productivity as many errors are detected
> > > > > on the spot.
> > > > > * Eval-ed code can inspect/mutate Waterfront by accessing the *app*
> > > > > variable. For instance, if you eval this expression,
> > > > > ((*app* :change) :font-name "Arial"), you will choose "Arial" as the
> > > > > UI font.
> > > > > * Eval-ed code can inspect the currently edited Clojure program. For
> > > > > instance, if you eval this expression, ((*app* :visit) #(when (= (str
> > > > > (first %1)) "cons") (println %1))), the output window will show all
> > > > > calls, made by your code, to the cons function.
> > > > > * Syntax and Evaluation errors are displayed on: (1) The Problems
> > > > > window; (2) The line-number panel, as red markers.
> > > > > * Source -> Generate -> Proxy: Generates a proxy for the given list of
> > > > > super-types, with stub implementations for all abstract methods.
> > > > > * F1: Shows the doc (as per Clojure's (doc x) function) of the
> > > > > identifier under the caret.
> > > > > * Source -> Reflect: Shows the synopsis of a Java class when the caret
> > > > > stands on a class symbol (e.g.: java.awt.Color).
> > > > 

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

2009-03-03 Thread Itay Maman

Konrad,

Your installation is probably fine. The problem lies in the
FileNameExtensionFilter  class. It was only introduced in Java6.
Therefore, despite the fact
that you now have binaries that are compatible with your JVM, the
program does not run. I'll try to fix this soon. I'll post a message
when a new revision is up.

Alternatively hoping that this is the only Java6-only dependency in
the code, you can also apply this patch to clj/net/sourceforge/
waterfront/ide/plugins/file.clj (I didn't test is though - I am away
from my machine, so no warranty...)

Replace lines 169..173 with this:

(defn add-chooser [app]
  (let [chooser (javax.swing.JFileChooser. (. System getProperty
"user.dir"))]
(assoc app :file-chooser chooser) ))


Hope that helps.
-Itay


On Mar 3, 5:21 pm, Konrad Hinsen  wrote:
> On Mar 3, 2009, at 11:46, Tom Ayerst wrote:
>
> > If you pull trunk out of subversion you can build it locally with  
> > Ant.  Would that do it?
>
> Definitely, thanks!  I pulled the latest revision and built it by  
> typing "ant". No compilation errors, but I can't run it either:
>
> Can't load plugin custom-editor.clj. Reason:  
> java.lang.ClassNotFoundException:  
> javax.swing.filechooser.FileNameExtensionFilter (file.clj:171)
> Can't load plugin context-menu.clj. Reason: nil
> Can't load plugin file.clj. Reason: java.lang.ClassNotFoundException:  
> javax.swing.filechooser.FileNameExtensionFilter (file.clj:171)
> Can't load plugin problem-window.clj. Reason: nil
> Can't load plugin undo.clj. Reason: java.lang.Exception: LazySeq used  
> in 'if' (lexer.clj:0)
> Can't load plugin comments.clj. Reason: java.lang.Exception: Unable  
> to resolve symbol: create-undo-transaction in this context  
> (comments.clj:48)
> Can't load plugin line-column.clj. Reason: nil
> Can't load plugin find.clj. Reason: java.lang.Exception: Unable to  
> resolve symbol: create-undo-transaction in this context (find.clj:117)
> Can't load plugin indicator.clj. Reason: nil
> Can't load plugin output-window.clj. Reason: nil
> Can't load plugin check-syntax.clj. Reason: java.lang.Exception:  
> LazySeq used in 'if' (lexer.clj:0)
> Can't load plugin indent.clj. Reason: java.lang.Exception: Unable to  
> resolve symbol: create-undo-transaction in this context (indent.clj:125)
> Can't load plugin paren-matching.clj. Reason: java.lang.Exception:  
> LazySeq used in 'if' (lexer.clj:0)
> Can't load plugin eval-as-you-type.clj. Reason: java.lang.Exception:  
> LazySeq used in 'if' (lexer.clj:0)
> java.lang.NullPointerException
>         at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:26)
>         at net.sourceforge.waterfront.ide.plugins$set_font__1700.invoke(font-
> observer.clj:20)
>         at net.sourceforge.waterfront.ide.plugins$set_fonts__1703.invoke
> (font-observer.clj:26)
>         at net.sourceforge.waterfront.ide$dispatcher__550$fn__554.invoke
> (ui.clj:85)
> ...
>
> It looks as if my installation lacks parts of Swing, but there also  
> seem to be some lazy-seq-related bugs in Waterfront itself (my  
> Clojure is compiled with clojure.assert-if-lazy-seq=true).
>
> Is anyone running Waterfront successfully on a Mac with Java 1.5?
>
> Konrad.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: The Application Context Pattern

2009-02-28 Thread Itay Maman

Hi,

On Feb 28, 8:32 pm, CuppoJava  wrote:
> Hi Itay,
> I'm a little confused about one aspect of the context pattern.
>
> If I understand this write, a listener is a function that takes an old
> context, and returns a new context, BUT it also calls the appropriate
> GUI functions (setText, setSize) to ensure that the gui state is
> consistent with the new context. Is that correct?

Yes.

>
> If so then the listeners aren't purely functional. They don't affect
> any mutable state in atoms or refs, but they mutate the current
> running state of the GUI. So side-effects of these functions are
> therefore important.


Processors/observers may mutate the UI. Yet, even if the processors
manipulate the UI, they will not cause observer-issued side effects.
Also, the affect of either processors or observers is limited to the
UI - their behavior WRT to the program-manged state is side-effect
free.

Thanks for bringing this up, I wasn't very clear.

-Itay

--~--~-~--~~~---~--~~
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-28 Thread Itay Maman



On Feb 27, 5:38 pm, Marko Kocić  wrote:
> 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?

I think that in general, when comparing powerful facilities (such as
the Context-Pattern or Cells) one usually ends up with the conclusion
that they are largely equivalent: the former can be implemented in
terms of the latter and vice-versa. Thus, a discussion of pros and
cons is more about stylistic issues: how hard is it to achieve a
certain behavior in the two approaches?

With that in mind I think that cells are the natural choice for
implementing a complicated net of (well...) spread-sheet-like cells.

Contexts are more natural for UI since the observers are ran only
after a processor has finished. Even if the processor alters several
values in the context, the observers will be notified only when the
processor returns, seeing all the changes bundled together. In many
cases this is the desired behavior in UI apps. If a single user
request adds 100 strings to a list you want the corresponding widget
to be updated once, not 100 times.

I think the differences boil down to the fact the processors are
functional in their nature: the processor per-se does not notify the
observers, only the dispatcher does. Thus, you can compose two
processors (in the same manner you compose functions) without worrying
of side effects due to observers being fired.

-Itay


>
> 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: The Application Context Pattern

2009-02-28 Thread Itay Maman



On Feb 28, 3:26 am, samppi  wrote:
> 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?

I believe that in many practical scenarios this is not a major
problem. Most observers will exit
almost immediately so iterating over them (even several hundreds of
them) will not be too expensive.

Anyway, if it does get into a problem I can think of two possible
solutions:

1) It is possible to create more than one context in a program (in
other words: the context
is not a singleton). By splitting the contexts the number of observers
per invocation of a context-processor
will get smaller.

2) It is possible to create one observer (parent) that delegates to
other observers (children). The parent will contain the logic as to
whether the children need to be invoked. If it decides that the answer
is "No" it will immediately return, thus reducing the workload on the
observer invocation loop.


-Itay


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

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

2009-02-28 Thread Itay Maman

Dan, Marko,

I wonder whether you have the time to do a little experiment. The L&F
is set at line 182 of net/sourceforge/waterfront/ide/ui.clj. Could you
please try to see which L&F works on your machine or, otherwise,
understand why an exception is thrown there?

Thanks,
-Itay


On Feb 28, 12:58 am, Dan  wrote:
> > 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: Waterfront - The Clojure-based editor for Clojure

2009-02-28 Thread Itay Maman



On Feb 28, 1:57 am, zoltar  wrote:
> 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

Curtis,

Yes, that's exactly what I did in rev. 148, already available at
sf.net.

Thanks,
-Itay

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



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



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: Waterfront's Issue tracker is up

2009-02-26 Thread Itay Maman

Should be "you can now submit..."
Sorry for the typo.

-Itay


On Feb 26, 9:37 pm, Itay Maman  wrote:
> For those of you who encountered issues/bugs with Waterfront, you not
> submit reports 
> at:http://sourceforge.net/tracker2/?func=browse&group_id=249246&atid=112...
>
> My intention is to get Waterfront into contrib in the near future.
> Till then, Waterfront will stay on sf.net.
>
> Also, thank you very much for the warm feedback and the wise comments.
>
> -Itay
--~--~-~--~~~---~--~~
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's Issue tracker is up

2009-02-26 Thread Itay Maman

For those of you who encountered issues/bugs with Waterfront, you not
submit reports at: 
http://sourceforge.net/tracker2/?func=browse&group_id=249246&atid=1126790

My intention is to get Waterfront into contrib in the near future.
Till then, Waterfront will stay on sf.net.

Also, thank you very much for the warm feedback and the wise comments.

-Itay

--~--~-~--~~~---~--~~
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 - The Clojure-based editor for Clojure

2009-02-26 Thread Itay Maman

>
> 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: Waterfront - The Clojure-based editor for Clojure

2009-02-26 Thread Itay Maman



On Feb 26, 2:02 pm, Konrad Hinsen  wrote:
> On Feb 26, 2009, at 12:30, Itay Maman wrote:
>
> > In Java6 @Override can also be attached to a method that overrides an
> > interface-declared method. So, the code is not supposed to compile w/
> > a Java5 compiler. As for the Java6 compiler, my guess is that your
> > compile is configured to be Java5 complaint. So I would suggest to
> > specify "-source 1.6" in the javac command line. Anyway, I will add it
> > to the build.xml file.
>
> Do you need Java 1.6 features? Clojure itself works fine with 1.5,  
> and there are still machines around for which there is no 1.6 (my PPC  
> Mac running MacOS 10.4, for example), so it would be nice if  
> Waterfront could work with Java 1.5 as well.

No I don't need Java6. My Eclipse is configured to be Java6-compliant
so it generates
these @Overrides annotations automatically. I agree with your point.
I'll get rid of those.

Coming to think about it, I don't even need the Java code so much. It
is just a few classes
which realize some low-level UI stuff which seemed to be more natural
in Java than in Clojure.
I do want to translate them to Clojure at some point. This will solve
this issue altogether.

-Itay

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

2009-02-26 Thread Itay Maman



On Feb 26, 2:11 pm, Onorio Catenacci  wrote:
> On Feb 26, 6:10 am, Itay Maman  wrote:
>
> > Hi Onorio
>
> > RC1-147 requires the use of Clojure's latest snapshot (can be obtained
> > from the SVN).
>
> I figured that was probably the case but I thought you might want to
> know about the assertion failure in case it were some other issue.

OK, I see your point now.

-Itay

>
> --
> Onorio
--~--~-~--~~~---~--~~
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 - The Clojure-based editor for Clojure

2009-02-26 Thread Itay Maman



On Feb 26, 3:02 am, "Stephen C. Gilardi"  wrote:
> On Feb 24, 2009, at 6:47 PM, Itay Maman wrote:
>
> > This version is fully functional and so far I didn't encounter any
> > bugs.
> > I guess that over the course of the next few days, as people start
> > using this version,
> > a few issues may come up. I'd be glad to fix these.
>
> > I also took Mike's suggestion, Waterfromt's main window is now using
> > a side-by-side layout.
>
> Hi Itay,
>
> Very nice work on waterfront! I gave it a try on Mac OS X. It worked  
> well and showcases many cool ideas.
>
> I had a couple of issues:
>
> - when building on Mac OS X with Java 6 64-bit or Java 5 32-bit, I got  
> errors like this one:
>
>      [javac] Compiling 1 source file to /sq/ext/waterfront/waterfront/
> bin
>      [javac] /sq/ext/waterfront/lab/src/net/sourceforge/waterfront/ide/
> services/Main.java:92: method does not override a method from its  
> superclass
>      [javac]     @Override
>      [javac]      ^
>      [javac] 1 error
>
> in every case where @Override was present in the waterfront source.

In Java6 @Override can also be attached to a method that overrides an
interface-declared method. So, the code is not supposed to compile w/
a Java5 compiler. As for the Java6 compiler, my guess is that your
compile is configured to be Java5 complaint. So I would suggest to
specify "-source 1.6" in the javac command line. Anyway, I will add it
to the build.xml file.


>
> I was able to build successfully by commenting all of them out.
>
> - 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.

Sure.

>
> Thanks very much for waterfront!


You're very welcome.
>
> --Steve
>
>  smime.p7s
> 3KViewDownload
--~--~-~--~~~---~--~~
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 Assertion Failure

2009-02-26 Thread Itay Maman

Hi Onorio

RC1-147 requires the use of Clojure's latest snapshot (can be obtained
from the SVN).

-Itay



On Feb 26, 4:21 am, Onorio Catenacci  wrote:
> Hi Itay (and everyone else),
>
> Every time I try to run Waterfront I keep running into the same
> error.  On line 83 of kit.clj the assertion fails.
>
> Version of Clojure: Revision: 1173
> I just pulled Waterfront from the SourceForge site. (RC1-147).  I
> didn't see the older version so I don't know if that makes a
> difference in this case or not.
> Windows XP SP2
>
> I have the same error with both JDK 1.6.0_03 and 1.6.0_12.
>
> If there's a bug tracking system for Waterfront I'll add this to the
> defect tracking system.  I can send along the wf.bat I'm using
> (modified to my paths of course) if it makes a difference.  When I
> initially saw this issue Clojure was sitting in a directory name with
> spaces (something like "My Documents\Desktop") so I moved it to a
> directory that should be fine under 8.3 and that didn't make a
> difference.
>
> --
> Onorio Catenacci
--~--~-~--~~~---~--~~
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 - The Clojure-based editor for Clojure

2009-02-25 Thread Itay Maman

For those of you who tried one of Waterfront's earlier revisions and
then switched to revision 147 (latest):

In 147 there was a change in the plugin loading order (due to plugin
dependencies). If you ran earlier versions you will get the following
message as Waterfront is launching:
   Can't load plugin output-window.clj. Reason: nil
   Can't load plugin eval-as-you-type.clj. Reason: nil

Here's the fix: close all Waterfront windows. Go to the directory
indicated by Java's user.home property (typically: c:\windows
\documents and settings\ or your Unix/Linux home
directory) and delete the file ".waterfront.config.clj".

-Itay


On Feb 25, 3:49 pm, Jeffrey Straszheim 
wrote:
> Count me interested also.
>
> On Wed, Feb 25, 2009 at 7:49 AM, Itay Maman  wrote:
>
> > On Feb 25, 11:48 am, linh  wrote:
> > > where can i read about "application context" pattern?
> > It is something I had occasionally used in the past. As I started
> > working on Waterfront, I realized it is well suited for GUI apps in
> > a functional language. I am not sure where you can find information
> > about
> > it, it is just something that was sitting there in my head.
>
> > Anyway, I plan to write a more detailed description of this pattern
> > as it addresses a concrete need of Clojure developers. Hope to get
> > to that within the next few days.
>
> > -Itay
>
> > > i this the idiomatic way to write GUI in functional languages?
> > > i'm writing a small swing based app in clojure, and i have problems
> > > wirting the gui, because the gui code tends to be very imperative and
> > > messy.
>
> > > On 24 Feb, 15:04, Itay Maman  wrote:
>
> > > > I've been silently following Clojure (and this group) for several
> > > > months now.Somewhere around December I started working on a Clojure
> > > > editor/REPL written in Clojure. This effort evolved into the
> > > > Waterfront project which is now available on sourceforge (http://
> > > > sourceforge.net/project/showfiles.php?group_id=249246).
>
> > > > Waterfront's Highlights:
>
> > > > * CTRL+E: Eval current selection, or the whole file if the selection
> > > > is empty
> > > > * Edit -> Eval as you type: When turned on (default) periodically
> > > > evaluates your code. Boosts productivity as many errors are detected
> > > > on the spot.
> > > > * Eval-ed code can inspect/mutate Waterfront by accessing the *app*
> > > > variable. For instance, if you eval this expression,
> > > > ((*app* :change) :font-name "Arial"), you will choose "Arial" as the
> > > > UI font.
> > > > * Eval-ed code can inspect the currently edited Clojure program. For
> > > > instance, if you eval this expression, ((*app* :visit) #(when (= (str
> > > > (first %1)) "cons") (println %1))), the output window will show all
> > > > calls, made by your code, to the cons function.
> > > > * Syntax and Evaluation errors are displayed on: (1) The Problems
> > > > window; (2) The line-number panel, as red markers.
> > > > * Source -> Generate -> Proxy: Generates a proxy for the given list of
> > > > super-types, with stub implementations for all abstract methods.
> > > > * F1: Shows the doc (as per Clojure's (doc x) function) of the
> > > > identifier under the caret.
> > > > * Source -> Reflect: Shows the synopsis of a Java class when the caret
> > > > stands on a class symbol (e.g.: java.awt.Color).
> > > > * CTRL+Space: Token-based auto completion.
> > > > * Full parenthesis matching.
> > > > * An extensible plugin architecture.
> > > > * Other goodies such as undo/redo, toggle comment, recently opened
> > > > files, indent/unindent, Tab is *always* two spaces, ...
>
> > > > In order to get started, you need to
> > > >   (1) Download the waterfront zip file from:
> >http://sourceforge.net/project/showfiles.php?group_id=249246.
> > > >   (2) Unpack it into a local directory.
> > > >   (3) Edit wf.bat: fix the path to clojure.jar according to its
> > > > location on your machine.
>
> > > > Personally, this effort was quite interesting. Writing GUI
> > > > applications in a functional language is sometimes a challenging task
> > > > (at least if you want your Clojure code not to be a transliteration of
> > > > Java code…).  I used a pattern the "application context&quo

Re: Waterfront - The Clojure-based editor for Clojure

2009-02-25 Thread Itay Maman



On Feb 25, 11:48 am, linh  wrote:
> where can i read about "application context" pattern?
It is something I had occasionally used in the past. As I started
working on Waterfront, I realized it is well suited for GUI apps in
a functional language. I am not sure where you can find information
about
it, it is just something that was sitting there in my head.

Anyway, I plan to write a more detailed description of this pattern
as it addresses a concrete need of Clojure developers. Hope to get
to that within the next few days.

-Itay


> i this the idiomatic way to write GUI in functional languages?
> i'm writing a small swing based app in clojure, and i have problems
> wirting the gui, because the gui code tends to be very imperative and
> messy.
>
> On 24 Feb, 15:04, Itay Maman  wrote:
>
> > I've been silently following Clojure (and this group) for several
> > months now.Somewhere around December I started working on a Clojure
> > editor/REPL written in Clojure. This effort evolved into the
> > Waterfront project which is now available on sourceforge (http://
> > sourceforge.net/project/showfiles.php?group_id=249246).
>
> > Waterfront's Highlights:
>
> > * CTRL+E: Eval current selection, or the whole file if the selection
> > is empty
> > * Edit -> Eval as you type: When turned on (default) periodically
> > evaluates your code. Boosts productivity as many errors are detected
> > on the spot.
> > * Eval-ed code can inspect/mutate Waterfront by accessing the *app*
> > variable. For instance, if you eval this expression,
> > ((*app* :change) :font-name "Arial"), you will choose "Arial" as the
> > UI font.
> > * Eval-ed code can inspect the currently edited Clojure program. For
> > instance, if you eval this expression, ((*app* :visit) #(when (= (str
> > (first %1)) "cons") (println %1))), the output window will show all
> > calls, made by your code, to the cons function.
> > * Syntax and Evaluation errors are displayed on: (1) The Problems
> > window; (2) The line-number panel, as red markers.
> > * Source -> Generate -> Proxy: Generates a proxy for the given list of
> > super-types, with stub implementations for all abstract methods.
> > * F1: Shows the doc (as per Clojure's (doc x) function) of the
> > identifier under the caret.
> > * Source -> Reflect: Shows the synopsis of a Java class when the caret
> > stands on a class symbol (e.g.: java.awt.Color).
> > * CTRL+Space: Token-based auto completion.
> > * Full parenthesis matching.
> > * An extensible plugin architecture.
> > * Other goodies such as undo/redo, toggle comment, recently opened
> > files, indent/unindent, Tab is *always* two spaces, ...
>
> > In order to get started, you need to
> >   (1) Download the waterfront zip file 
> > from:http://sourceforge.net/project/showfiles.php?group_id=249246.
> >   (2) Unpack it into a local directory.
> >   (3) Edit wf.bat: fix the path to clojure.jar according to its
> > location on your machine.
>
> > Personally, this effort was quite interesting. Writing GUI
> > applications in a functional language is sometimes a challenging task
> > (at least if you want your Clojure code not to be a transliteration of
> > Java code…).  I used a pattern the "application context" pattern: an
> > immutable map describing the application's current state that is
> > passed around. This made it possible for most of Waterfront's code to
> > be purely functional. Consequently, plugins can accomplish a lot with
> > just a handful of lines. Many plugins span about 60 lines of code.
> > Vast majority of them are less than 200 LOC. The main module, ui.clj,
> > that implements the underlying engine is also less than 200 LOC. I
> > think this is a very good indication to Clojure's power.
>
> > Hope you'll find it useful. I'd be happy if anyone would like to join
> > and contribute to Waterfront. Your feedback, either on-line or
> > offline, will be highly appreciated.
>
> > --
> > Itay Mamanhttp://javadots.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: Waterfront - The Clojure-based editor for Clojure

2009-02-25 Thread Itay Maman


On Feb 25, 11:08 am, bOR_  wrote:
> I'm trying to rewrite the wf.bat to a linux version, but I was a bit
> puzzled what all the ;%~dp0 's mean.

In .bat files %~dp0 specifies the directory where the .bat file is
located.
In sh scripts, it should be `dirname $0`.

>Apparently the bash version of it
> is ${0%/*}
>
> java -cp ~/src/clojure/clojure.jar;${0%/*}clj;${0%/*}java -
> Dnet.sourceforge.waterfront.plugins=${0%/*}clj/net/sourceforge/
> waterfront/ide/plugins clojure.main ${0%/*}clj/net/sourceforge/
> waterfront/ide/main.clj %*
>
> It seems like you're also assuming 'clj' to exist?
>

clj and java are the subdirectories in the Waterfront installation
directory. So if the zip was unzipped
successfully, it is safe to assume they exist.

I don't have a Linux machine. Could you send me this script (one it is
up and running)
so that I will put it inside the .zip file?

Thanks,
-Itay


> On Feb 25, 2:57 am, Kevin Albrecht  wrote:
>
> > Itay,
>
> > I took a look at Waterfront and it seems to have a lot of potential.
> > Keep me and the group updated on your future work.
>
> > I have also been working on a GUI application in Clojure and I share
> > your perspective on the challenges of designing a functional GUI.  I
> > am definitely intrigued by the application context pattern and I am
> > going to take a look at it for incorporation in my design.
>
> > Thanks,
> > Kevin Albrecht
>
> > On Feb 24, 6:04 am, Itay Maman  wrote:
>
> > > I've been silently following Clojure (and this group) for several
> > > months now.Somewhere around December I started working on a Clojure
> > > editor/REPL written in Clojure. This effort evolved into the
> > > Waterfront project which is now available on sourceforge (http://
> > > sourceforge.net/project/showfiles.php?group_id=249246).
>
> > > Waterfront's Highlights:
>
> > > * CTRL+E: Eval current selection, or the whole file if the selection
> > > is empty
> > > * Edit -> Eval as you type: When turned on (default) periodically
> > > evaluates your code. Boosts productivity as many errors are detected
> > > on the spot.
> > > * Eval-ed code can inspect/mutate Waterfront by accessing the *app*
> > > variable. For instance, if you eval this expression,
> > > ((*app* :change) :font-name "Arial"), you will choose "Arial" as the
> > > UI font.
> > > * Eval-ed code can inspect the currently edited Clojure program. For
> > > instance, if you eval this expression, ((*app* :visit) #(when (= (str
> > > (first %1)) "cons") (println %1))), the output window will show all
> > > calls, made by your code, to the cons function.
> > > * Syntax and Evaluation errors are displayed on: (1) The Problems
> > > window; (2) The line-number panel, as red markers.
> > > * Source -> Generate -> Proxy: Generates a proxy for the given list of
> > > super-types, with stub implementations for all abstract methods.
> > > * F1: Shows the doc (as per Clojure's (doc x) function) of the
> > > identifier under the caret.
> > > * Source -> Reflect: Shows the synopsis of a Java class when the caret
> > > stands on a class symbol (e.g.: java.awt.Color).
> > > * CTRL+Space: Token-based auto completion.
> > > * Full parenthesis matching.
> > > * An extensible plugin architecture.
> > > * Other goodies such as undo/redo, toggle comment, recently opened
> > > files, indent/unindent, Tab is *always* two spaces, ...
>
> > > In order to get started, you need to
> > >   (1) Download the waterfront zip file 
> > > from:http://sourceforge.net/project/showfiles.php?group_id=249246.
> > >   (2) Unpack it into a local directory.
> > >   (3) Edit wf.bat: fix the path to clojure.jar according to its
> > > location on your machine.
>
> > > Personally, this effort was quite interesting. Writing GUI
> > > applications in a functional language is sometimes a challenging task
> > > (at least if you want your Clojure code not to be a transliteration of
> > > Java code…).  I used a pattern the "application context" pattern: an
> > > immutable map describing the application's current state that is
> > > passed around. This made it possible for most of Waterfront's code to
> > > be purely functional. Consequently, plugins can accomplish a lot with
> > > just a handful of lines. Many plugins span about 60 lines of code.
> > > Vast majority of them are less than 200 LOC. The main module, ui

Re: Waterfront - The Clojure-based editor for Clojure

2009-02-24 Thread Itay Maman

After a few hours of intense work I managed to port Waterfront's code
to Clojure's latest snapshot. This version is now available for
download as "RC1-147" at the same location (http://sourceforge.net/
project/showfiles.php?group_id=249246).

This version is fully functional and so far I didn't encounter any
bugs.
I guess that over the course of the next few days, as people start
using this version,
a few issues may come up. I'd be glad to fix these.

I also took Mike's suggestion, Waterfromt's main window is now using
a side-by-side layout.

--
Itay Maman
http://javadots.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: Waterfront - The Clojure-based editor for Clojure

2009-02-24 Thread Itay Maman



On Feb 24, 10:22 pm, AlamedaMike  wrote:
> Thanks for this Itay.Very sweet.  I've been running it against the
> Dec. 17th download and it works fine on Vista SP1. I'm particularly
> impressed with the quality of the error messages.

Thanks

>
> A few suggestions / questions:
>
> * there's a lot of whitespace to the right even when I don't have the
> window maximized. Would you consider making the current top and bottom
> views side-by-side? Much less wasted space, I think.

I agree with you. Somewhere down the road I want the layout to be
completely flexible. Till then I will try to do something less
general.


>
> * I'm trying to get the reflect operation to work. Sample source code:
>
> (defn in-circle? [[x y]]
>   (<= (Math/sqrt (+ (* x x) (* y y))) 1))
>
> When I put the cursor anywhere on Math/sqrt or else highlight it and
> then select "reflect" from the source menu, I get "I could not
> evaluate the symbol 'Math/sqrt'". Ideas?
>

Yes. The symbol detection takes the whole thing, "Math/sqrt", as a
single token.
Reflect, OTOH, expects class symbols. Thus, the workaround is this:
highlight only the "Math" part and then choose Reflect.

--
Itay Maman
http://javadots.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: Waterfront - The Clojure-based editor for Clojure

2009-02-24 Thread Itay Maman

All, thanks so much for the feedback.
I am working on adapting Waterfront to the Clojure's latest snapshot.
Will let you know when this process is complete. Till then it can be
tried with Clojure's previous version (Dec.17).

-Itay


On Feb 24, 6:32 pm, Itay Maman  wrote:
> I built it against the latest download 20081217 (SVN Revision: 1173)
>
> -Itay
>
> On Feb 24, 6:19 pm, Tom Ayerst  wrote:
>
> > This is an interesting idea and a lightweight IDE distributed in contrib
> > would be a great addition IMHO.
>
> > I have tried it (on Windows using a pre-lazy version of clojure) and it
> > doesn't react to any events (though it does repaint after other apps windows
> > are dragged over it).  What version of clojure did you build it agaisnt?
>
> > Thanks
>
> > Tom
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Waterfront - The Clojure-based editor for Clojure

2009-02-24 Thread Itay Maman

I built it against the latest download 20081217 (SVN Revision: 1173)

-Itay


On Feb 24, 6:19 pm, Tom Ayerst  wrote:
> This is an interesting idea and a lightweight IDE distributed in contrib
> would be a great addition IMHO.
>
> I have tried it (on Windows using a pre-lazy version of clojure) and it
> doesn't react to any events (though it does repaint after other apps windows
> are dragged over it).  What version of clojure did you build it agaisnt?
>
> Thanks
>
> Tom
>
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Waterfront - The Clojure-based editor for Clojure

2009-02-24 Thread Itay Maman

Ooops...
Sorry for the multiple posting. Seems to be some glitch.

-Itay

--~--~-~--~~~---~--~~
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 - The Clojure-based editor for Clojure

2009-02-24 Thread Itay Maman

I've been silently following Clojure (and this group) for several
months now.Somewhere around December I started working on a Clojure
editor/REPL written in Clojure. This effort evolved into the
Waterfront project which is now available on sourceforge (http://
sourceforge.net/project/showfiles.php?group_id=249246).

Waterfront's Highlights:

* CTRL+E: Eval current selection, or the whole file if the selection
is empty
* Edit -> Eval as you type: When turned on (default) periodically
evaluates your code. Boosts productivity as many errors are detected
on the spot.
* Eval-ed code can inspect/mutate Waterfront by accessing the *app*
variable. For instance, if you eval this expression,
((*app* :change) :font-name "Arial"), you will choose "Arial" as the
UI font.
* Eval-ed code can inspect the currently edited Clojure program. For
instance, if you eval this expression, ((*app* :visit) #(when (= (str
(first %1)) "cons") (println %1))), the output window will show all
calls, made by your code, to the cons function.
* Syntax and Evaluation errors are displayed on: (1) The Problems
window; (2) The line-number panel, as red markers.
* Source -> Generate -> Proxy: Generates a proxy for the given list of
super-types, with stub implementations for all abstract methods.
* F1: Shows the doc (as per Clojure's (doc x) function) of the
identifier under the caret.
* Source -> Reflect: Shows the synopsis of a Java class when the caret
stands on a class symbol (e.g.: java.awt.Color).
* CTRL+Space: Token-based auto completion.
* Full parenthesis matching.
* An extensible plugin architecture.
* Other goodies such as undo/redo, toggle comment, recently opened
files, indent/unindent, Tab is *always* two spaces, ...

In order to get started, you need to
  (1) Download the waterfront zip file from:
http://sourceforge.net/project/showfiles.php?group_id=249246.
  (2) Unpack it into a local directory.
  (3) Edit wf.bat: fix the path to clojure.jar according to its
location on your machine.

Personally, this effort was quite interesting. Writing GUI
applications in a functional language is sometimes a challenging task
(at least if you want your Clojure code not to be a transliteration of
Java code…).  I used a pattern the "application context" pattern: an
immutable map describing the application's current state that is
passed around. This made it possible for most of Waterfront's code to
be purely functional. Consequently, plugins can accomplish a lot with
just a handful of lines. Many plugins span about 60 lines of code.
Vast majority of them are less than 200 LOC. The main module, ui.clj,
that implements the underlying engine is also less than 200 LOC. I
think this is a very good indication to Clojure's power.

Hope you'll find it useful. I'd be happy if anyone would like to join
and contribute to Waterfront. Your feedback, either on-line or
offline, will be highly appreciated.

--
Itay Maman
http://javadots.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: making code readable

2008-12-29 Thread Itay Maman

I think that just as important as "compactness" is the issue of
"density": the ratio
of the "conceptual weight"of the computation to the size of the code
expressing it.

if a computation is inherently complicated and I manage to squeeze it
into
a few lines (typically accomplished via an intense cognitive effort)
the resulting
code is usually hard to understand/maintain/debug because you need to
be
acquainted with all sorts of little truths and insights which are not
obvious for the casual
reader. This is what I call a high density code.

Given that Clojure is a very powerful language, I often find my self
in a situation
where I mange to write highly dense code, sometimes at the expense of
readability. In such
cases I think that the use of explaining variables, and simplified-but-
somewhat-longer expressions
is desirable.

OTOH, if the code is inherently simple (e.g.: a chain of straight-
forward transformations on a collection)
I think that using Clojure's power to reduce the line count by a
factor of more than 5  (compared to, say, Java),
is highly beneficial.

The predicament is that there's no objective way to measure
"conceptual weight" nor "density" so
this issue is largely a personal judgment call.

Just my 2c.

--
Itay Maman
http://javadots.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
-~--~~~~--~~--~--~---



Serializing functions

2008-12-29 Thread Itay Maman

I want to be able to read and write a clojure object, which contains
functions, from/to a file.

The structure looks something like this: { :s "my-string" :f (fn[x]
(inc x) }

Reading is easy: (load-file ...) works fine. The tricky part is
writing it back to the file. (pr ...) gives something like this: "{:s
"my-string", :f #}" which cannot
be subsequently read.

The only workaround I found is this:
I quote the function in the file (which means that it needs to
explicitly eval-ed when called).
Then, I save it like this:  (assoc my-map :f (cons 'quote (list (my-
map :f

Although this works it seems a bit cumbersome. I am pretty sure there
is a better way to do it. Any ideas?


Thanks,
-Itay

PS: This issue has been also mentioned at the  "Persistent storage"
discussion last week.






--~--~-~--~~~---~--~~
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: Functional way to implement a VM?

2008-12-22 Thread Itay Maman

No doubts this is very elegant. However, I think that the underyling
programming model is imperative:
there's a map which is essentially a RAM. Each instruction writes to
this RAM (alters the mappings in the map).

It seems that a stack-machine exhibits a more functional nature: an
instruction either pushes or pops values onto/off the stack, thereby
creating a local environment for subsequent computations.
This approach is outlined in this series:
http://www.codecommit.com/blog/cat/the-joy-of-concatenative-languages-part-1
(first chapter of three).


-Itay
http://javadots.blogspot.com

On Dec 22, 1:59 pm, Robert Feldt  wrote:
> On Dec 22, 12:27 pm, verec 
> wrote:> The design simplicity is certainly very appealing, though it appears
> > that you can only operate on a predetermined fixed set of
> > "registers" (ie: a and b in your example) and would need to define as
> > many add_, sub_, mul_ ... variants as there are 'registers' in your
> > model.
>
> Yes, although we can generalize:
>
> (defn addi [st reg i] {reg (+ (reg st) i)})
> (defn subi [st reg i] {reg (- (reg st) i)})
> (defn addr [st reg1 reg2] {reg1 (+ (reg1 st) (reg2 st))})
>
> user=> (vm-exec [[:addi :a 1] [:addi :a 3] [:subi :b 1]
> [:addr :a :b]])
> {:b -1, :a 3}
>
> > Also, simple arithmetic seems easy to implement, what about control
> > flow (tests, branches, calls...) ?
>
> Yes, the way I envisage it is to have explicit program counter and
> then assume instructions just increments it unless they set a new
> value for it. Instead of reduce in the vm-exec I have to loop and set
> the pc after each instruction.
>
> Cheers,
>
> Robert
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Recursive traversal of an object

2008-12-17 Thread Itay Maman

Hi,

I am trying to write a function that recursively traverses a given
object - applying a function to each node. Something along these
lines:

(defn traverse [f os]
  (f os)
  (when (coll? os)
(doseq [o os]
  (traverse f o

Although this fragment seems to be doing the job, I am not sure that
the underlying assumption - which is: everything that is not a
collection cannot be further decomposed - is true. Perhaps there's a
language construct that produces an object which is not a collection
but can be decomposed using some other mechanism?
(Seems highly unlikely, but I want to make sure that I am not missing
anything)

Thanks,
-Itay







I am

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