From: K�roly Ladv�nszky
Subject: Need some help
Date: 
Message-ID: <3be2f6ca_1@corp-goliath.newsgroups.com>
Hi,

I would like to get help on the following problems.

1. How to access a object slot in case it's name is in a string?
(setf (slot-value mybox 'width) 3)   ; "width" ?

2. Is it possible to add new object slots and functions runtime?

3. I understand a function can return a lambda function but can it return a
ordinary function?
In Python this is legal:

def mgte(n):
    def mgtex(x):
        return x>n
    return mgtex

Now setup a 'function variable' and use it:

mgte3=mgte(3)
mgte3(2) => returns false
mgte3(4) => returns true

even mgte(3)(4) works

4. Are there Lisp object persistence addons?

Thanks for any help.

Cheers,

K�roly


______________________________________________________________________________
Posted Via Binaries.net = SPEED+RETENTION+COMPLETION = http://www.binaries.net

From: ···@itasoftware.com
Subject: Re: Need some help
Date: 
Message-ID: <hesd6icf.fsf@itasoftware.com>
"K�roly Ladv�nszky" <··@bb.cc> writes:

> Hi,
> 
> I would like to get help on the following problems.
> 
> 1. How to access a object slot in case it's name is in a string?
> (setf (slot-value mybox 'width) 3)   ; "width" ?

You need to establish a mapping between strings and slot names.  There
are a few ways of doing this, possibly the best is by defining a
table, or you could use FIND-SYMBOL to query the package system.

> 2. Is it possible to add new object slots and functions runtime?

Yes.  You can even change the class hierarchy.

> 3. I understand a function can return a lambda function but can it return a
> ordinary function?

Yes.

> 4. Are there Lisp object persistence addons?

Yes.  Franz makes AllegroStore, there are others as well.
From: Marco Antoniotti
Subject: Re: Need some help
Date: 
Message-ID: <y6cady4x1v9.fsf@octagon.mrl.nyu.edu>
"K�roly Ladv�nszky" <··@bb.cc> writes:

> Hi,
> 
> I would like to get help on the following problems.
> 
> 1. How to access a object slot in case it's name is in a string?
> (setf (slot-value mybox 'width) 3)   ; "width" ?
> 
> 2. Is it possible to add new object slots and functions runtime?
> 
> 3. I understand a function can return a lambda function but can it return a
> ordinary function?
> In Python this is legal:
> 
> def mgte(n):
>     def mgtex(x):
>         return x>n
>     return mgtex
> 
> Now setup a 'function variable' and use it:
> 
> mgte3=mgte(3)
> mgte3(2) => returns false
> mgte3(4) => returns true
> 
> even mgte(3)(4) works
> 
> 4. Are there Lisp object persistence addons?
> 

The general answer to this kind of questions is that Python
(tllotbafir) is a re-invention of the wheel that perfectly applies
Greenspun's Tenth Rule of Programming.  :)

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: K�roly Ladv�nszky
Subject: Re: Need some help
Date: 
Message-ID: <3be3ef50_2@corp-goliath.newsgroups.com>
"Marco Antoniotti" <·······@cs.nyu.edu> az al�bbiakat �rta a k�vetkez�
�zenetben: ····················@octagon.mrl.nyu.edu...

> The general answer to this kind of questions is that Python
> (tllotbafir) is a re-invention of the wheel that perfectly applies
> Greenspun's Tenth Rule of Programming.  :)

Very helpful message. Thanks.

K�roly




______________________________________________________________________________
Posted Via Binaries.net = SPEED+RETENTION+COMPLETION = http://www.binaries.net
From: Marco Antoniotti
Subject: Re: Need some help
Date: 
Message-ID: <y6cn123devy.fsf@octagon.mrl.nyu.edu>
"K�roly Ladv�nszky" <··@bb.cc> writes:

> "Marco Antoniotti" <·······@cs.nyu.edu> az al�bbiakat �rta a k�vetkez�
> �zenetben: ····················@octagon.mrl.nyu.edu...
> 
> > The general answer to this kind of questions is that Python
> > (tllotbafir) is a re-invention of the wheel that perfectly applies
> > Greenspun's Tenth Rule of Programming.  :)
> 
> Very helpful message. Thanks.
> 

I am glad it helped. Didn't it? :)

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Barry Margolin
Subject: Re: Need some help
Date: 
Message-ID: <abDE7.30$KI3.4054@burlma1-snr2>
In article <··········@corp-goliath.newsgroups.com>,
K�roly Ladv�nszky <··@bb.cc> wrote:
>Hi,
>
>I would like to get help on the following problems.
>
>1. How to access a object slot in case it's name is in a string?
>(setf (slot-value mybox 'width) 3)   ; "width" ?

You can use INTERN translate a symbol's name to the symbol:

(setf (slot-value mybox (intern slot-name)) 3)

Note that if the string is lowercase but you're using the reader's default
case canonicalization, you'll need to call STRING-UPCASE on the string:

(setf (slot-value mybox (intern (string-upcase slot-name))) 3)

Or you could use READ-FROM-STRING to use whatever reader canonicalization
you have in effect:

(setf (slot-value mybox (read-from-string slot-name)) 3)

>2. Is it possible to add new object slots and functions runtime?

This can be done using the Meta-Object Protocol.

>3. I understand a function can return a lambda function but can it return a
>ordinary function?

Yes.  The FUNCTION special operator (normally used via the #' reader macro)
takes a function name and returns the function object it names.

>In Python this is legal:
>
>def mgte(n):
>    def mgtex(x):
>        return x>n
>    return mgtex

(defun mgte (n)
  (flet ((mgtex (x)
           (> x n)))
    #'mgtex))

>Now setup a 'function variable' and use it:
>
>mgte3=mgte(3)
>mgte3(2) => returns false
>mgte3(4) => returns true
>
>even mgte(3)(4) works

(setq mgte3 (mgte 3))
(funcall mgte3 2)
(funcall mgte3 4)
(funcall (mgte 3) 4)

>4. Are there Lisp object persistence addons?

Yes, but I don't know any specifics.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dr. Edmund Weitz
Subject: Re: Need some help
Date: 
Message-ID: <m38zdosxfd.fsf@bird.agharta.de>
"K�roly Ladv�nszky" <··@bb.cc> writes:

> 1. How to access a object slot in case it's name is in a string?
> (setf (slot-value mybox 'width) 3)   ; "width" ?

You can use INTERN to convert strings to symbols:
<http://www.xanalys.com/software_tools/reference/HyperSpec/Body/fun_intern.html>
 
> 2. Is it possible to add new object slots and functions runtime?

What do you mean by 'runtime'? Lisp has no code-compile-run cycle as
in C, so in a way it's always 'runtime'.

You can add methods after you have created a class by DEFMETHOD. You
can also redefine the class - see
<http://www.xanalys.com/software_tools/reference/HyperSpec/Body/sec_4-3-6.html>
 
> 3. I understand a function can return a lambda function but can it return a
> ordinary function?
> In Python this is legal:
> 
> def mgte(n):
>     def mgtex(x):
>         return x>n
>     return mgtex
> 
> Now setup a 'function variable' and use it:
> 
> mgte3=mgte(3)
> mgte3(2) => returns false
> mgte3(4) => returns true
> 
> even mgte(3)(4) works

This would be:

  CL-USER 1 > (defun mgte (n)
                #'(lambda (x) (> x n)))
  MGTE

  CL-USER 2 > (mgte 3)
  #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 21327822>

  CL-USER 3 > (funcall (mgte 3) 2)
  NIL

  CL-USER 4 > (funcall (mgte 3) 4)
  T

  CL-USER 5 > (setf (symbol-function 'mgte3) (mgte 3))
  #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 204D6FD2>

  CL-USER 6 > (mgte3 2)
  NIL

  CL-USER 7 > (mgte3 4)
  T

in Common Lisp. Note that #'something is just an abbreviation for
(function something).

> 4. Are there Lisp object persistence addons?

You might want to look at PLOB! <http://www.lisp.de/software/plob/> or
UncommonSQL <http://alpha.onshored.com/lisp-software/>.

HTH,
Edi.
From: K�roly Ladv�nszky
Subject: Re: Need some help
Date: 
Message-ID: <3be30bee_2@corp-goliath.newsgroups.com>
Thank you for your helpful answer.

> What do you mean by 'runtime'? Lisp has no code-compile-run cycle as
> in C, so in a way it's always 'runtime'.

What I mean is to add a slot to a working object.
In Python it is simply a matter of referencing the desired member:
obj.alfa=33, if alfa does not exist, it's added to the object! You can even
extend the class itself. Well, yes, quite dangerous stuff.

> This would be:
>
>   CL-USER 1 > (defun mgte (n)
>                 #'(lambda (x) (> x n)))
>   MGTE

Actually, the stress was on using a ordinary function within a function, not
a lambda.
Barry Margolin's message has given me the answer.

Cheers,

K�roly


______________________________________________________________________________
Posted Via Binaries.net = SPEED+RETENTION+COMPLETION = http://www.binaries.net
From: Barry Margolin
Subject: Re: Need some help
Date: 
Message-ID: <qDEE7.36$KI3.4334@burlma1-snr2>
In article <··········@corp-goliath.newsgroups.com>,
K�roly Ladv�nszky <··@bb.cc> wrote:
>Thank you for your helpful answer.
>
>> What do you mean by 'runtime'? Lisp has no code-compile-run cycle as
>> in C, so in a way it's always 'runtime'.
>
>What I mean is to add a slot to a working object.
>In Python it is simply a matter of referencing the desired member:
>obj.alfa=33, if alfa does not exist, it's added to the object! You can even
>extend the class itself. Well, yes, quite dangerous stuff.

In CLOS, the class defines the structure of all instances of that class.
If you redefine a class to add or remove slots the change will
automatically propagate to all existing instances.  To provide control over
how objects respond to such a change (e.g. if you want a new slot's value
to be a function of the contents of some obsolete slots) there are methods
you can define to intercede.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dr. Edmund Weitz
Subject: Re: Need some help
Date: 
Message-ID: <m33d3wlr1j.fsf@bird.agharta.de>
"K�roly Ladv�nszky" <··@bb.cc> writes:

> What I mean is to add a slot to a working object.
> In Python it is simply a matter of referencing the desired member:
> obj.alfa=33, if alfa does not exist, it's added to the object! You can even
> extend the class itself. Well, yes, quite dangerous stuff.

Yes, this can be done in CL like so:

  CL-USER 29 > (defclass my-class () ((slot-a :initarg :slot-a)))
  #<STANDARD-CLASS MY-CLASS 2132CADC>
  
  CL-USER 30 > (defparameter *a* (make-instance 'my-class :slot-a 3))
  *A*
  
  CL-USER 31 > (slot-value *a* 'slot-a)
  3
  
  CL-USER 32 > (defclass my-2nd-class (my-class) ((slot-b :initarg :slot-b)))
  #<STANDARD-CLASS MY-2ND-CLASS 204E9174>
  
  CL-USER 33 > (change-class *a* 'my-2nd-class :slot-b 5)
  #<MY-2ND-CLASS 204D6FAC>
  
  CL-USER 34 > (slot-value *a* 'slot-b)
  5
  
  CL-USER 35 > (slot-value *a* 'slot-a)
  3

  CL-USER 36 > (typep *a* 'my-2nd-class)
  T

  CL-USER 37 > (typep *a* 'my-class)
  T

As you can see, the working object *A* has changed its class, but has
retained the SLOT-VALUE for SLOT-A. It is also still of type
MY-CLASS. Granted, this is not a one-liner as in Python, but it is
definitely a cleaner and safer approach.
  
> > This would be:
> >
> >   CL-USER 1 > (defun mgte (n)
> >                 #'(lambda (x) (> x n)))
> >   MGTE
> 
> Actually, the stress was on using a ordinary function within a function, not
> a lambda.
> Barry Margolin's message has given me the answer.

I see. But in your original question you asked whether a function can
RETURN an ordinary function. Both Barry Margolin's example as well as
mine return an ordinary function:

  CL-USER 1 > (defun mgte (n)
                #'(lambda (x) (> x n)))
  MGTE

  CL-USER 2 > (mgte 3)
  #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 204EAFEA>

  CL-USER 3 > (defun mgte-2 (n)
                (flet ((mgtex (x) (> x n)))
                  #'mgtex))
  MGTE-2

  CL-USER 4 > (mgte-2 3)
  #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 20506722>

  CL-USER 5 > (type-of (mgte 3))
  LOW:CLOSURE

  CL-USER 6 > (type-of (mgte-2 3))
  LOW:CLOSURE

  CL-USER 7 > (functionp (mgte 3))
  T

  CL-USER 8 > (functionp (mgte-2 3))
  T

(Note that things like #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE
204EAFEA> and LOW:CLOSURE are implementation-dependent, but FUNCTIONP
must return T in both cases in all conforming implementations.)

The difference between these two examples isn't that big: (DEFUN
function-name ...) causes function-name to be a global name for the
function specified by a lambda expression, so it's more or less only
syntactical sugar for

  (SETF (SYMBOL-FUNCTION 'function-name) #'(LAMBDA ...))

[See the CLHS entry for DEFUN for details.]

FLET and LABELS are similar, only the scope of the name bindings is
different.

Anyway, the consequence is that the caller of MGTE or MGTE-2 won't be
able to tell the difference - what he gets is a function in both
cases.

See
<http://groups.google.com/groups?hl=en&threadm=47q59o%24hih%40hawk.ee.port.ac.uk>
for more on this subject.

Best regards,
Edi.
From: Marco Antoniotti
Subject: Re: Need some help
Date: 
Message-ID: <y6cy9lovizu.fsf@octagon.mrl.nyu.edu>
···@agharta.de (Dr. Edmund Weitz) writes:

> "K�roly Ladv�nszky" <··@bb.cc> writes:
> 
> > What I mean is to add a slot to a working object.
> > In Python it is simply a matter of referencing the desired member:
> > obj.alfa=33, if alfa does not exist, it's added to the object! You can even
> > extend the class itself. Well, yes, quite dangerous stuff.
> 
> Yes, this can be done in CL like so:
> 
>   CL-USER 29 > (defclass my-class () ((slot-a :initarg :slot-a)))
>   #<STANDARD-CLASS MY-CLASS 2132CADC>
>   
>   CL-USER 30 > (defparameter *a* (make-instance 'my-class :slot-a 3))
>   *A*
>   
>   CL-USER 31 > (slot-value *a* 'slot-a)
>   3
>   
>   CL-USER 32 > (defclass my-2nd-class (my-class) ((slot-b :initarg :slot-b)))
>   #<STANDARD-CLASS MY-2ND-CLASS 204E9174>
>   
>   CL-USER 33 > (change-class *a* 'my-2nd-class :slot-b 5)
>   #<MY-2ND-CLASS 204D6FAC>
>   
>   CL-USER 34 > (slot-value *a* 'slot-b)
>   5
>   
>   CL-USER 35 > (slot-value *a* 'slot-a)
>   3
> 
>   CL-USER 36 > (typep *a* 'my-2nd-class)
>   T
> 
>   CL-USER 37 > (typep *a* 'my-class)
>   T
> 
> As you can see, the working object *A* has changed its class, but has
> retained the SLOT-VALUE for SLOT-A. It is also still of type
> MY-CLASS. Granted, this is not a one-liner as in Python, but it is
> definitely a cleaner and safer approach.

A little different, yet meaningful example (using a different - yet
conforming - CL implementation).

* (defclass my-class () ((slot-a :initarg :slot-a)))
#<STANDARD-CLASS MY-CLASS {480ED945}>
* (defparameter *a* (make-instance 'my-class :slot-a 3))
*A*
* (slot-value *a* 'slot-a)
3
* (describe *a*)

#<MY-CLASS {480F05A5}> is an instance of class #<Standard-Class MY-CLASS {480E9B25}>:
 The following slots have :INSTANCE allocation:
 SLOT-A    3

* ;; Let's re define `my-class'
(defclass my-class () ((slot-a :initarg :slot-a) (slot-b :initarg :slot-b)))
#<STANDARD-CLASS MY-CLASS {480ED945}>

* (describe *a*)

#<MY-CLASS {480F05A5}> is an instance of class #<Standard-Class MY-CLASS {480E9B25}>:
 The following slots have :INSTANCE allocation:
 SLOT-B    "unbound"
 SLOT-A    3
* 

As you can see the instance has been corretly updated.  You also have
control over how you can reinitialize the instances.

So the question is (not specifically directed at the original poster):
why re-implement all of this in Python (tllotbafir) and not use the
real thing to start with?

Cheers.

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Pierre R. Mai
Subject: Re: Need some help
Date: 
Message-ID: <87ady47tui.fsf@orion.bln.pmsf.de>
"K�roly Ladv�nszky" <··@bb.cc> writes:

> 1. How to access a object slot in case it's name is in a string?
> (setf (slot-value mybox 'width) 3)   ; "width" ?

You can find an existing symbol using find-symbol, so that (assuming
standard default reader-case, etc.)

(find-symbol (string-upcase "width"))

will find you the symbol width, in the package that is currently bound
to *package*, if it existed before.  You can then use slot-value as
normal, e.g.

(defun slot-value-from-string (object string &optional (package *package*))
  (multiple-value-bind (slot-name present-p)
      (find-symbol (string-upcase string) package)
    ;; You should probably check whether slot-name is external here!
    (unless present-p
      (error "Didn't find a symbol named ··@(~A~) in ~S." string package))
    ;; Further checks for the validity of the slot-name should go here!
    (slot-value object slot-name)))

But the interesting question is whether you would really want to do
this sort of thing.  Maybe you could describe in more detail what you
are trying to achieve, so that we could point out possible pit-falls
or alternatives.

> 2. Is it possible to add new object slots and functions runtime?

Yes.  You can (re-)define classes at run-time, and you can of course
(re)define functions and methods at run-time.  Again, depending on the
details, various approaches can be used here, ranging from the use of
eval on newly-built defclass or defun/defmethod forms, to use of the
MOP, etc.

> 3. I understand a function can return a lambda function but can it return a
> ordinary function?

Of course.

> In Python this is legal:
> 
> def mgte(n):
>     def mgtex(x):
>         return x>n
>     return mgtex
> 
> Now setup a 'function variable' and use it:
> 
> mgte3=mgte(3)
> mgte3(2) => returns false
> mgte3(4) => returns true
> 
> even mgte(3)(4) works

(defun mgte (n)
  (flet ((mgtex (x) (> x n)))
    #'mgtex))

(let ((mgte3 (mgte 3)))
  (values (funcall mgte3 2) (funcall mgte3 4)))

=> nil t

(funcall (mgte 3) 4) works as well.

For the case above though, I'd rather write

(defun mgte (n)
  #'(lambda (x) (> x n)))

since naming the function doesn't really add to the readability of the
code.

> 4. Are there Lisp object persistence addons?

Franz offers AllegroStore for its Allegro Common Lisp product.  PLOB!
is a freely available system for ACL and LispWorks, see

  http://www.lisp.de/software/plob/

for details.

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein