# RFC __autodefine / spl_autodefine

- Thread: https://externals.io/message/50877
- Original archive: https://news-web.php.net/php.internals/50877
- Started by Loon on 2010-12-06T19:38:56+00:00
- Messages: 9
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #50877 — Loon — 2010-12-06T19:38:56+00:00

URL: https://externals.io/message/50877#50877

RFC __autodefine / spl_autodefine

This proposal proposes to introduce one function for automagically
defining missing definitions at run time.
The reader should have a reasonable level of PHP knowledge and
computer languages when reading this proposal.
Note: Whenever __autodefine is used, also spl_autodefine is meant.

Current situation

PHP currently supports defining missing classes by the __autoload function.
This solution mimics the class loader concept from Java.
Once defined, undefined class functions (methods) can be emulated by
using __call and __callStatic.
It can be argued that __autoload is enough for the future if the
future is object-oriented.


Proposition

While very useful in its own right __autoload is limited: only classes
can be loaded dynamically.
However, there is still a lot of code that is either mixed functional
and object-oriented or only functional.
Excluding that code from such a solution makes life very hard on
everyone maintaining mixed code bases.
It is understandable that by denying this function to non-object
oriented code an incentive exists for maintainers and developers to
switch to object-oriented programming.
Although understandable it is not acceptable, for the following reasons:
1) There are enough people maintaining and writing code in a perfect
manner that do not grasp object orientation
2) Any large code base should have the possibility to slowly migrate
and not be coerced into an object oriented way of working
3) Even if this coercion would work, it would not guarantee the
solution is object-oriented, only that it is coded in classes

So, it can be stated that a number of language constructs are missing
the option to autoload.

From a conceptual point, tokens in a sequence of statements refer to
definitions. The implementation of almost all run time environments
demands that a definition exists before first referenced. __autoload
changed this rule by allowing classes to be defined when the execution
of a statement hits on an undefined class. This behaviour should be
generalized.

Generally, it can be said that PHP needs a mechanism for automagically
defining undefined elements. The proposed name for that function is
__autodefine. The parameters to this function would be $name and
$type. The type parameter would refer to all the existing elements
that are defined. Probably the maximal set of language constructs that
could be supported are: T_ARRAY, T_CLASS, T_CLASS_C, T_CONST,
 `T_FUNCTION` T_FUNC_C, T_INCLUDE, T_INCLUDE_ONCE, T_INTERFACE,
T_METHOD_C, T_NAMESPACE, T_NS_C, T_REQUIRE, T_REQUIRE_ONCE, T_USE,
T_VAR, T_VARIABLE. The author believes the minimal solution should
support at least T_FUNCTION, T_CLASS, `T_INTERFACE` and include
(T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE). Namespaces
will be part of the name as is the case in call_user_func.

The relation with the current implementation is that __autoload equals
__autodefine( $name, `T_CLASS` ) with the exception of the optional
file_extensions parameter. __autoload need not be changed and
__autodefine can live alongside __autoload. Author believes __autoload
should be marked 'deprecated'.


Minimal solution proposal

  __autodefine( $name, $type )

  $name is the string of the missing definition

  $type is the integer identification of the type and defined by constants.


  $type constant            $name format
                        name examples

  `T_FUNCTION`             [namespace][class name][::|->]function name
a\b\foo, System::boot, SomeClass->getWidth
  `T_CLASS`                   [namespace]class name
   Image, ns\Image
  `T_INTERFACE`           [namespace]class name           Image, ns\Image
  `T_INCLUDE`                file name
  somefile, ../somefile, \includes\Somefile
  `T_INCLUDE_ONCE`  file name
somefile, ../somefile, \includes\Somefile
  `T_REQUIRE`                file name
  somefile, ../somefile, \includes\Somefile
  `T_REQUIRE_ONCE`  file name
somefile, ../somefile, \includes\Somefile


Code examples

  foo(b);            // __autodefine( 'foo', `T_FUNCTION` )

  p = new PHP();     // __autodefine( 'PHP', `T_CLASS` )

  include 'piece'    // __autodefine( 'piece', `T_INCLUDE` )

  ons\foo();         // __autodefine( 'ons\foo', `T_FUNCTION` )

  p->im();           // __autodefine( 'PHP->im', `T_FUNCTION` )

  p->cm();           // __autodefine( 'PHP::cm', `T_FUNCTION` )


