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


Reply via email to