• A challenge for Logtalk and GNU-Prolog (ensure_loaded/1)

    From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Jul 23 12:35:58 2021
    Whats a little challenge, is to get the canonical file names. In
    Jekejeke Prolog we call the file system to give us a canonical
    file name. Things then get even more funny for URLs, we

    even normalize them including %xx encoding manipulations and
    punny manipulations. Not sure how this all works out in JavaScript.
    The proof of concept will be if we have a predicate current_source/1,

    that lists the consulted sources. The same built-in also exists in
    Jekejeke Prolog. We could store sys_source/2 with additional flags, so
    as to detect cyclic ensure_loaded etc..

    current_source/1 would be only a facade.

    Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 21:23:46 UTC+2:
    Its the double DCG problem and similar problems,
    even the earth benders are lost on this problem
    and have suggested Tarau engines.

    LoL

    But what about the air nation? Can it solve the
    problem. I understand that it might be difficult,
    because of the various stages and artefact

    transformations involved in GNU Prolog. But maybe
    a little separate compilation and later linking
    would do the job. So that an ensure_loaded/1 directive

    would spawn a separate compilation, put the artefact
    on a list, and at the end of a consult batch all
    separate artefacts are linked together or

    otherwise integrated.

    Mostowski Collapse schrieb:
    Well the consult/1 I provide is weaker than
    the ensure_loaded/1. But ensure_loaded/1 is planned.

    Prolog explicit version of ensure_loaded/1 #80 https://github.com/jburse/dogelog-moon/issues/80

    Mostowski Collapse schrieb:
    Isn't ensure_loaded/1 a directive defined in the
    ISO core standard [ISO 7.4.2.8]. Why do Logtalk
    and GNU-Prolog not have it.

    I managed to provide a consult/1 for Dogelog runtime.
    Its reentrant. Means a file in progress of consult/1
    can call consult/1 on another file, and it

    gets correctly consulted as well. And Dogelog runtime
    is a transpiler similar like Logtalk or GNU-Prolog.
    Means the sub call of consult/1 will also pass

    the the compiler pipeline consisting of transform
    and encode. Why cant Logtalk or GNU-Prolog do that
    as well? Whats the Prolololoblem?


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Jul 23 21:17:28 2021
    Well the consult/1 I provide is weaker than
    the ensure_loaded/1. But ensure_loaded/1 is planned.

    Prolog explicit version of ensure_loaded/1 #80 https://github.com/jburse/dogelog-moon/issues/80

    Mostowski Collapse schrieb:
    Isn't ensure_loaded/1 a directive defined in the
    ISO core standard [ISO 7.4.2.8]. Why do Logtalk
    and GNU-Prolog not have it.

    I managed to provide a consult/1 for Dogelog runtime.
    Its reentrant. Means a file in progress of consult/1
    can call consult/1 on another file, and it

    gets correctly consulted as well. And Dogelog runtime
    is a transpiler similar like Logtalk or GNU-Prolog.
    Means the sub call of consult/1 will also pass

    the the compiler pipeline consisting of transform
    and encode. Why cant Logtalk or GNU-Prolog do that
    as well? Whats the Prolololoblem?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Fri Jul 23 21:16:12 2021
    Isn't ensure_loaded/1 a directive defined in the
    ISO core standard [ISO 7.4.2.8]. Why do Logtalk
    and GNU-Prolog not have it.

    I managed to provide a consult/1 for Dogelog runtime.
    Its reentrant. Means a file in progress of consult/1
    can call consult/1 on another file, and it

    gets correctly consulted as well. And Dogelog runtime
    is a transpiler similar like Logtalk or GNU-Prolog.
    Means the sub call of consult/1 will also pass

    the the compiler pipeline consisting of transform
    and encode. Why cant Logtalk or GNU-Prolog do that
    as well? Whats the Prolololoblem?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Jul 23 21:23:44 2021
    Its the double DCG problem and similar problems,
    even the earth benders are lost on this problem
    and have suggested Tarau engines.

    LoL

    But what about the air nation? Can it solve the
    problem. I understand that it might be difficult,
    because of the various stages and artefact

    transformations involved in GNU Prolog. But maybe
    a little separate compilation and later linking
    would do the job. So that an ensure_loaded/1 directive

    would spawn a separate compilation, put the artefact
    on a list, and at the end of a consult batch all
    separate artefacts are linked together or

    otherwise integrated.

    Mostowski Collapse schrieb:
    Well the consult/1 I provide is weaker than
    the ensure_loaded/1. But ensure_loaded/1 is planned.

    Prolog explicit version of ensure_loaded/1 #80 https://github.com/jburse/dogelog-moon/issues/80

    Mostowski Collapse schrieb:
    Isn't ensure_loaded/1 a directive defined in the
    ISO core standard [ISO 7.4.2.8]. Why do Logtalk
    and GNU-Prolog not have it.

    I managed to provide a consult/1 for Dogelog runtime.
    Its reentrant. Means a file in progress of consult/1
    can call consult/1 on another file, and it

    gets correctly consulted as well. And Dogelog runtime
    is a transpiler similar like Logtalk or GNU-Prolog.
    Means the sub call of consult/1 will also pass

    the the compiler pipeline consisting of transform
    and encode. Why cant Logtalk or GNU-Prolog do that
    as well? Whats the Prolololoblem?


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Jul 23 12:49:50 2021
    canonical file names can be a challenge. For example SWI-Prolog
    claims it does so. It says:

    absolute_file_name(+File, -Absolute)
    Expand a local filename into an absolute path.
    The absolute path is canonicalised: references to . and .. are deleted.
    https://www.swi-prolog.org/pldoc/man?section=files

    But it doesn't work. I have file named 'Dict.TXT' on a Mac:

    ?- absolute_file_name('/Users/janburse/Desktop/dict.txt', X).
    X = '/Users/janburse/Desktop/dict.txt'.

    So what am I supposed to do, if on one side Dict.TXT is consulted
    and on another side dict.txt is consulted? Am I supposed to call
    same_file/2?

    ?- same_file('/Users/janburse/Desktop/dict.txt', '/Users/janburse/Desktop/Dict.TXT').
    true.
    ?- same_file('/Users/janburse/Desktop/dict.TXT', '/Users/janburse/Desktop/Dict.txt').
    true.

    But this doesn't lead to a canonical name. Its only an equivalence
    relation on a relative large equivalence class, on the Mac file
    search is case insensitive.

    To implement ensure_loaded/1 with same_file/2 I would
    need to call it O(N^2) and cross compare all already compiled
    file names. With a canonical name I could do some first

    argument indexing which seems more natural to me.

    Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 21:36:00 UTC+2:
    Whats a little challenge, is to get the canonical file names. In
    Jekejeke Prolog we call the file system to give us a canonical
    file name. Things then get even more funny for URLs, we

    even normalize them including %xx encoding manipulations and
    punny manipulations. Not sure how this all works out in JavaScript.
    The proof of concept will be if we have a predicate current_source/1,

    that lists the consulted sources. The same built-in also exists in
    Jekejeke Prolog. We could store sys_source/2 with additional flags, so
    as to detect cyclic ensure_loaded etc..

    current_source/1 would be only a facade.
    Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 21:23:46 UTC+2:
    Its the double DCG problem and similar problems,
    even the earth benders are lost on this problem
    and have suggested Tarau engines.

    LoL

    But what about the air nation? Can it solve the
    problem. I understand that it might be difficult,
    because of the various stages and artefact

    transformations involved in GNU Prolog. But maybe
    a little separate compilation and later linking
    would do the job. So that an ensure_loaded/1 directive

    would spawn a separate compilation, put the artefact
    on a list, and at the end of a consult batch all
    separate artefacts are linked together or

    otherwise integrated.

    Mostowski Collapse schrieb:
    Well the consult/1 I provide is weaker than
    the ensure_loaded/1. But ensure_loaded/1 is planned.

    Prolog explicit version of ensure_loaded/1 #80 https://github.com/jburse/dogelog-moon/issues/80

    Mostowski Collapse schrieb:
    Isn't ensure_loaded/1 a directive defined in the
    ISO core standard [ISO 7.4.2.8]. Why do Logtalk
    and GNU-Prolog not have it.

    I managed to provide a consult/1 for Dogelog runtime.
    Its reentrant. Means a file in progress of consult/1
    can call consult/1 on another file, and it

    gets correctly consulted as well. And Dogelog runtime
    is a transpiler similar like Logtalk or GNU-Prolog.
    Means the sub call of consult/1 will also pass

    the the compiler pipeline consisting of transform
    and encode. Why cant Logtalk or GNU-Prolog do that
    as well? Whats the Prolololoblem?


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Fri Jul 23 12:53:47 2021
    In Jekejeke Prolog I get as expected:

    ?- absolute_file_name('/Users/janburse/Desktop/dict.txt', X).
    X = 'file:/Users/janburse/Desktop/Dict.TXT'

    Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 21:49:52 UTC+2:
    canonical file names can be a challenge. For example SWI-Prolog
    claims it does so. It says:

    absolute_file_name(+File, -Absolute)
    Expand a local filename into an absolute path.
    The absolute path is canonicalised: references to . and .. are deleted. https://www.swi-prolog.org/pldoc/man?section=files

    But it doesn't work. I have file named 'Dict.TXT' on a Mac:

    ?- absolute_file_name('/Users/janburse/Desktop/dict.txt', X).
    X = '/Users/janburse/Desktop/dict.txt'.

    So what am I supposed to do, if on one side Dict.TXT is consulted
    and on another side dict.txt is consulted? Am I supposed to call same_file/2?

    ?- same_file('/Users/janburse/Desktop/dict.txt', '/Users/janburse/Desktop/Dict.TXT').
    true.
    ?- same_file('/Users/janburse/Desktop/dict.TXT', '/Users/janburse/Desktop/Dict.txt').
    true.

    But this doesn't lead to a canonical name. Its only an equivalence
    relation on a relative large equivalence class, on the Mac file
    search is case insensitive.

    To implement ensure_loaded/1 with same_file/2 I would
    need to call it O(N^2) and cross compare all already compiled
    file names. With a canonical name I could do some first

    argument indexing which seems more natural to me.
    Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 21:36:00 UTC+2:
    Whats a little challenge, is to get the canonical file names. In
    Jekejeke Prolog we call the file system to give us a canonical
    file name. Things then get even more funny for URLs, we

    even normalize them including %xx encoding manipulations and
    punny manipulations. Not sure how this all works out in JavaScript.
    The proof of concept will be if we have a predicate current_source/1,

    that lists the consulted sources. The same built-in also exists in Jekejeke Prolog. We could store sys_source/2 with additional flags, so
    as to detect cyclic ensure_loaded etc..

    current_source/1 would be only a facade.
    Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 21:23:46 UTC+2:
    Its the double DCG problem and similar problems,
    even the earth benders are lost on this problem
    and have suggested Tarau engines.

    LoL

    But what about the air nation? Can it solve the
    problem. I understand that it might be difficult,
    because of the various stages and artefact

    transformations involved in GNU Prolog. But maybe
    a little separate compilation and later linking
    would do the job. So that an ensure_loaded/1 directive

    would spawn a separate compilation, put the artefact
    on a list, and at the end of a consult batch all
    separate artefacts are linked together or

    otherwise integrated.

    Mostowski Collapse schrieb:
    Well the consult/1 I provide is weaker than
    the ensure_loaded/1. But ensure_loaded/1 is planned.

    Prolog explicit version of ensure_loaded/1 #80 https://github.com/jburse/dogelog-moon/issues/80

    Mostowski Collapse schrieb:
    Isn't ensure_loaded/1 a directive defined in the
    ISO core standard [ISO 7.4.2.8]. Why do Logtalk
    and GNU-Prolog not have it.

    I managed to provide a consult/1 for Dogelog runtime.
    Its reentrant. Means a file in progress of consult/1
    can call consult/1 on another file, and it

    gets correctly consulted as well. And Dogelog runtime
    is a transpiler similar like Logtalk or GNU-Prolog.
    Means the sub call of consult/1 will also pass

    the the compiler pipeline consisting of transform
    and encode. Why cant Logtalk or GNU-Prolog do that
    as well? Whats the Prolololoblem?


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Sat Jul 24 02:13:59 2021
    Seems that Dogelog runtime and Jekejeke Prolog will
    maybe have slightly different implementation of consult/1 and
    ensure_loaded/1. Was also presenting a fundamental

    difference between consult/1 and ensure_loaded/1 wrongly.
    In a more refined Prolog text loader both consult/1 and
    ensure_loaded/1 would avoid duplicate loading.

    But ensure_loaded/1 would only load/re-load changed
    files, whereas consult/1 would load all Prolog texts.
    So there is the following browser analogy:

    - Browser Enter of Page: This corresponds to
    ensure_loaded/1, will reused cached resources.

    - Browser Forced Reload: This corresponds to
    consult/1, will invalidate caches before loading.

    This is how I have implemented consult/1 and ensure_loaded/1
    in Jekejeke Prolog. consult/1 is only needed in rare cases,
    like when syntax operators or term expansions change,

    and a more thorough reload is neded.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Sat Jul 24 02:17:21 2021
    But now in Dogelog runtime everything is different, since
    it has explicit cache clearning via the clear() JavaScript
    call, and also the cache is staged, the different stage

    scope can be changed via set_stage() JavaScript call.
    The Jekejeke Prolog does some cleanup after a consult,
    like Prolog texts that are not anymore used,

    in as far [F1,..,Fn] could be a little bit improved, I am
    more assuming a single top entry for consult/1 respectively
    ensure_loaded/1. Dogelog runtime works the other

    way around now, it does cleanup before consult.

    Mostowski Collapse schrieb am Samstag, 24. Juli 2021 um 11:14:01 UTC+2:
    Seems that Dogelog runtime and Jekejeke Prolog will
    maybe have slightly different implementation of consult/1 and ensure_loaded/1. Was also presenting a fundamental

    difference between consult/1 and ensure_loaded/1 wrongly.
    In a more refined Prolog text loader both consult/1 and
    ensure_loaded/1 would avoid duplicate loading.

    But ensure_loaded/1 would only load/re-load changed
    files, whereas consult/1 would load all Prolog texts.
    So there is the following browser analogy:

    - Browser Enter of Page: This corresponds to
    ensure_loaded/1, will reused cached resources.

    - Browser Forced Reload: This corresponds to
    consult/1, will invalidate caches before loading.

    This is how I have implemented consult/1 and ensure_loaded/1
    in Jekejeke Prolog. consult/1 is only needed in rare cases,
    like when syntax operators or term expansions change,

    and a more thorough reload is neded.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Sat Jul 24 02:20:51 2021
    What is needed, maybe only under the hood. Some built-in that
    gives access to a file system function realpath:

    realpath(P, Q):
    % realpath(+Atom, -Atom)
    The built-in succeeds in Q with the canonical path of P, by resolving . , ..
    and symbolic links. On case insensitive file systems Q is not case converted.

    The good news! JavaScript has realpath, I found asynchronous
    and synchronous, have to practically check what it does:

    fs.realpath(path[, options], callback)
    fs.realpathSync(path[, options])
    https://nodejs.org/api/fs.html

    Java is even more refined, it has getAbsolutePath() and
    getCanonicalPath(). getAbsolutePath() corresponds to the
    current SWI-Prolog absolute_file_name/2. getCanonicalPath()

    adds a realpath operating system call.

    Mostowski Collapse schrieb am Samstag, 24. Juli 2021 um 11:19:06 UTC+2:
    But the clouds about canonical file names is slowly lifting.
    SWI-Prolog is very close, it doesn’t do case conversion. For
    example when I query this here I get, I don’t see any case conversion,

    the flag has also the correct value on a Mac:

    ?- current_prolog_flag(file_name_case_handling, X).
    X = case_preserving.

    ?- absolute_file_name('/<user>/Desktop/Dict.txt', X).
    X = '/<user>/Desktop/Dict.txt'.

    But whats still missing is the operating system call to retrieve the realpath, which is Dict.TXT in my example. case_preserving would
    apply to the realpath.
    Mostowski Collapse schrieb am Samstag, 24. Juli 2021 um 11:17:22 UTC+2:
    But now in Dogelog runtime everything is different, since
    it has explicit cache clearning via the clear() JavaScript
    call, and also the cache is staged, the different stage

    scope can be changed via set_stage() JavaScript call.
    The Jekejeke Prolog does some cleanup after a consult,
    like Prolog texts that are not anymore used,

    in as far [F1,..,Fn] could be a little bit improved, I am
    more assuming a single top entry for consult/1 respectively ensure_loaded/1. Dogelog runtime works the other

    way around now, it does cleanup before consult.
    Mostowski Collapse schrieb am Samstag, 24. Juli 2021 um 11:14:01 UTC+2:
    Seems that Dogelog runtime and Jekejeke Prolog will
    maybe have slightly different implementation of consult/1 and ensure_loaded/1. Was also presenting a fundamental

    difference between consult/1 and ensure_loaded/1 wrongly.
    In a more refined Prolog text loader both consult/1 and
    ensure_loaded/1 would avoid duplicate loading.

    But ensure_loaded/1 would only load/re-load changed
    files, whereas consult/1 would load all Prolog texts.
    So there is the following browser analogy:

    - Browser Enter of Page: This corresponds to
    ensure_loaded/1, will reused cached resources.

    - Browser Forced Reload: This corresponds to
    consult/1, will invalidate caches before loading.

    This is how I have implemented consult/1 and ensure_loaded/1
    in Jekejeke Prolog. consult/1 is only needed in rare cases,
    like when syntax operators or term expansions change,

    and a more thorough reload is neded.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Sat Jul 24 02:19:05 2021
    But the clouds about canonical file names is slowly lifting.
    SWI-Prolog is very close, it doesn’t do case conversion. For
    example when I query this here I get, I don’t see any case conversion,

    the flag has also the correct value on a Mac:

    ?- current_prolog_flag(file_name_case_handling, X).
    X = case_preserving.

    ?- absolute_file_name('/<user>/Desktop/Dict.txt', X).
    X = '/<user>/Desktop/Dict.txt'.

    But whats still missing is the operating system call to retrieve the
    realpath, which is Dict.TXT in my example. case_preserving would
    apply to the realpath.

    Mostowski Collapse schrieb am Samstag, 24. Juli 2021 um 11:17:22 UTC+2:
    But now in Dogelog runtime everything is different, since
    it has explicit cache clearning via the clear() JavaScript
    call, and also the cache is staged, the different stage

    scope can be changed via set_stage() JavaScript call.
    The Jekejeke Prolog does some cleanup after a consult,
    like Prolog texts that are not anymore used,

    in as far [F1,..,Fn] could be a little bit improved, I am
    more assuming a single top entry for consult/1 respectively
    ensure_loaded/1. Dogelog runtime works the other

    way around now, it does cleanup before consult.
    Mostowski Collapse schrieb am Samstag, 24. Juli 2021 um 11:14:01 UTC+2:
    Seems that Dogelog runtime and Jekejeke Prolog will
    maybe have slightly different implementation of consult/1 and ensure_loaded/1. Was also presenting a fundamental

    difference between consult/1 and ensure_loaded/1 wrongly.
    In a more refined Prolog text loader both consult/1 and
    ensure_loaded/1 would avoid duplicate loading.

    But ensure_loaded/1 would only load/re-load changed
    files, whereas consult/1 would load all Prolog texts.
    So there is the following browser analogy:

    - Browser Enter of Page: This corresponds to
    ensure_loaded/1, will reused cached resources.

    - Browser Forced Reload: This corresponds to
    consult/1, will invalidate caches before loading.

    This is how I have implemented consult/1 and ensure_loaded/1
    in Jekejeke Prolog. consult/1 is only needed in rare cases,
    like when syntax operators or term expansions change,

    and a more thorough reload is neded.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Jul 27 06:59:56 2021
    Because assertz/1 is called before include/1, the user directive
    would also work for cyclic imports. Interestingly JavaScript
    can also do cyclic imports. I have used it by accident recently,

    and it worked. The ECMA standard says:

    A Cyclic Module Record is used to represent information about
    a module that can participate in dependency cycles with other
    modules that are subclasses of the Cyclic Module Record type.
    Module Records that are not subclasses of the Cyclic Module
    Record type must not participate in dependency cycles with
    Source Text Module Records.

    [[DFSIndex]] Integer | undefined Auxiliary field used during Link
    and Evaluate only. If [[Status]] is linking or evaluating, this non-negative number records the point at which the module was first visited during
    the ongoing depth-first traversal of the dependency graph.

    [[DFSAncestorIndex]] Integer | undefined Auxiliary field used during Link and Evaluate only. If [[Status]] is linking or evaluating, this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record

    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:46:05 UTC+2:
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph.
    The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of
    include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Jul 27 07:04:32 2021
    But this could also work as main entry, multiple
    Prolog texts. Define something like:

    [H|T] :-
    retractall(visited(_)),
    maplist(include, [H|T]).

    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:02:35 UTC+2:
    Whats a little tricky is allow debugging, i.e reconsult.
    One possible solution is to define:
    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    consult(file) :-
    retractall(visited(_)),
    include(file).

    So one would make a main entry file for the application
    he is working on. And call consult(main) when one wants

    to reconsult everything. A more smarter solution stores
    last modified in visited/2, etc.. etc..
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:59:57 UTC+2:
    Because assertz/1 is called before include/1, the user directive
    would also work for cyclic imports. Interestingly JavaScript
    can also do cyclic imports. I have used it by accident recently,

    and it worked. The ECMA standard says:

    A Cyclic Module Record is used to represent information about
    a module that can participate in dependency cycles with other
    modules that are subclasses of the Cyclic Module Record type.
    Module Records that are not subclasses of the Cyclic Module
    Record type must not participate in dependency cycles with
    Source Text Module Records.

    [[DFSIndex]] Integer | undefined Auxiliary field used during Link
    and Evaluate only. If [[Status]] is linking or evaluating, this non-negative
    number records the point at which the module was first visited during
    the ongoing depth-first traversal of the dependency graph.

    [[DFSAncestorIndex]] Integer | undefined Auxiliary field used during
    Link and Evaluate only. If [[Status]] is linking or evaluating, this is either
    the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:46:05 UTC+2:
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph.
    The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of
    include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to All on Tue Jul 27 06:46:04 2021
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph.
    The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of
    include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Jul 27 07:02:34 2021
    Whats a little tricky is allow debugging, i.e reconsult.
    One possible solution is to define:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    consult(file) :-
    retractall(visited(_)),
    include(file).

    So one would make a main entry file for the application
    he is working on. And call consult(main) when one wants

    to reconsult everything. A more smarter solution stores
    last modified in visited/2, etc.. etc..

    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:59:57 UTC+2:
    Because assertz/1 is called before include/1, the user directive
    would also work for cyclic imports. Interestingly JavaScript
    can also do cyclic imports. I have used it by accident recently,

    and it worked. The ECMA standard says:

    A Cyclic Module Record is used to represent information about
    a module that can participate in dependency cycles with other
    modules that are subclasses of the Cyclic Module Record type.
    Module Records that are not subclasses of the Cyclic Module
    Record type must not participate in dependency cycles with
    Source Text Module Records.

    [[DFSIndex]] Integer | undefined Auxiliary field used during Link
    and Evaluate only. If [[Status]] is linking or evaluating, this non-negative number records the point at which the module was first visited during
    the ongoing depth-first traversal of the dependency graph.

    [[DFSAncestorIndex]] Integer | undefined Auxiliary field used during
    Link and Evaluate only. If [[Status]] is linking or evaluating, this is either
    the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:46:05 UTC+2:
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph.
    The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of
    include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Jul 27 07:09:07 2021
    Corr.: But this here:

    retractall(visited(_)).

    Must be replaced by something that also flushes
    (abolish) the currently consulted predicates. Or
    some policy is in place, when a predicate is seen

    a second time during some include, it is first flushed.
    But this doesn't work so well for multifile predicates,
    The flushing (abolish) can be also integrated

    into ensure_loaded/1, so that in the end, retractall(visited(_))
    is nevertheless enought. Not only GNU Prolog
    could profit from a smarter Prolog loader, possibly

    also Logtalk, which seems to be a little ossified,
    concerning the proposed way how to work with it.
    Although ensure_loaded/1 is part of the ISO core standard.

    Have Fun!

    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:04:33 UTC+2:
    But this could also work as main entry, multiple
    Prolog texts. Define something like:

    [H|T] :-
    retractall(visited(_)),
    maplist(include, [H|T]).
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:02:35 UTC+2:
    Whats a little tricky is allow debugging, i.e reconsult.
    One possible solution is to define:
    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    consult(file) :-
    retractall(visited(_)),
    include(file).

    So one would make a main entry file for the application
    he is working on. And call consult(main) when one wants

    to reconsult everything. A more smarter solution stores
    last modified in visited/2, etc.. etc..
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:59:57 UTC+2:
    Because assertz/1 is called before include/1, the user directive
    would also work for cyclic imports. Interestingly JavaScript
    can also do cyclic imports. I have used it by accident recently,

    and it worked. The ECMA standard says:

    A Cyclic Module Record is used to represent information about
    a module that can participate in dependency cycles with other
    modules that are subclasses of the Cyclic Module Record type.
    Module Records that are not subclasses of the Cyclic Module
    Record type must not participate in dependency cycles with
    Source Text Module Records.

    [[DFSIndex]] Integer | undefined Auxiliary field used during Link
    and Evaluate only. If [[Status]] is linking or evaluating, this non-negative
    number records the point at which the module was first visited during
    the ongoing depth-first traversal of the dependency graph.

    [[DFSAncestorIndex]] Integer | undefined Auxiliary field used during
    Link and Evaluate only. If [[Status]] is linking or evaluating, this is either
    the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component. https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:46:05 UTC+2:
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph.
    The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of
    include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Tue Jul 27 07:50:45 2021
    Quizz: What happens first:

    a) Hell freezes over

    b) Logtalk has ensure_loaded/1 ?

    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:17:11 UTC+2:
    Sometimes I have the feeling the JavaScript programming
    language developers are all former Datalog gurus,
    when they write:

    strongly connected component <<< https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record

    Ok thats a little overrated, strongly connected component
    were discovered idependently by Robert Tarjan 1972 ?
    Why do they need SCC? Dunno. Computing imported

    tables more efficiently in the cyclic case? ensure_loaded/1
    wouldn't go that far. Requirement is simpler. But Logtalk
    could be interested in SCC algorithms?

    Modern OO languages usually allow a lot of cyclic stuff,
    especially on class import/export level and type import/
    export level, whereby often class=type and so on.

    cycles or only explicitly forbidden for example along
    a single inheritance change and such stuff.
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:09:09 UTC+2:
    Corr.: But this here:

    retractall(visited(_)).

    Must be replaced by something that also flushes
    (abolish) the currently consulted predicates. Or
    some policy is in place, when a predicate is seen

    a second time during some include, it is first flushed.
    But this doesn't work so well for multifile predicates,
    The flushing (abolish) can be also integrated

    into ensure_loaded/1, so that in the end, retractall(visited(_))
    is nevertheless enought. Not only GNU Prolog
    could profit from a smarter Prolog loader, possibly

    also Logtalk, which seems to be a little ossified,
    concerning the proposed way how to work with it.
    Although ensure_loaded/1 is part of the ISO core standard.

    Have Fun!
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:04:33 UTC+2:
    But this could also work as main entry, multiple
    Prolog texts. Define something like:

    [H|T] :-
    retractall(visited(_)),
    maplist(include, [H|T]).
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:02:35 UTC+2:
    Whats a little tricky is allow debugging, i.e reconsult.
    One possible solution is to define:
    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    consult(file) :-
    retractall(visited(_)),
    include(file).

    So one would make a main entry file for the application
    he is working on. And call consult(main) when one wants

    to reconsult everything. A more smarter solution stores
    last modified in visited/2, etc.. etc..
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:59:57 UTC+2:
    Because assertz/1 is called before include/1, the user directive would also work for cyclic imports. Interestingly JavaScript
    can also do cyclic imports. I have used it by accident recently,

    and it worked. The ECMA standard says:

    A Cyclic Module Record is used to represent information about
    a module that can participate in dependency cycles with other
    modules that are subclasses of the Cyclic Module Record type.
    Module Records that are not subclasses of the Cyclic Module
    Record type must not participate in dependency cycles with
    Source Text Module Records.

    [[DFSIndex]] Integer | undefined Auxiliary field used during Link
    and Evaluate only. If [[Status]] is linking or evaluating, this non-negative
    number records the point at which the module was first visited during the ongoing depth-first traversal of the dependency graph.

    [[DFSAncestorIndex]] Integer | undefined Auxiliary field used during Link and Evaluate only. If [[Status]] is linking or evaluating, this is either
    the module's own [[DFSIndex]] or that of an "earlier" module in the same
    strongly connected component. https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:46:05 UTC+2:
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph. The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to when they on Tue Jul 27 07:17:10 2021
    Sometimes I have the feeling the JavaScript programming
    language developers are all former Datalog gurus,
    when they write:

    strongly connected component <<< https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record

    Ok thats a little overrated, strongly connected component
    were discovered idependently by Robert Tarjan 1972 ?
    Why do they need SCC? Dunno. Computing imported

    tables more efficiently in the cyclic case? ensure_loaded/1
    wouldn't go that far. Requirement is simpler. But Logtalk
    could be interested in SCC algorithms?

    Modern OO languages usually allow a lot of cyclic stuff,
    especially on class import/export level and type import/
    export level, whereby often class=type and so on.

    cycles or only explicitly forbidden for example along
    a single inheritance change and such stuff.

    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:09:09 UTC+2:
    Corr.: But this here:

    retractall(visited(_)).

    Must be replaced by something that also flushes
    (abolish) the currently consulted predicates. Or
    some policy is in place, when a predicate is seen

    a second time during some include, it is first flushed.
    But this doesn't work so well for multifile predicates,
    The flushing (abolish) can be also integrated

    into ensure_loaded/1, so that in the end, retractall(visited(_))
    is nevertheless enought. Not only GNU Prolog
    could profit from a smarter Prolog loader, possibly

    also Logtalk, which seems to be a little ossified,
    concerning the proposed way how to work with it.
    Although ensure_loaded/1 is part of the ISO core standard.

    Have Fun!
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:04:33 UTC+2:
    But this could also work as main entry, multiple
    Prolog texts. Define something like:

    [H|T] :-
    retractall(visited(_)),
    maplist(include, [H|T]).
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 16:02:35 UTC+2:
    Whats a little tricky is allow debugging, i.e reconsult.
    One possible solution is to define:
    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    consult(file) :-
    retractall(visited(_)),
    include(file).

    So one would make a main entry file for the application
    he is working on. And call consult(main) when one wants

    to reconsult everything. A more smarter solution stores
    last modified in visited/2, etc.. etc..
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:59:57 UTC+2:
    Because assertz/1 is called before include/1, the user directive
    would also work for cyclic imports. Interestingly JavaScript
    can also do cyclic imports. I have used it by accident recently,

    and it worked. The ECMA standard says:

    A Cyclic Module Record is used to represent information about
    a module that can participate in dependency cycles with other
    modules that are subclasses of the Cyclic Module Record type.
    Module Records that are not subclasses of the Cyclic Module
    Record type must not participate in dependency cycles with
    Source Text Module Records.

    [[DFSIndex]] Integer | undefined Auxiliary field used during Link
    and Evaluate only. If [[Status]] is linking or evaluating, this non-negative
    number records the point at which the module was first visited during the ongoing depth-first traversal of the dependency graph.

    [[DFSAncestorIndex]] Integer | undefined Auxiliary field used during Link and Evaluate only. If [[Status]] is linking or evaluating, this is either
    the module's own [[DFSIndex]] or that of an "earlier" module in the same
    strongly connected component. https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#cyclic-module-record
    Mostowski Collapse schrieb am Dienstag, 27. Juli 2021 um 15:46:05 UTC+2:
    Currently the work around is to use include/1 (in GNU Prolog).
    But include/1 is not smart, it cannot deal with an import graph.
    The main benefit of ensure_loaded/1 would be to avoid

    duplicate include/1, which is not part of the requirement of include/1. So one workaround would be if one could define
    user directives, like:

    :- dynamic(visited/1).

    ensure_loaded(file) :-
    visited(file), !.
    ensure_loaded(file) ;-
    assertz(visited(file)),
    include(file).

    Such import graph traversal is very common in JavaScript.
    Its done by require() and now by import().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)