Hello! I’m looking into adding SWI-Prolog compatibility to a relatively large SICStus Prolog-based application.
Many parts of our codebase expect double-quoted literals to be codes lists, and not just in the context of DCGs. SWI-Prolog by default uses double quotes for true strings rather than codes lists, so during my initial testing, I ran swipl with the --traditional option, to avoid having to deal with this difference for now. However, when I use --traditional, I sometimes get errors from standard library code that relies on the new SWI-Prolog features (e. g. library(shell) uses the . operator with dicts).
Based on somecomments on the issue tracker, it seems that not all of SWI-Prolog’s standard modules maintain compatibility with --traditional anymore and that such errors are to be expected. Does this mean that --traditional is being deprecated? Or are only some of the standard modules dropping support for --traditional? I can’t find any information about this in the documentation - various places explain what behavior is changed by --traditional, but it’s not mentioned anywhere that this can cause problems with standard modules.
If --traditional shouldn’t be used anymore, what is the recommended approach for writing codes list literals so that they work on both SWI and SICStus, i. e. regardless of whether double quotes produce a true string or a list of codes? The portable way of getting a codes list from a double-quoted literal seems to be phrase("double quoted", Codes), but this is inconvenient, because it requires an intermediate variable for almost every literal. Another option seems to be set_prolog_flag(double_quotes, codes) to force interpreting double quotes as codes lists - is this a good idea, or could this also cause problems with builtins or library code? If it’s safe to set the flag like this, should expects_dialect(sicstus) perhaps do this automatically?
Depends on the interpretation of deprecated I do not expect the option to ever go away. Considering that development of all the tools and libraries do not anticipate on --traditional its use is limited to Prolog applications that do not need anything but the ISO core and some basic libraries like lists. So no, this is probably not what you want.
That works pretty well. The flag is scoped to a file, so typically a file should look like this and you should be fine. I think the double_quotes flag is even ISO, so SICStus should not complain.
The SICStus dialect support is in library/dialect/sicstus. That has for 99% been developed for porting Alpino. If you want to maintain the code as portable code the best option is probably to extend the emulation library.
Possibly. The scoping of this flag makes this rather tricky though. It all depends on the code. For Alpino there were quite a few “hello world” strings that were only used as format specifiers or handed to format ~s, so keeping SWI-Prolog’s string interpretation improved the code (more readable during debugging, faster and less resource usage). If I recall correctly there was only one of the pretty large set of files that required either a significant rewrite or changing this flag.
Please contribute additions to the SICStus emulation layer as pull requests!
Since DCGs and the double_quote flag are something I have a high interest in I checked this.
Yes double_quotes is in the ISO spec.
From 6.3.7 Terms - double quoted list notation it only notes the values chars, codes and atom, while in SWI-Prolog the allowed values are chars, codes,atom and string.
Personally I now use codes and contrary to library(dcg_bacis) I use open list with my DCGs as opposed to closed list since it is easy to convert an open list to a closed list and I can thread accumulators using open list instead of having to use append/3 hacks.
As such I don’t use library(dcg_bacis) any more. This however can lead to another problem if you are like me and like to think in terms of hierarchy of libraries, since Prolog works better not using a full hierarchy module system (for lack of a better description) one has to think in the way of Prolog when making libraries for DCGs and such.
Thank you for the replies! I’ll try using the double_quotes flag then. SICStus already has double_quotes set to codes by default, so setting it again for the benefit of SWI shouldn’t be a problem for SICStus. Good to know that the flag is even part of the ISO standard.
For now I think I’ll set the flag everywhere that use double quotes. We have a few files where double quotes are only used in DCGs or format/2, which could probably safely use strings instead. But we also have many places where double quotes are really used as codes lists, like iterating over codes or using append/3 to decompose or concatenate strings. Unfortunately most list operations fail silently instead of throwing an error when they encounter a non-list, which makes it harder to notice when code accidentally tries to use strings as lists. So to be safe I’ll set the flag everywhere at first and check later where it would be safe to use strings.
Yes, I’ll probably submit some additions to library(dialect/sicstus) soon. During testing I ran into many SICStus predicates that SWI doesn’t emulate yet, but most of them were easy to handle - often SWI already provides the predicates in question, just under a different name or module than SICStus.
A good step: load the code and run ?- list_undefined. to get an idea about what is missing. It isn’t perfect, notably for code lacking meta_predicate/1 declarations or doing other hard to track programming.