6 ms·
Not having generics makes it hard to do proper type safe functions and libraries. My specific problem when i realized it was an actual problem was when i tried
by callesgg 9y ago
Not having generics makes it hard to do proper type safe functions and libraries.
My specific problem when i realized it was an actual problem was when i tried to connect to a sql databse and working with a proper ORM.
- weberc2 9y agoWhy does an ORM need generics? I ask because I've built something very like an ORM in Go and I didn't have any problem without generics. ADTs on the other hand...
- callesgg 9y agoIn my specific case it was the fact that i could not have one insert function or one update function. I would need one for each and every struct(table). These days there is a tool that can generate all those struct methods: https://github.com/vattle/sqlboiler https://github.com/vattle/sqlboiler So from the ORM perspective we (as the community) have worked around it.
- staofbur 9y agoThis is incidentally where .Net was around the 1.1 release (2003ish) We had code generation frameworks kicking out swathes of boiler plate. Now Repository<T> and for us around 200,000 lines of code are gone and only one narrow set of tests to execute.
- slantedview 9y agoThe idea that we don't need generics because we can generate code is kind of ridiculous, and certainly doesn't pass the simplicity smell test.
- weberc2 9y agoHe wasn't making that argument...
- slantedview 9y agoNeither did I say he was. He was linking to a library that works around the lack of generics by generating code.
- weberc2 9y agoI guess I don't see how generics would help you reduce the number of insert/update functions. The basic problem of an ORM is to map struct fields to columns; I don't see how generics would help you here. Can you write the generic pseudocode you want to write?
- rmrfrmrf 9y agoI would guess something like: class Collection<T implements Entity> { void insert(T entity) { String vals = entity.props.map(escapeSql).join(","); String qs = entity.props.map(x => "?").join(","); PreparedStatement p = db.prepare("insert into %s (%s) values (%s);", this.tableName, qs, vals); db.submit(p); } }
- weberc2 9y agoGo supports that today. Slice is a generic collection. Map will need to become for loops, but that's minor.
- steveklabnik 9y agoThe strongest typed ORM I've ever used is http://diesel.rs/ http://diesel.rs/ This code (okay I made the use line up because it's not on the website and I'm lazy, you do need one though): use some::stuff::for::the::dsl; let versions = Version::belonging_to(krate) .select(id) .order(num.desc()) .limit(5); let downloads = version_downloads .filter(date.gt(now - 90.days())) .filter(version_id.eq(any(versions))) .order(date) .load::<Download>(&conn)?; is completely, statically typed, with zero runtime overhead. Generics + type inference makes sure that everything is valid, and if you screw it up, you get a compiler error (which honestly are not very nice at the moment). Thanks to generics, all of this checking is computed at compile time. The end resulting code is the equivalent of let results = handle.query("SELECT version_downloads.* WHERE date > (NOW() - '90 days') AND version_id = ANY( SELECT id FROM versions WHERE crate_id = 1 ORDER BY num DESC LIMIT 5 ) ORDER BY date"); but you get a ton of checking at compile time. It can even, on the far end of things, connect to your database and ensure things like "the version_downloads table exists, the versions table exists, it has a crate_id column, it has a num column", etc. You can absolutely create an ORM _without_ generics, but it cannot give you the same level of guarantees at compile time, with no overhead.
- weberc2 9y agoAh, 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.
- steveklabnik 9y agoIt can check that they match with the columns, yeah. It also heavily relies on generic types to ensure that everything is well-formed, and to provide zero overhead.
- weberc2 9y ago