Hacker News new | ask | show | jobs
by x1 5106 days ago
Are we really talking about type checking or the larger circle of validation (of which type checking is just a small part)?

( Bugs found by unit tests ( ) Bugs found by input validation )

Or in other words...

String s = "lastname'; drop table user--";

...is still a perfectly acceptable string.

It seems to me that type checking is the simplest form of validation (are you an int, are you a String) and nothing more. It wont tell you if that int is positive or negative or if that string is an email.

When dealing with either static/dynamic languages I think more unit tests should be spent validating.

1 comments

No, this is just common ignorance of static typing. That string is a perfectly acceptable String. But it isn't a perfectly acceptable Query, and you can't pass a String to the database, only a Query. In order to turn a String into a Query, it has to be passed to a function that escapes problem characters safely. You need to use such a function regardless of dynamic vs static typing, but static typing enforces that you always use that function, and can't forget and accidently submit an unescaped string to the database.
> but static typing enforces that you always use that function, and can't forget and accidently submit an unescaped string to the database.

So you're saying it is impossible to do this without static typing?

I don't think anyone is making that claim. You can obviously do runtime inspections of types before building the query, or rely on the "runtime inspection" of getting an exception when the unescaped String doesn't support the Query method being used.

It's entirely possible to do this without static typing. It's impossible to guarantee that all database calls use a Query instead of a String without running the code in some form.

I think he's saying it won't be automatically checked for you without static typing. Since, you know, that's what type checking is.
To have the compiler trap accidents for you? How would you do this if a query and a string were the same thing?
That is why you make them separate. You only really start taking advantage of the type system after you learn to encode system invariants and rules into the type system.
He is making the point that you can create a separation between Query and string just as easily in a dynamic language; it just gets caught at runtime (preferably during testing) rather than compile time.
So when the Query is sent to the database MySQL actually receives a Query object and then parses that Query object?

...oh wait, right before it is sent to mysql it is turned back into a string again.

My point is that static typing doesn't help you do anything other than verify that the objects being passed are of a particular type. I'm not saying static typing is bad or good I'm just saying that type checking itself is NEARLY USELESS unless you include some sort of validation.

		Query q = new Query("select * from users where id = (id)");
		QueryParam qp = new QueryParam("(id)",25);
		q.addParam(qp);
		ResultSet rs = q.execute();
		public class Query {
			public ResultSet execute() {
			for(QueryParam qp : this.getQueryParams()) { 
				this.getSql().replace(qp.getId(),qp.getValue());
			}
			super.execute(sql);
			}
		}
That's all type safe. So it should be good right?
Yes, you can write a Query type that is vulnerable to SQL injection, if you want to.

But if you write a secure version, you only have to write it once. You only have to maintain it in one place. You only need to test it in one place. And if you forget to use your secure Query type, anywhere else in your code, the compiler will yell at you. It's a significant advantage.

This is easier to see in a language with a rich, flexible and expressive type system than it is in Java. The writer of the original article used Haskell for a reason.

> But if you write a secure version, you only have to write it once.

> You only have to maintain it in one place.

> You only need to test it in one place.

Again, so this cannot be done in a dynamic language? If it can be done, why bring them up?

> And if you forget to use your secure Query type, anywhere else in your code, the compiler will yell at you. It's a significant advantage.

The only thing the compiler will yell at you is if you passed a type that is not of a Query type. The compiler will not yell at you for getting the current session directly or creating your own jdbc driver for that matter.

Interestingly Wikipaedia lists SQL injection as being mitigated by strong typing (no I did not just edit it!) http://en.wikipedia.org/wiki/SQL_injection
No, I am saying your strawman is a strawman. You were claiming static typing doesn't help since a string can contain a bad query. Now you are suggesting that you wouldn't write such code in a dynamically typed language anyways? Then why did you offer it as an example of how static typing doesn't help.

Of course you can make sure you never actually run the bad query with dynamic typing. I assumed it was obvious when talking about static typing that the difference would be compile time vs run time. With a statically typed language, when you make the error, you get told about it by the compiler. With a dynamically typed language, you find out about the error later, when that code actually runs.

> Now you are suggesting that you wouldn't write such code in a dynamically typed language anyways?

I never suggested that...?

> With a statically typed language, when you make the error, you get told about it by the compiler. With a dynamically typed language, you find out about the error later, when that code actually runs.

> static typing enforces that you always use that function, and can't forget and accidently submit an unescaped string to the database.

So you are really just saying "static typing requires you to use static typing". This has nothing to do with actually writing good code or having any sort of validation. Just that the compiler tells you that you are sending the wrong type... that's what we are arguing about?

Look my whole point is static typing by itself gives you next to nothing (See my code example below) without some form of validation beyond static typing. That obviously holds true to dynamic typing as well... I'm not even sure what we are arguing about.

> static typing by itself gives you next to nothing ... without some form of validation beyond static typing

You mean like the validation you get when you compile a program?

Yes, a statically typed program that never gets checked is strictly worse than a dynamic program, but that's the whole point of the type system: you can check it. This argument is a strawman because nearly every language with a static type system includes a validation step (maybe Dart is an up-and-coming counterexample).

>I never suggested that

Yes, you did suggest that. I am not sure how this level of cognitive dissonance is possible. What possible purpose does your example serve then if it doesn't impart any sort of meaning at all?

>I'm not even sure what we are arguing about

Clearly. Please, take the time to think through the subject and present a clear point that you will not later pretend you didn't make.

> What possible purpose does your example serve then if it doesn't impart any sort of meaning at all?

The example shows that static typing doesn't do anything more than what it says. It doesn't solve problems/fix bugs or provide some magical insight to the system as you seem to believe.

I'm genuinely curious as to your position and why you are so... clearly opinionated. I'll take the "idiot banner" for today. Please provide me with your insight as to what the fundamental argument (and why you feel so strongly about it) really is.