Advantages

A whole new array of possibilities opens up for managing code, both at
run time and both at design time (development). Code is no longer
bound to file containers. Small pieces of code can exist on their own.
At run time only the code pieces that are needed for execution are
defined. No longer parsing of complete files when only 5 code lines
will be executed. A parse error in a file not relevant to the piece of
code that will be executed will not prevent execution anymore. By
splitting code up, developers can work side by side on the same code
base, every developer on  a set of code pieces, much smaller than the
files now and thus reducing (locking) conflicts. Code pieces can be
tested standalone and accepted. Progress is measurable on function
level. Requirements can be tied to their functions. Basically, a lot
of metafunctions are suddenly possible because splitting up code in
smaller pieces has become a workable solution. Code could be for
example managed like in a wiki, with page (= code piece) revisions
etc. If needed the code pieces can be assembled into any number of
files for delivery. An extreme solution is assembling all the code
pieces into a zip file and having a run time implementation of
__autodefine that picks definitions from a zip file. While the same
code is available during development in a wiki. Large codebases can be
split up over time into more manageable pieces giving the developers
renewed control over their application. The __autodefine function will
enable all sorts of new ways of managing code and work processes.
Security can be enhanced enormously as it is not common anymore where
definitions will come from and how they are decrypted. Even if someone
gets access to the source code (outside the web root), it might be
scrambled. Also insight into the system can be obtained by observing
definition patterns that can be gathered during the autodefine
processing.


Disadvantages

Initially execution may be slower. However, this can be countered with
different implementations for __autodefine at production time and
development time. The author also believes that others will find ways
to counter this disadvantage by using caching or keeping definitions
in memory inbetween executions.


Conclusion

The minimal solution to support all definitions would be the function
__autodefine( $name, $type ). From there on, every developer can
determine his/her own strategy for automagically defining
implementations. The __autodefine function enables developers to split
code up into smaller pieces as before while at the same time make it
manageable by removing the need to include all these functions. By
splitting code up in smaller pieces more developers can work together
on one (1) code base. A parse error in a function that is not called
will not damage the run time as is the case in the current
implementation where many functions are grouped into files for reasons
of manageability. __autodefine also enables developers to utilize all
sorts of autodefinition mechanisms like retrieving definitions from
the file system, the network, a zip file or even a database. Even
multiple sources can be used, runtime versioning mechanisms can be
utilized, code decryption on the fly is possible. It would be even
interesting if the autodefinition could be in the form of byte codes.

The __autodefine function is generic enough that the same concept can
be applied in most other languages.

The request is to supply at least the minimal __autodefine in a very
near future version of PHP. To be complete and consistent spl_
autodefine_ call, spl_ autodefine_ extensions, spl_ autodefine_
functions, spl_ autodefine_ register, spl_ autodefine_ unregister and
spl_ autodefine should be defined (although considered not necessary
according to the author).

Reinier van Loon

---

## #50878 — Pierre Joye — 2010-12-06T19:40:51+00:00

URL: https://externals.io/message/50877#50878 · In reply to: #50877

hi,

Please put it in the wiki :)

