# Module magic?

**URL:** <https://swi-prolog.discourse.group/t/module-magic/3539>\
**Category:** General\
**Created:** [January 29, 2021, 4:22pm UTC](https://swi-prolog.discourse.group/t/module-magic/3539 "2021-01-29T16:22:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [January 29, 2021, 4:22pm UTC](https://swi-prolog.discourse.group/t/module-magic/3539/1 "2021-01-29T16:22:23Z")

</div>

Library module `arithmetic` has provides predicate `arithmetic_expression_value/2`:

```prolog
?- listing(arithmetic_expression_value).
:- meta_predicate arithmetic:arithmetic_expression_value(:,-).

arithmetic:arithmetic_expression_value(M:Expression, Result) :-
    eval(Expression, M, Result).

true.

?- arithmetic_expression_value(1+1,V).
V = 2.

```

And I’m wondering by what magic `1+1` unfies with `M:Expression`.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [January 29, 2021, 4:41pm UTC](https://swi-prolog.discourse.group/t/module-magic/3539/2 "2021-01-29T16:41:35Z")

</div>

> [@ridgeworks](#):
>
> what magic `1+1` unfies with `M:Expression`

When a predicate is declared as a meta\_predicate with “:” (or 0, 1, 2, etc.) then a call adds the module if it’s not already there. So, your `arithmetic_expression_value(1+1, V)`, when executed, becomes `arithmetic_expression_value(user:(1+1), V)` (or something like that).

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [January 29, 2021, 5:01pm UTC](https://swi-prolog.discourse.group/t/module-magic/3539/3 "2021-01-29T17:01:55Z")

</div>

Thanks, Peter. That complicates using `:` as a slice operator, but that’s probably fine as long as it’s only used in a block expression. Currently a naked `2:3` would evaluate to `3` since `2` isn’t a module and `3` is a valid arithmetic value. A workaround is to evaluate `_:2:3` which produces the expected value.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [January 30, 2021, 10:22pm UTC](https://swi-prolog.discourse.group/t/module-magic/3539/4 "2021-01-30T22:22:15Z")

</div>

To avoid the ambiguity I’d like to perform a quick test to see if `M` in `M:Expression` is a module name. The fastest I’ve been able to come up with is:

`atom(M), module_property(M,_)`

Any other suggestions?

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [January 30, 2021, 10:39pm UTC](https://swi-prolog.discourse.group/t/module-magic/3539/5 "2021-01-30T22:39:20Z")

</div>

> [@ridgeworks](#):
>
> see if `M` in `M:Expression` is a module name

Maybe a better solution is to use a different notation. For example `"abcdef"[1..3]`.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [January 31, 2021, 2:04am UTC](https://swi-prolog.discourse.group/t/module-magic/3539/6 "2021-01-31T02:04:00Z")

</div>

Reasonable suggestion. But I would like to maximize notation choices for the user. (This is a check in `library(arithmetic)`.) Even a simple `atom` check is sufficient for allowing numeric arguments with the `:` operator.
