Skip to content

Conversation

symbiont-daniel-gustafsson
Copy link
Contributor

@symbiont-daniel-gustafsson symbiont-daniel-gustafsson commented Feb 5, 2022

This is an experiment to automate the computation for offset of fields in a
record. This computation doesn't take alignment into account (and I'm not sure
it should). A benefit of having the macro is that when the type changes we don't
have to manually change the constants.

It works by adding a new macro offsetTo that given a field name computes the
size of all fields preceeding it.

*Journal> :set -XTemplateHaskell
*Journal> import OffsetMacro
*Journal OffsetMacro> $(offsetTo 'mdTermLength)
32
*Journal OffsetMacro> lOG_TERM_LENGTH_OFFSET
32

At the moment it computes to an expression that will do the sum at runtime, this
probably will be optimized away by the compiler.

This do require Template Haskell to work, with all what that entails, so not
sure yet if it is worth it.

This is an experiment to automate the computation for offset of fields in a
record. This computation doesn't take alignment into account (and I'm not sure
it should). A benefit of having the macro is that when the type changes we don't
have to manually change the constants.

It works by adding a new macro `offsetTo` that given a field name computes the
size of all fields preceeding it.

```haskell
*Journal> :set -XTemplateHaskell
*Journal> import OffsetMacro
*Journal OffsetMacro> $(offsetTo 'mdTermLength)
32
*Journal OffsetMacro> lOG_TERM_LENGTH_OFFSET
32
```

At the moment it computes to an expression that will do the sum at runtime, this
probably will be optimized away by the compiler.

This do require Template Haskell to work, with all what that entails, so not
sure yet if it is worth it.
@symbiont-stevan-andjelkovic
Copy link
Contributor

symbiont-stevan-andjelkovic commented Feb 7, 2022

One way around the problems of TH could perhaps be to only use this TH code in the testsuite to assure that the constants are correct, like a contract test?

I'm thinking something like:

data D = D
  { f1 :: A1
  , ...
  , fn :: AN
  }

d_F1_OFFSET = 0
d_FN_OFFSET = sizeOf (undefined :: A1) + ... + sizeOf (undefined :: AN)

-- In the testsuite:
assertOffsets 'D [d_F1_OFFSET, ..., d_FN_OFFSET]

This should catch if types of the fields change, if fields get renamed, if fields get removed or added (or rearranged). Is there anything else we need to worry about?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants