[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.lisp

inline declaration of local functions

Helmut Jarausch

4/9/2015 8:59:00 AM

Hi,

how can I declare a local function as inline.

The following code gives a warning that 'foo' in the declare
declaration is unknown - why, and how to fix this?

Many thanks for a hint,
Helmut

(flet ((foo (parm)
(declare (inline foo)) ;;; <<<< style warning undefined function FOO
(print parm)))
(print (foo "hello")))
45 Answers

Pascal Costanza

4/9/2015 9:06:00 AM

0

On 09/04/2015 10:59, jarausch@skynet.be wrote:
> Hi,
>
> how can I declare a local function as inline.
>
> The following code gives a warning that 'foo' in the declare
> declaration is unknown - why, and how to fix this?
>
> Many thanks for a hint,
> Helmut
>
> (flet ((foo (parm)
> (declare (inline foo)) ;;; <<<< style warning undefined function FOO
> (print parm)))
> (print (foo "hello")))

The declaration has to be in the correct scope:

(flet ((foo (parm) (print parm)))
(declare (inline foo))
(print (foo "hello")))

The style warning is actually correct: Inside the function foo there is
no (other) function foo visible that could be inlined.

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.

Luut

4/9/2015 10:28:00 AM

0

Pascal Costanza wrote:
> On 09/04/2015 10:59, jarausch@skynet.be wrote:

>> The following code gives a warning that 'foo' in the declare
>> declaration is unknown - why, and how to fix this?
>>
>> (flet ((foo (parm)
>> (declare (inline foo)) ;;; <<<< style warning undefined function FOO
>> (print parm)))
>> (print (foo "hello")))
>
> The declaration has to be in the correct scope:
>
> (flet ((foo (parm) (print parm)))
> (declare (inline foo))
> (print (foo "hello")))

Alternatively, use LABELS instead of FLET. (In my humble opinion,
LABELS is what you want 99% of the time anyway.)

Pascal J. Bourguignon

4/9/2015 10:51:00 AM

0

Luut <luut@example.com> writes:

> Pascal Costanza wrote:
>> On 09/04/2015 10:59, jarausch@skynet.be wrote:
>
>>> The following code gives a warning that 'foo' in the declare
>>> declaration is unknown - why, and how to fix this?
>>>
>>> (flet ((foo (parm)
>>> (declare (inline foo)) ;;; <<<< style warning undefined function FOO
>>> (print parm)))
>>> (print (foo "hello")))
>>
>> The declaration has to be in the correct scope:
>>
>> (flet ((foo (parm) (print parm)))
>> (declare (inline foo))
>> (print (foo "hello")))
>
> Alternatively, use LABELS instead of FLET. (In my humble opinion,
> LABELS is what you want 99% of the time anyway.)

That wouldn't help at all. Declaring foo inline in a labels inside the
function foo doesn't serve any purpose, because you cannot inline
recursive function calls! And since there would be no declaration
outside of the function, it would never be inlined. And again, even
outside, it would serve no purpose to declare a recursive function
inline, since you cannot inline recursive function calls! Therefore it
is completely useless and counter productive to use LABELS when the
purpose is to have an inline function call.

--
__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

Luut

4/9/2015 11:22:00 AM

0

Pascal J. Bourguignon wrote:
> Luut <luut@example.com> writes:

>> Alternatively, use LABELS instead of FLET. (In my humble opinion,
>> LABELS is what you want 99% of the time anyway.)
>
> That wouldn't help at all. Declaring foo inline in a labels inside the
> function foo doesn't serve any purpose, because you cannot inline
> recursive function calls! And since there would be no declaration
> outside of the function, it would never be inlined.

Nope. Its a bound declaration that has the same scope as the function
binding.

Helmut Jarausch

4/9/2015 11:35:00 AM

0

On Thursday, 9 April 2015 12:59:21 UTC+2, informatimago wrote:
>
> That wouldn't help at all. Declaring foo inline in a labels inside the
> function foo doesn't serve any purpose, because you cannot inline
> recursive function calls! And since there would be no declaration
> outside of the function, it would never be inlined. And again, even
> outside, it would serve no purpose to declare a recursive function
> inline, since you cannot inline recursive function calls! Therefore it
> is completely useless and counter productive to use LABELS when the
> purpose is to have an inline function call.
>

Hi Pascal,
why is 'get-key' a recursive function?
This function is just as if

(defun get-key (Node Node-key-fct)
(funcall (Node-key-fct) Node))
and Node-key-fct is an accessor function generated by defstruct.

And such accessor functions are prefect for inlining as C++ will do all over the place.
Helmut

Helmut Jarausch

4/9/2015 11:39:00 AM

0

On Thursday, 9 April 2015 12:28:53 UTC+2, Luut wrote:
> Pascal Costanza wrote:

> > The declaration has to be in the correct scope:
> >
> > (flet ((foo (parm) (print parm)))
> > (declare (inline foo))
> > (print (foo "hello")))
>
> Alternatively, use LABELS instead of FLET. (In my humble opinion,
> LABELS is what you want 99% of the time anyway.)

Many thanks, it works just fine, and the function is inline as disassemble shows.

Still, I don't understand why with LABELS the function is known within its
own definition while this is not the case with FLET.

Helmut

Luut

4/9/2015 11:45:00 AM

0

jarausch@skynet.be wrote:
> why is 'get-key' a recursive function?

It isn't. Some people, Pascal (probably) included, hold a stylistic
preference that says you (only) use LABELS if you're defining
(mututally) recursive functions, FLET otherwise.

So Pascal's objection was (probably) not directed at your code, but at
my stylistic preference that says: use LABELS as the default and only
use FLET to explicitly "capture and shadow" a function definition in
an enclosing lexical scope.

(The reasoning, btw, is that (mutual) recursion is quite normal in
Lisp while the capture-and-shadow shehanigans that FLET allows are
comparatively rare and potentially confusing.)

Pascal J. Bourguignon

4/9/2015 12:50:00 PM

0

jarausch@skynet.be writes:

> On Thursday, 9 April 2015 12:28:53 UTC+2, Luut wrote:
>> Pascal Costanza wrote:
>
>> > The declaration has to be in the correct scope:
>> >
>> > (flet ((foo (parm) (print parm)))
>> > (declare (inline foo))
>> > (print (foo "hello")))
>>
>> Alternatively, use LABELS instead of FLET. (In my humble opinion,
>> LABELS is what you want 99% of the time anyway.)
>
> Many thanks, it works just fine, and the function is inline as disassemble shows.
>
> Still, I don't understand why with LABELS the function is known within its
> own definition while this is not the case with FLET.

Because that's the way FLET and LABELS are specified, and their specific
purposes.

--
__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

Kaz Kylheku

4/9/2015 1:40:00 PM

0

On 2015-04-09, jarausch@skynet.be <jarausch@skynet.be> wrote:
> Hi,
>
> how can I declare a local function as inline.
>
> The following code gives a warning that 'foo' in the declare
> declaration is unknown - why, and how to fix this?

That is the raison d' etre for flet.

Flet defines lexical functions in such a way that their names are not scoped
over their own interior.

(flet ((x () x is not visible here))
x is visible here)

Contrast with:

(labels ((x () x and y are visible here)
(y () x and y are visible here))
x and y are visible here)

Why is flet useful? You can use it to wrap outer functions with inner
redefinitions of the same name.

Kaz Kylheku

4/9/2015 1:50:00 PM

0

On 2015-04-09, Luut <luut@example.com> wrote:
> Pascal Costanza wrote:
>> On 09/04/2015 10:59, jarausch@skynet.be wrote:
>
>>> The following code gives a warning that 'foo' in the declare
>>> declaration is unknown - why, and how to fix this?
>>>
>>> (flet ((foo (parm)
>>> (declare (inline foo)) ;;; <<<< style warning undefined function FOO
>>> (print parm)))
>>> (print (foo "hello")))
>>
>> The declaration has to be in the correct scope:
>>
>> (flet ((foo (parm) (print parm)))
>> (declare (inline foo))
>> (print (foo "hello")))
>
> Alternatively, use LABELS instead of FLET. (In my humble opinion,
> LABELS is what you want 99% of the time anyway.)

99% of the time it doesn't matter because the local function is neither
recursive, nor does it have to call another function of the same name
in an outer scope.

Arguably, when it doesn't matter, it seems that there is nevertheless some
justification in choosing the variant with a less encompassing scope. Or maybe
the one with the shorter name.

For instance, when it doesn't matter, you probably use LET rather than LET*.
Why expose forms to scopes that they don't need, right? Though if the names
of these two were reversed, you might still choose LET over LET* because of the
shorter name. FLET is also a nice name, not only a short one: function-let.

When it does matter, you want FLET about 100% of the time when a local function
FOO must call an outer function FOO, and you want LABELS 100% of the time when
a local function must call itself, or when two or more are mutually recursive.

(If you need to do both, you can split the function into a recursive part
with LABELS which has a different name, and a FLET interface to that.)