trueagi-io / hyperon-experimental

MeTTa programming language implementation
https://metta-lang.dev
MIT License
133 stars 44 forks source link

Discussion: subspace nesting ergonomics issues, and guard-rails we can add #618

Open luketpeterson opened 5 months ago

luketpeterson commented 5 months ago

Each of the following is true, and individually there is a perspective that each is not wrong. But taken together they make it easy for the user to find themselves in a frustrating situation.

  1. Having multiple copies of some MeTTa functions causes an infinite loop in the minimal interpreter. Consider the id function defined in the minimal stdlib. (= (id $x) $x) If you try and add a second copy of this function you get an infinite loop. (e.g. execute this: !(add-atom &self (= (id $x) $x)))

  2. A module's imported sub-modules are nested spaces within the module's space, and most modules import corelib & stdlib. They need to explicitly set a flag it if they don't want it.

  3. Modules track which sub-modules they import, and the import! op has silent guard rails to make sure sub-modules are flattened and duplicates are stripped away.

But if users are accessing modules' spaces directly (as we're encouraging with the mod-space! operation) I think we want something more fundamental than some special case checks built into import!

Better experience around infinite loops

Personally, I think we need a general solution to 1. as it doesn't really have anything to do with modules at all. If it's not realistic to avoid the infinite loop, then I think we need A.) timeouts and/or loop detection so we don't get stuck forever, and B.) good introspection tools so we can quickly pinpoint the cause of the hang. (This mostly exists already, maybe we just need to connect it through so ctrl-c results in displaying a partial trace)

Different way to embed sub-module spaces

I think the nested spaces for imports also deserves a rethink. I think it's fundamentally elegant and powerful so I'm not proposing changing the language semantic. But one idea I had (I remember writing it up somewhere but I can't seem to find where) is to make the running context's Space be a composite of the space containing the atoms of that space, and the spaces of the imported modules. So, rather than adding the sub-space directly to the module space, it's bonded within the context space.

I think the user would see no difference here, and it would greatly simplify the implementation of import! and get rid of problems caused by accidentally importing multiple copies of the stdlib / corelib.

vsbogd commented 5 months ago

I agree with 1. Basically, I believe it is possible to detect infinite loops of such kind using introspection. I can also look at the root cause and probably can fix it if works in rust interpreter.

vsbogd commented 5 months ago

I am not sure what you see as an issue in 2 and 3. Do you mean importing modules can lead to a function duplication and infinite loops? Or it is more a matter of an accurate design?

luketpeterson commented 5 months ago

The "Different way to embed sub-module spaces" aspect of this issue is an extension of https://github.com/trueagi-io/hyperon-experimental/issues/511