Re: Clojure blog post about laziness
Thanks Rich. I definitely appreciate the fuller explanation. It helped me understand what you've already tried, and what factors led to your design decision. You've given me a lot to think about. --~--~-~--~~~---~--~~ 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: Method overloading anomaly. (specifically ArrayList/remove)
CuppoJava a écrit : > That workaround works nicely for now. I think though that this problem > can potentially be the source of many hard-to-find bugs though. ie.. > like in my second example, the vector of ArrayLists. > You can ask to be warned: user=> (set! *warn-on-reflection* true) true user=> (let [temp [(java.util.ArrayList. ["foo"])]] (.remove (first temp) (int 0))) Reflection warning, line: 939 - call to java.util.ArrayList ctor can't be resolved. Reflection warning, line: 940 - call to remove can't be resolved. Christophe --~--~-~--~~~---~--~~ 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: adding line number while reading a file
(map vector (iterate inc 0) "foo") Emeka --~--~-~--~~~---~--~~ 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: adding line number while reading a file
> Next, instead of filter, you probably want doseq. The filter function > filters a collection according to a predicate. The doseq function > applies a function with side effects (such as println) to each item in > a collection. > > (with-open [rdr (reader "executors.clj")] > (doseq [[line index] (zip-index (line-seq rdr))] > (.println System/out (str (inc index) " " line Why would you use Java's (.println System/out ...) instead of (println ...)? Gavin [first post] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: In core structure editor, anyone?
Here is a link to an article comparing structure editors with other approaches to code editing. Seems apropos to this discussion. http://web.media.mit.edu/~lieber/Lieberary/Softviz/CACM-Debugging/Already-Full/Already-Full.html Also, anyone wanting to play with Interlisp's structure editor can do so without too much trouble. Just create a virtual machine (I used vmware player and it works fine), install damn small linux (with a 2.4 kernel) to it and download the software from: ftp://ftp.parc.xerox.com/pub/lfg/ *note that the license prohibits exporting the software to among others, Yugoslavia. So please refrain from travelling back in time and trafficking in the software* (it is a piece of software written inside a lisp development environment which runs among other lisps, Interlisp). Then either install csh (I didn't) or just modify the startup shell script to use the included bash shell. Now, you'll be able to interactively follow along the Interlisp Primer mentioned before in this discussion; specifically section "11.3 Using The List Structure Editor". On Dec 11 2008, 8:08 am, falcon wrote: > Can't say I understood all of it (being a LISP noob) but appreciate > the explanation. > > Does the following fit into the current discussion? > > Barista editor:http://faculty.washington.edu/ajko/barista.shtml > > Barista editor is based on > Citrushttp://faculty.washington.edu/ajko/citrus.shtml > > The citrus page has some _VERY_ cool videos. They are worth watching, > just for entertainment value (entertainment for developers only > though). > > On Dec 11, 9:32 am, "evins.mi...@gmail.com" > wrote: > > > On Dec 10, 2:59 pm, falcon wrote: > > > > Could you describe in-core editing a bit more? Sounds interesting. > > > The canonical structure editor (not "structured editor") is probably > > Interlisp-D's SEDIT, or its predecessor DEDIT. > > (Seehttp://bitsavers.org/pdf/xerox/interlisp/3102300_interlDprimer_Nov86.pdf > > for an archive of Interlisp docs, including docs on SEDIT.) Interlisp > > was for a while one of a couple major dialects of Lisp, along with > > MACLISP, that were perhaps the most widely used dialects. There were > > lots of dialects of lisp in fairly wide use; Common Lisp was intended > > to merge the most common idioms in use across a lot of dialects > > without losing *too* much of the facilities of any one popular > > dialect, but Common Lisp might perhaps resemble MACLISP a little more > > than it resembles Interlisp. > > > Interlisp was the system programming language for the Xerox D-machine > > series. > > > A structure editor, as exemplified by SEDIT, does not operate on text > > in a file buffer; instead, it operates on the lisp data structures > > represented by the text. When you edit lisp code in emacs, even with a > > utility like Paredit, which helps you with the syntactic structure, > > you are operating on text characters stored in some sort of array. > > There is a connection between the text and what the lisp reader > > produces in memory, but you operate on the text, not on the in-memory > > lisp objects that are represented by the text. > > > Structure editors are different: they operate on the in-memory data > > structures. > > > Consider a lisp (or Clojure) list, (a b). This list is a chain of cons > > cells, where a cons cell is a pair of pointers. The left pointer > > points to the symbol 'a'; the right one points to a second cons cell. > > In the second cons cell, the left pointer points to the symbol 'b' and > > the right one points to nil. > > > Now consider the text "(a b)", as seen by some editor. It's a row of > > character values: '(', 'a', ' ', 'b', ')'. > > > The lisp (or Clojure) reader converts that row of characters into the > > chain of cons cells described above; the printer converts the chain of > > cons cells into the row of characters. There is necessarily a close > > correspondence between the text and the in-memory objects, but they > > are not the same thing. > > > Text editors edit text. Structure editors edit the in-memory data > > structures. > > > This might be a good place to repeat that in lisp, and perhaps in > > Clojure, I'm not sure, the code is not the text; it's the in-memory > > objects. This differs from most programming languages. In most > > languages, when you say "source code," you mean text. Strictly > > speaking, the text in a ".lisp" text file is not the source code for a > > lisp program; it is a text description of lisp source code; the actual > > source code is constructed by the lisp reader when it reads the file. > > Indeed, given the syntactic rules of Common Lisp, it's possible to > > have two very different text files that contain (text specifications > > for) exactly the same source code. > > > Most of the time, this distinction is pretty much academic, because of > > the close and necessary correspondence between lisp source code and > > its textual representation. There are a few places where the > > differ
XML Pretty Printer
I've written a small XML pretty printing library that may be useful for debugging XHTML or XML outputs, especially those generated from libraries like clj-html or compojure.html. Usage is straightforward: => (use 'ppxml) nil => (ppxml "Hello") Hello I've uploaded the library to the group: http://groups.google.com/group/clojure/web/ppxml.clj I'm not sure if this is useful and generic enough to qualify for clojure-contrib, but if anyone feels that it is, they are welcome to add it :) - James --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
java static method call anomaly
Hi, thanks for a great language and discussion group ! I got an error calling a static method on a java class using the new calling form. I am using the december release of Clojure from the download page (on windows XP, java 6) Is this a bug, or is it a difference between (.method Class) and (. Class (method)) that tricks me here? I am calling newInstance() on javax.xml.transform.TransformerFactory, and in the first case it fails and in the second it works as I would expect: user=> (def tf (.newInstance javax.xml.transform.TransformerFactory)) java.lang.IllegalAccessException: Class clojure.lang.Reflector can not access a member of class javax.xml.transform.TransformerFactory with modifiers "protected" (NO_SOURCE_FILE:26) user=> (def tf (. javax.xml.transform.TransformerFactory (newInstance))) #'user/tf user=> tf # user=> --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
pre newbie entrance
Thanks in advance, and feel free to ignore ... if this sounds too much like I'm being lazy or too complainy. It's not at all a very well organized post. Consider it a sort of "raw" impression, having checked out some of the movies, some of the docs, and the "getting started" link. I'm also not a Lisp programmer having only used it a bit in school. Perhaps it would be best to just work my way through getting up and going with clojure the way any problem can be handled. . . . breaking it down. . . . .Doing the parts you know how to until you get to a question you can't solve . . . or working on the parts you can't solve first, breaking them down until they are of solvable size. Concretely, this would mean following the "Getting Started" instructions on clojure.org. Then seeing what there is to see . . . I assume some sort of command line for doing "REPL" will come up as it says? But what about using other libraries? I mean, eclipse makes it so you don't even have to really understand classpaths. You can start eclipse, pick a compiler from anywhere on your machine (I assume here, you'd be picking the compiler your reader would use?), pick the jvm programs are going to run in (I assume here it has to be the same as what the REPL is using?), and select any number of dependent projects. I expect this to be different from the eclipse experience, but I like to have sort of a picture of what to expect to at least have some idea that there's SOME path to success. So here's what's odd to me: how come it isn't clear how someone would go about making an application for an end user? I mean, it seems like clojure is for developers to use in a REPL. That just can't be the only use case, right? I'm wondering if one is supposed to write some sort of launcher in java that gets the reader up and running that then reads all the clojure stuff you feed it from your java program? If this is the case, I can see how to make other libraries available . . . just add them to the classpath when running the java main. And how should projects be broken down in clojure? You know what? There's no hello world program! That's what it feels like. I could be wrong. Is there? Is it on the getting started page and I missed it? Again, I'm sure I could start swimming through contribs and try to figure out how files map to what I would think of as a "program" that a user would run directly (not from some REPL environment) . . . . but any help up front would probably save me some time. On the other hand, if seeing for myself is important, ignore my reluctance, and advise thusly. Maybe I'll get a million replies saying, "the docs come with the download. why not download and see?". Or maybe I'll get zero responses because this post makes no sense. Or, who knows, maybe there will be a lot of people who say, "yeah, I've had all the same questions!" Anyway, I took Rich's advice and joined this, my first discussion group, so thanks again for bearing with me. - e --~--~-~--~~~---~--~~ 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: pre newbie entrance
On Jan 10, 4:54 pm, e wrote: > Concretely, this would mean following the "Getting Started" > instructions on clojure.org. Then seeing what there is to see . . . I > assume some sort of command line for doing "REPL" will come up as it > says? The Wiki covers getting started in much more detail: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started - James --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: adding line number while reading a file
On Jan 10, 1:17 pm, GS wrote: > > (with-open [rdr (reader "executors.clj")] > > (doseq [[line index] (zip-index (line-seq rdr))] > > (.println System/out (str (inc index) " " line > > Why would you use Java's (.println System/out ...) instead of > (println ...)? Because println is, I think, a recent addition to the Clojure API and I didn't know about it :) - James --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: pre newbie entrance
ah, this is useful, too: http://clojure.org/compilation On Jan 10, 12:39 pm, James Reeves wrote: > On Jan 10, 4:54 pm, e wrote: > > > Concretely, this would mean following the "Getting Started" > > instructions on clojure.org. Then seeing what there is to see . . . I > > assume some sort of command line for doing "REPL" will come up as it > > says? > > The Wiki covers getting started in much more detail: > > http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started > > - James --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: pre newbie entrance
> > > Concretely, this would mean following the "Getting Started" > instructions on clojure.org. Then seeing what there is to see . . . I > assume some sort of command line for doing "REPL" will come up as it > says? > Yes, "Getting Started" will show you how to start the REPL. I think that's near the beginning. > But what about using other libraries? I mean, eclipse makes it so you > don't even have to really understand classpaths. You can start > eclipse, pick a compiler from anywhere on your machine (I assume here, > you'd be picking the compiler your reader would use?), pick the jvm > programs are going to run in (I assume here it has to be the same as > what the REPL is using?), and select any number of dependent projects. Eclipse has a lot of nice features for writing Java code. I consider the REPL to be worth about as much as Eclipse's nice features, although it would still be nice to have both. I would prefer to use Clojure with notepad.exe and no REPL than Java with Eclipse. Clojure with an REPL and a decent editor is even better. Yes, I think you need to understand classpaths if you are working with Java code. > So here's what's odd to me: how come it isn't clear how someone would > go about making an application for an end user? I mean, it seems like > clojure is for developers to use in a REPL. That just can't be the > only use case, right? I am working on web applications, in which end users can use my application while it is running on my server in an REPL. That is actually how I prefer to work. I wrote an article about setting up "hello world" as a Clojure/Compojure web application. http://ericlavigne.wordpress.com/2008/12/18/compojure-on-a-slicehost-vps/ You can also choose between Repl and Script. The script option is closer to what you would expect. > I'm wondering if one is supposed to write some sort of launcher in > java that gets the reader up and running that then reads all the > clojure stuff you feed it from your java program? If this is the > case, I can see how to make other libraries available . . . just add > them to the classpath when running the java main. > There are two launchers: Repl and Script. Choose Repl for interactive programming, Script to run a program. Repl and Script are Java classes, and yes you need to set the classpath in the usual manner as in Java. You will also need to use Clojure's "import" command, which is similar to Java's "import." > Anyway, I took Rich's advice and joined this, my first discussion > group, so thanks again for bearing with me. > Welcome to Clojure. -- Education is what survives when what has been learned has been forgotten. - B. F. Skinner --~--~-~--~~~---~--~~ 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: java static method call anomaly
Hi, Am 10.01.2009 um 17:28 schrieb gammelgedden: Is this a bug, or is it a difference between (.method Class) and (. Class (method)) that tricks me here? I'm not sure about the protected stuff, since I don't have a Java background. But for the Clojure side: static Java methods are called using the / notation: (Class/staticMethod) Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: java static method call anomaly
Hi gammelgedden, I've also just recently figured out the reasoning behind Clojure's (Class/staticMethod) notation. (.newInstance TransformerFactory) This notation always expects the second argument to be an object of some sort. This means that TransformerFactory is actually being resolved as a Class object. So you're calling TransformerFactory.getClass().newInstance(); As Meikel mentioned, the correct way to call static methods is (TransformerFactory/newInstance) --~--~-~--~~~---~--~~ 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: Method overloading anomaly. (specifically ArrayList/remove)
After a bit more experimenting, I found the following workaround to be suitable for the time-being in case anyone else is having similar troubles. (defn arraylist_remove [#^ArrayList list index] (.remove list (int index))) --~--~-~--~~~---~--~~ 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: SLIME: trouble with java.lang.OutOfMemoryError
After talking to Jeffrey Chu, it seems like what is actually happening is possibly fairly obvious (in retrospect) - the java process runs out of heap space, and there's not even enough memory to keep swank- clojure working properly. Jeffrey tried some examples with just a plain REPL (without SLIME), and managed to get a dead REPL after causing an out of memory error, so there may be more fundamental lower level things going on, and it's not clear that this can really be addressed on the SLIME side. I'm not sure what a good solution to this problem would be, but I thought I'd post an update for anyone who was curious what the actual issue was. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure blog post about laziness
>From my limited understanding it seems that a lazy data structure must at some point reify and therefore be cached, to my mind, the alternative is better describes as a stream or generator. That is not to say that said stream is not the source of the reification but that it might be better to keep the two concepts separate for the purposes of deciding what abstraction one needs in a particular case. I don't have the gray matter to fully understand what is being discussed but it is absolutely fascinating to see the strength and depth of the community around clojure. On Jan 8, 10:20 am, Rich Hickey wrote: > On Jan 8, 2009, at 1:06 PM, Mark Engelberg wrote: > > > > > > > On Thu, Jan 8, 2009 at 5:55 AM, Rich Hickey > > wrote: > >> The > >> promise of the abstraction is not merely that the nth item/rest will > >> be equal - it is that it will be identical. I.e. a seq is persistent > >> and immutable. > > > I get that Clojure is making a promise of identity here, which is not > > possible if things uncached. But I look at this from a pragmatic > > standpoint and wonder how much people are relying on that promise? I > > notice that I haven't written any code that uses identical? And if I > > did, I don't think I'd mind the overhead of explicitly wrapping the > > sequence in a call to cache-seq. If people don't need this promise as > > a rule, maybe it's okay to rethink the abstraction, and start thinking > > of it as just a way to get the "first" and "rest" of a bunch of items, > > possibly generated by need, and with no other promises implied. > > I think the real test of non-cached seqs is to swap them in for > regular seqs, rebuild Clojure and some user libs and see what breaks > and why. Then you'll see the dependencies on caching that exist in the > real world. Your purely functional code might not care, other than > perf, but that is not the only user base Clojure and I need to support. > > Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: SLIME: trouble with java.lang.OutOfMemoryError
I don't think it is possible to define a way to deal with heap saturation that is general enough to cover all programs written in Clojure, and therefor I don't think this is something that the Clojure runtime should deal with at all. Personally, I only know of two ways to handle OutOfMemoryErrors: 1) let the program blow up and hope someone notices or 2) look at your body, pick the limb you are least likely to be needing pretty soon and cut it off (aka. free some memory) and _then_ yell for help through some hopefully reliable channel. On Sat, Jan 10, 2009 at 9:03 PM, Paul Mooser wrote: > > After talking to Jeffrey Chu, it seems like what is actually happening > is possibly fairly obvious (in retrospect) - the java process runs out > of heap space, and there's not even enough memory to keep swank- > clojure working properly. Jeffrey tried some examples with just a > plain REPL (without SLIME), and managed to get a dead REPL after > causing an out of memory error, so there may be more fundamental lower > level things going on, and it's not clear that this can really be > addressed on the SLIME side. > > I'm not sure what a good solution to this problem would be, but I > thought I'd post an update for anyone who was curious what the actual > issue was. > > > > -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Ugly Sudoku solver
Thanks Konrad A very elegant solution. 40 years of laziness, and I finally realize what a great feature the lazy evaluation is ;) Tzach On Jan 9, 3:30 pm, Konrad Hinsen wrote: > On Jan 9, 2009, at 13:18, Tzach wrote: > > > > > The main functionsudokuis recursive: > > 1. Getting asudokuboard as an input > > 2. Choosing the next empty (zero) cell to test, loop on all valid > > values, and callsudokuwith the new board > > 3. When a solution (board with no zero values) is found: throw. > > > (defnsudoku[board] > > "solve asudokuproblem" > > (when (complete? board) > > (do > > (println "complete") > > (print-board board) > > (throw nil))) > > (let [cell (next-cell board) > > pos (first cell) > > valid-values (second cell)] > > (when cell > > (doseq [v valid-values] > > (sudoku(assoc-in board pos v))) > > ))) > > > Although it does work, we can all agree its pretty ugly, so I would > > appreciate your help on the following questions: > > 1. How to can I return a solution via the recursive stack with out > > throwing an exception? I understand there is no "return-from" > > facility. > > The return value of a function is the last expression that was > evaluated. Yoursudokufunction could have a structure like this: > > (defnsudoku[board] > "solve asudokuproblem" > (if (complete? board) > board > (let [...] > ..)) > > The problem is then in the let branch, as it can terminate without > returning a valid board. > > > 2. Can this function be implemented as tail recursive (using loop? > > recur?) > > As it is, no, because you have multiple recursive calls. However, I > wonder what those are good for. If I understand your algorithm > correctly, it find all valid values for the next cell to be filled, > and then tries for each of them to complete the puzzle, using a > recursive call. > > I would rewrite the solver as a function that returns a lazy sequence > of valid solutions: > > (defn all-solutions [board] > (if (complete? board) > (list board) > (let [[pos valid-values] (next-cell board)] > (apply concat (for [v valid-values] > (all-solutions (assoc-in board pos v))) > > Note that you don't have to do anything to make the sequences lazy; > apply and for take care of that automatically. > The solver then just takes the first item of that sequence: > > (defnsudoku[board] > "solve asudokuproblem" > (first (all-solutions board))) > > Since the sequence is lazy, the remaining solutions (if any) are > never computed, so this version does not do more work than your > original one. > > 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: SLIME: trouble with java.lang.OutOfMemoryError
i wondered about this when I was asking about eclipse analogies. The vm that runs a program that you are writing should have nothing to do with the vm your editor is using. Maybe there should be some way for the actual running program to be in one VM, and then the REPL communicates to it via RMI. I know Rich talks about a new model for distributed concurrency ... seems like the whole program should optionally run in such a distributed (interprocess) thread. RMI, xml rpc, jms. Then one thing running out of memory has nothing to do with the other. on another aside that is mostly a rant ... totally ignorable, and not directly on topic: Nobody ever dings clojure, and I can't because I don't know it. I'm excited to (attempt to) learn it despite the fact that one major thing I was looking for in a new language is one that starts it's design thinking about the IDE . . . .actually building an IDE and letting the language follow in test-driven manner. Zero configuration. J somewhat seems like that, though I don't know if it started like that, but there isn't any syntax highlighting. Like, I don't really program in Java. I program in Eclipse . . . which assists me in writing java. Maybe I just think an IDE should have a GUI builder, project manager, version control, reviewing and markup (collaboration), wiki, milestone calendar, doc-builder that ties code to the docs, debugging, packaging, obfuscating, etc. You download language x. You run the launcher for language x. An IDE pops up. As you code, the IDE has some sort of "build" or "deliver" button, nevermind the REPL part that is useful during development ... that makes something you can give to a user. That sort of thing is what makes a language accessible to the masses. Is there a discussion group of project underway to make a dedicated IDE or Eclipse plugin for clojure? And . it's asking a lot to ask the next generation to make emacs their friend. It seems like that's what I'll need to do for now with clojure, right? And I wont have dot completion, I'm thinking even for java stuff (the main place I see dots). I guess what I am saying is that I actually pick the language based on the editor. I pick java over c# because I enjoy Eclipse way more than every time I've had to try to use visual studio (although that seems to finally be getting a little better). Maybe we at least need a jEdit plugin for clojure. On Jan 10, 3:03 pm, Paul Mooser wrote: > After talking to Jeffrey Chu, it seems like what is actually happening > is possibly fairly obvious (in retrospect) - the java process runs out > of heap space, and there's not even enough memory to keep swank- > clojure working properly. Jeffrey tried some examples with just a > plain REPL (without SLIME), and managed to get a dead REPL after > causing an out of memory error, so there may be more fundamental lower > level things going on, and it's not clear that this can really be > addressed on the SLIME side. > > I'm not sure what a good solution to this problem would be, but I > thought I'd post an update for anyone who was curious what the actual > issue was. --~--~-~--~~~---~--~~ 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: java static method call anomaly
Thanks, for your responses I have to read a bit more on that, I am not sure i fully understand, but I see that your suggestions work :-) --~--~-~--~~~---~--~~ 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: SLIME: trouble with java.lang.OutOfMemoryError
Try this: http://github.com/djspiewak/jedit-modes/tree/master/clojure.xml I work with Eclipse on a daily basis because of the java code base I have to deal with but it was asking my computer to carry an elephant until... I got my hands on a quad-core with 6 Gig of RAM and I had loaded in RAM at boot time all the tools I use regularly. Eclipse is useful to java because of all the bureaucratic configuration you need to create a Java app with almost every framework (I use Spring). You need wizards to create stuff, heavy validation tools to keep your code and XML configurations in sych, an integrated Java debugger, ... I started to work with Clojure in fall and used Scite after adding a Clojure mode to it by cloning the lisp mode and making mods to it. Later I tried Vim and JEdit also. I started using Emacs 3 weeks ago just to refresh my memory (I was using Emacs in the mid-80s). I do not use SLIME, just a separate REPL and I reload code when I update a file or just cut & paste in the terminal window. Whether you use Emacs or another language sensitive editor does not make a huge difference. SLIME is a nice add-on but it may be confusing and there still a couple of issues to fix about the SLIME Clojure mode. I tried it but tossed it away for a couple of months by necessity, I will come back to it when it will have matured a bit. I do not see any need for Eclipse to code in Clojure since the amount of code written compare to Java is much more smaller. Eclipse for Clojure is like using a dead blow mallet to hang a picture. A light language sensitive editor is what you need to track all these parenthesis :))) For debugging I am happy with JSWat but I do not need it very often. The core of the learning curve is to understand the functional language concepts and how Clojure implements these concepts plus the ones specific to Clojure, not the syntax. I walked this learning curve while coding in Clojure for a system that will be in production next Monday and all of that without Eclipse... I am old, my brains have burned a lot of cells along the way and I am not as fast as I used to be when I started programming :))) so if I can do it, I expect that others can do so... For me Eclipse is like getting a wheeled walker, that's the step just before my own death, I use it when there's not other choice than crawling inch by inch : Luc On Sat, 2009-01-10 at 12:35 -0800, e wrote: > i wondered about this when I was asking about eclipse analogies. The > vm that runs a program that you are writing should have nothing to do > with the vm your editor is using. Maybe there should be some way for > the actual running program to be in one VM, and then the REPL > communicates to it via RMI. I know Rich talks about a new model for > distributed concurrency ... seems like the whole program should > optionally run in such a distributed (interprocess) thread. RMI, xml > rpc, jms. Then one thing running out of memory has nothing to do with > the other. > > on another aside that is mostly a rant ... totally ignorable, and not > directly on topic: > Nobody ever dings clojure, and I can't because I don't know it. I'm > excited to (attempt to) learn it despite the fact that one major thing > I was looking for in a new language is one that starts it's design > thinking about the IDE . . . .actually building an IDE and letting the > language follow in test-driven manner. Zero configuration. J > somewhat seems like that, though I don't know if it started like that, > but there isn't any syntax highlighting. Like, I don't really program > in Java. I program in Eclipse . . . which assists me in writing > java. Maybe I just think an IDE should have a GUI builder, project > manager, version control, reviewing and markup (collaboration), wiki, > milestone calendar, doc-builder that ties code to the docs, debugging, > packaging, obfuscating, etc. You download language x. You run the > launcher for language x. An IDE pops up. As you code, the IDE has > some sort of "build" or "deliver" button, nevermind the REPL part that > is useful during development ... that makes something you can give to > a user. That sort of thing is what makes a language accessible to the > masses. Is there a discussion group of project underway to make a > dedicated IDE or Eclipse plugin for clojure? And . it's asking a > lot to ask the next generation to make emacs their friend. It seems > like that's what I'll need to do for now with clojure, right? And I > wont have dot completion, I'm thinking even for java stuff (the main > place I see dots). I guess what I am saying is that I actually pick > the language based on the editor. I pick java over c# because I enjoy > Eclipse way more than every time I've had to try to use visual studio > (although that seems to finally be getting a little better). Maybe we > at least need a jEdit plugin for clojure. > > On Jan 10, 3:03 pm, Paul Mooser wrote: > > After talking to Jeffrey Chu, it
Re: SLIME: trouble with java.lang.OutOfMemoryError
Yeah, I'm not really sure how I think the problem would be ideally solved. It would just be nice for an interactive programming environment to be able to recover from all exceptions that happen at a higher level than the VM itself. On Jan 10, 12:20 pm, "Christian Vest Hansen" wrote: > I don't think it is possible to define a way to deal with heap > saturation that is general enough to cover all programs written in > Clojure, and therefor I don't think this is something that the Clojure > runtime should deal with at all. > > Personally, I only know of two ways to handle OutOfMemoryErrors: 1) > let the program blow up and hope someone notices or 2) look at your > body, pick the limb you are least likely to be needing pretty soon and > cut it off (aka. free some memory) and _then_ yell for help through > some hopefully reliable channel. --~--~-~--~~~---~--~~ 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: SLIME: trouble with java.lang.OutOfMemoryError
thanks for the encouragement. As for eclipse, I just don't get the same feeling. I love the cntl- space and cntl-\ things that stub out your code (not just for dot completion). . . complete with cells for variables that repeat in the template (yeah they probably took this from emacs, but I can add more templates using a GUI or an xml file . . . .dirt simple). Awesome. I mean, people talk about how easy python is, right? For an OO person, python should be nice and gentle. Well, until I got PyDev for eclipse I wasn't into it at all. NOW (and only now), it's awesome. It's an awesome language BECAUSE there's an eclipse plugin for it. When I forget what something is, I hold down cntl, which turns it into a hyperlink, I click on it, and it follows me to the definition. Who cares where that is. I hit the back button and I'm back where I was. There's a big difference for me between an IDE and an editor. I cant remember. Besides J, was it clean that comes with it's own IDE? http://clean.cs.ru.nl/About_Clean/body_the_clean_ide/body_the_clean_ide.htm . . . . swi-prolog has a page talking about IDE's, but seem to have the same problem of pointing folks a bunch of directions to try a bunch of things that may or may not work . . . and vary from system to system . . .and may or may not come with GUI-based version control clients. Thanks for the information on jEdit, too. I'll check it out and Netbeans (enclojure?), too, though I'd hate to have to install the monstrosity that is Netbeans just to work with clojure. Oh, I get it! Yeah, if clojure is your only language, then eclipse could be seen as insane. But no, because, no doubt you'll want source control and other team development tools and the stuff I mentioned above. Yeah, it needs a lot of memory . . . because it's doing a lot of stuff. A lot of stuff I want. It underlines things orange that might not be safe, marks them red if they are just plain wrong . . . even tells you when you have spelling errors in your comments. How is that not cool? Maybe Netbeans does that stuff, too, so if you're using it for everything then, ok. I think it's useful (but correct me if I'm just being negative) to capture some of these impressions. I know I'll have a tough incline convincing my coworkers to make this our next language. If I fail due to the IDE issue it may be interesting to know that I may end up visiting F# on the dark side. It actually has some concurrency built in (transparently, I think?), and, I'm sure will come with an IDE. Then again, it won't be free (another I'm hoping this is couched as feedback and not as complaint. It's great to see progress in languages). On Jan 10, 4:28 pm, Luc Prefontaine wrote: > Try this: > > http://github.com/djspiewak/jedit-modes/tree/master/clojure.xml > > I work with Eclipse on a daily basis because of the java code base I > have to deal with but it was > asking my computer to carry an elephant until... I got my hands on a > quad-core with 6 Gig of RAM > and I had loaded in RAM at boot time all the tools I use regularly. > > Eclipse is useful to java because of all the bureaucratic configuration > you need to create a Java app with > almost every framework (I use Spring). You need wizards to create stuff, > heavy validation tools to keep your code and > XML configurations in sych, an integrated Java debugger, ... > > I started to work with Clojure in fall and used Scite after adding a > Clojure mode to it by cloning the lisp mode > and making mods to it. Later I tried Vim and JEdit also. > > I started using Emacs 3 weeks ago just to refresh my memory (I was using > Emacs in the mid-80s). > > I do not use SLIME, just a separate REPL and I reload code when I update > a file or just cut & paste in the terminal window. > Whether you use Emacs or another language sensitive editor does not make > a huge difference. > SLIME is a nice add-on but it may be confusing and there still a couple > of issues to fix about the SLIME Clojure mode. > I tried it but tossed it away for a couple of months by necessity, I > will come back to it when it will have matured a bit. > > I do not see any need for Eclipse to code in Clojure since the amount of > code written compare to Java is > much more smaller. Eclipse for Clojure is like using a dead blow mallet > to hang a picture. > > A light language sensitive editor is what you need to track all these > parenthesis :))) > For debugging I am happy with JSWat but I do not need it very often. > The core of the learning curve is to understand the functional language > concepts and how Clojure implements > these concepts plus the ones specific to Clojure, not the syntax. > > I walked this learning curve while coding in Clojure for a system that > will be in production next Monday and all of that without > Eclipse... I am old, my brains have burned a lot of cells along the way > and I am not as fast as I used > to be when I started programming :))) so if I can do it, I expect that > ot
Re: SLIME: trouble with java.lang.OutOfMemoryError
exactly. . . .but I bet a lot of people would just reply that this is not possible to address since the REPL is the one and only vm. Disclaimer, I'm only guessing at that, too. I don't understand any of this, yet. But if that's the case, fix that. Have the REPL send messages to the vm that's running the program . . . instead of the REPL being the program. On Jan 10, 5:00 pm, Paul Mooser wrote: > Yeah, I'm not really sure how I think the problem would be ideally > solved. It would just be nice for an interactive programming > environment to be able to recover from all exceptions that happen at a > higher level than the VM itself. > > On Jan 10, 12:20 pm, "Christian Vest Hansen" > wrote: > > > I don't think it is possible to define a way to deal with heap > > saturation that is general enough to cover all programs written in > > Clojure, and therefor I don't think this is something that the Clojure > > runtime should deal with at all. > > > Personally, I only know of two ways to handle OutOfMemoryErrors: 1) > > let the program blow up and hope someone notices or 2) look at your > > body, pick the limb you are least likely to be needing pretty soon and > > cut it off (aka. free some memory) and _then_ yell for help through > > some hopefully reliable channel. --~--~-~--~~~---~--~~ 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: SLIME: trouble with java.lang.OutOfMemoryError
If I'm not mistaken, this is fairly close to how SLIME works, when connected to a remote VM. The remote VM is running some server code which allows it to communicate with SLIME, which is running inside of emacs. On Jan 10, 2:15 pm, e wrote: > exactly. . . .but I bet a lot of people would just reply that this is > not possible to address since the REPL is the one and only vm. > Disclaimer, I'm only guessing at that, too. I don't understand any of > this, yet. But if that's the case, fix that. Have the REPL send > messages to the vm that's running the program . . . instead of the > REPL being the program. > > On Jan 10, 5:00 pm, Paul Mooser wrote: > > > Yeah, I'm not really sure how I think the problem would be ideally > > solved. It would just be nice for an interactive programming > > environment to be able to recover from all exceptions that happen at a > > higher level than the VM itself. > > > On Jan 10, 12:20 pm, "Christian Vest Hansen" > > wrote: > > > > I don't think it is possible to define a way to deal with heap > > > saturation that is general enough to cover all programs written in > > > Clojure, and therefor I don't think this is something that the Clojure > > > runtime should deal with at all. > > > > Personally, I only know of two ways to handle OutOfMemoryErrors: 1) > > > let the program blow up and hope someone notices or 2) look at your > > > body, pick the limb you are least likely to be needing pretty soon and > > > cut it off (aka. free some memory) and _then_ yell for help through > > > some hopefully reliable channel. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Simple Data Structure Question
Hello, I'm stumped as to how I create a mutually referential data structure in Clojure. My compsci is fuzzy. I don't know if what I'm trying to do is possible. Any insight would be helpful. I have a function that creates a Person, given his name and a list of friends. (defn new_person [name & friends] {:name name :friends friends}) But how do I create a mutually referential definition? ie. what if Bob is Bill's friend, and Bill is also Bob's friend? I would have to do something like the following: (which is not allowed) (def bob (new_person "Bob" bill)) <-Not allowed: forward reference. (def bill (new_person "Bill" bob)) Thanks a lot for your help -Patrick --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: SLIME: trouble with java.lang.OutOfMemoryError
seems like enclosjure addresses a bunch of my problems/questions. It also seems to work like we wanted SLIME to work, more or less . . .where you attach to the vm that's used for execution . . . only you attach to the REPL, I think, which still accomplishes the goal of keeping the editor separate from the memory, but what about having the REPL being able to attach to the vm it is managing. Then it wouldn't be something that NetBeans/enclosure is doing . . . rather something that's part of the language. So, yeah. enslojure sets up a HelloWorld that you can play with right away. In fact, when you click on "build" it even tells you how you could run your application from the command line using a java command. It jars up you whole clojure project and everything. Nice. On the other hand, I couldn't figure out how to use NetBeans' run button. it couldn't find main or something. So I also couldn't debug using NetBeans' debugger because of this. Also, it isn't clear how to get different clojure files to work together. Do you use the (load) function? If so, I don't know how the project thinks of relative file locations. It's not as clean/clear as java (for a beginner, at least) where you just import classes you want to use . . and make packages. . . . or modules in python. I don't know what the notion of "path" is in clojure. I see the namespace stuff but have no clue how to make it work yet. Are you just supposed to use one giant file for all your work? That wouldn't be good for teams, for sure. . . only for hacking. Also the REPL errors are USELESS to a beginner. something about iSeq all the time. The moral for me there was no to make an error. Better than where I was before enclojure. Again, I contend that a language is only as good as the IDE that has been written for it, which is why it's cool to see enclojure coming along (even though it means learning NetBeans instead of Eclipse). On Jan 10, 5:31 pm, Paul Mooser wrote: > If I'm not mistaken, this is fairly close to how SLIME works, when > connected to a remote VM. The remote VM is running some server code > which allows it to communicate with SLIME, which is running inside of > emacs. > > On Jan 10, 2:15 pm, e wrote: > > > exactly. . . .but I bet a lot of people would just reply that this is > > not possible to address since the REPL is the one and only vm. > > Disclaimer, I'm only guessing at that, too. I don't understand any of > > this, yet. But if that's the case, fix that. Have the REPL send > > messages to the vm that's running the program . . . instead of the > > REPL being the program. > > > On Jan 10, 5:00 pm, Paul Mooser wrote: > > > > Yeah, I'm not really sure how I think the problem would be ideally > > > solved. It would just be nice for an interactive programming > > > environment to be able to recover from all exceptions that happen at a > > > higher level than the VM itself. > > > > On Jan 10, 12:20 pm, "Christian Vest Hansen" > > > wrote: > > > > > I don't think it is possible to define a way to deal with heap > > > > saturation that is general enough to cover all programs written in > > > > Clojure, and therefor I don't think this is something that the Clojure > > > > runtime should deal with at all. > > > > > Personally, I only know of two ways to handle OutOfMemoryErrors: 1) > > > > let the program blow up and hope someone notices or 2) look at your > > > > body, pick the limb you are least likely to be needing pretty soon and > > > > cut it off (aka. free some memory) and _then_ yell for help through > > > > some hopefully reliable channel. --~--~-~--~~~---~--~~ 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: Simple Data Structure Question
Hi Patrick, Here's one way to do it: (defn new-person [name] (ref {:name name, :friends #{}})) (defn are-friends [a b] (dosync (commute a assoc :friends (conj (:friends @a) b)) (commute b assoc :friends (conj (:friends @b) a (def bill (new-person "Bill")) (def bob (new-person "Bob")) (are-friends bill bob) -Stuart Sierrra On Jan 10, 8:39 pm, CuppoJava wrote: > Hello, > I'm stumped as to how I create a mutually referential data structure > in Clojure. My compsci is fuzzy. I don't know if what I'm trying to do > is possible. Any insight would be helpful. > > I have a function that creates a Person, given his name and a list of > friends. > > (defn new_person [name & friends] > {:name name > :friends friends}) > > But how do I create a mutually referential definition? > > ie. what if Bob is Bill's friend, and Bill is also Bob's friend? > I would have to do something like the following: (which is not > allowed) > > (def bob (new_person "Bob" bill)) <-Not allowed: forward reference. > (def bill (new_person "Bill" bob)) > > Thanks a lot for your help > -Patrick --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple Data Structure Question
I suggest moving friendship outside of the objects themselves. (defn person [name] {:name name}) (def bob (person "Bob")) (def bill (person "Bill)) (def *friends* {bob bill}) now friends is a map of who likes whom. Then you can implement (defn friend? [p1 p2] (or (= p1 (*friends* p2)) (= p2 (*friends* p1))) As I wrote this, I see Stuart wrote a ref based version. Both work. The important point is make the graph of friendship separate from the nodes. Any sort of graph and edge based representation should work for you. Cheers, -Mark On Jan 10, 2009, at 7:39 PM, CuppoJava wrote: > > Hello, > I'm stumped as to how I create a mutually referential data structure > in Clojure. My compsci is fuzzy. I don't know if what I'm trying to do > is possible. Any insight would be helpful. > > I have a function that creates a Person, given his name and a list of > friends. > > (defn new_person [name & friends] > {:name name > :friends friends}) > > But how do I create a mutually referential definition? > > ie. what if Bob is Bill's friend, and Bill is also Bob's friend? > I would have to do something like the following: (which is not > allowed) > > (def bob (new_person "Bob" bill)) <-Not allowed: forward reference. > (def bill (new_person "Bill" bob)) > > Thanks a lot for your help > -Patrick > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple Data Structure Question
Thank you for the replies. My actual problem is a bit more convoluted, so I can't separate the issue like in Mark's solution very easily. Stuart's solution is more general, and I think I can apply that in a straight-forward way. Thanks. ps: I'm doing a bit of reading about mutually-recursive data structures on the net. Is Lisp's letrec supposed to handle this situation? It would be handy just to be able to do: (letrec [bob (create_person "bob" bill) bill (create_person "bill" bob)]) --~--~-~--~~~---~--~~ 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: Simple Data Structure Question
On Sat, Jan 10, 2009 at 6:57 PM, CuppoJava wrote: > ps: I'm doing a bit of reading about mutually-recursive data > structures on the net. Is Lisp's letrec supposed to handle this > situation? > > It would be handy just to be able to do: > > (letrec [bob (create_person "bob" bill) > bill (create_person "bill" bob)]) If you want to draw inspiration from other languages, take a look at PLT Scheme's "shared" which is kind of like a letrec for creating mutually recursive data structures: http://docs.plt-scheme.org/reference/shared.html But in the absence of such a construct, you've got two main options. One is to use mutation to set up the mutual references, like what Stuart Sierra described. The other main option is to give each of your people a unique ID or name. You keep a hash table that maps these names to the actual person object. Within a person, your list of friends is actually a list of names, rather than a list of people objects. This adds a level of indirection that avoids mutual references and makes everything work. To get to the actual person object, you look up the name in your hash table. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
non recursive impl in presence of persistence?
I'm just trying to understand basic stuff. say I have a local list called "myList" (assigned using 'let' . . . should I have used something else?) Who cares what's in it. Maybe I set it up from a list comprehension from some input to my function. I have no idea how to iteratively mess with it since everything is persistent. Ok, like, say it's a list of lists and I am going to be merging the lists, like Tarjan's mergesort from some book from college. so I have myList with contents [[11] [2] [4] [1] [99]] here's how I would do it in python: def msort(myList): myList = [[x] for x in someList] while len(myList) > 1: l1 = myList.pop(0) l2 = myList.pop(0) listmerge = some_merge_function(l1, l2) myList.append(listmerge) # important that newly merged go to back of queue to get proper runtime return myList[0] here's what I'm trying to do for clojure, and it's a mess: (defn msort [toSort] (def sorted (let [myList (for [x toSort] [x])] <- so far so good (not a real comment. I don't know how, yet) [ (while (> (count myList) 1) <--- infinite loop the way written? I don't know how to overwrite myList (let [l1 (nth myList 0)][]) (let [l2 (nth myList 1)][]) (let [listmerge (some_merge_func l1 l2)][]) (let [myList (concat (drop 2 myList) listmerge)][myList]) <--- probably a different local variable ) ])) sorted) doesn't compile anyway . . . I see that the let is causing the scope to be all screwed up. l1 and l2 can't be seen for the merge function. should I be using let at all here? Can things be redefined using def? see how much simpler it is not to say anything? Which is it def or let in python? Answer: No . . .but I'm sure there's value. This seems like something that might be in the FAQ. . . .or somewhere back in these discussions. I'll look around. 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: non recursive impl in presence of persistence?
> > > I have no idea how to iteratively mess with it since everything is > persistent. Ok, like, say it's a list of lists and I am going to be > merging the lists, like Tarjan's mergesort from some book from > college. > Sorting is done much more easily with recursion than with iteration. However, it looks like you are focused on learning language features rather than programming strategy, so I will just answer your questions. I have not actually done any iterative programming in Clojure, as I prefer the functional approach, so my answers are based on my limited understanding of the Clojure documentation. so I have myList with contents [[11] [2] [4] [1] [99]] > > here's how I would do it in python: > > def msort(myList): > myList = [[x] for x in someList] > while len(myList) > 1: >l1 = myList.pop(0) >l2 = myList.pop(0) >listmerge = some_merge_function(l1, l2) >myList.append(listmerge) # important that newly merged go > to back of queue to get proper runtime > return myList[0] > > here's what I'm trying to do for clojure, and it's a mess: > > (defn msort [toSort] > (def sorted (let Be careful with def. I think that it creates a global, and it looks like you want something with a scope limited to this function. http://clojure.org/Vars > [myList (for [x toSort] [x])] <- so far so good (not a > real comment. I don't know how, yet) Use a semicolon to create a comment: some code ; a comment > [ >(while (> (count myList) 1) <--- infinite loop the way > written? I don't know how to overwrite myList > (let [l1 (nth myList 0)][]) The line above does nothing. When you write "(let [x 1] expr1) expr2" the new value of x has a narrow scope so that it only affects expr1. You are wanting to create a local variable that you can change. Refs can do that: (let [x (ref 3)] (dosync (while (> @x 0) (ref-set x (- @x 1))) @x)) http://clojure.org/Refs > (let [l2 (nth myList 1)][]) > (let [listmerge (some_merge_func l1 l2)][]) > (let [myList (concat (drop 2 myList) listmerge)][myList]) <--- > probably a different local variable > ) > ])) > sorted) After all that work you just return the original list? I must have missed the part where you tried to change sorted. Any such attempt would fail, though, because Clojure collections are immutable. Maybe sorted should be a ref to a list instead of just a list. Here is a discussion of sorting implementations in Clojure. I hope that you find it useful. http://www.fatvat.co.uk/2008/12/bubbling-clojure.html -- Education is what survives when what has been learned has been forgotten. - B. F. Skinner --~--~-~--~~~---~--~~ 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: non recursive impl in presence of persistence?
Ok, first of all, here's how I translated that python code: (defn msort [myList] (if (> (count myList) 1) (let [l1 (first myList) l2 (second myList)] (recur (concat (drop 2 myList) (my-merge l1 l2 (first myList))) The main thing that might need explaining is the recur, which basically goes back to either the last function definition or last loop and rebinds whatever parameters werre passed in. In this case it goes back and is as if it's calling msort with (concat (drop 2 myList) (my-merge l1 l2)) as myList. The let is just for clarity's sake, you could have just put them in place of l1 and l2 in the recur. On Sun, Jan 11, 2009 at 12:21 AM, e wrote: > > I'm just trying to understand basic stuff. > say I have a local list called "myList" (assigned using 'let' . . . > should I have used something else?) Who cares what's in it. Maybe I > set it up from a list comprehension from some input to my function. > > I have no idea how to iteratively mess with it since everything is > persistent. Ok, like, say it's a list of lists and I am going to be > merging the lists, like Tarjan's mergesort from some book from > college. > > so I have myList with contents [[11] [2] [4] [1] [99]] > > here's how I would do it in python: > > def msort(myList): > myList = [[x] for x in someList] > while len(myList) > 1: >l1 = myList.pop(0) >l2 = myList.pop(0) >listmerge = some_merge_function(l1, l2) >myList.append(listmerge) # important that newly merged go > to back of queue to get proper runtime > return myList[0] > > here's what I'm trying to do for clojure, and it's a mess: > > (defn msort [toSort] > (def sorted (let > [myList (for [x toSort] [x])] <- so far so good (not a > real comment. I don't know how, yet) > [ >(while (> (count myList) 1) <--- infinite loop the way > written? I don't know how to overwrite myList > (let [l1 (nth myList 0)][]) > (let [l2 (nth myList 1)][]) > (let [listmerge (some_merge_func l1 l2)][]) > (let [myList (concat (drop 2 myList) listmerge)][myList]) <--- > probably a different local variable > ) > ])) > sorted) > > doesn't compile anyway . . . I see that the let is causing the scope > to be all screwed up. l1 and l2 can't be seen for the merge function. > > should I be using let at all here? Can things be redefined using > def? see how much simpler it is not to say anything? Which is > it def or let in python? Answer: No . . .but I'm sure there's > value. This seems like something that might be in the FAQ. . . .or > somewhere back in these discussions. I'll look around. > > 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: non recursive impl in presence of persistence?
By the way just to clarify, the use of recur is iterative, it's just written in clojure in its recursive form. On Jan 11, 1:32 am, "Nick Vogel" wrote: > Ok, first of all, here's how I translated that python code: > > (defn msort [myList] > (if (> (count myList) 1) > (let [l1 (first myList) l2 (second myList)] > (recur (concat (drop 2 myList) (my-merge l1 l2 > (first myList))) > > The main thing that might need explaining is the recur, which basically goes > back to either the last function definition or last loop and rebinds > whatever parameters werre passed in. In this case it goes back and is as if > it's calling msort with (concat (drop 2 myList) (my-merge l1 l2)) as > myList. The let is just for clarity's sake, you could have just put them in > place of l1 and l2 in the recur. > > On Sun, Jan 11, 2009 at 12:21 AM, e wrote: > > > I'm just trying to understand basic stuff. > > say I have a local list called "myList" (assigned using 'let' . . . > > should I have used something else?) Who cares what's in it. Maybe I > > set it up from a list comprehension from some input to my function. > > > I have no idea how to iteratively mess with it since everything is > > persistent. Ok, like, say it's a list of lists and I am going to be > > merging the lists, like Tarjan's mergesort from some book from > > college. > > > so I have myList with contents [[11] [2] [4] [1] [99]] > > > here's how I would do it in python: > > > def msort(myList): > > myList = [[x] for x in someList] > > while len(myList) > 1: > > l1 = myList.pop(0) > > l2 = myList.pop(0) > > listmerge = some_merge_function(l1, l2) > > myList.append(listmerge) # important that newly merged go > > to back of queue to get proper runtime > > return myList[0] > > > here's what I'm trying to do for clojure, and it's a mess: > > > (defn msort [toSort] > > (def sorted (let > > [myList (for [x toSort] [x])] <- so far so good (not a > > real comment. I don't know how, yet) > > [ > > (while (> (count myList) 1) <--- infinite loop the way > > written? I don't know how to overwrite myList > > (let [l1 (nth myList 0)][]) > > (let [l2 (nth myList 1)][]) > > (let [listmerge (some_merge_func l1 l2)][]) > > (let [myList (concat (drop 2 myList) listmerge)][myList]) <--- > > probably a different local variable > > ) > > ])) > > sorted) > > > doesn't compile anyway . . . I see that the let is causing the scope > > to be all screwed up. l1 and l2 can't be seen for the merge function. > > > should I be using let at all here? Can things be redefined using > > def? see how much simpler it is not to say anything? Which is > > it def or let in python? Answer: No . . .but I'm sure there's > > value. This seems like something that might be in the FAQ. . . .or > > somewhere back in these discussions. I'll look around. > > > 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: Ugly Sudoku solver
Following your good advice, I also update the next-cell function to work in a lazy way instead of sorting the values of the entire board. The full source bellow. Next phase: GUI. ;; sudoku solver by Tach ;; with the help of Konrad (defn print-board [board] "Pretty print the sudoku board" (doseq [row board] (println row))) (defn mod3range [x] (let [start (- x (rem x 3))] (range start (+ 3 start (defn neighbors-pos [pos] "return a collection of neighbors positions to pos" (remove #(= pos %) (distinct (concat (for [y (range 3) z (range 3)] [(get pos 0) y z]) ; row neighbors (for [x (range 9)] [x (get pos 1) (get pos 2)]) ; col neighbors (for [x (mod3range (get pos 0)) z (range 3)] [x (get pos 1) z]))) ; square neighbors; )) (defn neighbors-values [board pos] "return a list of neighbor positions values" (map #(get-in board %) (neighbors-pos pos))) (defn valid-values [board pos] "return a list of values which does not violate the neighbors values. return nil if the position already have a value" (if (zero? (get-in board pos)) (clojure.set/difference (set (range 1 10)) (neighbors-values board pos)) (seq nil))) (defn map-board [board f] "execute function f on each of the position on board. function f get the position and the board as parameters" (for [x (range 9) y (range 3) z (range 3)] (let [pos [x y z]] [pos (f board pos) ] ))) (defn next-cell [board] "return the next potential cell to set, and the valid alternatives" (first (for [n (range 1 10)] (filter #(= n (count (second %))) (map-board board valid-values) (defn complete? [board] (not (some #(second %) (map-board board (fn [board pos] (zero? (get-in board pos))) (defn all-solutions [board] (if (complete? board) (list board) (let [[pos valid-values] (next-cell board)] (apply concat (for [v valid-values] (all-solutions (assoc-in board pos v))) (defn sudoku [board] "solve a sudoku problem" (first (all-solutions board))) ;;; use the solver (def *sudoku-problem* [[[0 0 0] [5 0 0] [0 9 1]] [[1 0 0] [8 6 0] [0 3 2]] [[0 0 6] [9 3 0] [0 0 0]] [[0 0 4] [6 0 0] [0 7 3]] [[0 5 0] [4 9 3] [0 1 0]] [[3 6 0] [0 0 8] [9 0 0]] [[0 0 0] [0 8 5] [3 0 0]] [[8 3 0] [0 1 6] [0 0 5]] [[6 7 0] [0 0 9] [0 0 0]]]) (print-board (sudoku *sudoku-problem*)) On Jan 10, 10:22 pm, Tzach wrote: > Thanks Konrad > A very elegant solution. > 40 years of laziness, and I finally realize what a great feature the > lazy evaluation is ;) > > Tzach > > On Jan 9, 3:30 pm, Konrad Hinsen wrote: > > > On Jan 9, 2009, at 13:18, Tzach wrote: > > > > The main functionsudokuis recursive: > > > 1. Getting asudokuboard as an input > > > 2. Choosing the next empty (zero) cell to test, loop on all valid > > > values, and callsudokuwith the new board > > > 3. When a solution (board with no zero values) is found: throw. > > > > (defnsudoku[board] > > > "solve asudokuproblem" > > > (when (complete? board) > > > (do > > > (println "complete") > > > (print-board board) > > > (throw nil))) > > > (let [cell (next-cell board) > > > pos (first cell) > > > valid-values (second cell)] > > > (when cell > > > (doseq [v valid-values] > > > (sudoku(assoc-in board pos v))) > > > ))) > > > > Although it does work, we can all agree its pretty ugly, so I would > > > appreciate your help on the following questions: > > > 1. How to can I return a solution via the recursive stack with out > > > throwing an exception? I understand there is no "return-from" > > > facility. > > > The return value of a function is the last expression that was > > evaluated. Yoursudokufunction could have a structure like this: > > > (defnsudoku[board] > > "solve asudokuproblem" > > (if (complete? board) > > board > > (let [...] > > ..)) > > > The problem is then in the let branch, as it can terminate without > > returning a valid board. > > > > 2. Can this function be implemented as tail recursive (using loop? > > > recur?) > > > As it is, no, because you have multiple recursive calls. However, I > > wonder what those are good for. If I understand your algorithm > > correctly, it find all valid values for the next cell to be filled, > > and then tries for each of them to complete the puzzle, using a > > recursive call. > > > I would rewrite the solver as a function that returns a lazy sequence > > of valid solutions: > > > (defn all-solutions [board] > > (if (complete? board) > > (list board) > > (let [[pos valid-values] (next-cell board)] > > (apply concat (for [v valid-values] > > (all-solutions (assoc-in board pos v))) > > > Note that you don't h