From: Slobodan Blazeski
Subject: Is it possible to implement ,@  if it wasn't already there
Date: 
Message-ID: <e3a54ba9-dd09-45f1-922e-47355ee49e63@l28g2000prd.googlegroups.com>
I need to get rid of some funcalls some so could I do something
like ,@ is doing

((splice #'(lambda (x) (* 2 x))) 4) <=> (funcall #'(lambda (x) (* 2
x))) 4)

From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <aba80dd8-bcb8-42b2-a2f4-f0707eab8bea@z24g2000prf.googlegroups.com>
On Apr 15, 6:53 am, Slobodan Blazeski <·················@gmail.com>
wrote:
> I need to get rid of some funcalls some so could I do something
> like ,@ is doing
>
> ((splice #'(lambda (x) (* 2 x))) 4) <=> (funcall #'(lambda (x) (* 2
> x))) 4)


Try:

((lambda (x) (* 2 x)) 4)
From: Tim Bradshaw
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <970f5c38-1bba-41fe-aeca-f5b2886c59f5@p39g2000prm.googlegroups.com>
I don't understand your example, but to answer the question in the
subject: yes.  Remember that ,@ only makes sense inside a a backquote,
so all you need it to do is to expand into something that whatever
backquote expands into knows how to deal with.  There are
implementations of backquote out there.
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <9a1868d4-a05d-44c5-ad37-af2fa42265f8@q27g2000prf.googlegroups.com>
On Apr 15, 9:36 am, Tim Bradshaw <··········@tfeb.org> wrote:
> I don't understand your example, but to answer the question in the
> subject: yes.  Remember that ,@ only makes sense inside a a backquote,
> so all you need it to do is to expand into something that whatever
> backquote expands into knows how to deal with.  There are
> implementations of backquote out there.
No that way I want to remove verbosity not add even more of it.

The problem is that I need a single namespace like in scheme so I must
jump through some hoops.
Basically I need to tell the compiler that whatever comes after an
open paren is operator or expressions that returns an operator.
The cl was not designed with this in mind so I need some unusual
approch than regual clisping.
For example custom defun that sets both function and symbol value to a
function etc
From: Pascal Costanza
Subject: Re: Is it possible to implement ,@  if it wasn't already there
Date: 
Message-ID: <66ju32F2ivg2mU1@mid.individual.net>
Slobodan Blazeski wrote:
> I need to get rid of some funcalls some so could I do something
> like ,@ is doing
> 
> ((splice #'(lambda (x) (* 2 x))) 4) <=> (funcall #'(lambda (x) (* 2
> x))) 4)

What?!?


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@  if it wasn't already there
Date: 
Message-ID: <4804cb08$0$90271$14726298@news.sunsite.dk>
 SB> I need to get rid of some funcalls some so could I do something
 SB> like ,@ is doing

 SB> ((splice #'(lambda (x) (* 2 x))) 4) <=> (funcall #'(lambda (x) (* 2
 SB> x))) 4)

what's about this: ((lambda (x) (* 2 x)) 4)? 
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <1e5e92e6-70ba-4a02-ade3-f994e6c63938@t12g2000prg.googlegroups.com>
On Apr 15, 8:34 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  SB> I need to get rid of some funcalls some so could I do something
>  SB> like ,@ is doing
>
>  SB> ((splice #'(lambda (x) (* 2 x))) 4) <=> (funcall #'(lambda (x) (* 2
>  SB> x))) 4)
>
> what's about this: ((lambda (x) (* 2 x)) 4)?

Many thanks, just what I wanted .
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <ad3e23cb-4a44-423e-96ef-94346a212a5c@w5g2000prd.googlegroups.com>
On Apr 15, 11:32 am, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Apr 15, 8:34 am, "Alex Mizrahi" <········@users.sourceforge.net>
> wrote:
> > what's about this: ((lambda (x) (* 2 x)) 4)?
>
> Many thanks, just what I wanted .

I doubt it. That's how variable binding was done in early Lisp, but
luckily, sometime in the 1960's, someone invented LET:

  (let ((x 4)) (* 2 x))

:)
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <61e2c9b5-3290-4c39-ae23-352d66241a00@u36g2000prf.googlegroups.com>
On Apr 15, 11:46 am, Kaz Kylheku <········@gmail.com> wrote:
> On Apr 15, 11:32 am, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
> > On Apr 15, 8:34 am, "Alex Mizrahi" <········@users.sourceforge.net>
> > wrote:
> > > what's about this: ((lambda (x) (* 2 x)) 4)?
>
> > Many thanks, just what I wanted .
>
> I doubt it. That's how variable binding was done in early Lisp, but
> luckily, sometime in the 1960's, someone invented LET:
>
>   (let ((x 4)) (* 2 x))
>
> :)
Soprry If I'm not clear but here the problem


