mthom / scryer-prolog

A modern Prolog implementation written mostly in Rust.
BSD 3-Clause "New" or "Revised" License
2.07k stars 125 forks source link

Language Server Protocol support #161

Open XVilka opened 5 years ago

XVilka commented 5 years ago

There is lsp_server that works with SWI Prolog currently, but at some point can be used with Scryer too. So it makes sense to check if it works, maybe fix bugs if presented, to fit them together so to speak. You can read an author's blog post about it.

jamesnvc commented 4 years ago

I've started looking at how to port my above-linked LSP implementation to work with Scryer Prolog. The first thing that I've encountered is trying to figure out how to deal with predicates in different libraries (e.g. in SWI-Prolog, maplist/2 is in library(apply), while the same predicate is in library(lists)).

There are two approaches that occur to me:

  1. Have a directory of "shim" modules & add those to the load path. In SWI, I would do something like user:file_search_path(library, "shim_dir")., so the use_module directives could stay the same, but I'm not sure how to do the equivalent in Scryer.
    1. Do something like :- if(current_prolog_flag(prolog_dialect, scryer)). ... :- endif. or some other preprocessor directive to change the libraries being loaded, but I can't tell if Scryer supports such things.

Open for discussion as to other approaches I might try!

pmoura commented 4 years ago

See https://github.com/mthom/scryer-prolog/pull/84. Your second solution is typical and practical one when writing portable code that deal with non standard but common features that often are built-in is some systems, available on libraries with different names in other systems, or when the same predicate names have semantics differences on different systems.

P.S. Coincidently, Logtalk provides a prolog_dialect flag (defined in the backend adapter files) and also its own (portable) implementation of the also de facto standard conditional compilation directives. But the de facto Prolog standard flag is dialect.

triska commented 4 years ago

A simple and straight-forward solution that only needs standard features is to load the required libraries depending on the Prolog system that is being used.

For example, using:

system_libraries(scryer, [lists,clpz]).
system_libraries(sicstus, [lists,clpfd]).

We can easily load all indicated libraries for Scryer Prolog with:

?- system_libraries(scryer, Ls),
   \+ ( member(L, Ls),
        \+ use_module(library(L))).

A "dialect" flag should the very last resort, since the availability of such a flag inevitably increases the amount of non-portable code. I hope it can be avoided if possible, and if it is absolutely necessary, be introduced with a more fitting name.

pmoura commented 4 years ago

A simple and straight-forward solution that only needs standard features ...

But that's not the case in your suggested solution as use_module/1-2 are standard directives but not standard predicates.

A "dialect" flag should the very last resort, since the availability of such a flag inevitably increases the amount of non-portable code.

The availability of the de facto standard dialect flag doesn't increase by itself anything but allows portable code to deal with the differences between systems on how they provide common but non standardized features. It's also the most basic reflection support for a system to be able to identify itself to any running application. Reflection support, btw, is what allows developer tools to be written.

I hope it can be avoided if possible, and if it is absolutely necessary, be introduced with a more fitting name.

All other systems implement this flag with this name. Get over it.

triska commented 4 years ago

Open for discussion as to other approaches I might try!

Another approach that works immediately is to load the libraries that are required for Scryer in ~/.scryerrc. The system consults this file on startup.