[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

callable objects

Stefan Monnier

8/12/2015 4:22:00 PM

Common-Lisp has the notion of an object that can be called, functions
being one example, generic functions another (and IIUC symbols also are
callable).

AFAICT the Common-Lisp standard does not provide a standard way to build
such objects in general: you can't define your own kind of
callable object.

Do some Common-Lisp implementations offer a way to define your own
callable objects? If so, which ones, and what kind of primitive do they
provide to do that?


Stefan
20 Answers

Pascal J. Bourguignon

8/12/2015 4:34:00 PM

0

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Common-Lisp has the notion of an object that can be called, functions
> being one example, generic functions another (and IIUC symbols also are
> callable).
>
> AFAICT the Common-Lisp standard does not provide a standard way to build
> such objects in general: you can't define your own kind of
> callable object.
>
> Do some Common-Lisp implementations offer a way to define your own
> callable objects? If so, which ones, and what kind of primitive do they
> provide to do that?

Yes, it's done with the MOP and CLOS.

I don't know the details, but basically you can define your own
subclasses of closer-mop:FUNCALLABLE-STANDARD-OBJECT.

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Pascal Costanza

8/12/2015 5:18:00 PM

0

On 12/08/2015 18:22, Stefan Monnier wrote:
> Common-Lisp has the notion of an object that can be called, functions
> being one example, generic functions another (and IIUC symbols also are
> callable).
>
> AFAICT the Common-Lisp standard does not provide a standard way to build
> such objects in general: you can't define your own kind of
> callable object.
>
> Do some Common-Lisp implementations offer a way to define your own
> callable objects? If so, which ones, and what kind of primitive do they
> provide to do that?

The ones listed at
https://common-lisp.net/project/closer/close... should all be
fine. Other implementations may have this as well.

Pascal

--
My website: http:/...
Common Lisp Document Repository: http://cdr.eu...
Closer to MOP & ContextL: http://common-lisp.net/proje...
The views expressed are my own, and not those of my employer.

Stefan Monnier

8/12/2015 6:38:00 PM

0

> I don't know the details, but basically you can define your own
> subclasses of closer-mop:FUNCALLABLE-STANDARD-OBJECT.

But how do I specify the code executed when they're called?


Stefan

Didier Verna

8/12/2015 8:13:00 PM

0

Stefan Monnier <monnier@iro.umontreal.ca> wrote:

>> I don't know the details, but basically you can define your own
>> subclasses of closer-mop:FUNCALLABLE-STANDARD-OBJECT.
>
> But how do I specify the code executed when they're called?

Cf. SET-FUNCALLABLE-INSTANCE-FUNCTION (MOP, not standard lisp).

--
My new Jazz CD entitled "Roots and Leaves" is out!
Check it out: http://didierverna.com/records/roots-and-...

Lisp, Jazz, Aïkido: http://www.didier...

Stefan Monnier

8/12/2015 8:39:00 PM

0

>>> I don't know the details, but basically you can define your own
>>> subclasses of closer-mop:FUNCALLABLE-STANDARD-OBJECT.
>> But how do I specify the code executed when they're called?
> Cf. SET-FUNCALLABLE-INSTANCE-FUNCTION (MOP, not standard lisp).

Thanks. That lead me to
http://metamodular.com/CLOS-MOP/funcallable-inst... which even
gives me an example.

Does someone know of alternative APIs for that kind of functionality
(e.g. one that would allow to use a single underlying "vector" to
hold both the slots of the object and the free variables of the closure)?


Stefan

William James

8/12/2015 10:51:00 PM

0

Pascal J. Bourguignon wrote:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
> > Common-Lisp has the notion of an object that can be called, functions
> > being one example, generic functions another (and IIUC symbols also are
> > callable).
> >
> > AFAICT the Common-Lisp standard does not provide a standard way to build
> > such objects in general: you can't define your own kind of
> > callable object.
> >
> > Do some Common-Lisp implementations offer a way to define your own
> > callable objects? If so, which ones, and what kind of primitive do they
> > provide to do that?
>
> Yes, it's done with the MOP and CLOS.
>
> I don't know the details, but basically you can define your own
> subclasses of closer-mop:FUNCALLABLE-STANDARD-OBJECT.

Gauche Scheme:

(define-method object-apply ((v <vector>) (i <integer>))
(vector-ref v i))

(#(a b c d e) 4)
===>
e

--
He has nothing but kind sentiments for those who would destroy his home and
family.... He is universally tolerant.... If he has any principles, he keeps
them well concealed.... He is, to the extent of his abilities, exactly like
the next citizen, who, he trusts, is trying to be exactly like him: a faceless,
characterless putty-man. --- Father Feeney; "Should Hate Be Outlawed?"

Lars Brinkhoff

8/13/2015 7:11:00 AM

0

Stefan Monnier <monnier@iro.umontreal.ca> writes:
> Does someone know of alternative APIs for that kind of functionality
> (e.g. one that would allow to use a single underlying "vector" to
> hold both the slots of the object and the free variables of the closure)?

I have implemented funcallable objects as part of my CL written in Emacs
Lisp. That was before closures were added to Emacs, though.

I don't remeber the details of how or why, but looking at the code now,
it seems I chose to store funcallable objects in Emacs compiled-
functions. To access the slots, the function is used to index into a
hash table which holds vectors containing the slots.

Stefan Monnier

8/13/2015 3:49:00 PM

0

> I don't remeber the details of how or why, but looking at the code now,
> it seems I chose to store funcallable objects in Emacs compiled-
> functions. To access the slots, the function is used to index into a
> hash table which holds vectors containing the slots.

Interesting, thanks,


Stefan

smh

8/15/2015 5:13:00 AM

0

Well, you don't the entire machinery of the MOP, or even CLOS, to build funcallable instances with data slots. Closures are quite enough. Here is a quick hack that implements funcallable instances with a Pythony associative map for slots. Was fun to write. Enjoy!

(progn ; smh 2015-08-14
;; These unintered symbols are walled off from the world.
(defun f-fin (fin) (funcall fin '#1=#:||))
(defun f-set-fin (fin new) (funcall fin '#2=#:|| new))
(defun f-slot-value (fin slot-name) (funcall fin '#3=#:|| slot-name))
(defun f-set-slot-value (fin slot-name new)
(funcall fin '#4=#:|| slot-name new))
(defsetf f-slot-value f-set-slot-value)

(defun funcallable-object (fin &rest slotnames-and-values)
(let ((slots (make-hash-table :test #'eql)))
;; perhaps #'equal ht would be more powerful
(loop for (slot value) on slotnames-and-values by #'cddr
do (setf (gethash slot slots) value))
(lambda (&rest args) ; This is the new instance.
(case (car args) ; empty arglist is nil
(#1# fin)
(#2# (setf fin (cadr args)))
(#3# (gethash (cadr args) slots))
(#4# (setf (gethash (cadr args) slots) (caddr args)))
(t (apply fin args))))))

)

Here's a sample of its use. The implementation could be more bulletproof, of course, but this is only a proof of concept. Should be portable to any conforming CL implementation.

cl-user(36): (setq q (funcallable-object #'+
'name "Ishmael" 'ship 'Lollypop))
#<Closure (:internal funcallable-object 0) @ #x1012205d2>
cl-user(37): (f-fin q)
#<Function +>
cl-user(38): (funcall q 1 2 3 4)
10
cl-user(39): (f-set-fin q #'*)
#<Function *>
cl-user(40): (funcall q 1 2 3 4)
24
cl-user(41): (f-slot-value q 'name)
"Ishmael"
t
cl-user(42): (setf (f-slot-value q 'name) "Ahab")
"Ahab"
cl-user(43): (f-slot-value q 'name)
"Ahab"
t
cl-user(44): (f-slot-value q 22/7)
nil
nil
cl-user(45): (setf (f-slot-value q 22/7) "Starbucks")
"Starbucks"
cl-user(46): (f-slot-value q 22/7)
"Starbucks"
t

Pascal Costanza

8/15/2015 12:28:00 PM

0

On 15/08/2015 07:13, smh wrote:
> Well, you don't the entire machinery of the MOP, or even CLOS, to build funcallable instances with data slots. Closures are quite enough. Here is a quick hack that implements funcallable instances with a Pythony associative map for slots. Was fun to write. Enjoy!

Good point. While we're at it, you can actually also use symbols as
funcallable objects: make-symbol creates (uninterned) symbols,
symbol-function allows you to set the function, and symbol-plist gives
you a property list for storing your slots. Alternatively, symbol-value
could refer to a slot vector. You can also pass a symbol as the first
parameter to funcall / apply.

This is actually how Closette from AMOP simulates funcallable objects to
implement a subset of CLOS.

Pascal

--
My website: http:/...
Common Lisp Document Repository: http://cdr.eu...
Closer to MOP & ContextL: http://common-lisp.net/proje...
The views expressed are my own, and not those of my employer.