Ah, I think the bit where generics is useful is in making sure the value types are consistent (i.e., that you're not building a query that subtracts an int from a string or compares a date to a bool). This still doesn't guarantee that the types will match with the database columns, but it is a step up from the non-generic alternative.
How does the compiler know the types of the database columns?
That information has to come from somewhere. Also, type checking is negligible from a performance perspective, so I the "zero overhead" is of minimal interest.
> How does the compiler know the types of the database columns?
There's two variants on a single way: basically, a "schema.rs" file contains your schema. You can write it out, and (with the help of migrations) it will update it when you create a new migration, or, you can have it literally connect to the DB at compile time and introspect the schema.
> Also, type checking is negligible from a performance perspective, so I the "zero overhead" is of minimal interest.
Ah, but it's not "the type checking is fast", it's the "diesel can generate hyper-optimized outputs that don't do runtime checks". Like, as an interesting example, Diesel can (well, will be, this has been designed but not implemented yet) actually be _faster_ than a literal SQL statement. Why? The SQL literal is in a string. That means, at runtime, your DB library has to parse the string, check that it's correct, convert it to the databases' wire format, and then ship it off. Thanks to strong generics, since the statements are checked at compile time, none of those steps need to be done at runtime; the compiler can pre-compile that DSL into postgres' wire format directly.
The reason this hasn't actually been implemented yet is that it's admittedly a tiny part of the overall time, and the Diesel maintainers have more pressing work to do. I use it as an example because it's an easier one to understand than some of the other shenanigans that Diesel does internally. It couldn't remove this kind of run-time overhead without generics.
This is all very neat, but I think Go could do all of this too, except that "query compile time" would happen on application init or on the first query or some such. Still, very cool and good work to the diesel team!
The whole point of an ideal type system is that if code compiles, it is provably correct and won’t have bugs.
Few typesystems come close to that (Coq is one of the few languages where the system might be advanced enough), but generally you want to completely remove entire classes of errors.
Yes, because Go couldn’t do all that on compile, which is the entire issue. It can’t prove the type safety of your SQL query at compile time, or the type safety of your generics usage.
I think you meant to respond to Steve. I'm not a Rust guru (I keep trying it, but I don't have any applications for which it's reasonable to trade development time for extreme performance). I definitely don't know anything about diesel.