HNHacker News
TopNewBestAskShowJobs

eevee

625 karma · joined February 1, 2012

submissionscomments
eevee··on Why I think Rust is the "language of the future" for systems programming
Awesome.
eevee··on Why I think Rust is the "language of the future" for systems programming
Grandparent has a point, and it's not quite as outlandish as you make it out to be.

Consider that a lot of Python developers write most of their code in Python, then rewrite critical parts in C to speed it up. Python is not a speed demon, and that becomes particularly problematic with tight loops or heavy math—but writing entire applications in C is error-prone and tedious.

Rust won't outright replace both of those, but it does offer a nice middle ground: it's safe, it has some higher-level constructs, it does away with some boilerplate, it builds fairly easily, and it still compiles essentially to machine code. Writing quick shell-like scripts or entire applications in a systems language is now a viable option for lazy jerks like me, even if it's not always the best one.

eevee··on Why I think Rust is the "language of the future" for systems programming
Is this intentionally snide? You appear to be implying that nobody should try to solve problems, because we already know how to work around them.
eevee··on Why I think Rust is the "language of the future" for systems programming
Apparently it won't work yet! Tragic. In the meantime, I can deliberate on whether or not to call it FOXDIE.
eevee··on Why I think Rust is the "language of the future" for systems programming
Ha, I was just thinking about how Rust bindings to Python might look.

I haven't actually tried this, but since Rust libraries just compile to .so's and it's possible to declare a Rust function with a C signature, I bet it'd be a simple exercise to write a CPython-compatible extension module.

eevee··on Why I think Rust is the "language of the future" for systems programming
For what it's worth, I like Rust because I like Python. Python does strive to have one "obvious way to do it", but that ends up meaning it has a very colorful toolbox full of different ways to solve different problems, much like Rust. Generators, context managers, metaclasses, decorators, and descriptors are all very different mechanisms, but they all work together well.

Hell, I keep discovering that Rust has already implemented language features I'd independently thought up half-baked versions of.

And not to encourage a flamewar, but I believe there's a gigantic unspoken niche that Rust and Go will be fighting over: people like me who stay away from systems programming because it's a pain in the ass. C is tedious, C++ is bozotic, D is obscure—so the lowest I've bothered to go for a while is Cython. But now there's Rust, and I'm genuinely enjoying it, and I see other people who've mainly been sticking to Ruby or Python who are enjoying Go. This will be interesting to watch. And regardless of what I think of Go, I'm glad there's finally some activity in this space again. :)

eevee··on Quick doesn't have to mean dirty
There are plenty of cases where a data type doesn't sufficiently capture semantics, and without static typing, Python isn't very well built for checking that values have the right semantic type. A float could mean money or time or a percentage; a string could be plain text or HTML or JavaScript or a filename.

The really really hard part is still checking that a given page "isn't broken"—something that's easy for a human to spot but hard for a computer—for all possible combinations of state. But very strict typing would at least make the output less likely to break.

eevee··on Quick doesn't have to mean dirty
Cars and spaceships built on existing engineering and physics principles. We've never had anything like programming. We can't even decide if it's a math, a science, or some kind of engineering.

We have languages with built-in async support (and some that fake it decently), languages with syntax for safe and unsafe pointer use, languages that bundle impurity away from everything else.

It's a slow process, since any new language has a massive uphill battle to gain any traction. But I think we're getting there.

eevee··on Quick doesn't have to mean dirty
Hey, thanks. :)

The problem with evangelizing the Right Way is that the benefits tend to come later; if you haven't experienced the pain of dealing with the Wrong Way's fallout once it hits critical mass, it seems easy to brush off. "SQL injection? Pfft, no one cares enough to attack my site." "Transactions? I only write one or two rows at a time anyway." "Templates? What's wrong with string formatting?"

