Closed kenbowen closed 4 years ago
?- put_number(user,integer,3).
Should not throw error, and should print: 3
put_number/3
's 2nd arg is restricted to byte/short/long/float/double, so anything outside that is a domain error. Here's a proposed test case:
catch(put_number(user, integer, 3), error(domain_error(output_type, integer), _), true),
?- put_number(user,float,3.4).
??Y@
Should print: 3.4
I think all the put_*
preds perform low level output, so put_number/3
outputs raw binary. I.e. 3.4 is output as a 4 byte IEEE encoded float. The ??Y@
is likely correct. Here's a test case for little-endian systems:
( open(string(S), write, O), put_number(O, float, 3.4), close(O), write(S), S == [0'\x9a, 0'\x99, 0'\x59, 0'\x40] ),
On Oct 16, 2019, at 3:40 PM, Chuck Houpt notifications@github.com wrote:
?- put_number(user,integer,3). Should not throw error, and should print: 3
put_number/3's 2nd arg is restricted to byte/short/long/float/double, so anything outside that is a domain error.
A case of “seeing" something (“integer") that wasn’t there in the list in the comment before the defn of put_number/3. The first clause simply calls sio_put_number with no change in args, so most certainly — in your next message — you’re right about “...so put_number/3 outputs raw binary”.
Interestingly (grepping), put_number doesn’t occur in builtins or library.
I’ll drop the put_number items from the Issue.
put_atom uses ‘integer' wherever it ought to use ‘atom’:
?-put_atom(user, "abc"). Error: Argument of type integer expected instead of "abc".
?- put_atom(user, f(X)). Error: Argument of type integer expected instead of f(_A).
This appears due to put_atom’s last clause calling put_failure/4, which has this clause:
put_failure(2,Stream,Arg,Call) :- %% SIOEINARG !, curmod(Mod), functor(Call,,LastArg), arg(LastArg,Call,Culprit), type_error(integer, Culprit, [Mod:Call]).
The same problem occurs for put_code and put_char. Changing “integer” to “atom” would make put_atom correct, but still leave put_code, put_char, and put_number incorrect. Now put_failure/4 only occurs in sio.pro in builtins and doesn’t occur in library. So one possibility is to add an argument to put_failure/4, and pass the appropriate constant (atom, char, code, number) in that argument.
Let me know what you think. ——Ken
Here's a proposed test case:
catch(put_number(user, integer, 3), error(domain_error(outputtype, integer), ), true),
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.
Possibly you could distinguish code/char from atom by matching the Call argument. I.e. something like:
put_failure(2,Stream,Arg,put_atom(S, A)) :-
...
type_error(atom, ....).
For completeness, we should note that put_string/2
also needs exception fixes because it currently just fails instead of correctly throwing instantiation or type errors. For example:
% Should throw type error:
?- put_string(user, foo).
no.
Errors occurring in put_atom/2, put_number/3 error mechanisms:
?- put_atom(user, 3). Error: Argument of type integer expected instead of 3.
?- put_atom(user, 3.4). Error: Argument of type integer expected instead of 3.4.
?- put_number(user,integer,3). Error: Argument of type integer expected instead of 3.
?- put_number(user,float,3.4). ??Y@ yes.