Hacker News new | ask | show | jobs
by jessedhillon 5511 days ago
*_once doesn't memoize, however. The result of include_once called twice isn't that the same template is repeated, but rather that the first call outputs the template and the second call is silent.

include/require_once are not statements to the effect of "return same output as the last time I include/required this" but rather "if I haven't already include/required this, do it now."

It's a very difficult proposition to say that good programming requires the latter capability.

1 comments

Uh, that's what import in Python does. It doesn't reimport; it ignores the import request if you've already done it, right? (I must confess I haven't used Python a lot in the last few years, but it used to be my primary language).

So, if you're willing to accept my assertion that Python is a good programming language, then you'll have to agree that that latter capability is the default in at least some good programming languages.

The former capability to which you refer, though, is quite often useful for including template fragments, so I wouldn't want to throw it out, either. If you said, "Hey, these only seem conceptually similar because of the name, and they're really different things", I'd be willing to go with that, I think. Or, if you were to say, "Hey, these are so similar that we shouldn't have a whole separate name for the behavior switch", I'd agree with that, as it's my position. However, it seems as though you're arguing that one of the two behaviors is never needed in a good web application domain language, and I disagree with that.

I think you misunderstood what I said.

First, it's important to understand that include/require_once is useful in PHP because of a particular pattern -- include/require the files containing classes and functions I need; these statements are placed at the top of every script that needs those definitions. It's an error in PHP to declare the same function twice (to redeclare). So if you include script A and B, and both depend on C, then you have to use require_once in A and B when they call in C. This way, anyone calling in both A and B won't trigger a redeclaration error.

This use case is not relevant to people using the statements to pull in templates, because you would deliberately place the require statement where you needed it. Someone using the same partial template in the header of a page and in the footer of a page would not care if the template had been invoked before -- "place this in the footer unless you already placed it somewhere else in the document (or even if you simply included it and threw it away, or emailed it to someone, or anything else at all)" would be a very poorly written template.

So what we have is the case that a set of processing scripts all include the same file at the top and this could potentially trigger redeclaration errors. So instead of addressing the fact that the interpreter cannot distinguish a common pattern (multiple inclusion) from something that really isn't even an error (redeclaration), we have four statements that serve very minor variations of the same function.

There are two binary choices here: require or include and once or not once. The distinction between include and require is totally unnecessary -- in what case would you want to optionally include another file, but not even receive notification or change your behavior depending on whether the file was able to be included? The _once distinction is only a guard against redeclaration, and it's beyond me why it matters that something was declared multiple times -- or why the programmer needs to count the number of inclusions.

Ideally, calling in a template would be different from calling in essential definitions, and would be treated differently.

BTW in Python, the import statement is idempotent -- importing multiple times has the same effect as importing once.