| I think there are two points that are being mostly missed in this discussion: A) How to define the Query type such that it would convert injection bugs to type-checking errors (No, it cannot simply be a function from a full String containing a query to a Query type, as you demonstrated). B) Sure, you could define the same Query primitives to do the same in a dynamically typed language. The main difference is that the type-checking errors due to incorrect use of the query primitives would be caught at runtime. As for A, you would want to define primitives that build query strings safely. That is: Query(unsafe_string_here) wouldn't work. Either because it allows too much (still can inject the original string) or disallows too much (escapes everything, makes the query invalid). Instead, you would define "select", "update" and other querying primitives as non-string primitives you can use to build queries. You would basically mirror SQL or the query language you use into non-string primitives that allow constructing safe queries. B) Yes, you could do this with dynamically typed languages. Right before executing your query you would need to do an isinstance() check or some other way to validate that the query was generated using the safe machinery. This means no duck typing. If you allow other, unsafe implementations of the query type here, you get the unsafety back. |