develooper Front page | perl.perl5.porters | Postings from October 2016

Re: Extend the fat comma to deal with undef

Thread Previous | Thread Next
Sam Kington
October 7, 2016 03:35
Re: Extend the fat comma to deal with undef
Message ID:
Thanks everyone for the feedback!

I’d like to reiterate that the problem I’m interested is when you say (foo => …, bar => … ) and you end up with an uneven list. It would be nice if there was a more robust fat comma that could protect you from that, at least for the more common uses.

On 7 Oct 2016, at 01:14, Zefram <> wrote:
> Sam Kington wrote:
>>   this => $this, # might be undef or blank
> $this can be undef, but it can't be an empty list, or in general anything
> other than one list element.  So "$this // undef" which you expand this
> to is redundant.

Sorry, yes, that was careless.

>>   that => get_that_maybe()
> A sub call can yield any number of list elements, so this is the
> one that needs attention (which in this example you didn't give it).
> You've talked about a sub call yielding an empty list, but you omitted to
> mention the possibility of it yielding more than one value.  The effect
> you're looking for for your `mandatory' fat comma is simply to put its
> rhs into scalar context, which is what "scalar()" or "// undef" does.

Yes, I’m increasingly of the opinion that the mandatory fat comma isn’t a fantastically useful idea - and thank you to everyone who has commented on this subject.

I am still interested in the optional fat comma, though, which would gobble the lhs if there was nothing on the rhs (once forced into scalar context): e.g.:

foo =>? 'bar'          # produces ()'foo', 'bar')
foo =>? ()             # produces ()
foo =>? ('foo', 'bar') # produces foo => 2
foo =>? maybe_foo(), bar =>? maybe_bar()
# produces potentially ('foo', ..., 'bar', ...),
#  ('foo', ...) or ('bar', ...)

So the =>? operator (or whatever it would end up as) would consider everything between it and either comma, semicolon or a closing brace (or anything else I’ve forgotten about that matters to the parser).

>> my %thing_params = (thing => $thing);
>> $thing_params{this} = $this if $this;
>> if (my $that = get_that_maybe()) {
>>   $thing_params{that} = $that;
>> }
>> do_thing(%thing_params);
> can be written inline as
>    do_thing(
> 	thing => $thing,
> 	($this ? (this => $this) : ()),
> 	do { my $that = get_that_maybe(); $that ? (that => $that) : () },
>    );

Sure. But that’s clumsy, and the constant repetition of names is what drove me to want this feature. It’s not too bad when using toy examples; it’s when you start using longer identifiers that things break down: for instance

    will_always_have => $will_always_have,
    $optional_setting ? (optional_setting => $optional_setting) : (),
    ? (other_optional_setting => $other_optional_setting)
    : (),
    do {
        my $mandatory_override = get_mandatory_override_maybe();
            ? (mandatory_override => $mandatory_override)
            : ()


    will_always_have       =>  $will_always_have,
    optional_setting       =>? $optional_setting,
    other_optional_setting =>? $other_optional_setting,
    mandatory_override     =>? get_mandatory_override_maybe(),

In the first example I said mandatory_override five times, compared to only twice in the second example. 

>> And that's annoyingly messy. It would be a lot nicer if there was
>> an infix operator that acted like the fat comma, but gobbled the lhs if
>> the rhs was undef or missing:
> Ah, but what should that condition be, exactly?  Is it only undef that
> means the key should be omitted?  That's not the condition you used in
> the above example, where you tested truthiness, not definedness, of both
> $this and $that.  That is, should "0" be a null value alongside undef?
> It acts as a null in your example above, but not in the criterion you just
> stated.  And there's the rub: the condition controlling whether the key
> should be included varies between situations.  No single "=>?" operator
> can handle even the most common variations.  Whereas the existing ?:
> operator can handle any condition.

Sorry, you’re right, and I was sloppy. I meant to say e.g. (foo =>? ()) should become (). =>? expects there to be two elements in the list, and if there aren’t there should be none instead, so as to not break hashes etc.

Considering *only* the optional fat comma, here’s what I’d think would be reasonable behaviour:

It quotes the lhs, like the standard fat comma does.
It forces the rhs into scalar context.
If the rhs ends up being undef, it throws away both the lhs and the rhs.

And actually, there’s still a vague case for the mandatory fat comma: it just does the first two things. That’s not fantastically useful, but it beats having to type // undef everywhere, and it acts as an intermediary step towards the more useful optional fat comma.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About