CloudFormation is the most featureless of the Infrastructure-as-Code template languages. It is miles behind Terraform, Azure ARM/Bicep, and Google Cloud Deployment Manger. I don't think there has been any direct improvement with the language syntax since the introduction of YAML support over a decade ago. The core syntax and functionality of CloudFormation have been frozen for many years and there is no sign that will ever change. From the outside, it appears the CloudFormation team has been under-resourced and left to rot.
Support for new resource types and properties can take up to 2 years to get implemented. If you are tied to using CloudFormation and need support for a new resource type or property, you are left with creating and maintaining custom resource types (Lambda Functions).
All recent language improvements have been in the AWS::LanguageExtensions transform, which is just an AWS manage CloudFormation Macro, and it was only release last September. CloudFormation Macros are Lambda functions that will run against a template before it is processed. They allow you to interpret your own syntax changes and transform the template before deployment.
Before this looping function support, AWS::LanguageExtensions transform didn't contain any functionality that made it compelling to use. If you were already aware of how to extend CloudFormation, you probably already had a collection of CloudFormation Macros that went above and beyond the functionality of the AWS::LanguageExtensions transform.
Currently, if you want to do anything more advanced than what is built-in, you have to create and maintain your own CloudFormation Macros (more Lambda Function). They are a pain to debug, add a lot more complexity, and increase your maintenance workload. Having AWS provide a macros that greatly extends CloudFormation into something usable would be awesome. We just aren't there yet, but this update shows there is some life left in the corpse.