Function parameters in SmileBASIC are not type-checked - a parameter can have any type, regardless of the variable name, depending only on what value was passed to the function.
If you want to treat different types of parameters differently, it is useful to be able to identify the type of a parameter. Currently there is no known way to identify arrays, but it is possible to differentiate between real number type, integer type, and string type. Consider the following function:
'Returns 0 for real, 1 for integer, 2 for string
DEF TYPEOF(X)
IF X*0 && X*0==X*0 THEN RETURN 2
RETURN X*0-&H80000000<0
END
So, how does this work? First, let's consider differentiating strings from numbers. The critical point of this is that all strings are considered to be True in IF statements or the && and || operators. So if you multiply a string by 0, you get the empty string, which is considered True. On the other hand, if you multiply a number by 0, usually you get 0, which is False.
I say "usually" because there are some special cases as far as real numbers are concerned. Multiplying Infinity or NaN (Not a Number) by 0 will produce NaN, which is considered non-zero, or True. So if we check only X*0, then strings, Infinity, and NaN will be detected. The key to solving this problem is that NaN is considered to be not equal to itself, while on the other hand the empty string is always equal to itself. So X*0==X*0 out of these possible values will be True only if X is a string.
After strings are ruled out, it is fairly simple to differentiate between reals and integers. We will detect an instance of integer overflow - calculating (0 - (-2^31)) should return 2^31, but if we are working with integers, that overflows and becomes negative, so we return True or 1. On the other hand, if X is real it will return 2^31 as expected, so we return False or 0. Note also that if X*0 is our good friend NaN, comparing NaN<0 will also return False. All possible cases are handled.

12 Comment(s)dfrost2Expert ProgrammerProgramming no longer gives me any trouble. Come to me for help, if you like!Programming StrengthMinecraft Is Awesome!I love Minecraft!Express YourselfThere is a way to determine a string array. Check the length of a part of it is greater than 1snail_HelperReceived for being very helpful around SmileBASIC SourceAchievementsFirst DayJoined on the very first day of SmileBASIC SourceWebsiteNight PersonI like the quiet night and sleep late.Express YourselfWhich part? All of them? What happens if it is a string array full of single characters? Also, it's a desireable property of type checking to not fail when you give it something it doesn't recognize (which this will.)
I guess what I'm saying is, the only thing this can tell you is either "certainly a string array" or "maybe something else."dfrost2Expert ProgrammerProgramming no longer gives me any trouble. Come to me for help, if you like!Programming StrengthMinecraft Is Awesome!I love Minecraft!Express Yourselfany part. Loop through it to check the length until the end or until length>0dfrost2Expert ProgrammerProgramming no longer gives me any trouble. Come to me for help, if you like!Programming StrengthMinecraft Is Awesome!I love Minecraft!Express YourselfI am extending this a little further at the moment
It can detect ~70% of things correctly. The input is strictly a string. It can return the following:

function

string

integer

float

NaN

inf

string array

array

The way it determines arrays is simple:
It requires the use of logInArrayDimensions(a custom command)
It checks all of the names logged into an array and checks the existence of the input. It also checks if a "$" is at the end. It will then determine if it is string, and then determines inf or NaN using CLASSIFY if it returns zero, checks integer or real. If integer, do the following:
IF INTEGER== TRUE THEN
IF FLOOR(ABS(X))==ABS(X) THEN RETURN "integer"
RETURN "float"
snail_HelperReceived for being very helpful around SmileBASIC SourceAchievementsFirst DayJoined on the very first day of SmileBASIC SourceWebsiteNight PersonI like the quiet night and sleep late.Express YourselfThe first statement can be changed to
IF (X||0)==3 THEN RETURN 2
This is because string || anything always returns 3 instead of 1 or 0, bizarrely enough. This saves you 3 multiplies and is generally shorter.12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSNight PersonI like the quiet night and sleep late.Express YourselfSecond YearMy account is over 2 years oldWebsiteIF X==0==3 THEN RETURN 21 character shorter.
EDIT:
IF X>0>1 THEN RETURN 2
EDIT 2:
SmileBASIC, 57 52 46 bytesDEF Y(X)IF X>0>2THEN RETURN 2
X=.1RETURN!X
END
But should we rely on an obvious bug?
Of course comparison operators should never return any value other than true/false... if this is fixed, all type checking will stop working. (and according to squarefingers, the int/float check is a bug as well)
A safer alternative might be something like:
DEF TYPEOF(X)
X=X*0
IF X && X==X THEN RETURN 2
X=0.1
RETURN !X
ENDSquareFingersWow, this exposes a very strange aspect of SmileBasic.
Your code relies on &H80000000 being interpreted as the 'integer' type, not the 'floating-point' type. But...
PRINT &H0-&H80000000
gives a positive result. So, &H0 appears to be getting treated as a floating-point, and &H80000000 appears to be getting treated as integer. Just for fun I tried
PRINT &H00000000-&H80000000
and that also showed the zero was treated as floating-point.
calc84maniacOSP Contest 1 WinnerI won the first SmileBASIC Source OSP Contest!Programming ContestAmazing PageHiddenAchievementsScholarReceived for knowing a great deal about programming topicsAchievementsAs I said in the relevant forum thread, none of those constants individually are floating-point, but combined the result are automatically extended to floating point because of the overflow (as a part of the preprocessing step of constant folding). This does not happen at runtime.randomousPower UserRobotHiddenEaster EggsSecond YearMy account is over 2 years oldWebsiteDrawingI like to draw!HobbiesOh... yeah, there's no bbcode on comments yet. Sorry!GuzzlerFirst WeekJoined in the very first week of SmileBASIC SourceWebsiteDrawingI like to draw!HobbiesIntermediate ProgrammerI can make programs, but I still have trouble here and there. Programming StrengthHey randomouse, FIX THAT ALREADY . Lol, see what I did?kldck_hulFirst MonthJoined in the very first month of SmileBASIC SourceWebsiteScholarReceived for knowing a great deal about programming topicsAchievementsZelda Is Awesome!I love The Legend Of Zelda!Express YourselfThis is plain brilliant. I'm working on an object-oriented language extension and this was one of the big things missing. I will probably include this in my library.randomousPower UserRobotHiddenEaster EggsSecond YearMy account is over 2 years oldWebsiteDrawingI like to draw!HobbiesThis is REALLY useful, and I'm glad you took the time to figure all this out. Thank you for posting this!

- function
- string
- integer
- float
- NaN
- inf
- string array
- array

The way it determines arrays is simple: It requires the use of logInArrayDimensions(a custom command) It checks all of the names logged into an array and checks the existence of the input. It also checks if a "$" is at the end. It will then determine if it is string, and then determines inf or NaN using`CLASSIFY`

if it returns zero, checks integer or real. If integer, do the following:`IF INTEGER== TRUE THEN IF FLOOR(ABS(X))==ABS(X) THEN RETURN "integer" RETURN "float"`

`IF (X||0)==3 THEN RETURN 2`

This is because`IF X==0==3 THEN RETURN 2`

1 character shorter. EDIT:`IF X>0>1 THEN RETURN 2`

EDIT 2:SmileBASIC,~~57 52~~46 bytes`DEF Y(X)IF X>0>2THEN RETURN 2 X=.1RETURN!X END`

But should we rely on an obvious bug? Of course comparison operators should never return any value other than true/false... if this is fixed, all type checking will stop working. (and according to squarefingers, the int/float check is a bug as well) A safer alternative might be something like:`DEF TYPEOF(X) X=X*0 IF X && X==X THEN RETURN 2 X=0.1 RETURN !X END`

`PRINT &H0-&H80000000`

gives a positive result. So, &H0 appears to be getting treated as a floating-point, and &H80000000 appears to be getting treated as integer. Just for fun I tried`PRINT &H00000000-&H80000000`

and that also showed the zero was treated as floating-point.FIX THAT ALREADY. Lol, see what I did?