From: Eric Marsden
Subject: Lisp with XML concrete syntax
Date: 
Message-ID: <wzisnoipzkp.fsf@mail.dotcom.fr>
Quoting from <URL:http://www.w3.org/TR/xexpr/>:

    In many applications of XML, there is a requirement for using XML
    in conjunction with a scripting language. Many times, this results
    in a scripting language such as JavaScript being bound within the
    XML content (like the <script> tag). XEXPR is a scripting language
    that uses XML as its primary syntax, making it easily embeddable
    in an XML document. In addition, XEXPR takes a functional
    approach, and hence maps well onto the syntax of XML.

here is an example of the scripting language with the buzz-enabled
syntax: 

,----
| <define name="factorial" args="x">
|   <define name="iterator" args="product counter max">
|     <if>
|       <gt><counter/><max/></gt>
|       <product/>
|       <iterator>
|         <multiply><counter/><product/></multiply>
|         <add><counter/>1</add>
|         <max/>
|       </iterator>
|     </if>
|   </define>
| 
|   <iterator>1 1 <x/></iterator>
| </define>
`----

-- 
Eric Marsden                          <URL:http://www.laas.fr/~emarsden/>

From: Rainer Joswig
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <joswig-5CB643.19092723112000@news.is-europe.net>
In article <···············@mail.dotcom.fr>, Eric Marsden 
<········@mail.dotcom.fr> wrote:

> Quoting from <URL:http://www.w3.org/TR/xexpr/>:
> 
>     In many applications of XML, there is a requirement for using XML
>     in conjunction with a scripting language. Many times, this results
>     in a scripting language such as JavaScript being bound within the
>     XML content (like the <script> tag). XEXPR is a scripting language
>     that uses XML as its primary syntax, making it easily embeddable
>     in an XML document. In addition, XEXPR takes a functional
>     approach, and hence maps well onto the syntax of XML.
> 
> here is an example of the scripting language with the buzz-enabled
> syntax: 
> 
> ,----
> | <define name="factorial" args="x">
> |   <define name="iterator" args="product counter max">
> |     <if>
> |       <gt><counter/><max/></gt>
> |       <product/>
> |       <iterator>
> |         <multiply><counter/><product/></multiply>
> |         <add><counter/>1</add>
> |         <max/>
> |       </iterator>
> |     </if>
> |   </define>
> | 
> |   <iterator>1 1 <x/></iterator>
> | </define>
> `----

A barf bag, quick...

-- 
Rainer Joswig, Hamburg, Germany
Email: ·············@corporate-world.lisp.de
Web: http://corporate-world.lisp.de/
From: Michael Livshin
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <s3r94235r5.fsf@bigfoot.com>
Eric Marsden <········@mail.dotcom.fr> writes:

> | <define name="factorial" args="x">
> |   <define name="iterator" args="product counter max">
> |     <if>
> |       <gt><counter/><max/></gt>
> |       <product/>
> |       <iterator>
> |         <multiply><counter/><product/></multiply>
> |         <add><counter/>1</add>
> |         <max/>
> |       </iterator>
> |     </if>
> |   </define>
> | 
> |   <iterator>1 1 <x/></iterator>
> | </define>

I propose we call this "the mOdeRn syntax".

how long till there's a Mozilla-based volonteer project to support
this?

*gag*

-- 
(only legal replies to this address are accepted)

This code is a piece of crap! You have no honor!
                                        -- Klingon Programmer
