[eeps] allow external function as literals

Richard A. O'Keefe ok@REDACTED
Fri Oct 3 05:03:56 CEST 2014


On 2/10/2014, at 7:36 PM, Tony Rogvall wrote:

> 
> On 2 okt 2014, at 01:02, Richard A. O'Keefe <ok@REDACTED> wrote:
> 
>> 
>> On 2/10/2014, at 10:55 AM, Tony Rogvall wrote:
>>> In a toy project
>> 
>> The obvious questions are
> 
> Not at all obvious to me.
> 
>> (1) Do we really have a problem?
> 
> My obvious question is who are we?

The subscribers to this list, who else?
> 
>> (2) If we have a problem, is *this* the problem we really have?
>> 
> Yes we have, regardless of who we are.

The point of my message was that I think the answer
is a resounding *NO*.

The problem is not that external function references are
not *LITERALS* but that they are *evaluated more than once*.
These are markedly different properties.

It is perfectly possible for a language to have syntactic
forms that anyone would think of as literals, but which
allocate new space every time they are evaluated.  For
example, in Eiffel, string literals are like this.  It is
also perfectly possible for a language to have syntactic
forms that are obviously *not* literals, but which are
evaluated at most once.  For example, in C, 1+1 is not a
literal, but it _is_ evaluated at most once.

SO no, the problem is definitely *not* that external
functions are not literals, but that they (and therefore
data structures including them) are re-evaluated whenever
they are encountered.

And this means that we are dealing with quite a general
problem, which could be dealt with by a *single*
(conceptually) simple general mechanism, rather than by
a patch here, a patch there, and a plethora of patches
over there.  Not only that, we can swipe the mechanism
we need from other languages where it has a proven record
of working quite nicely.

Eiffel has 'once' functions.  Some functional languages have
lazily evaluated CAFs.  They are basically the same idea.
Wait until the value is requested, *then* evaluate it, and
save the result.

This mechanism lets us compute sets and dictionaries once.
It would even let us accept in-line funs, which are clearly
not literals by any reading.

> 
>> Ad 1, why does it *matter* whether tuples containing
>> fun mod:nam/ari terms are compiled as stored-once literals
>> or not?  What is the measured difference it makes to the
>> performance of a realistic program?
> 
> I guess the answer is yes in at least two ways.
> 
> The produced code is not a literal, as I tried to explain.
> The performance impact is enormous.

You have not provided any evidence to support that claim.

> The term is built every call and I had intend to do a lot of them.

That was obvious.  What was not and is not obvious is whether
that overhead matters *in context*.
> 
>> 
>> As far as I know, {Module,Name} pairs still work as 
>> functions:
>> 
>> 1> F = {erlang,now}.
>> 2> F().
>> 
> The answer is NO. The extern fun is nothing close to this

What extern funs are close to is irrelevant.
The question is what difference it makes to
*measured* performance of the *whole* program.

> (I am just joking), is is close
> but it is much more efficient since it creates and export entry (check internals if you like)
> that is ready to be used and does not have to lookup the function every time.

My experience here is with Prolog implementation, but I know
from experience that it possible to ameliorate *that* lookup.
For example, the Prolog equivalent would be 
	call(F, Y1, Y2)
where F = mod:pred(X1).  It's possible to implement that
with just two switches and a jump. 

>> So you could replace fun ffe:docol/4 by {ffe,docol}.
>> What difference does it make?
>> 
> As explained above, a lot.

No.  As *asserted* without any supporting *measurements*, yes.
You have provided the already obvious reasons why it is
*plausible* that the overheads might be high, but no numbers.

Depending on what else is going on in your program, it is
just as plausible that the difference might be unnoticeable.

Example: I've just been reading a paper about Hop, Michael
Serrano's web server/language based on Bigloo.  Bigloo runs
about twice as slowly as C, but for static pages, Hop and
Apache were hard to tell apart.  (For dynamic pages, Hop was
better.)

>> Ad 2, perhaps what we *really* want is an analogue of
>> Eiffel's "once" features, or the pthread_once() function
>> in POSIX.  Here's what I have in mind.
>> 
> This is a really bad idea.

Why?  It is an idea that has been proven in practice
over nearly 30 years.  Unlike your proposal, it is not
ad hoc: it addresses the *general* issue.  It isn't even
new to functional languages.

> Why add extra declaration to a language

It's an optimisation, just like -inline (which did not always
exist in Erlang).  It's *only* an optimisation.  It provides
information that cannot be had any other way.

> 
> No. We do not need this! This is like an initialization of a static variable in C code?

What variable?  It's just a function whose body doesn't
get re-evaluated.

By the way, to revert to the original message,
why do you need a tuple?

What a tuple provides is a length and a bunch of
elements identified by numbers.  So what about

'_ffe_sqr'(n) -> 6;
'_ffe_sqr'(1) -> 0;
'_ffe_sqr'(2) -> <<"sqr">>;
'_ffe_sqr'(3) -> fun ffe:docol/4;
'_ffe_sqr'(4) -> fun ffe:dupe/0;
'_ffe_sqr'(5) -> fun ffe:star/0;
'_ffe_sqr'(6) -> fun ffe:semis/0.

'_ffe_sum'( n) -> 11;
'_ffe_sum'( 1) -> 0;
'_ffe_sum'( 2) -> <<"sum">>;
'_ffe_sum'( 3) -> fun ffe:docol/4;
'_ffe_sum'( 4) -> fun ffe:lit/0;
'_ffe_sum'( 5) -> 1;
'_ffe_sum'( 6) -> fun ffe:pdqo/0;
'_ffe_sum'( 7) -> 4;
'_ffe_sum'( 8) -> fun ffe:plus/0;
'_ffe_sum'( 9) -> fun ffe:ploop/0;
'_ffe_sum'(10) -> -2;
'_ffe_sum'(11) -> fun ffe:semis/0.

With your scheme,
   Size = tuple_size('_ffe_sum'()),
   Fun  = element(Size, '_ffe_sum'())
will take constant time.

With the encoding above,
   Size = '_ffe_sum'(n),
   Fun  = '_ffe_sum'(Size)
takes constant time right now.

It is impossible to tell whether any detectable
loss of performance relative to your special-case
hack would arise without knowing what your program
needs to *do* with the tuples, other than look things
up in them.


> 
> /Tony
> 




More information about the eeps mailing list