(defun make-adder (n)
                #'(lambda (x) (+ x n)))
MAKE-ADDER
(funcall (make-adder 3) 8)
11

((make-adder 3) 8)

Error: Illegal argument in functor position: (MAKE-ADDER 3) in ((MAKE-
ADDER 3) 8).
  1 (continue) Evaluate (MAKE-ADDER 3) and ignore the rest.
  2 (abort) Return to level 0.
  3 Return to top loop level 0.

The only solution is playing on lambda level  or switching to scheme.
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <ebf8598d-ed58-4e2e-9f5d-e90e59653b41@a22g2000hsc.googlegroups.com>
On Apr 15, 12:03 pm, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Apr 15, 11:46 am, Kaz Kylheku <········@gmail.com> wrote:> On Apr 15, 11:32 am, Slobodan Blazeski <·················@gmail.com>
> > wrote:
>
> > > On Apr 15, 8:34 am, "Alex Mizrahi" <········@users.sourceforge.net>
> > > wrote:
> > > > what's about this: ((lambda (x) (* 2 x)) 4)?
>
> > > Many thanks, just what I wanted .
>
> > I doubt it. That's how variable binding was done in early Lisp, but
> > luckily, sometime in the 1960's, someone invented LET:
>
> >   (let ((x 4)) (* 2 x))
>
> > :)
>
> Soprry If I'm not clear but here the problem
>
> (defun make-adder (n)
>                 #'(lambda (x) (+ x n)))
> MAKE-ADDER
> (funcall (make-adder 3) 8)
> 11
>
> ((make-adder 3) 8)

You can make a macro which will create a lexical function binding that
is connected to a lambda.

(defmacro fname-bind ((&rest name-function-pairs) &body body)
  (loop for (name function) in name-function-pairs
        and for sym = (gensym)
        collect `(,sym ,function) into temps
        collect `(,name (&rest args)
                  (apply ,sym args)) into funcs
        finally (return `(let ,temps
                           (flet ,funcs
                             ,@body)))))

(defun make-counter (start)
  (lambda () (prog1 start (incf start))))

(fname-bind ((counter (make-counter 1)))
  (list (counter) (counter) (counter)))

==> (1 2 3)

Above, (make-counter 1) is called to return a counter that generates
successive integers from 1 as it is called. This is associated with
the lexical function name COUNTER, so that calling (counter) calls
into the closure.

Without this you would instead write:

 (let ((counter (make-counter 1)))
   (list (funcall counter) (funcall counter) (funcall counter)))

Even if we hacked a way to have ((make-counter 1)), it would do the
wrong thing anyway, since we want to call the same function object
multiple times.
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <35afcf9f-2f58-4a89-b933-afba138be4e6@k37g2000hsf.googlegroups.com>
On Apr 16, 4:07 am, Kaz Kylheku <········@gmail.com> wrote:
> On Apr 15, 12:03 pm, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
>
>
>
>
> > On Apr 15, 11:46 am, Kaz Kylheku <········@gmail.com> wrote:> On Apr 15, 11:32 am, Slobodan Blazeski <·················@gmail.com>
> > > wrote:
>
> > > > On Apr 15, 8:34 am, "Alex Mizrahi" <········@users.sourceforge.net>
> > > > wrote:
> > > > > what's about this: ((lambda (x) (* 2 x)) 4)?
>
> > > > Many thanks, just what I wanted .
>
> > > I doubt it. That's how variable binding was done in early Lisp, but
> > > luckily, sometime in the 1960's, someone invented LET:
>
> > >   (let ((x 4)) (* 2 x))
>
> > > :)
>
> > Soprry If I'm not clear but here the problem
>
> > (defun make-adder (n)
> >                 #'(lambda (x) (+ x n)))
> > MAKE-ADDER
> > (funcall (make-adder 3) 8)
> > 11
>
> > ((make-adder 3) 8)
>
> You can make a macro which will create a lexical function binding that
> is connected to a lambda.
>
> (defmacro fname-bind ((&rest name-function-pairs) &body body)
>   (loop for (name function) in name-function-pairs
>         and for sym = (gensym)
>         collect `(,sym ,function) into temps
>         collect `(,name (&rest args)
>                   (apply ,sym args)) into funcs
>         finally (return `(let ,temps
>                            (flet ,funcs
>                              ,@body)))))
>
> (defun make-counter (start)
>   (lambda () (prog1 start (incf start))))
>
> (fname-bind ((counter (make-counter 1)))
>   (list (counter) (counter) (counter)))
>
> ==> (1 2 3)
>
> Above, (make-counter 1) is called to return a counter that generates
> successive integers from 1 as it is called. This is associated with
> the lexical function name COUNTER, so that calling (counter) calls
> into the closure.
>
> Without this you would instead write:
>
>  (let ((counter (make-counter 1)))
>    (list (funcall counter) (funcall counter) (funcall counter)))
>
> Even if we hacked a way to have ((make-counter 1)), it would do the
> wrong thing anyway, since we want to call the same function object
> multiple times.- Hide quoted text -
>
> - Show quoted text -

I don't understand what that buys me. I want one simple rule whatever
comes after opening paren is a function or phrase that returns a
function, so go ahead and evaluate it using the rest of the sentence
as arguments. Forget about wrapping anything into something else.
So there is only two cases:
(function arg arg arg ...)
((something-that-returns-a-function arg arg) arg arg..)
that's it.
No staff like
(some-macro
  ((something-that-returns-a-function arg arg) arg arg..))
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <355220b7-4512-4a65-8c06-ccb34f5da503@a1g2000hsb.googlegroups.com>
On Apr 16, 12:33 am, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Apr 16, 4:07 am, Kaz Kylheku <········@gmail.com> wrote:
> > (fname-bind ((counter (make-counter 1)))
> >   (list (counter) (counter) (counter)))
>
> > ==> (1 2 3)
>
> > Above, (make-counter 1) is called to return a counter that generates
> > successive integers from 1 as it is called. This is associated with
> > the lexical function name COUNTER, so that calling (counter) calls
> > into the closure.
>
> > Without this you would instead write:
>
> >  (let ((counter (make-counter 1)))
> >    (list (funcall counter) (funcall counter) (funcall counter)))
>
> > Even if we hacked a way to have ((make-counter 1)), it would do the
> > wrong thing anyway, since we want to call the same function object
> > multiple times.- Hide quoted text -
>
> > - Show quoted text -
>
> I don't understand what that buys me.

I don't understand what an obsession with eliminating funcall buys
anyone.

What the above macro buys you is that you can bind a symbol to a
function object in a way very similar to LET, rather than to a
function definition as with LABELS or FLET.  You can then use the
symbol as a function name.

> Forget about wrapping anything into something else.
> So there is only two cases:
> (function arg arg arg ...)
> ((something-that-returns-a-function arg arg) arg arg..)
> that's it.
> No staff like
> (some-macro
>   ((something-that-returns-a-function arg arg) arg arg..))

In general, you need (SOME-MACRO ...)  if the ``...'' part is to be
understood as a different programming language.

Macros are the primary means for assigning your own meaning to syntax,
and macros don't work unless they are called.

Something in the Lisp source code has to indicate that ``from here to
here, a different programming language is in effect''.

The only way around that is to implement your own COMPILE-FILE and
LOAD, etc. Then you control how even top-level forms (not wrapped in
any other form) are evaluated, and so the entire source file is
understood to be in your own custom language.
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <4805e411$0$90274$14726298@news.sunsite.dk>
 KK> The only way around that is to implement your own COMPILE-FILE and
 KK> LOAD, etc.

wrong. this can be implemented either on reader level (to some extent, this 
is likely to interfere with other features), or via a code walker macro --  
it is possible to shadow defun and transform code inside it.
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <5f7af238-c487-46c9-b78f-1f07dd2f30e8@u69g2000hse.googlegroups.com>
On Apr 16, 4:33 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  KK> The only way around that is to implement your own COMPILE-FILE and
>  KK> LOAD, etc.
>
> wrong. this can be implemented either on reader level (to some extent, this
> is likely to interfere with other features), or via a code walker macro --  
> it is possible to shadow defun and transform code inside it.

Shadowing defun won't work for toplevel forms which are not in the
body of a defun. To do this shadowing, you have to switch to a
different package before loading the module that uses this shadow
defun. That's like writing your own custom LOAD. The file will not
load correctly if you do not set up that shadowing around LOAD.

Writing a code-walker macro won't do any good if the macro isn't
called. (That you will need code walking in order to support ((expr)
args ...) is clear).

Implementing this on the reader level requires that you turn on the
custom reader somewhere, so again, the file either has to contain
something explicit which denotes a change in syntax, or else it can
only be loaded by a customized loading function.
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <48072c80$0$90269$14726298@news.sunsite.dk>
 ??>> wrong. this can be implemented either on reader level (to some extent,
 ??>> this is likely to interfere with other features), or via a code walker
 ??>> macro --   it is possible to shadow defun and transform code inside
 ??>> it.

 KK> Shadowing defun won't work for toplevel forms which are not in the
 KK> body of a defun.

yep. but one who will use such extensions probably will know of limitations, 
no?

 KK>  To do this shadowing, you have to switch to a different package before
 KK> loading the module that uses this shadow defun.

someone will have to do something to switch into "fancy mode". i.e. write 
(in-package :fancy) at top of file, or something like that.

 KK>  That's like writing your own custom LOAD. The file will not load
 KK> correctly if you do not set up that shadowing around LOAD.

you mean hacking LOAD is required to hijack all forms, not just defun?
yep, right, but hijacking DEFUN and some other forms will make it right in 
99% of cases

 KK> Implementing this on the reader level requires that you turn on the
 KK> custom reader somewhere, so again, the file either has to contain
 KK> something explicit which denotes a change in syntax, or else it can
 KK> only be loaded by a customized loading function.

what's about library being loaded in rc file loaded when lisp starts? 
finally this needs to be enabled in some way, after all.

as i understand Slobodan was objecting from having to use macro _each time_ 
he needs this syntax. 
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <1234a842-c6bb-4ae1-8b2f-7786a533eead@y21g2000hsf.googlegroups.com>
On Apr 16, 11:08 am, Kaz Kylheku <········@gmail.com> wrote:
> On Apr 16, 12:33 am, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
>
>
>
>
> > On Apr 16, 4:07 am, Kaz Kylheku <········@gmail.com> wrote:
> > > (fname-bind ((counter (make-counter 1)))
> > >   (list (counter) (counter) (counter)))
>
> > > ==> (1 2 3)
>
> > > Above, (make-counter 1) is called to return a counter that generates
> > > successive integers from 1 as it is called. This is associated with
> > > the lexical function name COUNTER, so that calling (counter) calls
> > > into the closure.
>
> > > Without this you would instead write:
>
> > >  (let ((counter (make-counter 1)))
> > >    (list (funcall counter) (funcall counter) (funcall counter)))
>
> > > Even if we hacked a way to have ((make-counter 1)), it would do the
> > > wrong thing anyway, since we want to call the same function object
> > > multiple times.- Hide quoted text -
>
> > > - Show quoted text -
>
> > I don't understand what that buys me.
>
> I don't understand what an obsession with eliminating funcall buys
> anyone.

I want to see how much could I squeeze of functionality without
introducing syntax, considering the style I'm trying will mean
operating on functions instead, tacit programming and worse adding
funcall will reintroduce too much vebosity.

> In general, you need (SOME-MACRO ...)  if the ``...'' part is to be
> understood as a different programming language.

Well in sort of sense it is a different language and I I'm trying to
make that it isn't. Integrating it behind the curtain. But it
obviously won't with cl the way I want it.
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <b53a7776-fc3d-42d4-ba80-3de3dcddce0a@l42g2000hsc.googlegroups.com>
On Apr 17, 12:09 am, Slobodan Blazeski <·················@gmail.com>
wrote:
> On Apr 16, 11:08 am, Kaz Kylheku <········@gmail.com> wrote:
>
>
>
>
>
> > On Apr 16, 12:33 am, Slobodan Blazeski <·················@gmail.com>
> > wrote:
>
> > > On Apr 16, 4:07 am, Kaz Kylheku <········@gmail.com> wrote:
> > > > (fname-bind ((counter (make-counter 1)))
> > > >   (list (counter) (counter) (counter)))
>
> > > > ==> (1 2 3)
>
> > > > Above, (make-counter 1) is called to return a counter that generates
> > > > successive integers from 1 as it is called. This is associated with
> > > > the lexical function name COUNTER, so that calling (counter) calls
> > > > into the closure.
>
> > > > Without this you would instead write:
>
> > > >  (let ((counter (make-counter 1)))
> > > >    (list (funcall counter) (funcall counter) (funcall counter)))
>
> > > > Even if we hacked a way to have ((make-counter 1)), it would do the
> > > > wrong thing anyway, since we want to call the same function object
> > > > multiple times.- Hide quoted text -
>
> > > > - Show quoted text -
>
> > > I don't understand what that buys me.
>
> > I don't understand what an obsession with eliminating funcall buys
> > anyone.
>
> I want to see how much could I squeeze of functionality without
> introducing syntax

But you are introducing syntax.

> Well in sort of sense it is a different language and I I'm trying to
> make that it isn't. Integrating it behind the curtain. But it
> obviously won't with cl the way I want it.

The evaluation rules are buried deep inside the EVAL and COMPILE
functions, which are used by LOAD and COMPILE-FILE, and your listener
REPL.

Those rules are simply not programmable (in any portable way); they
are part of the hard-coded bottom layer of the Lisp system. (Well,
there is one exception: there is a way to hook into the macroexpansion
process. See my comments near the end).

To change the behavior of evaluation and compilation (in a proper way
which isn't some half-broken hack, such as tricks with the reader, or
shadowing DEFUN etc) you have to write your own EVAL and COMPILE.  One
way to do this would be to write a code walking function which
analyzes your language and transforms it to Lisp. That is to say, it
will take a Lisp form and recursively walk it in order to discover all
forms that are embedded in it which occur in an evaluation context.
Those, and only those, forms are then subject to the transformation
((X ...) Y ...) -> (funcall (X ...) Y ...).

Your custom EVAL can then be implemented by filtering code through
this walker and then passing the result to the built-in EVAL. COMPILE
can be implemented in a similar way.

The harder task is writing your own COMPILE-FILE and LOAD which would
recognize files written in this language, and your own listener which
will read, evaluate (through your custom evaluator) and print forms.

There may be a way to hack this almost perfectly using *macroexpand-
hook*, relying on the idea that almost all Lisp code is already
wrapped in some kind of macro form (such as DEFUN, DEFMACRO, DEFVAR,
etc).

The global variable *macroexpand-hook* provides a way to instrument
Lisp's macroexpansion process. You acn make this variable point to
your own function, which will get control before macroexpansion takes
place.

Your macroexpander hook function can expand the form normally, and
then run your code-walker on the expanded code to perform the
aforementioned transformation that turns ((expr) arg ...) into
(funcall (expr) arg ...).

You return this transformed code and it goes straight into the
evaluator or compiler.

There is no generic ``*form-process-hook*'' by which you can gain
control over the processing of arbitrary forms before they are
evaluated or compiled, but being able to intercept all macros is more
than enough rope to hang yourself with.

You get considerable control over the evaluation process this way
without having to write your own EVAL, COMPILE, etc.
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <0dab09aa-e6db-4787-95ba-0f60f6dc7d71@a70g2000hsh.googlegroups.com>
On Apr 17, 1:32 am, Kaz Kylheku <········@gmail.com> wrote:
> On Apr 17, 12:09 am, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
>
>
>
>
> > On Apr 16, 11:08 am, Kaz Kylheku <········@gmail.com> wrote:
>
> > > On Apr 16, 12:33 am, Slobodan Blazeski <·················@gmail.com>
> > > wrote:
>
> > > > On Apr 16, 4:07 am, Kaz Kylheku <········@gmail.com> wrote:
> > > > > (fname-bind ((counter (make-counter 1)))
> > > > >   (list (counter) (counter) (counter)))
>
> > > > > ==> (1 2 3)
>
> > > > > Above, (make-counter 1) is called to return a counter that generates
> > > > > successive integers from 1 as it is called. This is associated with
> > > > > the lexical function name COUNTER, so that calling (counter) calls
> > > > > into the closure.
>
> > > > > Without this you would instead write:
>
> > > > >  (let ((counter (make-counter 1)))
> > > > >    (list (funcall counter) (funcall counter) (funcall counter)))
>
> > > > > Even if we hacked a way to have ((make-counter 1)), it would do the
> > > > > wrong thing anyway, since we want to call the same function object
> > > > > multiple times.- Hide quoted text -
>
> > > > > - Show quoted text -
>
> > > > I don't understand what that buys me.
>
> > > I don't understand what an obsession with eliminating funcall buys
> > > anyone.
>
> > I want to see how much could I squeeze of functionality without
> > introducing syntax
>
> But you are introducing syntax.
I mean without intorducing new syntax.
Damn that's wrong explanation again.
What I really mean is I want to look like normal cl, something like
adding a new engine into a same chasis.
Everything is same but car goes faster. (And spends much more
gasoline).

>
> > Well in sort of sense it is a different language and I I'm trying to
> > make that it isn't. Integrating it behind the curtain. But it
> > obviously won't with cl the way I want it.
>
> The evaluation rules are buried deep inside the EVAL and COMPILE
> functions, which are used by LOAD and COMPILE-FILE, and your listener
> REPL.
>
> Those rules are simply not programmable (in any portable way); they
> are part of the hard-coded bottom layer of the Lisp system. (Well,
> there is one exception: there is a way to hook into the macroexpansion
> process. See my comments near the end).
>
> To change the behavior of evaluation and compilation (in a proper way
> which isn't some half-broken hack, such as tricks with the reader, or
> shadowing DEFUN etc) you have to write your own EVAL and COMPILE.  One
> way to do this would be to write a code walking function which
> analyzes your language and transforms it to Lisp. That is to say, it
> will take a Lisp form and recursively walk it in order to discover all
> forms that are embedded in it which occur in an evaluation context.
> Those, and only those, forms are then subject to the transformation
> ((X ...) Y ...) -> (funcall (X ...) Y ...).
>
> Your custom EVAL can then be implemented by filtering code through
> this walker and then passing the result to the built-in EVAL. COMPILE
> can be implemented in a similar way.
>
> The harder task is writing your own COMPILE-FILE and LOAD which would
> recognize files written in this language, and your own listener which
> will read, evaluate (through your custom evaluator) and print forms.
>
> There may be a way to hack this almost perfectly using *macroexpand-
> hook*, relying on the idea that almost all Lisp code is already
> wrapped in some kind of macro form (such as DEFUN, DEFMACRO, DEFVAR,
> etc).
>
> The global variable *macroexpand-hook* provides a way to instrument
> Lisp's macroexpansion process. You acn make this variable point to
> your own function, which will get control before macroexpansion takes
> place.
>
> Your macroexpander hook function can expand the form normally, and
> then run your code-walker on the expanded code to perform the
> aforementioned transformation that turns ((expr) arg ...) into
> (funcall (expr) arg ...).
>
> You return this transformed code and it goes straight into the
> evaluator or compiler.
>
> There is no generic ``*form-process-hook*'' by which you can gain
> control over the processing of arbitrary forms before they are
> evaluated or compiled, but being able to intercept all macros is more
> than enough rope to hang yourself with.
>
> You get considerable control over the evaluation process this way
> without having to write your own EVAL, COMPILE, etc.- Hide quoted text -
>
> - Show quoted text -

You're explanations are great Kaz, I never played with those features
so I will have to check on them and see where they'll take me.
In theory it looks like it will work in practice will see when I throw
everything I got.
From: Pascal J. Bourguignon
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <7ctzi0zk32.fsf@pbourguignon.anevia.com>
Kaz Kylheku <········@gmail.com> writes:
> To change the behavior of evaluation and compilation (in a proper way
> which isn't some half-broken hack, such as tricks with the reader, or
> shadowing DEFUN etc) you have to write your own EVAL and COMPILE.  One
> way to do this would be to write a code walking function which
> analyzes your language and transforms it to Lisp. That is to say, it
> will take a Lisp form and recursively walk it in order to discover all
> forms that are embedded in it which occur in an evaluation context.
> Those, and only those, forms are then subject to the transformation
> ((X ...) Y ...) -> (funcall (X ...) Y ...).
>
> Your custom EVAL can then be implemented by filtering code through
> this walker and then passing the result to the built-in EVAL. COMPILE
> can be implemented in a similar way.
>
> The harder task is writing your own COMPILE-FILE and LOAD which would
> recognize files written in this language, and your own listener which
> will read, evaluate (through your custom evaluator) and print forms.

For example, you can have a look at PSEUDO, to see how it's done.


C/USER[55]> (pseudo)
This is Pseudoscheme 2.12.

C/SCHEME[56]> ((if (< 1 2) + -)  10 5)
15
C/SCHEME[57]> (quit)
Leaving Pseudoscheme.

C/USER[58]> (funcall (if (< 1 2) (function +) (function -)) 10 5) ; back home
15
C/USER[59]> 

-- 
__Pascal Bourguignon__
From: Pascal J. Bourguignon
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <7cy77czypw.fsf@pbourguignon.anevia.com>
Slobodan Blazeski <·················@gmail.com> writes:

> On Apr 16, 11:08�am, Kaz Kylheku <········@gmail.com> wrote:
>> On Apr 16, 12:33�am, Slobodan Blazeski <·················@gmail.com>
>> wrote:
>>
>>
>>
>>
>>
>> > On Apr 16, 4:07�am, Kaz Kylheku <········@gmail.com> wrote:
>> > > (fname-bind ((counter (make-counter 1)))
>> > > � (list (counter) (counter) (counter)))
>>
>> > > ==> (1 2 3)
>>
>> > > Above, (make-counter 1) is called to return a counter that generates
>> > > successive integers from 1 as it is called. This is associated with
>> > > the lexical function name COUNTER, so that calling (counter) calls
>> > > into the closure.
>>
>> > > Without this you would instead write:
>>
>> > > �(let ((counter (make-counter 1)))
>> > > � �(list (funcall counter) (funcall counter) (funcall counter)))
>>
>> > > Even if we hacked a way to have ((make-counter 1)), it would do the
>> > > wrong thing anyway, since we want to call the same function object
>> > > multiple times.- Hide quoted text -
>>
>> > > - Show quoted text -
>>
>> > I don't understand what that buys me.
>>
>> I don't understand what an obsession with eliminating funcall buys
>> anyone.
>
> I want to see how much could I squeeze of functionality without
> introducing syntax, considering the style I'm trying will mean
> operating on functions instead, tacit programming and worse adding
> funcall will reintroduce too much vebosity.

You could use a reader macro, but that is considered syntax...

(let ((counter (make-counter 1))
   (list {counter} {counter} {counter}}))

(defmacro my-if (c th el) `(if (not ,c) ,el ,th))

{{my-if (oddp x) (function +) (function -)} a b}


Or:

(let ((counter (make-counter 1))
   (list �(counter) �(counter) �(counter))))

(defmacro my-if (c th el) `(if (not ,c) ,el ,th))

�((my-if (oddp x) (function +) (function -)) a b)


-- 
__Pascal Bourguignon__
From: Kent M Pitman
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <uej95amah.fsf@nhplace.com>
Slobodan Blazeski <·················@gmail.com> writes:

> I want one simple rule whatever comes after opening paren is a
> function or phrase that returns a function,

That isn't what Common Lisp does.  It is not a customizable aspect
of Common Lisp, not because of obstinance but because there is already
a different meaning attached to being "after the open paren" (I might
prefer "in the car of the list", but it amounts to the same).  What
you want is not an addition but an incompatible change.

If you don't want to just go use Scheme (which I'm not urging you to
do, but I'm pointing out does come with the rule you're saying), and
you don't want to locally address the problem (e.g., using some of the
techniques that Alex Mizrahi suggested) then your only real option is
a mode you can go into that does language preprocessing for you.

