Skip to content

execute() should return a set not a handle #2530

Description

@linas

Below is a partially-finished thought for a fundamental architectural change. It is motivated by the discussion seen in MOZI-AI/annotation-scheme#165 The issue was this:

A GSN is called to perform several computations. Rather than just depositing the results of those calculations in the AtomSpace, it was felt that the GSN should "return" several results. Since, by default, the GSN can only return a single Handle, the multiple results were wrapped in a ListLink. This lead to a proliferation of un-needed, pointless ListLinks in the AtomSpace.

This could be "fixed" by allowing the GSN to return a list (an ordered list) or a set (an unordered set), instead of returning a Handle. Under the covers, this suggests that the execute() method should return a list or set. All atomspace intrnals would have to be modified to deal with this. If some caller of execute() really, really needed a single atom, then they could explicitly wrap it in a ListLink/SetLink at that time.

The advantage of doing this is that there is less pollution of the AtomSpace with ListLinks, SetLinks. The end-user no longer would need to manage these. Another advantage is that the AtomSpace currently has multiple spots where ListLinks, SetLinks are implicitly unwrapped; perhaps these implicit unwrappings can be eased?

What might the actual solution look like? I see several possibilities:

  • Change execute() to return std::vector<ValuePtr> or maybe std::set<ValuePtr>
  • Create an InternalUseOnlySetListValue and return that. This way the C++ signature doesn't change. We just have to be carefully to make sure the user never sees this special value.
  • Create some other polymorphic return type, reminiscent of Vertex in the MOSES code-base. This kind of polymorphism is already a central underpinning concept in LISP and Scheme. This would make Atomese more lisp-like. :-/

Both the second and the third bullets enable result-polymorphism. The main difference between the second and the third bullets above is that InternalUseOnlySetListValue is supposed to be hidden from the end-user, while the polymorphism of Vertex is explicitly exposed to the user. I'm not sure I like making it explicit -- this leads to a snowball of design decisions that would turn Atomese into just another also-ran, poorly-designed dialect of LISP .. and that is not the intent...

Somewhat related is issue #1502 aka "Stop using SetLink for search results!" The current working prototype there is to declare an AnchorNode to which return values are attached, as they appear. That is, the return value is really more of a future or a promise, that can be polled, or blocked on, until the results appear. This suggests a fourth idea:

The best answer remains cloudy; this requires more ... prototyping and experimentation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions