UniFormal / MMT

The MMT Language and System
https://uniformal.github.io/
Other
68 stars 23 forks source link

Document extensions being required to be added/initialized by the controller #446

Closed ComFreek closed 5 years ago

ComFreek commented 5 years ago

E.g. the following code fails due to the report field of Logger (as inherited by every Extension) is not populated without the extension being added to the controller (which does that initialization):

val simplifier = new RuleBasedSimplifier() // it extends Extension
simplifier(…)

Fix:

val simplifier = new RuleBasedSimplifier() // it extends Extension
ctrl.extman.addExtension(simplifier, Nil)
simplifier(…)

Maybe extensions should never allow to be instantiated on their own? (where "allow" means that the Scala type system should enforce this)

Jazzpirate commented 5 years ago

This is behavior as is expected. Extensions extend the controller. Without being added to it, they can't do anything. https://uniformal.github.io/doc/api/extensions/

"Maybe extensions should never allow to be instantiated on their own? (where "allow" means that the Scala type system should enforce this)"

It's unclear to me how that would be possible...

ComFreek commented 5 years ago

It wasn't clear from the RuleBasedSimplifier API doc that it is in fact an extension until I inspected the inheritance chain.

It's unclear to me how that would be possible...

I am not sure, however, one common rule is to never allow objects to be created in an inconsistent state to begin with.

Jazzpirate commented 5 years ago

There's probably no reason to ever create a new RuleBasedSimplifier at all - the controller is initialized with one, which you can (and should) use instead (if there aren't other reasons why you might want to create a new one, but I can't think of any).

one common rule is to never allow objects to be created in an inconsistent state to begin with.

It seems to me that rule is broken by lots of java best practices, where initialization is routinely done with null objects which are only replaced later on. This is in fact what happens here. The problem is that the controller needs to be handed the extension to register and initialize it, which means the extension has to exist before, but the point of an extension is that it has access to the controller- so the initial controller is a null object and is replaced by the controller itself before initialization.

The way around that would be to hand over the whole instantiation process to the controller itself, which is often extremely inconvenient in practice and requires some reflection (you'd have to tell the controller the class path instead etc...) ....so... let's not go down that road please :D

Jazzpirate commented 5 years ago

however, the latter is in fact what happens when you execute the "extension <classpath>" command in the MMT shell, which is why I routinely use that in some parts of the code, which are however unstable wrt refactoring (when you change the class path of the extension, you have to replace the fully qualified class path string in the above command as well) and do not return the very extension you just created, which you often want to have,of course ;)