Passing parameters to a switch template

  • 12
  • 46

Is it even possible?
I can pass parameters to a simple template but no to a switch template. And if I could solve my generation problem by combining switches/templates and passing parameters, curently it is impossible.

Why one can't pass a parameter to a switch template?
MPS-18146 Allow template parameters definition for switch template

No good reason, except of the lack of time and relatively low priority. :(

I have just faced a problem when I tried to improve my language. Before, I had 3x2x2 cases of node reduction (all listed in mapping configuration, and this amount could be reduced by passing parameters to switches), and now I have to multiply this amount by 2. It's getting pretty messy to have all of those listed in one file (or have different copy-pasted switches with small distinctions).

Perhaps there is some other way to solve your problem without switch templates? You can add conditions to reduction rules or perhaps some things can be done with COPY_SRC macro. In last years, I had not so much use cases for switch macros...

Yes, at first I felt back to using conditions for templates, but as a result I had dozens of "MyConceptXXX" reduction rules. The problem is that exactly this piece of code has multiple parallel aspects that would be solved gracefully only if I have switch parameters:)

I solved my last problem by applying same reduction approach (that is more sophisticated than the one was before) to all existing cases - wether it's necessary or not. This made generated code more difficult to understand, but it works with a new feature added.

Sounds interesting. Is it open so that we as community could do a code review?
Would it help passing down data in genContext e.g. as var template? Or to generate polymorphic code? Or to do a model-to-model transformation first, applying aspect oriented modeling?

I'm not familiar with Git yet, so I have attached the code to this post: builders_sample.zip (826KB). Any thoughts, comments, suggestions, code review, etc. will be appreciated.

The language is an MPS version of a library we are using in our current project. Main idea of library is that you can define basic builders and build composite ones on top of them, overriding some aspects of building blocks if needed. For example, if I define a panel with two components in it, and want the second component to be variable (depending on use case), I mount a "shortcut" to a second component thus it could be overriden in sub-builders.

If you have a look at the code (and especially at examples), here are my concerns:
The most messy part of this language is a generation of extended builder's property set mechanism. I have shortcut values and default values for extended builder's property to set, shourcut can be mounted on property or not, and so is a default value. There are also two kinds of types of properties - single valued and list (and in our current project we have maps also). I can set the property of a parent builder or a property of a base class. And, at last, I can pass a parameter to shortcut.

So, eventually I could have a look at it. (Unfortunately right at this moment I can't have a look at the code again, I'm writing from my memory so please forgive me if I'm not correct at some places.) I see your subject - in generator main there is lots of duplicated (and complicate) code. And it gets worse if you add e.g. the map as third shortcut type and so on. When there is duplication or strong similarity, the questions arises where to source out this stuff? So I'm wondering if that is the right place in design to decide what should happen with shortcuts. I mean another possibility would be to have a simpler generator but let the generated Java code figure out what to do. I suspect that then there is a kernel of code which is independent of the language, solutions, and generated code. A kernel that implements the idea of swing frames with slots which can be configured to contain content and provides some abstractions and constraints. That could be an existing base - a platform - which does not need to be generated each time.
All of this generated code goes into the same class hierarchy. There could also be polymorphic 'Shortcut' classes be generated which decide themself e.g. if there has to be an 'add' or 'addAll' method.
Basically you define a screen layout and allow certain parts to be overridden. You do this by inheritance. Maybe it could be done better by composition. Inheritance is a very strong coupling, and nowadays often composition is favored over inheritance.
For me, this example is very clear case that with Language Oriented Programming there are some new dimensions for spreading responsibilities. With OOP one could decide if a responsibility is better in this or that class - e.g. in an entity or a service - placed, is it better in this or that component or in this or that layer. Now responsibilities could also be in the platform the generator uses, the generator itself or stay in the generated code. Or even alrady in the languages/solutions. And in the generator as you mention if there would be parameters in switch template there would also be even more possibilities.
In OOP, over decades of years patterns, thumb rules, principles have emerged - and some declined as well. This development has still to come and to be made in LOP.
I see how you implemented the shortcut thing but cannot completely understand /why/.
Would you possibly a little bit elaborate on this? How did you decide which responsibility gets at that place where it is, what options did you see and what forces drove you?
I had only a short glimpse on the project and as I said I don't get the "why" yet, but my feeling says I would possibly do more things in the platform and narrow the language more in a 'configuration only' direction.

Thanks for your detailed response!

Regarding to "why", if I get your question right, you're asking why generator become so overloaded (in sense of complexity) and why there is no a runtime solution that could take some of generator's functionality. Well, actually, this is a first version of this language, and at very first thought I planned builders to actually extend basic class, and I intented not to use additional classes for implementation of the language. Now, when you mentioned this, I can see that I could easily use runtime classes for each kind of shourtcut, and it would be more flexible, actually :)

Regarding to reduction to UI classes - this language is ment to be used not only for building the UI. Base class could be any - MyExpression, MyStatement, MyComponentLocator, etc, so with only builders language, baseLanguage and standard builders library distributed, one could compose complex logic without even knowing Java. This language is intented to be used by superusers.

And regarding to inheritance - actually, there is no inheritance between generated classes because of complicated shortcuts/fields hiding behavior across builders hierarchy (in model design time). Shortcuts and class fields could be hidden from subbuilders, I can explain it more if needed.

As for LOP patterns, we could start (for example, in dslzoo project) list of cases that look like patterns (although there is no enough experience in DSL to describe these cases as patterns, I think) or common problems to be solved by almost every language designer.

It took me some time to formalize my intention to move this code to generator. The main thing I want to achive while working with DSL/MPS is to move as maximum designtime-known-information to generation as I can.

From very begining MPS was for me like a missing part of programming, something that fills the gap between concrete domain model and the code that works with general information. With code generation it's possible to build code that knows about exact entities of domain model and behaves based on that knowledge. ORM tool is a good example of this: ORM framework doesn't knows which fields and links a programmer will use, so it's preferred behavior is to load-on-demand or prefetch-everything-that-isn't-expensive-to-get. With DSL it is possible to generate a code that selects exactly the data which is used in a code.

Back to shortcuts, code could be rewritten to Shortcut classes hierarchy with predefined behavior (SingleValueAccessor, ListAccessor, MapAccessor, ShortcutAccessor, ClassFieldAccessor, etc). Also, the code currently ignores generics (ClassConcept references are used instead of ClassifierType). It will be my homework on hollidays :)

Got it, thanks. Now I also have to download MPS 3 EAP (we are still on the stable version for productive coding...), that is unexpected slow at the moment.