Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more detail,
and perhaps get a voting on.
Thanks
Br,
Thomas Gielfeldt
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:
Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more detail,
and perhaps get a voting on.
so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an interface
for each method seems a bit much as well.
Thanks
Br,
Thomas Gielfeldt
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an interface
for each method seems a bit much as well.
Yeah, I've thought of this as well. PHP has got a load of sort functions.
I've also considered other options:
1.) 5 interfaces for, respectively, (r)sort, a(r)sort, k(r)sort, u(a|k)sort
and nat(case)sort, with 2-3 methods per interface.
2.) Same as above, but with a flag for reverse instead of a dedicated
function resulting in 5 interfaces with 1-3 methods each.
3.) 1 interface with 2 methods, sort()
and usort()
, and flags for reverse,
key and maintaining index.
I did consider the latter much, but wasn't sure if the methods would get
too monolithic.
I also did consider an interface per method. Briefly. :-)
Thanks
Br,
Thomas Gielfeldt
Le 24/02/2015 20:20, Thomas Gielfeldt a écrit :
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an interface
for each method seems a bit much as well.Yeah, I've thought of this as well. PHP has got a load of sort functions.
I've also considered other options:1.) 5 interfaces for, respectively, (r)sort, a(r)sort, k(r)sort, u(a|k)sort
and nat(case)sort, with 2-3 methods per interface.
2.) Same as above, but with a flag for reverse instead of a dedicated
function resulting in 5 interfaces with 1-3 methods each.
3.) 1 interface with 2 methods,sort()
andusort()
, and flags for reverse,
key and maintaining index.I did consider the latter much, but wasn't sure if the methods would get
too monolithic.I also did consider an interface per method. Briefly. :-)
Thanks
Br,
Thomas Gielfeldt
Hi,
I posted a message in the discussion about function names consistency
which is, in part, related to this thread. The main subject may be
defining a consistent API, but one part is about ordering native arrays.
http://news.php.net/php.internals/84429
I started to write some documentation for an OO API dedicated to arrays
- and hence sorting arrays.
https://github.com/gplanchat/php-oop-api/blob/master/doc/array-sorter.md
I wrote in this document an abstract method, named SplArraySorter, which
only has an abstract sort()
method. Every variant implements the
functionalities of one or multiple array sorting native functions.
The point I want to come after is that the collection should not be
aware of how we would want to sort it, but let this control to a
external object.
Therefore, the way collections may be actually sorted would become
dependent on an external object and be changed on the fly by the program
itself, without having to rewrite any line of code. This has the
avantage of letting you have the control over any source code, whether
you are the author (or able to change it) or if this code comes from a
dependency (PEAR, Composer, ect...).
So, to make it more visual, I would suggest intead to create the 2
interfaces Sorter and Sortable, which could be vritten as :
<?php
interface Sortable
{
}
interface Sorter
{
public function sort(Sortable $collection);
}
Greetings
Grégory Planchat
Le 24/02/2015 20:20, Thomas Gielfeldt a écrit :
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an
interface
for each method seems a bit much as well.Yeah, I've thought of this as well. PHP has got a load of sort
functions.
I've also considered other options:1.) 5 interfaces for, respectively, (r)sort, a(r)sort, k(r)sort,
u(a|k)sort
and nat(case)sort, with 2-3 methods per interface.
2.) Same as above, but with a flag for reverse instead of a dedicated
function resulting in 5 interfaces with 1-3 methods each.
3.) 1 interface with 2 methods,sort()
andusort()
, and flags for
reverse,
key and maintaining index.I did consider the latter much, but wasn't sure if the methods would get
too monolithic.I also did consider an interface per method. Briefly. :-)
Thanks
Br,
Thomas Gielfeldt
Hi,
I posted a message in the discussion about function names consistency
which is, in part, related to this thread. The main subject may be
defining a consistent API, but one part is about ordering native arrays.http://news.php.net/php.internals/84429
I started to write some documentation for an OO API dedicated to
arrays - and hence sorting arrays.https://github.com/gplanchat/php-oop-api/blob/master/doc/array-sorter.md
I wrote in this document an abstract method, named SplArraySorter,
which only has an abstractsort()
method. Every variant implements the
functionalities of one or multiple array sorting native functions.The point I want to come after is that the collection should not be
aware of how we would want to sort it, but let this control to a
external object.Therefore, the way collections may be actually sorted would become
dependent on an external object and be changed on the fly by the
program itself, without having to rewrite any line of code. This has
the avantage of letting you have the control over any source code,
whether you are the author (or able to change it) or if this code
comes from a dependency (PEAR, Composer, ect...).So, to make it more visual, I would suggest intead to create the 2
interfaces Sorter and Sortable, which could be vritten as :<?php
interface Sortable
{
}interface Sorter
{
public function sort(Sortable $collection);
}
Empty interfaces are fine for extension-built objects, which under the
hood implement some particular data structure or whatever that the
implementation expects, but they're useless for userland classes,
because there's no way to actually implement them.
If I have a class called UserList, and I want to make it sortable, how
do I do that with this setup? Again, thinking about different use cases
might help pin down where this approach would and wouldn't be useful.
Regards,
--
Rowan Collins
[IMSoP]
Le 08/03/2015 15:19, Rowan Collins a écrit :
Le 24/02/2015 20:20, Thomas Gielfeldt a écrit :
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an
interface
for each method seems a bit much as well.Yeah, I've thought of this as well. PHP has got a load of sort
functions.
I've also considered other options:1.) 5 interfaces for, respectively, (r)sort, a(r)sort, k(r)sort,
u(a|k)sort
and nat(case)sort, with 2-3 methods per interface.
2.) Same as above, but with a flag for reverse instead of a dedicated
function resulting in 5 interfaces with 1-3 methods each.
3.) 1 interface with 2 methods,sort()
andusort()
, and flags for
reverse,
key and maintaining index.I did consider the latter much, but wasn't sure if the methods would get
too monolithic.I also did consider an interface per method. Briefly. :-)
Thanks
Br,
Thomas Gielfeldt
Hi,
I posted a message in the discussion about function names consistency
which is, in part, related to this thread. The main subject may be
defining a consistent API, but one part is about ordering native arrays.http://news.php.net/php.internals/84429
I started to write some documentation for an OO API dedicated to
arrays - and hence sorting arrays.https://github.com/gplanchat/php-oop-api/blob/master/doc/array-sorter.md
I wrote in this document an abstract method, named SplArraySorter,
which only has an abstractsort()
method. Every variant implements the
functionalities of one or multiple array sorting native functions.The point I want to come after is that the collection should not be
aware of how we would want to sort it, but let this control to a
external object.Therefore, the way collections may be actually sorted would become
dependent on an external object and be changed on the fly by the
program itself, without having to rewrite any line of code. This has
the avantage of letting you have the control over any source code,
whether you are the author (or able to change it) or if this code
comes from a dependency (PEAR, Composer, ect...).So, to make it more visual, I would suggest intead to create the 2
interfaces Sorter and Sortable, which could be vritten as :<?php
interface Sortable
{
}interface Sorter
{
public function sort(Sortable $collection);
}Empty interfaces are fine for extension-built objects, which under the
hood implement some particular data structure or whatever that the
implementation expects, but they're useless for userland classes,
because there's no way to actually implement them.If I have a class called UserList, and I want to make it sortable, how
do I do that with this setup? Again, thinking about different use cases
might help pin down where this approach would and wouldn't be useful.Regards,
Yes, I agree there is a missing part in the proposed implementation.
So, let me change my previous definition to this meta-code:
interface Sortable
{
}
interface SortableAggregate extends Sortable
{
public function sort(Sorter $sorter);
}
interface SortableCollection extends Sortable, Traversable
{
public function swap(mixed $leftKey, mixed $rightKey);
}
interface Sorter
{
public function sort(Sortable $collection);
}
Then, this is example 1, using the interface SortableCollection:
class Foo implements SortableCollection
{
private $internalCollection = [];
public function swap(mixed $leftKey, mixed $rightKey)
{
/*
* I assume a function like array_swap() would be more
* appropriate as long as it already exists in the engine
* and presumably not so difficult to bring to the
* userspace anyway, but it currently does not exist
*/
$tmp = $this->internalCollection[$leftKey];
$this->internalCollection[$leftKey] =
$this->internalCollection[$rightKey];
$this->internalCollection[$rightKey] = $tmp;
}
}
class BarSortable implements Sorter
{
public function sort(Sortable $collection)
{
$previousKey = null;
$previousElement = null;
foreach ($collection as $key => $element) {
if ($previousKey === null) {
$previousKey = $key;
$previousElement = $element;
continue;
}
if ($previousElement < element) {
$collection->swap($previousKey, $key);
}
$previousKey = $key;
$previousElement = $element;
}
}
}
Then, this is example 2, using the interface SortableAggregate:
class Baz implements SortableAggregate
{
private $internalCollection;
public function __construct()
{
$this->internalCollection = new YourRandomSortedDataStructure();
}
public function sort(Sorter $sorter)
{
$sorter->sort($collection);
}
}
class BarSortable implements Sorter
{
private $internalSorter;
public function __construct()
{
$this->internalSorter = new YourUsefulSorter();
}
public function sort(Sortable $collection)
{
$collection->sort($this->internalSorter);
}
}
By this way, with a swap() method, we let to the user-land code a way to
map his internal implementation to the core array/SPL datastructure
implementation. It just has to specify the keys in the collection to
swap. The rules are then defined by the Sorter object.
I assume there will be a big issue at start : the swap() method does not
exist anywhere, neither on array nor on SPL data structures (nor other
structures).
Tell me if I you see any issues.
Grégory Planchat
class BarSortable implements Sorter
{
public function sort(Sortable $collection)
{
$previousKey = null;
$previousElement = null;foreach ($collection as $key => $element) { if ($previousKey === null) { $previousKey = $key; $previousElement = $element; continue; } if ($previousElement < element) { $collection->swap($previousKey, $key); } $previousKey = $key; $previousElement = $element; } }
}
Unfortunately, this won't actually sort the array - it only makes one
check of each value, so [4, 1, 2, 3, 5] would come out as [4, 2, 3, 1,
5], when it should be [5, 4, 3, 2, 1] (your < sign means you're sorting
largest value first). It's almost like a bubble sort, though (you keep
swapping things until you know that there's no more swaps to be made),
which is the simplest but also least efficient way of sorting a list.
I think insertion sort, which is simple and efficient for small lists,
could be done with iteration plus a single callback of
"insertElementAt". For larger lists, though, you're going to want a
quicksort, and I can't quite picture what callbacks that would need to
run on the collection as it went; it ultimately requires some way of
partitioning the list into multiple pieces.
Regards,
--
Rowan Collins
[IMSoP]
Le 08/03/2015 19:05, Rowan Collins a écrit :
class BarSortable implements Sorter
{
public function sort(Sortable $collection)
{
$previousKey = null;
$previousElement = null;foreach ($collection as $key => $element) { if ($previousKey === null) { $previousKey = $key; $previousElement = $element; continue; } if ($previousElement < element) { $collection->swap($previousKey, $key); } $previousKey = $key; $previousElement = $element; } }
}
Unfortunately, this won't actually sort the array - it only makes one
check of each value, so [4, 1, 2, 3, 5] would come out as [4, 2, 3, 1,
5], when it should be [5, 4, 3, 2, 1] (your < sign means you're sorting
largest value first). It's almost like a bubble sort, though (you keep
swapping things until you know that there's no more swaps to be made),
which is the simplest but also least efficient way of sorting a list.I think insertion sort, which is simple and efficient for small lists,
could be done with iteration plus a single callback of
"insertElementAt". For larger lists, though, you're going to want a
quicksort, and I can't quite picture what callbacks that would need to
run on the collection as it went; it ultimately requires some way of
partitioning the list into multiple pieces.Regards,
Yes you're right, I wrote up this example a bit too fast, with lots of
mistakes. I since went over my proposal and fixed them.
It is in fact a bit too large for sending it on internals@ and related
to another proposal I made here, so I wrote it on a github repository
and merged it with the other proposal:
https://github.com/gplanchat/php-oop-api/blob/master/doc/sorting.md
I think this implementation is a bit more solid.
The point made after the SortableAggregate and SorterAggregate is that a
userland class may encapsulate the real collection. Instead of making
decorators over and over again - which would be a performance hurdle - I
brought the idea of passing the real sorter via a visitor pattern.
I thought of this implementation to find a solution for OO API with
arrays, as you can read here:
https://github.com/gplanchat/php-oop-api/blob/master/doc/array.md
https://github.com/gplanchat/php-oop-api/blob/master/doc/array-sorter.md
Grégory Planchat
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an interface
for each method seems a bit much as well.
I have some more proposals for how to implement this interface. Should we
create an RFC for purposes of discussion, or do you usually do this in the
mailing lists?
1 interface with 2 methods, controlled by flags.
/** @ingroup SPL
- @brief This Interface allows to hook into the global
sort()
functions. - @since PHP 5.1
/
interface Sortable
{
/*- Sort values or keys.
- @param int $flags
-
SORT_REGULAR
-
SORT_NUMERIC
-
SORT_STRING
-
SORT_LOCALE_STRING
-
SORT_NATURAL
- -- bitwise flags
- SORT_SORT_FLAG_CASE - case insensitive sorting.
- SORT_REVERSE - sort in reverse.
- SORT_KEYS - sort keys.
- SORT_INDEX - maintain indexes.
- @return bool
-
TRUE
on success.
*/
function sort($flags);
/**
- Sort values or keys.
- @param callback $cmp_function
- Compare callback
- @return bool
-
TRUE
on success.
*/
function usort($cmp_function);
}
4 interfaces with 1 method, controlled by flags.
/** @ingroup SPL
- @brief This Interface allows to hook into the global
sort()
functions. - @since PHP 5.1
/
interface Sortable
{
/*- Sort values.
- @param int $flags
-
SORT_REGULAR
-
SORT_NUMERIC
-
SORT_STRING
-
SORT_LOCALE_STRING
-
SORT_NATURAL
- -- bitwise flags
- SORT_SORT_FLAG_CASE - case insensitive sorting.
- SORT_REVERSE - sort in reverse.
- @return bool
-
TRUE
on success.
*/
function sort($flags);
}
/** @ingroup SPL
- @brief This Interface allows to hook into the global aXsort() functions.
- @since PHP 5.1
/
interface SortableIndex
{
/*- Sort values and maintain index association.
- @param int $flags
-
SORT_REGULAR
-
SORT_NUMERIC
-
SORT_STRING
-
SORT_LOCALE_STRING
-
SORT_NATURAL
- -- bitwise flags
- SORT_SORT_FLAG_CASE - case insensitive sorting.
- SORT_REVERSE - sort in reverse.
- @return bool
-
TRUE
on success.
*/
function asort($flags);
}
/** @ingroup SPL
- @brief This Interface allows to hook into the global kXsort() functions.
- @since PHP 5.1
/
interface SortableKeys
{
/*- Sort keys.
- @param int $flags
-
SORT_REGULAR
-
SORT_NUMERIC
-
SORT_STRING
-
SORT_LOCALE_STRING
-
SORT_NATURAL
- -- bitwise flags
- SORT_SORT_FLAG_CASE - case insensitive sorting.
- SORT_REVERSE - sort in reverse.
- @return bool
-
TRUE
on success.
*/
function ksort($flags);
}
/** @ingroup SPL
- @brief This Interface allows to hook into the global uXsort() functions.
- @since PHP 5.1
/
interface SortableUser
{
/*- Sort values or keys.
- @param callback $cmp_function
- Compare callback
- @return bool
-
TRUE
on success.
*/
function usort($cmp_function);
}
The natsort()
and natcasesort()
can already be covered by sort()
through
flags, so I think we should leave them out.
Thanks
Br,
Thomas Gielfeldt
2015-02-25 13:21 GMT+03:00 Thomas Gielfeldt thomas@gielfeldt.dk:
I have some more proposals for how to implement this interface. Should we
create an RFC for purposes of discussion, or do you usually do this in the
mailing lists?
Best interface is described by the one single method: sort()
that accepts
optional flags and callback function:
So,
interface Sortable {
const ASC = 1;
const DESC = 2;
const SORT_REGULAR
= 4;
const SORT_NUMERIC
= 8;
// more consts here...
public function sort($flags = 0, callable $callback = null);
}
Callback will accept key and value pair.
2015-02-25 11:31 GMT+01:00 Alexander Lisachenko lisachenko.it@gmail.com:
2015-02-25 13:21 GMT+03:00 Thomas Gielfeldt thomas@gielfeldt.dk:
I have some more proposals for how to implement this interface. Should we
create an RFC for purposes of discussion, or do you usually do this in the
mailing lists?Best interface is described by the one single method:
sort()
that accepts
optional flags and callback function:So,
interface Sortable {
const ASC = 1;
const DESC = 2;
constSORT_REGULAR
= 4;
constSORT_NUMERIC
= 8;
// more consts here...public function sort($flags = 0, callable $callback = null);
}
Callback will accept key and value pair.
Yeah, but the "problem" with this, is that your class' sort method, you
have to implement all the possible permutations the flags can produce. This
basically just squeezes the 11 functions into 1. The 1 interface with
sort()
and usort()
splits this into 2 functions (8+3). With that in mind,
I'm more inclined to choose the 4 interface approach.
2015-02-25 13:37 GMT+03:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Yeah, but the "problem" with this, is that your class' sort method, you
have to implement all the possible permutations the flags can produce. This
basically just squeezes the 11 functions into 1. The 1 interface with
sort()
andusort()
splits this into 2 functions (8+3). With that in mind,
I'm more inclined to choose the 4 interface approach.
For that case, move all configurations to the several classes and configure
these flags in the concrete constructors. Interface will be more simple:
interface Sortable {
const ASC = 1;
const DESC = 2;
public function sort($direction = self::ASC, callable $callback = null);
}
class KeySorter implements Sortable {}
2015-02-25 12:15 GMT+01:00 Alexander Lisachenko lisachenko.it@gmail.com:
2015-02-25 13:37 GMT+03:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Yeah, but the "problem" with this, is that your class' sort method, you
have to implement all the possible permutations the flags can produce. This
basically just squeezes the 11 functions into 1. The 1 interface with
sort()
andusort()
splits this into 2 functions (8+3). With that in mind,
I'm more inclined to choose the 4 interface approach.For that case, move all configurations to the several classes and
configure these flags in the concrete constructors. Interface will be more
simple:interface Sortable {
const ASC = 1;
const DESC = 2;public function sort($direction = self::ASC, callable $callback =
null);
}class KeySorter implements Sortable {}
That seems a little backwards to me? How would the consumer of e.g.
KeySorter know which sort variations are implemented?
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an interface
for each method seems a bit much as well.
Another solution could be:
/** @ingroup SPL
- @brief This Interface allows to hook into the global Xsort() functions.
- @since PHP 5.6
/
interface Sortable
{
/*- Sort the entries by values.
- @param integer $sort_flags
- SORT_REGULAR: compare items normally (don't change types)
- SORT_NUMERIC: compare items numerically
- SORT_STRING: compare items as strings
- SORT_LOCALE_STRING: compare items as strings, based on the current
locale. It uses the locale, which can be changed usingsetlocale()
- SORT_NATURAL: compare items as strings using "natural
ordering" likenatsort()
- SORT_FLAG_CASE: can be combined (bitwise OR) with
SORT_STRING
or
SORT_NATURAL
to sort strings case-insensitively - SORT_FLAG_REVERSE: can be combined (bitwise OR) with any of the
other options to sort in reverse
*/
function sort($sort_flags = SORT_REGULAR);
/** Sort the entries by values using user defined function.
*/
function usort(mixed cmp_function);
}
/** @ingroup SPL
- @brief This Interface allows to hook into the global XaXsort() functions.
- @since PHP 5.6
/
interface SortableAssoc
{
/*- Sort the entries by values and maintain indexes.
- @param integer $sort_flags
- SORT_REGULAR: compare items normally (don't change types)
- SORT_NUMERIC: compare items numerically
- SORT_STRING: compare items as strings
- SORT_LOCALE_STRING: compare items as strings, based on the current
locale. It uses the locale, which can be changed usingsetlocale()
- SORT_NATURAL: compare items as strings using "natural
ordering" likenatsort()
- SORT_FLAG_CASE: can be combined (bitwise OR) with
SORT_STRING
or
SORT_NATURAL
to sort strings case-insensitively - SORT_FLAG_REVERSE: can be combined (bitwise OR) with any of the
other options to sort in reverse
*/
function asort($sort_flags = SORT_REGULAR);
/** Sort the entries by values using user defined function and maintain
index.
*/
function uasort(mixed cmp_function);
}
/** @ingroup SPL
- @brief This Interface allows to hook into the global XkXsort() functions.
- @since PHP 5.6
/
interface SortableKeys
{
/*- Sort the entries by key.
- @param integer $sort_flags
- SORT_REGULAR: compare items normally (don't change types)
- SORT_NUMERIC: compare items numerically
- SORT_STRING: compare items as strings
- SORT_LOCALE_STRING: compare items as strings, based on the current
locale. It uses the locale, which can be changed usingsetlocale()
- SORT_NATURAL: compare items as strings using "natural
ordering" likenatsort()
- SORT_FLAG_CASE: can be combined (bitwise OR) with
SORT_STRING
or
SORT_NATURAL
to sort strings case-insensitively - SORT_FLAG_REVERSE: can be combined (bitwise OR) with any of the
other options to sort in reverse
*/
function ksort($sort_flags = SORT_REGULAR);
/** Sort the entries by key using user defined function.
*/
function uksort(mixed cmp_function);
}
I have a working implementation of this also.
Thanks
Br,
Thomas Gielfeldt
2015-02-24 17:36 GMT+01:00 Benjamin Eberlei kontakt@beberlei.de:
Hi,
On Tue, Feb 24, 2015 at 5:17 PM, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.so you need to implement all methods? This can probably be considered a
violation of the Interface Segregation Principle. But adding an interface
for each method seems a bit much as well.
I've made another PR to show a different implementation. I've also
registered a wiki account. I don't have access to create an RFC for this.
I'm not actually sure how to go about this?
https://github.com/php/php-src/pull/1123
Thanks
Br,
Thomas Gielfeldt
Hi!
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more detail,
and perhaps get a voting on.
Can't you sort any class that provides ordered list of elements and
Comparable or some kind of comparison callback by a generic algorithm?
Interface with 11 functions, all similar but slightly different, seems
unoptimal.
--
Stas Malyshev
smalyshev@gmail.com
2015-02-24 20:49 GMT+01:00 Stanislav Malyshev smalyshev@gmail.com:
Hi!
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail,
and perhaps get a voting on.Can't you sort any class that provides ordered list of elements and
Comparable or some kind of comparison callback by a generic algorithm?
Interface with 11 functions, all similar but slightly different, seems
unoptimal.One of the goals of this, is to make at it possible to use the Xsort()
functions on objects. I agree, implementing 11 methods might be
sub-optimal. We could reduce it to 2 methods, and then provide flags for
the variations.
--
Stas Malyshev
smalyshev@gmail.com
Thomas Gielfeldt wrote on 24/02/2015 16:17:
Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more detail,
and perhaps get a voting on.
I think the reason this interface is proving hard to simplify is that
you're putting too much of the responsibility on the implementing
object. Most containers don't need or want to reimplement an entire
quicksort algorithm, or be responsible for tracking the various types of
comparison.
Ideally, you could start by writing an OO implementation of QuickSort
which takes as its input an abstract "Collection" instead of an array,
and look at what methods you end up wanting to call on that Collection.
That might end up rather complex in practice, though, because the
underlying data structures do make a difference to an efficient
implementation.
However, the types of sort differ primarily in the way values are
compared, so if the engine passed in an appropriate comparison callback,
the interface needs only one method:
public function sort(callable $comparison_callback, boolean $preserve_keys)
where $comparison_callback is:
function($l_key, $l_value, $r_key, $r_value): int
The only flag that the object might want to care about is whether to
preserve keys (asort, uasort, ksort, uksort), because it could allow
optimisations rather than reindexing after the sort has completed. For
everything else, it should just be repeatedly asking the engine "which
of these two items should come first?" By passing both keys and values,
ksort()
can be implemented with the same callback signature, the only
disadvantage being that the user callbacks to usort()
and uksort()
would
need to be wrapped, with the engine basically emulating the following:
// For usort($object, $usort_callback)
$comparison_callback = function($l_key, $l_value, $r_key, $r_value) use
($usort_callback) { return $usort_callback($l_value, $r_value); };
// For ksort($object, $ksort_callback)
$comparison_callback = function($l_key, $l_value, $r_key, $r_value) use
($ksort_callback) { return $ksort_callback($l_key, $r_key); };
Regards,
Rowan Collins
[IMSoP]
2015-02-24 17:17 GMT+01:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail, and perhaps get a voting on.Thanks
Br,
Thomas Gielfeldt
The 2nd PR I made addresses this (https://github.com/php/php-src/pull/1123),
exposing 3 much simpler interfaces depending on what the user wants/needs
to implement, which combined covers all the 11 sort functions.
Also, the point of this/these interface(s) is to provide the same power
that some of the other SPL interfaces have (Countable, Serializable,
ArrayAccess, Iterator, etc.). That is, using native functions with objects
possessing certain capabilities.
Thomas Gielfeldt wrote on 02/03/2015 07:43:
2015-02-24 17:17 GMT+01:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail, and perhaps get a voting on.Thanks
Br,
Thomas Gielfeldt
The 2nd PR I made addresses this (https://github.com/php/php-src/pull/1123),
exposing 3 much simpler interfaces depending on what the user wants/needs
to implement, which combined covers all the 11 sort functions.Also, the point of this/these interface(s) is to provide the same power
that some of the other SPL interfaces have (Countable, Serializable,
ArrayAccess, Iterator, etc.). That is, using native functions with objects
possessing certain capabilities.
I don't think a container should be expected to reimplement something as
specific as a case-insensitive natural string comparison; its job should
be to do the actual sorting of data.
I suggest a single interface with 3 methods: sortValues($cmp_function),
sortValuesAssoc($cmp_function), and sortKeys($cmp_function):
https://gist.github.com/IMSoP/4ea904203eadf8d5859a
This maintains the obvious connection between userland functions and the
method called, and keeps the userland implementation much lower on
boilerplate. Conveniently, a collection which internally stores data in
an array can pass the callback directly to usort/uasort/uksort for a
trivial implementation.
Obviously, this means more implementation needed on the engine side, in
that it needs to expose callback functions for the various different
comparisons, but I think that's where the comparison logic belongs.
Regards,
Rowan Collins
[IMSoP]
Rowan Collins wrote on 02/03/2015 10:52:
Thomas Gielfeldt wrote on 02/03/2015 07:43:
2015-02-24 17:17 GMT+01:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail, and perhaps get a voting on.Thanks
Br,
Thomas Gielfeldt
The 2nd PR I made addresses this
(https://github.com/php/php-src/pull/1123),
exposing 3 much simpler interfaces depending on what the user
wants/needs
to implement, which combined covers all the 11 sort functions.Also, the point of this/these interface(s) is to provide the same power
that some of the other SPL interfaces have (Countable, Serializable,
ArrayAccess, Iterator, etc.). That is, using native functions with
objects
possessing certain capabilities.I don't think a container should be expected to reimplement something
as specific as a case-insensitive natural string comparison; its job
should be to do the actual sorting of data.I suggest a single interface with 3 methods:
sortValues($cmp_function), sortValuesAssoc($cmp_function), and
sortKeys($cmp_function):
https://gist.github.com/IMSoP/4ea904203eadf8d5859aThis maintains the obvious connection between userland functions and
the method called, and keeps the userland implementation much lower on
boilerplate. Conveniently, a collection which internally stores data
in an array can pass the callback directly to usort/uasort/uksort for
a trivial implementation.Obviously, this means more implementation needed on the engine side,
in that it needs to expose callback functions for the various
different comparisons, but I think that's where the comparison logic
belongs.
Incidentally, note that this is exactly how the sorting of real arrays
is done internally: zend_hash_sort_ex [1] takes a comparison callback,
using a global set by php_set_compare_func [2] for flags, and wrappers
for things like key vs data comparison [3].
Basically, to implement my suggestion, you need a way to expose the
php_array_*_compare functions in ext/standard/array.c as callbacks to
userland, presumably without actually making them named functions.
[1] http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_hash.c#1930
[2] http://lxr.php.net/xref/PHP_TRUNK/ext/standard/array.c#144
[3] http://lxr.php.net/xref/PHP_TRUNK/ext/standard/array.c#173
Regards,
Rowan Collins
[IMSoP]
2015-03-02 16:26 GMT+01:00 Rowan Collins rowan.collins@gmail.com:
Rowan Collins wrote on 02/03/2015 10:52:
Thomas Gielfeldt wrote on 02/03/2015 07:43:
2015-02-24 17:17 GMT+01:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Hi internals.
I've made PR proposing a feature request: A new interface Sortable.
https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in more
detail, and perhaps get a voting on.Thanks
Br,
Thomas Gielfeldt
The 2nd PR I made addresses this (https://github.com/php/php-
src/pull/1123),
exposing 3 much simpler interfaces depending on what the user wants/needs
to implement, which combined covers all the 11 sort functions.Also, the point of this/these interface(s) is to provide the same power
that some of the other SPL interfaces have (Countable, Serializable,
ArrayAccess, Iterator, etc.). That is, using native functions with
objects
possessing certain capabilities.I don't think a container should be expected to reimplement something as
specific as a case-insensitive natural string comparison; its job should be
to do the actual sorting of data.I suggest a single interface with 3 methods: sortValues($cmp_function),
sortValuesAssoc($cmp_function), and sortKeys($cmp_function):
https://gist.github.com/IMSoP/4ea904203eadf8d5859aThis maintains the obvious connection between userland functions and the
method called, and keeps the userland implementation much lower on
boilerplate. Conveniently, a collection which internally stores data in an
array can pass the callback directly to usort/uasort/uksort for a trivial
implementation.Obviously, this means more implementation needed on the engine side, in
that it needs to expose callback functions for the various different
comparisons, but I think that's where the comparison logic belongs.Incidentally, note that this is exactly how the sorting of real arrays is
done internally: zend_hash_sort_ex [1] takes a comparison callback, using a
global set by php_set_compare_func [2] for flags, and wrappers for things
like key vs data comparison [3].Basically, to implement my suggestion, you need a way to expose the
php_array_*_compare functions in ext/standard/array.c as callbacks to
userland, presumably without actually making them named functions.
Though I can appreciate the elegance in what you propose, I'm worried about
a couple of things with this approach.
1.) Having to pass a comparison function through userland, could hurt
performance for the ArrayObject, which otherwise would use the native C
sort functions directly on its hashtable.
2.) This approach forces the implementor to rely on a userland comparison
function. While this would not be a problem for the specific use case I had
in mind, it could destroy the possibility of further abstraction. One
example could be a sort in conjunction with a database class. Probably not
the best example, but I hope you understand what I'm getting at.
Dispatching the sort to something outside PHP. If all that the sort methods
get are closures, then it's near impossible to determine the intent of the
caller.
3.) I'm probably gonna the one implementing this, and I think this approach
would be much more complex than the two I've already made :-) ... though,
of course, that's not an excuse :-)
That being said, I still like the approach you suggest wrt responsibility
of the interface. I just think that there may be some practical
implications.
[1] http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_hash.c#1930
[2] http://lxr.php.net/xref/PHP_TRUNK/ext/standard/array.c#144
[3] http://lxr.php.net/xref/PHP_TRUNK/ext/standard/array.c#173Regards,
Rowan Collins
[IMSoP]
2015-03-02 16:26 GMT+01:00 Rowan Collins rowan.collins@gmail.com:
Rowan Collins wrote on 02/03/2015 10:52:
Thomas Gielfeldt wrote on 02/03/2015 07:43:
2015-02-24 17:17 GMT+01:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Hi internals.
I've made PR proposing a feature request: A new interface
Sortable.https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in
more
detail, and perhaps get a voting on.Thanks
Br,
Thomas Gielfeldt
The 2nd PR I made addresses this (https://github.com/php/php-
src/pull/1123),
exposing 3 much simpler interfaces depending on what the user
wants/needs
to implement, which combined covers all the 11 sort functions.Also, the point of this/these interface(s) is to provide the same
power
that some of the other SPL interfaces have (Countable,
Serializable,
ArrayAccess, Iterator, etc.). That is, using native functions with
objects
possessing certain capabilities.I don't think a container should be expected to reimplement
something as
specific as a case-insensitive natural string comparison; its job
should be
to do the actual sorting of data.I suggest a single interface with 3 methods:
sortValues($cmp_function),
sortValuesAssoc($cmp_function), and sortKeys($cmp_function):
https://gist.github.com/IMSoP/4ea904203eadf8d5859aThis maintains the obvious connection between userland functions and
the
method called, and keeps the userland implementation much lower on
boilerplate. Conveniently, a collection which internally stores data
in an
array can pass the callback directly to usort/uasort/uksort for a
trivial
implementation.Obviously, this means more implementation needed on the engine side,
in
that it needs to expose callback functions for the various different
comparisons, but I think that's where the comparison logic belongs.Incidentally, note that this is exactly how the sorting of real
arrays is
done internally: zend_hash_sort_ex [1] takes a comparison callback,
using a
global set by php_set_compare_func [2] for flags, and wrappers for
things
like key vs data comparison [3].Basically, to implement my suggestion, you need a way to expose the
php_array_*_compare functions in ext/standard/array.c as callbacks to
userland, presumably without actually making them named functions.Though I can appreciate the elegance in what you propose, I'm worried
about
a couple of things with this approach.1.) Having to pass a comparison function through userland, could hurt
performance for the ArrayObject, which otherwise would use the native C
sort functions directly on its hashtable.
Anything implemented in a C extension can still do so, just as they can overload property access or Traversable behaviour. This interface is only necessary when implementing the sort logic in userland anyway.
2.) This approach forces the implementor to rely on a userland
comparison
function. While this would not be a problem for the specific use case I
had
in mind, it could destroy the possibility of further abstraction. One
example could be a sort in conjunction with a database class. Probably
not
the best example, but I hope you understand what I'm getting at.
Dispatching the sort to something outside PHP. If all that the sort
methods
get are closures, then it's near impossible to determine the intent of
the
caller.
Hm, yes, I hadn't thought of the use case of sorting external data. Perhaps we actually need to specify both interfaces (yes, I realise I'm just inventing more work here, sorry!) - one for the use case of a custom data structure that wants to worry about the sort mechanics but not the ordering, and one for the different use case of wanting to sort something other than PHP values. I strongly believe that making the first type of object reimplement 11 types of comparison callback which the engine already has is a bad idea.
Regards,
Rowan Collins
[IMSoP]
Hm, yes, I hadn't thought of the use case of sorting external data. Perhaps we actually need to specify both interfaces (yes, I realise I'm just inventing more work here, sorry!) - one for the use case of a custom data structure that wants to worry about the sort mechanics but not the ordering, and one for the different use case of wanting to sort something other than PHP values. I strongly believe that making the first type of object reimplement 11 types of comparison callback which the engine already has is a bad idea.
I'd been following this thread, but only from a distant need. I tend to
be working with lists pulled directly from a database, and Firebird
allows the selection of collation rules to take care of the bulk of the
problems this interface is also trying to address. This option allows
all of the complication created by unicode to be addressed and a ready
sorted array is provided. The starting point for a generic approach
needs to be based on a unicode rule set which currently we do not have a
standard for. ICU provides a collation system in parallel with the
database standards and if the ICU based string object is adopted then
sort interfaces need to be based on that.
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Hm, yes, I hadn't thought of the use case of sorting external data. Perhaps we actually need to specify both interfaces (yes, I realise I'm just inventing more work here, sorry!) - one for the use case of a custom data structure that wants to worry about the sort mechanics but not the ordering, and one for the different use case of wanting to sort something other than PHP values. I strongly believe that making the first type of object reimplement 11 types of comparison callback which the engine already has is a bad idea.
I'd been following this thread, but only from a distant need. I tend to
be working with lists pulled directly from a database, and Firebird
allows the selection of collation rules to take care of the bulk of the
problems this interface is also trying to address. This option allows
all of the complication created by unicode to be addressed and a ready
sorted array is provided. The starting point for a generic approach
needs to be based on a unicode rule set which currently we do not have a
standard for. ICU provides a collation system in parallel with the
database standards and if the ICU based string object is adopted then
sort interfaces need to be based on that.
Actually, collation is an interesting point - of all the different sort
functions in current PHP, none of them really considers it.
That's a disadvantage of passing the flags through to the collection
being sorted, rather than the comparison implementation - it's very hard
for us to change the underlying set of sort options without a BC break
on the interface, because they're so closely coupled. For remote data
sources, they'd need a new argument or method to accept and act on the
new options; for simple data structures, they'd want to just use the new
comparison type.
Like so many things, it's probably a good idea to consider up front the
kinds of use cases we're targeting, and those that we're not, otherwise
we end up with an implementation that is very well-engineered in itself,
but doesn't actually meet people's needs.
Regards,
--
Rowan Collins
[IMSoP]
Hm, yes, I hadn't thought of the use case of sorting external data.
Perhaps we actually need to specify both interfaces (yes, I realise
I'm just inventing more work here, sorry!) - one for the use case of
a custom data structure that wants to worry about the sort mechanics
but not the ordering, and one for the different use case of wanting
to sort something other than PHP values. I strongly believe that
making the first type of object reimplement 11 types of comparison
callback which the engine already has is a bad idea.
I'd been following this thread, but only from a distant need. I tend to
be working with lists pulled directly from a database, and Firebird
allows the selection of collation rules to take care of the bulk of the
problems this interface is also trying to address. This option allows
all of the complication created by unicode to be addressed and a ready
sorted array is provided. The starting point for a generic approach
needs to be based on a unicode rule set which currently we do not have a
standard for. ICU provides a collation system in parallel with the
database standards and if the ICU based string object is adopted then
sort interfaces need to be based on that.Actually, collation is an interesting point - of all the different sort
functions in current PHP, none of them really considers it.That's a disadvantage of passing the flags through to the collection
being sorted, rather than the comparison implementation - it's very hard
for us to change the underlying set of sort options without a BC break
on the interface, because they're so closely coupled. For remote data
sources, they'd need a new argument or method to accept and act on the
new options; for simple data structures, they'd want to just use the new
comparison type.Like so many things, it's probably a good idea to consider up front the
kinds of use cases we're targeting, and those that we're not, otherwise
we end up with an implementation that is very well-engineered in itself,
but doesn't actually meet people's needs.
One of the advantages that a well designed database provides is that
things like 'lower' or 'upper' sort order can be provided and indexed
separately to the mixed case base records. One of the things which is
unique to Firebird is that a field can be defined with it's own
collation rather than the whole database working with a single
collation. (Not sure if this is now possible on other engines?) The
result is that one can index translated fields in the manor correct for
that language rather than having to read the data and resort it.
Collation is the tidy way to define a set of sort rules, and even 'up
and 'down' may have different results to just reversing the order. Until
you drop back to ASCII sorting ...
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
2015-03-04 10:41 GMT+01:00 Rowan Collins rowan.collins@gmail.com:
On 4 March 2015 07:12:41 GMT, Thomas Gielfeldt thomas@gielfeldt.dk
wrote:2015-03-02 16:26 GMT+01:00 Rowan Collins rowan.collins@gmail.com:
Rowan Collins wrote on 02/03/2015 10:52:
Thomas Gielfeldt wrote on 02/03/2015 07:43:
2015-02-24 17:17 GMT+01:00 Thomas Gielfeldt thomas@gielfeldt.dk:
Hi internals.
I've made PR proposing a feature request: A new interface
Sortable.https://github.com/php/php-src/pull/1116
If possible, I would like to create and RFC describing this in
more
detail, and perhaps get a voting on.Thanks
Br,
Thomas Gielfeldt
The 2nd PR I made addresses this (https://github.com/php/php-
src/pull/1123),
exposing 3 much simpler interfaces depending on what the user
wants/needs
to implement, which combined covers all the 11 sort functions.Also, the point of this/these interface(s) is to provide the same
power
that some of the other SPL interfaces have (Countable,
Serializable,
ArrayAccess, Iterator, etc.). That is, using native functions with
objects
possessing certain capabilities.I don't think a container should be expected to reimplement
something as
specific as a case-insensitive natural string comparison; its job
should be
to do the actual sorting of data.I suggest a single interface with 3 methods:
sortValues($cmp_function),
sortValuesAssoc($cmp_function), and sortKeys($cmp_function):
https://gist.github.com/IMSoP/4ea904203eadf8d5859aThis maintains the obvious connection between userland functions and
the
method called, and keeps the userland implementation much lower on
boilerplate. Conveniently, a collection which internally stores data
in an
array can pass the callback directly to usort/uasort/uksort for a
trivial
implementation.Obviously, this means more implementation needed on the engine side,
in
that it needs to expose callback functions for the various different
comparisons, but I think that's where the comparison logic belongs.Incidentally, note that this is exactly how the sorting of real
arrays is
done internally: zend_hash_sort_ex [1] takes a comparison callback,
using a
global set by php_set_compare_func [2] for flags, and wrappers for
things
like key vs data comparison [3].Basically, to implement my suggestion, you need a way to expose the
php_array_*_compare functions in ext/standard/array.c as callbacks to
userland, presumably without actually making them named functions.Though I can appreciate the elegance in what you propose, I'm worried
about
a couple of things with this approach.1.) Having to pass a comparison function through userland, could hurt
performance for the ArrayObject, which otherwise would use the native C
sort functions directly on its hashtable.Anything implemented in a C extension can still do so, just as they can
overload property access or Traversable behaviour. This interface is only
necessary when implementing the sort logic in userland anyway.2.) This approach forces the implementor to rely on a userland
comparison
function. While this would not be a problem for the specific use case I
had
in mind, it could destroy the possibility of further abstraction. One
example could be a sort in conjunction with a database class. Probably
not
the best example, but I hope you understand what I'm getting at.
Dispatching the sort to something outside PHP. If all that the sort
methods
get are closures, then it's near impossible to determine the intent of
the
caller.Hm, yes, I hadn't thought of the use case of sorting external data.
Perhaps we actually need to specify both interfaces (yes, I realise I'm
just inventing more work here, sorry!) - one for the use case of a custom
data structure that wants to worry about the sort mechanics but not the
ordering, and one for the different use case of wanting to sort something
other than PHP values. I strongly believe that making the first type of
object reimplement 11 types of comparison callback which the engine already
has is a bad idea.
What about a "hybrid" solution? Pass the flags as well as a callback. Then
the implementor can react on the flags if necessary.
https://gist.github.com/gielfeldt/c0ca611f525878c36a65
In this case, I've introduced a new constant for user defined sort.
However, I see a couple of variations on this.
1.) Constant for determining user defined sort (as per the example).
2.) 2 methods, one for usorts, and one for the others (still with both
flags and callbacks). This will result in 6 methods, if we keep it to just
one interface.
3.) 3 interfaces with either one or two methods (option 1 & 2 above).
Regards,
--
Rowan Collins
[IMSoP]
What about a "hybrid" solution? Pass the flags as well as a callback. Then
the implementor can react on the flags if necessary.
Off topic I know - but how the **** do I make the github text readable?
Light grey on white may work for some, but even changing contrast on the
monitor I can't actually read that :(
In this case, I've introduced a new constant for user defined sort.
However, I see a couple of variations on this.1.) Constant for determining user defined sort (as per the example).
2.) 2 methods, one for usorts, and one for the others (still with both
flags and callbacks). This will result in 6 methods, if we keep it to just
one interface.
3.) 3 interfaces with either one or two methods (option 1 & 2 above).
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk