2015-03-04 10:41 GMT+01:00 Rowan Collins <rowan.coll...@gmail.com>: > On 4 March 2015 07:12:41 GMT, Thomas Gielfeldt <tho...@gielfeldt.dk> > wrote: > >2015-03-02 16:26 GMT+01:00 Rowan Collins <rowan.coll...@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 <tho...@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. > >>> > >> > >> > >> 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] > >