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