Better demo:

But this points out that the input to hex-to-number should be type text, not type number, because you can't type an "x" into a number-type input slot.

Nice work on the elegant recursive algorithm, and thank you for getting the block names right!

If it were me, though, I wouldn't require the "0x" at the beginning of the input to hex-to-number. I'd check for it and remove it in the top-level procedure before calling the subprocedure, whose input would then be just the digits.

I really don't like the block name. A number is a number is a number regardless of whether it is expressed in hexadecimal, binary, or decimal (or whatever). So a better name would be hexadecimal ... to decimal.
to hexadecimal is a fine name.

This is a consequence of the fact that Snap! uses +n to convert n to a number in JavaScript (if possible).

imo all the text/number behavior is difficult to work with precisely

here i will write (join [x]) as "x" and (x)+(0) as +x
"2748.0" is displayed as 2748.0, and adding 0 changes it to +2748, displayed as 2748
"2748.0" is not identical to "2748"
<is ["2748.0"] a [text]?> says false
<is ["2748.0"] a [number]?> says true
"2748.0" is identical to +2748

the identical block especially bothers me here because from my perspective, the whole point is that you can expect them to be EXACTLY the same. but in this case they have different behaviors with the same operations, (join [2748.0] [whatever]) isn't the same as (join ((2748) + (0)) [whatever]), and it gets much worse when doing things like splitting numbers by digits

i can imagine someone making a project that asks for a number, does sensible checks on it, and then has issues displaying it later because it was formatted differently from how snap displays other numbers. it could even break entirely if it did things like replacing digits with text operations, expecting an integer but running into issues with a .0

this type stuff should probably be moved to another thread if it continues

Testing numeric equality is what the = block is for. The IS IDENTICAL TO block is our way of letting users see under the hood a little to see whether the internal representation of some value is the same as the internal representation of some other value, even if the two values are displayed the same.

No no no no no no no!

Yes, there is an underlying number for any representation. But the representation is a different thing from the number. When people get confused about this, it makes me regret the automatic conversion between numbers and numerals done in Snap! (as in Logo). Fortran programmers and C programmers never get confused about this, because if they have a string of digits and they want to do arithmetic on the corresponding number, they have to do an explicit conversion from numeral to number.

If you look at the OP's code, you will see that it operates on (hexadecimal) numerals by doing text operations, JOIN and LAST LETTER OF and so on, whereas it operates on numbers by doing arithmetic operations, + and FLOOR and MOD and so on. There are places where it multiplies or divides a number by 16, because that's what you have to do to make room for another (hex) digit in the numeral, but there aren't places where it multiplies or divides by 10, because there are no decimal numerals involved in the algorithm.

that's exactly what i'm expecting it to do, and what it's not doing.

(join [2.0]) is NOT the same as ((2.0)+(0)), but the is identical block says they are.
they clearly are different because the first is 3 characters long, and the second is one. (2.0, and 2)

Yes. I should have said a better name is

hexadecimal string ... to number

I think my problem is that when I hear "hexadecimal" I think "hexadecimal number" so converting it to a number isn't what is going on. But, yes, calling the output "decimal" is confusing since it is a "number that displays as a decimal".

Right, but there's no such thing as a "hexadecimal number." As you said, the number is the number, however it's represented. You'll be a happier person if you teach yourself to think "hexadecimal numeral." :~)

P.S. And "number that displays as a decimal" is misleading, because that's not a property of a number. Snap! displays numbers as decimal numerals, period.