# Gleamgen
[](https://hex.pm/packages/gleamgen)
[](https://hexdocs.pm/gleamgen/)
A package for generating clean, type-checked, and formatted Gleam code ✏️
## Installation 🚀
```sh
gleam add gleamgen
```
## Example
```gleam
import gleam/io
import gleam/list
import gleam/string
import gleamgen/expression
import gleamgen/expression/block
import gleamgen/function
import gleamgen/import_
import gleamgen/module
import gleamgen/module/definition
import gleamgen/parameter
import gleamgen/render
import gleamgen/types
pub fn generate() {
let mod = {
use imported_io <- module.with_import(import_.new(["gleam", "io"]))
use imported_string <- module.with_import(import_.new(["gleam", "string"]))
// module_used is of type Expression(String)
use module_used <- module.with_constant(
definition.new("module_used"),
expression.string("Gleamgen"),
)
use greeter <- module.with_function(
definition.new("greeter"),
function.new1(
param1: parameter.new("greeting", types.string),
// we have said that greeter returns a string, so handler returning anything
// else would be a type error
returns: types.string,
handler: fn(greeting) {
greeting
|> expression.concat_string(expression.string(" from "))
// trying to concatenate any other type would be a compilation error
|> expression.concat_string(module_used)
},
),
)
// Let's pick a greeting that we will use inside the generated code
let assert [outer_greeting, ..] =
list.shuffle([
expression.string("Howdy"),
expression.string("Hello"),
expression.call2(
// If this is not the selected greeting, gleam/string will not be
// imported in the final code
import_.value_of_type(
imported_string,
"repeat",
types.reference(string.repeat),
),
expression.string("Hi"),
expression.int(5),
),
])
use _main <- module.with_function(
definition.new("main") |> definition.with_publicity(True),
function.new0(types.nil, fn() {
use greeting <- block.with_let_declaration(
"greeting",
expression.call1(greeter, outer_greeting),
)
expression.call1(
// reference the actual io.println function to get the name and
// the type signature
import_.value_of_type(
imported_io,
"println",
types.reference(io.println),
),
greeting,
)
}),
)
module.eof()
}
mod
|> module.render(render.default_context())
|> render.to_string()
}
```
This will generate something like:
```gleam
import gleam/io
const module_used = "Gleamgen"
fn greeter(greeting: String) -> String {
greeting <> " from " <> module_used
}
pub fn main() -> Nil {
let greeting = greeter("Hello")
io.println(greeting)
}
```
In general, there are two versions of every gleamgen function:
- The version with phantom types to ensure type safety of the generated code
- The "dynamic" version, which does not ensure type safety but is more flexible
When possible, use the typed version to ensure the correctness of the generated code.
Note:
This library has not reached version 1.0.0, so it is not stable.
1.0.0 should be released soon.
Further documentation can be found at <https://hexdocs.pm/gleamgen>.
Also check out the examples folder (or the tests).