Re: Capitalize string
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
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?
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
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
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
(+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
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)
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)
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
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
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
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)
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
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)
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)
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.
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
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
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
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
> > 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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 -~--~~~~--~~--~--~---