On Mon, Dec 6, 2010 at 8:38 PM, Loon, Reinier van
<reinier.van.loon@gmail.com> wrote:
> RFC __autodefine / spl_autodefine
>
> This proposal proposes to introduce one function for automagically
> defining missing definitions at run time.
> The reader should have a reasonable level of PHP knowledge and
> computer languages when reading this proposal.
> Note: Whenever __autodefine is used, also spl_autodefine is meant.
>
> Current situation
>
> PHP currently supports defining missing classes by the __autoload function.
> This solution mimics the class loader concept from Java.
> Once defined, undefined class functions (methods) can be emulated by
> using __call and __callStatic.
> It can be argued that __autoload is enough for the future if the
> future is object-oriented.
>
>
> Proposition
>
> While very useful in its own right __autoload is limited: only classes
> can be loaded dynamically.
> However, there is still a lot of code that is either mixed functional
> and object-oriented or only functional.
> Excluding that code from such a solution makes life very hard on
> everyone maintaining mixed code bases.
> It is understandable that by denying this function to non-object
> oriented code an incentive exists for maintainers and developers to
> switch to object-oriented programming.
> Although understandable it is not acceptable, for the following reasons:
> 1) There are enough people maintaining and writing code in a perfect
> manner that do not grasp object orientation
> 2) Any large code base should have the possibility to slowly migrate
> and not be coerced into an object oriented way of working
> 3) Even if this coercion would work, it would not guarantee the
> solution is object-oriented, only that it is coded in classes
>
> So, it can be stated that a number of language constructs are missing
> the option to autoload.
>
> From a conceptual point, tokens in a sequence of statements refer to
> definitions. The implementation of almost all run time environments
> demands that a definition exists before first referenced. __autoload
> changed this rule by allowing classes to be defined when the execution
> of a statement hits on an undefined class. This behaviour should be
> generalized.
>
> Generally, it can be said that PHP needs a mechanism for automagically
> defining undefined elements. The proposed name for that function is
> __autodefine. The parameters to this function would be $name and
> $type. The type parameter would refer to all the existing elements
> that are defined. Probably the maximal set of language constructs that
> could be supported are: T_ARRAY, T_CLASS, T_CLASS_C, T_CONST,
> `T_FUNCTION` T_FUNC_C, T_INCLUDE, T_INCLUDE_ONCE, T_INTERFACE,
> T_METHOD_C, T_NAMESPACE, T_NS_C, T_REQUIRE, T_REQUIRE_ONCE, T_USE,
> T_VAR, T_VARIABLE. The author believes the minimal solution should
> support at least T_FUNCTION, T_CLASS, `T_INTERFACE` and include
> (T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE). Namespaces
> will be part of the name as is the case in call_user_func.
>
> The relation with the current implementation is that __autoload equals
> __autodefine( $name, `T_CLASS` ) with the exception of the optional
> file_extensions parameter. __autoload need not be changed and
> __autodefine can live alongside __autoload. Author believes __autoload
> should be marked 'deprecated'.
>
>
> Minimal solution proposal
>
>  __autodefine( $name, $type )
>
>  $name is the string of the missing definition
>
>  $type is the integer identification of the type and defined by constants.
>
>
>  $type constant            $name format
>                        name examples
>
>  T_FUNCTION             [namespace][class name][::|->]function name
> a\b\foo, System::boot, SomeClass->getWidth
>  T_CLASS                   [namespace]class name
>   Image, ns\Image
>  T_INTERFACE           [namespace]class name           Image, ns\Image
>  T_INCLUDE                file name
>  somefile, ../somefile, \includes\Somefile
>  T_INCLUDE_ONCE  file name
> somefile, ../somefile, \includes\Somefile
>  T_REQUIRE                file name
>  somefile, ../somefile, \includes\Somefile
>  T_REQUIRE_ONCE  file name
> somefile, ../somefile, \includes\Somefile
>
>
> Code examples
>
>  foo(b);            // __autodefine( 'foo', `T_FUNCTION` )
>
>  p = new PHP();     // __autodefine( 'PHP', `T_CLASS` )
>
>  include 'piece'    // __autodefine( 'piece', `T_INCLUDE` )
>
>  ons\foo();         // __autodefine( 'ons\foo', `T_FUNCTION` )
>
>  p->im();           // __autodefine( 'PHP->im', `T_FUNCTION` )
>
>  p->cm();           // __autodefine( 'PHP::cm', `T_FUNCTION` )
>
>
> Advantages
>
> A whole new array of possibilities opens up for managing code, both at
> run time and both at design time (development). Code is no longer
> bound to file containers. Small pieces of code can exist on their own.
> At run time only the code pieces that are needed for execution are
> defined. No longer parsing of complete files when only 5 code lines
> will be executed. A parse error in a file not relevant to the piece of
> code that will be executed will not prevent execution anymore. By
> splitting code up, developers can work side by side on the same code
> base, every developer on  a set of code pieces, much smaller than the
> files now and thus reducing (locking) conflicts. Code pieces can be
> tested standalone and accepted. Progress is measurable on function
> level. Requirements can be tied to their functions. Basically, a lot
> of metafunctions are suddenly possible because splitting up code in
> smaller pieces has become a workable solution. Code could be for
> example managed like in a wiki, with page (= code piece) revisions
> etc. If needed the code pieces can be assembled into any number of
> files for delivery. An extreme solution is assembling all the code
> pieces into a zip file and having a run time implementation of
> __autodefine that picks definitions from a zip file. While the same
> code is available during development in a wiki. Large codebases can be
> split up over time into more manageable pieces giving the developers
> renewed control over their application. The __autodefine function will
> enable all sorts of new ways of managing code and work processes.
> Security can be enhanced enormously as it is not common anymore where
> definitions will come from and how they are decrypted. Even if someone
> gets access to the source code (outside the web root), it might be
> scrambled. Also insight into the system can be obtained by observing
> definition patterns that can be gathered during the autodefine
> processing.
>
>
> Disadvantages
>
> Initially execution may be slower. However, this can be countered with
> different implementations for __autodefine at production time and
> development time. The author also believes that others will find ways
> to counter this disadvantage by using caching or keeping definitions
> in memory inbetween executions.
>
>
> Conclusion
>
> The minimal solution to support all definitions would be the function
> __autodefine( $name, $type ). From there on, every developer can
> determine his/her own strategy for automagically defining
> implementations. The __autodefine function enables developers to split
> code up into smaller pieces as before while at the same time make it
> manageable by removing the need to include all these functions. By
> splitting code up in smaller pieces more developers can work together
> on one (1) code base. A parse error in a function that is not called
> will not damage the run time as is the case in the current
> implementation where many functions are grouped into files for reasons
> of manageability. __autodefine also enables developers to utilize all
> sorts of autodefinition mechanisms like retrieving definitions from
> the file system, the network, a zip file or even a database. Even
> multiple sources can be used, runtime versioning mechanisms can be
> utilized, code decryption on the fly is possible. It would be even
> interesting if the autodefinition could be in the form of byte codes.
>
> The __autodefine function is generic enough that the same concept can
> be applied in most other languages.
>
> The request is to supply at least the minimal __autodefine in a very
> near future version of PHP. To be complete and consistent spl_
> autodefine_ call, spl_ autodefine_ extensions, spl_ autodefine_
> functions, spl_ autodefine_ register, spl_ autodefine_ unregister and
> spl_ autodefine should be defined (although considered not necessary
> according to the author).
>
> Reinier van Loon
>
> --
> 
> 
>
>



