http://www.perlmonks.org?node_id=564869


in reply to Re: Secret Perl Operators: the boolean list squash operator, x!!
in thread Secret Perl Operators: the boolean list squash operator, x!!

obscure implementation details

Disagree. The shape of booleans in Perl 5 is specified behaviour, and is only going to become more explicit in Perl 6.

I would instead suggest that a clearer, more maintainable version might be ($string) x ($cond ? 1 : 0)

If you’re using a ternary anyway, why would you want to throw in an x op? All that does is lose the shortcircuiting, make the code longer, and force some extraneous parens. Just do all the work using the ternary: $cond ? $string : ()

I don’t find either of your original “problem” examples to be particularly onerous

I’d never use the push version. The one with ternaries doesn’t look onerous because there are so many conditional bits that you have no hope of putting it all on a single line anyway, and the lists are simpler than the conditionals, and it’s highly regular, and all. I was trying to come up with an example that can’t be simplified using grep.

I can’t recall the exact code that led me to post the thread on perl6-users which led Larry to nudge me in this direction, but it was a case of injecting a single list into the arguments of a one-liner join, where precedence forced me to parenthesise things, so the version using the ternary absolutely was more ornery than it should have been. With such a short list, it’s more annoying than the example I gave in the root node, because nothing really helps – putting it on a single line makes it unwieldy, breaking it into multiple lines makes it breathlessly verbose, using an extra temporary looks hackish. Sticking an x!! wouldn’t have been ideal, but would certainly read better than all the alternatives.

Makeshifts last the longest.

  • Comment on Re^2: Secret Perl Operators: the boolean list squash operator, x!!

Replies are listed 'Best First'.
Re^3: Secret Perl Operators: the boolean list squash operator, x!!
by Tanktalus (Canon) on Jul 31, 2006 at 22:47 UTC

    That !0 == 1 is not "well-defined" that I've noticed - perhaps someone could point out precisely where this is stated in a way that is not only definitive, but unambivalent (e.g., I don't want to see docs saying "It works this way, but don't trust it.").

    I have found referenced in perlsyn that ! $true_value returns something special. But it says nothing about ! $false_value.

    As for perl6, that's not part of the current conversation. As in, if they explicitly document that this is how the not operator works, great, it's explicit. Perl 5 doesn't document it, though, as tye pointed out in Re: One out of three ain't bad (order), perl 5 can't change it now.

    Even then, what really is a boolean in numeric context? What is a list, multiplied by "true" times? Or by "false" times? These are conceptually wrong. Just as adding "true + true" to try and get "2" (you don't - you get "true"). You may as well be trying to multiply $string x 'banana' - it makes as much sense.

    Except that computer programmers seem to think that 0 == false and 1 == true. Which is a horrible habit to be in (especially when someone gets the brilliant idea to compare if ($var == true)). Let's not expand on that disservice by promoting its further abuse. Instead, let's promote using booleans as booleans, numbers as numbers, and strings as strings. Now, before someone chews my head off ("That's not the perl way! We luvs our automatic type-changes!"), I do think that Larry got it right in Perl6. These automatic changes aren't actually so automatic. They use deep amounts of context to figure it out. And, if we continue with the warnings of perl5 (where things are allowed, but you're probably not doing it right - turn off warnings if you are), some automatic changes will continue to get warnings, even though they work. I hope that booleans in numeric context will be one of them. Unless, of course, you manually set something to say you want a specific boolean (or booleans in general) to have certain values in numeric (or even string) context. For example, setting:

    Bool.context(:numeric(true => 1, false => -1)); Bool.context(:string(true => Locale.gettext("true"), false => Locale +.gettext("false"));
    Or something like that (my perl6-fu is weak - that was intended to be something approaching a global setting). After all, what is the stringification of a boolean value? Shouldn't that be language-specific? Perhaps one variable should be "true" and "false" - but another variable should be "enabled" and "disabled". Of course, then another could use "male"/"female" (unless you need to keep track of 'other'), or "cowabunga dude!"/"to infinity and beyond!" or ... whatever you want. Of course, that would be more like $bool_var.context(...) or something

    Anyway, my point is that booleans != numbers. Anymore than strings are numbers. Using computers, we just have to store them as numbers, because we don't have anything else to store them with. We have boolean operators, numeric operators, and string operators. Use the right operators for the type of data you're using. If you want numbers, convert from boolean to numeric. Make it explicit. The next guy to take care fo the code will thank you.

      I don't want to chew your head off, but I don't want to loose wantarray either. Strings are numbers, and numbers are strings, all of them are sequences of bits, utf-8 strings are binary and a file is a sequence of bytes or a set of records, which are sets of fields. It depends all of how you look at them, and that's called context. That's why IV and SV exist, and that's why a number is stored internally as a string as well, if it was used in string context; and both representations are strung together.

      perl's context awareness may seem a swamp of pitfalls, but that's only until you understand it (by which statement I don't want to insinuate that you don't understand it.) But once you can speak perl it is just handy. In the long run? I don't know. Maybe we should just stick to C.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        That !0 == 1 is not "well-defined" that I've noticed - perhaps someone could point out precisely where this is stated in a way that is not only definitive, but unambivalent (e.g., I don't want to see docs saying "It works this way, but don't trust it.").

      I can still remember Drew Sullivan, currently GTALUG President, pointing out years ago that !!!0 == 1 works, even if !0 == 1 is not necessarily accurate.

      Alex / talexb / Toronto

      "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds