Representation_error, domain_error, type_error

When I called PL_cvt_i_int() with a value 4294967296, I got back the error representation_error(uint). Shouldn’t this be domain_error(unit,4294967296)?

The definition of representation_error/1 is:

A representation error indicates a limitation of the implementation. SWI-Prolog has no such limits that are not covered by other errors, but an example of a representation error in another Prolog implementation could be an attempt to create a term with an arity higher than supported by the system.

This seems to say that representation_error/1 should never happen with SWI-Prolog but might occur in other Prologs (or did I misunderstand?)

I would consider this to be a domain_error/2, because it

has a value that is outside the supported values

… which is supported by the description of type_error/2:

Suppose an argument must be a non-negative integer. If the actual argument is not an integer, this is a type_error. If it is a negative integer, it is a domain_error.

Also, domain_error/2 is more useful than representation_error/1 because it has the offending value in the error term.

(*) I think that the call was to PL_cvt_i_int() – I traced the code by hand and could have easily made a mistake – but it might have been something else. At any rate, the calling code is trying to connvert a term to an unsigned (32-bit) integer and 4294967296 doesn’t fit in 32-bits unsignned.

These things are always hard :frowning: ISO dictates a representation error for integers that are outside min_integer..max_integer on systems with bounded integers (7.12.2 Error classification). While SWI-Prolog itself has unbounded integers, the C types can be seen as bounded integers. At least, that was my reasoning while deciding on the error. It is a pity that representation error only passes an indication on what type of limit was reached and not the thing that hit this limit. I think that is a separate discussion. There are a number of ISO exceptions that lack valuable context :frowning:

My $0.01 … I’m happy to hear the opinion from ISO exception experts.

Putting on my language lawyer hat (*), and admitting that I haven’t read the ISO standard (does it still cost $$$s?), my interpretation is thatrepresentation_error is for when some input can’t be parsed or can’t be represented; but PL_cvt_i_int() et al are for internal values, and the error is that the Prolog “internal object” can’t be converted to fit within 32 bits or whatever … so it should be a domain_error rather than representation_error.

There’s an edge case where it makes sense that the representation_error term doesn’t contain the unrepresentable item – suppose there’s a limit of 255 bytes to atom names, then it would not be possible to create an error term with a 256-byte name. This situation would not occur with a 64-bit integer than doesn’t fit in 32 bits … an appropriate domain_error term could still be created.

(*) I didn’t participate in the ISO Prolog standardisation (and I know a number of people, such as Richard O’Keefe stopped participated); but I spent quite a bit of time working with IBM’s ANSI-C representative, when the first C standard was created and it was hard work. (We had to do “fun” stuff like allowing either ASCII or EBCDIC strings, dealing with record I/O, naming conventions for files, etc.; I have no desire to deal with such minutiae again.)

I don’t know. I’ve understood representation error to mean that something is “logically” correct and the system should thus handle but it can’t due to some limitation. Too long atoms, not being able to represent some valid character code, not to represent a large integer when integers are bounded, etc. I don’t know whether it should matter whether that is internal or external. A foreign module using uint that is sent a too large integer is IMO the same as a Prolog system with bounded integers that cannot handle this. If the application wants a domain error because it is logically incorrect to pass such a big value it can, and I think it should check the value is an integer and outside the domain. Typically though, C/C++ code uses bounded integers because it is fast, compact, easy and typically big enough, not because there is some domain that logically restricts the value.

I’ll throw in in hour PIP meetings to see whether there are other opinions and/or practice.