optics icon indicating copy to clipboard operation
optics copied to clipboard

Enable -fdicts-strict and -fdicts-cheap in optics-tests

Open phadej opened this issue 7 months ago • 3 comments

On my machine one inspection tests starts to pass with GHC-9.10 (EDIT: because of -fdicts-cheap), I'm curious about others.

phadej avatar Jun 10 '25 15:06 phadej

I'm somewhat surprising how much effect these flags have. But on the other hand, the affected tests seems to be the ones which we have GHC-version conditionals on them. So this illustrates that we are sometimes on the edge of GHC heuristics.

I will go through these and check if these flags make more tests pass. If so, we could argue for -fdicts-strict being in -O and/or some mechanism to make -fdicts-cheap less experimental (E.g. allowing to annotate specific classes / instances as cheap).

Opionions on that? @adamgundry

phadej avatar Jun 10 '25 16:06 phadej

Afaik there's been an attempt to include -fdicts-strict in -O, but ultimately it landed in -O2 (https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2575), not sure exactly why since there's a lot of comments in the MR.

arybczak avatar Jun 11 '25 14:06 arybczak

@arybczak I'd say that -fdicts-cheap has more impact than -fdicts-strict.

I'm not sure what -fdicts-cheap does precisely, but it's different from -funfolding-dict-discount. I think it affects lambda-floating, e.g. one test which passes on GHC-9.6.5 with -fdicts-strict, but not without has following error:

        LHS:
            eta6lhs
              = ... let { $dFunctor = $p1Applicative $dApplicative_a1uG7 } in
                    let { lvl_s2eyT = $fMonoidTraversed $dApplicative_a1uG7 } in
                    let { lvl_s2eyU = $fApplicativeConst lvl_s2eyT } in
                    let { lvl_s2eq0 = $fMonoidTraversed lvl_s2eyU } in
                    \ f1 ->
                      let {
                        g1
                          = ifoldMap
                              $dFoldableWithIndex_a1uG8
                              lvl_s2eq0
                              ((\ i1 -> f1 i1) `cast` <Co:30> :: ...) } in
                      \ x -> <$ $dFunctor () ((g1 x) `cast` <Co:21> :: ...)
        RHS:
            eta6rhs
              = ... \ f ->
                      let { $dFunctor = $p1Applicative $dApplicative_a1uG7 } in
                      let {
                        g1
                          = ifoldMap
                              $dFoldableWithIndex_a1uG8
                              ($fMonoidTraversed
                                 ($fApplicativeConst ($fMonoidTraversed $dApplicative_a1uG7)))
                              ((\ i1 -> f i1) `cast` <Co:30> :: ...) } in
                      \ x -> <$ $dFunctor () ((g1 x) `cast` <Co:21> :: ...)

Sadly I have no idea what version -fdicts-cheap produces, but I'd expect it's to b eclosed to the RHS above, maybe even with $dFunctor pushed down inside he lambda.

EDIT: it doesn't. With -fdicts-cheap the above test looks like

eta6lhs
  = \ @f_a1dVI
      @i_a1dVJ
      @t_a1dVK
      @a_a1dVL
      @r_a1dVM
      $dApplicative_a1dVN
      $dFoldableWithIndex_a1dVO
      eta_B0 ->
      let { $dFunctor_s1XCx = $p1Applicative $dApplicative_a1dVN } in
      let {
        g1_s1XCz
          = ifoldMap
              $dFoldableWithIndex_a1dVO
              ($fMonoidTraversed
                 ($fApplicativeConst ($fMonoidTraversed $dApplicative_a1dVN)))
              ((\ i1_aOy1 -> eta_B0 i1_aOy1) `cast` <Co:30> :: ...) } in
      \ x_a1Xtu ->
        <$ $dFunctor_s1XCx () ((g1_s1XCz x_a1Xtu) `cast` <Co:21> :: ...)

TL;DR, at least for eta-tests -fdicts-cheap makes more stuff succeed

phadej avatar Jun 11 '25 16:06 phadej