3 ms·
> Even though I didn't understand their arguments, I still believed what they said, because I thought they were experienced, so they must be right. Even though
by chriswarbo 5y ago
> Even though I didn't understand their arguments, I still believed what they said, because I thought they were experienced, so they must be right. Even though I hadn't used the tools personally, I started developing premature opinions on them
> This made me arrogant, because I saw myself as above my classmates
As others have said, "good" and "bad" depend on the use-case; everything has pros and cons; but some things are still objectively better than others (e.g. if tool A supports more data formats than tool B, whilst being just as fast, just as secure, just as supported, etc. then A is a "Pareto improvement" over B; there is no reason to choose B for a new project).
Whilst it's common to explain why something is "bad" (e.g. PHP encourages 'stringly typed programming', which makes SQL injection and cross-site-scripting vulnerabilities more likely); it's also important to explain why such "bad" tools are nevertheless widely used. For example, PHP is widely supported by free/cheap web hosts, is easy to set up (just copy a .php file to the server) and run (the URL is the .php file's path); it runs concurrently without needing shared state/threading/etc.; it has a built-in Web framework ('$_GET', '$_POST', 'echo', etc.); it can be embedded inside HTML files; and so on. This all helped it grow a large community in the Web 2.0 days, and lead to useful applications like Wordpress and MediaWiki, whose 'plugins' got many people into programming. This community of pragmatic (but often inexperienced) developers and their ability to quickly churn out Web apps has sustained itself to today; whilst the developers have matured, applications/libraries/frameworks have grown much more complex, the demands on the language are more diverse, and the language maintainers add new features and fix some of the language's underlying problems.
I still consider PHP to be a particularly bad language, and would need an incredibly compelling reason to choose it for new project. Yet I know there are many reasons why people have chosen it, and continue to do so. Those aren't necessarily "pros" for the language, e.g. it often comes down to historical inertia and 'what we know', which is much less important for those just starting out, or working in a different field (e.g. data scientists), or facing a different context (e.g. Web apps implemented client-side, fetching data from managed cloud services).
If we see the arguments against, but don't know much of the context or reasons things still get used, it's easy to make the assumption that others made bad choices due to ignorance. I think this is similar to Chesterton's Fence https://en.wiktionary.org/wiki/Chesterton%27s_fence https://en.wiktionary.org/wiki/Chesterton%27s_fence i.e. we should understand the reasons why someone did things in a particular way before we scoff at their poor life choices (after all, sometimes those reasons make it even more hilarious!).
- tored 5y ago> PHP encourages 'stringly typed programming', which makes SQL injection and cross-site-scripting vulnerabilities more likely Every language phasing the web is stringly typed, I have seen unproper filtering and escaping in all languages I worked professionally with.
- chriswarbo 5y ago> Every language phasing the web is stringly typed Heh, not even close. Off the top of my head I can think of Ur/Web as an extreme example ( http://www.impredicative.com/ur http://www.impredicative.com/ur ), and slightly more mainstream systems like Yesod ( https://www.yesodweb.com https://www.yesodweb.com ). I've worked professionally with Haskell, although not for Web stuff. These days I mostly work with Scala, which has a similar typing mindset to ML/Haskell, but unfortunately inherits a lot of stringly typed legacy from Java. We use an in-house library that provides zero-cost newtypes to distinguish between different semantically-distinct data types, many of which just-so-happen to be representable as subsets of String (e.g. GET parameter names, GET parameter values, POST bodies, etc.). This makes it a type error to try and e.g. concatenate different sorts of data together. W.r.t. "escaping", I tend to avoid it entirely since it's inherently unsafe: - "Escaping" doesn't distinguish between its input and output types; they're both just "String", and we have to make assumptions about the contents of each (i.e. it's unsafe) - Having the same input and output types makes it possible to "double-escape" by accident. This discourages the use of escaping, just-in-case it happens to be done elsewhere; hence it's very common to end up without any escaping taking place. - Having the same input and output types makes escaping functionally unnecessary: anything we do to an escaped string could also be done to an unescaped string, so it's up to us to remember that it's needed (i.e. it's unsafe). The whole idea of "escaping a string" betrays a flawed approach to the problem. Instead of throwing everything into the same representation, then manually trying to figure out whether or not a value comes from a particular subset of that representation or not, it's much easier and safer to avoid lumping them all together in the first place. If our inputs have a certain type (e.g. HTTP.Get.Val) and we can only output certain other types (e.g. JSON, Map[HTTP.Header.Key, HTTP.Header.Val], etc.), then the processing which turns input into output is forced to specify any necessary conversions. Whilst such conversions may involve escape sequences, having them associated to particular types is more akin to serialisation. Heck, at my first PHP job we largely solved this problem not by 'filtering and escaping', but by modifying the PHP interpreter to distinguish between 'clean' and 'dirty' strings (with literals being clean, and $_GET, etc. being dirty). Operations like concatenation would propagate 'dirtiness', and output functions like 'echo' would crash if given a dirty string. Traditional 'escaping' functions would convert dirty strings to clean ones, and crash when given a clean string. Having this be dynamic was more annoying than ahead-of-time compile errors, but it still did a pretty good job. There's pretty much no excuse for stringly typed languages/libraries/etc. when such such trivial solutions exist, other than the historical inertia of legacy systems.