Re: [PHP-DEV] deprecation status of $str{42} versus $str[42]
2008/6/16 Edward Z. Yang [EMAIL PROTECTED]: PHP userland code may not treat strings as first class arrays, but that's certainly how they are represented internally. Anyway, it would be neat if we could get that foreach syntax to work. I get sick of for($i = 0, $c = strlen($str); $i $c; $i++) very quickly. Totaly agree, the best example from the whole thread
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi, - I am a little confused about the OOP interaction. How does a function become a public method of the class? To clarify: the public method ist just the internal representation of the lambda function and has *nothing* to do with the semantics of calling the lambda itself. The method only means that the lambda function defined inside another method can access the class members and public only means that the lambda function can still be called from outside the class. class Example { private $a = 2; function myMethod($b) { $lambda = function() { lexical $b; return $this-a * $b; // This part I get }; return $lambda; } } $e = new Example(); $lambda = $e-myMethod(); $e-$lambda(5); No, that's not what my patch does. My patch does: class Example { private $a = 2; public function myMethod ($b) { return function () { lexical $b; return $this-a * $b; }; } } $e = new Example (); $lambda = $e-myMethod (4); var_dump ($lambda ()); // int(8) $lambda2 = $e-myMethod (6); var_dump ($lambda2 ()); // int(12) So esentially, it does not matter whether you define a lambda function inside a method or a function (or in global scope, for that matter), you always use it the same way. The in-class-method lambda function only has the additional advantage of being able to access the private and protected class members since *internally* it is treated like a public class method. - Related to that, would it then be possible to add methods to a class at runtime using lambda functions as the added methods? No. If not, is that something that could reasonably be added here without hosing performance (or at least doing so less than stacking __call() and call_user_func_array() does)? If you want to add methods dynamically to classes, why not use the runkit extension? I really don't see a point in making lambda functions and closures something they are not. Regards, Christiaan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi! class Dynamic { private $someVar = 5; /// adding a function to instances from within the class public function addMethodAtRuntime() { $this-dynamicFunc1 = function() { return $this-someVar; // expected to work } } } /// invoking dynamically added methods /// (anticipated behavior given above definitions) $dynamic-addMethodAtRuntime(); echo $dynamic-dynamicFunc1(); // 5 This will not work - for the same reason as this does not work: class SpecialChars { public $process = 'htmlspecialchars'; } $sc = new SpecialChars (); var_dump ($sc-process ('')); // call to undefined ... On the other hand, the following will work: $sc = new SpecialChars (); $processor = $sc-process; var_dump ($processor ('')); // string(8) lt;gt; The same with closures: echo $dynamic-dynamicFunc1(); // call to undefined ... $func = $dynamic-dynamicFunc1; echo $func (); // 5 echo call_user_func ($dynamic-dynamicFunc1); // 5 As I sead in my other mail: I don't see closures as a method for somehow making it possible to extend classes dynamically - if you want that, use runkit. Regards, Christian -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] deprecation status of $str{42} versus $str[42]
2008/6/16 Chris Stockton [EMAIL PROTECTED]: Hello, On Sun, Jun 15, 2008 at 11:20 PM, Arvids Godjuks [EMAIL PROTECTED] wrote: String is an array of chars, always was and is such in any programming language. So I see argument for {} as missing knowledge for some programming basics. And I don't understand why are you arguing on this. This was decided for removal long ago - so just do it. Seems like you are missing some PHP programming basics. Strings are not an array of chars, please go back to making ping pong in java c# or whatever other little comp sci classes you took. PHP is not any of them. Foreach(foo as $key = $char) {}, after learning, please be quiet and let andi answer my question on his ideas he had for improvements to the existing and once favored syntax. -Chris Sort of in response to whatever other little comp sci classes you took and sort of explaining what a user sees. I'm a self taught software developer and have been in paid employment for over 20 years and only in 2 jobs. So, even if I don't know everything about PHP's internals, my skills are good enough not to get me fired. In that time, I've used (to a different amount) COBOL, Sage Retrieve 4GL, C, Delphi, JS, PHP, MS DOS Batch files. In nearly all of these languages a string is a series of characters which can be accessed via an offset from the beginning of the string. In many cases the syntax is the same as that of accessing an array element. In the languages where it is necessary to define the length of the string, defining an array and a string are done in similar ways. Not identically by any means, but the user impression is that they are similar. The example Chris gave was for iterating an array. Strings cannot be iterated in the same manner, but that doesn't mean you cannot traverse a string and an array in the same way. ?php $a = array(1,2,3,5,7,11,13,17,19); $s = 'abcegkmqs'; for ($i = 0 ; $i 9 ; ++$i) { echo $a[$i], ' vs ', $s[$i], ' vs ', $s{$i}, PHP_EOL; } outputs ... 1 vs a vs a 2 vs b vs b 3 vs c vs c 5 vs e vs e 7 vs g vs g 11 vs k vs k 13 vs m vs m 17 vs q vs q 19 vs s vs s So, using the same syntax to access a string and an array, from a user's perspective, does suggest that a string is an array of characters. Please be a little more forgiving of users. My only criticism against the use of $s{$i} is that { } is used to wrap compound statements (say like begin / end in other languages/syntaxes). With that in mind, you should be able to put statements which have a return value of some sort which is then used to access the appropriate element. But I think that is getting very close to closures. $s{return some_complex_calc();} sort of thing (smells like JS). I would like this syntax as I don't want to create a real function for just 1 use - the function may not be reuseable, so it doesn't need to get into the namespace. But I think that's a different argument. So, to all the devs who read my missives, keep up the good work. I'm paid because of the work you do. Your efforts make my life easier. Thank you, Richard Quadling. -- - Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498r=213474731 Standing on the shoulders of some very clever giants!
Re: [PHP-DEV] deprecation status of $str{42} versus $str[42]
Hi, Seems like you are missing some PHP programming basics. Strings are not an array of chars, please go back to making ping pong in java c# or whatever other little comp sci classes you took. PHP is not any of them. Foreach(foo as $key = $char) {}, after learning, please be quiet and let andi answer my question on his ideas he had for improvements to the existing and once favored syntax. Please, keep this kind of personal abuse off the core development list. It adds absolutely nothing to the debate, and we're all very, very bored with it. Thanks, - Steph -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] deprecation status of $str{42} versus $str[42]
On Tuesday 17 June 2008 08:27:37 Arvids Godjuks wrote: 2008/6/16 Edward Z. Yang [EMAIL PROTECTED]: PHP userland code may not treat strings as first class arrays, but that's certainly how they are represented internally. Anyway, it would be neat if we could get that foreach syntax to work. I get sick of for($i = 0, $c = strlen($str); $i $c; $i++) very quickly. Totaly agree, the best example from the whole thread You're not learning from the mistakes of other languages (ruby in this case, which removed Enumerable from String in 1.9) ... foreach makes no sense for strings, because it's unclear what you want (with unicode terminology here, as this is for php6): for each byte for each codeunit for each codepoint, or for each line, or ... if you want to use foreach in your example, just do foreach (str_split($str) as $value) { ... Regards, Stefan -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] PHP RFC: closures
Hi, Let me introduce myself (as much as pertains to this letter): I am one of the lead developers of Drupal core (Drupal, I believe, is quite well known by now), I maintain the form API and the menu system. I do not know much about PHP internals, but I spent most of the awake time in the last four years writing code in PHP. I can't wait to have lambda and closures in PHP. I am well aware of the fact that it will be many years before we can raise the minimum PHP version of Drupal to 5.3 but if we do not start now then it will be even later :) Just a real life quick example, http://api.drupal.org/api/function/_filter_url_parse_full_links/6 has no reason to exist, it should be lambda, it's called from preg_replace_callback only. So: a resounding yes. Regards Karoly Negyesi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hello Christian, very nice work. I think we should really add this to 5.3. The only thing I don't like is the function naming (“\0__compiled_lambda_FILENAME_N”). Can we drop the \0? For methods inside classes, do we have to provide real private methods or do we support visibility fully? Or did you use the \0 prefix to prevent direct invocations? If so, it doesn't help, as the user can simply create the function call with the \0. I think the best option would be to force lambda functions being public always. The last question is about changing visibility and overriding functions, do we want that, or should we mark lamdas as final? Note that preceeding the function names with a \0 does not help. In fact it might confuse reflection. Actually how does it integrate with reflection? Comments about the implementation: - ZendEngine2/zend_compile.c: Why provide forward declaration for free_filename(), simply putting the new function above the first user avoids it and does the same with increased maintainability. s/static void add_lexical_var (/static void add_lexical_var(/ Other than that it all looks fine. marcus Monday, June 16, 2008, 7:39:19 PM, you wrote: Hi, As a followup to the discussion in January, I'd like post a revised patch to this list that implements closures and anonymous functions in PHP. INTRODUCTION Closures and lambda functions can make programming much easier in several ways: 1. Lambda functions allow the quick definition of throw-away functions that are not used elsewhere. Imaging for example a piece of code that needs to call preg_replace_callback(). Currently, there are three possibilities to acchieve this: a. Define the callback function elsewhere. This distributes code that belongs together throughout the file and decreases readability. b. Define the callback function in-place (but with a name). In that case one has to use function_exists() to make sure the function is only defined once. Example code: ?php function replace_spaces ($text) { if (!function_exists ('replace_spaces_helper')) { function replace_spaces_helper ($matches) { return str_replace ($matches[1], ' ', 'nbsp;').' '; } } return preg_replace_callback ('/( +) /', 'replace_spaces_helper', $text); } ? Here, the additional if() around the function definition makes the source code difficult to read. c. Use the present create_function() in order to create a function at runtime. This approach has several disadvantages: First of all, syntax highlighting does not work because a string is passed to the function. It also compiles the function at run time and not at compile time so opcode caches can't cache the function. 2. Closures provide a very useful tool in order to make lambda functions even more useful. Just imagine you want to replace 'hello' through 'goodbye' in all elements of an array. PHP provides the array_map() function which accepts a callback. If you don't wan't to hard-code 'hello' and 'goodbye' into your sourcecode, you have only four choices: a. Use create_function(). But then you may only pass literal values (strings, integers, floats) into the function, objects at best as clones (if var_export() allows for it) and resources not at all. And you have to worry about escaping everything correctly. Especially when handling user input this can lead to all sorts of security issues. b. Write a function that uses global variables. This is ugly, non-reentrant and bad style. c. Create an entire class, instantiate it and pass the member function as a callback. This is perhaps the cleanest solution for this problem with current PHP but just think about it: Creating an entire class for this extremely simple purpose and nothing else seems overkill. d. Don't use array_map() but simply do it manually (foreach). In this simple case it may not be that much of an issue (because one simply wants to iterate over an array) but there are cases where doing something manually that a function with a callback as parameter does for you is quite tedious. [Yes, I know that str_replace also accepts arrays as a third parameter so this example may be a bit useless. But imagine you want to do a more complex operation than simple search and replace.] PROPOSED PATCH -- I now propose a patch that implements compile-time lambda functions and closures for PHP while keeping the patch as simple as possible. The patch is based on a previous
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi Marcus, very nice work. Thanks! The only thing I don't like is the function naming (“\0__compiled_lambda_FILENAME_N”). Can we drop the \0? I used \0 because it is already used in two other places: 1) create_function (run-time lambda functions) uses \0__lambda_N 2) build_runtime_defined_function_key uses \0 to start function names. I can drop it if you like; personally, I don't care for either solution - it's an internal name that *may* leak to userspace in some circumstances but is never really useful for userspace anyway.. A minor side-note here: I oriented myself at build_runtime_defined_function_key at the time of writing but I have noticed a slight discrepancy between function names generated by build_runtime_defined_function_key and the normal function names: When stored in the corresponding function_table hash, for runtime defined function keys it is opline-op1.u.constant.value.str.len, whereas for normal function names it is »Z_STRLEN_P(...) + 1« and thus including the *trailing* (not preceding!) \0 in the hash key for normal function names but not including it for runtime defined function keys. Any idea why that is the case? [For the record: I'm refering to the code that is already used in PHP, not to my patch!] Or did you use the \0 prefix to prevent direct invocations? No, direct invocations are prevented by the is_lambda == 1 is_closure == 0 check. I think the best option would be to force lambda functions being public always. They are. If you look at my modified version of zend_do_begin_function_declaration, you will see that: if (is_lambda CG(active_class_entry)) { is_method = 1; fn_flags = ZEND_ACC_PUBLIC; if (CG(active_op_array)-fn_flags ZEND_ACC_STATIC) { fn_flags |= ZEND_ACC_STATIC; } } else if (is_lambda) { fn_flags = 0; } The only attribute that is inherited from the parent function is whether that function is static or not. The last question is about changing visibility and overriding functions, do we want that, or should we mark lamdas as final? Internal representations of lambda fuctions should never be overridden, so yes, ZEND_ACC_FINAL would probably be a good idea. Overriding them won't work anyway since the new opcode that instantiates a closure will always use the class in which the closure was defined to look it up. I'll add that. Actually how does it integrate with reflection? Good question, I will investigate that and come back to you. Comments about the implementation: - ZendEngine2/zend_compile.c: Why provide forward declaration for free_filename(), simply putting the new function above the first user avoids it and does the same with increased maintainability. s/static void add_lexical_var (/static void add_lexical_var(/ Ok, I will fix that. Regards, Christian -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] [PATCH] ext/phar/util.c
d:\devel\php\php5\ext\phar\util.c(1832) : error C2036: 'void *' : unknown size d:\devel\php\php5\ext\phar\util.c(1864) : error C2036: 'void *' : unknown size NMAKE : fatal error U1077: 'C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe' : return code '0x2' Stop. Index: ext/phar/util.c === RCS file: /repository/php-src/ext/phar/util.c,v retrieving revision 1.55.2.10 diff -u -r1.55.2.10 util.c --- ext/phar/util.c15 Jun 2008 22:51:46 - 1.55.2.10 +++ ext/phar/util.c 17 Jun 2008 11:12:50 - @@ -1827,12 +1827,12 @@ */ static int phar_add_empty(HashTable *ht, char *arKey, uint nKeyLength) /* {{{ */ { - void *dummy = (void *) 1; + char *dummy = (char *) 1; if (SUCCESS == zend_hash_find(ht, arKey, nKeyLength, (void **)dummy)) { dummy++; } - return zend_hash_update(ht, arKey, nKeyLength, dummy, sizeof(void *), NULL); + return zend_hash_update(ht, arKey, nKeyLength, (void*)dummy, sizeof(void *), NULL); } /* }}} */ @@ -1856,7 +1856,7 @@ /* we use filename_len - 1 to avoid adding a virtual dir for empty directory entries */ for (; s - filename filename_len - 1; s++) { if (*s == '/') { - void *dummy; + char *dummy; if (FAILURE == zend_hash_find(phar-virtual_dirs, filename, s - filename, (void **)dummy)) { continue; } @@ -1864,7 +1864,7 @@ if (!--dummy) { zend_hash_del(phar-virtual_dirs, filename, s - filename); } else { - zend_hash_update(phar-virtual_dirs, filename, s - filename, dummy, sizeof(void *), NULL); + zend_hash_update(phar-virtual_dirs, filename, s - filename, (void*)dummy, sizeof(void *), NULL); } } } = Done. Index: ext/phar/util.c === RCS file: /repository/php-src/ext/phar/util.c,v retrieving revision 1.55.2.10 diff -u -r1.55.2.10 util.c --- ext/phar/util.c 15 Jun 2008 22:51:46 - 1.55.2.10 +++ ext/phar/util.c 17 Jun 2008 11:12:50 - @@ -1827,12 +1827,12 @@ */ static int phar_add_empty(HashTable *ht, char *arKey, uint nKeyLength) /* {{{ */ { - void *dummy = (void *) 1; + char *dummy = (char *) 1; if (SUCCESS == zend_hash_find(ht, arKey, nKeyLength, (void **)dummy)) { dummy++; } - return zend_hash_update(ht, arKey, nKeyLength, dummy, sizeof(void *), NULL); + return zend_hash_update(ht, arKey, nKeyLength, (void*)dummy, sizeof(void *), NULL); } /* }}} */ @@ -1856,7 +1856,7 @@ /* we use filename_len - 1 to avoid adding a virtual dir for empty directory entries */ for (; s - filename filename_len - 1; s++) { if (*s == '/') { - void *dummy; + char *dummy; if (FAILURE == zend_hash_find(phar-virtual_dirs, filename, s - filename, (void **)dummy)) { continue; } @@ -1864,7 +1864,7 @@ if (!--dummy) { zend_hash_del(phar-virtual_dirs, filename, s - filename); } else { - zend_hash_update(phar-virtual_dirs, filename, s - filename, dummy, sizeof(void *), NULL); + zend_hash_update(phar-virtual_dirs, filename, s - filename, (void*)dummy, sizeof(void *), NULL); } } } = Done. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] deprecation status of $str{42} versus $str[42]
Stefan Walk wrote: You're not learning from the mistakes of other languages (ruby in this case, which removed Enumerable from String in 1.9) ... foreach makes no sense for strings, because it's unclear what you want (with unicode terminology here, as this is for php6): for each byte for each codeunit for each codepoint, or for each line, or ... You bring up a good point. However, as a counterpoint, Python does allow strings to be used as arrays: s = 'asdf' for c in s: print c In my opinion, it only makes sense for foreach to emulate the code snippet I posted above: for binary strings, that means byte-by-byte, and for Unicode strings, that means codepoint by codepoint. But as I said, it would be neat. This is by no means an essential feature, and I probably wouldn't be able to use it anyway for BC concerns. if you want to use foreach in your example, just do foreach (str_split($str) as $value) { ... I would never do that, because it requires allocating an entire another PHP array, more than doubling memory usage, just to iterate across a string. If I'm doing this sort of heavy string processing, I probably need some semblance of performance. -- Edward Z. YangGnuPG: 0x869C48DA HTML Purifier http://htmlpurifier.org Anti-XSS Filter [[ 3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA ]] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Larry Garfield wrote: $e = new Example(); $lambda = $e-myMethod(); $e-$lambda(5); That doesn't seem right at all, but that's how I interpret Essentially, closures inside methods are added as public methods to the class that contains the original method. Can you give an example of what that actually means? At first blush, this sets off warning bells in my head, I suppose because my notion of a lambda says that the lambda should not carry any baggage about the context it was created in. However, with further thought, I believe that binding the lambda's lexical scope to the place it was defined is: * Conducive to good coding (you will always be able to look outside the lambda to find out where the lexical variables are coming form) * Adds functionality, since anything you want to pass to the function via the callee's context can be passed via a parameter What would be neat, however, is the ability to rebind the lambda to another context. Also, I don't know how other languages do it (Python? Lisp?). -- Edward Z. YangGnuPG: 0x869C48DA HTML Purifier http://htmlpurifier.org Anti-XSS Filter [[ 3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA ]] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] wiki update
Hello, I just updated wiki.php.net to the 2008-05-05 release [1]. No data should have been lost. Aside from minor visual tweaks the main improvement is that we now default to a diff in the RSS feeds. We might see some other tweaks today (or over the course of the day). The main thing we are working now during the hackday 2 co-workers and myself are holding here at Liip is to allow people to choose between the dokuwiki and the reST syntax. regards, Lukas Kahwe Smith [EMAIL PROTECTED] [1] http://wiki.splitbrain.org/wiki%3Achanges -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi Marcus, I now have revised my patch to include your suggestions: http://www.christian-seiler.de/temp/closures-php-5.3-2008-06-17-2.diff The changes to the previous version: - \0 at the start of the compiled lambda function name is dropped. - lambdas which are class members are now marked as final - the generated name of the lambda is now also stored within the op_array (before op_array-function_name was simply lambda) - your suggestions for code cleanups in zend_compile.c Actually how does it integrate with reflection? Consider the following class: class Example { private $x = 0; public function getIncer () { return function () { $this-x++; }; } public function show () { $this-reallyShow (); } protected function reallyShow () { echo {$this-x}\n; } } Running Reflection::export(new ReflectionClass('Example')); will yield (among other things): - Methods [4] { Method [ user public method getIncer ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 6 - 10 } Method [ user final public method __compiled_lambda_/home/christian/dev/php5.3/c-tests/reflection.php_0 ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 7 - 9 } Method [ user public method show ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 12 - 14 } Method [ user protected method reallyShow ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 16 - 18 } } So lambda functions appear simply as additional methods in the class, with their generated name. Of course, the ReflectionMethod / ReflectionFunction classes could be extended so that it provides and additional method isLambda() in order to determine whether a function actually is a lambda function. But I'd rather do that in a separate step and a separate patch. Regards, Christian -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hello, Great patch and a much needed feature. One thing I do not agree with is the point in the lexical key word, seems it should be natural to inherit the outer scope. I guess the choice of adding lexical and going slightly against the grain of typical closure implementations like scheme or ecmascript is that is not really consistent with php so i can understand disagreement and your note you made on performance. Seems like the right choice to force manual inheritance of outer scope. But great work on this, hope it gets added and none of the core developers say it is not the php way or is only useful in brainless languages. -Chris
Re: [PHP-DEV] deprecation status of $str{42} versus $str[42]
On Tue, Jun 17, 2008 at 2:21 AM, Steph Fox [EMAIL PROTECTED] wrote: Hi, Seems like you are missing some PHP programming basics. Strings are not an array of chars, please go back to making ping pong in java c# or whatever other little comp sci classes you took. PHP is not any of them. Foreach(foo as $key = $char) {}, after learning, please be quiet and let andi answer my question on his ideas he had for improvements to the existing and once favored syntax. Please, keep this kind of personal abuse off the core development list. It adds absolutely nothing to the debate, and we're all very, very bored with it I was trying to have a productive discussion on the topic, his response is the one that added no value, was nothing but a troll. Anyways, I like the fact my response brought up iterating strings, which I think as far as code points or bytes etc, go, really its the same problem as $str{0} on a Unicode string, im sure PHP6 will fix this with Unicode strings. Still, I wish this was not being removed I have a lot of legacy code around that uses it and am sure many companies do as well, and it has always felt more correct _to_me_ but it is what it is. Case closed I guess. -Chris
Re: [PHP-DEV] extensions status, to move to pecl or to drop
What would rock is to have it supported by gcov (by us or somewhere else with a public report), would it be possible? How can I get this done? I'm adding Nuno to the loop, he is the one leading the gcov initiative and will surely explain the setup in a better way than me :) I can add it, as long as you provide me instruction on what I need to install and how the configure options should look like. Also I will need to know if there's some file/environment var that needs to be modified in order to run the tests. Nuno -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hello Christian, Johannes, Tuesday, June 17, 2008, 2:24:01 PM, you wrote: Hi Marcus, I now have revised my patch to include your suggestions: http://www.christian-seiler.de/temp/closures-php-5.3-2008-06-17-2.diff The changes to the previous version: - \0 at the start of the compiled lambda function name is dropped. - lambdas which are class members are now marked as final - the generated name of the lambda is now also stored within the op_array (before op_array-function_name was simply lambda) - your suggestions for code cleanups in zend_compile.c Actually how does it integrate with reflection? Consider the following class: class Example { private $x = 0; public function getIncer () { return function () { $this-x++; }; } public function show () { $this-reallyShow (); } protected function reallyShow () { echo {$this-x}\n; } } Running Reflection::export(new ReflectionClass('Example')); will yield (among other things): - Methods [4] { Method [ user public method getIncer ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 6 - 10 } Method [ user final public method __compiled_lambda_/home/christian/dev/php5.3/c-tests/reflection.php_0 ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 7 - 9 } Method [ user public method show ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 12 - 14 } Method [ user protected method reallyShow ] { @@ /home/christian/dev/php5.3/c-tests/reflection.php 16 - 18 } } So lambda functions appear simply as additional methods in the class, with their generated name. Of course, the ReflectionMethod / ReflectionFunction classes could be extended so that it provides and additional method isLambda() in order to determine whether a function actually is a lambda function. But I'd rather do that in a separate step and a separate patch. Yep, Reflection details can and should be addressed separately. I think the next step is confirming with the rest of the core team that we all ewant this. IMO it has often enough been requested and your patch solves every tiny piece that was missing so far. And if people agree then unfortunately you need to provide a patch for HEAD first. Actually you could do so just now. Johannes, what's your take on this one for 5.3? Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi! Johannes, what's your take on this one for 5.3? I'm not Johannes and I didn't review the proposal in detail yet, but I think we have enough for 5.3 right now. I'd think we better concentrate on tying the loose ends and rolling beta out and then moving towards the release than adding more and more features and never releasing it. 5.3 is not the final release until the end of times, there will be 5.4 etc. and 6, so there will be ample opportunity to add stuff. And 5.3 has enough stuff to be released, there's no rush to add more new things, especially radically new ones. My opinion is that we better take some time with it and not tie it to 5.3. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
I'm not Johannes and I didn't review the proposal in detail yet, but I think we have enough for 5.3 right now. I'd think we better concentrate on tying the loose ends and rolling beta out and then moving towards the release than adding more and more features and never releasing it. 5.3 is not the final release until the end of times, there will be 5.4 etc. and 6, so there will be ample opportunity to add stuff. And 5.3 has enough stuff to be released, there's no rush to add more new things, especially radically new ones. My opinion is that we better take some time with it and not tie it to 5.3. Amen to that. - Steph -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
On 6/17/08, Stanislav Malyshev [EMAIL PROTECTED] wrote: I'm not Johannes and I didn't review the proposal in detail yet, but I think we have enough for 5.3 right now. I'd think we better concentrate on tying the loose ends and rolling beta out and then moving towards the release than adding more and more features and never releasing it. 5.3 is not the final release until the end of times, there will be 5.4 etc. and 6, so there will be ample opportunity to add stuff. And 5.3 has enough stuff to be released, there's no rush to add more new things, especially radically new ones. My opinion is that we better take some time with it and not tie it to 5.3. although I really want to have this functionality right now, I agree with Stas. 5.3 has a lot of new things already. this should go to HEAD, and, hopefully, it will attract more people to actually try php-6 -- Alexey Zakhlestin http://blog.milkfarmsoft.com/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hello Stanislav, nicely put but not in agreement with the PHP world. First we cannot add a new feature like this in a mini release as it comes with an API change. And second PHP is not anywhere close so we'd have to do it in a PHP 5.4 and personally I would like to avoid it. marcus Tuesday, June 17, 2008, 9:19:56 PM, you wrote: Hi! Johannes, what's your take on this one for 5.3? I'm not Johannes and I didn't review the proposal in detail yet, but I think we have enough for 5.3 right now. I'd think we better concentrate on tying the loose ends and rolling beta out and then moving towards the release than adding more and more features and never releasing it. 5.3 is not the final release until the end of times, there will be 5.4 etc. and 6, so there will be ample opportunity to add stuff. And 5.3 has enough stuff to be released, there's no rush to add more new things, especially radically new ones. My opinion is that we better take some time with it and not tie it to 5.3. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi! nicely put but not in agreement with the PHP world. First we cannot add a new feature like this in a mini release as it comes with an API change. And second PHP is not anywhere close so we'd have to do it in a PHP 5.4 and personally I would like to avoid it. You meant PHP 6 not anywhere close? well, if we keep adding completely new stuff to 5.3 then 5.3 would not be anywhere close so what we earn by that? I understand that we all want new and cool stuff in PHP, but endlessly delaying 5.3 is not the answer. And this feature is a big thing, it's not adding yet another module or function - it should be thoroughly reviewed and seen how it affect all other things. It's probably very cool addition, but yet more reason to consider all the side effects and surprises on the way. Pushing it in now would mean we'd either have to delay 5.3 yet another half-year or we'd release buggy 5.3 and then we'd be bound by API compatibility and couldn't fix things that we might want to fix. I think as much as we want to add yet another cool feature - we have to release versions for the users to actually be able to enjoy features we already added, from time to time. And time for 5.3 is very much due, and we still have a bunch of work to do on it. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Hi! I'm not Johannes and I didn't review the proposal in detail yet, but I think we have enough for 5.3 right now. I'd think we better concentrate on tying the loose ends and rolling beta out and then moving towards the release than adding more and more features and never releasing it. 5.3 is not the final release until the end of times, there will be 5.4 etc. and 6, so there will be ample opportunity to add stuff. And 5.3 has enough stuff to be released, there's no rush to add more new things, especially radically new ones. My opinion is that we better take some time with it and not tie it to 5.3. I would like to see 5.3 released first before we add really cool features like this. I'm really +1 for closures but I please for 5.4 and 6. If I may add my own personal (and biased ;-)) opinion (which may not count much but I'd like to present the arguments): I'd like to see it in PHP 5.3. Mainly because of two reasons: First: My patch is quite non-intrusive, it only adds things in a few places (new opcode, a few checks). If you only look at the non-generated files (i.e. excluding files generated by re2c or zend_vm_gen.php), the patch is actually not even that long: http://www.christian-seiler.de/temp/closures-php-5.3-2008-06-17-3-redux.diff Except for the introduction of a 'lexical' keyword I carefully designed the patch not to have *any* impact *at all* on PHPs other behaviour. I'd be genuinely surprised if any code breaks with my patch. I also don't see how this would delay 5.3 - of course things have to be tested but at least as far as I can tell the major showstoppers currently are class inheritance rules and namespaces which still cause quite a few headaches of their own. Second: If closures are not supported in PHP 5.3, even with the release of PHP 6 backwards compability will be a hindrance in using them. Since PHP 6 will have Unicode support and thus quite a few semantic changes, this will of course not matter much for the actual PHP applications since these will have to change anyway. But think of class libraries: There are many things that can be implemented in class libraries where unicode support doesn't matter at all - such as for example advanced date and time calculations (beyond timelib), financial calculations etc. Such libraries will probably want to maintain compability with PHP 5.3 as long as possible. But these libraries may profit from closures. If you still decide to include closures only from post PHP 5.3, I suggest to at least declare 'lexical' a reserved keyword in PHP 5.3. Just my 2 cents... As to the patch for HEAD: I thought it best to wait for unicode.semantics to go away along with the if (UG(unicode)) checks before implementing it (everything else would be a waste of time - since if I'm not mistaken someone is actually currently removing those). If I really am mistaken in my interpretation of the discussions here on this topic and they are not going away (at least not in the short term), I can of course provide one now (meaning the next few days). Regards, Christian -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Algorithm Optimizations - string search
Hi, Sorry for taking so long to answer, but I'm trying to catch up last stuff. It's known that usually to optimize things for longer inputs you usually end up making things for short inputs worst. So IMHO, I think you should have the len==1 optimization and then use the KMP algorithm. Your implementation can be further optimized (at least on 32 bits machines), but seems ok for now. I suggest you to produce a final patch, send it here, and then move on to optimize other things (like strtr() that I'm sure wikipedia guys will appreciate). Nuno - Original Message - Hello again I have setup small page where I am publishing all the profiling and evaluation results. It is here: http://83.168.205.202/~michal/ standard15/ So far I have put there function usage profile, zend_memnstr analysis, stripos and strrpos analysis including some charts etc. CVS diffs where applicable are also posted along with comparison of original and patched code. Michal On 2008-06-11, at 09:47, Stanislav Malyshev wrote: Hi! Here are some statistics: - average haystack length: 624.2 - average needle length: 1.9 ! - 63% of needles of length 1 - avg length of haystacks shorter than avg: 41.0 - 85% of all haystacks - avg length of haystacks longer than avg: 5685.11 I think it would be interesting to see same excluding 1-char needles since in this case it should do one-char lookup (btw, if we don't do it on C level, it might be a good idea to). Although strpos implements fix for that, some other functions don't. My idea is than to implement ZEND_MEMNSTR once again in shape: if (needle_len = 1) here just linear sweep else if haystack_len 5000 (5000 is arbitrary - maybe some more tests needed to choose good value) original implementation (as it is the best one in this case) else BM/KMP (i think BM will be better in this case, as some people suggested) I'm not sure very big haystacks really worth the trouble - how many of them are used? It may be interesting to see medians instead of averages for that. But len=1 I think worth having special case. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
Christian Seiler wrote: As a followup to the discussion in January, I'd like post a revised patch to this list that implements closures and anonymous functions in PHP. Did I miss seeing its phpt tests? A really thorough test suite might the case for inclusion in PHP 5.3. Chris -- Christopher Jones, Oracle Email: [EMAIL PROTECTED]Tel: +1 650 506 8630 Blog: http://blogs.oracle.com/opal/ Free PHP Book: http://tinyurl.com/f8jad -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
On Tuesday 17 June 2008, Christian Seiler wrote: Hi, - I am a little confused about the OOP interaction. How does a function become a public method of the class? To clarify: the public method ist just the internal representation of the lambda function and has *nothing* to do with the semantics of calling the lambda itself. The method only means that the lambda function defined inside another method can access the class members and public only means that the lambda function can still be called from outside the class. If one knew how to access it, which it seems is not possible/feasible for user-space code. class Example { private $a = 2; function myMethod($b) { $lambda = function() { lexical $b; return $this-a * $b; // This part I get }; return $lambda; } } $e = new Example(); $lambda = $e-myMethod(); $e-$lambda(5); No, that's not what my patch does. My patch does: class Example { private $a = 2; public function myMethod ($b) { return function () { lexical $b; return $this-a * $b; }; } } $e = new Example (); $lambda = $e-myMethod (4); var_dump ($lambda ()); // int(8) $lambda2 = $e-myMethod (6); var_dump ($lambda2 ()); // int(12) So esentially, it does not matter whether you define a lambda function inside a method or a function (or in global scope, for that matter), you always use it the same way. The in-class-method lambda function only has the additional advantage of being able to access the private and protected class members since *internally* it is treated like a public class method. I see. It would be great if you could update the RFC with this information so that it's clearer. If you want to add methods dynamically to classes, why not use the runkit extension? I really don't see a point in making lambda functions and closures something they are not. I was asking if they could be used for that, not to make them into a different animal. As for using runkit, do I really need to answer that? :-) Two other questions that just occurred to me: 1) What is the interaction with namespaces, if any? Are lambdas as implemented here ignorant of namespace, or do they take the namespace where they are lexically defined? 2) What happens with the following code? class Foo { private $a; } $f = new Foo(); $b = 5; $f-myfunc = function($c) { lexical $b; print $a; // This generates an error, no? print $b; // This prints 5, right? print $c; // Should print whatever $c is. } $f-myfunc(3); Or is the above a parse error entirely? -- Larry Garfield AIM: LOLG42 [EMAIL PROTECTED] ICQ: 6817012 If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of every one, and the receiver cannot dispossess himself of it. -- Thomas Jefferson -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php