Written by

Question Jorge Torres · Jun 7, 2017

"Sort After" ObjectScript Bug?

Hello experts,

I’m working on an "Sort After" (]]) bug that I traced back to some weird behavior in ObjectScript.  Perhaps someone can enlighten me…

The problem is as follows:

Let’s say we have:

Set A = “1.0”
Set B = “2.2”

If you execute the command ‘Sort After’ (]]), you get the following:

W A]]B
​1

…Which is wrong, A does NOT sort after B.  The output should be 0.

If you set A and B to numeric values, it correctly outputs false (0):

set A = 1.0
set B = 2.2
​W A]]B

0

I dug for a bit, and came up with this:   If you set  a numeric string to “<number>.0” an write the variable, it will be set as a string:

Set A = “1.0”
Set B = “2.2”
W​
A = “1.0”
B= 2.2

…And that is the problem.  The “Sort After” algorithm works in ascending order, where the null String collates first, followed by canonical numbers in numeric order with negative numbers first, zero, positive numbers, followed lastly by nonnumeric values.  Therefore, any numeric string ending in .0 will always sort after any number.  This appears to be an ObjectScript bug.

  • JT

Comments

Ray Fucillo · Jun 7, 2017

This behavior looks correct to me (but it's tricky).  The reason is that the string "2.2" is a number in canonical form, so it collates with the numeric subscripts. "1.0" is non-cananonical, so it's stored as a string subscript.  Sorts after operation is all about resolving subscript ordering.  You can convince yourself of this behavior by actually setting these as subscripts in a global or local variable and then ZWRITE'ing it.

The same reasoning is why "2.2" = 2.2 evaluates true but "1.0" = 1.0 is false.

Note, of course, that numeric conversion will happen as part of any arithmatic operation so "1.0" still functions as 1 in such operations.

0
Alexander Koblov · Jun 7, 2017

']]' means 'Sorts After'. Indeed, as we can see A sorts after B.

USER>kill
 
USER>set A="1.0"
 
USER>set B="2.2"
 
USER>write A]]B
1
USER>set c(A) = 1, c(B) = 1
 
USER>zwrite c
c(2.2)=1
c("1.0")=1
0
Jorge Torres  Jun 8, 2017 to Alexander Koblov

Thanks for the input.  However, see the definition of how "Sorts After" works:

"Binary Sorts after tests whether the left operand sorts after the right operand in numeric subscript collation sequence. In numeric collation sequence, the null string collates first, followed by canonical numbers in numeric order with negative numbers first, zero next, and positive numbers, followed lastly by nonnumeric values."

Therefore in your case, 'A', which is 1.0, does NOT sort after 'B', which is 2.2.  

1.0 sorts BEFORE 2.2.

"".......-2.......-1.......0.......1.0.......2.2.......2.......1.......A.......Z.......

0
Ray Fucillo  Jun 8, 2017 to Jorge Torres

Again, "1.0" is not a canonical number; "2.2" is.  Both are valid numbers, but only one is in canonical form.  So exactly what you quoted here is the reason for this behavior.

Since both are valid numbers, you don't have to use + for any function that evaluates them as numbers or as boolean.  You do have to use + any time you desire conversion to canonical form (like equality, array sorting, etc).

0
Jorge Torres  Jun 8, 2017 to Sean Connelly

Yes, I had thought about this, thanks!  It looks like this is how I'm going to implement my solution.   However, I shouldn't have to "plus" the variables.  I still think there is a deeper problem with ObjectScript.

0
Otto Medin · Jun 8, 2017

Depending on the exact behavior you're after, the "binary follows" operator (]) may do the trick. For your two values, it yields the desired result, regardless of how you set them:

USER>set a = "1.0", b = "2.2" write a]b
0
USER>set a = "1.0", b = 2.2 write a]b
0
USER>set a = 1.0, b = 2.2 write a]b
0
USER>set a = 1.0, b = "2.2" write a]b
0
0
Jorge Torres  Jun 8, 2017 to Otto Medin

That's a good idea, but it won't work in my particular use case.

0