News for hackers. Stuff that matters.
Re:Ent: An Entity Framework for Go by jitl on Sunday October 30, 2022 @08:35PM (#33400642)
None of the industrial languages I’ve looked at (Kotlin, Typescript, Go, Java, Swift, Rust) can do the things I want to do using only typelevel features, especially at practical scale. Eg, transform a schema type that describes my database tables into an easy-to-use query builder and data abstraction API with rich method chaining.

Often in Java/Kotlin projects people end up writing compiler plugins / annotation processors which is like moving the codegen to build time and making it harder to inspect/understand, while simultaneously spending more developer time on it since those systems may need to run for every compiler invocation. The same goes for Rust; rust’s various macro systems target the problem I have, but Rust users report long compile times due to macro magic. More esoteric languages like Scala and Haskell might have the expressive power I want, but don’t seem practical to implement for other reasons.

Of course there’s always the runtime only approach in Ruby/ActiveRecord but that runs into correctness problems at practical scales.

Codegen is usually brittle and is often ugly, but is guaranteed to have more metaprogramming power than in-language typelevel features. Ultimately any such system can be complex, I just hope to build one where the leverage I payed for with complexity is well worth it.

Re:Ent: An Entity Framework for Go by valenterry on Sunday October 30, 2022 @08:52PM (#33400763)
> More esoteric languages like Scala and Haskell might have the expressive power I want, but don’t seem practical to implement for other reasons.

Well, if you can't use languages that make it possible/feasible, then code generation might indeed be the best option. It's just that your claim sounded quite general, so I had to jump in. :)

Re:Ent: An Entity Framework for Go by spion on Sunday October 30, 2022 @09:26PM (#33400963)
> Eg, transform a schema type that describes my database tables into an easy-to-use query builder and data abstraction API with rich method chaining.

TypeScript can do this. It was done already halfway-well 6 years ago with way fewer features in TypeScript (https://github.com/brianc/node-sql/blob/master/lib/types.d.t...) - today we can do much better.

Re:Ent: An Entity Framework for Go by spion on Sunday October 30, 2022 @09:28PM (#33400986)
FWIW I've given up the SQL query builder route and instead went with GraphQL query builder / Hasura route (https://typed-graphql-builder.spion.dev/).

Its technically codegen but only from the schema; queries are fully typed on-the-fly.

Re:Ent: An Entity Framework for Go by jitl on Sunday October 30, 2022 @09:59PM (#33401192)
I want to derive a Model type with methods from a Row type so I can write something like `const openDiscussions = blockModel.getContent({ where: c => c.getType() !== “page” }).andRecurse().getDiscussions({ where: d => !d.getResolvedAt() })` given an input row type like `type BlockRow = { id: BlockId, type: “page” | “text”, content?: BlockId[], discussions?: DiscussionId[] }; type DiscussionRow = { id: DiscussionId, resolvedAt?: Date }`
Re:Ent: An Entity Framework for Go by spion on Monday October 31, 2022 @04:18AM (#33403206)
You cannot use the lambdas operators combo without a preprocessor (like ttypescript) mainly because closure captures cannot be accessed from the function AST.

You will also need to use a tuntime dsl to describe the schema, and then derive both the model classes and the model types from it (just because runtime parts cannot be derived from types)

Other than that, the rest is very possible.

Re:Ent: An Entity Framework for Go by camgunz on Monday October 31, 2022 @07:36AM (#33404396)
> You will also need to use a tuntime dsl to describe the schema

This is kind of the whole ballgame right? How would you do any of this with types if the schema isn't defined until runtime?

Re:Ent: An Entity Framework for Go by spion on Monday October 31, 2022 @08:45AM (#33404953)
I meant that since types are erased at compile-time in typescript, its much easier to make a schema description DSL that would then serve as the base to derive both the ORM DSL (runtime objects) and the types (compile time checks). If you go the types-first route, you will be forced to use proxies which can be more painful and constraining.

The popular choice here is to use classes plus decorators, but its not the only choice

https://typegraphql.com/docs/introduction.html#what

The convenient bit here is that classes already have both a type and a runtime representation, and decorators are also available to attach any extra metadata necessary to that runtime representation

Re:Ent: An Entity Framework for Go by chrislloyd on Sunday October 30, 2022 @10:40PM (#33401472)
The other benefit of codegen in situations like this (a company wide schema) is the potential for multi language bindings. Entgo demonstrates this by bridging a Go ORM, SQL migrations and a GraphQl schema.

Interesting reading along the same lines is Language Oriented Programming (1994) http://www.gkc.org.uk/martin/papers/middle-out-t.pdf