Dismiss of CST.Types module #65
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR is not a fix for a bug/issue or an asserted proposal for a change.
I will explain my line of thoughts here that makes me propose/discuss this.
Generally, I consider
*.Types
and similarly genericly named shared modules (e.g.*.Monad
) to be an unintentional, though widely established, poor practice that leads to more complex module structure design and relationships.Such "common" modules issue sometimes is refered to horsontal vs vertical organization, though it may not be very intuitive why having such modules is not the best design choice and may seem more of subjective opinion than justified objection (though in the link above some valuable and important reasons are mentioned).
More objectively, when such modules are in place this often means violation of the following module hierarchy principle, which implies that if there are modules
A
andA.X
thenA.X
may depend onA
, butA
can never depend onA.X
. According to this principle, semanticallyA.X
extends or specifiesA
in terms ofX
and not thatA.X
holdsX
part ofA
functionality. For example, considerCodec
andCodec.JSON
.I would argue that violating this principle eventually leads to more complex and less intuitive designs, but following this simple design limitation allows for more problem specific and meaningful structure.
As a side note: as purescript doesn't support internal (not exposed) modules, I see an exception case for this only when dealing with such internal modules that hold indivisible core functionality intended to be hidden by structured external API (e.g. latest implementation of JSON modules).
I found this package in its current state to be intresting and obvious case of this problem, which is easy to fix. Based on the above considerations I made the following changes to the module structure of
Purescript.CST
:CST.Types - > CST (parent namespace to contain CST representations, which are "types" obviously)
CST -> CST.Recovered (extends CST with parsing functionality, exposes PartialModule and RecoveredParserResult, not sure if the name Recovered here conveys intention the best/correct way, but probably it does)
CST.Parser.Monad -> CST.Parser (implements and exposes Parser)
CST.Parser -> CST.Parser.Recovered (extends CST.Parser in terms of parsing to Recovered result)
CST.Range -> CST.Range and CST.Tokens (split into two independent modules)
CST.Range.TokenList -> CST.TokenList
Move print related functions to CST.Print:
I believe that this change removes some ownership and responsibilities issues, makes the structure more problem-specific and some modules simpler. Although it may seem kind of "inconvenient" that the most required functionality like
parseModule
is not in theCST
but nested inCST.Recovered
space, but this reflects intention and problem stucture more corectly. It also shows that it is now easier to split the package into something that contains only CST abstractions and other things that are focused on parsing.This is my view on the problem, I'm interested in what you think about the issue in general and specifically applied to this package.