> I'm concerned that the ability to freely order comments and code will not > interact well with Clojure's namespaces. With Clojure's namespaces, you > can have things with the same name in two different namespaces. Functions > local to a namespace are referred to in one way, whereas you need some sort > of prefix to refer to one in a different namespace. These prefixes are > often aliases, and the aliases may vary from one context to another, for > example, in one namespace I may refer to clojure.string as `str` and in > another namespace I may refer to it as `string`. > <snip>
How do you deal with this "lack of context" when you present your code in a > way that is completely unrelated to the namespace organization of your > files? > > Well, my experience thus far has led me down two different roads here. Sometimes, I follow the path you came to on your own, which is to use one section or chapter per namespace. Within that section/chapter I can reorganize my code into whatever order lends itself to the clearest explanation. Because I use org-babel, it can export each namespace section to its own file during the tangling process. It's straightforward to run the program through the REPL or leiningen at that point. The other approach that I have tried a few times now is to simply throw out the whole namespace construct entirely. After all, namespaces in functional programming mostly serve as simply a tool for collecting together functions and global vars that work together to accomplish some shared goal. If I am working on a literate program, it seems very natural for me to simply use sections/chapters to organize my functions by their purpose. The namespace then just becomes an unnecessary build construct. That is, I just tell org-babel to tangle the entire codebase to a single .clj file. Simple. > Actually it isn't really a change in workflow but a change in mindset. >> Literate programming is not documentation, they are different ideas. >> > > Here's why I called it a change in workflow -- please correct me if I'm > mistaken: > > Every time the subject of literate programming comes up, I ask one simple > question: When you get a stacktrace, is the file/line number information > correct? A year or two back when I asked this, you elaborated that for > you, this was mostly a non-issue. You said you developed your code by > sending over one tiny code block at a time to the REPL, rather than sending > a whole file over, and you never used any debugging facilities. I consider > that a change in workflow. > I'm in the same boat with Tim. I try to test my functions one at a time through the REPL if possible. Whenever I have to make several modifications to different parts of the program at once, then I'll just re-evaluate the file and resume testing it one piece at a time. It is true that the stacktraces don't tend to get the file/line numbers right, but since Clojure stacktraces are good at naming the function where the error occured, I rarely find that to be an issue that C-s or C-r (isearch-forward/backward) can't solve in an instant. > > >> >> For Clojure specific efforts see >> http://daly.axiom-developer.org/clojure.pdf (PDF) >> http://daly.axiom-developer.org/clojure.pamphlet (source) >> > > This is a great example of using literate programming to document a > program that is complete and stable. Have you successfully used literate > programming in a program that is rapidly evolving? > > I have developed a rather large fire simulation toolkit using the LP model, and it was...interesting. Prior to that, I had only created shortish programs that were mostly just helping me to get my feet wet with the concepts and workflows of literate programming. When I worked on the fire program though, I ran into several new hurdles and successes. The benefit of LP was (not surprisingly) that my design errors really jumped right out at me when I tried to explain them in English. Previously, I had started hacking together this program in the usual non-LP way, but I started to get stuck in some of the messy statistical details. I backed up and started over using LP, and my code's organization really came together beautifully in a matter of a couple of days of hacking. The downside unfortunately was that I had never written a literate program at that scale before, and lacking Tim's 42 years of experience, I wasted a lot of time just trying to figure out basic code organization things like the ones you are asking in this thread: How do I deal with these namespace imports? What is the best way to organize toplevel chunk references? Should they be sequential or hierarchical? Can org-babel support multiple code blocks with the same name in the same way that Tim's tangle.lisp program does? (Hint: the answer is no) Why does tangling work with swank-clojure+SLIME but not with NREPL? (I had to patch that) How do I get org-mode to communicate with the Clojure REPL? (Note: it's documented :session support did not work, so nrepl-interaction mode was needed). And so on. Eventually, I worked these things out through trial and error, but it was one of those experiences that both made me proud of the finished product while simultaneously dreading having to update it for fear of uncovering some new workflow issue that I hadn't thought of yet. That experience happened about a year ago, and I feel much better about it all these days. There's still a sad lack of documentation on doing good literate programming specifically with Clojure (although Tim's language agnostic stuff is quite solid). One of these days I'd like to try and remedy that. Blegh. > Is it true that there's nothing like org-babel for environments other than > emacs? > I don't know of anything to date. noweb is language agnostic, but it doesn't support live code evaluation or code block chaining the way org-babel does. > To me, the most compelling reason to stick with tools that use regular > Clojure files and regular Clojure comments, especially for open source > projects, is that it allows for collaboration between people using > different Clojure platforms and tools, whereas locking things into a file > that can be only be processed by emacs or a unix shell script would limit > the pool of contributors. > That is a reasonable point. On the other hand, Benjamin Mako Hill makes the counterpoint in his LibrePlanet 2013 talk that the median number of contributors to any open source project hosted on Sourceforge, GitHub, Savannah, and a few other less commonly used public repos he analyzed is 1. Yep, that's it. One lonely developer. Even highly active projects rarely showed more than 2 or 3 developers. It's those rare ones that usually have ongoing financial backing that end up with developer teams. Think Apache, the Linux kernel, Debian, or Mozilla. Anyway, it was a pretty good talk IMO. Check it out. http://media.libreplanet.org/u/libby/m/mako/ I suppose my suggestion here is that maybe we overestimate the difficulty of finding those one or two other developers who are sufficiently motivated to study and change our code but don't want to use the same tools as us. YMMV. ;-) > One thing I do like about org-babel code is that it makes it easy to > create "live" examples in the docs that actually recompute when the code > changes. > Me too. Guess that wasn't a question, eh? > As far as I can tell, neither your script nor org-babel mode address the > third prong of literate programming as defined by Knuth, specifically, the > extensive cross-indexing, letting you know not only where functions are > defined, but also where defined functions are used. Why do you not > consider this to be as essential as, say, the ability to reorder your code? > This is a very good point, and one that I would like to see addressed in a future version of org babel. (I guess I'd better go write that patch now...) I suspect I haven't worried too much about it because my programs are frequently just one giant org file, which is easy to search with standard emacs commands. Even when a program outgrows a single file, it hasn't (yet) required anything more from me than a single directory of org files, which are again trivially searched with grep. The lack of deep namespace-imposed directory structures is one of those nice side benefits of LP AFAICT. One downside I will mention about org-babel is that tangling becomes really quite slow once a file grows past a few thousand lines. This does necessitate splitting the program into multiple files as I just mentioned, and when that happens something like Tim's make script becomes quite helpful in tangling and weaving the whole system in one go. ~Gary > -- -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.