-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #50879 — Sebastian Bergmann — 2010-12-06T20:01:53+00:00

URL: https://externals.io/message/50877#50879 · In reply to: #50877

> Note: Whenever __autodefine is used, also spl_autodefine is meant.

  __autoload() should die (as in get deprecated ASAP and later removed),
  please do not add new __auto*() functions. Note that this does not mean
  that I agree or disagree with the functionality itself.

-- 
Sebastian Bergmann                    Co-Founder and Principal Consultant
http://sebastian-bergmann.de/                           http://thePHP.cc/

---

## #50883 — Ross Masters — 2010-12-07T00:59:08+00:00

URL: https://externals.io/message/50877#50883 · In reply to: #50879

Hi Sebastien,


> __autoload() should die (as in get deprecated ASAP and later removed)


I couldn't find anything about your opinions on this so I was wondering if
you could elaborate.  Do you consider autoloading as a bad practice or just
that spl_autoload_register should be used to add relevant
functions/closures?

Regards, Ross



> 
>
> > […]
>
>  __autoload() should die (as in get deprecated ASAP and later removed),
>  please do not add new __auto*() functions. Note that this does not mean
>  that I agree or disagree with the functionality itself.
>
> --
> Sebastian Bergmann                    Co-Founder and Principal Consultant
> http://sebastian-bergmann.de/                           http://thePHP.cc/
>
>
> --
> 
> 
>
> --
Ross Masters <ross@php.net>
http://rossmasters.com/

---

## #50884 — Larry Garfield — 2010-12-07T04:44:16+00:00

URL: https://externals.io/message/50877#50884 · In reply to: #50883

> Hi Sebastien,
> 
> > […]
> 
> I couldn't find anything about your opinions on this so I was wondering if
> you could elaborate.  Do you consider autoloading as a bad practice or just
> that spl_autoload_register should be used to add relevant
> functions/closures?

__autoload() works fine if you have exactly one implementation for your entire 
system with exactly one set of logic for how to map a class name to a file 
name.  As soon as you try to mix two different libraries together, fatal 
error.

 `spl_autoload()` does not suffer from this short-sighted problem but 
accomplishes the same goal in a much more robust fashion.