You've driven the stake pretty hard into the ground with this statement,
so there's not much wiggle room.

Your problem is that you implicitly want to believe a non-truth, which
is that a function definition does not reside in a different place than
the value.  The truth is, it does.  It resides in the function cell, and
the function cell is different than the value cell.  So if you write
 (f x)
there is ALREADY a meaning to this and it is NOT "get the value of f and
call it".  It is "get the contents of the function cell and call it".  So
if you allow a form in that position, you get in the unpleasant position
where ((progn f) x) does not mean what (f x) means.  And it also means that
if you write (defmacro g (x) x) and then write ((g f) x) you have to either
define that (f x) when a macro expands in the car of a list, the expansion
gets treated differently than what it looks like, that is that ((g f) x)
means (funcall f x) not (f x), or else you have to say that some macros cannot
be used in the car of forms.  Whatever you think of the CL rule, any rule
that has to make such bizarre exceptions would be worse.
From: Don Geddis
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <87ej9548au.fsf@geddis.org>
Kent M Pitman <······@nhplace.com> wrote on 16 Apr 2008 10:4:
> So if you write (f x) there is ALREADY a meaning to this and it is NOT "get
> the value of f and call it".  It is "get the contents of the function cell
> and call it".

Sure.  But at the same time, CL says that ((f) x) is an error, rather than
assigning any "useful" meaning to it.

> So if you allow a form in that position, you get in the unpleasant position
> where ((progn f) x) does not mean what (f x) means.

Personally, I don't find that particularly unpleasant.

