On Tue, Jun 30, 2015 at 8:15 AM, Bob Weinand <bobw...@hotmail.com> wrote: >> Am 30.06.2015 um 12:53 schrieb François Laupretre <franc...@php.net>: >> >>> De : Bob Weinand [mailto:bobw...@hotmail.com] >>> >>> Precisely. Instead of tight coupling to the structure, we now couple to the >>> macro… and it's not like the macro will be left untouched once we change the >>> underlying structure. >> >> There are different levels of encapsulation : 1st level can be seen as the C >> structure, 2nd level is the macro (allows to change the structure >> organization), 3rd level provides separate read-only getters and write-only >> setters. If you look at https://github.com/php/php-src/pull/1381, you will >> see the API I want to integrate (not sure there is enough time before 7.0 >> freeze). It doesn't use macros any more but active methods/functions. There, >> ZSTR_LEN() is a pure getter, which cannot be used as lvalue. ZSTR_SET_LEN() >> is the corresponding write-only setter. I don't say that such API is >> supposed to resist any implementation change but it should already allow a >> lot. When we achieve this encapsulation level on arrays/HashTables, we'll be >> much more comfortable with future potential changes. >> >> I understand your pov. If any future change in the underlying implementation >> requires changing the API, this API is much less valuable. You think that >> zend_string internal implementation will never evolve without requiring API >> changes. I don't think the same, I make no assumption on other's creativity, >> I just know that, if the need for a better isolation arises someday, it will >> be too late. So, I prefer to have it from the beginning. In zend_string, the >> need comes more from the countless number of locations accessing the API >> than from the implementation complexity. Of course, when we have both, like >> on arrays, isolation is still more important. >> >> Once again, zend_string is just an example. Zval needs some work too but is >> somewhat easier as an extensive API already exists and most people use it, >> it just needs to be made 'stricter'. Making the zval API stricter (with >> separate getters/setters) will allow for a lot of debugging/monitoring >> instrumentation to be added to the API. Some of them are also interesting >> for zend_strings. Just imagine simple checks in debug mode ensuring the >> string length remains in allocated bounds. If you set the length using a >> '->len' assignment or a macro, it cannot be trapped and checked. It is >> really the simplest example of what encapsulation makes possible. When we >> work on zend_string/smart_str integration, code can also be inserted to >> measure the efficiency of various over-allocation policies. With you >> '->len', what will you do ? "grep '--' '->len' `find . -type f`" and rewrite >> thousands of occurrences ? > > I see where you're heading to. But I still hold my position that you're > overvaluing abstraction in that particular case. Like… it would be ideal to > automatically reset the hash value on each change. Do we want that? No. It'd > do millions of useless hash-resetting operations. So… what we end up? Having > to manually control hash values. We always need to fallback to low-level > control, even though we have an API. That's not good. > It'd be nice to abstract it away, but that's at a cost we aren't willing to > pay. You only can have a certain level of abstraction without paying the > price. > > I think, zend_string * may evolve without structure changes. But in case we > change the structures, something will have changed so drastically that the > higher level APIs need change too. > I doubt that it will allow a lot. > > Let's take your example with "stricter" API. What can you now debug/monitor? > Like how a value changes? That you easily can right now with every smart C > debugger… setting a watchpoint. > Also, smart string is an own API, with dedicated functions. We can very well > test that at that level. No need to leak that over onto zend_string *. Smart > string is a high-level API on top of zend_string *, _using_ the primitive > zend_string API. > > Oh, a check if it's in allocated bounds? Only issue is that we actually don't > store the boundaries (also no reason to) … anyway, I can guarantee that the > prefect abstraction will be leaky, or include a ton of functions operating on > them. That's not the way to go. > Example… reallocing a string without setting a length (to extend but not > knowing the exact final length yet) … not possible, currently. I'm sure, if > you search for cases where the abstraction is leaky, you'll find enough. > Do NOT introduce leaky abstractions where it's not hiding complexity. > >>> Like … PHP 7 changed the semantics of Z_TYPE() macro… you can no longer >>> assign directly to it. We anyway have to change our code. >>> It's rare that such underlying changes don't leak through the API. >> >> No, we need to change our code because the zval API's encapsulation level >> was not high enough. It type setters and getters had been already separate >> in PHP 5, switching to PHP 7 wouldn't have required changing our code. >> That's why defining access macros is not enough. We need stricter 'methods', >> designed as services. > > Okay. Other example. Refcounts. The macro itself still works… just that it'll > badly fail when you try to refcount a primitive type now. The changes leak on > all levels … Oh sure. You could have added a branch for each refcount > checking the type… Just that will cost precious instructions. > > Or IS_REFERENCE handling. A new type. Needs to be handled at all levels and > beyond. > Or having now Z_STR() … sure, Z_STRVAL(), Z_STRLEN() still work, but became > inefficient to use. > > I could continue that list... > > Merci, > Bob > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php
Just to time in with my $0.02: I feel that using macros as an abstraction in this case is bad practice. I believe that in *most* cases macros as an abstraction is a bad practice. Furthermore, there isn't any reason that `zend_string_*` functions cannot act as an abstraction layer since zend_string's are passed by pointer. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php