Any new meta-auto-load mechanism should forego the dead-end that is a single 
unique __auto*() function and just use a design that actually works, aka 
 `spl_autoload()` or similar.

With that said, I like the idea of generalizing autoload to include functions 
et al.  Autoloading functions would make my life a lot easier. :-)  To be 
fair, though, half of the potential benefits the OP listed are already solved 
by using a version control system.  Any version control system.  If you're 
still having collisions at the file level when two people work on the same 
file it's because you're an idiot and are not using version control (or the 
changes touch each other, in which case this proposal wouldn't help you 
anyway).

The main advantage of this proposal would be lazy-loading of functions.  I 
don't think autoloading methods makes any sense since classes cannot be split 
between files anyway.  

I'm not entirely sure what else is actually reasonable to autoload.  Classes, 
Interfaces, Functions, and Traits make up the scope of first-class code 
structures, don't they?  Autoloading a variable doesn't even make sense to me, 
and include files are already handled by include[_once].  

--Larry Garfield

---

## #50886 — Sebastian Bergmann — 2010-12-07T07:28:12+00:00

URL: https://externals.io/message/50877#50886 · In reply to: #50884

Am 07.12.2010 05:44, schrieb Larry Garfield:
> `spl_autoload()` does not suffer from this short-sighted problem but 
> accomplishes the same goal in a much more robust fashion.

 Exactly.

-- 
Sebastian Bergmann                    Co-Founder and Principal Consultant
http://sebastian-bergmann.de/                           http://thePHP.cc/

---

## #50910 — Loon — 2010-12-08T11:10:09+00:00

URL: https://externals.io/message/50877#50910 · In reply to: #50877

All, I made a RFC in the Wiki for autodefine.

http://wiki.php.net/rfc/autodefine

Cheers, Reinier

---

## #50911 — Loon — 2010-12-08T12:05:05+00:00

URL: https://externals.io/message/50877#50911 · In reply to: #50910

> __autoload() works fine if you have exactly one implementation for your entire
> system with exactly one set of logic for how to map a class name to a file
> name.  As soon as you try to mix two different libraries together, fatal
> error.
>
> `spl_autoload()` does not suffer from this short-sighted problem but
> accomplishes the same goal in a much more robust fashion.
>
> Any new meta-auto-load mechanism should forego the dead-end that is a single
> unique __auto*() function and just use a design that actually works, aka
> `spl_autoload()` or similar.

I see the problem. At projectpier.org we have the one code set situation.
Given the reactions, I will rewrite the RFC to use spl* functions with
the information supplied above.

> With that said, I like the idea of generalizing autoload to include functions
> et al.  Autoloading functions would make my life a lot easier. :-)

Yes, the alternative solution is to write a wrapper function:
somefunc($a, $b) becomes ppcall("somefunc", $a, $b)
Works but if we can get this in PHP itself it will be much better.

>To be fair, though, half of the potential benefits the OP listed are already solved
> by using a version control system.  Any version control system.  If you're
> still having collisions at the file level when two people work on the same
> file it's because you're an idiot and are not using version control (or the
> changes touch each other, in which case this proposal wouldn't help you
> anyway).

