From: Sacha
Subject: inlining and (compile
Date: 
Message-ID: <V2k5i.194984$Sq.1322095@phobos.telenet-ops.be>
Hello all,

I'm in a quest to make functional data structures, with referencial 
transparency. In the process i had to define a record structure, which 
is based on arrays.

The whole thing is easy with macros, but i'd like to have a functional 
interface underlying those macros. (as record types need to be redefined 
dynamically when one of their "superclass" is redefined)

Defining accessors from the functional interface is trivial using the 
compile function. But i would like those accessors to be inlined as well.

so i did something like this :

(defun make-accessor (class-name slot-name slot-index)
   (eval `(declaim (inline ,(slot-name class-name slot-name))))
   (compile (slot-name class-name slot-name)
            `(lambda (instance)
               (aref instance ,slot-index))))

I suspect this might not work though. And i don't even know how to make 
sure this works !

Any idea on how to do this, and also how to make sure those accessors 
are actually inlined ?

I'm using lispworks 5.0.2

Thanks in advance,
Sacha

ps : yes, i'm aware this is greenspuning CL records !

From: Joe Marshall
Subject: Re: inlining and (compile
Date: 
Message-ID: <1180031251.581633.291450@r3g2000prh.googlegroups.com>
On May 24, 10:36 am, Sacha <····@address.spam> wrote:
> Hello all,
>
> I'm in a quest to make functional data structures, with referencial
> transparency. In the process i had to define a record structure, which
> is based on arrays.
>
> The whole thing is easy with macros, but i'd like to have a functional
> interface underlying those macros. (as record types need to be redefined
> dynamically when one of their "superclass" is redefined)
>
> Defining accessors from the functional interface is trivial using the
> compile function. But i would like those accessors to be inlined as well.
>
> so i did something like this :
>
> (defun make-accessor (class-name slot-name slot-index)
>    (eval `(declaim (inline ,(slot-name class-name slot-name))))
>    (compile (slot-name class-name slot-name)
>             `(lambda (instance)
>                (aref instance ,slot-index))))

That's weird.  Why not a macro?

 (defun make-accessor (class-name slot-name slot-index)
   `(progn
       (declaim (inline ,(slot-name class-name slot-name)))
       (defun ,(slot-name class-name slot-name) (instance)
          (aref instance ,slot-index))))
From: Barry Margolin
Subject: Re: inlining and (compile
Date: 
Message-ID: <barmar-2B59CA.19411424052007@comcast.dca.giganews.com>
In article <························@r3g2000prh.googlegroups.com>,
 Joe Marshall <··········@gmail.com> wrote:

> On May 24, 10:36 am, Sacha <····@address.spam> wrote:
> > Hello all,
> >
> > I'm in a quest to make functional data structures, with referencial
> > transparency. In the process i had to define a record structure, which
> > is based on arrays.
> >
> > The whole thing is easy with macros, but i'd like to have a functional
> > interface underlying those macros. (as record types need to be redefined
> > dynamically when one of their "superclass" is redefined)
> >
> > Defining accessors from the functional interface is trivial using the
> > compile function. But i would like those accessors to be inlined as well.
> >
> > so i did something like this :
> >
> > (defun make-accessor (class-name slot-name slot-index)
> >    (eval `(declaim (inline ,(slot-name class-name slot-name))))

Use PROCLAIM instead of EVAL of DECLAIM:

(proclaim `(inline ,(slot-name class-name slot-name)))

> >    (compile (slot-name class-name slot-name)
> >             `(lambda (instance)
> >                (aref instance ,slot-index))))
> 
> That's weird.  Why not a macro?

I think because he's creating these things at runtime.  BTW, why does 
your supposed macro definition start with DEFUN? :)

