Reference to unknown object: list

Help requests on developing Logtalk applications

Moderator: Paulo Moura

Post Reply
DamienDeville
Posts: 7
Joined: Fri Jan 03, 2020 8:13 pm

Reference to unknown object: list

Post by DamienDeville » Mon Jan 06, 2020 10:29 pm

I am having a hard time understanding:
a) The relationship between the :-uses/2 and :-logtalk_load directives
b) Whether the aliases created by :-uses are inherited down the instantiation and specialization hierarchies
c) The Linter warnings about unknown objects on the :-uses lines

Assuming that the answer to b) is yes, I have created the following meta-circular metacclass object:

Code: Select all

 1 :- object(metaclass, instantiates(metaclass)).
 2	:- use_module(clpfd, [
 3		op(760, yfx, #<==>), op(730, yfx, #\), op(720, yfx, #/\),
 4		op(700, xfx, #=), op(700, xfx, ins), op(450, xfx, ..), 
 5		(#<==>)/2, (#/\)/2, (#\)/2, (in)/2, (#=)/2, labeling/2
 6	]).
 7	:- uses(list, [append/3, member/2]).
 8	:- uses(loop, [foreach/3]).
 9	:- public(new/2).
10	new(Instance, Clauses) :- self(Class), create_object(Instance, [instantiates(Class)], [], Clauses).
11:- end_object.
hoping to avoid having to repeat the :-uses_module and :-uses directives in every object or every class.

My loader file loader.lgt is:

Code: Select all

 1 :- ensure_loaded(library(clpfd)).
 2 :- initialization((
 3 	logtalk_load(loops(loader)), 
 4 %	logtalk_load(basic_types(loader)),
 5 %   logtalk_load([listp, list]),
 6	logtalk_load(types(loader)),
 7	logtalk_load(refasModel)
 8 )).
 9 %:- initialization(logtalk_load([loops(loader), types(loader), refasModel])).
When I go to the VSC tab of the refasModel.lgt file containing my metaclass object definition the Linter warns me:
refasModel.lgt:7: Warning: Reference to unknown object: list

If I comment line 7 out, the warning then becomes:
refasModel.lgt:8: Warning: Reference to unknown object: loop

If I in turn comment line 8 out, the warning then becomes:
refasModel.lgt:2: Warning: Reference to unknown module: clpfd

I have tried to change the loading of the list object with commented out lines 4, 5 and 6 in my loader.lgt file, to no avail.

This behavior of the Linter, first cascading warnings down and then up the file is more confusing than helpful to a newb like me and the existing threads on "reference to unknown object" in this forum seem to address complex cross-referencing dynamic loading files and hence unrelated to my trivial toy problem.

How to correctly load and use the Logtalk libraries. ?

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Mon Jan 06, 2020 10:48 pm

The uses/2 and use_module/2 directives only declare predicates that will be called, respectively, using implicit message sending or implicit module qualification. Actual loading of the objects or modules referred in those directives must be done in the loader file using logtalk_load/1-2 calls.

The uses/2 and use_module/2 directives scope is local to the objects (or categories); they are never inherited. You may use a separate file with those directives (that you want to repeat) and the include/1 directive if you must but that's not a common solution.

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Tue Jan 07, 2020 8:31 am

When I go to the VSC tab of the refasModel.lgt file containing my metaclass object definition the Linter warns me:
refasModel.lgt:7: Warning: Reference to unknown object: list

If I comment line 7 out, the warning then becomes:
refasModel.lgt:8: Warning: Reference to unknown object: loop

If I in turn comment line 8 out, the warning then becomes:
refasModel.lgt:2: Warning: Reference to unknown module: clpfd

I have tried to change the loading of the list object with commented out lines 4, 5 and 6 in my loader.lgt file, to no avail.

This behavior of the Linter, first cascading warnings down and then up the file is more confusing than helpful to a newb like me and the existing threads on "reference to unknown object" in this forum seem to address complex cross-referencing dynamic loading files and hence unrelated to my trivial toy problem.
The VSC third-party plug-in parses each source file independently and is not aware of the loader file. This results in the misleading linter warnings you mention. It's a plug-in issue. If you open a terminal window, start Logtalk, and load the loader file, you will no longer get those particular warnings.

DamienDeville
Posts: 7
Joined: Fri Jan 03, 2020 8:13 pm

Re: Reference to unknown object: list

Post by DamienDeville » Tue Jan 07, 2020 7:18 pm

Paulo Moura wrote:
Mon Jan 06, 2020 10:48 pm
The uses/2 and use_module/2 directives scope is local to the objects (or categories); they are never inherited. You may use a separate file with those directives (that you want to repeat) and the include/1 directive if you must but that's not a common solution.
OK, so if an app has 200 objects, with each one of them using N basic libraries, the recommended Logtalkish style is to add N :- uses directives in each of the 200 objects so as to make all dependencies locally explicit?

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Tue Jan 07, 2020 7:30 pm

You only need to use uses/2 (or use_module/2) directives if you want implicit message sending (or module qualification). Some users like it, other users prefer explicit. Does your application requires you to write the source code of 200 distinct objects, which with their own dependencies in other objects or modules? Details?

DamienDeville
Posts: 7
Joined: Fri Jan 03, 2020 8:13 pm

Re: Reference to unknown object: list

Post by DamienDeville » Wed Jan 08, 2020 12:21 am

Paulo Moura wrote:
Tue Jan 07, 2020 7:30 pm
You only need to use uses/2 (or use_module/2) directives if you want implicit message sending (or module qualification). Some users like it, other users prefer explicit.
I am using clpfd. Putting a clpfd:: prefix in front of every occurence of its very concise operators #=, #=> etc. rapidly becomes repetitively verbose. So do I need a :-use_module(clpfd [ ... ]) directive in every object using any of those constraints? Or can I just call them everywhere without the module prefix once I have added the :- ensure_loaded(library(clpfd)). directive in my loader.lgt file?
Paulo Moura wrote:
Tue Jan 07, 2020 7:30 pm
Does your application requires you to write the source code of 200 distinct objects, which with their own dependencies in other objects or modules? Details?
Not yet I am just starting with a uber-toyish example to figure out whether Logtalk is a viable option. But in a few months, I guess it will :)

Thank you very much for your responsiveness and help.

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Wed Jan 08, 2020 8:39 am

Note that loading and usage are separated in Logtalk. Thus, in your loader.lgt file, you will have a directive:

Code: Select all

:- use_module(library(clpfd)).
But in your objects (or categories) where you want to call CLP(FD) predicates using implicit module-qualification, you will need to use the Logtalk use_module/2 directive (which differs from the same directive in Prolog in that (1) it takes a module name instead of a file spec in the first argument and (2) doesn't load the module, only declares that the entity containing the directive uses it):

Code: Select all

:- use_module(clpfd, [
    ...
]).
This is required as library predicates loaded into "user" are not visible inside objects (or categories). I.e. objects (and categories) don't inherit from "user".
Paulo Moura
Logtalk developer

DamienDeville
Posts: 7
Joined: Fri Jan 03, 2020 8:13 pm

Re: Reference to unknown object: list

Post by DamienDeville » Wed Jan 08, 2020 9:53 am

Thank you for those clarifications.
Too bad usage aliases are neither inherited nor imported though :)

Now in the loader files what is the difference between the following two syntaxes?

Code: Select all

 
 :- initialization(logtalk_load([lib1(loader), ... ,linN(loader)]).
 

Code: Select all

 
 :- initialization((
 	logtalk_load(lib1(loader)),
 	...
 	logtalk_load(libN(loader))
 )).
 

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Wed Jan 08, 2020 10:15 am

Now in the loader files what is the difference between the following two syntaxes?
No difference when using logtalk_load/1. Just user preference. But when using logtalk_load/2, the first is used when all loaded files share the same compiler options while the second allows different sets of options per loaded file.

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Thu Jan 09, 2020 9:25 pm

Related to your initial question about the warnings when using the VSC Logtalk plug-in:

https://github.com/arthwang/vsc-logtalk/issues/8

Paulo Moura
Logtalk developer
Posts: 510
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: Reference to unknown object: list

Post by Paulo Moura » Fri Jan 10, 2020 3:18 pm

P.S. Until we get a reply from the plug-in author, I suggest you try an alternative to VSC. E.g. Atom (see the coding/atom directory in the Logtalk distribution for details).

Post Reply