# Read\_term\_from\_atom and upper case functor

**URL:** <https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944>\
**Category:** Predicate\
**Created:** [March 2, 2020, 10:51am UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944 "2020-03-02T10:51:34Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2020, 10:51am UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/1 "2020-03-02T10:51:34Z")

</div>

Hello,

Is there a way to have read\_term\_from\_atom/2 work with an upper case functor, e.g. with the following string “Property(x)”.

Or, do i have to first ensure that the functor is lower case — i am trying to avoid manipulating the string received, but it seems i have to lower case the functor first – which will likely require an internal copying of the whole string – something i want to avoid.

Alternatively, for my purpose i could just truncate the functor – such as a right operation with the length of the string minus one … i guess i would need to stitch this together with string\_length and substring … which probably also implies processing overhead.

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2020, 11:08am UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/2 "2020-03-02T11:08:12Z")

</div>

solved it with this:

atom\_chars(R,[\_, |R2]).

but i guess it adds processing across the string – just removed the first char – its good enough in my case

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 2, 2020, 11:10am UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/3 "2020-03-02T11:10:00Z")

</div>

There are several options to, I guess, using the Prolog parser to parse expressions that are pretty close to Prolog but with some more conventional rules. One is the Prolog flag `allow_variable_name_as_functor` and the other is the Prolog flag `var_prefix`, which is probably more useful. `var_prefix` is module local, so you can create a module, set this flag and (probably) define additional operators. Next you can use the module(M) argument of read\_term/3 or term\_string/3 to use the syntax of the specified module.

The `allow_variable_name_as_functor` flag is global, but doesn’t conflict with normal Prolog syntax and thus you can probably just set it.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 2, 2020, 11:22am UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/4 "2020-03-02T11:22:42Z")

</div>

> [@grossdan](#):
>
> atom\_chars(R,[\_, |R2]).

`sub_string(S, 1, _, 0, R2)` is a _lot_ quicker if the string gets long, especially if the next step is to open it as a stream. A Prolog list of characters requires quite a bit more resources for storing and processing than a simple array as used for SWI-Prolog strings. One of the few reasons to turn an atom or string into a list of characters is to use a DCG on it.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2020, 11:48am UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/5 "2020-03-02T11:48:05Z")

</div>

Great, thank you.

I will just set it globally – unless, i notice that it interference …

thank you,

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2020, 2:28pm UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/6 "2020-03-02T14:28:09Z")

</div>

Just noticed that arguments can also be upper case.

is there a way to get those quoted as well, via a global flag setting …

E.g.

Param(Arg1)

to

‘Param’(‘Arg1’).

Dan

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [March 2, 2020, 2:42pm UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/7 "2020-03-02T14:42:05Z")

</div>

See the `var_prefix` flag documentation.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 2, 2020, 2:43pm UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/8 "2020-03-02T14:43:04Z")

</div>

See the `var_prefix` flag. That might get you close. An alternative can be to use the variable\_names(Names) option and call `maplist(call, Names)` to bind all the variables to their names.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2020, 5:16pm UTC](https://swi-prolog.discourse.group/t/read-term-from-atom-and-upper-case-functor/1944/9 "2020-03-02T17:16:10Z")

</div>

> [@jan](#):
>
> variable\_names(Names)

looks like a great workaround …

thanks,

Dan
