Open MateuszKowalewski opened 1 year ago
I think the description needs to be a bit more concrete.
I'm still digesting how the DSL and it's implementation are "folded".
You seem to practice some form of "origami" with the different parts of the DSL and it's implementation. (I'm even not sure this is a good idea in general, but that's something for another issues.)
I've just noticed that this isn't very straight forward, and after replacing implicits with givens we have even some imho random looking imports here and there: Remember the comments about "why do we need this import here"? (Which I removed to open this issue here.)
I think this here is a long term issue. Nothing that needs instant action. But something to keep on the screen.
As soon as I understand more about the code and it's structure I'll come up likely with some proposal how to proceed here. But maybe you have already some ideas how to improve things for end-users? (Especially more documentation would be a really helpful first step… :wink: Concrete questions would be: How the DSLs, Libs, and Kits are meant to be used? What it the canonical way to start a Libretto app? Yes, one can figure it out by looking at the code. But "normal", future end-users should have docu for that.)
I meant the description of the problem needs to be more concrete. You don't have to have an idea of the solution in mind.
Remember the comments about "why do we need this import here"?
I do remember that for now, and know where to go looking for that random looking code. I will not know that in a few months. All I mean is to make the description of the problem more self-contained ;)
How the DSLs, Libs, and Kits are meant to be used?
Libretto is not one language, that would be too easy 😄 There is a hierarchy of languages.
For example, there is CoreDSL
. Then there is Scaletto
, which extends CoreDSL
.
Scaletto
gives more power to the users (producers of programs), namely gives them the ability to use Scala functions and Scala objects as managed resources.
CoreDSL
gives more power to the interpreters (consumers of programs). For example, absence of Scala functions makes it possible to serialize, analyze, generate code from, visualize, ... CoreDSL
programs.
The point being, "constraints liberate, liberties constrain."
Whenever you write a piece of Libretto code, you have to pick a DSL you are writing it in. You would pick the least powerful DSL that has all you need.
A lib is a library of code (functions, type definitions) built on top of a DSL.
If a lib requires only CoreDSL
, everything in it can be used in a Scaletto
program as well.
OTOH, things from a lib defined on top Scaletto cannot be used from a CoreDSL
program.
A kit is meant to shield the end user from the above complexity.
A kit picks one DSL, one runtime, and perhaps a bunch of libs, and makes them available to the user, without the user having to "fold the origami" themselves. Or at least that's the goal.
What if users want to write their own libraries?
They can start by writing it against (a DSL from) a selected kit.
Later, they may make it polymorphic in the DSL and runtime, by requiring only (any implementation of) the least powerful DSL.
What it the canonical way to start a Libretto app?
Write the app against a concrete kit. There's really only one kit at the moment, StarterKit
. It implements Scaletto
. For the main executable, extend StarterApp
and implement it's blueprint
method.
object MyApp extends StarterApp {
override def blueprint: Done -⚬ Done =
/* your code goes here */
}
The move to
given
made random looking "given imports" in random looking places necessary.This looks fishy.
I guess some redesign of how the givens, exports, and imports are structured would be good. Something like the common "syntax" pattern (similar to e.g. Cats) could help here.