From: Erik Naggum
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <3183998509472620@naggum.net>
* Eric Marsden <········@mail.dotcom.fr>
| here is an example of the scripting language with the buzz-enabled
| syntax: 
| 
| ,----
| | <define name="factorial" args="x">
| |   <define name="iterator" args="product counter max">
| |     <if>
| |       <gt><counter/><max/></gt>
| |       <product/>
| |       <iterator>
| |         <multiply><counter/><product/></multiply>
| |         <add><counter/>1</add>
| |         <max/>
| |       </iterator>
| |     </if>
| |   </define>
| | 
| |   <iterator>1 1 <x/></iterator>
| | </define>
| `----

  Wow!  This is almost like watching sports on TV.  You just know that
  those guys out there are generally in a lot of pain, seem to overcome
  it, at least while everyone's watching them and while the money from
  sponsors keep coming in, and are delightfully soon to be replaced by
  somebody else in a little _more_ pain.  Bring out the beer, this can
  get _fun_!

  XML -- till death do us parse.

#:Erik
-- 
  Solution to U.S. Presidential Election Crisis 2000:
    Let Texas secede from the Union and elect George W. Bush their
    very first President.  All parties, states would rejoice.
From: Geoff Summerhayes
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <t1r29rb3qur66a@corp.supernews.com>
How about:

<define name="factorial">
   <dup/>1<neq/><if><dup/>1<minus/><recurse/><multiply/></if>
</define>

What can I say, I hate typing. In XML, RPN is kind of nice.

Geoff


"Eric Marsden" <········@mail.dotcom.fr> wrote in message
····················@mail.dotcom.fr...
> ,----
> | <define name="factorial" args="x">
> |   <define name="iterator" args="product counter max">
> |     <if>
> |       <gt><counter/><max/></gt>
> |       <product/>
> |       <iterator>
> |         <multiply><counter/><product/></multiply>
> |         <add><counter/>1</add>
> |         <max/>
> |       </iterator>
> |     </if>
> |   </define>
> |
> |   <iterator>1 1 <x/></iterator>
> | </define>
> `----
>
> --
> Eric Marsden                          <URL:http://www.laas.fr/~emarsden/>
From: Marc Battyani
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <8vk2dq$6ei$1@reader1.fr.uu.net>
"Eric Marsden" <········@mail.dotcom.fr> wrote in message
····················@mail.dotcom.fr...
> Quoting from <URL:http://www.w3.org/TR/xexpr/>:
>
>     In many applications of XML, there is a requirement for using XML
>     in conjunction with a scripting language. Many times, this results
>     in a scripting language such as JavaScript being bound within the
>     XML content (like the <script> tag). XEXPR is a scripting language
>     that uses XML as its primary syntax, making it easily embeddable
>     in an XML document. In addition, XEXPR takes a functional
>     approach, and hence maps well onto the syntax of XML.
>
> here is an example of the scripting language with the buzz-enabled
> syntax:
>
> ,----
> | <define name="factorial" args="x">
> |   <define name="iterator" args="product counter max">
> |     <if>
> |       <gt><counter/><max/></gt>
> |       <product/>
> |       <iterator>
> |         <multiply><counter/><product/></multiply>
> |         <add><counter/>1</add>
> |         <max/>
> |       </iterator>
> |     </if>
> |   </define>
> |
> |   <iterator>1 1 <x/></iterator>
> | </define>

So brilliant, I hope they patented it. ;-)

