Need a review of linear-typed API

Have you considered making runBuilder nonlinear, i.e. runBuilder :: Builder -> Text? I don’t think that introduces any unsafety.

1 Like

@jaror done in Make runBuilder multiplicity polymorphic · Bodigrim/linear-builder@d3f3159 · GitHub

2 Likes

I think you’re right, but does this actually achieve anything? Isn’t a -o b a subtype of (or at least has an injection to) a -> b?

1 Like

Indeed, if you have

f :: a ⊸ b

you can always define

g :: a -> b 
g a = f a 

So it is preferrable to mark linear functions as such, as clients can always downgrade to a normal arrow, if it fits their API better.

2 Likes

I asked because I believe that it the only place where linearity is used in the Builder module (if you make the Builder type opaque), so that part of the API could just as well be added to the existing text package. That should already give a large speedup compared to the existing lazy text builder.

3 Likes

Hrm:

  • runBuilder :: (Builder %1 -> Builder) -> Text
  • runBuilder :: (Builder ⊸ Builder) -> Text

…anyone for plain ol’ boring:

runBuilder :: (*Builder -> Builder) -> Text

It’s concise and {-# UnicodeSyntax #-}-free.

1 Like

@atravers I made runBuilder arrow-polymorphic, see updated Data.Text.Builder.Linear

3 Likes

Alright, last call for reviews. I’ve added a section on design.
https://hackage.haskell.org/package/text-builder-linear-0.1/candidate

2 Likes

Looks amazing! I would perhaps copy one or two examples from both Builder and Buffer to the README, just to complement the benchmarks; then again, they’re well visible in the modules documentation.

Thank you

1 Like

In the recent developments text-linear-builder gained a ByteString backend: instead of threading an unpinned ByteArray, we can make it pinned and receive a ByteString in the end, both from the same Builder:

7 Likes