> And it also means that if you write (defmacro g (x) x) and then write ((g
> f) x) you have to either define that (f x) when a macro expands in the car
> of a list, the expansion gets treated differently than what it looks like,
> that is that ((g f) x) means (funcall f x) not (f x), or else you have to
> say that some macros cannot be used in the car of forms.

That's more interesting.  And indeed, another choice.

> Whatever you think of the CL rule, any rule that has to make such bizarre
> exceptions would be worse.

I'm not convinced.  The current rule simply assigns no (useful) meaning to
the syntax.  And there are clearly plenty of programmers who would like the
obvious thing to happen with something like
        ((if x #'+ #'-) a b)
to do the "obvious" thing.

I really wonder if the proposed extension would be as disruptive or confusing
as you are suggesting.

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
--------- if you cut here, you'll probably destroy your monitor ----------
From: Barry Margolin
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <barmar-01D4AE.21231016042008@newsgroups.comcast.net>
In article <··············@geddis.org>, Don Geddis <···@geddis.org> 
wrote:

> Kent M Pitman <······@nhplace.com> wrote on 16 Apr 2008 10:4:
> > So if you write (f x) there is ALREADY a meaning to this and it is NOT "get
> > the value of f and call it".  It is "get the contents of the function cell
> > and call it".
> 
> Sure.  But at the same time, CL says that ((f) x) is an error, rather than
> assigning any "useful" meaning to it.

One of the reasons this was done in CL is because some of the 
implementations it was derived from DID define what this means.  By 
leaving it unspecified in CL, implementation-specific extensions are 
permitted.  The CL designers didn't want to force everyone to adopt any 
specific design here.

Zetalisp has a feature called lambda-macros, which allows you to define 
new things that are like LAMBDA.  If you do:

(define-lambda-macro mylamb ...)

you can the use ((mylam ...) x) and #'(mylam ...).  I think this feature 
may have been used to implement SETF functions, as well as some internal 
mechanisms for CLOS.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Marco Antoniotti
Subject: Forms in functional position: asking the implementors (Re: Is it 	possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <f84a8f04-2f83-46ba-bf60-4597105b6f6c@f36g2000hsa.googlegroups.com>
So,  let's make it a real issue.  (This has come up before)

CL implementors:  how difficult would it really really be to make

((make-adder 42) 123)

and

((progn f) x) == (f x) ; where (typep f 'function) => T

work in your implementation?  Remember that ((lambda (foo) ...) 42)
already works.

If this is not all that difficult and if this is a left-over from the
time of upper-case-only terminals, then somebody can take it up to
write a CDR for it.

Cheers
--
Marco






On Apr 17, 2:46 am, Don Geddis <····@geddis.org> wrote:
> Kent M Pitman <······@nhplace.com> wrote on 16 Apr 2008 10:4:
>
> > So if you write (f x) there is ALREADY a meaning to this and it is NOT "get
> > the value of f and call it".  It is "get the contents of the function cell
> > and call it".
>
> Sure.  But at the same time, CL says that ((f) x) is an error, rather than
> assigning any "useful" meaning to it.
>
> > So if you allow a form in that position, you get in the unpleasant position
> > where ((progn f) x) does not mean what (f x) means.
>
> Personally, I don't find that particularly unpleasant.
>
> > And it also means that if you write (defmacro g (x) x) and then write ((g
> > f) x) you have to either define that (f x) when a macro expands in the car
> > of a list, the expansion gets treated differently than what it looks like,
> > that is that ((g f) x) means (funcall f x) not (f x), or else you have to
> > say that some macros cannot be used in the car of forms.
>
> That's more interesting.  And indeed, another choice.
>
> > Whatever you think of the CL rule, any rule that has to make such bizarre
> > exceptions would be worse.
>
> I'm not convinced.  The current rule simply assigns no (useful) meaning to
> the syntax.  And there are clearly plenty of programmers who would like the
> obvious thing to happen with something like
>         ((if x #'+ #'-) a b)
> to do the "obvious" thing.
>
> I really wonder if the proposed extension would be as disruptive or confusing
> as you are suggesting.
>
>         -- Don
> ___________________________________________________________________________ ____
> Don Geddis                  http://don.geddis.org/              ····@geddis.org
> --------- if you cut here, you'll probably destroy your monitor ----------
From: Don Geddis
Subject: Re: Forms in functional position
Date: 
Message-ID: <87d4oors5u.fsf_-_@geddis.org>
Marco Antoniotti <·······@gmail.com> wrote on Thu, 17 Apr 2008:
> So,  let's make it a real issue.  (This has come up before)
> CL implementors:  how difficult would it really really be to make
> ((make-adder 42) 123)

I'm sure that little bit would be "easy" in most implementations.
The question isn't how hard the implementation is.  The question is
how good (regular, predictable, useful) the design of the feature is.

> and
> ((progn f) x) == (f x) ; where (typep f 'function) => T

I think you're already inconsistent here.  Perhaps you didn't read Kent's
post carefully?  You recall that CL is already a Lisp-2, where variables
have both function and value cells.

Consider:

        lisp> (defvar f #'-)
        #<Function - ...>
        lisp> (defun f (&nums) (apply #'+ nums))
        F
        lisp> (f 1 2 3)
        6
        lisp> (funcall f 1 2 3)
        -4
        lisp> f
        #<Function - ...>
        lisp> (progn f)
        #<Function - ...>
        lisp> (typep f 'function)
        T

So what, again, do you think
        ((progn f) 1 2 3)
should return?

It doesn't appear that it could both be:
1. composed from the result of (progn f) with the arguments; and also
2. identical to (f 1 2 3)
even though (typep f 'function) is T.

Unless you just want to turn Common Lisp into a Lisp-1 (i.e., into Scheme).
But that's no longer a "simple enhancement" to CL implementations.  That's
a whole new language.

        -- Don
_______________________________________________________________________________
Don Geddis                  http://don.geddis.org/               ···@geddis.org
One way to make more money at your job is just to make everything an "extra."
For instance, showing up at work, that's extra; actually doing work, that's
extra; wearing clothes, that's extra.  See how it works?
	-- Deep Thoughts, by Jack Handey [1999]
From: Kent M Pitman
Subject: Re: Forms in functional position
Date: 
Message-ID: <uhcdz3eof.fsf@nhplace.com>
Don Geddis <···@geddis.org> writes:

> So what, again, do you think
>         ((progn f) 1 2 3)
> should return?

Well, there would have been no harm in Zetalisp if someone had done
 (deflambda-macro progn (&rest forms)
   `(lambda (&rest args)
      (apply (progn ,@forms) args)))
Whether this was the right thing to have is another question.
But it doesn't create any semantic problem to want it... other than
that you do indeed have to answer the question you pose above in either
of two acceptable ways:
 (a) It returns what (funcall #'f 1 2 3) does, and so there's no reason for
     ((progn f) ...) because it adds no power over (f 1 2 3) or certainly
     over (funcall #'f 1 2 3).

 (b) It returns what (funcall f 1 2 3) does, in which case it offers power
     we don't have right now.  Any implementation could define this as
     an extension, and on the LispM it was possible for people to define
     for themselves.

Incidentally, I think the reason for lambda macros was to allow interlisp
support. e.g., interlisp nlambda didn't evaluate its arguments, and one
could write something vaguely like this in Zetalisp:

 (deflambda-macro nlambda (bvl &rest forms)
   `(lambda (&quote ,@bvl) ,@forms))

Note that the LispM's &quote and &eval were effectively a weirder version
of FEXPRs and were necessary to the LispM bootstrapping (since its own
fexprs were defined this way), but they weren't super-popular to use in 
any user code I saw for all the reasons outlined in my special forms paper.
http://www.nhplace.com/kent/Papers/Special-Forms.html
There were some other problems with &quote, too, like that they attached
the info in the wrong place; it should have been on the function name, not
the function value. If you get as far as having a function value, it's too
late to stop evaluation.  Consider:
 (apply #'(lambda (&quote x) x) '(a))
and how it is NOT different than
 (apply #'(lambda (x) x) '(a))
Both of them return A. Even though
 (defun foo1 (&quote x) x)
 (defun foo2 (x) x)
 (setq a 'b)
 (foo1 a) => a
 (foo2 a) => b
So it was really a property of the name that just happened to be stored
in the function value for want of a better place.
From: Barry Margolin
Subject: Re: Forms in functional position: asking the implementors (Re: Is it possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <barmar-5945FE.18331517042008@newsgroups.comcast.net>
In article 
<····································@f36g2000hsa.googlegroups.com>,
 Marco Antoniotti <·······@gmail.com> wrote:

> So,  let's make it a real issue.  (This has come up before)
> 
> CL implementors:  how difficult would it really really be to make
> 
> ((make-adder 42) 123)
> 
> and
> 
> ((progn f) x) == (f x) ; where (typep f 'function) => T
> 
> work in your implementation?  Remember that ((lambda (foo) ...) 42)
> already works.

The second one seems like it would be pretty hard.  If we evaluated the 
function position of an expression as an ordinary expression, (progn f) 
would return the value of the *variable* named F, not the *function* 
named F.  So you'd need to perform the evaluation in a special way, to 
get the functional value.  But this gets tricky; consider:

((if (> thing1 thing2) f g) x)

You presumably would want F and G to be evaluated as function names, but 
THING1 and THING2 should be evaluated as variable names.  The rules for 
which sub-expressions should be evaluated in function versus variable 
contexts will get really complicated, I think.


((lambda ...) 42) already works because it's a special case in the 
language.  The car of an expression can be either a function name, a 
macro name, a special operator, or a lambda expression.  Remember that 
lambda expressions used in this way goes back decades -- the macro that 
expands (lambda ....) to #'(lambda ...) is relatively recent, introduced 
during the CL standardization.  It's never been the case in Lisp that 
this notation came from just evaluating the function position (Scheme is 
a different matter).

I'm not even sure why we kept this in the language, other than for 
compatibility.  This notation was the original way to do what we now do 
with LET, and the original LET macro simply expanded into this.  But 
since LET has been made a primitive operator in the language, there's 
little need for the ((lambda ...) ...) expression.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Ari Johnson
Subject: Re: Forms in functional position: asking the implementors (Re: Is it possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <m2skxkm43e.fsf@hermes.theari.com>
Barry Margolin <······@alum.mit.edu> writes:

> In article 
> <····································@f36g2000hsa.googlegroups.com>,
>  Marco Antoniotti <·······@gmail.com> wrote:
>
>> So,  let's make it a real issue.  (This has come up before)
>> 
>> CL implementors:  how difficult would it really really be to make
>> 
>> ((make-adder 42) 123)
>> 
>> and
>> 
>> ((progn f) x) == (f x) ; where (typep f 'function) => T
>> 
>> work in your implementation?  Remember that ((lambda (foo) ...) 42)
>> already works.
>
> The second one seems like it would be pretty hard.  If we evaluated the 
> function position of an expression as an ordinary expression, (progn f) 
> would return the value of the *variable* named F, not the *function* 
> named F.  So you'd need to perform the evaluation in a special way, to 
> get the functional value.  But this gets tricky; consider:

The (typep f 'function) => T takes care of that.  He meant to retrieve
the value.  If you prefer, think of it in terms of
  ((progn #'f) x) == (f x)
instead, since (typep #'f 'function) is safely assumed to be T.
From: Ari Johnson
Subject: Re: Forms in functional position: asking the implementors (Re: Is it possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <m2od88m3tf.fsf@hermes.theari.com>
Ari Johnson <·········@gmail.com> writes:

> Barry Margolin <······@alum.mit.edu> writes:
>
>> In article 
>> <····································@f36g2000hsa.googlegroups.com>,
>>  Marco Antoniotti <·······@gmail.com> wrote:
>>
>>> So,  let's make it a real issue.  (This has come up before)
>>> 
>>> CL implementors:  how difficult would it really really be to make
>>> 
>>> ((make-adder 42) 123)
>>> 
>>> and
>>> 
>>> ((progn f) x) == (f x) ; where (typep f 'function) => T
>>> 
>>> work in your implementation?  Remember that ((lambda (foo) ...) 42)
>>> already works.
>>
>> The second one seems like it would be pretty hard.  If we evaluated the 
>> function position of an expression as an ordinary expression, (progn f) 
>> would return the value of the *variable* named F, not the *function* 
>> named F.  So you'd need to perform the evaluation in a special way, to 
>> get the functional value.  But this gets tricky; consider:
>
> The (typep f 'function) => T takes care of that.  He meant to retrieve
> the value.  If you prefer, think of it in terms of
>   ((progn #'f) x) == (f x)
> instead, since (typep #'f 'function) is safely assumed to be T.

That being said, I see now that I missed something separate.
((progn f) x) should not be the same as (f x).  It should be the same
as (funcall f x).  The fact that I missed this is evidence of another
side point I thought of after I wrote the above:  This feature would
introduce a new, unnecessary, complicated rule into the language, namely
that the car of an expression can be a symbol naming a function, macro,
or special operator or, if it's not a symbol, it can instead be a
(lambda ...) form or, if it's also not that, then it can instead be
an expression that evaluates to a value of type function.

Just pretend ((lambda (...) ...) ...) was never permitted, use funcall
for this functionality, and be glad to have very few rules to remember
when you are writing code.
From: Barry Margolin
Subject: Re: Forms in functional position: asking the implementors (Re: Is it possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <barmar-EA5D45.20472117042008@newsgroups.comcast.net>
In article <··············@hermes.theari.com>,
 Ari Johnson <·········@gmail.com> wrote:

> This feature would
> introduce a new, unnecessary, complicated rule into the language, namely
> that the car of an expression can be a symbol naming a function, macro,
> or special operator or, if it's not a symbol, it can instead be a
> (lambda ...) form or, if it's also not that, then it can instead be
> an expression that evaluates to a value of type function.

Actually, it's only two cases:

1. A symbol naming a function, macro, or special operator, or

2. an expression that evaluates to a value of type function.

The lambda expression case is subsumed by #2, because of the LAMBDA 
macro.

Maclisp actually had an option to behave like this.  When set, if the 
car of an expression was not a lambda expression or a symbol with a 
binding in the function namespace, it would evaluate it expecting to get 
a function (maybe it could also evaluate to a function name, I don't 
recall).  I don't recall anyone actually using this option much.

As I mentioned in the other thread, a problem with adding this to the 
language now would be that it would conflict with extensions that 
implementations have made that provide additional things that can appear 
in the car of an expression.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Ron Garret
Subject: Re: Forms in functional position: asking the implementors (Re: Is it possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <rNOSPAMon-3B7A15.23183517042008@news.gha.chartermi.net>
In article <····························@newsgroups.comcast.net>,
 Barry Margolin <······@alum.mit.edu> wrote:

> In article 
> <····································@f36g2000hsa.googlegroups.com>,
>  Marco Antoniotti <·······@gmail.com> wrote:
> 
> > So,  let's make it a real issue.  (This has come up before)
> > 
> > CL implementors:  how difficult would it really really be to make
> > 
> > ((make-adder 42) 123)
> > 
> > and
> > 
> > ((progn f) x) == (f x) ; where (typep f 'function) => T
> > 
> > work in your implementation?  Remember that ((lambda (foo) ...) 42)
> > already works.

Look in:

http://www.flownet.com/ron/lisp/nx1-combination-hook.lisp

and

http://www.flownet.com/ron/lisp/ir1-combination-hook.lisp

for code that (mostly) does this in MCL/CCL and SBCL.  I also have a 
CLisp version somewhere if people are interested (but it's much more 
complicated).

Disclaimer: this code has not been used for a long time and may no 
longer work.  But it worked once upon a time.

rg
From: Kent M Pitman
Subject: Re: Forms in functional position: asking the implementors (Re: Is it possible to implement ,@ if it wasn't already there)
Date: 
Message-ID: <ulk3b3f70.fsf@nhplace.com>
Barry Margolin <······@alum.mit.edu> writes:

> In article 
> <····································@f36g2000hsa.googlegroups.com>,
>  Marco Antoniotti <·······@gmail.com> wrote:
> 
> > So,  let's make it a real issue.  (This has come up before)
> > 
> > CL implementors:  how difficult would it really really be to make
> > 
> > ((make-adder 42) 123)
> > 
> > and
> > 
> > ((progn f) x) == (f x) ; where (typep f 'function) => T
> > 
> > work in your implementation?  Remember that ((lambda (foo) ...) 42)
> > already works.
> 
> The second one seems like it would be pretty hard.  If we evaluated the 
> function position of an expression as an ordinary expression, (progn f) 
> would return the value of the *variable* named F, not the *function* 
> named F.  So you'd need to perform the evaluation in a special way, to 
> get the functional value.  But this gets tricky; consider:
> 
> ((if (> thing1 thing2) f g) x)
> 
> You presumably would want F and G to be evaluated as function names, but 
> THING1 and THING2 should be evaluated as variable names.  The rules for 
> which sub-expressions should be evaluated in function versus variable 
> contexts will get really complicated, I think.
> 
> 
> ((lambda ...) 42) already works because it's a special case in the 
> language.  The car of an expression can be either a function name, 

Strictly, the name of something in the syntactic space of functions and
not otherwise taken up by a macro, special operator, or lambda expression.
(This matters a lot because forward references to functions get compiled
correctly even when the thing does not refer to a function yet.)
 
Also, names other than (setf xxx), which is a valid 'argument' to
FUNCTION but not a valid car of a form.  I was never clear on why we
didn't allow it there.  Ah well.

> a 
> macro name, a special operator, or a lambda expression.  Remember that 
> lambda expressions used in this way goes back decades -- the macro that 
> expands (lambda ....) to #'(lambda ...) is relatively recent, introduced 
> during the CL standardization.  It's never been the case in Lisp that 
> this notation came from just evaluating the function position (Scheme is 
> a different matter).

Indeed.  In Maclisp the car of a form had hugely more complexity to it.
It's mild today.  There were a LOT of properties that could be on symbols,
and Lisp looked for various of those properties at various times (using GET,
though with clever caching to avoid too many repeated calls to GET during
FUNCALL).

> I'm not even sure why we kept this in the language, other than for 
> compatibility.

I think most designers would have said "because it's more primitive
than let".  Wheter that's really so now, I don't know. But most people
felt it quite deeply at the time.  I recall some people hinting that
(lambda ...) should not be a macro but should be primitive, and that
(function (lambda ...)) should be a macro expanding into it [rather than,
as now, vice versa].  And people said no, that the FUNCTION expression
with a literal LAMBDA symbol in it was more primitive than any LAMBDA
expression ever could be.  People are funny about what they think is
primitive; often it doesn't matter which is primitive, only that things
bottom out.

> This notation was the original way to do what we now do 
> with LET, and the original LET macro simply expanded into this.

Heh. One of them. LET is a recent innovation--I recall it going in, which
means it happened after I started using Maclisp, which was in about 1977.
I suspect it was added around 1978 or so.  But before that, many people
had private definitions.  MACSYMA had three definitions of it privately.
One used LAMBDA. One used PROG. And one, amazingly, used a DO that did
not iterate. MACLISP's DO actually had a syntax that said "don't iterate".
 (do ((i 0)) nil (print i))
executes exactly once.  In fact, it complains if you specify a step since
it isn't going to iterate.
 (do ((i 0 'foo)) nil (print i))
 ;(I 0 (QUOTE FOO)) EXTRANEOUS STEPPER - DO
Of course, both DO and PROG had the issue of an implicit block and an
implicit tagbody (not that those were separable facilities in MACLISP;
I had suggested in email to maclisp's bug list that they be factored out
as separate operators, but it wasn't until CL that this actually occurred),
but some people LIKED having a LET that had those features and in fact in
the debate over standardizing it, one thing that came up was that some 
people who wanted to use it wanted to be able to use RETURN and/or GO.

People fuss over all kinds of crazy things.  They fussed when we moved from
base 8 to base 10 by default, too.  That was silly.  I fussed about losing
comma as a synonym for space when backquote came along and re-purposed comma.
I used to like writing lists as (a,b,c) in some math situations and was
annoyed to have to write (a b c) instead.

> But 
> since LET has been made a primitive operator in the language, there's 
> little need for the ((lambda ...) ...) expression.

Well, it's still useful as part of the algebra of construction of programs.
Alex Mizrahi was recently promoting a #,foo macro that expanded into
(lambda (&rest args) (apply foo args)) which would have the useful property
that it could be done even in the car of a form.  Admittedly, not everyone
wants that. But it's an example of modern day use of that syntax.
From: Matthias Benkard
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <cc8fdf34-c86d-44ca-ab2e-1fcdce5152e8@a22g2000hsc.googlegroups.com>
On Apr 17, 2:46 am, Don Geddis <····@geddis.org> wrote:
> I'm not convinced.  The current rule simply assigns no (useful)
> meaning to the syntax.  And there are clearly plenty of programmers who
> would like the obvious thing to happen with something like
>         ((if x #'+ #'-) a b)
> to do the "obvious" thing.

Obvious?  What about:

  ((setf car) 3 (cons 1 2))

I'd expect that to be a call of the function (SETF CAR), if anything.
(There's no ambiguity in the case of ((lambda ...) ...) because a list
starting with the symbol LAMBDA isn't a valid function name.)

~ Matthias
From: Kent M Pitman
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <uskxj3g6l.fsf@nhplace.com>
Matthias Benkard <··········@gmail.com> writes:

> On Apr 17, 2:46 am, Don Geddis <····@geddis.org> wrote:
> > I'm not convinced.  The current rule simply assigns no (useful)
> > meaning to the syntax.  And there are clearly plenty of programmers who
> > would like the obvious thing to happen with something like
> >         ((if x #'+ #'-) a b)
> > to do the "obvious" thing.
> 
> Obvious?  What about:
> 
>   ((setf car) 3 (cons 1 2))
> 
> I'd expect that to be a call of the function (SETF CAR), if anything.
> (There's no ambiguity in the case of ((lambda ...) ...) because a list
> starting with the symbol LAMBDA isn't a valid function name.)

Actually, let's be clear about some thing here:

The Lisp Machine had a thing called "lambda macros" that allowed you to
key on the name in the caar of a form an expand into something to handle
it.  Using lambda macros, you could make ((setf car) ...) work by doing
(approximately--I don't have the manual handy here so this is from 15
years of faded memory and probably isn't the exactly right syntax):

(deflambda-macro setf (getter)
  `(lambda (update-value place-value)
     (funcall #'(setf ,getter) update-value place-value)))

In that way you could do something like:

 (macroexpand-1 '((setf car) 3 (cons 1 2)))
 => ((lambda (update-value place-value)
       (funcall #'(setf car) update-value place-value))
     3
     (cons 1 2))

So the capability was there for a long time (and is mentioned in the
ISO-COMPATIBILITY proposal).
http://www.lispworks.com/documentation/HyperSpec/Issues/iss198_w.htm

Ah, I see. There IS some doc on lambda macros on the web.  It's in
  http://common-lisp.net/project/bknr/static/lmman/fd-fun.xml
And I even got the syntax right. Cool. (I'm not sure if
macroexpand-1 is what expanded it, but you get the idea.)

But ok, so you'd need something like that to make things work now.
And it could be made to work.

But also, on the issue of whether forms should "macroexpand" into primitive
syntax, including allowing people the option to decide what (f x) means,
see my SPIEL hack (well, half a hack) at
 http://www.nhplace.com/kent/Half-Baked/
(If you can stand the color. I admit I should probably make it a
little less like a can of tomato soup...)  The whole "Lisp Omega" idea
was to address that.  I have a better version of the SPIEL idea coming
some day since I've redone it a better way. But I'm not prepared to
talk about that version yet... Still playing with it.  But no harm in
others playing with it, too.  It's just important to understand that not
every language has to be a playground for everything.  You design in
what you can in terms of flexibility and then you use it.  CL is in
"use it" mode, not design mode.
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <071b0464-34fc-4ff7-9a3e-6741ae955a46@a22g2000hsc.googlegroups.com>
On Apr 16, 4:48 pm, Kent M Pitman <······@nhplace.com> wrote:
> Slobodan Blazeski <·················@gmail.com> writes:
> > I want one simple rule whatever comes after opening paren is a
> > function or phrase that returns a function,
>
> That isn't what Common Lisp does.  It is not a customizable aspect
> of Common Lisp, not because of obstinance but because there is already
> a different meaning attached to being "after the open paren" (I might
> prefer "in the car of the list", but it amounts to the same).  What
> you want is not an addition but an incompatible change.
>
> If you don't want to just go use Scheme (which I'm not urging you to
> do, but I'm pointing out does come with the rule you're saying), and
> you don't want to locally address the problem (e.g., using some of the
> techniques that Alex Mizrahi suggested) then your only real option is
> a mode you can go into that does language preprocessing for you.
>
> You've driven the stake pretty hard into the ground with this statement,
> so there's not much wiggle room.
>
> Your problem is that you implicitly want to believe a non-truth, which
> is that a function definition does not reside in a different place than
> the value.  The truth is, it does.  It resides in the function cell, and
> the function cell is different than the value cell.  So if you write
>  (f x)
> there is ALREADY a meaning to this and it is NOT "get the value of f and
> call it".  It is "get the contents of the function cell and call it".  So
> if you allow a form in that position, you get in the unpleasant position
> where ((progn f) x) does not mean what (f x) means.  And it also means that
> if you write (defmacro g (x) x) and then write ((g f) x) you have to either
> define that (f x) when a macro expands in the car of a list, the expansion
> gets treated differently than what it looks like, that is that ((g f) x)
> means (funcall f x) not (f x), or else you have to say that some macros cannot
> be used in the car of forms.  Whatever you think of the CL rule, any rule
> that has to make such bizarre exceptions would be worse.

I'm starting to learn that the hard way. Everybody whose bitching
about design of some langauge should sit down and try to design one
himself.
I feel like harlequin The Servant of Two Masters, but instead of two
there is a multitude  of them and keep coming
From one side are the abstract concepts that my language want to
support: implicit looping, reflections, tacit style, polymorphism...
yelling add more
From the other side is the syntax, keep it very very simple or you're
going to lose macros and you'll degrade into c++
And readability ask for ... readibility
I feel like a string theorists trying to unify concepts that doesn't
want to be unified, and finally going into utter madness that doesn't
have any sense
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <48073053$0$90266$14726298@news.sunsite.dk>
 KMP> prefer "in the car of the list", but it amounts to the same).  What
 KMP> you want is not an addition but an incompatible change.

incompatible in which way? you think some people depend on behaviour when 
lisp throws an error?

 KMP> it".  So if you allow a form in that position, you get in the
 KMP> unpleasant position where ((progn f) x) does not mean what (f x)
 KMP> means.  And it also means that if you write (defmacro g (x) x) and
 KMP> then write ((g f) x) you have to either define that (f x) when a macro
 KMP> expands in the car of a list, the expansion gets treated differently
 KMP> than what it looks like, that is that ((g f) x) means (funcall f x)
 KMP> not (f x), or else you have to say that some macros cannot be used in
 KMP> the car of forms.  Whatever you think of the CL rule, any rule that
 KMP> has to make such bizarre exceptions would be worse.

these are only a problems because we don't have consistent model how it 
should work. but i'm pretty sure there is a way to make quite a consistent 
one..
for example, in addition to lambda expressions, we can introduce "funcall 
expressions", like this

((funcall f) x) -> (funcall f x)
((funcall (make-adder 3)) 4) -> (funcall (make-adder 3) 4)

it does not make much sense as it is, but then we say -- anything that is 
not a symbol, lambda expression or a funcall expression gets transformed 
into funcall expression.
so we have quite consistent tranformation rules:
((progn f) x) -> ((funcall (progn f)) x) -> (funcall (progn f) x) -> 
(funcall f x)
((g f) x) -> ((funcall (g f)) x) -> (funcall (g f) x) -> (funcall f x)

i don't find these rules anyhow bizzare exceptions, just one needs to 
remember a clean model that everything is transformed _before_ 
macroexpansion is done etc,
and so even if you use identity macro it is not same as there was no such 
macro, because implicit transformation is done. 
From: Didier Verna
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <muxhce2hvid.fsf@uzeb.lrde.epita.fr>
Slobodan Blazeski <·················@gmail.com> wrote:

> Forget about wrapping anything into something else. So there is only
> two cases: 

> (function arg arg arg ...)
> ((something-that-returns-a-function arg arg) arg arg..)
> that's it.

  And what about

(;; blah blah
 (something-that-returns-a-function arg arg) args)

etc ?


  Here's a gross proof of concept for SBCL only (and also a proof that
you're walking on a mine field). But really, if you're so upset about
funcall, it means that 1/ you haven't used CL enough, or 2/ you're a
schemer and you just didn't know...


CL-USER> (defun make-adder (n) (lambda (x) (+ n x)))
MAKE-ADDER
CL-USER> (funcall (make-adder 3) 4)
7
CL-USER> ((make-adder 3) 4)
; in: LAMBDA NIL
;     ((MAKE-ADDER 3) 4)
; 
; caught ERROR:
;   illegal function call
; 
; compilation unit finished
;   caught 1 ERROR condition
; Evaluation aborted.
CL-USER> (defun left-paren-reader (stream paren)
  (declare (ignore paren))
  (let ((c (read-char stream)))
    (cond ((char= c #\()
	   (let ((func (eval (sb-impl::read-list stream :ignore)))
		 (args (sb-impl::read-list stream :ignore)))
	     `(apply ,func ',args)))
	  (t
	   (unread-char c stream)
	   (sb-impl::read-list stream :ignore)))))
LEFT-PAREN-READER
CL-USER> (set-macro-character #\( #'left-paren-reader)
T
CL-USER> ((make-adder 3) 4)
7
CL-USER> 


-- 
5th European Lisp Workshop at ECOOP 2008, July 7: http://elw.bknr.net/2008/

Didier Verna, ······@lrde.epita.fr, http://www.lrde.epita.fr/~didier

EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (0)1 44 08 01 85
94276 Le Kremlin-Bic�tre, France   Fax.+33 (0)1 53 14 59 22  ······@xemacs.org
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <48433ed0-046b-46d9-aae5-b4f7e054a6ed@m44g2000hsc.googlegroups.com>
On Apr 16, 1:47 pm, Didier Verna <······@lrde.epita.fr> wrote:
> But really, if you're so upset about
> funcall, it means that ...... you're a
> schemer and you just didn't know...

It looks that way,  I'll leave my cl member card at the doorway.
From: Didier Verna
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <muxbq497xra.fsf@uzeb.lrde.epita.fr>
Slobodan Blazeski <·················@gmail.com> wrote:

> On Apr 16, 1:47�pm, Didier Verna <······@lrde.epita.fr> wrote:
>> But really, if you're so upset about
>> funcall, it means that ...... you're a
>> schemer and you just didn't know...
>
> It looks that way,  I'll leave my cl member card at the doorway.

  Please keep it. You don't *need* to be an active member :-)

-- 
5th European Lisp Workshop at ECOOP 2008, July 7: http://elw.bknr.net/2008/

Didier Verna, ······@lrde.epita.fr, http://www.lrde.epita.fr/~didier

EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (0)1 44 08 01 85
94276 Le Kremlin-Bic�tre, France   Fax.+33 (0)1 53 14 59 22  ······@xemacs.org
From: Marco Antoniotti
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <295555cf-48b5-4d01-8912-e16cb6dd07e0@a22g2000hsc.googlegroups.com>
On Apr 16, 1:47 pm, Didier Verna <······@lrde.epita.fr> wrote:
> Slobodan Blazeski <·················@gmail.com> wrote:
> > Forget about wrapping anything into something else. So there is only
> > two cases:
> > (function arg arg arg ...)
> > ((something-that-returns-a-function arg arg) arg arg..)
> > that's it.
>
>   And what about
>
> (;; blah blah
>  (something-that-returns-a-function arg arg) args)
>
> etc ?
>
>   Here's a gross proof of concept for SBCL only (and also a proof that
> you're walking on a mine field). But really, if you're so upset about
> funcall, it means that 1/ you haven't used CL enough, or 2/ you're a
> schemer and you just didn't know...
>
> CL-USER> (defun make-adder (n) (lambda (x) (+ n x)))
> MAKE-ADDER
> CL-USER> (funcall (make-adder 3) 4)
> 7
> CL-USER> ((make-adder 3) 4)
> ; in: LAMBDA NIL
> ;     ((MAKE-ADDER 3) 4)
> ;
> ; caught ERROR:
> ;   illegal function call
> ;
> ; compilation unit finished
> ;   caught 1 ERROR condition
> ; Evaluation aborted.
> CL-USER> (defun left-paren-reader (stream paren)
>   (declare (ignore paren))
>   (let ((c (read-char stream)))
>     (cond ((char= c #\()
>            (let ((func (eval (sb-impl::read-list stream :ignore)))
>                  (args (sb-impl::read-list stream :ignore)))
>              `(apply ,func ',args)))
>           (t
>            (unread-char c stream)
>            (sb-impl::read-list stream :ignore)))))
> LEFT-PAREN-READER
> CL-USER> (set-macro-character #\( #'left-paren-reader)
> T
> CL-USER> ((make-adder 3) 4)
> 7
> CL-USER>
>
> --
> 5th European Lisp Workshop at ECOOP 2008, July 7:http://elw.bknr.net/2008/
>
> Didier Verna, ······@lrde.epita.fr,http://www.lrde.epita.fr/~didier
>
> EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (0)1 44 08 01 85
> 94276 Le Kremlin-Bicêtre, France   Fax.+33 (0)1 53 14 59 22  ······@xemacs.org

Two comments.  (1) scary, in a beautiful and attractive way: I love
this. (2) can you make it portable?

Cheers
--
Marco
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <f6e1ed84-ab64-4022-9bf8-0876b60b393c@m3g2000hsc.googlegroups.com>
On Apr 16, 4:47 am, Didier Verna <······@lrde.epita.fr> wrote:
> CL-USER> (defun left-paren-reader (stream paren)
>   (declare (ignore paren))
>   (let ((c (read-char stream)))
>     (cond ((char= c #\()
>            (let ((func (eval (sb-impl::read-list stream :ignore)))
>                  (args (sb-impl::read-list stream :ignore)))
>              `(apply ,func ',args)))

Is that doing what I think it is? Evaluating the expression at read-
time and then substituting a function object into the source code? One
more strike and you're out. :)

This the EVAL is unnecessary. You don't have to insert a function
object into the (apply ...) code; rather, you can simply insert the
original expression. It will be evaluated when the APPLY is evaluated.

Your only job in this read macro is this transformation:

   ((X...) Y...) -> (funcall (X...) Y...)

That's it! You can do this simply by reading the rest of the form with
READ-DELIMITED-LIST. Instead of checking for an embedded ( by reading
characters from the stream, you implement a proper type test: is the
CAR of the expression a CONS? If so, apply the special logic.

Note that ((lambda ...) ...) will continue to work properly, so you
don't have to worry about that. But you break compound function names
like ((setf ...) ...).

A robust implementation of this, if there is such a thing, should
check for these cases. Or at least it should be documented that it
doesn't work.
From: Kaz Kylheku
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <3c7915fb-a22f-4dda-b2df-587c2e94cf9c@24g2000hsh.googlegroups.com>
On Apr 16, 4:47 am, Didier Verna <······@lrde.epita.fr> wrote:
> CL-USER> (defun left-paren-reader (stream paren)
>   (declare (ignore paren))
>   (let ((c (read-char stream)))
>     (cond ((char= c #\()
>            (let ((func (eval (sb-impl::read-list stream :ignore)))
>                  (args (sb-impl::read-list stream :ignore)))
>              `(apply ,func ',args)))
>           (t
>            (unread-char c stream)
>            (sb-impl::read-list stream :ignore)))))

(defun left-paren-reader (stream paren)
  (declare (ignore paren))
  (let ((obj (read-delimited-list #\) stream t)))
    (if (consp (car obj))
      `(funcall ,@obj)
      obj)))

And this is still seriously braindamaged:

[1]> (set-macro-character #\( #'left-paren-reader)
T
[2]> '((a) b c)
(FUNCALL (A) B C)

The transformation is indiscriminately applied, which is why others
have suggested that some other parentheses be used for this.

No! :)
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <480507a6$0$90262$14726298@news.sunsite.dk>
 SB> Soprry If I'm not clear but here the problem

 SB> (defun make-adder (n)
 SB>                 #'(lambda (x) (+ x n)))
 SB> MAKE-ADDER
 SB> (funcall (make-adder 3) 8)
 SB> 11

 SB> ((make-adder 3) 8)

 SB> Error: Illegal argument in functor position: (MAKE-ADDER 3) in ((MAKE-
 SB> ADDER 3) 8).

(defun lambdasplice-reader (stream char n)
  (declare (ignore char n))
  (let ((args (gensym)))
    `(lambda (&rest ,args) (apply ,(read stream) ,args))))

(set-dispatch-macro-character #\# #\, #'lambdasplice-reader *readtable*)

CL-USER> (defun make-adder (n)
    #'(lambda (x) (+ x n)))

MAKE-ADDER
CL-USER> (#,(make-adder 3) 8)

11

perhaps it would be even better to hook bracket characters [] or curly 
braces {} and make it just like () but evaluating first arg:

[(make-adder 3) 8]

if you don't use brackets for anything else (iirc it's used in CLSQL), why 
not, actually, if you have lots of lambdas, you say..

 SB> The only solution is playing on lambda level  or switching to scheme.

or refactor your code so you don't need that much lambdas. use objects or 
something.. 
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <f3e16bfa-72e0-45d3-aee7-c7cca2b99082@p25g2000hsf.googlegroups.com>
On Apr 15, 9:53 pm, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  SB> Soprry If I'm not clear but here the problem
>
>  SB> (defun make-adder (n)
>  SB>                 #'(lambda (x) (+ x n)))
>  SB> MAKE-ADDER
>  SB> (funcall (make-adder 3) 8)
>  SB> 11
>
>  SB> ((make-adder 3) 8)
>
>  SB> Error: Illegal argument in functor position: (MAKE-ADDER 3) in ((MAKE-
>  SB> ADDER 3) 8).
>
> (defun lambdasplice-reader (stream char n)
>   (declare (ignore char n))
>   (let ((args (gensym)))
>     `(lambda (&rest ,args) (apply ,(read stream) ,args))))
>
> (set-dispatch-macro-character #\# #\, #'lambdasplice-reader *readtable*)
>
> CL-USER> (defun make-adder (n)
>     #'(lambda (x) (+ x n)))
>
> MAKE-ADDER
> CL-USER> (#,(make-adder 3) 8)
>
> 11
>
> perhaps it would be even better to hook bracket characters [] or curly
> braces {} and make it just like () but evaluating first arg:
>
> [(make-adder 3) 8]
>
> if you don't use brackets for anything else (iirc it's used in CLSQL), why
> not, actually, if you have lots of lambdas, you say..
Inelegant.  Using []  signals that something odd is happening.
>
>  SB> The only solution is playing on lambda level  or switching to scheme.
>
> or refactor your code so you don't need that much lambdas. use objects or
> something..

Neither will work for me, actually I want integrating , as opposed to
embedding, things I like from APL and prolog I found cool.
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <4805ef51$0$90273$14726298@news.sunsite.dk>
 ??>> if you don't use brackets for anything else (iirc it's used in CLSQL),
 ??>> why not, actually, if you have lots of lambdas, you say..
 SB> Inelegant.  Using []  signals that something odd is happening.

and something odd is happening indeed -- if you did not notice, Common Lisp 
has separate namespaces for values and functions, and you're going to crush 
them into one.
if you don't like funcall verbosity, solution in Common Lisp style would be 
shorthand notation, like #, or [] i've suggested above, that will be more 
compact, but still will suggest that non-standard semantics is used.

still, if you want lambdas like these to be called in completely transparent 
way, i think it's doable either via a reader hack, or via code-walker macro.
so you can, for example, shadow defun (and other stuff, whatever reasonable) 
in your package, and inside this macro traverse whole tree, searching for 
patterns like ((somefun x) y) and transforming them into appropriate 
funcalls.

as a proof-of-concept:

(defun splice-transform (body)
  (cond ((atom body) body)
             ((atom (car body)) body)
             ((eq (caar body) 'lambda) body)
             (t (cons 'funcall body))))

(defmacro defun-x (name args &body body)
  `(defun ,name ,args ,@(mapcar #'splice-transform body)))

CL-USER> (defun make-adder (n)
                #'(lambda (x) (+ x n)))

MAKE-ADDER

CL-USER> (defun-x scoff (x y)
    ((make-adder x) y))

SCOFF
CL-USER> (scoff 3 4)
7


you see, it works (i deserve a medal?), and in your own package you can make 
it totally transparent.
but this code is too simplistic -- it might screw some macros or quoted 
data, so real code walker is needed.

alternative approach would be to record all functions like make-adder, i.e. 
define them via def-closure-maker rather than via simple defun, and then 
while travesing body you can replace all such calls with funcalls..
it has less chances to screw stuff, but still won't work in some situations 
like inside macro etc. again needs code walker to be 100% correct.
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <737c74c9-3790-41af-8107-de05d8972ce3@26g2000hsk.googlegroups.com>
On Apr 16, 2:21 pm, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  ??>> if you don't use brackets for anything else (iirc it's used in CLSQL),
>  ??>> why not, actually, if you have lots of lambdas, you say..
>  SB> Inelegant.  Using []  signals that something odd is happening.
>
> and something odd is happening indeed --
Agreed. Actually after some trials I would actually need to
reimplement a lot of staff from cl even artihmetic operators like
+,-,*,-.
Because I would need them to do staff like this:
(* 2 '(1 2 3))
(2 4 6)

so probbaly using [] for my language is a good thing. Something very
very odd is happening,
[* 2 '[1 2 3]]
[2 4 6]


> if you did not notice, Common Lisp
> has separate namespaces for values and functions, and you're going to crush
> them into one.
> if you don't like funcall verbosity, solution in Common Lisp style would be
> shorthand notation, like #, or [] i've suggested above, that will be more
> compact, but still will suggest that non-standard semantics is used.
>
> still, if you want lambdas like these to be called in completely transparent
> way, i think it's doable either via a reader hack, or via code-walker macro.
> so you can, for example, shadow defun (and other stuff, whatever reasonable)
> in your package, and inside this macro traverse whole tree, searching for
> patterns like ((somefun x) y) and transforming them into appropriate
> funcalls.
>
> as a proof-of-concept:
>
> (defun splice-transform (body)
>   (cond ((atom body) body)
>              ((atom (car body)) body)
>              ((eq (caar body) 'lambda) body)
>              (t (cons 'funcall body))))
>
> (defmacro defun-x (name args &body body)
>   `(defun ,name ,args ,@(mapcar #'splice-transform body)))
>
> CL-USER> (defun make-adder (n)
>                 #'(lambda (x) (+ x n)))
>
> MAKE-ADDER
>
> CL-USER> (defun-x scoff (x y)
>     ((make-adder x) y))
>
> SCOFF
> CL-USER> (scoff 3 4)
> 7
>
> you see, it works (i deserve a medal?), and in your own package you can make
> it totally transparent.
> but this code is too simplistic -- it might screw some macros or quoted
> data, so real code walker is needed.
>
> alternative approach would be to record all functions like make-adder, i.e.
> define them via def-closure-maker rather than via simple defun, and then
> while travesing body you can replace all such calls with funcalls..
> it has less chances to screw stuff, but still won't work in some situations
> like inside macro etc. again needs code walker to be 100% correct.
From: danb
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <9074b555-7b2c-43d2-9016-55dfa8e3f6e2@8g2000hsu.googlegroups.com>
On Apr 15, 2:03 pm, Slobodan Blazeski <·················@gmail.com>
wrote:
> (defun make-adder (n) #'(lambda (x) (+ x n)))
> ((make-adder 3) 8)

What about just abbreviating funcall as FC?
Is that too verbose?  While you're at it, you can
rip off Arc and abbreviate lambda as FN.  That way,
you buy yourself both concision and notational
consistency with ony four characters, six including
white space.

(defun make-adder (n) (fn (x) (+ x n)))
(fc (make-adder 3) 8)

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <8b351157-e862-4157-8ac4-41efbf99bfc1@c65g2000hsa.googlegroups.com>
On Apr 17, 3:45 am, danb <·········@gmail.com> wrote:
> On Apr 15, 2:03 pm, Slobodan Blazeski <·················@gmail.com>
> wrote:
>
> > (defun make-adder (n) #'(lambda (x) (+ x n)))
> > ((make-adder 3) 8)
>
> What about just abbreviating funcall as FC?
> Is that too verbose?  While you're at it, you can
> rip off Arc and abbreviate lambda as FN.  That way,
> you buy yourself both concision and notational
> consistency with ony four characters, six including
> white space.
>
> (defun make-adder (n) (fn (x) (+ x n)))
> (fc (make-adder 3) 8)

I'm not going after terseness only, else I would be using J,  K or
Q( Q is better looking than j or k but still... ), the price you have
to pay is in the readibility and too much syntax.
So no matter would I use fc or get-the-function-value-cell-and-call-it
the amount of tokens is the same. The language is still too verbose.
Also I have a better *TRICKS* than Arc
(f + a b)
(lambda (a b) (+ a b))

(f / b a))
(lambda (a b) (/ b a))

Average
(divide plus length)
(lambda (x) (/ (reduce #'+ x) (length x))

Range difference between largest and smallest item
(minus > <)


Heron's formula for the area of a triangle, given the lengths of the
sides a, b, and c, is
sqrt(s*(s-a)*(s-b)*s-c)) where s is (a+b+c)%2 .

(sqrt (abate times (minus (/ plus 2) identity)))

(lambda (a b c)
  (sqrt (* (- (/ (+ a b c) 2) a)
           (- (/ (+ a b c) 2) b)
           (- (/ (+ a b c) 2) c)))
From: danb
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <0996d927-028e-41cf-8035-d915266586e1@8g2000hse.googlegroups.com>
> On Apr 17, 3:45 am, danb wrote:
> > What about just abbreviating funcall as FC?

On Apr 17, 6:58 am, Slobodan Blazeski wrote:
> I'm not going after terseness only
> Also I have a better *TRICKS* than Arc
> (f + a b)
> (lambda (a b) (+ a b))
> (f / b a))
> (lambda (a b) (/ b a))

But how do you know a and b are arguments?
If that's all you need, I just finished a
small read macro that handles it.  For source
code, click the "#func" entry here:
http://www.prairienet.org/~dsb/myclcode.htm

You just write an underline* for each argument,
and you get a single-form lambda:

#f(+ _ _) => (lambda (#:G1 #:G2) (+ #:G1 #:G2))
#f(push _ xs) => (lambda (#:G3) (push #:G3 xs))
#3f(foo) =>
    (lambda (#:G4 #:G5 #:G6) (foo #:G4 #:G5 #:G6))

--Dan

* I saw this trick on the web somewhere, but I don't
remember where.  Maybe Paul Graham mentioned it in
an Arc article somewhere.

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: Slobodan Blazeski
Subject: Re: Is it possible to implement ,@ if it wasn't already there
Date: 
Message-ID: <7fb64fc0-8291-4442-be1d-b12a25f3e99d@x41g2000hsb.googlegroups.com>
On Apr 17, 6:44 pm, danb <·········@gmail.com> wrote:
> > On Apr 17, 3:45 am, danb wrote:
> > > What about just abbreviating funcall as FC?
>
> On Apr 17, 6:58 am, Slobodan Blazeski wrote:
>
> > I'm not going after terseness only
> > Also I have a better *TRICKS* than Arc
> > (f + a b)
> > (lambda (a b) (+ a b))
> > (f / b a))
> > (lambda (a b) (/ b a))
>
> But how do you know a and b are arguments?

Convention, f is a function builder that builds upon encountering a b
c ..z y z.
Meaning a is always a first arguments (if encountered in your
expression) b second etc.
It's unable to deal with capturing arguments that are in a..z
interval, you need classical lambda for that,
but it's quite handy for most of the (my) jobs.
I thought of using some special character like $ for params
(f + $foo $baz)
but than I've encountered the problem of supplying arguments in
different order than using them like:
(lambda (a b) (/ b a))



> If that's all you need, I just finished a
> small read macro that handles it.  For source
> code, click the "#func" entry here:http://www.prairienet.org/~dsb/myclcode.htm
>
> You just write an underline* for each argument,
> and you get a single-form lambda:
>
> #f(+ _ _) => (lambda (#:G1 #:G2) (+ #:G1 #:G2))
> #f(push _ xs) => (lambda (#:G3) (push #:G3 xs))
> #3f(foo) =>
>     (lambda (#:G4 #:G5 #:G6) (foo #:G4 #:G5 #:G6))

That won't work for me I wan't uniform look (operator &rest args),
that's it nothing  more.
>
> --Dan
>
> * I saw this trick on the web somewhere, but I don't
> remember where.  Maybe Paul Graham mentioned it in
> an Arc article somewhere.
>
> ------------------------------------------------
> Dan Bensenhttp://www.prairienet.org/~dsb/
From: Alex Mizrahi
Subject: Re: Is it possible to implement ,@  if it wasn't already there
Date: 
Message-ID: <4804d3b6$0$90267$14726298@news.sunsite.dk>
 SB> I need to get rid of some funcalls some so could I do something
 SB> like ,@ is doing

 SB> ((splice #'(lambda (x) (* 2 x))) 4) <=> (funcall #'(lambda (x) (* 2
 SB> x))) 4)

<applying telepathy>

if you want shorthand notation for funcall, you can do a reader macro that 
will be sort of inverse of #' -- instead of converting from function 
namespace to variable one, it will convert variables into function.

i.e.

(let ((f (lambda (x) (* 2 x))))
 (#,f 2)) => 4

it can work expanding stuff in such way: #,f -> (lambda (&rest) (apply f 
rest)), in expression it will look like that:

(#,f a b c) -> ((lambda (&rest rest) (apply f rest)) a b c)