I first thought it was a joke as it is a good conclusion to a recent thread
(http://www.deja.com/getdoc.xp?AN=638290840 ) but it seems real.

They went even farther than the jokes. A good example of how reality always
surpass fiction...

Marc
From: Tom Breton
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <m3snoi2fe6.fsf@world.std.com>
Eric Marsden <········@mail.dotcom.fr> writes:

> Quoting from <URL:http://www.w3.org/TR/xexpr/>:
> 
>     In many applications of XML, there is a requirement for using XML
>     in conjunction with a scripting language. Many times, this results
>     in a scripting language such as JavaScript being bound within the
>     XML content (like the <script> tag). XEXPR is a scripting language
>     that uses XML as its primary syntax, making it easily embeddable
>     in an XML document. In addition, XEXPR takes a functional
>     approach, and hence maps well onto the syntax of XML.
> 
> here is an example of the scripting language with the buzz-enabled
> syntax: 
> 
> ,----
> | <define name="factorial" args="x">
> |   <define name="iterator" args="product counter max">
> |     <if>
> |       <gt><counter/><max/></gt>
> |       <product/>
> |       <iterator>
> |         <multiply><counter/><product/></multiply>
> |         <add><counter/>1</add>
> |         <max/>
> |       </iterator>
> |     </if>
> |   </define>
> | 
> |   <iterator>1 1 <x/></iterator>
> | </define>
> `----

The thing that's most unLisp is that you can't start a listform with
an arbitrary head.  Everything has to be pre-defined in the dtd.  Eg,
there's no:

(flet
   ((foo () ...))

   (foo))

-- 
Visit this site to make your views known: www.AlGoreLost.org
Tom Breton, http://world.std.com/~tob
Not using "gh" 1997-2000. http://world.std.com/~tob/ugh-free.html
Some vocal people in cll make frequent, hasty personal attacks, but if
you killfile them cll becomes usable.
From: Valeriy E. Ushakov
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <8vmj2l$1ojm$1@news.spbu.ru>
Tom Breton <···@world.std.com> wrote:

>> ,----
>> | <define name="factorial" args="x">


> The thing that's most unLisp is that you can't start a listform with
> an arbitrary head.  Everything has to be pre-defined in the dtd.

Hey, that's XML.  They don't care about DTDs...

(You don't even have to bring FLET to discussion, the "define" above
 demonstrates it already.)

PS: Actually the MetaHTML (www.metahtml.org) was released in 1996
(IIRC) and it uses less tags.  Prepare your bard bags)...

  <define-tag splashy-bars start end step>
     <while <not <gt end start>>>
       <hr width=<get-var start>%>
       <set-var start=<sub start step>>
     </while>
  </define-tag>

SY, Uwe
-- 
···@ptc.spbu.ru                         |       Zu Grunde kommen
http://www.ptc.spbu.ru/~uwe/            |       Ist zu Grunde gehen
From: Bob Bane
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <3A2282F2.F853D9EB@removeme.gst.com>
The really sad thing about this is that they clearly don't have a clue
as to what a lexical scope is, or decent instincts for writing
tail-recursive code.  The Common Lisp equivalent to their XML concrete
is:

(defun factorial (x)
  (labels ((iterator (product counter max)
             (if (> counter max)
                product
                (iterator (* counter product)
                          (+ counter 1)
                          max)))
   (iterator 1 1 x)))

which could be written better as:

(defun factorial (x)
  (labels ((iterator (product counter)
             (if (> counter x)
                product
                (iterator (* counter product)
                          (+ counter 1))))
   (iterator 1 1)))

Or better yet:

(defun factorial (x)
  (labels ((iterator (product counter)
             (if (<= counter 0)
                product
                (iterator (* counter product)
                          (- counter 1))))
   (iterator 1 x)))

Once again, proof that nothing has been learned in the last 40 years of
computer science.

-- 
Remove obvious stuff to e-mail me.
Bob Bane
From: Hannah Schroeter
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <8vu7ap$4j2$1@c3po.schlund.de>
Hello!

In article <·················@removeme.gst.com>,
Bob Bane  <····@removeme.gst.com> wrote:
>[...]

>(defun factorial (x)
>  (labels ((iterator (product counter)
>             (if (<= counter 0)
>                product
>                (iterator (* counter product)
>                          (- counter 1))))
>   (iterator 1 x)))

And why not

(defun factorial (x &optional (ac 1))
 (if (<= x 1)
     ac
     (factorial (1- x) (* ac x))))

Kind regards,

Hannah.
From: Joe Marshall
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <vgt9w529.fsf@content-integrity.com>
······@schlund.de (Hannah Schroeter) writes:

> Hello!
> 
> In article <·················@removeme.gst.com>,
> Bob Bane  <····@removeme.gst.com> wrote:
> >[...]
> 
> >(defun factorial (x)
> >  (labels ((iterator (product counter)
> >             (if (<= counter 0)
> >                product
> >                (iterator (* counter product)
> >                          (- counter 1))))
> >   (iterator 1 x)))
> 
> And why not
> 
> (defun factorial (x &optional (ac 1))
>  (if (<= x 1)
>      ac
>      (factorial (1- x) (* ac x))))

1.  Factorial is function of 1 argument, not two.

2.  It may add an additional conditional test at the beginning of the
    call.


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Kent M Pitman
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <sfwu28tyvff.fsf@world.std.com>
Joe Marshall <···@content-integrity.com> writes:

> ······@schlund.de (Hannah Schroeter) writes:
> 
> [...]
> > And why not
> > 
> > (defun factorial (x &optional (ac 1))
> >  (if (<= x 1)
> >      ac
> >      (factorial (1- x) (* ac x))))
> 
> 1.  Factorial is function of 1 argument, not two. [...]

Well, yes, but one argument factorial is not tail recursive, like its
two argument friend is.
From: Joe Marshall
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <d7fhw0io.fsf@content-integrity.com>
Kent M Pitman <······@world.std.com> writes:

> Joe Marshall <···@content-integrity.com> writes:
> 
> > ······@schlund.de (Hannah Schroeter) writes:
> > 
> > [...]
> > > And why not
> > > 
> > > (defun factorial (x &optional (ac 1))
> > >  (if (<= x 1)
> > >      ac
> > >      (factorial (1- x) (* ac x))))
> > 
> > 1.  Factorial is function of 1 argument, not two. [...]
> 
> Well, yes, but one argument factorial is not tail recursive, like its
> two argument friend is.

Sure it is.  The one-argument factorial can simply tail recurse onto
its two-argument friend (with the appropriate argument).

I was saying that *semantically* that you may wish to avoid using
optional arguments as iteration state because they give the impression
that there is an additional `user-specified' parameter that usually
defaulted.  In this case, the function no longer computes the
factorial of its first argument if you override the second.  It would
most likely be an error to provide the second argument anywhere but in
that one recursive call.





-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Geoff Summerhayes
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <t25mvu2vdabq49@corp.supernews.com>
I don't see the problem. For example, just call it factorial-aux, lose the
&optional and
(defun factorial(x)       <--interface
   (factorial-aux x 1))   <--tail-recursion

or ...

Geoff

"Joe Marshall" <···@content-integrity.com> wrote in message
·················@content-integrity.com...
> Kent M Pitman <······@world.std.com> writes:

> I was saying that *semantically* that you may wish to avoid using
> optional arguments as iteration state because they give the impression
> that there is an additional `user-specified' parameter that usually
> defaulted.  In this case, the function no longer computes the
> factorial of its first argument if you override the second.  It would
> most likely be an error to provide the second argument anywhere but in
> that one recursive call.
From: glauber
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <8vuqp5$hi2$1@nnrp1.deja.com>
In article <··············@corp.supernews.com>,
  "Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> wrote:
> I don't see the problem. For example, just call it factorial-aux, lose the
> &optional and
> (defun factorial(x)       <--interface
>    (factorial-aux x 1))   <--tail-recursion

and scope factorial-aux so it's only visible inside factorial, and you're
protected.

--
Glauber Ribeiro
··········@my-deja.com    http://www.myvehiclehistoryreport.com
"Opinions stated are my own and not representative of Experian"


Sent via Deja.com http://www.deja.com/
Before you buy.
From: Janis Dzerins
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <87bsv0v4gf.fsf@asaka.latnet.lv>
glauber <··········@my-deja.com> writes:

> In article <··············@corp.supernews.com>,
>   "Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> wrote:
> > I don't see the problem. For example, just call it factorial-aux, lose the
> > &optional and
> > (defun factorial(x)       <--interface
> >    (factorial-aux x 1))   <--tail-recursion
> 
> and scope factorial-aux so it's only visible inside factorial, and you're
> protected.

And then we're back at where we started 6 articles ago:

Bob Bane wrote:
>(defun factorial (x)
>  (labels ((iterator (product counter)
>             (if (<= counter 0)
>                product
>                (iterator (* counter product)
>                          (- counter 1))))
>   (iterator 1 x)))

Janis Dzerins
-- 
  Ever feel like life was a game and you had the wrong instruction book?
From: Erik Naggum
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <3184424063976812@naggum.net>
* Hannah Schroeter
| And why not
| 
| (defun factorial (x &optional (ac 1))
|  (if (<= x 1)
|      ac
|      (factorial (1- x) (* ac x))))

  There are many good reasons not to do tail-call merging for calls to
  global, user-defined functions.  The function is conceptually distinct
  from the name, and while few people do it, you could copy the function
  over to a different symbol, and do something else with the old symbol.
  You _should_ expect to see it call the function in the old symbol, as
  that is the defined semantics of Common Lisp function calls.  It also
  helps debugging and numerous other common tasks not to confuse symbol
  with function named by symbol.

  Local functions have no such restrictions, of course, being part of
  the function itself rather than depend on the symbol for its meaning.

  I consider the above code fragment tantamount to using dynamic binding
  simply out of tradition.  The optional argument is another sign of old
  design and should be considered abuse of a language feature today.

#:Erik
-- 
  Solution to U.S. Presidential Election Crisis 2000:
    Let Texas secede from the Union and elect George W. Bush their
    very first President.  All parties, states would rejoice.
From: Tim Bradshaw
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <ey3pujb2dk4.fsf@cley.com>
* Erik Naggum wrote:

>   There are many good reasons not to do tail-call merging for calls to
>   global, user-defined functions.  The function is conceptually distinct
>   from the name, and while few people do it, you could copy the function
>   over to a different symbol, and do something else with the old symbol.
>   You _should_ expect to see it call the function in the old symbol, as
>   that is the defined semantics of Common Lisp function calls.  It also
>   helps debugging and numerous other common tasks not to confuse symbol
>   with function named by symbol.

Is this right?  From the hyperspec (3.2.2.3):

     Within a function named F, the compiler may (but is not required
     to) assume that an apparent recursive call to a function named F
     refers to the same definition of F, unless that function has been
     declared notinline. The consequences of redefining such a
     recursively defined function F while it is executing are
     undefined.

Which I read as meanind that within a definition like:

.. no NOTINLINE declaration for F ...

(defun f (...)
  ... no intervening local function bindings for F ...
  ... no intervening NOTINLINE declarations for F ...
  (f ...)
  ...)

the recursive call to F can safely be assumed to be a call to the F
defined by the DEFUN.

However I may not have read carefully enough, or I may have
misunderstood what you are saying.

--tim
From: Kent M Pitman
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <sfwu28mkfo9.fsf@world.std.com>
Tim Bradshaw <···@cley.com> writes:

> 
> * Erik Naggum wrote:
> 
> >   There are many good reasons not to do tail-call merging for calls to
> >   global, user-defined functions.  The function is conceptually distinct
> >   from the name, and while few people do it, you could copy the function
> >   over to a different symbol, and do something else with the old symbol.
> >   You _should_ expect to see it call the function in the old symbol, as
> >   that is the defined semantics of Common Lisp function calls.  It also
> >   helps debugging and numerous other common tasks not to confuse symbol
> >   with function named by symbol.
> 
> Is this right?  From the hyperspec (3.2.2.3): [...]
> the recursive call to F can safely be assumed to be a call to the F
> defined by the DEFUN.
> 
> However I may not have read carefully enough, or I may have
> misunderstood what you are saying.

Both of you are using slightly confusing language, IMO.

Tim, you're right that the compiler is permitted to optimize tail calls
in the way you describe.  But it is not required to.  Hence, you cannot
expect it to.

Erik, I think when you say "You _should_ expect" you're confusing him,
since you're using the English word "should expect", which has the
formal standards meaning "must not expect".  That is, anything that
doesn't say "must" isn't required and therefore should not be expected. :-)

The standard's wording is correct as to expectation:

     Within a function named F, the compiler may (but is not required
     to) assume that an apparent recursive call to a function named F
     refers to the same definition of F,

That is, you can't really expect anything.  It just encourages you not
to send a bug report in either case...
From: Tim Bradshaw
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <ey3g0k63jts.fsf@cley.com>
* Kent M Pitman wrote:

> Tim, you're right that the compiler is permitted to optimize tail calls
> in the way you describe.  But it is not required to.  Hence, you cannot
> expect it to.

I agree, and I'm sorry for vagueness.  What I really meant is that
if you do something like this (assuming no NOTINLINE declarations &
reasonable stack limits &c)


    ;;; in a file which is compiled & loaded
    (defun f (n)
      (if (zerop n)
          (end-the-world :now t)
          (f (- n 1))))

    (defun f-caller ()
      (f 2))

    ;;; in a file which is compiled and loaded after the above
    (defvar *f-fn* (symbol-function 'f))

    (setf (symbol-function 'f)
      #'(lambda (n)
          (declare (ignore n))
          (format t "~&The world has not ended~%")))

    (defun f-fn-caller ()
      (funcall *f-fn* 2))

Then you can not assume anything at all about whether either a call to
F-CALLER or F-FN-CALLER will cause END-THE-WORLD to be called.  In
particular you can not assume that it will *not* be called.

I hope that's right.  I guess the elaborateness of the example
demonstrates how fiddly the concepts are...

--tim
From: Kent M Pitman
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <sfwpuja21ht.fsf@world.std.com>
Tim Bradshaw <···@cley.com> writes:

> [big code example omitted]
> Then you can not assume anything at all about whether either a call to
> F-CALLER or F-FN-CALLER will cause END-THE-WORLD to be called.  In
> particular you can not assume that it will *not* be called.
> 
> I hope that's right.  I guess the elaborateness of the example
> demonstrates how fiddly the concepts are...

Right.  I think the primary guarantee you get is that you can do:

 (defmacro autoload (fn file)
   (check-type fn   symbol "a function name")
   (check-type file (or string pathname) "a filename")
   `(defun ,fn (&rest args)
      (declare (notinline ,fn))
      (let ((,fn #',fn))
        (load ,file)
        (when (eq ,fn #'fn)
          (error "Definition of ~S not found in ~A."
		 ',fn ',file))
        (apply #',fn args))))

or things like that where you don't want the compiler to get confused
and think you're a wayward Scheme programmer setting up an infinite loop.
That is, it's for self-defining and self-redefining functions.
For efficiency, of course, I'd probably do this particular task I used
above as a closure instead, as in:

 (defun autoloader (function file)
   #'(lambda (&rest args)
       (let ((function (symbol-function fn)))
          (load file)
	  (let ((new (symbol-function fn)))
            (when (eq new function)
              (error "Definition of ~S not found in ~A." function file))
	    (apply new args)))))

 (defmacro autoload (fn file)
   (check-type fn   symbol "a function name")
   (check-type file (or string pathname) "a filename")
   `(progn (setf (symbol-function ',fn) (autoloader ',fn ',file))
	   ',fn))

But then, of course, the NOTINLINE issue wouldn't come up and this would
have been a lousy example.  Ah well.

What? Did I *test* the above code? Not me... Just for illustration.  No
warranty (as if there would be one otherwise--ha,ha).  Caveat emptor. ...
From: Bob Bane
Subject: Re: Lisp with XML concrete syntax
Date: 
Message-ID: <3A22BB5F.7FA4FE8C@removeme.gst.com>
A depressingly direct example of:

Greenspun's Tenth Rule of Programming: "Any sufficiently complicated C
or Fortran
program contains an ad-hoc, informally-specified bug-ridden slow
implementation of
half of Common Lisp."

See http://philip.greenspun.com/research/index.html

-- 
Remove obvious stuff to e-mail me.
Bob Bane