I disagree (but otoh, I am an idiot :-)). I just think there is no
conceptual need to group functions into a file.
I also don't believe in distributed vcs (probably idiotic again :-)).
The problem of integrating code is simply postponed with a dvcs.
At work we have good experiences with a centralized code repository
where people can work together, where backups are taken care of and
were revision history is built in. Integration issue are solved before
the code is touched.
Also, I think it is crazy I have to do a grep on a filesystem to find
out in which file a function is defined (e.g. grep -i -l "ion
pick_date_widget"). I know, documentation etc. But that argument only
works when a system is in good shape when you take over. Why can't I
just see by the file name what definition hides inside?

> The main advantage of this proposal would be lazy-loading of functions.
> I don't think autoloading methods makes any sense since classes cannot be split between files anyway.

I think I was not clear with my remark on __call and __callStatic. I
think autodefining of methods is already possible by using __call and
__callStatic for that. The __call is used in this example for
dynamically adding methods to a class:
http://www.php.net/manual/en/function.call-user-func.php#89636. The
same __call function can be used to dynamically add code to the class.
But I think it would be better if the run time would do this in a
uniform way via autodefine.
The minimal definition in my view for a class would be "class
SomeClass {}" or "class SomeClass;" . But then classes resemble
namespaces to much (but in my view a class can also be viewed as a
namespace for a set of variables and functions). This is however
getting to theoretical, so lets keep it simple and let's assume that
the minimal definition of a class should have its variables, like this
"class SomeClass { var a; var b; }" and that methods can be added
dynamically.

> I'm not entirely sure what else is actually reasonable to autoload.  Classes,
> Interfaces, Functions, and Traits make up the scope of first-class code
> structures, don't they?  Autoloading a variable doesn't even make sense to me,
> and include files are already handled by include[_once].

Autodefining variables does make sense. Suppose you have a variable
called "$language" which is an array with a lot of language items and
that you have put this array somewhere. Current practices forces you
think what the possible paths are how the variable is accessed and
then include this array at the proper places. So far so good. But
things change in time and code is added to the system and suddenly the
variable is referenced via a path which was not foreseen. Current
practice forces you to rethink the include locations. But what happens
in reality? Most people simply include all the files somewhere
upfront, just to be sure. Again a lot of code parsed and processed
which may not be executed. Wouldn't it be much more elegant to define
the variable when it is first referenced?
Of course, this could be emulated with a function that would be
autodefined, so that is why I chose the minimal solution to not have
variables autodefined.

But another interesting option for autodefining variables is that you
are able to track which variables are used in your application. The
fun thing is that you can do this in every environment. For
development it is interesting to see if you are using variables which
you don't recognize (typo's) or don't want to use (e.g.
$HTTP_POST_VARS), for testing it is interesting to see if your test
cases are using the most important variables and for production it is
interesting to see which variables are used at all and which never.
The paragraph above applies of course to all objects that can be
autodefined. As pointed out in the RFC, autodefine enables you to get
more insight and thus more control over your codebase.

The include and include_once are simply mentioned because they are
already identified by the parser. And there is a difference between
the two. Maybe you want to know that an include_once is called
multiple times to rethink the location of the include.

Thanks for all the feedback so far. It is much easier for me to react
to arguments and remarks then to come up with answers / ideas when
writing an RFC.

Cheers, Reinier

---

## #50918 — Larry Garfield — 2010-12-09T03:28:41+00:00

URL: https://externals.io/message/50877#50918 · In reply to: #50911

> > […]
> 
> Yes, the alternative solution is to write a wrapper function:
> somefunc($a, $b) becomes ppcall("somefunc", $a, $b)
> Works but if we can get this in PHP itself it will be much better.

Background: I am a Drupal developer.  We already call most of our functions 
indirectly via `call_user_func_array()`.  Please for the love of god don't add 
another slow function call on top of that which we'd need to use for lazy-
loading functions. :-)  

> > […]
> 
> I disagree (but otoh, I am an idiot :-)). I just think there is no
> conceptual need to group functions into a file.
> I also don't believe in distributed vcs (probably idiotic again :-)).
> The problem of integrating code is simply postponed with a dvcs.
> At work we have good experiences with a centralized code repository
> where people can work together, where backups are taken care of and
> were revision history is built in. Integration issue are solved before
> the code is touched.

I said nothing about a DVCS (although having worked with Git for the past year 
I have grown quite fond of it).  That is, however, irrelevant to the issue at 
hand.  You could use CVS and avoid the file-collision problem you describe.  
Hell, you could probably even use RCS if you wanted to be really retro/stupid.  
Any VCS that doesn't resolve the issue you describe (two people edit different 
parts of the same file and the changes need to be integrated) should be 
deleted outright for the good of mankind, and any project that is developed 
without the use of a VCS capable of doing so should be abandoned on the 
grounds that the team working on it doesn't know what they're doing.  Just 
sayin'. :-)

> Also, I think it is crazy I have to do a grep on a filesystem to find
> out in which file a function is defined (e.g. grep -i -l "ion
> pick_date_widget"). I know, documentation etc. But that argument only
> works when a system is in good shape when you take over. Why can't I
> just see by the file name what definition hides inside?

I am on the record stating that the Java-style class-per-file organization 
strategy is quite dumb in PHP.  To do one-function-per-file as well strikes me 
as ludicrous and is not at all a pattern we should be supporting.  I recall a 
colleague of mine once benchmarking a user-space implementation of such a 
strategy and the performance implications being horrific.  

As for knowing what functions are in a file, that's what a proper file name is 
for: foo.inc contains functions relating to the "foo" system.  If grep isn't 
your cup of tea, there's a half-dozen IDEs that are quite capable of "click to 
go to definition" functionality of some form.

Really, I'm in favor of function-level autoloading but you're making all of 
the wrong arguments to support it. :-)