> 
>  (defun make-accessor (class-name slot-name slot-index)
>    `(progn
>        (declaim (inline ,(slot-name class-name slot-name)))
>        (defun ,(slot-name class-name slot-name) (instance)
>           (aref instance ,slot-index))))

-- 
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: Sacha
Subject: Re: inlining and (compile
Date: 
Message-ID: <4Wq5i.195532$cA7.1371192@phobos.telenet-ops.be>
Barry Margolin wrote:
> In article <························@r3g2000prh.googlegroups.com>,
>  Joe Marshall <··········@gmail.com> wrote:
> 
>> On May 24, 10:36 am, Sacha <····@address.spam> wrote:
>>> Hello all,
>>>
>>> I'm in a quest to make functional data structures, with referencial
>>> transparency. In the process i had to define a record structure, which
>>> is based on arrays.
>>>
>>> The whole thing is easy with macros, but i'd like to have a functional
>>> interface underlying those macros. (as record types need to be redefined
>>> dynamically when one of their "superclass" is redefined)
>>>
>>> Defining accessors from the functional interface is trivial using the
>>> compile function. But i would like those accessors to be inlined as well.
>>>
>>> so i did something like this :
>>>
>>> (defun make-accessor (class-name slot-name slot-index)
>>>    (eval `(declaim (inline ,(slot-name class-name slot-name))))
> 
> Use PROCLAIM instead of EVAL of DECLAIM:
> 
> (proclaim `(inline ,(slot-name class-name slot-name)))
> 


Thanks you =P

Now the last question remains : how do i make sure the inlining actually 
works (beside decompiling) ?

Sacha
From: Pascal Bourguignon
Subject: Re: inlining and (compile
Date: 
Message-ID: <87bqg9k6hi.fsf@thalassa.lan.informatimago.com>
Sacha <····@address.spam> writes:

> Barry Margolin wrote:
>> In article <························@r3g2000prh.googlegroups.com>,
>>  Joe Marshall <··········@gmail.com> wrote:
>> 
>>> On May 24, 10:36 am, Sacha <····@address.spam> wrote:
>>>> Hello all,
>>>>
>>>> I'm in a quest to make functional data structures, with referencial
>>>> transparency. In the process i had to define a record structure, which
>>>> is based on arrays.
>>>>
>>>> The whole thing is easy with macros, but i'd like to have a functional
>>>> interface underlying those macros. (as record types need to be redefined
>>>> dynamically when one of their "superclass" is redefined)
>>>>
>>>> Defining accessors from the functional interface is trivial using the
>>>> compile function. But i would like those accessors to be inlined as well.
>>>>
>>>> so i did something like this :
>>>>
>>>> (defun make-accessor (class-name slot-name slot-index)
>>>>    (eval `(declaim (inline ,(slot-name class-name slot-name))))
>> Use PROCLAIM instead of EVAL of DECLAIM:
>> (proclaim `(inline ,(slot-name class-name slot-name)))
>> 
>
>
> Thanks you =P
>
> Now the last question remains : how do i make sure the inlining
> actually works (beside decompiling) ?

Reading the doc of your implementation, and seeing what guarantee they
give about inlining.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Sacha
Subject: Re: inlining and (compile
Date: 
Message-ID: <Wtr5i.195572$sz7.967740@phobos.telenet-ops.be>
Pascal Bourguignon wrote:
> Sacha <····@address.spam> writes:
> 
>> Barry Margolin wrote:
>>> In article <························@r3g2000prh.googlegroups.com>,
>>>  Joe Marshall <··········@gmail.com> wrote:
>>>
>>>> On May 24, 10:36 am, Sacha <····@address.spam> wrote:
>>
>> Now the last question remains : how do i make sure the inlining
>> actually works (beside decompiling) ?
> 
> Reading the doc of your implementation, and seeing what guarantee they
> give about inlining.
> 

Haha well ok, not quite the answer i expected but thanks anyways.

Sacha
From: Barry Margolin
Subject: Re: inlining and (compile
Date: 
Message-ID: <barmar-471990.21090925052007@comcast.dca.giganews.com>
In article <·······················@phobos.telenet-ops.be>,
 Sacha <····@address.spam> wrote:

> Pascal Bourguignon wrote:
> > Sacha <····@address.spam> writes:
> > 
> >> Barry Margolin wrote:
> >>> In article <························@r3g2000prh.googlegroups.com>,
> >>>  Joe Marshall <··········@gmail.com> wrote:
> >>>
> >>>> On May 24, 10:36 am, Sacha <····@address.spam> wrote:
> >>
> >> Now the last question remains : how do i make sure the inlining
> >> actually works (beside decompiling) ?
> > 
> > Reading the doc of your implementation, and seeing what guarantee they
> > give about inlining.
> > 
> 
> Haha well ok, not quite the answer i expected but thanks anyways.

What kind of answer DID you expect?  How can you tell anything about 
what the compiler does, except by decompiling?

As far as the Common Lisp spec is concerned, a valid implementation of 
COMPILE could work by expanding all macros and outputing code that calls 
EVAL on the resulting expression.  But no serious implementation would 
do this (although byte-compiling, as in Emacs Lisp, is not too much 
better), so you don't have to worry about it.

The same thing with inline functions.  Either an implementation supports 
them, in which case I'd expect it to do it all the time, or it doesn't.

-- 
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: Sacha
Subject: Re: inlining and (compile
Date: 
Message-ID: <FZL5i.197311$oo.1311845@phobos.telenet-ops.be>
Barry Margolin wrote:
> In article <·······················@phobos.telenet-ops.be>,
>  Sacha <····@address.spam> wrote:
> 
>> Pascal Bourguignon wrote:
>>> Sacha <····@address.spam> writes:
>>>
>>>> Barry Margolin wrote:
>>>>> In article <························@r3g2000prh.googlegroups.com>,
>>>>>  Joe Marshall <··········@gmail.com> wrote:
>>>>>
>>>>>> On May 24, 10:36 am, Sacha <····@address.spam> wrote:
>>>> Now the last question remains : how do i make sure the inlining
>>>> actually works (beside decompiling) ?
>>> Reading the doc of your implementation, and seeing what guarantee they
>>> give about inlining.
>>>
>> Haha well ok, not quite the answer i expected but thanks anyways.
> 
> What kind of answer DID you expect?  How can you tell anything about 
> what the compiler does, except by decompiling?
> 
> As far as the Common Lisp spec is concerned, a valid implementation of 
> COMPILE could work by expanding all macros and outputing code that calls 
> EVAL on the resulting expression.  But no serious implementation would 
> do this (although byte-compiling, as in Emacs Lisp, is not too much 
> better), so you don't have to worry about it.
> 
> The same thing with inline functions.  Either an implementation supports 
> them, in which case I'd expect it to do it all the time, or it doesn't.
> 

yep this makes sense ...
Anyways i had warnings all over the place telling me the inline 
expansion wasn't available... so i guess that's not working =(

Sacha
From: Sacha
Subject: Re: inlining and (compile
Date: 
Message-ID: <cTq5i.195528$lp.1320003@phobos.telenet-ops.be>
Joe Marshall wrote:

> That's weird.  Why not a macro?
> 
>  (defmacro make-accessor (class-name slot-name slot-index)
>    `(progn
>        (declaim (inline ,(slot-name class-name slot-name)))
>        (defun ,(slot-name class-name slot-name) (instance)
>           (aref instance ,slot-index))))
> 


