Path to XP7
thekid opened this issue · 46 comments
Scope of Change
This RFC describes the path towards XP 7.0
Rationale
Multiple big changes will be introduced. This document holds the roadmap; and what migrations will be necessary when.
Functionality
What needs to change
- We need to get rid of our base lang.Object / lang.Generic - see #297 (comment)
- While
$instance->getClass()
can be replaced bytypeof($instance)
we need to introduce a shortcut for$instance->getClassName()
as core functionalitynameof()
. - We need to remove the
null
class and xp::null() - We need to remove extension methods from the core
- We need to remove reflection from the core (-> library)
- We need to remove process control and threading from the core (-> library)
- We need to remove wrapper types from the core (-> library)
- We should remove
uses()
completely - We should remove support for RFC #37 as well as for classes in global namespace being aliased to their namespaced equivalents (just use namespaces!)
- We need to remove everything but the bare minimum from XP core - see RFC #296
- We should add support for variadics (and thus require PHP 5.6 minimum)
- Add ideas for object kinds supporting extension methods (e.g. https://github.com/xp-forge/partial). Think about need for generics and create()
Roadmap
Release | Changes relevant for XP 7.0 |
---|---|
6.0.0 | _Starting point_ |
6.1.0 | _The preparation release_ - Core: Trait reflection support, deprecate uses() and raise() , Libraries: Introduce new better reflection API (https://github.com/xp-forge/mirrors) |
6.2.0 | _The null handling release_ - Core: Deprecate delete(), xp::null() - not commonly used anyways, util.Optional (from https://github.com/xp-forge/sequence) |
6.3.0 | _The naming release_ - Core: Deprecate xp::nameOf(), introduce nameof(), support for type unions, lang.Value interface (see RFC #297). Deprecate lang.types, boxing/unboxing, Libraries: Introduce new concept for wrapper types that don't and won't nameclash with PHP, to be used by e.g. remote or rdbms |
6.4.0 | _The namespaces release_ - Core: Remove uses() and raise() , now supports namespace-only classes, deprecate using create() for anything other than generics, deprecate this() , long array syntax in both annotations and code |
6.5.0 | _Enter PHP 5.5_ - Core: Require PHP 5.5, remove delete() . Deprecate ensure() which is replaced by finally . Libraries: Unittests and logging will be extracted (see RFC #293 and RFC #301). |
6.6.0 | _Enter PHP 5.6_ - Core: Suggest PHP 5.6 minimum, support variadics, remove xp::nameOf(), xp::null(), this() , xp::error() (the latter is not commonly used and can be replaced by exceptions). Libraries: Extract collections library |
6.7.0 | _The core minimizing release_ - Extract most libraries leaving us ony with lang, io and util. Remove xp::reflect() which has been deprecated for more than a year |
6.8.0 | _The cleanup release_ - Introduce seven branch, refactor code to work without extracted APIs, forward compatible adjustments, cleanup |
6.9.0 | _The error handling release_ Wrap native exceptions, remove ensure() . |
6.10.0 | _New XP runners_ Integrate support for RFC #303 subcommands |
7.0.0 | _Target_: Require PHP 5.6 minimum, suggest PHP 7.0 |
Security considerations
Speed impact
Dependencies
- XP 6.0.0 - 2015-02-08
- XP 6.1.0 - 2015-04-06
- XP 6.2.0 - 2015-05-05
- XP 6.3.0 - 2015-06-02
- XP 6.4.0 - 2015-07-12
- XP 6.5.0 - 2015-08-22
- XP 6.6.0 - 2015-11-23
- XP 6.7.0 - 2015-12-09
- XP 6.8.0 - 2015-12-20
- XP 6.9.0 - 2015-12-24 🎄
- XP 6.10.0 - 2016-01-10
Related documents
- https://github.com/xp-framework/rfc/milestones/7.0.0-RELEASE (all XP 7.0 RFCs)
- RFC #293 - Extract unittests from core
- https://wiki.php.net/rfc/php7timeline - PHP7 timeline
Places using xp::null()
:
$ grep -Hirn xp::null src/main/|cut -d ':' -f 1|sort|uniq
src/main/php/lang.base.php
src/main/php/lang/ClassLoader.class.php
src/main/php/lang/Process.class.php
src/main/php/lang/Wildcard.class.php
src/main/php/lang/XPClass.class.php
src/main/php/unittest/TestResult.class.php
src/main/php/unittest/web/WebTestCase.class.php
src/main/php/util/CompositeProperties.class.php
src/main/php/util/Filters.class.php
src/main/php/util/cmd/Console.class.php
Places using xp::error()
:
$ grep -Hirn xp::error src/main/|cut -d ':' -f 1|sort|uniq
src/main/jay/webservices/json/json.jay
src/main/php/io/File.class.php
src/main/php/io/ZipFile.class.php
src/main/php/lang.base.php
src/main/php/lang/types/Character.class.php
src/main/php/lang/types/String.class.php
src/main/php/util/Hashmap.class.php
_The core functionality raise
is now deprecated in 6.1.0 and will be removed in 6.4.0._ The original idea to introduce it was to only load exceptions raised in seldomly executed code paths lazily. With namespaces, this is always the case. Thus, the function has become obsolete.
_The uses
statement is now deprecated in 6.1.0 and will be removed in 6.4.0._ This means also classes in the global namespace which are aliased to fully qualified names as well as package classes from RFC #37 are considered deprecated.
On PHP 5.6
The above plan states XP 6.6.0 will require PHP 5.6 as its minimum version. This was chosen instead of PHP 5.5 for the following reasons:
Availability
PHP 5.6 was originally released in late August 2014. By the time XP 6.6.0 is released:
- It will have been out there for roughly a year.
- Debian Jessy should be out and support it: https://packages.debian.org/jessie/php5
- For Wheezy, you can use dotdeb: https://www.dotdeb.org/2015/03/22/php-5-6-7-for-wheezy/
- Current Ubuntu (vivid, 15.04, released March 2015) supports it: http://packages.ubuntu.com/vivid/php5
- For trusty (14.04), use https://launchpad.net/~ondrej/+archive/ubuntu/php5-5.6
HHVM
HHVM 3.5.0 matches PHP 5.6 - see http://3v4l.org/s50F2#vhhvm-341
Features
On top of the following XP-relevant PHP features in PHP 5.5
- Finally - replaces ensure()
- Generators - makes code "flow"
T::class
- replaces string references to classes- Non-scalar iterator keys - comes in handy for util.collections
....it also supports:
- use function and use const - will be helpful in introducing library functions
- Variadics and arg unpacking - finally, no more func_get_args() and call_user_func_array()
...and contains a fix for PHP bug #66608 (Incorrect behavior with nested "finally" blocks).
_The core functionality delete
is now deprecated in 6.2.0 and will be removed in 6.5.0_. Simply use the language construct unset
instead, which also accepts variadics.
_The core functionality xp::null()
is now deprecated in 6.2.0 and will be removed in 6.6.0._. If you need null
-safe handling, you can use the cast()
core functionality or the ?:
operator.
$ xp -w '$period= ...; return cast($period->endDate(), "util.Date")'
Uncaught exception: Exception lang.ClassCastException (Cannot cast NULL to util.Date)
# ...
$ xp -w '$period= ...; return $period->endDate() ?: Date::now()'
2015-04-25 13:55:47+0200
Criticism on the Optional
class in Java:
- http://java.dzone.com/articles/java-8-optional-whats-point
- http://blog.jooq.org/2014/03/28/java-8-friday-optional-will-remain-an-option-in-java/
Maybe we should think about this a bit more before introducing it to the framework
Naming
On renaming the wrapper types (see the reserving more types and reserving even more types RFCs, the following are now all reserved:
int, float, bool, string, true, false, null, resource, object, scalar, mixed, numeric
Since class names in PHP are case insensitive this means we'll to rename some prominent classes in the XP Framework:
core
- With the "rebase" RFC #297 we suggest to remove the base class lang.Object
- xp::null() is already deprecated and scheduled for removal
- The
Primitive
class provides methods for boxing and unboxing. These will also be deprecated and removed:wrapperClasss(), unboxed(), boxed()
.
wrappers
- We could use use short names for strings like Python and lang.types.String => lang.types.Str
- We could add 32 to Float and Integer - lang.types.Float => lang.types.Float32 and lang.types.Integer => lang.types.Int32 (while the latter doesn't really conflict it would be done for consistency stakes)
- Alternatively, we could rename the Float wrapper type to Single as done in C#
By removing the class aliasing for lang.types.* in lang.base.php and the wrapperClasss(), unboxed(), boxed() methods from Primitive, the sequence library runs once again with PHP 7:
Timm@slate ~/devel/xp/sequence [master]
$ XP_RT=7.0 unittest src/test/php/
# ...
✓: 496/496 run (0 skipped), 496 succeeded, 0 failed
Memory used: 3090.66 kB (3409.80 kB peak)
Time taken: 0.037 seconds
The "Object" name has not been reserved yet, though.
_The wrapper types in lang.types , primitive boxing and unboxing are now deprecated in 6.3.0_. The new wrapper type library is https://github.com/xp-forge/wrappers
_The core functionality xp::nameOf() is now deprecated in 6.3.0 and will be removed in 6.6.0._ Simply use the new nameof()
instead.
PHP 7.0.0 alpha1
Following PHP7's first alpha - see http://php.net/archive/2015.php#id2015-01-11-6 - we've created a release which passes all tests but those where it's clear we won't have compatibility, like with the String
and Float
wrapper types:
https://github.com/xp-framework/core/releases/tag/v6.3.1
Please note the XP6 series will not support PHP7 officially: It reserves the name object , which clashes with our root class lang.Object . However, PHP7 alpha 1 does not yet raise an error if this class name is used.
SDK support ✅
These SDK parts support PHP7:
- xp-framework/http - See here: https://travis-ci.org/xp-framework/http/builds/66681416
- xp-framework/rdbms v6.3.1 - See here: https://travis-ci.org/xp-framework/rdbms/builds/66686505
- xp-framework/csv - See here: https://travis-ci.org/xp-framework/csv/builds/66687828
- xp-framework/ftp v6.1.0 - see here: https://travis-ci.org/xp-framework/ftp/builds/66690023
- xp-framework/webservices v6.1.0 - see here: https://travis-ci.org/xp-framework/webservices/builds/66695082
- xp-framework/rest v6.2.0 - see here: https://travis-ci.org/xp-framework/rest/builds/66695731
- xp-framework/xml v6.2.0 - see here: https://travis-ci.org/xp-framework/xml/builds/66700255
- xp-framework/scriptlet v6.2.0 - see here: https://travis-ci.org/xp-framework/scriptlet/builds/66701554
- xp-framework/imaging - see here: https://travis-ci.org/xp-framework/imaging/builds/66702533
- xp-framework/zip - see here: https://travis-ci.org/xp-framework/zip/builds/66702789
- xp-framework/mail - see here: https://travis-ci.org/xp-framework/zip/builds/66702952
- xp-framework/parser - see here: https://travis-ci.org/xp-framework/parser/builds/66703180
Library support ✅
The first libraries to support PHP7 are:
- xp-forge/mirrors v0.8.0 - see here: https://travis-ci.org/xp-forge/mirrors/builds/66665726
- xp-forge/sequence - see here: https://travis-ci.org/xp-forge/sequence/builds/66666099
- xp-forge/inject - see here: https://travis-ci.org/xp-forge/inject/builds/66673831
- xp-forge/handlebars v0.3.0 - see here: https://travis-ci.org/xp-forge/handlebars/builds/66675603
- xp-forge/json - see here: https://travis-ci.org/xp-forge/json/builds/66676062
- xp-forge/mustache - see here: https://travis-ci.org/xp-forge/mustache/builds/66676273
- xp-forge/partial - see here: https://travis-ci.org/xp-forge/partial/builds/66676611
- xp-forge/ratelimit - see here: https://travis-ci.org/xp-forge/ratelimit/builds/66676839
- xp-forge/pivot - see here: https://travis-ci.org/xp-forge/pivot/builds/66677048
- xp-forge/parse - see here: https://travis-ci.org/xp-forge/parse/builds/66677415
- xp-forge/geoip - see here: https://travis-ci.org/xp-forge/geoip/builds/66677596
- xp-forge/measure v0.4.0 - see here: https://travis-ci.org/xp-forge/measure/builds/66677783
- xp-forge/wrappers - see here: https://travis-ci.org/xp-forge/wrappers/builds/66703773
- xp-forge/match - see here: https://travis-ci.org/xp-forge/match/builds/66704210
- xp-forge/yaml - see here: https://travis-ci.org/xp-forge/yaml/builds/66704555
- xp-forge/markdown - see here: https://travis-ci.org/xp-forge/markdown/builds/66704663
- xp-forge/address v0.3.0 - see here: https://travis-ci.org/xp-forge/address/builds/66706941
- xp-forge/gsa-xmlfeed - see here: https://travis-ci.org/xp-forge/gsa-xmlfeed/builds/66705483
- xp-forge/stomp - see here: https://travis-ci.org/xp-forge/stomp/builds/66733823
- xp-forge/assert v0.7.0 - see here: https://travis-ci.org/xp-forge/assert/builds/66736038
All of them allow failures for PHP 7 as long as it's not final yet.
_The pre-namespace class loading is no longer supported in 6.4.0_. No more uses(), now more support for package-qualified and global namespace classes as fully qualified class names.
_The raise() core function is longer supported in 6.4.0_. It was related to pre-namespace class loading, lazily loads exception and then throws it. No longer necessary now that we are using the PHP builtin class loading, which is lazy by default.
_The core functionality create() can now only be used to create generics in 6.4.0_. The second usecase, create(new T())->method()
is replaced by PHP 5.4's syntactic support for (new T())->method()
.
The wrapper type library has its first release, 0.1.0. In it:
package lang.types {
public abstract class lang.types.Num
public final class lang.types.Int8 // "Byte", -128 to 127
public final class lang.types.Int16 // "Short", -32768 to 32767
public final class lang.types.Int32 // "Int", -2^31 to (2^31)- 1
public final class lang.types.Int64 // "Long", -2^63 to (2^63)- 1
public final class lang.types.Single // "Float", -3.4 x 10^38 to +3.4 x 10^38
public final class lang.types.Double // "Double", ±5.0 x 10^324 to ±1.7 x 10^308
public final class lang.types.Str // "String"
}
The reflection replacement library has now reached 1.0.0, fully supporting:
- PHP 5.6+
- PHP 7.0alpha2+ and its scalar and return type hinting
- HHVM 3.5+ and its HACK language
_Heads up: XP 6.5.0 will require PHP 5.5.0 minimum!_ Unofficially (meaning: tests will no longer verify its functionality), XP 6.5.0 will still run on PHP 5.4.X, as none of the code in src/main uses PHP 5.5 features yet, but do upgrade!
_The delete()
core function is longer supported in 6.5.0._ It can be replaced by using the language construct unset
.
_The ensure()
core functionality is deprecated in 6.5.0._ It can be replaced by the PHP 5.5 language construct finally
:
Before
try {
$file->write(...);
} catch (\lang\Throwable $e) {
// Empty
} ensure($e); {
$file->close();
if ($e) throw $e;
} |
After
try {
$file->write(...);
} finally {
$file->close();
} |
Before
try {
$file->write(...);
} catch (\lang\Throwable $e) {
$cat->warn('Could not write to file');
} ensure($e); {
$file->close();
if ($e) throw $e;
} |
After
try {
$file->write(...);
} catch (\lang\Throwable $e) {
$cat->warn('Could not write to file');
throw $e;
} finally {
$file->close();
} |
_You are encouraged to use ::class
for newinstance() and in annotations as of XP 6.5.0_. Instead of providing the class name in dotted form, import via use
and then use PHP's native name resolution.
$instance= newinstance(Runnable::class, [], [
'run' => function() { ... }
]);
#[@test, @expect(IllegalArgumentException::class)]
public function negative_test() {
// ...
}
_The this() core function is longer supported in 6.6.0_. It's been obsoleted by syntactic support in PHP:
// Before
$first= this($class->getMethods(), 0);
// After
$first= $class->getMethods()[0];
See https://wiki.php.net/rfc/functionarraydereferencing (implemented in PHP 5.4).
_The xp::error() core function is longer supported in 6.6.0_. Replace by throwing exceptions in the spirit of PHP 7, which has done away with most fatal errors.
See https://wiki.php.net/rfc/catchable-call-to-member-of-non-object and https://wiki.php.net/rfc/engine_exceptions_for_php7
_The xp::null() core function is longer supported in 6.6.0._. Replace by the "real" null
(and then check for it) or use the sequence library's Optional
class.
_The xp::nameOf() core function is longer supported in 6.6.0_ and has been superseded by nameof($instance)
.
_The util.collections package is deprecated in 6.6.0_. It has been extracted from core. Its development will continue inside https://github.com/xp-framework/collections
XP 6.6.0 has been released
_Quite a bunch of APIs are deprecated (but not removed) in XP 6.7.0_ and have been extracted. This means development will continue in the separate places, and the code will be removed from XP core in 7.0.0.
The relevant changelog entry:
- Implemented more parts of #296:
- Extracted the
peer.*
APIs to its own package and deprecated the
one inside core. See https://github.com/xp-framework/networking - Extracted the
math
API to its own package and deprecated the
one inside core. See https://github.com/xp-framework/math - Extracted the
text
API to its own package and deprecated the
one inside core. Split into:
. https://github.com/xp-framework/tokenize
. https://github.com/xp-framework/patterns
. https://github.com/xp-framework/text-encode - Extracted the
security
API to its own package and deprecated the
one inside core. See https://github.com/xp-framework/security
- Extracted the
xp::reflect() has been deprecated since September 2014, and can be replaced seamlessly by literal()
.
These places need to be fixed:
- compiler
xp/compiler/src/main/php/xp/compiler/JitClassLoader.class.php:166: if (isset(\xp::$cl[$class])) return \xp::reflect($class);
xp/compiler/src/main/php/xp/compiler/types/Scope.class.php:257: class_exists(\xp::reflect($qualified), false) ||
xp/compiler/src/main/php/xp/compiler/types/Scope.class.php:258: interface_exists(\xp::reflect($qualified), false) ||
xp/compiler/src/test/php/net/xp_lang/tests/execution/source/ClassDeclarationTest.class.php:135: $this->assertEquals('demo\SourceClassInPackage', \xp::reflect($class->getName()));
xp/compiler/src/test/php/net/xp_lang/tests/execution/source/ClassDeclarationTest.class.php:146: $this->assertEquals('demo\SourcePackageClassInPackage', \xp::reflect($class->getName())); - doclet
Binary file xp/doclet/src/main/php/text/doclet/RootDoc.class.php matches - rdbms
xp/rdbms/src/main/php/rdbms/Peer.class.php:167: return self::getInstance(\xp::reflect($classname)); - webservices
xp/webservices/src/main/php/webservices/soap/native/NativeSoapClient.class.php:213: $this->map[$qname->localpart]= \xp::reflect($class->getName()); - xml
xp/xml/src/main/php/xml/Tree.class.php:36: $this->nodeType= \xp::reflect('xml.Node');
XP 6.7.0 has been released
XP7 branch
Now that PHP7 is out on the one hand and we're getting quite close to the final stripped down stadium of XP core, we could create a branch in xp-framework/core and start development on the 7.X code base.
XP 6.8.0 has been released
remote
library when XP7 comes out, see XP RFC 0304
XP 6.9.0 has been released
XP 6.10.0 has been released. It contains support for RFC-303 style runners, which bring a new "TL;DR" style for usage messages:
Switch branches
One of the next steps will be to switch branches:
- Master -> Six
- Seven -> Master
- Delete "Seven" branch
_Master of xp-framework/core is now at 7.0.0-dev_
✅ Changed all libraries to use nameof()
instead of getClassName()
, see xp-framework/core#120
Interesting PHP 7.1 feature: The void
return type: https://wiki.php.net/rfc/void_return_type
_Other than xp-framework/core#57, I think we're all set for XP7_ - need to decide whether this should go in or not.
Decided to implement basic hack language support in xp-framework/core#123 (see also #308)
Mind changes
XP 7 -> PHP 7
I decided against this after finding out Debian wasn't going to provide PHP 7 until 2017. Lots of production systems inside companies are just making the step towards jessie, which gives us PHP 5.6 (/cc @kiesel @mikey179)
We need to remove reflection from the core (-> library)
This has not happened. I decided to leave this in until XP8, as the mirrors
library isn't breaking any speed records, and I haven't succeeded in fixing this yet.
We need to remove process control and threading from the core (-> library)
I haven't felt this is necessary after all, also moving this until a later release.
Think about need for generics and create()
At the moment, there are still some libraries benefiting from generics, so I decided to keep them. It remains to be seen whether e.g. xp-forge/partial has the potential to replace them. Maybe something similar to Hack's type constants?
Coming from XP 6.0, and migrating to current XP 6-master as preparation for XP 7, here's the list of removed core functionality
- xp::nameOf()
- xp::null() & null class
- xp::reflect()
- xp::error()
- uses()
- raise()
- ensure()
- delete()
- this()
- create() no longer supports Generic
- Omnipresent classes no longer aliased to short names