|
|
Subscribe / Log in / New account

Scalar typing in the PHP world

By Jonathan Corbet
February 13, 2015
When one thinks about the PHP language, terms like "strong typing" and "strict checking" do not normally come to mind. But, as the project works toward its next major release (to be called PHP 7), it has become embroiled in a fierce debate over the proposed addition of some simple typing features to the language. To some, PHP is growing up into a safer, better-defined language, while others see the changes as possibly destroying the character of a historically freewheeling language.

Some history

PHP has traditionally taken a loose approach to types, trying to make things "just work" in almost all circumstances. A simple session in the interpreter's interactive mode shows how accommodating it can be:

    $ php -a
    php > echo 1 + "1";
    2
    php > echo 1 + true;
    2
    php > echo 1 + "1with_extra_junk";
    2

This flexibility undoubtedly makes PHP fun for some programmers to use; there is little of the messing around required by some other languages to keep the interpreter happy. Among other things, it allows the creation of library functions that can take a wide variety of types as parameters and do something (maybe even the right thing) with them.

But others would like to see things tightened down a bit. It would be nice, they argue, if a PHP function could count on the types of the arguments passed to it. That would enable certain kinds of errors to be caught by the interpreter; it would also make it easier to write static analyzers for the language that could be used for both correctness checking and performance improvements. These developers have made their case well enough that there is little controversy about adding some type checking; the problem arises when one tries to determine how much checking makes sense.

The specific issue at hand has to do with the passing of simple, scalar parameter types to functions — types like integers, floating-point numbers, strings, and booleans. The first attempt to add type hints for these parameter types was posted by Anthony Ferrara in 2012. It changed the function-definition syntax to look like this:

    function f ((int) arg) {
	// "arg" is guaranteed to be int here
    }

This version implemented what has been termed "weak" typing, in that a non-integer argument passed to f() would be converted to the int type if possible. So floating-point numbers would be truncated, strings would be converted, etc. This proposal generated a lot of discussion that eventually bogged down; a year later, Anthony loudly bailed out of PHP development, strongly criticizing the environment found on the php-internals mailing list.

PHP voting

The discussion of a vote may be surprising to those who are not familiar with how the PHP community works. Perhaps uniquely among language-development communities, PHP decides issues of language design via a vote of the developers. Issues involving an actual change to the language are deliberately hard to pass; they require a ⅔ supermajority.

Two years later (July, 2014), Andrea Faulds restarted the conversation with a new scalar type-hinting proposal. It was still a weakly typed mechanism; this time the bulk of the discussion centered on whether conversion of bogus strings ("1with_extra_junk", say) to integers should succeed or not. Yes, there are core PHP developers who believe that integer conversions should silently "succeed" in the presence of random junk. The proposal returned in September, with a request for a vote that was withdrawn shortly thereafter; yet another version came out in December.

Weak or strong?

As the various versions of the proposal went by, the real point of contention became clear. Nobody seems to object to the idea of adding scalar type hints to function definitions; the real problem had to do with how strictly they would be enforced. The "strict typing" camp wants the interpreter to disallow all implicit type conversions; if f() is defined to require an integer argument, calls like f(1.0) or f("1") should generate an error. In this view of the world, if an API developer puts type declarations onto a function, that function must be called with parameters of exactly the specified type.

The arguments for strict checking are fairly straightforward. It can catch errors that weak (or no) type checking will miss — the sort of nasty error that never happens on a developer's test system but which certain types of users can provoke easily. Strict checking lets API developers design their code with the knowledge that it will be called with the correct types. It also expands the range of static analysis options available, again turning up errors but also, it is said, opening the door to new optimization techniques.

On the other side, opponents of strong typing feel that it would drastically change the nature of the language. PHP has always allowed a high level of freedom in the mixing of types. Changing that for PHP 7 would create a language that, in their view, is not PHP. Among these folks, many of whom are core developers of the language, adding strong typing would seemingly be like trying to get Python developers to add braces or Perl developers to restrict themselves to "one way to do it." Opponents also worry that strict typing may just lead developers to write lots of casts, effectively taking away the benefits that strict typing is supposed to provide.

An attempt at compromise

Andrea appears to have despaired of ever bridging the gap between these two factions; instead, she put together a new proposal that tried to please everybody, then called for a vote. In the call, she optimistically said "I don’t think there needs to be, or will be, much further discussion"; that is not how things turned out.

The new scalar typing mechanism is still weakly typed, but with a twist. A PHP developer can add a line like this to their code:

    declare(strict_types=1);

The effect of this line will be to turn on strict scalar type checking for the rest of the source file in which it is found. Library authors can add types to their function definitions; they can even turn on strict checking within the library with the above option. But it will be the author of the calling code who decides whether or not to add that line to their own code and turn on strict checking for their program.

In theory, this mechanism gives everybody what they want; developers who want to work in a strict-checking environment can have it, while those who want weak typing get it by default. In practice, this approach appears to have pleased almost nobody. Proponents of strong typing would rather see it enabled as a mandatory thing; they want callers of their functions to be required to pass the correct types. Opponents, instead, see it as a way of sneaking an alien concept into the language. PHP creator Rasmus Lerdorf also worries that it could end up breaking a lot of code and generally leading to surprising results.

To top it off, almost nobody seems to like the use of declare() which, among other things, can make it hard to tell which rules apply to a given segment of code. As Zeev Suraski put it:

If there's one thing that's worse than introducing an alien concept like strict typing into PHP, it's introducing it as a feature that will include all the negatives of this alien concept, PLUS have the ability to radically change how it behaves based on a runtime option.

Even the declare() option has proponents, though; Anthony returned to the fray to argue in its favor:

This is where the current proposal comes in. Many call it a compromise. Many call it a "worst-of-both-worlds". I call it the only way to do strict typing in PHP that won't utterly suck.

The genius of this proposal is that your code controls how you call other functions. So if you want your code to be strict, any function you call will be treated strictly. But if you don't want to be strict, then the functions you call will accept weakly.

The current vote is scheduled to end on February 19. As of this writing, the results suggest that proposal might just pass with something very close to the required supermajority. In theory, that should put this long-lived debate to rest; long experience suggests, though, that an issue this contentious will not be resolved quite so easily.


to post comments

Scalar typing in the PHP world