Our profession is a bit lacking in context. Nobody believes the lessons of others. (Granted, we're so crazy that half the time we learn the wrong lessons.)

Still a young discipline, though. Maybe we'll grow out of it.

eevee··on Quick doesn't have to mean dirty
You're quoting from a paragraph about tradeoffs in core language design. That's not the same as best practices, though the latter often exist to avoid pitfalls in the former.
eevee··on Quick doesn't have to mean dirty
Have you tried automated testing on a large complex web application? It's an insanely monumental task.

I actually mentioned Haskell in the post because coworkers have lamented not having its type system, which would immediately find problems at compile-time that we otherwise have a very very hard time thoroughly covering with tests.

eevee··on Quick doesn't have to mean dirty
That thesis reflects a common false dichotomy that many programmers (who often have only used PHP!) seem to actually believe: that anything written in a non-scruffy language won't ever ship because the authors will be too busy sipping lattes and debating type polymorphism. That persistent belief is what I (the author) find annoying.

The underlying point here is that you can get something out the door quickly and have it not be a Jenga tower held up by duct tape. I'm sure there are plenty of people who can do that with PHP and I don't mean to imply otherwise; I'm only asserting that it can also be done with Python.

eevee··on Coding Horror: The PHP Singularity
> No, Java is not the same. Scalars not objects in Java and are passed by value.

How are pass-by-value and pass-by-object distinguishable for immutable values?

> That's not what we were talking about.

Yes it is. You said (array) as a cast is useful because a function can accept either a single value or an array of values, and the (array) cast will produce an array either way. I contend that doing this doesn't really work, because passing a single value that happens to be an object will cause the function to cast it to an array of the object's contents, which will have fascinating but useless results.

> You cited byte-code interpreted as if that's somewhat significant.

I only mentioned bytecode for the sake of pedantry: strictly speaking Python isn't interpreted, whereas e.g. shell is.

> You could read the manual.

I had to do quite a lot of that. It's kind of wordy. :)

> Most languages make the distinction. Why shouldn't there be? That's really ugly code.

I'm not proposing that people write code like this. I'm objecting to the inconsistency between a value in a variable and a value in source code.

Note that, for the same reason, you also can't chain calls like `foo()()`. There ARE good reasons for that: you could return a function name, or a closure, or an object that supports being called. But because the parser doesn't just allow trying to use parentheses on an arbitrary value, this doesn't work. Just like `foo()[]` didn't work until recently, because it too had to be special-cased.

> That's fine. It doesn't mean every language should do the same. Most languages, especially those PHP is based on, do not do that.

Really? C doesn't have methods. C++ has methods, but string literals are C strings so they have no methods. Perl doesn't consider builtin types to be objects, but if you turn them into objects with `autobox`, methods work equally well on variables and literals. Python allows method calls on literals -- and will let you try to call them, but of course literal strings aren't callable so this won't do anything. It parses, though. Ruby is the same. "foo".equals("bar") is a common Java idiom.

What language are you thinking of where there's a distinction made -- in the parser, no less -- between a variable and an expression?

> Maybe one day PHP will have that but because it's weakly typed, it's difficult to know even what methods should exist. In PHP, it's perfectly reasonable to say strlen(1). Does that mean every number should have string methods? I'm guessing you never considered that?

Sure, why not? Not that I was suggesting PHP direly needs scalar methods, but if a number responds to strlen(), why not to ->strlen()?

> Yes, because the encoding properties of the current database connection are needed for encoding properly. If have two database connections, then what?

Then you're screwed no matter what Zend does and still need to fix your code. So the options were: 1. Leave the existing function totally broken. Create a new one with a confusing and even longer name. Make everyone fix their code and remember to use the new function in the future. 2. Fix the issue in-place for the vast majority of existing code. Make the edge cases fix their code by doing the same thing they have to do with every other API function anyway. Optionally, throw a warning when multiple handles exist and mysql_escape_string is called with only one argument.

What, then, is the appeal of (1)?

> You've got a very singular perspective on things. That's fine. But by critiquing another language without knowing it you're making a lot of assumptions and blowing things way out of proportion.

I'm hearing this a lot, but (as far as I can be trusted to say this) I don't see it. I draw a lot of comparisons to Python and Perl because they're in the same family and I know more about their inner workings than anything else. That doesn't mean they're the only languages I've used or the only languages I think are worthwhile.

Yes, I picked on a lot of little things. It's the little things that matter. Every language (ahem, most) has function calls, data structures, and loops. What differentiates them is the little day-to-day stuff.

So what am I missing? What makes these design decisions good, what makes PHP great? I've heard a lot of defenses and a lot of statistics, but not too many outright advantages. Most of your original response is just workarounds, not reasons why the behavior is good or even acceptable. The image I'm left with is that of an overgrown playground filled with active mines, but most of the mines have upturned buckets over them so you probably won't step on them, and that's supposed to make it a great place to send your kids. If even PHP's supporters can do no better than explain how to write passable PHP when I have a gun to my head, why would I want to use it?

eevee··on Coding Horror: The PHP Singularity
I drooled far more PHP into my terminal that weekend than you would believe. There were a scant few legitimate errors, and I've removed all the ones brought to my attention.

The rest of it should be factually correct, in which case, why do you care that I listed it? If you're correct in that many of the things I listed aren't really a big deal, the reader will agree with you anyway, right?

(Also, "trawled". No snark intended; it's a neat word and deserves more exposure.)

eevee··on Coding Horror: The PHP Singularity
tl;dr: I value consistency in my tools because it's a great measure of how frequently they'll trip me up and get in my way while reading or writing code. My biggest problem with PHP above all else, which I tried to write my article around, is that it's an inconsistent jumble from top to bottom.

You're absolutely correct, of course, in that you can write decent PHP by avoiding large chunks of the language, memorizing what things act differently from other things that look the same, not trying to do anything too dynamic, adding boilerplate to every project to fix useless default interpreter behavior, and so on. You can also waltz across a minefield if you just remember where all the mines are. But the necessity of doing all these things is exactly my argument: why bother with all this from a tool that's supposed to help you get stuff done? Because it has $_GET out of the box? You can't even claim "ease of learning" as an advantage after all this, because judging by your own responses, much of the language is pitfalls just waiting to trip up beginners who haven't yet learned the right painful lessons.

Yes, I'm not a PHP programmer. And as a not-PHP programmer, a lot of PHP looks totally crazy. But when outsiders complain about craziness in Python or Perl or Haskell or whatever, at least that craziness can usually be explained as consistent with the rest of the language, or part of an overall philosophy, or the result of some valuable tradeoff. And if not, we're very sympathetic about the ugly warts on our dearly beloved. Yet all anyone has ever been able to tell me about PHP craziness is "well, you shouldn't do that anyway" or "that's how it is in one of ten other languages" or "I have no explanation but here's a workaround so it's like the problem doesn't actually exist, right".

It is hard for me to understand how even someone who loves PHP can't see this as deeply alarming.

> You only need distinct operators if your language is weakly typed.

I don't dispute that: I claim that having separate addition and concatenation operators, but having a single set of equality/comparison operators, is inconsistent.

> Yes, like most ever other language in existence. You know, Java, C#, Python, etc.

Incorrect. Python passes everything by reference (value reference, not name reference) because everything is an object. Passing never performs a copy. I'm under the impression that Java is the same. Perl passes by alias, though the aliases are generally then copied to locals, and it has that whole array-flattening behavior which muddies things.

> Because all code should be contained within a namespace going forward. Constants should not be defined in the top-level.

Everything in Perl is in the `main` namespace unless otherwise specified. One wonders why PHP could not retrofit its new features onto the language like Perl has done for decades, rather than leaving half the language to flounder.

> No, it doesn't work that way. You have to explicitly cast. If you use an array type-hint you can only pass an array.

I'm assuming you're using the explicit cast inside the hypothetical function.

> PHP is also bytecode-interpreted. I'm not really sure what point you're trying to make.

You appeared to be citing interpreted-ness as a reason for having a wonky module system. I am naming other interpreted languages with useful module systems as counterexamples.

> The fact that is or is not a function is insignificant; you use it the same way.

Unless you want to do other function-y things to it, or any of the other pseudo-functions. The syntax is deliberately designed to make you think something is a function, but it only acts like a function in one particular way. (And as a side effect, there are a ton of simple function names you can't use as method names, because the parser gets very confused -- even though this seems like it should be unambiguous.)

> Oh, you're saying if you don't provide any of your own error handling and let it spill out the terminal -- yes, you're right -- no stack trace by default. Not that you should be doing that.

Defaults matter. This is an atrocious default.

> Turn on E_STRICT and it'll tell you.

It'll tell me what things I've already done; I can't easily find out what I should be avoiding proactively.

> Calling a string literal is pointless! 'test'() is test()!

So what? Both are values; why is there any distinction? Hell, you can call methods on numbers in Ruby and Python. I don't care about the practical value here; it's yet another place where PHP is inconsistent for seemingly no reason.

> If you've ever complained about security in PHP, you need to give that up right now. Because you just gave everyone a false sense of security.

Howso? The problem with mysql_escape_string was that it didn't take the current database handle into account. So: make it take the current database handle into account. It may not have solved everyone's problems, but the exceptions are obvious, and it would have fixed problems for far more people than the actual solution (zero).

If you're using multiple handles and passing them around explicitly, you'll have to fix your code either way.

eevee··on Coding Horror: The PHP Singularity
> Strict-equals on objects compares the references; but regular equals compares the contents of the objects. Two objects compare equal if the contain exactly the same fields and values. Seems pretty reasonable to me.

The line you quoted is talking about ordering, not equality.

> This is a good thing; JavaScript gets this wrong.

It IS a good thing, but it stands out when most of the language is extremely weakly-typed and even the original manual claims that separate operators for strings and numbers are confusing.

> I'm not sure if I understand this but all objects are passed-by-reference in PHP (since 5) and PHP references act appropriately when used as function parameters, etc.

So some things (objects) are passed by reference implicitly, and some (all else) are not. Yikes!

> You can declare constants in classes and namespaces with the const keyword.

Okay. Why not at top-level?

> You can cast scalars to single element arrays and objects to arrays with the same structure. Both are actually very useful.

You've practically invented a bug right there: if I write a function that can take either one value or an array of items, and you pass in a single object, I'll get a useless keyed array of its attributes.

> PHP is interpreted -- namespaces and autoloaders are PHP's module system.

What does being interpreted have to do with anything? Python and Perl are bytecode-interpreted (not positive about Ruby) and they both have rich module systems that don't require any fussing around. Heck, shell is interpreted, but zsh manages something almost like modules.

> Empty is equivalent to the not operator but will also work on undefined variables -- that's why it requires a variable.

Why does it need to look like a function when it clearly isn't one? return and echo don't.

> Useful inside of templates where matching { } is much more difficult.

In theory, but I've never seen any actual PHP code that uses them.

> Sometimes you don't care if a function succeeds; like with the unlink() function which will raise an error if the file you're trying to delete doesn't exist.

That's what exception handling is for -- unfortunately, PHP errors are an entirely separate beast from PHP exceptions.

> Not true. Debug_backtrace() will give you a stack trace in an error handler.

I said "PHP errors don't provide stack traces", and you aren't disputing that. Your own code can muck around to give you a stack trace (in most cases), yes, but the runtime doesn't do it for you.

> Assuming, of course, the programmer doesn't do anything to handle errors.

Defaults are important. I sure have a lot of people telling me it's great that PHP does web stuff out of the box -- why is it not then bad that PHP doesn't help you fix errors out of the box?

> E_STRICT (or lack of it) is for compatibility with PHP4. When enabled it will "warn you about code usage which is deprecated or which may not be future-proof." -- quote from the manual.

Yes, and that doesn't describe what it does. You can't tell what it's for, either: it's clearly not for compatibility with just PHP4, because even the PHP 5.4 release notes mention the addition of a new E_STRICT. Yet I can't be sure on what parts of the language actually ARE deprecated without reading the entire manual looking for mentions of E_STRICT.

> This author is confused why syntax errors would be parse errors but logic errors are not.

Read more carefully; the two lists are written roughly in parallel. A bogus object attribute gets a warning, but a bogus class attribute is a fatal error. (Not an exception, either, so you can't catch it with the exception handling that the OO system is supposed to be using.) A string value stored in a variable can be called, but the same string value as a literal cannot. And so on.

> This is sort of true; PHP errors and exceptions exist in different universes but it's easy to unify them and PHP even provides a built-in exception ErrorException to do so. You can turn every PHP error into an exception with 4 lines of code complete with stack traces.

Neat, though my understanding is that this still doesn't work with fatal errors, which are shockingly common.

I have the same kind of complaints about Perl's exception handling -- it's entirely possible to hack it into something more useful, but why on Earth should I have to mess around just to make something as fundamental as errors be developer-friendly?

> PHP supports both procedural and OO programming styles -- this is not a bad thing.

Exception handling isn't inherently OO. Perl has its own flavor of try/catch that requires zero objects whatsoever.

> PHP is reference counted with a cycle-detecting GC. That would not leak memory.

I believe it used to, but I removed this due to the short window during which it was a bug. I see this list of counter-arguments hasn't been updated in a while.

> This is true, but it's an ongoing discussion on how to correctly handle scalar type hints. For all the discussion about how PHP isn't designed the author takes issue with the thing they're taking their time on.

My issue isn't that they're taking their time, but that they implement half of a feature and then decide to sit down and think about the other half (while now constrained by whatever hack job they've already done).

> Because of the dynamic abilities of PHP, there is simply no way for the interpreter to ever figure out the variable to close over.

Every other dynamic language ever sure seems to be able to get this right.

> C++ does it. $obj::foo doesn't make any sense, if you're accessing class attributes then you use the class name Class::foo.

Then why not use Class->foo? Why does this need two operators? $obj::foo is perfectly reasonable if I want the foo attribute of whatever class $obj is; that's half the reason I ever use class attributes.

> This is personal taste not a valid critique.

Yes, which is why I said it's personal taste. Regardless, it's still wildly inconsistent with the rest of the language and poorly bolted on.

> That is, in fact, the point. PHP is supposed to be a thin scripting language layer over C. It's expanded beyond that. Many of the poor naming conventions are not because of PHP but rather are the exact API of the underlying C library.

How many people using PHP today came from C, exactly?

> Both the C API and PHP have both these functions for backwards compatibility reasons.

No. The C API has two functions because one takes only a value to escape, and the other takes both a value and a connection pointer. Both functions in PHP can be called with merely a value, and the "real" one will use the current global connection. Zend could have merely switched the old escape function to have the new behavior, and all existing code would have been instantly fixed, not broken.

> Most of these are provided by frameworks just as they are in Python, Ruby, C#, etc.

PHP is praised for its web features, but is missing a whole pile of functionality instrumental for actually writing nontrivial web applications. Either judge PHP only by the core language, or judge everything else by what you get with frameworks.

eevee··on Coding Horror: The PHP Singularity
Or I think they're misfeatures everywhere.
eevee··on Coding Horror: The PHP Singularity
I guess I'll chip in here.

The handful of advantages that make PHP popular are also some of its worst liabilities. Yes, you can deploy with just FTP... but then you have upload security to worry about, and have to protect all your library files, and yadda yadda. Yes, you can do SQL right off the bat... but you have to take care of SQL injection yourself. Yes, you can stick your code right in your HTML... as hard to read as that may be. Yes, there's no resource leakage... but every request has to recompile the code and reconnect to your database.

None of these things are problems at first, but they become problems quickly once your software expands beyond two pages or a hundred hits a day. Some of them may not even be obvious problems, but you'll pay the cost anyway when some kid steals your database.

Other platforms, meanwhile, tend to have fairly simple solutions to all of these problems, for the price of a minor increase in upfront learning. But since the problems are all things that happen later on, newcomers will just see that language X is harder.

This poses something of a difficulty. How can other languages introduce the ease of PHP that everyone's demanding? We can't just port exactly the same features over, or we'll have exactly the same problems. mod_python was a bad enough idea that it's dead now. Heroku is a neat thing, but still requires writing configuration files, and nobody enjoys doing that. Nothing is really well-suited for single-page fire-and-forget, either.

I have been thinking about this since writing that damned fractal post, but I'm not clever enough to have thought up a solution yet. So, you know, it would be useful if we could brainstorm on how to fix the learning curve and deployment instead of "just turn everything else into PHP!"

eevee··on [dead]
How can you argue that both "tied to the web" and "frameworks" are benefits, yet keep a straight face?

Frameworks in any language plug the language into the web—that's what they exist to do.

And if you're using the parts of PHP that are tied to the web, then you must not be using a framework, or those would surely be wrapped.

...but those parts of PHP must suck, or you wouldn't need to use a framework!

So then... PHP is good because it solves the problems it causes? I don't get it.

eevee··on [dead]
I've heard this same quip a lot, and I don't understand it either. I pored through a lot of PHP documentation to write an angry blog post about it, and it was unbelievably painful; documentation for simple extensions was broken into a dozen tiny useless pages, obvious cross-references were missing, similar items are documented in radically different places, etc. There's a lot of text, sure, but it's poorly organized and not all equally useful.
eevee··on [dead]
The language doesn't do something, so it's the developer's responsibility, and thus the developer's fault when it goes wrong.

This is a strange way to judge your tools.

eevee··on SaferWeb: Injects in Various Ruby Websites Through Regexp
A subtle problem with this "common knowledge": \z is different across languages.

In PCRE (Perl and Ruby), \z matches the end of a string; \Z matches the end of a string but allows for a single trailing newline.

In Python, \Z matches the end of a string. There is no \z.

In POSIX extended regexes, there is no \z or \Z. I think. Who knows, man.

eevee··on I only know PHP. How do I write a Web application in Python?
Strictly speaking, `main` isn't even a special function in C. It's only special to your C library and linker and something something I forget the details. Anyway it doesn't matter at all; you could leave off the `if` in Flask's example and never notice any difference. Just emerged as common practice to bracket off stuff like that /in case/ you ever decide to import your script as a module.

Part of my problem with PHP is that it doesn't seem to know what it is; there are the C parts, and the C++/Java parts, and both sides are sort of glued together with Perl influence, yet don't very well interoperate otherwise.

I have a pretty patchwork background and I could get work done in just about any language you'd pay me to use. I'd even happily write a web app in C. Doesn't make PHP any more attractive.

eevee··on I only know PHP. How do I write a Web application in Python?
But even something quick and dirty is longer than "hello world". I've written a couple pretty dinky things with Flask, and the minuscule overhead of typing `import Flask` was definitely worth having e.g. a solid template language and XSS protection ready to go.
eevee··on I only know PHP. How do I write a Web application in Python?
I assume he's talking about the `nonlocal` keyword introduced in py3, which allows overwriting names defined in outer-but-not-global scopes.
eevee··on I only know PHP. How do I write a Web application in Python?
Flask comes as a self-contained install where you can get started in 5 minutes.
eevee··on I only know PHP. How do I write a Web application in Python?
Who am I trying to convert? The article answers the question asked in the beginning—a question I've been asked several times since writing the PHP article.
eevee··on I only know PHP. How do I write a Web application in Python?
I don\'t see the problem with \"sanitizing\". It\'s easy: just add a \\ before every quote and the string is totally safe!
eevee··on I only know PHP. How do I write a Web application in Python?
I'm kinda the de facto owner of Cheetah for a fairly heavy user of it—quite possibly the heaviest. It may appear-to-work for a small project, but you would not believe the insanity that lurks beneath the surface.

It's been effectively dead for years, anyway, and the author admitted he'd jumped ship for Mako in 2008.

eevee··on I only know PHP. How do I write a Web application in Python?
I get the feeling you aren't very familiar with Python. Actually I'm hard-pressed to name a popular language in which writing a string to a file is particularly difficult.

You don't have to check for errors in Python; most functions raise exceptions on error, rather than letting your program continue with a known bad state.

The `if __name__ == "__main__":` pattern is a cute trick to distinguish a module from a file being run directly. It's not strictly necessary; just a nice habit. It's spiritually similar to the checks you have to do in PHP library files to make sure they're not being run directly.

You don't have to pass `self` around. You just list it as a parameter. There are design reasons for this, it's a tradeoff, blah blah. Think of it as the price you pay for getting to type 'def' instead of 'function'.

I'm not a C programmer, and I doubt many people writing web applications are, so how does wrapping C functions with C names help me? Are `'b' in 'abc'` and `len('foo')` that difficult to understand?

I like to think I've covered my reasons for disliking PHP well enough by now.

Okay. You're not the target audience of this article, then.

← PreviousPage 8 of 10Next →