An acceptable way to define schemas in Gleam #1876
Replies: 4 comments 13 replies
-
What would help me a lot is being able to reuse variant type values without wrapping them so I can define them somewhere and import them. That being said you can create a field that holds the name so you can access that at runtime, pretty much like Elixir Structs hold a name AFAIR. Maybe it would be helpful to have compile time constants #1501 and one could be |
Beta Was this translation helpful? Give feedback.
-
One existing example of the creation of a schema is the
Could you share some ideas and possibly pseudocode on how you might use this feature? Thanks! |
Beta Was this translation helpful? Give feedback.
-
I've been thinking about this for the past few days, but it seems like I only have a vague idea and I cannot totally grasp it! import gleam/reflection
pub type User {
User(username: String, score: Float)
}
reflection.kind(String) // "Primitive"
reflection.kind(User) // "Custom"
reflection.name(User) // "User"
reflection.fields(User) // [#("username", "String"), #("score", "Float")] or maybe [#("username", String), #("score", Float)] now that types are also values! This would mean that Gleam should have a type for types(a kind maybe?). Or maybe two types, one for primitive types and one for custom types. Which would make things more clear and then you won't need the Of course there is the complicated case of: pub type User {
Guest
LoggedIn(username: String)
} which I'm not sure how to handle right now. Taking a look at this may help! It's very interesting but I'm not sure how we can adapt it to Gleam. |
Beta Was this translation helpful? Give feedback.
-
➕ 1️⃣ for having some reflection stuff in Gleam. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
As you may or may not know, I'm the developer of the gleam_mongo package and you can see in the roadmap that I plan to add more features to it so that someday people can actually use it in production. But there is one feature that comes to my mind from time to time that I can't bring myself to put in the roadmap because of one particular problem that I can't seem to find a good way to solve and that feature is supporting mongodb's schema validation.
I've also thought about writing a graphql library for Gleam, but I had to put that thought aside because of the same problem I mentioned above and that problem is:
I'm pretty sure anybody that reads this, instantly thinks of a way to do this in Gleam that may actually look satisfactory to them but since Gleam isn't stable yet, I think it makes sense to not be satisfied so easily and actually look for a better way. So let me go through my thought process to show why I don't think there is a good solution for the mentioned problem in Gleam yet!
The obvious solution that comes to mind, is to have a function that developers can use to define their schemas. This function will receive e.g. a document of type
List(#(String, String))
. I'm also sure you can come up with a type that allows for nested schemas. But my problem with this approach is that inevitably the developer needs to define some Gleam types equivalent with the schemas they define and that means there are now multiple sources of truths for the entities that the developer needs to define to implement their business logic and that seems like bad DX to me!Another solution is to use non-Gleam code to define the schemas as a single source of truth and then auto-generate Gleam types from them. For graphql you can use
gql
files and for mongodb you can usejson
schemas insidejson
files. Then you can run a task that goes through those schemas and creates some Gleam files that contain the equivalent Gleam types. This has the advantage that we now have a single source of truth for the business entities we want to define. But there are several disadvantages. First: What if we want to use mongodb schema validation and graphql in the same project? Then we'll have the same problem of multiple sources of truths. Second: It would be ideal if we could let Gleam developers use Gleam to solve their problem. Third: Gleam currently does not have a standard way of running predefined tasks (But I think implementing one is a milestone, so I mentioned it as the third problem).The last solution that comes to my mind, and I really think is the ideal solution, is that the developer only needs to define Gleam types and those types can be used to generate mongodb and graphql schemas. I've actually tried to accomplish this. Of course the types themselves will not be there when you're running your code but you can inspect values created using those types using the
dynamic
module. But the problem is that those values don't retain the field names in the custom type so I can't actually use them to define a schema. Another problem is that fields in custom types can't have default values, so you have to give each of them a dummy value to create the entity that you want to inspect, which means you can't actually use this solution in the general case when you don't have an idea what the fields and their types are.As I said the last solution seems to me to be the ideal solution to this problem but you can't actually implement it using Gleam. I understand that retaining full type information at runtime may seem wasteful given that this may be the only problem that it may solve, but I just want to say that if this is actually supported, people will probably find more use cases for it. There is also the option to just retain type information for a few selected types. So maybe you can have e.g. a
firm
keyword like this:And maybe if you define some types as
firm
, the Gleam compiler creates some kind of a data structure that contains all the information about all thosefirm
types that can somehow be accessed at runtime.These are just some primitive thoughts of someone who doesn't have a lot of practical knowledge about implementing a compiler so I don't think I can actually formulate a concrete proposal, I'm not even sure if this actually makes sense. But hopefully we can have a fruitful discussion about this issue.
EDIT: I was searching for something similar for typescript/javascript and I found this which seems interesting!
Beta Was this translation helpful? Give feedback.
All reactions