Skip to content

Predicate literals for Podlang#492

Open
robknight wants to merge 1 commit intomainfrom
podlang_predicate_literals
Open

Predicate literals for Podlang#492
robknight wants to merge 1 commit intomainfrom
podlang_predicate_literals

Conversation

@robknight
Copy link
Collaborator

@robknight robknight commented Mar 13, 2026

Closes #491.

This introduces predicate literals, of two kinds:

  • Unqualified predicate literals, of the form ::pred_name, which can be used for either native or intro predicates
  • Qualified predicate literals, of the form module::pred_name, which can be used for external module predicate

Predicates from the local module cannot be referred to, to avoid circularity. Predicate literals can be used anywhere that a regular literal can appear, so it's possible to declare them as part of a set, dictionary, or array literal.

In making this PR I also observed that it's possible to create both intro predicates and custom predicates whose names clash with those of native predicates. I have adjusted the parser to reject such names.

@robknight robknight force-pushed the podlang_predicate_literals branch 3 times, most recently from 170adba to 954817f Compare March 13, 2026 16:24
@robknight robknight requested a review from ed255 March 13, 2026 16:25
@robknight robknight force-pushed the podlang_predicate_literals branch from 954817f to 3c3ebff Compare March 14, 2026 09:17
@ed255
Copy link
Collaborator

ed255 commented Mar 16, 2026

I would like to discuss the syntax for this.
Before this PR, arguments in statement templates could be:

  • wildcards
  • literals

The wildcards act as variables, you're writing a name as a reference to a runtime value identified by that name. In compilation each wildcard gets assigned a number.
The literals act as embedded constants, the value you write is directly embedded there.

"Predicate literals" is a feature to choose literal values, but the syntax to me looks more "variable-like" to me. As in, it's not obvious that the compilation will replace ::pred_name by the literal value of the predicate name. I find this a small detail and I'm sure I could get used to it; but I would like to discuss alternatives first.

To me this feature looks like a C-style macro, where you write a macro name and the preprocessor just replaces it by the literal content of the macro. In C macros are written in upper-case; but here using uppercase would look strange because we're not defining new macros, the predicate names already exist. So here's some ideas for alternative syntax that convey this "macro" idea:

# Option A
@embed(::pred_name)
@embed(module_name::pred_name)

# Option B
embed!(::pred_name)
embed!(module_name::pred_name)

# Option C
@literal(::pred_name)
@literal(module_name::pred_name)

# Option D
@quote(::pred_name)
@quote(module_name::pred_name)

@robknight
Copy link
Collaborator Author

@quote makes sense to me, although none of these names indicate that this is only to be used for replacing predicate names with hashes.

@ed255
Copy link
Collaborator

ed255 commented Mar 16, 2026

perhaps @quote_predicate(...) then? (or @literal_predicate(...))

@robknight
Copy link
Collaborator Author

This makes me wonder if other constants could be defined. For example:

const WoodPickDefault = { "durability": 100 }

NewWoodPick(obj, ...) = AND(
  Equal(obj, @quote(WoodPickDefault))
)

The same approach could be used for defining other constants, and these could be addressable across modules. This would require that modules also have a "constants" export table, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Podlang literal forms for predicates as values

2 participants