How to make eshell pick up the right PATH

Context:
a freshly installed Emacs on Mac OS X.

Itch:
the PATH is the default system path, not that one you get in your terminal:
~ $ echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin
~ $ bash -l -c "echo \$PATH"
/Users/mike/.rvm/gems/ruby-1.9.2-p180/bin:
/Users/mike/.rvm/gems/ruby-1.9.2-p180@global/bin:
/Users/mike/.rvm/rubies/ruby-1.9.2-p180/bin:/Users/mike/.rvm/bin:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:
/usr/X11/bin:/opt/local/bin:/usr/local/cuda/bin:/Users/mike/bin
~ $ rvm
rvm: command not found
Not good.

Scratch:
Now here's the choice: either you fiddle with .MacOSX/environment.plist or use a quick and dirty sub-shell hack. I chose the latter for the sake of not touching XML. The idea is to call bash directly from Emacs and ask it for the right PATH:
(setenv "PATH" (shell-command-to-string "/bin/bash -l -c 'echo -n $PATH'"))
Add the line above to your ~/.emacs and the next time you start eshell you will see:
~ $ echo $PATH
/Users/mike/.rvm/gems/ruby-1.9.2-p180/bin:
/Users/mike/.rvm/gems/ruby-1.9.2-p180@global/bin:
/Users/mike/.rvm/rubies/ruby-1.9.2-p180/bin:/Users/mike/.rvm/bin:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:
/usr/X11/bin:/opt/local/bin:/usr/local/cuda/bin:/Users/mike/bin
~ $ rvm
= rvm
* http://github.com/wayneeseguin/rvm
...........
blah blah blah...
............
limitations under the License.
Schnell und lustig!

Tail recursion without TCO

Emacs lisp has no Tail Call Optimization (TCO), neither do many other lisp dialects. The lack of TCO is not a big deal--it's always possible to transform a tail recursive algorithm into a cycle. However, it makes procedures uglier. Here is a very simple method of enabling Clojure-style tail call recursion in Emacs lisp:

;; A very simple linearized Y combinator.
;; All the state management stuff is incapsulated here.
;; Don't call it directly.
(defun rloop- (body &rest args)
  (let ((res nil))
    (while (progn
             ;; here's the idea: we keep calling body 
             ;; while it returns the recursion marker
             (setq res (apply body args))
             (when (and (consp res)
                        (eq :loop-recur-marker (car res)))
               (progn (setq args (cdr res))
                      t))))
    res))

;; Recursion marker factory
(defun recur (&rest args)
  ;; instead of a real recursive call,
  ;; just signal an intention to make one
  (cons :loop-recur-marker args))

;; The form macro
(defmacro rloop (init body)
  (let ((args (mapcar 'car init)))
    ;; a little courtesy to the macro users
    `(let* ,init
       ;; make a lambda from the body and pass it 
       ;; to the combinator function
       (rloop- (function (lambda (,@args) ,body))
               ,@args))))

Here's how to use it:

(defun factorial (x)
  ;; this is the recursion entry point
  (rloop ((x   x) 
          (acc 1))
         (if (< x 1)
             acc ;; done, just return the result
           ;; not done, start the whole rloop block again
           (recur (1- x) 
                  (* x acc)))))

ELISP> (factorial 10)
3628800

The funny part is defun is not necessary. You can have as many sequential inlined rloops as you want. I like this approach a lot: all the state management stuff is off the sight. The procedure is almost identical to the underlying algorithm. Another classic example:

(defun fibo (x)
  (rloop ((x    x)
          (curr 0)
          (next 1))
         (if (= x 0)
             curr
           (recur (1- x) 
                   next 
                  (+ curr next)))))

ELISP> (fibo 10)
55

Nice, eh? Of course, this kind of beauty comes with a price. Here is how the rloop macro expands:

ELISP> (macroexpand '(rloop ((n 0)) (if (> n 5) n (recur (1+ n)))))

(let*
    ((n 0))
  (rloop-
   #'(lambda
       (n)
       (if
           (> n 5)
           n
         (recur
          (1+ n))))
   n))

...which means two extra function calls on each iteration. But realistically, it's not such a big deal. Clarity of the code is way more important.