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 da...@bosatsu.net 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 adrian.cuthbert...@gmail.com
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: 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 konrad.hin...@laposte.net wrote:
 On Mar 4, 2009, at 14:06, Mibu wrote:

  On Mar 4, 2:46 pm, Michael Wood esiot...@gmail.com wrote:
  On Wed, Mar 4, 2009 at 2:07 PM, Mibu mibu.cloj...@gmail.com 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: JavaWorld article

2009-03-04 Thread Itay Maman



On Mar 4, 7:33 pm, Joshua Fox joshuat...@gmail.com 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

Sorry, this was supposed to be offline

On Mar 4, 8:29 pm, Itay Maman itay.ma...@gmail.com wrote:
 On Mar 4, 7:33 pm, Joshua Fox joshuat...@gmail.com 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: 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 robert.fe...@gmail.com 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: 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 konrad.hin...@laposte.net 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
-~--~~~~--~~--~--~---



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 apero...@gmail.com 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 itay.ma...@gmail.com wrote:

  On Feb 25, 11:08 am, bOR_ boris.sch...@gmail.com 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 onlya...@gmail.com 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 itay.ma...@gmail.com 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

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 LF
is set at line 182 of net/sourceforge/waterfront/ide/ui.clj. Could you
please try to see which LF works on your machine or, otherwise,
understand why an exception is thrown there?

Thanks,
-Itay


On Feb 28, 12:58 am, Dan redalas...@gmail.com wrote:
  I'm not sure I understand. Are you referring to
  UIManager.getSystemLookAndFeelClassName() ?
  This is the LF that Waterfront is using. If you don't get this LF
  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 LF 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: The Application Context Pattern

2009-02-28 Thread Itay Maman



On Feb 28, 3:26 am, samppi rbysam...@gmail.com 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 itay.ma...@gmail.com 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

Re: The Application Context Pattern

2009-02-28 Thread Itay Maman

Hi,

On Feb 28, 8:32 pm, CuppoJava patrickli_2...@hotmail.com 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
-~--~~~~--~~--~--~---



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 time for the JLabel to 

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 patrickli_2...@hotmail.com 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
-~--~~~~--~~--~--~---



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 itay.ma...@gmail.com 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: Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)

2009-02-27 Thread Itay Maman



On Feb 27, 5:22 pm, Marko Kocić marko.ko...@gmail.com 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 LF that Waterfront is using. If you don't get this LF
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: 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 catena...@gmail.com 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-26 Thread Itay Maman



On Feb 26, 3:02 am, Stephen C. Gilardi squee...@mac.com 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 - The Clojure-based editor for Clojure

2009-02-26 Thread Itay Maman



On Feb 26, 2:02 pm, Konrad Hinsen konrad.hin...@laposte.net 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 - 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
-~--~~~~--~~--~--~---



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=browsegroup_id=249246atid=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'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 itay.ma...@gmail.com wrote:
 For those of you who encountered issues/bugs with Waterfront, you not
 submit reports 
 at:http://sourceforge.net/tracker2/?func=browsegroup_id=249246atid=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
-~--~~~~--~~--~--~---



Re: Waterfront - The Clojure-based editor for Clojure

2009-02-25 Thread Itay Maman


On Feb 25, 11:08 am, bOR_ boris.sch...@gmail.com 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 onlya...@gmail.com 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 itay.ma...@gmail.com 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:48 am, linh nguyenlinh.m...@gmail.com 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 itay.ma...@gmail.com 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

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\your user name or your Unix/Linux home
directory) and delete the file .waterfront.config.clj.

-Itay


On Feb 25, 3:49 pm, Jeffrey Straszheim straszheimjeff...@gmail.com
wrote:
 Count me interested also.

 On Wed, Feb 25, 2009 at 7:49 AM, Itay Maman itay.ma...@gmail.com wrote:

  On Feb 25, 11:48 am, linh nguyenlinh.m...@gmail.com 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 itay.ma...@gmail.com 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

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



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 tom.aye...@gmail.com 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

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 itay.ma...@gmail.com wrote:
 I built it against the latest download 20081217 (SVN Revision: 1173)

 -Itay

 On Feb 24, 6:19 pm, Tom Ayerst tom.aye...@gmail.com 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

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



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 #user$fn__895 user$fn__...@2dc62dc6} 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: 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 weightof 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
-~--~~~~--~~--~--~---



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 robert.fe...@gmail.com wrote:
 On Dec 22, 12:27 pm, verec jeanfrancois.brouil...@googlemail.com
 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
-~--~~~~--~~--~--~---