Posted Feb 14, 2015 0:07 UTC (Sat) by mathstuf (subscriber, #69389) [Link] (8 responses)

Since we're in the wonderful world of PHP syntax, why not:

weak checking:
> function f ((int) arg)

strict checking:
> function f (((int)) arg)

At least php.ini hasn't been enough of a suggestion to make the article.

Scalar typing in the PHP world

Posted Feb 14, 2015 13:11 UTC (Sat) by Thue (guest, #14277) [Link] (7 responses)

That would break the PHP paradigm, effectively force all users to always use strict typing, for fear that a "4" slipped through somewhere and crashed a strong type check in a library somewhere.

The patch's "caller decides strictness" is really very elegant. The callee gets what he expects, and the caller (he generates the disputed values) can use the strictness level he prefer.

Scalar typing in the PHP world

Posted Feb 15, 2015 3:45 UTC (Sun) by mathstuf (subscriber, #69389) [Link] (6 responses)

But with this, the called can set the setup if the caller doesn't hasnt made a decision. I just hope the current solution has a way to tell you warnings about this stuff so it can eventually get fixed.

Anyways, it was somewhat tongue-in-cheek anyways since I, personally, care very little for how PHP goes about patching its gaping flaws. This won't stop me from putting every PHP app I do use into its own little playground with read-only filesystem over fcgi so it can't mess things up and I never have to worry about conflicting php.ini settings. I boggle at folks running mod_php (assuming it still means PHP and Apache share address space).

Scalar typing in the PHP world

Posted Feb 16, 2015 11:26 UTC (Mon) by Thue (guest, #14277) [Link] (5 responses)

> But with this, the called can set the setup if the caller doesn't hasnt made a decision. I just hope the current solution has a way to tell you warnings about this stuff so it can eventually get fixed.

If the caller doesn't set strict checking, then he has made the decision to not have it checked, and to not try to "eventually fix" it.

PHP has always allowed weak typing. You are suggesting to remove weak typing to make it into a completely different language, make all existing PHP code obsolete.

Scalar typing in the PHP world

Posted Feb 16, 2015 14:14 UTC (Mon) by mathstuf (subscriber, #69389) [Link] (4 responses)

> You are suggesting to remove weak typing to make it into a completely different language, make all existing PHP code obsolete.

Eh, I see no problem there ;) .

Anyways, I was suggesting that the default behavior be to *warn* if you don't declare whether you want the weak or strong typing. If it is clean, you can add the strictness. With it being opt-in, you have *no idea* what will break when you turn it on. And testing is not one of the strong suits of PHP apps I've seen…

Scalar typing in the PHP world

Posted Feb 16, 2015 14:53 UTC (Mon) by JGR (subscriber, #93631) [Link] (1 responses)

Warning seems a bit pointless with PHP, as it requires someone to actually read the logs. I would suspect that that is even more of a rarity than testing.

Scalar typing in the PHP world

Posted Feb 16, 2015 15:29 UTC (Mon) by mathstuf (subscriber, #69389) [Link]

Well, IME, it seems that logs do get read, but usually by the enduser when they get puked into the HTML stream rather than syslog.

Scalar typing in the PHP world

Posted Feb 16, 2015 20:59 UTC (Mon) by Thue (guest, #14277) [Link] (1 responses)

> With it being opt-in, you have *no idea* what will break when you turn it on.

You can't just expect to turn on strict typing and have it work out of the box.

Adding warnings everywhere in non-strict would bury normal warnings, again virtually forcing everybody to use strict typing, since ignoring warnings is insane.

Scalar typing in the PHP world

Posted Feb 16, 2015 21:04 UTC (Mon) by Cyberax (✭ supporter ✭, #52523) [Link]

> virtually forcing everybody to use strict typing, since ignoring warnings is insane.
You're telling this like it's a bad thing.

Poor arguments against

Posted Feb 14, 2015 0:15 UTC (Sat) by Thue (guest, #14277) [Link] (123 responses)

The arguments against just seem so weak to me.

Taking Rasmus' email, he starts with two examples:

> tan(1);

That is a point, since tan will have the float type hint. But Andrea's plan is next introduce a numeric type hint to handle exactly this problem. So this is hardly a reason to oppose.

> echo strstr("test", "est", 1);

Here Rasmus is using 1 instead of true, for no good reason, which is just silly. An int is not a bool.

The whole rest of the email talks about declare. Andrea has described it as a per-file directive, and it will work just fine that way. It happens that you can also set it on and off in the middle of the file, which does lead to some funky behavior, but just because you can do that doesn't mean you should! And there are also talk about using e.g. "<?php strict" instead, but I really can't see that the way of enabling per-file strict mode should be that important.

Zeev seems to think that strict typing is just not the PHP way, will break code in some way. I suppose that importing non-strict code into a strict file could confuse some, but it just doesn't seem that big a deal to me (you can always put the imported code into its own non-strict file). Code which works in strict mode will always work in non-strict mode.

I have been following the debate, but I had to go re-read those two emails to try to remember what the opponents even use as arguments. The logic of the opposition just seems so fuzzy and weak to me. The opponents seem to that with their gut conclusion (no), and then try to justify that conclusion.

Poor arguments against

Posted Feb 14, 2015 19:50 UTC (Sat) by PetervF (subscriber, #68517) [Link] (122 responses)

I oppose this RFC for two reasons.

Firstly, I don't really see the point in strict typing. There has never been a difference between "4" and 4 in PHP, and I don't see what adding one is going to accomplish, except a load of useless casts (in that the behavior of the code is exactly the same, so why bother) everywhere, making the code less readable.

You get the IDE type inference advantages from weak typing. Strict typing just adds runtime errors for situations where what you want to do is unambiguous.

Secondly, using two different typing system is confusing. It add's another piece of context, no matter how trivial, that I don't want to have to deal with.

In php <7 i know what this line of code does:
> array_slice($array, $_GET['offset'],10)
I don't in php 7, it might work, it might not, and that sucks.

For my own projects, I'm probably going to use weak typing, catch the lossy data conversion notices, and convert them into errors. This seems the best of both worlds.

Poor arguments against

Posted Feb 14, 2015 23:34 UTC (Sat) by HelloWorld (guest, #56129) [Link] (108 responses)

> There has never been a difference between "4" and 4 in PHP, and I don't see what adding one is going to accomplish, except a load of useless casts
There is not reason to ever pass around an integer in the form of a string. The only place where that makes sense is when data first enters the program (GET parameters and such). If this kind of code makes up a significant part of your program then you're Doing It Wrong.

Poor arguments against

Posted Feb 15, 2015 0:13 UTC (Sun) by mchapman (subscriber, #66589) [Link] (104 responses)

> There is not reason to ever pass around an integer in the form of a string.

On the other hand, there is also no need to convert it from string to integer until necessary.

This looks like just another thing that Perl got right, all those years ago. *Operations* should be typed, not values. There's no confusion about what $a + $b means if + can only ever mean "numeric addition", not "string concatenation" or "array union". In PHP, it's all three, and the only thing that distinguishes them is the types of the arguments, and those aren't even expressed in the code!

Poor arguments against

Posted Feb 15, 2015 1:05 UTC (Sun) by gerdesj (subscriber, #5446) [Link] (7 responses)

"*Operations* should be typed, not values."

Madness! Fancy specifying what you _mean_ in code (unambiguously) rather than leaving it to the data to provide some sort of context.

The Perl way would seem to me to be the best way for a scripting language to operate. It provides some safety in that you are saying what you mean in a pretty explicit way but not too prescriptive (ints cast to doubles as required etc). Silly things like string to int don't go bad: Is "1 or 2" 1 or 2? I think 1 + "1 or 2" is probably 2 in PHP rather than 3 but is it?

Poor arguments against

Posted Feb 15, 2015 1:08 UTC (Sun) by HelloWorld (guest, #56129) [Link] (4 responses)

Shouldn't 1 + "1 or 2" be "2 or 3"?

Poor arguments against

Posted Feb 15, 2015 16:07 UTC (Sun) by mathstuf (subscriber, #69389) [Link] (3 responses)

What about "2 ps 3" or "2!ps!3"?

Poor arguments against

Posted Feb 15, 2015 20:23 UTC (Sun) by HelloWorld (guest, #56129) [Link] (2 responses)

I don't understand. Was it not obvious that I was joking? Or am I missing a joke in your comment?

Poor arguments against

Posted Feb 15, 2015 21:30 UTC (Sun) by mathstuf (subscriber, #69389) [Link] (1 responses)

I was continuing the joke (it being that 1+string could also be map((1+), string)).

Poor arguments against

Posted Feb 15, 2015 21:35 UTC (Sun) by HelloWorld (guest, #56129) [Link]

Oh, I get it now. Like most jokes, it's not funny any longer if you have to explain it. Oh well.

Poor arguments against

Posted Feb 16, 2015 13:58 UTC (Mon) by gerdesj (subscriber, #5446) [Link] (1 responses)

php > echo 1 + "1 or 2";
2

Clearly, 1 + "1 or 2" should be 4:

php > echo 1 + (1 | 2);
4

Poor arguments against

Posted Feb 26, 2015 12:27 UTC (Thu) by Wol (subscriber, #4433) [Link]

Shoudn't it be 13 - unlucky for some! :-)

Cheers,
Wol

Poor arguments against

Posted Feb 15, 2015 1:20 UTC (Sun) by HelloWorld (guest, #56129) [Link] (7 responses)

> This looks like just another thing that Perl got right, all those years ago.
Yes, but let's not jump to conclusions here and do as if there's any kind of sanity in the Perl language. There isn't. And let's not forget that ML got that (and *many* other things) right something like 15 years before Perl.

Poor arguments against

Posted Feb 15, 2015 6:29 UTC (Sun) by mchapman (subscriber, #66589) [Link] (5 responses)

> Yes, but let's not jump to conclusions here and do as if there's any kind of sanity in the Perl language. There isn't.

No, there isn't. Perl is unapologetically a pragmatic language only, not the epitome of purity.

I don't know anything about ML, so I can't comment on that. I am, however, continually astonished that language designers keep making the same mistakes over and over again.

For what it's worth, I support the use of type hints, whether that be as discussed here for PHP, or in Perl (Method::Signatures etc.), Python (PEP 484), or whatever. They may be useless for the language implementation itself -- a "correct" program in these languages must remain correct if all the type hints are stripped -- but they assist the programmer.

However, I still think that going down the route of having different type *values*, where 4 and "4" are distinct and not interchangeable, is a bad idea when it comes to these kinds of languages. As gerdesj pointed out, that can easily lead to program behaviour that isn't actually specified in the source code.

Poor arguments against

Posted Feb 15, 2015 13:47 UTC (Sun) by HelloWorld (guest, #56129) [Link] (4 responses)

> No, there isn't. Perl is unapologetically a pragmatic language only, not the epitome of purity.
Perl is supposed to be a high-level language, but as soon as you create a reference cycle anywhere in your program it's going to leak memory. It didn't have subroutine signatures until a few months ago. Nesting anonymous subs creates closures while nesting named subs doesn't. (3, 5) == (4, 5) is true… err, I mean 1. This isn't pragmatic, this is just broken, broken, broken, broken, unusably broken.

Poor arguments against

Posted Feb 15, 2015 16:45 UTC (Sun) by flussence (guest, #85566) [Link] (3 responses)

I agree; expecting a numeric equality operator to introspect arbitrary data structures and do a deep structural comparison of their contents is truly a broken, utterly insane way of thinking. Classic PHP.

Perl does the sane thing, and compares the only numeric property of the array: the length. Deep comparisons are done with the eqv operator which of course has been around for over a decade. It's no surprise PHP is ten years behind, not only in its design but its user's perceptions of the outside world. What an awful echo chamber to live in.

Poor arguments against

Posted Feb 15, 2015 17:38 UTC (Sun) by HelloWorld (guest, #56129) [Link] (2 responses)

> I agree; expecting a numeric equality operator to introspect arbitrary data structures and do a deep structural comparison of their contents is truly a broken, utterly insane way of thinking. Classic PHP.
There's no point in having different equality operators because the purpose is always the same: testing for equality. And in fact, this works just fine in sane languages such as Haskell.

> Perl does the sane thing, and compares the only numeric property of the array: the length
No, it doesn't. (3,5) and (4,5) aren't arrays, they're lists, and comparing two lists yields a different result than comparing two arrays. (3,5) == (4,5) because their last elements match, therefore (1,3,5) == (4,5) as well. You're welcome to explain how that is sane. But then, I can't blame anyone for not grokking Perl, the sheer amount of pointless complexity makes that an arduous endeavour.

> Deep comparisons are done with the eqv operator which of course has been around for over a decade.
There is no eqv operator in perlop(1) and eq doesn't do deep comparisons.

Poor arguments against

Posted Feb 15, 2015 22:02 UTC (Sun) by flussence (guest, #85566) [Link] (1 responses)

>There's no point in having different equality operators because the purpose is always the same: testing for equality. And in fact, this works just fine in sane languages such as Haskell.

I don't think any non-joke comparison operator will return true for sanity("Haskell") == sanity("PHP"), sorry.

Let's return to the original topic, wherein you try to bash Perl by comparing your outdated strawman effigy of it to PHP.

>No, it doesn't. (3,5) and (4,5) aren't arrays, they're lists, and comparing two lists yields a different result than comparing two arrays.

Comparing values and pointers numerically works differently in other languages too. Where do you draw the line at which ones are broken or not for doing so? Is C broken?

>(3,5) == (4,5) because their last elements match, therefore (1,3,5) == (4,5) as well. You're welcome to explain how that is sane.

Ah, you constructed a deliberately contrived example to maintain a "clever" comeback in reserve.

Nice try. It won't work on me.

Quoting from the same perlop document you referenced:

> Binary "," is the comma operator. In scalar context it evaluates its left
> argument, throws that value away, then evaluates its right argument and
> returns that value. This is just like C's comma operator.

It looks like C, it behaves like C. Consistent, justifiable behaviour. Read perldata(1) if you'd like to reattempt that criticism from a position of cluefulness.

>There is no eqv operator in perlop(1) and eq doesn't do deep comparisons.

I thought we were comparing like-for-like here - hence trying to be on-topic by comparing what an unreleased-as-of-2015 new major version of PHP offers compared to the equivalent Perl version. Or are you now complaining that *that's* somehow unfair?

But if you insist on comparing PHP 2015 to Perl 1995, allow me to introduce you to one of the core features of every other reasonable scripting language released in the past twenty years: a usable module ecosystem! You can satisfy your urgent need for deep comparison operators in Perl 5 at metacpan.org - or they may already be in your distro's package manager (alongside hundreds of python, ruby *and* haskell modules - fancy that!). If not, they're one `cpan` command away.

The batteries aren't included, but they're also replaceable and not leaking acid everywhere.

I leave you with the following fine piece of PHP 7 code for consideration:
<? $a = ["123", "456A", "78"]; print_r([$a[0] < $a[1], $a[1] < $a[2], $a[2] < $a[0]]); ?>

Poor arguments against

Posted Feb 15, 2015 22:59 UTC (Sun) by HelloWorld (guest, #56129) [Link]

> Let's return to the original topic, wherein you try to bash Perl by comparing your outdated strawman effigy of it to PHP.
Dude, what are you talking about? First of all, I never even mentioned PHP, Perl's madness speaks entirely for itself. Secondly, I consider them both crap. Thirdly, there is *nothing* outdated about what I wrote about Perl, all those behaviours persist.

> Comparing values and pointers numerically works differently in other languages too.
This has nothing to do with pointers.

> Where do you draw the line at which ones are broken or not for doing so? Is C broken?
C is broken in many ways, equality is one of them. There's no reason an expression like 'a' == 97 should even be well-typed, much less be 1.

> Consistent, justifiable behaviour.
You lost when you started talking about “scalar context”. No other language has that notion and that's for a reason: it's a useless complexity generator. Nobody sane needs it.

> I thought we were comparing like-for-like here - hence trying to be on-topic by comparing what an unreleased-as-of-2015 new major version of PHP offers compared to the equivalent Perl version.
Again, I don't care what PHP does. They both suck.

> Perl 1995
Again, all of the behaviours I pointed out above persist to this day (except the lack of subroutine signatures).

> You can satisfy your urgent need for deep comparison operators in Perl 5 at metacpan.org
Why would I use a language that doesn't even come with a sane notion of equality built in?

HelloWorld is a subscriber

Posted Feb 17, 2015 12:38 UTC (Tue) by rvfh (guest, #31018) [Link]

I see you've subscribed! Well done :-)

Now, your comments are not filtered anymore :-P

Poor arguments against

Posted Feb 15, 2015 8:36 UTC (Sun) by alankila (guest, #47141) [Link] (86 responses)

On the other hand, you rapidly run out of usable operator characters if you actually wish to continue with the operator-guided type coercion.

To illustrate the issue, Perl actually ended up reusing ^ for both numbers and strings, e.g. 0^1 is number 1, but "0"^"1" is the binary value "\x01". On the other hand, Perl rather uniquely has ^^ which is logical-xor. It's not short-circuiting operator despite what it looks like, but it does signify that it does boolean interpretation of the LHS and RHS, which is why it exists.

Looking into the future and upcoming release of Perl6, we are about to grapple a large array of operators that again enhances Perl's look of line noisiness: http://doc.perl6.org/language/operators and I think that's harmful. There is some value in maintaining newbie friendliness and using library constructs for functionality that must be pretty rare to run on in practice.

There are some utterly baffling things as well like this:

substr('abc': 1); # same as 'abc'.substr(1)

because Tim is croaking again, I guess.

Poor arguments against

Posted Feb 15, 2015 8:56 UTC (Sun) by dlang (guest, #313) [Link] (1 responses)

> There are some utterly baffling things as well like this:
>
> substr('abc': 1); # same as 'abc'.substr(1)
>
> because Tim is croaking again, I guess.

This is just Perl continuing to support "if it works in other languages, try it and it will probably work" approach.

That's how most programmers invoke the function substr() on the string 'abc' in python and javascript for example.

Used properly it can greatly simplify the text and make it more readable. Used badly and it can make things next to impossible to decipher.

One more case of Perl providing rope to the developers for them to do with as they will.

Poor arguments against

Posted Feb 16, 2015 19:08 UTC (Mon) by alankila (guest, #47141) [Link]

I just think it's going to add another weird thing to remember when you are reading Perl. My guess is that someone really loved to be able to do substr($a, $b, $c) so they had to keep some form of it rather than force transformation to $a.substr($b, $c). This reminds me of (but is clearly less irritating) the syntactic issue with the indirect object notation, which ordinarily allows Perl to attempt to parse any sequence of barewords into some kind of (static) method invocation nonsense. In other words, I'm predisposed to think that this too is another bad idea.

Poor arguments against

Posted Feb 15, 2015 13:19 UTC (Sun) by HelloWorld (guest, #56129) [Link] (80 responses)

Sensible languages (i. e. with strong, static typing) don't need a logical xor, because they already have it. It's typically spelled !=, <> or /=.

Poor arguments against

Posted Feb 15, 2015 16:14 UTC (Sun) by dlang (guest, #313) [Link] (73 responses)

"not equal" is not anything close to "exclusive or"

Poor arguments against

Posted Feb 15, 2015 18:05 UTC (Sun) by HelloWorld (guest, #56129) [Link] (72 responses)

It's the exact same thing. The only thing that could convince one of the contrary is intellectual mutilation caused by extended use of languages that pretend that boolean operators make sense on anything other than booleans.

Poor arguments against

Posted Feb 16, 2015 7:51 UTC (Mon) by niner (subscriber, #26151) [Link] (71 responses)

You mean languages that actually help the programmer be productive.

Poor arguments against

Posted Feb 16, 2015 8:12 UTC (Mon) by HelloWorld (guest, #56129) [Link] (20 responses)

They don't.

Poor arguments against

Posted Feb 16, 2015 8:16 UTC (Mon) by niner (subscriber, #26151) [Link] (19 responses)

Because....you say so. And you know the needs of every single programmer in the world. So whatever you say must unquestionably be true.

Poor arguments against

Posted Feb 16, 2015 22:26 UTC (Mon) by HelloWorld (guest, #56129) [Link] (18 responses)

Well, I guess it depends on what you compare it to. More productive than C or Pascal or something? Probably, but that's not very hard. More productive than a modern language with a modern type system like Haskell or Scala? No way. The tricky part isn't setting the default in case an optional value isn't there, it's keeping track of which values are optional. “clever” operators help with the former, decent type systems with the latter.

Poor arguments against

Posted Feb 17, 2015 9:37 UTC (Tue) by niner (subscriber, #26151) [Link] (17 responses)

Yes, as we've seen in this thread, it only takes two people and some discussion over the course of hours to come to a solution for assigning a default value in Haskell. Quite productive, I imagine.

Well, Perl 6 brings a decent type system in addition to the existing productivity features.

Poor arguments against

Posted Feb 17, 2015 12:59 UTC (Tue) by HelloWorld (guest, #56129) [Link] (16 responses)

Clearly you're not interested in a sensible discussion, so I'll stop wasting my time with you. Have a nice life.

Poor arguments against

Posted Feb 17, 2015 14:28 UTC (Tue) by niner (subscriber, #26151) [Link] (15 responses)

Because sentences and phrases like "This isn't pragmatic, this is just broken, broken, broken, broken, unusably broken." and "And in fact, this works just fine in sane languages such as Haskell.", "Perl's madness" and "Nobody sane needs it." were meant to facilitate a sensible discussion. I sincerely wonder what a senseless argument of yours would look like.

Poor arguments against

Posted Feb 17, 2015 22:44 UTC (Tue) by HelloWorld (guest, #56129) [Link] (14 responses)

Allright, I apologize if my admittedly rather blunt criticism of Perl and other languages hurt anybody's feelings. Perhaps we can now return discuss this rationally.

Yes, as we've seen in this thread, it only takes two people and some discussion over the course of hours to come to a solution for assigning a default value in Haskell.
No. The fromMaybe function I pointed to is perfectly satisfactory for the majority of cases where the default is a pure expression. Now if you don't like Haskell's separation of side-effecting computations and pure computations (I can see how operators like <$>, <*> and >>= can appear a bit scary at first), Scala's Option.getOrElse method does the same thing and one doesn't have to worry about side effects there. In any case, conflating boolean operators and unrelated things like optional values is not necessary to reap the benefits.

My points on the other hand still stand:

  • How is it justifiable to call a language “high-level” when one has to worry about memory leaks through reference cycles?
  • The convenience of Perl's // operator can be easily had in languages like Scala or Haskell, while the advantages of the latter (e. g. helping you keeping track of which values are optional and which aren't) haven't made it into Perl 5, and likely never will.
  • Perl's behaviour when nesting named subs (i. e. “Variable "$x" will not stay shared”) is confusing and useless
  • the utility of Perl's notion of “context” has yet to be convincingly demonstrated

I'm looking forward to your counter-arguments.

Poor arguments against

Posted Feb 17, 2015 23:25 UTC (Tue) by pizza (subscriber, #46) [Link] (12 responses)

> How is it justifiable to call a language “high-level” when one has to worry about memory leaks through reference cycles?

Oh come now, you're setting up a strawman here.

Leaking memory due to cyclical references is a well-known quirk of reference-counted, garbage-collected MM systems, and solving that particular problem in a generic manner is quite costly.

Cyclical reference memory leaks are also a sign that the programmer doesn't understand the implications of their data structures.

Poor arguments against

Posted Feb 18, 2015 0:07 UTC (Wed) by HelloWorld (guest, #56129) [Link] (11 responses)

> Cyclical reference memory leaks are also a sign that the programmer doesn't understand the implications of their data structures.
Wrong, there are many perfectly sensible and widely-employed cyclical data structures. One example that comes to mind are finite state machines, another one is parsing combinators.

Poor arguments against

Posted Feb 18, 2015 0:34 UTC (Wed) by mchapman (subscriber, #66589) [Link] (10 responses)

In my experience, the benefits of reference counted objects outweigh these problems. For instance, reference counting gives you guarantees on when an object's destructor is called -- RAII is only half the story, after all.

Perl programmers know that this is the memory model perl uses, so they write their code accordingly; they know when they need to explicitly tear down cyclical data structures or mitigate the problem in some other ways, such as by weakening particular references. It simply isn't a big issue.

Poor arguments against

Posted Feb 18, 2015 8:08 UTC (Wed) by HelloWorld (guest, #56129) [Link] (6 responses)

> In my experience, the benefits of reference counted objects outweigh these problems. For instance, reference counting gives you guarantees on when an object's destructor is called
Not if the data structure happens to be cyclic, therefore it's an incomplet solution at best. Rust gets this right.

> Perl programmers know that this is the memory model perl uses, so they write their code accordingly;
That's the point, Perl programmers need to think about this sort of things, and this is exactly the kind of thing that a high-level language should relieve one of. Cycles can hide in very surprising places.

Poor arguments against

Posted Feb 18, 2015 8:34 UTC (Wed) by mchapman (subscriber, #66589) [Link] (5 responses)

> That's the point, Perl programmers need to think about this sort of things, and this is exactly the kind of thing that a high-level language should relieve one of.

Yeah, so? All programming languages have required knowledge.

Optimizing a language for new programmers is a losing strategy. You're only new to a language once.

Poor arguments against

Posted Feb 19, 2015 21:52 UTC (Thu) by HelloWorld (guest, #56129) [Link] (4 responses)

> Yeah, so? All programming languages have required knowledge.
This has nothing to do with being new to a language. It has to do with not solving a problem even though the solution is known and has been for decades. Anyway, I don't really care if you agree or not. A language that requires me to think about memory management is not high-level, period.

Poor arguments against

Posted Feb 20, 2015 4:34 UTC (Fri) by mathstuf (subscriber, #69389) [Link] (3 responses)

So what do you call managing space leaks in Haskell if not "memory management"? Or is Haskell not high level?

Poor arguments against

Posted Feb 20, 2015 5:50 UTC (Fri) by nybble41 (subscriber, #55106) [Link] (2 responses)

I don't think most programmers would consider that "memory management". The runtime is still transparently taking care of allocating memory and freeing it when it's no longer required. It's not even a "space leak", really, since that would imply that the program is failing to free memory that it no longer needs. When non-strict evaluation results in higher memory use, it's because the inputs to an expression are larger than the final value—e.g. you need the sum of a long list and don't otherwise care about the contents. If you compute the sum eagerly then you can free the list and just store the sum, at the cost of potentially wasting some CPU time if the sum isn't needed later. Since the expression hasn't been evaluated yet, the inputs are still needed, and aren't being "leaked".

This is more about controlling the order of evaluation than managing memory. It isn't something which affects most programs, but it is something you have to be aware of when working in a non-strict language like Haskell, particularly when summarizing large data structures. Sometimes it works the other way, though; for example, `print (take 5 [1..])` requires constant memory (~1 list element) due to non-strict evaluation, whereas strict evaluation would demand infinite memory just to evaluate the `[1..]`.

Poor arguments against

Posted Feb 21, 2015 6:08 UTC (Sat) by zlynx (guest, #2285) [Link] (1 responses)

This sounds like exactly the sort of arguments Java programmers start to make when their software takes up too much RAM.

"No, it isn't a memory management problem. We just happened to completely redesign the object storage system to better manage object lifetimes."

And you look at what they did and realize it would have been simpler to write it in C++.

Poor arguments against

Posted Feb 22, 2015 5:07 UTC (Sun) by nybble41 (subscriber, #55106) [Link]

I realize this thread is getting way off topic, but the original point was about actual object leaks in Perl where objects with cyclic references will never be freed, even if none of them are accessible from active code. That is a good example of a problem with memory management, or rather a failure of the system to manage memory automatically. Dealing with cycles is one of the basic functions of a garbage collector; if you have to design your program to avoid them or risk leaking objects, you might as well be managing memory manually.

Anyway, the point was that the fundamental purpose of memory management is to recognize and free memory which will never be accessed throughout the remainder of the program so that it can be reused for new objects. In C++ all memory management is manual. Breaking cycles in Perl is something the programmer must do to ensure that unreachable objects get freed. That is low-level manual memory management. Redesigning an object storage system to better track object lifetimes is also memory management, albeit at a much higher level: an ideal garbage collector would recognize "reachable" objects which will in fact never be accessed regardless of the input and free them; manually removing the references is a hint necessitated by imperfect garbage collection.

On the other hand, I would not consider modifying an algorithm to compute a result a different way to be memory management, even though it may have an effect on the amount of memory required. Changes in evaluation order can have a fundamental impact on the nature of the program, to the point of altering whether it's computable at all within finite time. This is not to say that managing the order of evaluation in Haskell is any less work than managing memory manually in C++, just that it doesn't come under the heading of memory management. The equivalent task in C++ would be designing the algorithm, though in C++ it's much more difficult to defer evaluation, and you're consequently less likely to consider that option.

Poor arguments against

Posted Feb 18, 2015 8:18 UTC (Wed) by mbunkus (subscriber, #87248) [Link] (2 responses)

> In my experience, the benefits of reference counted objects outweigh these problems. For instance, reference counting gives you guarantees on when an object's destructor is called -- RAII is only half the story, after all.

I'm not sure this was meant, but unfortunately there are no such guarantees in Perl. Perl only guarantees that your object will be destructed sometime after its reference count has reached zero. This could be directly after its visibility ends. Or it could be at the end of the program. Or sometime in between.

This is very different from C++ where there are hard rules about when objects are destructed. I really love this about C++.

Poor arguments against

Posted Feb 18, 2015 8:32 UTC (Wed) by mchapman (subscriber, #66589) [Link] (1 responses)

> I'm not sure this was meant, but unfortunately there are no such guarantees in Perl.

The documentation says:

"""
When the last reference to an object goes away, the object is destroyed. [...] If you want to do something when the object is destroyed, you can define a "DESTROY" method in your class. This method will always be called by Perl at the appropriate time, unless the method is empty.
"""

But Perl is what the perl(1) binary does, no matter what its documentation says. DESTROY is called from sv_curse, which itself is called by sv_free or sv_free2, the latter of which is invoked by SvREFCNT_dec if the refcount hits zero. People have been relying on this behaviour for years; it is unlikely to ever change.

Poor arguments against

Posted Feb 18, 2015 8:59 UTC (Wed) by mbunkus (subscriber, #87248) [Link]

True enough. I also compared two different sets of things here: ref-counted objects in Perl vs. normal objects in C++. Of course they behave differently. As soon as you use ref-counted objects in C++ (e.g. std::shared_ptr<>) the situation is much more like in Perl. So please disregard my previous comment; I shouldn't have sent it.

Poor arguments against

Posted Feb 18, 2015 7:37 UTC (Wed) by niner (subscriber, #26151) [Link]

> Allright, I apologize if my admittedly rather blunt criticism of Perl and other languages hurt anybody's feelings.

Thank you!

> (I can see how operators like <$>, <*> and >>= can appear a bit scary at first)

Indeed. So we now have Perl, Haskell and PostgreSQL looking like line noise. Maybe that's not so bad a trait after all...

> How is it justifiable to call a language “high-level” when one has to worry about memory leaks through reference cycles?

Honestly, I think I've written only one application in almost 20 years of Perl where this was an issue and it's easily resolved by using weak references. Nevertheless Perl 6 does away with reference counting and uses a modern garbage collector instead.

> The convenience of Perl's // operator can be easily had in languages like Scala or Haskell, while the advantages of the latter (e. g. helping you keeping track of which values are optional and which aren't) haven't made it into Perl 5, and likely never will.

Yes, flexibility is a two edged sword. I would not discount Perl 5 though. If Perl has one advantage over the other commonly used languages, it's the ability to evolve. Perl went from ridiculously bare bones OO to one of the most advanced meta object protocols there are. And Perl 6 advances the ability to evolve even further. Aside from providing a decent type system, real method signatures and more.

> Perl's behaviour when nesting named subs (i. e. “Variable "$x" will not stay shared”) is confusing and useless

Yes, that's surely true, but again something one gets used to. And it's fixed in Perl 6.

> the utility of Perl's notion of “context” has yet to be convincingly demonstrated

I do find it somewhat useful at times, hurtful at other times. Perl 6's designers considered it too much of a confusion and replaced it by type coercions.

Haskell's design is heavily influenced by mathematics, while Perl's design is influenced by linguistics. It's only natural that these languages find fans in different audiences. That said, I think many people in #perl6 actually like Haskell.

Poor arguments against

Posted Feb 16, 2015 8:48 UTC (Mon) by marcH (subscriber, #57642) [Link] (49 responses)

> You mean languages that actually help the programmer be productive.

Productive thanks to a non-boolean xor? Now I'm curious, example?

Unless you were actually just referring to a bitwise operator.

Poor arguments against

Posted Feb 16, 2015 8:55 UTC (Mon) by niner (subscriber, #26151) [Link] (48 responses)

I was talking about boolean operators that work on non-boolean data. Like Perl's defined-or operator.

my $foo = bar('baz') // $default_foo;

is just so much less to type, read and understand than:

my $foo = bar('baz');
if (not defined $foo) {
$foo = $default_foo;
}

and can be used in expressions like foo($bar // 'whatever'). Same goes for other boolean operators like && and || (together with the low precedent variants 'and' and 'or').

Poor arguments against

Posted Feb 16, 2015 14:12 UTC (Mon) by HelloWorld (guest, #56129) [Link] (47 responses)

There's nothing wrong with having an operator to make the handling of optional values easy. What wrong is conflating it with something that is completely unrelated, i. e. boolean operators. In Haskell you'd write let foo = fromMaybe defaultFoo (bar "baz") or foo <- fromMaybe defaultFoo <$> bar "baz" depending on whether or not bar "baz" invokes side effects.

Poor arguments against

Posted Feb 16, 2015 19:32 UTC (Mon) by marcH (subscriber, #57642) [Link] (46 responses)

> What wrong is conflating it with something that is completely unrelated, i. e. boolean operators.

It's not "completely" unrelated if you keep short-circuit evaluation in mind, but yeah it's very confusing and hard read for non-experts in the language, and probably error-prone for wannabe experts, too.

While the code samples provided by niner are interesting (in the "History of programming languages" sense of "interesting"), I still haven't seen any example of non-boolean and non-bitwise XOR. Not being a Perl or PHP expert, did I miss it?

Poor arguments against

Posted Feb 16, 2015 20:34 UTC (Mon) by HelloWorld (guest, #56129) [Link] (1 responses)

Lazy evaluation can help with that to a degree. When one does fromMaybe foo bar, foo won't be evaluated unless bar is Nothing. The same holds for fromMaybe foo <$> bar, i. e. when bar can invoke side effects. However, if both foo and bar invoke side effects, one would have to write fromMaybe <$> foo <*> bar and both the side effects caused by foo and by bar would be executed, even if bar yields Nothing. But given that side-effecting actions are first-class values in Haskell, it's trivial to write something like fromMaybe which does the right thing in that case: fromMaybeM def value = value >>= maybe def return.

Poor arguments against

Posted Feb 16, 2015 22:48 UTC (Mon) by HelloWorld (guest, #56129) [Link]

> both the side effects caused by foo and by bar would be executed, even if bar yields Nothing
Oops, it should be “even if bar does yield a value”.

Poor arguments against

Posted Feb 16, 2015 23:33 UTC (Mon) by rgmoore (✭ supporter ✭, #75) [Link] (43 responses)

I still haven't seen any example of non-boolean and non-bitwise XOR.

I don't think you'll see one from Perl because its logical xor behaves differently from logical and and or. Logical and and or can short circuit and return the last value they looked at because it will have the same truth value as the overall expression. Logical xor can't short circuit, so it can't use the same trick. Perl might have decided to return whichever of the inputs was true as its true value, but it chose to return 1 for true instead.

Poor arguments against

Posted Feb 17, 2015 14:54 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (42 responses)

Perl does state that ^^ short circuits on two true values.

Poor arguments against

Posted Feb 17, 2015 17:27 UTC (Tue) by marcH (subscriber, #57642) [Link] (34 responses)

> Perl does state that ^^ short circuits on two true values.

Evaluating both sides is the exact opposite of the definition of short-circuit.

Mere documentation oversight? Do you have a pointer?

Poor arguments against

Posted Feb 17, 2015 18:02 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (33 responses)

It[1] means that if you had:

> a ^^ b ^^ c

and a and b were truthy, c is not executed.

[1]http://doc.perl6.org/language/operators#infix_%5E%5E

Perl6's ^^

Posted Feb 17, 2015 19:03 UTC (Tue) by marcH (subscriber, #57642) [Link] (32 responses)

Fascinating, thanks.

- So this does not run the function:

"a" ^^ "b" ^^ func_with_side_effects_returns_true()

- whereas parentheses can be used to force the function to run and have side effects like this, correct?

"a" ^^ ( "b" ^^ func_with_side_effects_returns_true() )

(I am NOT saying this would be good programming - side effects in expressions like these are typically evil anyway)

Perl6's ^^

Posted Feb 17, 2015 19:32 UTC (Tue) by mbunkus (subscriber, #87248) [Link] (31 responses)

Short-circuiting is not just about side-effects, it's also about efficiency. Even completely side-effect-free functions can be costly to run.

Perl6's ^^

Posted Feb 17, 2015 20:04 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (27 responses)

Well, in this case, I think that the short-circuiting behavior of ^^ is *very* surprising[1]. You have three return values: "", Nil, and some truthy value. You have no idea if the 'else' branch of an if statement is because there were no truthy values or more than one without storing it in a variable (though I wouldn't be surprised to find that Perl has a built-in variable for "last control statement expression result" or even "last conditional expression result").

[1]Then again, I find many of Perl's operators surprising in and of themselves, but I digress…

Perl6's ^^

Posted Feb 17, 2015 20:11 UTC (Tue) by mbunkus (subscriber, #87248) [Link] (26 responses)

The other logical operators (&&, ||, // and their assignment variants) are all short-circuiting, even in Perl < 6. I would have been way more surprised if ^^ wouldn't have been.

Perl6's ^^

Posted Feb 17, 2015 20:22 UTC (Tue) by dlang (guest, #313) [Link] (14 responses)

how can you possible short circuit xor? after you evaluate the first argument, you have no way of knowing what the result is going to be until you evaluate the second one.

Perl6's ^^

Posted Feb 17, 2015 20:24 UTC (Tue) by marcH (subscriber, #57642) [Link]

> how can you possible short circuit xor?

By inventing a brand new type of short-circuit without bothering giving it a new name.

Who cares about confusion - it's only Perl after all.

Perl6's ^^

Posted Feb 17, 2015 20:32 UTC (Tue) by mbunkus (subscriber, #87248) [Link] (12 responses)

Of course you cannot short-circuit a two-operand xor. But you can short-circuit xor consisting of three or more operands. If, at any time, two of those operands are true then the result will always be false, no matter which value the other operands have.

It's been explained at least twice in this thread with links to Perl's man page giving examples for it.

Perl6's ^^

Posted Feb 17, 2015 21:04 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (11 responses)

> If, at any time, two of those operands are true then the result will always be false, no matter which value the other operands have.

That doesn't match the diagrams on Wikipedia on xor[1]. "true xor true xor true" is "false xor true" is "true". I don't see any reasonable reduction of it such that it can be false.

[1]https://en.wikipedia.org/wiki/Xor

Perl6's ^^

Posted Feb 17, 2015 21:11 UTC (Tue) by mbunkus (subscriber, #87248) [Link] (10 responses)

You're correct, of course, and my answer was imprecise. I should not have used the word »xor« like that because it isn't the bit-wise xor. It's infix ^^. Sorry.

Perl6's ^^

Posted Feb 17, 2015 22:20 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (1 responses)

Do you at least admit that there is potential for serious confusion around this operator then (whether popular or not)? IIRC, there's some law about features of programming languages always getting (ab)used.

Perl6's ^^

Posted Feb 17, 2015 23:15 UTC (Tue) by mbunkus (subscriber, #87248) [Link]

Of course there's potential for confusion. That's always a danger with a language you're not that familiar with, especially with ones that, just like Perl, aren't that readable in the first place. For example, in PHP the ternary operator is right-associative (unlike ternary operators in any other language).

For me (and I'm really only speaking about myself here) having ^^ short-circuit is completely logical as all the other logical operators are short-circuiting as well. I find it easy to remember. Other people's brains work quite differently from my own, though, so of course they may find it a lot less logical or highly confusing.

For me »serious confusion« means a completely different set of topics in Perl. Those are also the things I dislike most about the language. For example: functions returning different results depending on context (wantarray – or the whole notion of having different contexts in the first place); the subtle but incredibly dangerous distinction between lists and arrays; all the magic and cryptically-named special variables ($_ or _ or $[ or $< or $/ or…).

Perl6's ^^

Posted Feb 18, 2015 19:41 UTC (Wed) by bronson (subscriber, #4806) [Link] (7 responses)

Now I'm really confused. You're saying "Infix ^^" is some sort of logical operation that isn't xor but everyone will be confused because '^'?

The linked page says it, "returns the first true argument if there is only one, and Nil otherwise". How is that useful? Is it common enough to be worth making it an operator? I'd google but that would obviously be futile. :)

Perl6's ^^

Posted Feb 18, 2015 19:56 UTC (Wed) by marcH (subscriber, #57642) [Link] (6 responses)

Assuming ^^ is useful, it should be part of some "list" module and given a full name and obviously not re-using the ^ symbol which is the traditional symbol for XOR.

Having the logic of this new ^^ operator somewhat related to XOR... yet different makes the re-use of the ^ symbol even worse: even more confusing, even more error-prone.

The unusual short-circuit logic which triggers only with 3 operands or more and the confusing effect of parentheses are the icing on the cake of surprises.

This looks like a futile exercise in code obfuscation; let's just stop beating a dead horse.

Perl6's ^^

Posted Feb 18, 2015 20:05 UTC (Wed) by niner (subscriber, #26151) [Link] (5 responses)

In Perl 6 ^^ is the infix operator version of the ^ junction operator.
Junction operators are: none, one (^), any (|), all (&). The infix operators behave accordingly. As such ^^'s behavior is indeed consistent with the other operators.

From Wikipedia:

List Operators

List operators construct a junction as a list:

my $options = any(1, 2, 3, 4); # Any of these is good
my $requirements = all(5, 6, 7, 8); # All or nothing
my $forbidden = none(9, 10, 11); # None of these
my $onlyone = one(12, 13, 4); # One and only one

Infix Operators

Another way to specify a junction is to use infix operators like we have already seen:

my $options = 1 | 2 | 3 | 4; # Any of these is good
my $requirements = 5 & 6 & 7 & 8; # All or nothing
my $onlyone = 12 ^ 13 ^ 4; # One and only one

Perl6's ^^

Posted Feb 18, 2015 20:19 UTC (Wed) by marcH (subscriber, #57642) [Link] (2 responses)

> Another way to specify a junction is to use infix operators...

One of the most dramatic things Open-Source changed is the fact that code is read, reviewed, reworked and read again by many more random people from many more random places with many more random backgrounds and many more education and knowledge levels. From this specific perspective Perl (and I guess PHP too - dunno it enough) are missing the open source revolution, because of this completely off the mark "There is more than one way to do it" mantra.

No Larry, computer languages should not try to emulate the fuzziness of natural languages, absolutely not. Machines are machines and humans are humans; two very different things which complement each other and don't need to copy each other.

Perl6's ^^

Posted Feb 19, 2015 7:31 UTC (Thu) by niner (subscriber, #26151) [Link] (1 responses)

Exactly! Code is a means to communicate with the next programmer and is almost incidentally executable by a computer. As you say, machines are machines and humans are humans. And humans understand human languages far better than machine code. Since the major goal is to communicate the intent of a piece of code to the next programmer that happens to read it, the fullness of a natural language can only help. And as a bonus, even the computer understands better what you're trying to achieve and thus has for example a better chance at optimizing.

Perl6's ^^

Posted Feb 19, 2015 15:25 UTC (Thu) by marcH (subscriber, #57642) [Link]

High-level abstractions and fullness are good but "There is more than one way" goes too far beyond fullness. Fullness is not the point here.

Natural languages have redundancy, semantic overlap, fuzziness, assumptions,... These have pros and cons; one (limited) purpose: expressing nuances. In pure technical communications nuances are completely unnecessary; even harmful in programming languages and any specification. For instance a natural language like English is so poorly suited to protocol specification that readers typically complain that they feel like they are reading a new, foreign language.

For driving machines (including machines that could kill), a language model to follow is not natural languages but maths: high-level, expressive, very limited redundancy and most importantly of all: unambiguous. Who wants machines to do something... "maybe"? Merely changing the vocabulary is fine since this does not change the properties, however adding assumptions and/or redundancy only brings confusion with users constantly wondering about what they are reading.

[BTW you don't seriously think that a redundant and inconsistent ^^ operator brings Perl closer to natural languages, do you?]

Perl6's ^^

Posted Feb 18, 2015 21:33 UTC (Wed) by bronson (subscriber, #4806) [Link] (1 responses)

I still don't get it. In your example, you're using ^ as an infix operator. So why does ^^ exist?

I liked Perl5, and still have some modules on CPAN, but this sort of discussion is giving me the heebie jeebies... Perl6 seems to have a number of false friends (^ and xor) and subtle nuances to learn.

Perl6's ^^

Posted Feb 19, 2015 7:27 UTC (Thu) by niner (subscriber, #26151) [Link]

^ creates a Junction: http://doc.perl6.org/type/Junction
^^ returns the first true argument if there is only one, and Nil otherwise.

Perl6's ^^

Posted Feb 17, 2015 20:26 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (9 responses)

It's not that it's short-circuiting, but *when* it does so that is surprising. To me, xor is a parity operator, so bailing on "more than one" is, IMO, silly. Not to mention a boolean operator not returning a boolean… Honestly, this is closer to "find me the first viable item in this list and signal if there is more than one such item"…which is *not* xor by any means. All I can tell is that Perl was already hard for me to decipher (I admit to some confirmation bias) and it doesn't look like Perl 6 is going to make it any easier.

Perl6's ^^

Posted Feb 17, 2015 20:46 UTC (Tue) by mbunkus (subscriber, #87248) [Link] (8 responses)

First, Perl doesn't know Booleans as a data type. Perl knows values which are truthy (or truish or whatever you want to call them – values that cause a condition to evaluate to true) and values that are falsy. But those are not types, they're whole classes of values. Similar to C, actually. Not that I think lacking a Boolean type is good or anything, but none of Perl's operators returns a Boolean because there are no Booleans.

Second, Perl 6's man page[1] doesn't even call it an »xor operator«. It calls it »infix ^^«. It's not XOR. It behaves similar to one in that its result looks similar, but that's the same as with && and ||: those two aren't bit-wise AND/OR either because they don't look at all operands either.

[1] http://doc.perl6.org/language/operators#infix_%5E%5E

Perl6's ^^

Posted Feb 17, 2015 21:00 UTC (Tue) by mathstuf (subscriber, #69389) [Link] (7 responses)

> doesn't even call it an »xor operator«. It calls it »infix ^^«

It also calls "||" the "infix ||" operator, but that doesn't stop anyone from pronouncing it "or". I can only see confusion coming from using "^^" for this for people who haven't taken that operators document to heart (and my eyes glaze over just looking at the table of contents…which lists 24(!) levels in the precedence chain).

Perl6's ^^

Posted Feb 17, 2015 21:05 UTC (Tue) by niner (subscriber, #26151) [Link] (6 responses)

How often do you think infix ^^ will be used in real world code? And how many of these cases will be actual chained uses with more than two operands where the shortcutting property will show?

I dare say that this whole discussion is kind of moot since this operator will just not be used often enough to confuse anyone and it's there mostly for completeness. Perl 6's designers placed very high value in consistency, so having an xor-like operator that in contrast to the others would not short cut would have been confusing indeed.

Perl6's ^^

Posted Feb 17, 2015 23:23 UTC (Tue) by HelloWorld (guest, #56129) [Link] (4 responses)

I don't buy that, xor is fundamentally different from and and or. The latter are fundamentally equivalent, each can be expressed in terms of the other and negation. For xor, this is not the case and this is by no means the only difference. For example, and and or are associative while xor isn't. Making an “xor” operator short-circuit is thus not sensible in my opinion, especially as it is usually generalised to more than two arguments by having it return true iff the number of true arguments is odd.

Perl6's ^^

Posted Feb 17, 2015 23:29 UTC (Tue) by marcH (subscriber, #57642) [Link] (2 responses)

You forgot that Perl6' ^^ is not xor; it's only looking like it.

Perl6's ^^

Posted Feb 17, 2015 23:34 UTC (Tue) by HelloWorld (guest, #56129) [Link] (1 responses)

Which kinda makes it inconsistent, doesn't it? So my point stands.

Perl6's ^^

Posted Feb 18, 2015 0:28 UTC (Wed) by rgmoore (✭ supporter ✭, #75) [Link]

Actually, it looks as if that doesn't make it inconsistent, because Perl 6 has done away with the built-in bitwise operators. Now, &, |, and ^ produce Junctions with different properties. And Junctions, made by joining with &, return true on a test only if all items in the Junction return true for the test, Or Junctions, made by joining with |, return true if any item returns true, and One Junctions, made by joining with ^, return true if exactly one item returns true. So ^^ returning true if exactly one item is true is consistent with ^, just not with the way ^ and xor worked under earlier versions of Perl.

Perl6's ^^

Posted Feb 17, 2015 23:31 UTC (Tue) by HelloWorld (guest, #56129) [Link]

Oops, of course xor is also associative. Sorry about that.

Perl6's ^^

Posted Feb 17, 2015 23:43 UTC (Tue) by rgmoore (✭ supporter ✭, #75) [Link]

I dare say that this whole discussion is kind of moot since this operator will just not be used often enough to confuse anyone and it's there mostly for completeness. Perl 6's designers placed very high value in consistency, so having an xor-like operator that in contrast to the others would not short cut would have been confusing indeed.

I don't buy that argument. If it's something that's rarely used, it's that much more likely to be confusing when somebody actually does use it. That's especially true because it changes behavior from the Perl 5 xor operator, which never short circuited.

The problem as I see it is that && and similar operations are associative when you chain them, so that $a && $b && $c && $d will always give the same result as ($a && $b) && ($c && $d), which gives the same result as (($a && $b) && $c) && $d. But that's not true of ^^; $a ^^ $b ^^ $c ^^ $d is not guaranteed to give the same result as ($a ^^ $b) ^^ ($c ^^ $d) or (($a ^^ $b) ^^ $c) ^^ $d. That is not what I expect, especially after seeing xor in Perl 5.

Perl6's ^^

Posted Feb 17, 2015 23:27 UTC (Tue) by rgmoore (✭ supporter ✭, #75) [Link]

The other logical operators (&&, ||, // and their assignment variants) are all short-circuiting, even in Perl < 6.

But xor is explicitly not short circuiting in Perl < 6, so it's quite surprising that ^^ is short circuiting in Perl == 6. To put it another way, $a && $b && $c is identical to ($a && $b) && $c, and $a || $b || $c is identical to ($a || $b) || $c. In Perl 5, $a xor $b xor $c is identical to ($a xor $b) xor $c. It violates the principle of least surprise that in Perl 6, $a ^^ $b ^^ $c behaves differently from ($a ^^ $b) ^^ $c.

Perl6's ^^

Posted Feb 17, 2015 20:27 UTC (Tue) by marcH (subscriber, #57642) [Link] (2 responses)

> Short-circuiting is not just about side-effects, it's also about efficiency. Even completely side-effect-free functions can be costly to run.

Of course. Any answer to the question I did actually ask?

Perl6's ^^

Posted Feb 17, 2015 21:37 UTC (Tue) by mbunkus (subscriber, #87248) [Link] (1 responses)

Sorry about that. I honestly didn't know and had to compile Rakudo Star (Perl 6) first in order to give it a try. And yes, you can cause all three terms to be evaluated by using parenthesis this way:

perl6 -e 'sub a{ say "moo"; 1 }; sub b{ say "yay"; 1 }; sub c { say "stuff"; 1 }; a() ^^ (b() ^^ c())'

This will output all three strings and not just the first two.

Perl6's ^^

Posted Feb 17, 2015 22:55 UTC (Tue) by marcH (subscriber, #57642) [Link]

> I had to compile Rakudo Star (Perl 6) first in order to give it a try.

Thanks, really appreciated.

Poor arguments against

Posted Feb 17, 2015 18:14 UTC (Tue) by rgmoore (✭ supporter ✭, #75) [Link] (6 responses)

I'd also like to see some documentation for this. As far as I can tell (e.g. by looking at the latest version of perlop) there isn't a "^^" operator in the first place. There are "&&", "||", and "//" operators listed, but there is no "^^". OTOH, there is a low precedence "xor" operator similar to the "and", "or", and "not" operators, but the documentation specifically says:

It cannot short-circuit (of course).

My quick test shows that on the version of Perl I have installed (admittedly an older version, though with the same comment in the documentation about short circuiting), "xor" returns 1 on true and undef on false. Even if xor could somehow short circuit and return one value, it doesn't make sense for it to do so on two true values, since the return value in that case must be false and thus can't be either of the two inputs. The only case where it would make sense is to return an input is when exactly one is true and, as far as I can tell, that isn't what it does.

Poor arguments against

Posted Feb 17, 2015 18:25 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

This was perl6 (see the root of the thread). Link is in the other branch of this subthread.

Poor arguments against

Posted Feb 17, 2015 18:28 UTC (Tue) by rgmoore (✭ supporter ✭, #75) [Link] (4 responses)

Now I see the source of confusion. It appears that Perl 6 is changing things compared to Perl 5. Perl 6 will have a "^^" operator (and not an "xor") that will return the value of one of its inputs on true.

The confusion for me is that it doesn't behave the way I would expect "^^" to behave when chained. It returns true if exactly one input is true, which lets it short circuit and return Nil if it finds two true values. I would expect it to return the last true value if it had an odd number of true inputs, which would make it behave the same as if you used a series of parentheses. IOW:

$a = "true";
$b = "false";
$c = "unknown";
say $a ^^ $b ^^ $c;   #prints a blank line
say ($a ^^ $b) ^^ $c; #prints "unknown"

Poor arguments against

Posted Feb 17, 2015 18:58 UTC (Tue) by marcH (subscriber, #57642) [Link] (3 responses)

> say $a ^^ $b ^^ $c; #prints a blank line
> say ($a ^^ $b) ^^ $c; #prints "unknown"

I would expect both to return nil/blank line. Did you run these?

Poor arguments against

Posted Feb 18, 2015 0:01 UTC (Wed) by rgmoore (✭ supporter ✭, #75) [Link] (2 responses)

I just tested, and the first does return Nil and the second "unknown". This makes perfect sense to me, because "true" ^^ "false" returns Nil, and Nil ^^ "unknown" returns "unknown".

Poor arguments against

Posted Feb 18, 2015 0:22 UTC (Wed) by marcH (subscriber, #57642) [Link] (1 responses)

I thought "false" was false (why did you use it?!)

Poor arguments against

Posted Feb 18, 2015 8:30 UTC (Wed) by mbunkus (subscriber, #87248) [Link]

In Perl 5 the following values are false in Boolean contexts: the number 0, an empty string, empty lists and arrays, undef and the string containing the single digit "0". All other values (including strings of any length > 0 no matter their content, e.g. "false") are true in Boolean contexts. The same is true in Perl 6 with Nil instead of undef.

Therefore in "true" ^^ "false" you have two trueish operands and therefore the result will be Nil.

Those strings are probably not the best and most self-explanatory when explaining Boolean concepts, though.

Poor arguments against

Posted Feb 16, 2015 12:31 UTC (Mon) by etienne (guest, #25256) [Link] (5 responses)

> Sensible languages (...) don't need a logical xor

Well, "^" and "!=" have different priorities, so you may want the (small) difference to reduce use of parenthesis.
if (a != b + 1) {}
if (a ^ b + 1) {}

Poor arguments against

Posted Feb 17, 2015 20:05 UTC (Tue) by HelloWorld (guest, #56129) [Link]

Fair enough. Though I suspect that logical xor is actually quite a rare occurrence.

Poor arguments against

Posted Mar 9, 2015 21:33 UTC (Mon) by ggiunta (guest, #30983) [Link] (1 responses)

Not sure if you mean this as a joke, or not, but given the general tone of this thread, I imagine everyone here is wearing their asbestos underwear already, so off we go...

I would fail your abuse of knowledge of operators precedence in a code review, and force you to always add parenthesis to your code, lest you be removed from my dev team.

Code is not supposed to be ascii art, and there is a definite limit to the benefits of terseness. Do you have a disease limiting your fingers movement? Maybe your keyboard has a couple of missing keys? What is the problem with 2 extra characters???

Someone else already stated above (or below) that code is meant to be understandable by humans first (meaning other beings than the one who wrote it in the 1st place), and execute correctly second. Amen to that.

With that off my chest, let me wax lyrical about how a bunch of extremely intelligent, highly trained, experienced developers, such as the majority of readers here surely are, seem to go nuts every single time discussions about programming languages arise (and systemd, but I think that wound will heal quicker than expected given a bit of time).
PHP is everyone's favourite scapegoat of course, but here it inexplicably got beaten to 1st place flamewar-topic by none the less than Perl! (while the Lisp gurus were somehow asleep in their caves and missed all the fun).

Is there anything we can learn from this?

Personally, what I think is that language design is not an exact science, and that we developers can not definitely not yet call ourselves engineers with a straight face. Otherwise there would not be so much disagreement, pure and simple. We're all still a bunch of artisans. Except the few ones who are truly just religious zealots ;-)

Poor arguments against

Posted Mar 12, 2015 12:13 UTC (Thu) by etienne (guest, #25256) [Link]

> asbestos underwear
> I would fail your abuse of knowledge of operators precedence in a code review, and force you to always add parenthesis to your code, lest you be removed from my dev team.

I may fail your (??abuse of??) reading and understanding English course.
I gave two C lines to show that "!=" and "^" cannot be exchanged without changing the meaning, even when simple case like "if(a != b){}" and "if(a ^ b){}" are obviously identical.

Poor arguments against

Posted Mar 10, 2015 0:44 UTC (Tue) by mpr22 (subscriber, #60784) [Link] (1 responses)

A gentlebeing knows the complete order of operator precedence in C. A true gentlebeing is never so discourteous as to demand that anyone else do so.

Poor arguments against

Posted Mar 10, 2015 6:12 UTC (Tue) by bronson (subscriber, #4806) [Link]

Beautiful and true.

Poor arguments against

Posted Feb 15, 2015 13:57 UTC (Sun) by JGR (subscriber, #93631) [Link]

"^^" seems to be a Perl6 operator, which is not quite the same as logical-xor and does in fact short circuit. http://doc.perl6.org/language/operators#infix_%5E%5E
As someone who uses Perl on a regular basis, that does seem a tad confusing and unnecessary.

Logical xor is the "xor" operator, which by the nature of logical xor, cannot short circuit.

Never knew about the bitstrings stuff, that also seems to violate the principle of least surprise a bit.

Poor arguments against

Posted Feb 17, 2015 16:57 UTC (Tue) by nix (subscriber, #2304) [Link] (1 responses)

Looking into the future and upcoming release of Perl6, we are about to grapple a large array of operators that again enhances Perl's look of line noisiness: http://doc.perl6.org/language/operators and I think that's harmful.
You never want to look at PostgreSQL then, with its operators named things like >>= and @@@ and @-@ and #>> and -|-... of course, all of them are user-defined overloaded operators, because everything in PostgreSQL is a user-defined overloaded operator, except for the bootstrap language that nobody should ever use. PostgreSQL is both a terrible example of why operator overloading should be prohibited and a shining example of just how useful it can be (isn't it *obvious* in hindsight that -|- means 'is adjacent to'? It's pictorial!)

Poor arguments against

Posted Feb 19, 2015 15:07 UTC (Thu) by mathstuf (subscriber, #69389) [Link]

That isn't operator overloading, but just user-defined operators (and AFAIK, they are specific to certain types). Overloading is doing things like "string + string" rather than having a separate operator for list concatenation. Anyways, SQL is (IMO) sufficiently narrow enough that dealing with these operators isn't that much of a big deal (then again, I very rarely write SQL, nevermind procedural SQL). Haskell is similar with the menagerie of operators available, but they're also usually confined to libraries rather than the language itself.

Poor arguments against

Posted Feb 17, 2015 9:24 UTC (Tue) by jezuch (subscriber, #52988) [Link]

> *Operations* should be typed, not values.

Isn't this what BCPL (direct ancestor of C) did?

Poor arguments against

Posted Feb 19, 2015 14:28 UTC (Thu) by etienne (guest, #25256) [Link] (1 responses)

> There is not reason to ever pass around an integer in the form of a string.

In an interpreted language, I am not sure a variable should not be able to contain those strings:
"10³", "10E6", "12 ÷ 2", "¾", "⅒", "√2", "∛8", "1.25±0.01"
"MMXV" or "ⅯⅯⅹⅪ" (Roman numeral)
"𐹢" Rumi Digit Three
Maybe even:
"4%" , "4‰", "[1..1.25["
And for another type of "typing" that cannot be (easily) done with a compiler:
"4kΩ", "2µm", "30℃", "70℉"
"2$", "3£", "5$25¢", "450¥"
I am not sure I want to write the function "is_valid_integer()" myself, but the advantage of an interpreted language is that it could do the right thing at runtime, even if your problem is unusual.

Poor arguments against

Posted Feb 19, 2015 22:01 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> In an interpreted language, I am not sure a variable should not be able to contain those strings:
Guess what, I am sure.

> "4kΩ", "2µm", "30℃", "70℉"
> "2$", "3£", "5$25¢", "450¥"
This has been possible for many years even in mainstream languages like C++.

Poor arguments against

Posted Feb 26, 2015 12:26 UTC (Thu) by Wol (subscriber, #4433) [Link]

> There is not reason to ever pass around an integer in the form of a string.

You've clearly never programmed in DataBasic, or Snobol, or various languages like that! (Or sqlite, come to that!)

The lack of type checking can be a real pain, but the idea that "all variables are strings" does have some real advantages. Not least, that when dealing with a real-world problem, it lets you apply a real-world solution without enforcing some compiler-writer's faulty idea of an axiom on you!!!

Cheers,
Wol

Poor arguments against

Posted Feb 15, 2015 17:55 UTC (Sun) by NAR (subscriber, #1313) [Link] (8 responses)

There has never been a difference between "4" and 4 in PHP, and I don't see what adding one is going to accomplish

Interoperability with other systems? If one writes "4" to a socket where the other end waits for 4, that would be annoying.

Poor arguments against

Posted Feb 16, 2015 8:33 UTC (Mon) by drag (guest, #31333) [Link] (5 responses)

A network protocol were 0x04 and 0x34 are supposed to be treated as the same thing just seems wrong.

Poor arguments against

Posted Feb 16, 2015 9:27 UTC (Mon) by NAR (subscriber, #1313) [Link] (4 responses)

The network protocol does not treat it the same, but PHP does and I think this might lead to strange bugs.

Poor arguments against

Posted Feb 16, 2015 10:14 UTC (Mon) by mchapman (subscriber, #66589) [Link] (3 responses)

> The network protocol does not treat it the same, but PHP does and I think this might lead to strange bugs.

The integer value 4 doesn't magically get turned into \x04 when written to a socket. It's up to the programmer to convert internal values to byte sequences for output, and to convert incoming byte sequences to internal values. The "outside world", whether that be network connections, files, user input, or whatever, only consists of byte sequences.

And all of this holds whether or not PHP were to have strict typing or not. The fact that PHP presently treats the integer 4 and the string "4" as much the same thing is irrelevant. Conversion between internal and external representations is necessary whether you've got strict typing or not.

Poor arguments against

Posted Feb 17, 2015 18:45 UTC (Tue) by drag (guest, #31333) [Link] (2 responses)

Well sometimes you really want a 0x04. Sometimes you really want a 0x34. Such as dealing with binary data with ascii strings mixed into it.

I ran into this with python while trying to do some interoperability with legacy hardware programming which relied on a binary protocol over serial device. It was irritatingly difficult to deal with manipulating binary data in Python and I ended up using some C-style arrays to do it, which ended up working fine and I was able to manipulate the bits and bytes how I needed to.

'Everything a string' is a nice abstraction for doing normal things on a Unix-like system, but it does get in the way.

The fact that PHP treats strings and arrays as the same thing is a problem because they are not the same things. They are very different things. They certainly never should equal each other.

I like to have the ability to transform integers to string representations of that number in a very easy manner, but only explicitly. Anything else is just a bug waiting to bite me, really. I don't want things to happen by happy accident.

Poor arguments against

Posted Feb 17, 2015 19:09 UTC (Tue) by rschroev (subscriber, #4164) [Link] (1 responses)

I ran into this with python while trying to do some interoperability with legacy hardware programming which relied on a binary protocol over serial device. It was irritatingly difficult to deal with manipulating binary data in Python and I ended up using some C-style arrays to do it, which ended up working fine and I was able to manipulate the bits and bytes how I needed to.
I find the struct module works pretty well in such cases, depending on exactly what you need to do.

Poor arguments against

Posted Feb 17, 2015 23:34 UTC (Tue) by marcH (subscriber, #57642) [Link]

> I find the struct module works pretty well in such cases,

I second that.

Drag: did "struct" not work for you and if not then why?

Poor arguments against

Posted Feb 17, 2015 1:52 UTC (Tue) by ThinkRob (guest, #64513) [Link] (1 responses)

Doesn't that prompt one to ask why PHP was chosen as the language to implement one of the endpoints of that hypothetical system?

If you're dealing with a protocol that's not just "everything is text", I'd argue that PHP is almost always a poor choice...

Poor arguments against

Posted Feb 17, 2015 18:49 UTC (Tue) by sorpigal (guest, #36106) [Link]

The trouble is that for one reason or another PHP is usually a bad choice for just about everything. That does nothing to stop its use for things to which it is not suited.

Poor arguments against

Posted Feb 26, 2015 12:21 UTC (Thu) by Wol (subscriber, #4433) [Link] (3 responses)

> Firstly, I don't really see the point in strict typing. There has never been a difference between "4" and 4 in PHP, and I don't see what adding one is going to accomplish, except a load of useless casts (in that the behavior of the code is exactly the same, so why bother) everywhere, making the code less readable.

Have you ever worked with a language with strict typing? Have you ever worked with a language with no typing? Have you ever worked with a language with optional typing?

Having done all three myself (and my favourite language will happily let you multiply by 10 by concatenating a "0" :-) I can tell you that, given optional typing, I usually crank it up to max!!!

Yes it can get in the way. Yes it's incredibly useful to be able to turn it off. Yes I love the fact I can use my human type "number" rather than faff about with floats, ints, doubles and reals. But as a developer, the ability to switch on strong typing and have the compiler check my work is worth its weight in gold.

Cheers,
Wol

Poor arguments against

Posted Feb 27, 2015 7:30 UTC (Fri) by renox (guest, #23785) [Link] (2 responses)

> my favourite language will happily let you multiply by 10 by concatenating a "0"

By 10 only if the number is base-10.. Hexadecimal number injection? Funny idea!

Poor arguments against

Posted Feb 27, 2015 14:02 UTC (Fri) by mathstuf (subscriber, #69389) [Link] (1 responses)

Also need a to be an integer.

Poor arguments against

Posted Feb 28, 2015 15:31 UTC (Sat) by Wol (subscriber, #4433) [Link]

Actually, that's not true :-) Although it can get extremely confusing when working with scaled decimal that have decimal points in them :-)

Yes the internal representation has to be an integer, but as far as the programmer is concerned it can be "a number with 4 decimal places". And the poor programmer has to keep track of whether the string is "internal format" ie "10000", or "external format" ie "1.0000".

Given that it was used a lot for accounting, it worked quite well. Use internal format for pence, and external format for pounds. Just don't try to convert from internal to internal, or external to external ... I've seen a few bugs like that :-)

Cheers,
Wol

Scalar typing in the PHP world

Posted Feb 14, 2015 1:36 UTC (Sat) by ejr (subscriber, #51652) [Link]

This is a corollary of Greenspun's tenth rule ( http://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule ). Someday computer "science" will reach beyond standing on each others' toes.

Error-proofing syntax for: pass by reference

Posted Feb 14, 2015 18:28 UTC (Sat) by Richard_J_Neill (subscriber, #23093) [Link] (5 responses)

While we're at it, is there any chance that passing by reference could be changed to be explicit in the function call, rather than just the function definition?

One of PHP's nastiest traps for the experienced user, imho, is a function whose definition decides that some arguments are passed by reference - yet the function call has no syntactic indication of this. This makes reading/debugging the code really difficult.

It seems to me that a function that requires arguments passed by reference should need the "&" sign in both the function definition AND the function call.

The current situation has:

//function definition:
function refdemo ($a, &$b){ ... }

//function call:
$a = 1; $ b = 2;
refdemo ($a, $b);
//$b could now be different, and you could get a surprise!

In my view, the function call (as well as the definition) should be written as:
refdemo ($a, &$b);
which was the old PHP behaviour, but is now explicitly forbidden.

Error-proofing syntax for: pass by reference

Posted Feb 14, 2015 20:29 UTC (Sat) by renox (guest, #23785) [Link] (4 responses)

I don't know PHP so I can't comment whether it is a good idea for PHP or not, but I'm surprised that (AFAIK) there is no language which do this (C is close in a way) but it is a good idea, this way reading a function call, you would know immediately the input and the input/output parameters..

Error-proofing syntax for: pass by reference

Posted Feb 14, 2015 21:38 UTC (Sat) by Inkane (guest, #90843) [Link] (2 responses)

I'm pretty sure that C# does this with its ref and out keywords.

Error-proofing syntax for: pass by reference

Posted Feb 15, 2015 8:50 UTC (Sun) by renox (guest, #23785) [Link] (1 responses)

Thanks, I didn't know this, even though C# seems like a nice language, I didn't learn it as it was made by Microsoft and I prefer 'ecosystem agnostic' languages (well as much as possible).

Error-proofing syntax for: pass by reference

Posted Feb 15, 2015 16:05 UTC (Sun) by mathstuf (subscriber, #69389) [Link]

C# is getting more cross-platform. Though it still reminds me too much of Java personally.

Error-proofing syntax for: pass by reference

Posted Feb 15, 2015 1:36 UTC (Sun) by marcH (subscriber, #57642) [Link]

I don't think you can really transpose this logic to many top-tier languages like C, Java, Python,... since they have a SINGLE way to pass parameters anyway, entirely missing this value-vs-reference distinction.

I realize most of these languages have the same "obfuscated side effects" problem (which is actually quite a shame when you think about it), but it looks *very* different to me.

In C, maybe you could allow some kind of extension like this one to achieve the desired effect:

void f(const char *str1)
{
int x = strlen(const str1); // reminder of prototype / immutability

And then optionally enforce the new feature with some "declare(immutability_at_caller_point)" at the top of your file(s) :-)

Scalar typing in the PHP world

Posted Feb 15, 2015 1:52 UTC (Sun) by marcH (subscriber, #57642) [Link] (1 responses)

> In theory, this mechanism gives everybody what they want; developers who want to work in a strict-checking environment can have it, while those who want weak typing get it by default. In practice, this approach appears to have pleased almost nobody.

This utterly nice and simple kind of "strict" directive/compiler flag has been successfully applied all over the programming place already. But of course PHP must be too "special" to work with it.

I'm not sure how you can write such a [very good] summary and stay [almost] serious. Mmmm... probably because you're a true professional. But then if you're a professional, how come you've just spent so much time reading PHP mailing lists? Relaxation after reading some tough RCU paper maybe? Or worse, RCU code?

Or... maybe because [some form of] PHP + Linux is running one of the top 5 websites in the world, *sigh*.

PS for the one or two persons reading this thread which never saw this before:
https://www.google.com/search?q=php%20fractal%20bad%20design

Scalar typing in the PHP world

Posted Feb 23, 2015 2:05 UTC (Mon) by jospoortvliet (guest, #33164) [Link]

And then there is reality of course: http://blog.mailchimp.com/ewww-you-use-php/

(ownCloud is written in PHP and we are quite happy with it, too)

Scalar typing in the PHP world - RFC author quits...

Posted Feb 16, 2015 8:49 UTC (Mon) by DG (subscriber, #16978) [Link] (2 responses)

Related news - http://news.php.net/php.internals/82750 - so the RFC is probably dead.

Scalar typing in the PHP world - RFC author quits...

Posted Feb 17, 2015 17:28 UTC (Tue) by nix (subscriber, #2304) [Link]

Clearly PHP typing is a developer burnout trigger.

Scalar typing in the PHP world - RFC author quits...

Posted Feb 18, 2015 18:54 UTC (Wed) by corbet (editor, #1) [Link]

The original RFC may be dead, but the idea lives on with different proponents. This looks like a story that will continue to run for a while yet.

Lipstick on a pig

Posted Feb 16, 2015 13:44 UTC (Mon) by dskoll (subscriber, #1630) [Link]

Why does the phrase in the subject of this comment come to mind?

If PHP had implemented the equivalent of Perl's use strict; and use warnings;, it would have been a far bigger advance than strict typing. And not conflating lists and hashes would've been a giant step forward too.

Scalar typing in the PHP world

Posted Feb 18, 2015 18:45 UTC (Wed) by iabervon (subscriber, #722) [Link] (1 responses)

It seems to me that, if the language has (1 + "1") = 2, it ought to provide to programmers the ability to use the language's built-in conversion tersely at the beginnings of functions.

I'm not sure that it makes sense for a function to control the ability of callers to get their data converted by the runtime going into the function; going from wrong-type input to the strict function, it will have to be converted or checked somewhere, and, unless the language doesn't have conversion at all, it will probably be converted using the language's built-in conversion, implicitly, somewhere pretty close to whatever insists that it already be converted, without any more extensive error handling than if no functions were strict.

On the other hand, having an easy way to ask for a pedantic conversion (where "1andjunk" causes an error if converted to an integer) would be useful, and not substantially change the language capabilities, since a library could always check that, if the argument is a string, it consists entirely of digits before converting it to a number.

Scalar typing in the PHP world

Posted Feb 19, 2015 21:17 UTC (Thu) by smurf (subscriber, #17840) [Link]

These are two sides of the same medal.

A language whose designers (I use that word loosely) allow, or in fact appear to embrace, nonsense like the results of this snippet of code

<?php $a = ["123", "456A", "78"]; print_r([$a[0] < $a[1], $a[1] < $a[2], $a[2] < $a[0]]); ?>

(which shows that these three strings do not even have a consistent ordering) is fundamentally broken, sorry.

The problem is that the RFC does not mention that. It is solely concerned with function arguments but ignores the fact that the actual values are then still treated in an inconsistent manner, which IMHO makes the whole thing useless.


Copyright © 2015, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds