]> Git — Sourcephile - haskell/symantic.git/blob - symantic.cabal
Add Gram_Term.
[haskell/symantic.git] / symantic.cabal
1 author: Julien Moutinho <julm+symantic@autogeree.net>
2 bug-reports: Julien Moutinho <julm+symantic@autogeree.net>
3 build-type: Simple
4 cabal-version: >= 1.24
5 category: Language
6 description:
7 __Description__
8 .
9 Library for composing, typing, compiling, transforming and interpreting
10 a custom DSL (Domain-Specific Language) expressing a subset of GHC's Haskell.
11 Its main goal is to enable the runtime handling of terms typed
12 according to some compile-time defined types.
13 The idea being that the more complex logic shall remain coded in Haskell
14 and then this library used to project an interface into a DSL
15 giving runtime users the flexibility to write simple programs suited to their needs.
16 .
17 Typical use cases:
18 .
19 * Enabling runtime users to enter some Haskell-like expressions
20 without using GHC at runtime (eg. by using <https://hackage.haskell.org/package/hint hint>).
21 * Limiting those expressions to be built only from well-controlled expressions.
22 * Run some analyzes/optimizations on those well-controlled expressions.
23 .
24 __Warning__
25 .
26 Please be aware that despite its using of powerful ideas from clever people,
27 this remains a fund-less single-person experimental library.
28 Meaning that it is all but heavily tested and documented,
29 does not have a strong commitment to preserving backward compatibility,
30 and can just die without notice.
31 Its version follows the <http://www.haskell.org/haskellwiki/Package_versioning_policy PVP>,
32 so you may want to use upper-bounds in @build-depends@.
33 This said, hope you'll enjoy the tool :)
34 .
35 __Usage__
36 .
37 Reading the boring @Test.hs@ files should give you enough examples
38 to understand how to use this library,
39 and reading some of the repetitively boring and painfully repetitive @Compiling/*.hs@ files
40 should give you some templates and the general pattern
41 to let you extend this library with your own symantics.
42 .
43 The @Test.hs@ files use <https://hackage.haskell.org/package/megaparsec megaparsec> as parser
44 and a default grammar somehow sticking to Haskell's, but staying context-free
45 (so in particular: insensitive to the indentation).
46 This grammar, itself written as a symantic embedded DSL,
47 can be reused to build another one,
48 is not bound to a specific parser,
49 and can produce its EBNF rendition.
50 .
51 __Main ideas__
52 .
53 * __Symantic DSL__.
54 To encode terms in the <http://okmij.org/ftp/tagless-final/ Tagless-Final> way
55 (aka. the /symantic/ way)
56 i.e. to use a /class/ to encode the /syntax/ of terms (eg. 'Sym_Bool')
57 and /class instances/ on a dedicated type to encode their /semantics/
58 (eg. @(Sym_Bool HostI)@ interprets a term as a value of its type
59 in the host language (Haskell here),
60 or @(Sym_Bool TextI)@ interprets a term as a textual rendition, etc.).
61
62 DSL are then composed by selecting those symantic /classes/.
63 When using symantics for an embedded DSL
64 those /classes/ are all inferred by GHC from the terms used,
65 provided that the @NoMonomorphismRestriction@ extension is on.
66 Otherwise, when using symantics for a non-embedded DSL
67 — the whole point of this library — the /classes/ composing the DSL
68 are selected manually at GHC's compile-time,
69 through the /type-level list/ given to 'compile'.
70
71 Moreover, the terms are parameterized by the type of the value they encode,
72 in order to get the same type safety as with plain Haskell values.
73 Hence the symantic /classes/ have the higher kind: @((* -> *) -> Constraint)@
74 instead of just @(* -> Constraint)@.
75
76 Amongst those symantics, 'Sym_Lambda' introduces /lambda abstractions/ by an higher-order approach,
77 meaning that they directly reuse GHC's internal machinery
78 to abstract or instantiate variables,
79 which I think is by far the most efficient and simplest way of doing it
80 (no DeBruijn encoding nor <https://hackage.haskell.org/package/bound bound>'s monads).
81
82 * __Singleton for any type__.
83 To typecheck terms using a @(Type cs h)@ @GADT@ which acts
84 as a /singleton type/ for any Haskell type @h@
85 buildable by composing the /type constants/ @cs@,
86 each one wrapped inside a @Proxy@ to fit into a common /type-level list/
87 (eg. @cs ~ [Proxy Bool, Proxy (->), Proxy Eq]@).
88
89 * __Extensible data type__.
90 To inject a type into a /type-level list/
91 or project a /type-level list/ onto a type,
92 to compose an /extensible data type/
93 (eg. the 'Token' @GADT@ gathering the 'TokenT' /data instances/,
94 that a parser can build and then give to 'compile').
95 This type-level programming requires @UndecidableInstances@,
96 but not @OverlappingInstances@.
97
98 There is a similarity with
99 <http://dx.doi.org/10.1017/S0956796808006758 Data types à la carte>
100 (see for instance <https://hackage.haskell.org/package/compdata compdata>
101 or <https://hackage.haskell.org/package/syntactic syntactic>).
102 Those also enable to compose a DSL using some machinery
103 based upon (co)free(r) (co)monads and (cata|ana)morphisms.
104 Which library fits best your problem domain and brain is for you to judge :)
105 On that topic, see also:
106 <https://www.youtube.com/watch?v=qaAKRxO21fU Stop Paying for Free Monads>.
107
108 Here, I just came up using /type-level lists/ by hacking
109 <https://hackage.haskell.org/package/glambda glambda>'s @Elem@.
110
111 * __Extensible class__.
112 To recurse on a /type-level list/ through
113 /class instances/ to compose an /extensible class/
114 (eg. 'CompileR' gathering the 'CompileI' /class instances/,
115 or the more tricky 'TermO' /type-level list-zipper/
116 gathering 'Sym_of_Iface' /class instances/
117 while providing in scope the current 'Sym_of_Iface'
118 within each 'TermO' built in a 'CompileI' /class instance/).
119 .
120 __Main extensions__
121 .
122 * @GADTs@ for knowing types by pattern-matching terms,
123 or building terms by using type classes.
124 * @Rank2Types@ for parsing @GADT@s.
125 * @TypeInType@ (introduced in GHC 8.0.1)
126 for 'Type' to also bind a kind equality for the type @h@ it encodes.
127 Which makes the /type application/ (':$')
128 give us an /arrow kind/ for the Haskell /type constructor/
129 it applies an Haskell type to, releaving me from tricky workarounds.
130 * @ConstraintKinds@ for @cs@ to contain 'Constraint's,
131 or defining /type synonym/ of /type classes/,
132 or merging /type constraints/.
133 * @DataKinds@ for type-level data structures (eg. /type-level lists/).
134 * @TypeFamilies@ for type-level programming.
135 * @UndecidableInstances@ for type-level programming
136 that may never terminate.
137 * @PolyKinds@ for avoiding a lot of uses of 'Proxy'.
138 * @TypeApplications@ for having a more concise syntax
139 to build 'Type' (eg. @ty \@Bool@).
140 * @DefaultSignatures@ for providing identity transformations of terms,
141 and thus avoid boilerplate code when a transformation
142 does not need to alter all semantics.
143 As explained in <https://ro-che.info/articles/2016-02-03-finally-tagless-boilerplate Reducing boilerplate in finally tagless style>.
144 .
145 __Bugs__
146 .
147 Your comments, problem reports, or questions are welcome!
148 .
149 You have my email address, so… just send me some emails :]
150 .
151 __To do__
152 .
153 * Study to which point /type inferencing/ is doable,
154 so that it would improve the current /type checking/,
155 and remove some type annotations in the DSL.
156 Currently each /lambda abstraction/ must have its variable explicitely typed,
157 and terms must be called with enough arguments to typecheck,
158 be it term arguments (for instance
159 @(+) :: Num a => a -> a -> a@ needs at least one term argument to check @Num a@)
160 or type arguments (for instance
161 @return :: Monad m => a -> m a@ needs a type argument to check @Monad m@).
162 * Study to which point error messages can be improved.
163 * A lot of common terms should be added in @Compiling.*@ modules.
164 Maybe as separate packages to limit dependencies.
165 * No transformation is implemented so far,
166 maybe there should be some, at least as examples
167 to demonstrate their power.
168 * Study where to put @INLINE@, @INLINEABLE@ or @SPECIALIZE@ pragmas.
169 extra-source-files:
170 extra-tmp-files:
171 -- homepage:
172 license: GPL-3
173 license-file: COPYING
174 maintainer: Julien Moutinho <julm+symantic@autogeree.net>
175 name: symantic
176 stability: experimental
177 synopsis: Library for Typed Tagless-Final Higher-Order Composable DSL
178 tested-with: GHC==8.0.1
179 -- PVP: +-+------- breaking API changes
180 -- | | +----- non-breaking API additions
181 -- | | | +--- code changes with no API change
182 version: 4.0.0.20170124
183
184 Source-Repository head
185 location: git://git.autogeree.net/symantic
186 type: git
187
188 Library
189 default-extensions:
190 DataKinds
191 DefaultSignatures
192 FlexibleContexts
193 FlexibleInstances
194 InstanceSigs
195 LambdaCase
196 MultiParamTypeClasses
197 NamedFieldPuns
198 OverloadedStrings
199 Rank2Types
200 ScopedTypeVariables
201 StandaloneDeriving
202 TupleSections
203 TypeApplications
204 TypeFamilies
205 TypeOperators
206 ghc-options: -Wall
207 -fwarn-incomplete-patterns
208 -fno-warn-tabs
209 -fprint-explicit-kinds
210 default-language: Haskell2010
211 exposed-modules:
212 Language.Symantic
213 Language.Symantic.Compiling
214 Language.Symantic.Compiling.Alternative
215 Language.Symantic.Compiling.Applicative
216 Language.Symantic.Compiling.Bool
217 Language.Symantic.Compiling.Char
218 Language.Symantic.Compiling.Either
219 Language.Symantic.Compiling.Eq
220 Language.Symantic.Compiling.Foldable
221 Language.Symantic.Compiling.Functor
222 Language.Symantic.Compiling.IO
223 Language.Symantic.Compiling.If
224 Language.Symantic.Compiling.Int
225 Language.Symantic.Compiling.Integer
226 Language.Symantic.Compiling.Integral
227 Language.Symantic.Compiling.Lambda
228 Language.Symantic.Compiling.List
229 Language.Symantic.Compiling.Map
230 Language.Symantic.Compiling.Maybe
231 Language.Symantic.Compiling.Monad
232 Language.Symantic.Compiling.MonoFoldable
233 Language.Symantic.Compiling.MonoFunctor
234 Language.Symantic.Compiling.Monoid
235 Language.Symantic.Compiling.NonNull
236 Language.Symantic.Compiling.Num
237 Language.Symantic.Compiling.Ord
238 Language.Symantic.Compiling.Sequences
239 Language.Symantic.Compiling.Show
240 Language.Symantic.Compiling.Term
241 Language.Symantic.Compiling.Term.Grammar
242 Language.Symantic.Compiling.Text
243 Language.Symantic.Compiling.Traversable
244 Language.Symantic.Compiling.Tuple2
245 Language.Symantic.Compiling.Unit
246 Language.Symantic.Interpreting
247 Language.Symantic.Interpreting.Dup
248 Language.Symantic.Interpreting.Host
249 Language.Symantic.Interpreting.Text
250 Language.Symantic.Lib.Data.Type.List
251 Language.Symantic.Lib.Data.Type.Peano
252 Language.Symantic.Parsing
253 Language.Symantic.Parsing.Token
254 Language.Symantic.Parsing.Grammar
255 Language.Symantic.Parsing.EBNF
256 Language.Symantic.Transforming
257 Language.Symantic.Transforming.Trans
258 Language.Symantic.Typing
259 Language.Symantic.Typing.Constant
260 Language.Symantic.Typing.Constraint
261 Language.Symantic.Typing.Family
262 Language.Symantic.Typing.Kind
263 Language.Symantic.Typing.Type
264 build-depends:
265 base >= 4.6 && < 5
266 , containers
267 , ghc-prim
268 , mono-traversable
269 , transformers
270 , text
271
272 Test-Suite symantic-test
273 type: exitcode-stdio-1.0
274 default-extensions:
275 DataKinds
276 FlexibleContexts
277 FlexibleInstances
278 MultiParamTypeClasses
279 NoMonomorphismRestriction
280 OverloadedStrings
281 ScopedTypeVariables
282 TupleSections
283 TypeApplications
284 TypeFamilies
285 TypeOperators
286 default-language: Haskell2010
287 ghc-options: -Wall
288 -fwarn-incomplete-patterns
289 -fno-warn-tabs
290 -main-is Test
291 -O0
292 -- -dshow-passes
293 -- -fmax-simplifier-iterations=0
294 -- -fprint-explicit-kinds
295 hs-source-dirs: Language/Symantic
296 main-is: Test.hs
297 other-modules:
298 Compiling.Applicative.Test
299 Compiling.Bool.Test
300 Compiling.Foldable.Test
301 Compiling.Functor.Test
302 Compiling.Map.Test
303 Compiling.MonoFunctor.Test
304 Compiling.Num.Test
305 Compiling.Term.Test
306 Compiling.Test
307 Compiling.Tuple2.Test
308 Parsing.Grammar.Test
309 Parsing.Test
310 Typing.Test
311 build-depends:
312 base >= 4.6 && < 5
313 , containers
314 , megaparsec
315 , monad-classes
316 , mono-traversable
317 , symantic
318 , tasty >= 0.11
319 , tasty-hunit
320 , text
321 , transformers
322
323 Test-Suite ebnf
324 type: exitcode-stdio-1.0
325 default-extensions:
326 ConstraintKinds
327 DataKinds
328 EmptyDataDecls
329 FlexibleContexts
330 FlexibleInstances
331 MultiParamTypeClasses
332 NamedFieldPuns
333 OverloadedStrings
334 PatternGuards
335 PolyKinds
336 Rank2Types
337 ScopedTypeVariables
338 StandaloneDeriving
339 TupleSections
340 TypeFamilies
341 TypeApplications
342 TypeOperators
343 ghc-options: -Wall
344 -fno-warn-tabs
345 -main-is Parsing.EBNF.Print
346 main-is: Parsing/EBNF/Print.hs
347 default-language: Haskell2010
348 hs-source-dirs: Language/Symantic
349 build-depends:
350 base >= 4.6 && < 5
351 , containers
352 , megaparsec
353 , symantic
354 , transformers
355 , tasty >= 0.11
356 , tasty-hunit
357 , text