gleam-lang / stdlib

🎁 Gleam's standard library
https://hexdocs.pm/gleam_stdlib/
Apache License 2.0
492 stars 175 forks source link

Add primitives to set fields on `Uri` objects. #618

Open vxern opened 5 months ago

vxern commented 5 months ago

Considering the signature of Uri, to make working with the type a little nicer, I would propose to add value setter primitives corresponding to fields on the Uri type:

pub type Uri {
  Uri(
    scheme: Option(String),
    userinfo: Option(String),
    host: Option(String),
    port: Option(Int),
    path: String,
    query: Option(String),
    fragment: Option(String),
  )
}

The primitives would have the following signatures:

If okay'd, I'd be happy to go ahead and implement these myself.

lpil commented 4 months ago

Hello! What's the use case here? Could you give some examples from your programs and how these functions would help with them. Thanks!

chuckwondo commented 4 months ago

@lpil, this appears to be merely for convenience. See some examples in #619.

I don't know how prevalent this pattern is throughout the various gleam libraries, but at least one precedent for this type of "builder" pattern can be seen in the gleam http library, where there are a number of "setter" functions for the Request type, such as set_header, set_body, set_scheme, set_host, etc.

vxern commented 3 months ago

Sure.

https://github.com/vxern/tatoeba/blob/main/src%2Ftatoeba%2Fapi.gleam#L11

This is an example where it would have been quicker and nicer to write:

pub fn url() -> String {
  url.new()
  |> url.set_scheme("https")
  |> url.set_host("tatoeba.org")
  |> url.set_path("/eng/api_v0")
}

over:

pub const url = Uri(
  scheme: Some("https"),
  userinfo: None,
  host: Some("tatoeba.org"),
  port: None,
  query: None,
  path: "/eng/api_v0",
  fragment: None,
)
lpil commented 3 months ago

They seem about the same to me, and it's nice that the constant one has no runtime cost.

I've done a search on GitHub and it seems that directly constructing Uris is uncommon. It doesn't seem like something that there's a huge benefit to adding a small amount of convenience for.