Hi Kai, 2009/7/2 Kai <poki...@gmail.com>: > > Hi all, > > @Laurent > > I haven't placed the code anywhere other than on my server. It was > just an experiment in Clojure but I'm glad it's useful to others. I'll > go ahead and make it open source and let you know when I do. It should > be relatively robust as it is -- I ran it through some of the src > Clojure libraries and they look as intended. The only change I > intended to make and never did was to apply the "defn" style to all > types of defs. I'll probably do that before releasing the code on a > repo.
Ok, I'll wait then, thanks. BTW, I don't really understand how you could have StackOverflows. I would expect that the solving algorithm would make the size of the call stack proportional to the depth of the datastructure graph ? If so, I guess that even the most evil human created code would not reach the StackOverflow limit ? Regards, -- Laurent > > @Rick > > I experimented with many different versions of this before I came to > the "large function" format. At first I tried doing it completely > regex which failed miserably. One intention, which I felt would be > much more functional-like, was to split up the code into a list of > functions. For example, code that starts like this: > > (defn plus-five [n] (+ 5 n)) > > Would end up something like this after my parsing: > > (format-list "(" (format-def "defn") " " (format-func-name "plus- > five") " [" (format-param-list "n") "] " (format-list "(" (format-func- > name "+") " 5 n)" ) ")" ) > > It seems wieldy when I write it out but now that it's all parsed as a > list it would be trivial to implement each of those format- functions > and eval the entire thing to generate your desired HTML. > > My code didn't start off large, of course. What I did was work > incrementally. First I figured out how to detect string starting and > ending since that seems the simplest. I knew that there had to be some > sort of "state" so that we know when we encounter a quote whether or > not it is the end of a string we've already begun reading. I realized > that in functional languages we already have a stack given to us -- > the function stack. So, the next step for me was to see if I could > make this approach work by hopping back and forth between functions. > > I got fairly far into this before I had problems with stack overflows. > I found out later than I needed knowledge of trampoline and mutual > recursion to solve the issue. I think the approach still has potential > but the setback forced me to consider other options. This lead me to > implement the stack local in the recursive definition of parse-code. > > After I got strings working, it was mostly smooth sailing until I got > to the point where I wanted to highlight the names of variables after > "def" and "defn". Now my approach of reading a character at a time was > becoming quite unorganized. After some more thought experiments, I > decided to give the stack an upgrade and go with a struct to record > state instead of just a keyword. Now I could actually put values on > the stack and therefore keep track of, for example, the first element > of the list that an element is contained in. Continuing down this > path, along with incremental updates, led the code to where it is now. > > I did use the REPL extensively to test each new feature. I don't use > an emacs-like editor at all, I coded it in Notepad++. I would simply > paste each snippet of code into the REPL as I write it to make sure > that it works in basic cases. I also used load-file quite often to run > the entire program against sample input and especially itself. > > In summary, the "large function" approach wasn't an end goal, it was > just a result of incremental progress. I don't know if it's Clojure- > like which is a big reason that I asked for advice on my first post. I > haven't received any criticism about that yet so I assume it's not a > bad approach. Even though it seems lengthily, it reads linearly and > doesn't have logic scattered in pieces all around. In the end, I think > that's what functional programming is about anyway. > > ~ Kai > > On Jul 2, 6:48 am, Rick Moynihan <rick.moyni...@gmail.com> wrote: >> 2009/6/26 Kai <poki...@gmail.com>: >> >> >> >> >> >> > Hi all, >> >> > I'm new to this discussion group and Clojure. I'm sharing the first >> > "bigger-than-REPL" script that I've written because I haven't seen >> > anything else like it for Clojure. It's a script that takes Clojure >> > code as input and generates a pretty HTML version. You can view it >> > here (I ran the script through itself): >> >> >http://kai.myownsiteonline.com/clojure/html.clj.html >> >> > The style sheet is kept separate for cases with more than one Clojure >> > script shown on a page. Also, it still formats just as well without >> > the javascript; the javascript only contains code that highlights >> > Clojure script as you mouse over it. >> >> > I don't have any particular intention by creating this script, it was >> > just a warmup into Clojure. Feel free to use it for whatever purpose. >> > I'd appreciate comments on the coding style as well as how to make it >> > faster - core.clj takes a good 10 minutes! It was a pain and a >> > pleasure to code :) >> >> Cute! >> >> Though I've spent a lot of time over the last 6 months reading about >> and toying with clojure, I've not yet found the time to write anything >> even as substantial as this. I did however take a quick look at the >> code, and it seems reasonably easy for a noob such as myself to >> follow. >> >> That said, it did remind of something I was meaning to ask which >> concerns large function definitions (here and elsewhere e.g. >> clojure.core). >> >> Your parse-code function definition seems quite long and it seems >> counter to the way I think I would write this program; as I would be >> inclined to write lots of smaller functions responsible for emitting >> the different spans for comments, strings, etc; and then tie them up >> into a larger function. That way I could evaluate them all separately >> and combine them later. >> >> I have seen similar large functions elsewhere e.g. a few in >> clojure.core, and my question is: >> >> How do you go about writing a large function like this? What is the >> process involved? I realise referential transparency means that >> almost every s-exp is evaluatable separately (providing the necessary >> bindings are in scope) but is it not a hassle to build such things? >> How is it you compose a large function and get the benefits of the >> REPL and lisps interactive development model? Do you evaluate these >> snippets in a let bind? If so what tools support this? >> >> I'm also curious as to what the pro's are in writing large functions >> like this. There are several in clojure.core, I think gen-class is >> the one that springs to mind; why is this not defined as a series of >> smaller functions? >> >> Thanks again for the HTML pretty printer! >> >> R. > > > --~--~---------~--~----~------------~-------~--~----~ 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 Note that posts from new members are moderated - please be patient with your first post. 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 -~----------~----~----~----~------~----~------~--~---