Let's say i have a class foo deriving from bar, bar has 3 slots.
so the first slot of foo will be (aref instance 3)

now i redefine bar so that it has 4 slots ... now the first slot of foo 
is at (aref instance 4) ... so i need to recompile slot definitions for 
all derived instances of bar.

Using a macro, i would end up with a macro expansion about foo in the 
file concerning bar ... that doesn't sound right, hence the functional 
interface.


Sacha
From: Barry Margolin
Subject: Re: inlining and (compile
Date: 
Message-ID: <barmar-D8D1CC.21265124052007@comcast.dca.giganews.com>
In article <·······················@phobos.telenet-ops.be>,
 Sacha <····@address.spam> wrote:

> Joe Marshall wrote:
> 
> > That's weird.  Why not a macro?
> > 
> >  (defmacro make-accessor (class-name slot-name slot-index)
> >    `(progn
> >        (declaim (inline ,(slot-name class-name slot-name)))
> >        (defun ,(slot-name class-name slot-name) (instance)
> >           (aref instance ,slot-index))))
> > 
> 
> 
> Let's say i have a class foo deriving from bar, bar has 3 slots.
> so the first slot of foo will be (aref instance 3)
> 
> now i redefine bar so that it has 4 slots ... now the first slot of foo 
> is at (aref instance 4) ... so i need to recompile slot definitions for 
> all derived instances of bar.

Is there a good reason you're not using CL's built-in object system, 
rather than rolling your own and reinventing these wheels?

-- 
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: Sacha
Subject: Re: inlining and (compile
Date: 
Message-ID: <Isr5i.195570$721.1372226@phobos.telenet-ops.be>
Barry Margolin wrote:
> In article <·······················@phobos.telenet-ops.be>,
>  Sacha <····@address.spam> wrote:
> Is there a good reason you're not using CL's built-in object system, 
> rather than rolling your own and reinventing these wheels?
> 

Not quite a good reason.
First and foremost, for the hell of it ! have fun, learn new concepts, 
see how it's done.

Then there is a long term goal.

I have this application consuming lots and lots of memory, maintaining 
tons of objects .... every now and then i need to serialize those to 
disk, and the whole thing blocks until serialization is done. This is 
quite a problem for a service which is supposed to be available at all 
times.

I figured it would be nice to have the whole data model defined as 
purely functional so that i could pass the current root object to a 
thread for serialization, and keep using the structure and "updating" it 
without waiting for the end of serialization.

Then i'd get all the goodies that come with it, easy transactions, 
non-blocking read from any thread and so on.

So i plundered the Haskell library source code for Data.Map ...a purely 
functional binary balanced tree, but my CLOS implementation was really 
performing poorly compared to other non-functional implementations. So i 
tested this with arrays for nodes and a couple macros to make it look 
quite like clos objects. There my implementation was performing as well 
as non-functional ones i could find.

So there it is, i want to have this _very lightweight_ record system, 
and already started building around it, having great fun in the process =P

I could have been using Haskell for this, but i miss the lisp syntax and 
the macro system as soon as i go see elsewhere now ... damn you all for 
this !

Sacha
From: Thomas F. Burdick
Subject: Re: inlining and (compile
Date: 
Message-ID: <1180075979.143312.142430@x35g2000prf.googlegroups.com>
On May 25, 4:02 am, Sacha <····@address.spam> wrote:

> So i plundered the Haskell library source code for Data.Map ...a purely
> functional binary balanced tree, but my CLOS implementation was really
> performing poorly compared to other non-functional implementations. So i
> tested this with arrays for nodes and a couple macros to make it look
> quite like clos objects. There my implementation was performing as well
> as non-functional ones i could find.
>
> So there it is, i want to have this _very lightweight_ record system,
> and already started building around it, having great fun in the process =P

Common Lisp comes with heavier-weight objects via defclass/make-
instance, and lighter-weight ones via defstruct.  SBCL (and CMUCL)
even have very nice semantics defined for what happens when you
incompatibly redefine a structure class.  It also allows you to
specify representation as a vector or a list, but I think that's a bit
of an anachronism.
From: Joe Marshall
Subject: Re: inlining and (compile
Date: 
Message-ID: <1180116301.573561.50160@n15g2000prd.googlegroups.com>
On May 24, 6:22 pm, Sacha <····@address.spam> wrote:
> Joe Marshall wrote:
> > That's weird.  Why not a macro?
>
> >  (defmacro make-accessor (class-name slot-name slot-index)
> >    `(progn
> >        (declaim (inline ,(slot-name class-name slot-name)))
> >        (defun ,(slot-name class-name slot-name) (instance)
> >           (aref instance ,slot-index))))
>
> Let's say i have a class foo deriving from bar, bar has 3 slots.
> so the first slot of foo will be (aref instance 3)
>
> now i redefine bar so that it has 4 slots ... now the first slot of foo
> is at (aref instance 4) ... so i need to recompile slot definitions for
> all derived instances of bar.
>
> Using a macro, i would end up with a macro expansion about foo in the
> file concerning bar ... that doesn't sound right, hence the functional
> interface.

I think this will turn out to be the least of your problems.

If you redefine bar, you not only have to recompile all the accessors
for every class derived from bar, but you also have to figure out what
to do with the old instances of those classes (which will not be
morphologically the same) *and* recompile every function that inlined
the old accessors (I don't know *how* you'd enumerate these).
From: Sacha
Subject: Re: inlining and (compile
Date: 
Message-ID: <tYL5i.197309$sm4.1183885@phobos.telenet-ops.be>
Joe Marshall wrote:
> On May 24, 6:22 pm, Sacha <····@address.spam> wrote:
>> Joe Marshall wrote:
>>> That's weird.  Why not a macro?
>>>  (defmacro make-accessor (class-name slot-name slot-index)
>>>    `(progn
>>>        (declaim (inline ,(slot-name class-name slot-name)))
>>>        (defun ,(slot-name class-name slot-name) (instance)
>>>           (aref instance ,slot-index))))
>> Let's say i have a class foo deriving from bar, bar has 3 slots.
>> so the first slot of foo will be (aref instance 3)
>>
>> now i redefine bar so that it has 4 slots ... now the first slot of foo
>> is at (aref instance 4) ... so i need to recompile slot definitions for
>> all derived instances of bar.
>>
>> Using a macro, i would end up with a macro expansion about foo in the
>> file concerning bar ... that doesn't sound right, hence the functional
>> interface.
> 
> I think this will turn out to be the least of your problems.
> 
> If you redefine bar, you not only have to recompile all the accessors
> for every class derived from bar, but you also have to figure out what
> to do with the old instances of those classes (which will not be
> morphologically the same) *and* recompile every function that inlined
> the old accessors (I don't know *how* you'd enumerate these).
> 
> 
for the instances of old class i can do with it, scratch the data start 
anew ... but yeah i didn't think about the inlined code ... so much for 
inlining then!

Sacha