-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider switching to microlens or overloaded dot syntax? #465
Comments
I think the main issue is that we're very reliant on two things: a) the a) is important because there is a lot of name reuse in the LSP spec. We really need overloaded field accessors, and with lens that means using the classy lenses AFAIK. b) is important because there are so many types, there is no way we could write them by hand. Maybe once I finally get #458 over the line we could consider writing our own lens generation machinery... but that seems like a lot of work :/ Alternatively I guess something like |
I have to admit I'm not that experienced with lenses and such. 😅 |
In any particularly big development you'll have Consider the install plan for
I'm actually somewhat surprised that there aren't more dependencies on In the big picture TL;DR if you change EDIT: |
I'm considering switching to
I don't know how bad this would be downtream, though. |
Trying it out it seems that kcsongor/generic-lens#96 would be annoying for us. |
But then you'll do a lot of generics evaluation at compile time at each use site (and GHC is slow to do that). It's far from clear it is a net win (especially if |
Yes, I agree the compilation time is maybe a wash. Honestly the thing I find most pleasing is being able to get away from prefixing all the fields with |
With {-# LANGUAGE NoFieldSelectors, TemplateHaskell #-}
import Control.Lens
import Language.Haskell.TH (mkName, nameBase)
data Foo = MkFoo { int :: Int, char :: Char} deriving Show
$(let namer _ty _ns n = [TopName $ mkName $ nameBase n] -- identity namer
rules = lensRules & lensField .~ namer
in makeLensesWith rules ''Foo)
main :: IO ()
main = do
print $ (MkFoo 21 'x')
& char .~ 'y'
& int %~ (* 2) Tested with GHC-9.2.7. |
FYI, generic lenses and prisms from As for the runtime performance, generic lenses at least for pure products always (well, up to 100 fields at minimum) optimize well (this is ensured by tests from https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2965), for sums it's more restrictive (more details are in the MR if you're interested). A long time ago I've switched a large codebase with about 3k use sites of lenses from TH generated optics to generic optics and compile times with optimizations were pretty much the same (about 15% slower without optimizations). |
This adopts the approach discussed here: #465 (comment) That is: - We export normal, non-prefixed record selectors (still using `DuplicateRecordFields`, of course). - Users who want lenses can use `generic-lens`; `lsp` and `lsp-test` do this. - It's sensible for `lsp-types` to define some useful lenses that aren't derived from fields; these go in a `lsp-types-lens` component. I think the result is... fine? kcsongor/generic-lens#96 is a pain in some cases, but by and large using the generic lenses is quite nice. I also tried to just use `OverloadedRecordDot` instead of lenses where I could, since we now support 9.2 as our earliest version. I couldn't quite get rid of `lens` in `lsp`, it's too useful. I did get rid of it entirely in `lsp-types`, which was quite painful in at least one place. This would obviously be a huge breaking change, but I think it's the right direction.
Hi,
I saw that
lsp
has a dependency onlens
, which is a fairly large dependency.Would it be possible to swap it out for an alternative such as overloaded dot syntax or
microlens
?I'm asking this because my compiler's build time almost doubled just including this library.
Are there any things blocking this? Or is there another reason behind it?
The text was updated successfully, but these errors were encountered: