This is not exactly an answer to the "advantages/disadvantages" question, but the way Forth does it is interesting. It supports arbitrary number bases from 2 to 36, but without needing special syntax to do so. Rather, the interpreter parses and converts numbers according to the current value of the variable BASE
, which can be changed dynamically by the user's code. So the numerical value pushed by a token like 17
may be different in different parts of the code, if the value of BASE
has been modified in between.
This can make things very confusing if you forget the current value of BASE
, because then you have trouble resetting it. For example, at first glance you might think 10 BASE !
(the Forth equivalent of BASE = 10
) would bring you back to decimal, but on further thought, you will realize that 10 BASE !
is always a no-op. You also can't easily inquire about the current base, because BASE
is also used by .
to format numbers for output, and so BASE @ .
will likewise always print 10
.
So the standard word DECIMAL
is predefined, to set BASE
back to ten. (And : DECIMAL 10 BASE ! ;
is a valid implementation, assuming BASE
is ten when compiling it, because the 10
is parsed at compile time.) HEX
is also available as a standard extension, and then of course you can define more if you like.
Examples:
DECIMAL
17 ( pushes seventeen )
8 BASE ! ( set octal )
17 ( pushes fifteen )
DECIMAL 36 BASE ! ( set base thirty-six )
HI ( pushes six hundred and thirty )
DECIMAL
: DUODECIMAL 12 BASE ! ; ( define a word for base twelve )
Note that Forth has no syntax to distinguish a number from a word. Rather, each token that's encountered is looked up in the dictionary of currently defined words. If it's not found, then the interpreter attempts to parse the token as a number (using BASE
). So if you had previously done : HI ." Hello world" ;
, then after 36 BASE !
, doing HI
will print Hello world
rather than pushing six hundred and thirty. (I don't know if there is a way in standard Forth to force a token in the input stream to be interpreted as a number, even if it's already defined as a word.)
This also means that you can define words for tokens that otherwise appear to be numbers. You can make use of this by doing things like 0 CONSTANT 0
, which defines 0 as a word that, when executed, pushes the value 0 on the stack. The advantage is that now when the token 0
is encountered, it's handled by looking up 0
in the dictionary and executing it directly, instead of having to call the number parsing routine.
You can also use it for evil, e.g. prank your friends by doing 47 CONSTANT 2
, after which 2
will push the value forty-seven, or : 1 ." It's the loneliest number" ;
.