> > […]
> 
> I think I was not clear with my remark on __call and __callStatic. I
> think autodefining of methods is already possible by using __call and
> __callStatic for that. The __call is used in this example for
> dynamically adding methods to a class:
> http://www.php.net/manual/en/function.call-user-func.php#89636. The
> same __call function can be used to dynamically add code to the class.
> But I think it would be better if the run time would do this in a
> uniform way via autodefine.
> The minimal definition in my view for a class would be "class
> SomeClass {}" or "class SomeClass;" . But then classes resemble
> namespaces to much (but in my view a class can also be viewed as a
> namespace for a set of variables and functions). This is however
> getting to theoretical, so lets keep it simple and let's assume that
> the minimal definition of a class should have its variables, like this
> "class SomeClass { var a; var b; }" and that methods can be added
> dynamically.

A class is not even remotely the same as a namespace.  A class is a data type.  
You can use a class as if it were a poor-man's namespace but that's just as 
much a hack as having parallel named functions that really ought to be methods 
and passing a by-convention-opaque data structure to them.  No, actually it's 
even more of a hack.  (Note: Sadly Drupal does the former far too often.  I'm 
working on ripping those out. <g>)

Also, __call() does not add a method to a class.  You cannot add a method to a 
class at runtime.  In PHP 5.4 you can (assuming this went in; I think it did) 
bind a closure to an object in a way that gets called like a method, but 
that's an entirely different animal.  Believe me, I've done some unholy things 
with __call() trying to emulate what you describe, and lazy-loading of methods 
is entirely irrelevant.

> > […]
> 
> Autodefining variables does make sense. Suppose you have a variable
> called "$language" which is an array with a lot of language items and
> that you have put this array somewhere. Current practices forces you
> think what the possible paths are how the variable is accessed and
> then include this array at the proper places. So far so good. But
> things change in time and code is added to the system and suddenly the
> variable is referenced via a path which was not foreseen. Current
> practice forces you to rethink the include locations. But what happens
> in reality? Most people simply include all the files somewhere
> upfront, just to be sure. Again a lot of code parsed and processed
> which may not be executed. Wouldn't it be much more elegant to define
> the variable when it is first referenced?
> Of course, this could be emulated with a function that would be
> autodefined, so that is why I chose the minimal solution to not have
> variables autodefined.

An application doesn't have variables.  A scope has variables.  A function or 
method has variables.  The closest you get to "an application having 
variables" is globals, and if you're relying on that then you've already 
screwed up your architecture royally.  (Yep, I've worked on a system that used 
globals as its main form of inter-system communication.  Especially for the 
template layer.  I wish I was joking.)

If such logic is properly placed in a function or class, as you should be 
doing, then current autoload or a function-level autoload would handle it and 
you're done.

> But another interesting option for autodefining variables is that you
> are able to track which variables are used in your application. The
> fun thing is that you can do this in every environment. For
> development it is interesting to see if you are using variables which
> you don't recognize (typo's) or don't want to use (e.g.
> $HTTP_POST_VARS), for testing it is interesting to see if your test
> cases are using the most important variables and for production it is
> interesting to see which variables are used at all and which never.
> The paragraph above applies of course to all objects that can be
> autodefined. As pointed out in the RFC, autodefine enables you to get
> more insight and thus more control over your codebase.

That's what a taint mode, `E_ALL` / E_STRICT, or runtime analysis tool is for.  
It's not something that belongs in a runtime part of the language.  If 
anything, autoloading variables would make typos and such harder to track 
down, harder to debug, and harder to comprehend.


Really, I want to like your RFC because I've wanted function-level autoloading 
for a long time.  It would make my life a ton easier.  Please, please, please 
make good arguments for it instead of coming up with use cases that would make 
any responsible developer start with rm -rf as a way to debug a system. :-)  
You'll never convince TPTB around here to accept it otherwise.

--Larry Garfield
