How about something like this?
This may neither be suitable in the context of teaching newbies nor appeal to your sense of aesthetics, however I like this general approach as a way of cleanly (?) "overlaying" a new family of operators on top of already established symbols as an alternative to "let's shadow 100 symbols and have tons of package conflicts later" and "let's 'duplicate' 100 symbols by adopting some naming convention based on the original names".
(Also pasted to http://paste.lisp.org/display/128782 for formatting and future reference.)
(in-package #:cl-user)
(defvar *functionals* (make-hash-table :test 'eq))
(defun find-functional (name &key (errorp t)) (or (gethash name *functionals*) (when errorp (error "There is no functional named ~S." name))))
(defun (setf find-functional) (new name &key (errorp t)) (declare (ignore errorp)) (setf (gethash name *functionals*) new))
(defmacro functional (operator-or-form) (etypecase operator-or-form (symbol `(find-functional ',operator-or-form)) (cons `(funcall (functional ,(car operator-or-form)) ,@(cdr operator-or-form)))))
(defmacro define-functional (name args &body body) `(setf (find-functional ',name) (lambda ,args ,@body)))
(define-functional while (predicate body) (when (funcall predicate) (funcall body) (functional (while predicate body))))
(defmacro while (predicate &body body) `(functional (while (lambda () ,predicate) (lambda () ,@body))))
;;; And then:
(let ((counter 0)) (while (< counter 3) (print (incf counter)))) == (let ((counter 0)) (functional (while (lambda () (< counter 3)) (lambda () (print (incf counter)))))) == (let ((counter 0)) (funcall (functional while) (lambda () (< counter 3)) (lambda () (print (incf counter))))) == (let ((counter 0)) (funcall (find-functional 'while) (lambda () (< counter 3)) (lambda () (print (incf counter)))))