Predicates with topics

Hi again!

I was surprised to discover that topics apparently can’t be used in predicates. To demonstrate:

(topic keyword @life)
(describe topic @life)

    Here we test if we can record that life
    (now) (@life has been output)
    has been printed
    (if) (@life has been output) (then)
    and if so do something conditionally

This compiles fine but gives a runtime error:

Here we test if we can record that life(Technical trouble: Type error: Expected object. Attempting to recover with UNDO.)
Undo failed!

My specific use case: recording when a word has been said, so that I can include it in a dictionary of keywords that have been read. I could easily do " (now) (life has been output)" and have a million different predicates floating around, but there are probably other predicates that it would make sense to be able to have topic parameters for. Is there a technical reason this isn’t allowed?



Dynamic predicates—those that you modify with (now)—need an object as the first parameter (with the exception of global variables). So if you want to set or clear flags on your topics, they have to be objects.

It may be a simple matter of replacing every @life with #life in your code.

The latest version of the library (0.32) adds something called topic objects, declared with (topic $). They are easier to use than the old dictionary-word topics.

The new topic objects behave much like ordinary objects, with (name $) and (dict $), but they don’t have to be in scope. The parser will recognize them everywhere a topic is expected. So you could define:

(topic *)
(name *)    life
(proper *)

[Edit: Added (proper *)]

and there’s no need for (describe topic $) or (topic keyword $). Then you could have a rule for e.g. (perform [ask #doctor about #life]), and things would just work.

1 Like

Interesting! I can’t find mention of topic objects in the documentation, I’ll have to dig through the standard library and see how they work. Thanks!

Here: Non-player characters — Conversation

1 Like