Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113820 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 81884 invoked from network); 28 Mar 2021 02:52:39 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Mar 2021 02:52:39 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 6B4E51804B7 for ; Sat, 27 Mar 2021 19:49:15 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 27 Mar 2021 19:49:14 -0700 (PDT) Received: by mail-qt1-f195.google.com with SMTP id x9so7052413qto.8 for ; Sat, 27 Mar 2021 19:49:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20150623.gappssmtp.com; s=20150623; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=C+3M1tavk4JcBieodS6FVaWLeKzqUZ0XTgrYYq1L198=; b=w17VeHK91rqTcYijeKJQzDct8TqIw2uSBBIa8YckkeLIVS3aM+Uo5dAEvHkuK21IrS Inain9HHyR8+We1VBK1MH9oZTSnyCwFb98X9Pa+fEuVDv3uCCOhOkFjJ04n9/N9MkSju t6/IV59fZHvV8yRYpaRNmpOS7cCyzrLAbalM/AAg8gHCz+Z1eoES2cS3dooyE5GwbYCH VdIclHdACqcgAJGw11ctXyPcG3fo1xqhGAbJaNaJFTZie/hB7m5DMZIkldxfW4nowaUp d/Z5FouI2xt0mY6Erqp9bB3ystoE0jm0PxXDBHsXKljlqcIqMAUHhIFMIAQQJnlTKtSe 8sJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=C+3M1tavk4JcBieodS6FVaWLeKzqUZ0XTgrYYq1L198=; b=DU3HhiCEtAReYg5+o4OhRsTXDO4wdaVsZ1oqrOSmfWpn3vZ5gW5PiCz7lefG3WHqzP KJxestRZdg+CJbwOo9/fMQrFpzNmZhHHrD2nCVX1HP0hldtaO+A3ns7yGyv8Oz7P0S7F KL0Zd/ljLVfqzPbJOoypfIOTDJi6Aa68cma6wA1Md0Wv+SFEoVUSu7Dz7nJzmRTN2bLV GIAQWyMUv5lbjUF1XkZ9RJ3BhrdGBMhkGujfbCm31+kBBsjTCcfY2GszdLO4SlT/Xosh NBvzT+XLsvwZQ/JQyi7ROxM17IAUKvAWIzfLRJjxFEYdFHW1vwazBTwXipn/uvruIVNp Gj1Q== X-Gm-Message-State: AOAM530bpR+i1ET+yHWUpX2t/bzfz7nIiIKexE/QA2d6Zv04EoB3JMqj 109Ea/LcZnMrbC8EEKJChaBNhA== X-Google-Smtp-Source: ABdhPJwSm2AGdbCgM4JqlSrCry21zf3y3vERys+Dnr1qkP7/C794qE2wVPvzHrkr0b51w7J6u6ZTCA== X-Received: by 2002:ac8:7b23:: with SMTP id l3mr18018370qtu.165.1616899752417; Sat, 27 Mar 2021 19:49:12 -0700 (PDT) Received: from [192.168.1.239] (c-24-98-254-8.hsd1.ga.comcast.net. [24.98.254.8]) by smtp.gmail.com with ESMTPSA id j6sm10031758qkm.81.2021.03.27.19.49.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 27 Mar 2021 19:49:11 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\)) In-Reply-To: <3d453ce7-db16-fb75-91b4-9a2a71994164@gmail.com> Date: Sat, 27 Mar 2021 22:49:11 -0400 Cc: PHP Internals Content-Transfer-Encoding: quoted-printable Message-ID: <28DB910B-957D-4E63-A157-F6BEEA68A782@newclarity.net> References: <88c9eb5f-f80c-4869-b7f8-1b58b9e2eaa3@www.fastmail.com> <605bae82.1c69fb81.f49f7.d11eSMTPIN_ADDED_MISSING@mx.google.com> <919e30e7-3e5e-d955-7bb4-1e1b5825cdd1@gmail.com> <635DD146-FC6F-4991-8D2C-5A6B492722D5@newclarity.net> <734f12de-da98-6b76-c2fe-8682f4d177aa@gmail.com> <36E45DD6-E2BD-4801-BAAE-4355C83D1AC3@newclarity.net> <15AE4315-A456-4ED8-990A-49EBD76C5B46@newclarity.net> <5501FE70-FBED-47EB-8010-173644BC064F@newclarity.net> <3d453ce7-db16-fb75-91b4-9a2a71994164@gmail.com> To: Rowan Tommins X-Mailer: Apple Mail (2.3608.120.23.2.4) Subject: Re: [PHP-DEV] [RFC] Auto-capture multi-line closures and shortfunctions take 2 From: mike@newclarity.net (Mike Schinkel) > On Mar 27, 2021, at 12:05 PM, Rowan Tommins = wrote: >=20 > On 27/03/2021 00:05, Nuno Maduro wrote: >>=20 >> I've just added a few more tests with the exact examples you have = presented in this mail list: = https://github.com/php/php-src/pull/6246/commits/c3a50d671c5d8fa4b775ec67f= e77d0cbd5cc8030 = . >=20 >=20 > Hi Nuno, >=20 > Thanks, I hadn't thought of writing out test cases, that makes a lot = of sense; although I now realise my question wasn't very clear. >=20 > My biggest concern with automatic capture is the potential for = *accidentally* capturing variables - that is, intending to introduce a = local variable inside the closure, but capturing a variable from the = outer scope that happens to have the same name. This is less of an issue = with capture by value, but can still mean resources not being freed, = e.g. a large array of data not being freed from memory, or an object = destructor not executing when expected. >=20 > This is more likely in PHP than many other languages, because there is = no requirement, or even an option, to explicitly declare a local = variable in the closure. It's not a new problem, but since = single-expression closures are unlikely to use many local variables, = it's probably not one that's been given lots of thought. >=20 >=20 > I've written some tests that demonstrate the current behaviour using = an object destructor: = https://github.com/nunomaduro/php-src/commit/ae18662cc92f5d07520b4574dcae7= 1d38a9e0a41 >=20 > Based on those, there seems to be no way to prevent a variable being = captured, even if its value is immediately discarded each time the = closure runs. This may be less than ideal: >=20 > $results =3D getLargeReportFromDatabase(); > // ... > $fn =3D fn() { > $results =3D []; // coincidentally the same name, immediately = assigned its own value > // ... > } > unset($results); // does not free the array, because $fn has captured = the value In this case doesn't $results get released when $fn goes out of scope? =20= IOW, if fn() is used and discarded by the end of the function in which = is it declared then this accidental capture is not an issue (unless it = breaks the outer code, of course), right? If it breaks in the outer code then I would say that is not really any = different than overwriting the variable in a later loop, for example. So = not really an indictment of auto-capture. It is only if the function allows the closure to live on by returned it = directly or indirectly, assigning it to a by-reference parameter or = assigning to a property of an object that was passed in that it can = "leak." Which then begs the question of "How often do closure get returned in a = manner they have a long life AND a large number of the same types of = closures are created? I can envision how that might happen, but I = question how common that scenario would be? And finally, most to the time a PHP page terminates after a page load = thus releasing all these captured variables. Yes CLI apps and "Fiber" = apps might be different, but they are certainly less common than = request/response web pages. IOW, it feels like there would need be a confluence of many factors that = collectively are likely rare before this scenario could become a real = problem.=20 Where one solution would be, of course, to not write long functions such = that it is hard to identify accidentally captured variables. Which seems = like a best practice anyway? Did I get anything wrong above? I don't think so but then I could well = have missed something. In summary, is this accidental-capture-which-turns-into-a-resource-leak = actually a problem worth worrying about? > I wonder if the capture analysis could be made smarter to make this = less likely. >=20 >=20 > PS I'd like to apologise if some of my messages in this thread have = come across as harsh or demanding, I do appreciate you bringing up this = feature, as I know it's one a lot of people want, even if I'm sceptical. >=20 > Regards, >=20 > --=20 > Rowan Tommins > [IMSoP] >=20 > --=20 > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >=20