Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125395 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id E36F41A00BD for ; Mon, 2 Sep 2024 19:52:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1725306896; bh=cy1G0LFatPpJVXes5gOhgMnNIrsOQJ+DyThW2Puc1Nk=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=PCLzcafeSqIA7BPIQNnUJzLN7e2jnu1oN4BOLXV4rln1tjejhFVuTTZqeqmGc13un rVvWpwrT+03VR/UsexArixjrsFtU2At9R4bX5xF3gxx7Ll62+dqVpCW6cj/rCgwX6/ tSR5q3CQvev1Kc+f5KzzMCS+PC+TFuOP35Ofn+FcCAUHpDYWZDfoa0lpe9ZgZEhzsn OIuI3JL/ecu0WeY5sxcL6mh6PB0mLbxev6o+UeODpQj7yGG61jvuRtzFJ3QHM+D0QS wJahhenBsLhVRQmS5kQIscwJxHw4eJQ7PTauR9f8phj2Scrt+2R1G2VwoxWX9yTvG4 QQhHDoLCkN9lQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2F3E61801E9 for ; Mon, 2 Sep 2024 19:54:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DMARC_MISSING,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f170.google.com (mail-yb1-f170.google.com [209.85.219.170]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 2 Sep 2024 19:54:50 +0000 (UTC) Received: by mail-yb1-f170.google.com with SMTP id 3f1490d57ef6-e164caa76e4so4305701276.1 for ; Mon, 02 Sep 2024 12:52:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1725306773; x=1725911573; darn=lists.php.net; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=rrya8u4iuEIqggZd9aW/8JwU1wbLyt82k50Q3hxKotY=; b=a+qAgr/6QYvCCMRpd7ESHWpJN0H95VhETjHrBachDPcCQ18JZdxL1umMk0SN25RudQ sq2kDJqJ2EthHDAAk7eZd+fI2cOgtFCwDk5Gb/uB+NZT1CO2jT12xvwmUWMJ7UFqnX0U w+iSkFUSTMea6f4ljZFcCShTCqoFghFMt7IoeVqgO6cTVFWlYfvjIZI1KGq0/hy3cXfE g+2eO1wRiOuyyQvba9qz/voGNFDECF4g+tlmG5Zo7IoboEXUnNTJd0CDic/RmG17KgKp p+NywTf3RHmsaTg5T3IOH4wPT1FBlTp8b2DYa17FamL++UiqpSe5O2ZcXEZr5rtvPE1x iluw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725306773; x=1725911573; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rrya8u4iuEIqggZd9aW/8JwU1wbLyt82k50Q3hxKotY=; b=mREnBE4yzcxkMA5T4BELEiNCVPMSei6eo9C5NGw/kdrU0GskWILwatwEI1GLXg2iBR k29FreI+ReQbRVs4PcjKtVjvAW7dgE2GW7nyFH+PywGIET9A7YSc6g1SLQSOiQgmuESP gYOjIjxqFK17WUk5wZz066biuS9TngyDoHqC+A/V/VNkWyMCQsdzkVreYEeGcmqPwAlq hXHQhWCsbsgN95d6bFg/Z38lQRM+BIJHCEss+q4JgkuqqnP6ekZoTRsObgiDg+UGKcEW vAZCvpUXhaqQumfTnfRDT14MB660Jek/6md/0hcY1dJld2DBxOcXXRIEhyfMGSG9oQbf 1GXA== X-Gm-Message-State: AOJu0YyO97KfjIfpjnmoxOgHv4HaYbtUUplTcCwcO7nJ4yrg8R35CG9G emowztRyw3UPhTJRS1oH5obs6rIbQxMJUQY8NozUuPKcvXgXVJMGup18nfN/x4c= X-Google-Smtp-Source: AGHT+IHBwTegugEElUR/F/ECg+UvahW5u31ezbajCHN2YlOrSOdEGVDY89YO93lrUVdw/9WPJZ46/w== X-Received: by 2002:a05:6902:100b:b0:e1a:7830:c6e6 with SMTP id 3f1490d57ef6-e1a7a02eae3mr10896069276.27.1725306772366; Mon, 02 Sep 2024 12:52:52 -0700 (PDT) Received: from smtpclient.apple (c-98-252-216-111.hsd1.ga.comcast.net. [98.252.216.111]) by smtp.gmail.com with ESMTPSA id 3f1490d57ef6-e1a6266e40esm1911496276.16.2024.09.02.12.52.51 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Sep 2024 12:52:51 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.10\)) Subject: Re: [PHP-DEV] Pre-RFC Discussion: Support for String Literals as Object Properties and Named Parameters in PHP In-Reply-To: Date: Mon, 2 Sep 2024 15:52:51 -0400 Cc: internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: <3DFFDF2E-5C2F-4DEA-9C47-3830B09D9406@newclarity.net> References: <1C1BB102-EE71-49A6-A057-C727A39FC38F@newclarity.net> To: Hammed Ajao X-Mailer: Apple Mail (2.3696.120.41.1.10) From: mike@newclarity.net (Mike Schinkel) > On Sep 2, 2024, at 1:48 PM, Hammed Ajao wrote: >=20 > Hello Mike, >=20 > Thanks for reading and responding. While your enum does technically = address some of the issues I am discussing, it does so in a very verbose = and cumbersome way. > - First you need the DefaultValue attribute > - Then you need to use it on each of your `properties` > - You also need to define an identifier for the const which defeats = the purpose of using literal strings > - Then you need to use reflection to access the properties > - Then you're left with : MyHeaders::create(MyHeaders::CONTENT_TYPE, = "plain/text", MyHeaders::X_CUSTOM_HEADER,"new_value"); which isn't super = clear that it's mapping every other value to the one before it. That is why I wrote that maybe we could consider reducing the verbosity = and more cumbersome aspects as I proactively recognized it was painful.=20= That is why I asked about other use-cases. If the only solid use-case is = HTTP headers we write it once and its done.=20 OTOH, if there are many other use-cases then we could look at adding = syntax sugar. Adding syntax sugar to languages when boilerplate patterns = emerge has many benefits: fewer bugs, easier coding, making the language = more powerful, and etc. > As for the idea that an object property must be a valid identifier, = I'm not sure that's correct. Objects can have integer properties = natively i.e $obj->{1}, and literal string properties are already = possible when you cast an array to an object Yes, that was pointed out to me.=20 I was thinking more about the PHP language for language parsers syntax = when I wrote that and thinking less about the fact that instances can = have dynamically assigned properties. My bad. > Let me show you a few other use cases i've run into >=20 > ```php >=20 > class Sizes { > public function __construct( > private string $sm, > private string $md, > private string $lg, > private string $xl, > private string $2xl, // will throw > private string "10xl", // wouldn't this be nice > ) {} > } Is that really a class that someone would write, with a different = property for each size and a constructor that required setting each = size? Or wouldn't they typically have an Enum for the sizes and an array = property indexed by the enum? Maybe your example was just to illustrate your desire for a `$2xl` and = `"10xl"` property? I see what you want here, OTOH I would not be a fan. = I'm just as happy to name them `$twoXL` and `$tenXL`, or `$_2xl` and = `$_10xl` vs. dealing with non-identifiers in declared property names. I = get that is not what you want, but realize I am not the decider, I am = just representing one person's opinion, and I can't even vote on RFCs, = so there is that. =C2=AF\_(=E3=83=84)_/=C2=AF > function htmlElement(string $tag, string $content, = string|bool ...$attr) {} > htmlElement("div", "Hello, world!", class: "greeting", id: = "greeting", "data-foo": "bar"); I did not grasp the use-case you are showing here because the one in = your original email included using non-identifiers as parameter names so = I conflated your two proposals as being one. In the case you presenting here =E2=80=94assuming I understand what you = are proposing =E2=80=94 I would likely be in favor of something like it. = That is if it were orthogonal and not requiring of your first proposal = i.e. in its own RFC.=20 Taking what you have I would expect something more like the following = but where `[HtmlAttribute]` is my placeholder for a syntax that would = specify that zero or more named parameters be collected and assigned by = property name to the object `$attr` of type `HtmlAttribute` =E2=80=94 = bikeshed away on that syntax =E2=80=94, and to assign to arrays you = specify the array index in the named argument, e.g. `data["foo"]`: class HtmlAttribute { public string $_class; public string $id; public array $data; } function htmlElement(string $tag, string $content, [HtmlAttribute] = ...$attr) {} htmlElement("div", "Hello, world!", class: "greeting", id: "greeting", = data["foo"]: "bar"); Alternately if you were not envisioning the mapping to an object a = similar feature could just be way to use a function to collect = arbitrarily names parameters into an array, e.g.: function htmlAttributes(string|int ...$attr) {} htmlAttributes(class: "greeting", id: "greeting", data["foo"]: "bar"); The above would collect the args into an array `$attr` shaped like this: array( "class" =3D> "greeting", "id" =3D> "greeting", "data" =3D> array( "foo" =3D> "greeting", ), ); Actually, it would be nice if PHP offered both options. > - Then you're left with : MyHeaders::create(MyHeaders::CONTENT_TYPE, = "plain/text", MyHeaders::X_CUSTOM_HEADER,"new_value"); which isn't super = clear that it's mapping every other value to the one before it. BTW: it could currently be written like any of the following: // 2-element arrays represents name-value pairs public static function create(string ...$headers): self {...} MyHeaders::create( [MyHeaders::CONTENT_TYPE, "plain/text"],=20 [MyHeaders::X_CUSTOM_HEADER,"new_value"] ) // 1-element arrays w/key and value represents name-value pairs public static function create(string ...$headers): self {...} MyHeaders::create( [MyHeaders::CONTENT_TYPE =3D> "plain/text"],=20 [MyHeaders::X_CUSTOM_HEADER =3D>"new_value"] ) // 1-element array w/multiple elements represents name-value pairs public static function create(array $headers): self {...} MyHeaders::create([ MyHeaders::CONTENT_TYPE =3D> "plain/text",=20 MyHeaders::X_CUSTOM_HEADER =3D>"new_value" ]) Alternately imagine some syntax sugar that allows dropping the = `MyHeaders::` from the enum reference when a parameter is declared to be = an instance of that enum: // Objects represents name-value pairs Header(MyHeaders $header, string $name):array {...} public static function create(Header ...$headers): self {...} MyHeaders::create( Header(CONTENT_TYPE, "plain/text"),=20 Header(X_CUSTOM_HEADER, "new_value") ) Finally imagine adding a feature that allows specifying that a parameter = is the result of a function call give brace enclosed parameters where = `Header(*)` is my placeholder syntax for bikeshedding, e.g.: // Objects represents name-value pairs public static function create(Header(*) ...$headers): self {...} MyHeaders::create( { CONTENT_TYPE, "plain/text" },=20 { X_CUSTOM_HEADER, "new_value"} ) #fwiw -Mike=