Changes between Version 3 and Version 4 of Annotations
- Timestamp:
- 10/13/08 08:09:43 (5 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Annotations
v3 v4 3 3 == Motivation == 4 4 5 Annotations are useful for both [wiki:Plugins Plugins] and for users that would like to introspect more carefully on other, already-compiled modules. 5 Annotations are useful for both [wiki:Plugins Plugins] and for users that would like to introspect more carefully on other, already-compiled modules. The concept is substantially similar to the annotation systems in such popular languages as C# and Java. Some use cases might be: 6 7 * Mark functions for modification by [wiki:Plugins Plugins] 8 9 * Store extra information relevant to a plugin but which is added by that plugin itself, such as a strictness analysis plugin that adds a demand signature to functions, which can be inspected later on by the same plugin when it comes to compile modules that depend on that one 10 11 * Specify extra documentation or comments for functions / types in the source code that could be extracted / nicely formatted by a later program 12 13 * Mark certain functions as tests, suitable for execution by a QuickCheck runner 6 14 7 15 == State Of Play == … … 9 17 An annotations system was implemented as part of the Compiler Plugins Summer of Code project (Summer 08). It is currently in the process of being revised before being committed to GHC HEAD. Details of the implementation are below. 10 18 11 == Summer of Code Implementation ==12 13 Annotations look like this:19 == Summer of Code Implementation (OLD) == 20 21 In this old implementation, annotations look like this: 14 22 15 23 {{{ … … 107 115 Yet another disadvantage is that we will be doing some compile time compilation without it being introduced with the $() syntax that has heralded all such computation previously - instead, annotations are wrapped in a sort of "implicit splice". This might cause user confusion. 108 116 109 Another disadvantage is that currently there is no standard Binary class in the Haskell libraries. We propose to add such a beast by adding [http://code.haskell.org/binary/ Data.Binary] as a boot library and supporting automatic instance deriving for it in GHC. The advantages of doing this rather than somehow reusing GHCs inbuilt Binary class are that: 117 === Serialization Issues === 118 119 Another disadvantage of this new annotations scheme is that currently there is no standard Binary class in the Haskell libraries. We propose to add such a beast by adding [http://code.haskell.org/binary/ Data.Binary] as a boot library and supporting automatic instance deriving for it in GHC. The advantages of doing this rather than somehow reusing GHCs inbuilt Binary class are that: 110 120 111 121 * It is compiler independent … … 115 125 * The binary package will be distributed with the Haskell Platform anyway because it is depended on by cabal-install 116 126 127 * We can provide ''deriving (Binary)'' 128 117 129 Disadvantages are that: 118 130 … … 121 133 * GHCs own Binary instances for it's own data types cannot be reused straightforwardly. We contend that there are few cases where doing so would be useful, and if e.g. you want to refer to another thing rather than use a GHC Name you can use a TH Name. It would be difficult to piggyback the GHC Binary instance on Data.Binary because there is nowhere in Data.Binary to squirrel away the UserData GHCs Binary instance needs to do some of its stuff (but maybe you could deserialize to a function of type ''UserData -> Iface*'' to achieve the same effect...) 122 134 135 * By adding binary as a boot library distributed with GHC it will be impossible to upgrade binary separately from GHC itself without introducing problems. Consider packages P and Q, the binary package distributed with ghc (binary-1) and that installed at a later point by a user (binary-2), and the following web of dependencies: 136 137 {{{ 138 P 139 |\____ 140 / Q 141 ghc \ 142 / binary-1 143 binary-2 144 }}} 145 146 P depends indirectly on both binary versions. What happens if it tries to use an instance of Binary from binary-1 with ghc, or an instance of Binary from binary-2 with Q? They won't unify, so this is a (rather confusing) type error! Argh! What's more, this really might happen because Binary is exported in the API to access annotations: 147 148 {{{ 149 -- For normal GHC API users: 150 getAnnotations :: (Typeable a, Binary a) => Name -> GHCM [a] 151 152 -- Only for plugins adding their own annotations: 153 getAnnotations :: (Typeable a, Binary a) => Name -> CoreM [a] 154 putAnnotations :: (Typeable a, Binary a) => Name -> a -> CoreM () 155 }}} 156 157 We have sort of the same problem outlined above even today because bytestring is a boot library. However, since bytestring isn't exported by GHC you don't end up with this sort of weird situation. (Though it might give Cabal as much of a headache as the binary problem outlined above). 158 159 The main alternative to using binary as a boot package is to import the whole source tree for binary and bytestring but rename them to ghc-binary and ghc-bytestring respectively. This ensures there are no conflicts with user code, but: 160 161 * Might be confusing! 162 163 * Means user code might have to make use of the package-qualified import syntax if they intend to reference both ghc-binary and binary from their code 164 165 * Means we have to have two identical instance declarations for any user types that want to be used both as normal Binary and GHC Binary 166 167 * Means we can't support ''deriving Binary'' 168 169 * Etc etc... 170 171 The other alternative we came up with is to change the GHC API to annotations to this: 172 173 174 {{{ 175 -- For normal GHC API users: 176 getAnnotations :: (Typeable a) => (ByteString -> a) -> Name -> GHCM [a] 177 178 -- Only for plugins adding their own annotations: 179 getAnnotations :: (Typeable a) => (ByteString -> a) -> Name -> CoreM [a] 180 putAnnotations :: (Typeable a) => (a -> ByteString) -> Name -> a -> CoreM () 181 }}} 182 183 This doesn't require any more packages (we could even remove the ByteString usages here) and it does allow use of multiple different serialization libraries for annotations (should that be desirable). However, this doesn't enforce that the serializer and deserializer for a particular bit of data should be coherent and makes the API a bit unfriendlier. 184 123 185 == Future Work == 124 186 125 * Plugins cannot currently add further annotations during compilation that will be compiled into the result. I.e. any annotations they add are transient and disappear at the end of that particular run of the Core pipeline.187 * '''(Only in SoC implementation)''' Plugins cannot currently add further annotations during compilation that will be compiled into the result. I.e. any annotations they add are transient and disappear at the end of that particular run of the Core pipeline. 126 188 127 189 * We might want to add attribute metadata, so users can specify the multiplicity attributes should take, what sorts of things they can be attached to (value, type, module), and perhaps even what types they can be attached to (e.g. "only things of type a -> Bool for some a"), similar to C# ([http://msdn.microsoft.com/en-us/library/tw5zxet9(VS.80).aspx]) or Java. … … 143 205 * Non-top-level identifiers (for plugins: tricky because such names are unstable) 144 206 145 * I believe it would make sense to allow annotations to use the implementations of values in the module being compiled,: after all, I they can use the implementations of values in imported modules. This would filling out the relevant field with an error during compilation (for the benefit of plugins) and linking the annotation fields up to the required values after compilation. Is this a good idea?207 * '''(Only in SoC implementation)''' I believe it would make sense to allow annotations to use the implementations of values in the module being compiled,: after all, I they can use the implementations of values in imported modules. This would filling out the relevant field with an error during compilation (for the benefit of plugins) and linking the annotation fields up to the required values after compilation. Is this a good idea? 146 208 147 209 * Have retention policies, similar to Java?
