For those who like to program in a functional style without having to
type FUNCALL all the time:
(defun \_-reader (stream char)
(declare (ignore char))
`(lambda (&rest #1=#.(gensym "ARGS")) (apply ,(read stream) #1#)))
(set-macro-character #\_ '\_-reader t)
Now you can call the local version of a function simply by preceding its
name with an underscore. (The cost is that you lose the ability to have
variables and functions whose names begin with underscore. If you don't
like that you can choose a different character, or use a dispatching
macro character.)
e.g.:
(defun foo (list)
(list 1 (_list 2))) ; Instead of (list 1 (funcall list 2))
(foo #'vector) --> (1 #(2))
rg
Ron Garret wrote:
> For those who like to program in a functional style without having to
> type FUNCALL all the time:
>
> (defun \_-reader (stream char)
> (declare (ignore char))
> `(lambda (&rest #1=#.(gensym "ARGS")) (apply ,(read stream) #1#)))
>
> (set-macro-character #\_ '\_-reader t)
>
For the (lambda (&rest args) (apply something args)) idiom it's a good
idea to actually say:
(lambda (&rest args)
(declare (dynamic-extent args))
(apply something args))
Just a sidenote...
Pascal
--
3rd European Lisp Workshop
July 3-4 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
In article <···············@individual.net>,
Pascal Costanza <··@p-cos.net> wrote:
> Ron Garret wrote:
> > For those who like to program in a functional style without having to
> > type FUNCALL all the time:
> >
> > (defun \_-reader (stream char)
> > (declare (ignore char))
> > `(lambda (&rest #1=#.(gensym "ARGS")) (apply ,(read stream) #1#)))
> >
> > (set-macro-character #\_ '\_-reader t)
> >
>
> For the (lambda (&rest args) (apply something args)) idiom it's a good
> idea to actually say:
>
> (lambda (&rest args)
> (declare (dynamic-extent args))
> (apply something args))
>
> Just a sidenote...
Good point.
rg
Pascal Costanza <··@p-cos.net> writes:
> For the (lambda (&rest args) (apply something args)) idiom it's a good
> idea to actually say:
>
> (lambda (&rest args)
> (declare (dynamic-extent args))
> (apply something args))
Is the dynamic extent valid if something is #'(lambda (&rest args) args)?
--
__("< Marcin Kowalczyk
\__/ ······@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
Marcin 'Qrczak' Kowalczyk wrote:
> Pascal Costanza <··@p-cos.net> writes:
>
> > For the (lambda (&rest args) (apply something args)) idiom it's a good
> > idea to actually say:
> >
> > (lambda (&rest args)
> > (declare (dynamic-extent args))
> > (apply something args))
>
> Is the dynamic extent valid if something is #'(lambda (&rest args) args)?
Yes, the list is copied in case the called function side-effects its
argument list... Yet another cause of inefficiency :)
Paul Khuong
In article <························@g10g2000cwb.googlegroups.com>,
·······@gmail.com wrote:
> Marcin 'Qrczak' Kowalczyk wrote:
> > Pascal Costanza <··@p-cos.net> writes:
> >
> > > For the (lambda (&rest args) (apply something args)) idiom it's a good
> > > idea to actually say:
> > >
> > > (lambda (&rest args)
> > > (declare (dynamic-extent args))
> > > (apply something args))
> >
> > Is the dynamic extent valid if something is #'(lambda (&rest args) args)?
>
> Yes, the list is copied in case the called function side-effects its
> argument list... Yet another cause of inefficiency :)
>
> Paul Khuong
It depends on the compiler. It works in SBCL, but MCL returns a #<BOGUS
OBJECT> if you do this. I think the spec says this is not required to
work.
rg
Marcin 'Qrczak' Kowalczyk wrote:
> Pascal Costanza <··@p-cos.net> writes:
>
>> For the (lambda (&rest args) (apply something args)) idiom it's a good
>> idea to actually say:
>>
>> (lambda (&rest args)
>> (declare (dynamic-extent args))
>> (apply something args))
>
> Is the dynamic extent valid if something is #'(lambda (&rest args) args)?
No, but you can pass the following instead:
(lambda (&rest args)
(declare (dynamic-extent args))
(copy-list args))
What do you want to use this for?
Pascal
--
3rd European Lisp Workshop
July 3-4 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
Pascal Costanza <··@p-cos.net> writes:
> No, but you can pass the following instead:
>
> (lambda (&rest args)
> (declare (dynamic-extent args))
> (copy-list args))
>
> What do you want to use this for?
You seem to have suggested to declare as dynamic-extent the &rest
parameter which is passed down to another function, irrespective
of how the other function is written (if "idiom" is understood as
"any code matching this pattern").
I was just worried that this optimization requires the knowledge about
the other function. In particular it would be unsafe with the _func
reader syntax that this thread is about, because the function might
return its original parameter list as a part of its result.
--
__("< Marcin Kowalczyk
\__/ ······@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:
> Pascal Costanza <··@p-cos.net> writes:
>
>> No, but you can pass the following instead:
>>
>> (lambda (&rest args)
>> (declare (dynamic-extent args))
>> (copy-list args))
>>
>> What do you want to use this for?
>
> You seem to have suggested to declare as dynamic-extent the &rest
> parameter which is passed down to another function, irrespective
> of how the other function is written (if "idiom" is understood as
> "any code matching this pattern").
>
> I was just worried that this optimization requires the knowledge about
> the other function. In particular it would be unsafe with the _func
> reader syntax that this thread is about, because the function might
> return its original parameter list as a part of its result.
>
> --
> __("< Marcin Kowalczyk
> \__/ ······@knm.org.pl
> ^^ http://qrnik.knm.org.pl/~qrczak/
It is always unsafe to modify &rest arguments.
--
This is a song that took me ten years to live and two years to write.
- Bob Dylan
Ron Garret wrote:
> For those who like to program in a functional style without having to
> type FUNCALL all the time:
> (list 1 (_list 2))) ; Instead of (list 1 (funcall list 2))
Uh, you know, all you have really done is made _ a synonym for funcall.
Except that a space is not allowed after it, which isn't necessarily
any kind of advantage.
(defmacro _ (f &rest args)
`(funcall f ,@args))
(_ list 2) ;; instead of (funcall list 2)
But at least we haven't stolen the _ constituent character. Moreover,
we have only claimed the symbol named "_" in one package.
Shortening symbol names to save typing is ... boring.
Ron Garret <·········@flownet.com> writes:
> For those who like to program in a functional style without having to
> type FUNCALL all the time:
>
> (defun \_-reader (stream char)
> (declare (ignore char))
> `(lambda (&rest #1=#.(gensym "ARGS")) (apply ,(read stream) #1#)))
>
> (set-macro-character #\_ '\_-reader t)
>
> Now you can call the local version of a function simply by preceding its
> name with an underscore. (The cost is that you lose the ability to have
> variables and functions whose names begin with underscore. If you don't
> like that you can choose a different character, or use a dispatching
> macro character.)
>
> e.g.:
>
> (defun foo (list)
> (list 1 (_list 2))) ; Instead of (list 1 (funcall list 2))
>
> (foo #'vector) --> (1 #(2))
Wouldn't
(defun foo (list)
(list 1 [list 2])) ; Instead of (list 1 (funcall list 2))
(foo #'vector) --> (1 #(2))
look a bit less Perl-ish?
(defun open-bracket-macro-character (stream char)
(declare (ignore char))
(let ((list (read-delimited-list #\] stream t)))
`(funcall ,(first list) ,@(rest list))))
(set-macro-character #\[ #'open-bracket-macro-character)
(set-macro-character #\] (get-macro-character #\)))
Andras
Ron Garret <·········@flownet.com> writes:
> (defun \_-reader (stream char)
> (declare (ignore char))
> `(lambda (&rest #1=#.(gensym "ARGS")) (apply ,(read stream) #1#)))
I think the call should in principle be (read stream t nil t),
to support this:
(let ((#1=#:foo #'cons))
(_#1# t nil))
> (set-macro-character #\_ '\_-reader t)
Anyway, the whole thing could be simplified to:
(set-macro-character #\_ (constantly 'funcall) t)
which doesn't detect misuses like (_) at read time as yours does,
but I expect that would not be a problem.