From: Nate
Subject: fn abstraction?
Date: 
Message-ID: <1180581526.755102.311210@d30g2000prg.googlegroups.com>
so I've been wondering, am I missing something hideously wrong with
this? As in, is there something ugly, etc? because it's clear when you
use it for one use or the other, and I'm wondering why it's not been
done before (probably readability?).

(defmacro fn (&body bd)
  (if (consp (first bd))
      `(function (lambda ,(first bd) ,@(cdr bd)))
      `(defun ,(first bd) ,(second bd) ,@(cddr bd))))

as in

(mapcar #'(lambda (x y) (list x y)) lst1 lst2) =>

(mapcar (fn (x y) (list x y)) lst1 lst2)

nate

ps I might have stolen the idea from arc

From: Kaz Kylheku
Subject: Re: fn abstraction?
Date: 
Message-ID: <1180582441.099749.122510@n15g2000prd.googlegroups.com>
On May 30, 8:18 pm, Nate <·············@gmail.com> wrote:
> so I've been wondering, am I missing something hideously wrong with
> this? As in, is there something ugly, etc? because it's clear when you
> use it for one use or the other, and I'm wondering why it's not been
> done before (probably readability?).
>
> (defmacro fn (&body bd)
>   (if (consp (first bd))
>       `(function (lambda ,(first bd) ,@(cdr bd)))
>       `(defun ,(first bd) ,(second bd) ,@(cddr bd))))
>
> as in
>
> (mapcar #'(lambda (x y) (list x y)) lst1 lst2) =>
>
> (mapcar (fn (x y) (list x y)) lst1 lst2)

So now you can do

  (mapcar (fn foo) ...) ;; named

  (mapcar (fn (x y) ...) ;; anon

Versus

  (mapcar (funtion foo) ...)

  (mapcar (lambda (x y) ...) ...)

Doesn't buy anything. The real action is in semantics, and what action
there is in syntax, it is outside of trivial transliterations like
this.

Also consider that function names can be compound forms, giving rise
(fn (setf foo) ...) being misinterpreted into (lambda (setf foo) ...).
From: Kent M Pitman
Subject: Re: fn abstraction?
Date: 
Message-ID: <uhcpso6k1.fsf@nhplace.com>
Nate <·············@gmail.com> writes:

> so I've been wondering, am I missing something hideously wrong with
> this? 

I usually try to put such remarks in more diplomatic terms, but since
they're your words and not mine, I'll bargain down to them and just 
say "yes".

Certainly it is not, if you'll pardon the expression, my idea of fn.

> As in, is there something ugly, etc? because it's clear when you
> use it for one use or the other, and I'm wondering why it's not been
> done before (probably readability?).

I'm pressed for time, so I'll just say "avoid overloading".

> (defmacro fn (&body bd)
>   (if (consp (first bd))
>       `(function (lambda ,(first bd) ,@(cdr bd)))
>       `(defun ,(first bd) ,(second bd) ,@(cddr bd))))
> 
> as in
> 
> (mapcar #'(lambda (x y) (list x y)) lst1 lst2) =>
> 
> (mapcar (fn (x y) (list x y)) lst1 lst2)

Nothing wrong with this.  The problem is not the fn usage as a lambda.
(I do think your propensity to shorten names ("bd") is something to overcome.
Call it body.  There's no problem with spelling out names.  We are not
Scheme, where you often have to make short parameter names to avoid shadowing
functions you want to use.  CL is designed to be read.  bd is an abbreviation
for who knows what.  Spelling it out makes it less ugly.)

Though note that lambda already does what you suggest.  It all you're
buying is 5 chars.  That is,
 (mapcar (lambda (x y) (list x y)) list1 list2)
works as well
 (mapcar (fn     (x y) (list x y)) list1 list2)
after all that work.  It's a possible thing to do.  Just marginal.

> nate
> 
> ps I might have stolen the idea from arc

Then I don't recommend they do it either. :)

I don't have time to explain the detail of why overloading this is
bad, but I'll allude to the reasons and one of the many other
competent commenters here can add detail if this is too cryptic:

(a) Emacs will like having defxxx names separate from other names.
    (Both because it likes to find starts of definitions and because
     it's easier to compute where the body is.)

(b) Eventually someone will figure out you can use the defun part in a
    body to denote recursive functions but that the effects are a little
    weird (not to mention possibly also slow).  Here's an example to
    ponder.  Ask yourself what the scope of and the time of definition of
    the function fact is:
    (defun foo ()
      (let ((one 1))
        (funcall (fn fact (x)
                   (if (zerop x) one (* x (fact (- x 1))))) 6)))