# User-defined function on dict not found

**URL:** https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090
**Category:** General
**Created:** [December 20, 2023, 5:09pm UTC](https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090 "2023-12-20T17:09:15Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)
#### Post date: [December 20, 2023, 5:09pm UTC](https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090/1 "2023-12-20T17:09:15Z")

</div>

I have a dictionary of dictionaries, like this:

```prolog
type{name: person, args: [arg{name: name}, arg{name:dob}]}

```

Types and arguments have optional descriptions; if missing, the description is to be sourced from the name. I want to say that with a user-defined function:

```prolog
D.description() := D.get(description) :- !.
D.description() := D.name.

```

When I use the function within the module where I defined it as with SomeType.description(), I get:

```prolog
ERROR: -g main: eval_dict_function/4: Unknown procedure: type:description/2

```

Reverting to a normal predicate works just fine:

```prolog
spec_description(Spec, Description) :-
  Description = Spec.get(description), !.
spec_description(Spec, Spec.name).

```

Perplexingly, the user-defined function works fine when I use it in a different module.

**Side question:** how come these user-defined functions don’t have to be published in the module header in order to be used in other modules? Are these definitions global?

**Side question:** what’s the best way to make a user-defined function work only with certain dictionary types? Do I need to put conditions on the dictionary tag name? `D.description() := … :- D = type{_}`?

**Side note:** the error message doesn’t have a file and line number like typical error messages do. That makes dictionary error debugging more cumbersome than it needs to be.

---

<div class="post-metadata">

### Author: ![Ian](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ian/32/1026_2.png) [@Ian](https://swi-prolog.discourse.group/u/Ian)
#### Post date: [December 20, 2023, 5:29pm UTC](https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090/2 "2023-12-20T17:29:16Z")

</div>

The function is looked up in the module with the same name as your tag (which also answers your second side question). See [SWI-Prolog -- User defined functions on dicts](https://www.swi-prolog.org/pldoc/man?section=ext-dict-user-functions)  
I created a module named mydict, and from the user module saw the below.

mydict.pl

```prolog
:-module(mydict,[]).
D.description() := D.get('description',D.name).

```

And at the top level.

```prolog
?- use_module(mydict).
true.

?- Z=mydict{description:'Hello',name:'N/A'},writeln(Z.description()).
Hello
Z = mydict{description:'Hello', name:'N/A'}.

?- module(mydict).
true.

mydict: ?- Z=mydict{description:'Hello',name:'N/A'},writeln(Z.description()).
Hello
Z = mydict{description:'Hello', name:'N/A'}.

mydict: ?- Z=mydict{name:'Ian'}.description().
Z = 'Ian'.

```

---

<div class="post-metadata">

### Author: ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)
#### Post date: [December 20, 2023, 6:17pm UTC](https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090/3 "2023-12-20T18:17:20Z")

</div>

I’ve read something in the doc about there being a module for each dictionary. Then do I have to define description() once for type and once for arg, in separate modules?

And can I create the same module in multiple places? It seems so based on your example.

---

<div class="post-metadata">

### Author: ![viridium](https://avatars.discourse-cdn.com/v4/letter/v/e56c9b/32.png) [@viridium](https://swi-prolog.discourse.group/u/viridium)
#### Post date: [December 31, 2023, 2:18am UTC](https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090/4 "2023-12-31T02:18:24Z")

</div>

Also, does the very fact of defining a dictionary create a module? How does that interact with modules of the same name elsewhere in the project? Do we have to keep the module names separate across the board?

---

<div class="post-metadata">

### Author: ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)
#### Post date: [December 31, 2023, 9:58am UTC](https://swi-prolog.discourse.group/t/user-defined-function-on-dict-not-found/7090/5 "2023-12-31T09:58:23Z")

</div>

> [@viridium](#):
>
> defining a dictionary create a module?

Your question is a bit ambiguous, but seems to me that modules are involved only when [you’re defining your own code](https://www.swi-prolog.org/pldoc/man?section=bidicts#sec:ext-dict-user-functions) for a specialized dictionary.  
FWIW, a quick test could use current\_module/1:

```prolog
...
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- setof(M,current_module(M),Ms).
Ms = [ansi_term, base32, link_xpce, pce_swi_hooks, predicate_options, predopts_analysis, prolog, prolog_clause, prolog_debug|...].

?- P=a_point{x:1,y:2}.
P = a_point{x:1, y:2}.

?- setof(M,current_module(M),Ms).
Ms = [ansi_term, base32, link_xpce, pce_swi_hooks, predicate_options, predopts_analysis, prolog, prolog_clause, prolog_debug|...].

```
