A metaprogramming proposal #5850
Replies: 3 comments
-
|
Sounds interesting! I'd love to learn more. To evaluate any proposal we need to have a shared understanding of the motivations and use cases for this the feature, and what the alternatives are (both in Gleam today and other potential additions to the language). Could you expand in this area please? 🙏 For the specific example given there I've some questions:
|
Beta Was this translation helpful? Give feedback.
-
type Field {
//Accessing the field of an element of a list would normally be invalid, but templates iterate over lists anyway, so it's fine.
Field(name: String, type: Type)
}
type Constructor {
Constructor(name: String, field: List(Field))
}
type SumType {
SumType(constructor: List(Constructor))
}
type RecordType {
RecordType(field: List(Field))
}
import gleam/json
import gleam/dynamic/decode
pub template json_stuff(t: RecordType) {
pub type Encoders[t] {
Encoders(encoder[t.field]: fn($t.field.type) -> Json)
}
pub type Decoders[t] {
Decoders(decoder[t.field]: Decoder($t.field.type))
}
pub fn to_json[t](enc: Encoders[$t], value: t) -> Json {
json.object([
#[t.field]($t.field.name, enc.encoder[$t.field](value.$t.field)),
])
}
pub fn decoder[t](dec: Decoders[$t]) -> Decoder($t) {
use [t.field] <- decode.field($t.field.name, dec.decoder[$t.field])
decode.success($t([t.field]:))
}
}Note the use of |
Beta Was this translation helpful? Give feedback.
-
|
So What happens in the lens example if a field does not have any labels? Are there other things that
We can implement type checking, but the typing rules of any new feature have to be designed, and then the implementation of these rules has to be designed. Gleam has a value language and a type language, so for anything to be added we have to have a design for both aspects.
Could you expand on the type checking you have in mind? 🙏
Typically template metaprogramming systems do worse than code generators when it comes to automated refactoring, etc, as templates are opaque to the tools. There's no way for them to know how to update the templates to get the desired outcome of the refactoring. How would this system avoid that problem?
If we could do that then that could be very compelling! Could you add detailed comments to each line of that code, to explain what each part does? 🙏 |
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.
-
Let's say you want boilerplate-free lenses. Then you might want to write something like:
which can be type-checked before monomorphization, which is possible because the declarations do not depend on
t, and nothing abouttis inspected except for the fact that it is aRecordType. For instance, you can't pattern match on the types of the fields because they don't exist before monomorphization.For
pub type Person {Person(name: String, age: Int)}, you use the template by writingderive lenses(Person)which monomorphizes into the following at build-time:Conceptually, a template takes a
SumType, considered as a list of constructors which are themselves lists of fields, and iterates over all its constructors and fields, generating declarations for each. ADTs with one constructor can be considered as aRecordType, which is merely a list of fields, in addition to being aSumType, to avoidResult-heavy logic, which would otherwise be used to account for the possibility of the absence of fields.Edited: Adjusted syntax for the example template
Beta Was this translation helpful? Give feedback.
All reactions