Author Topic: Query a variable ?  (Read 276 times)

0 Members and 1 Guest are viewing this topic.

Offline krovit

  • Forum Regular
  • Posts: 125
Query a variable ?
« on: November 27, 2020, 02:29:18 PM »
Hallo!

Maybe I got lost... and I ask a stupid thing: can you query a variable to know what type it is (integer, double, string, etc.)?
Nothing is easy, especially when it appears simple

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 275
  • Needle nardle noo. - Peter Sellers
Re: Query a variable ?
« Reply #1 on: November 27, 2020, 03:49:51 PM »
I can't imagine why you'd need that, but it is interesting. 

Determining floating point numbers is easy:
var = 3.1415
if var = INT(var) then print "Not floating point, Watson!"

For integers, you could have an error checking routine and then try to assign
numbers that are too large, triggering the error.  Same idea to determine the
type of float.

Or you could use _MEM to figure it out:

Code: QB64: [Select]
  1. DIM st AS STRING * 8
  2.  
  3. DIM m(10) AS _MEM
  4.  
  5. m(1) = _MEM(i)
  6. m(2) = _MEM(l)
  7. m(3) = _MEM(s)
  8. m(4) = _MEM(d)
  9. m(5) = _MEM(f)
  10. m(6) = _MEM(st)
  11. FOR i = 1 TO 6
  12.     PRINT m(i).SIZE; m(i).TYPE; m(i).ELEMENTSIZE
  13.  
It works better if you plug it in.

Online FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 2710
  • LET IT = BE
    • QB64.org
Re: Query a variable ?
« Reply #2 on: November 27, 2020, 04:04:05 PM »
Quote
I can't imagine why you'd need that, but it is interesting. 

I feel the same as Richard, especially cause you'd be the one declaring your own variables anyway. It'd of course be useful if we could declare sub/function parameters as ANY, which we can't as of now.

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 275
  • Needle nardle noo. - Peter Sellers
Re: Query a variable ?
« Reply #3 on: November 27, 2020, 05:33:25 PM »
Here's a program that works.  Identifies most types of goat.
Code: QB64: [Select]
  1. DIM t AS STRING * 8
  2. DIM d$(10), m(10) AS _MEM
  3.  
  4. d$(1) = "i": m(1) = _MEM(i)
  5. d$(2) = "l": m(2) = _MEM(l)
  6. d$(3) = "s": m(3) = _MEM(s)
  7. d$(4) = "d": m(4) = _MEM(d)
  8. d$(5) = "f": m(5) = _MEM(f)
  9. d$(6) = "t": m(6) = _MEM(t)
  10. d$(7) = "u": m(7) = _MEM(u)
  11.  
  12. FOR i = 1 TO 6
  13.     RESTORE
  14.     FOR j = 1 TO 7
  15.         READ goat, d$
  16.         IF m(i).TYPE = goat THEN PRINT d$(i); " "; d$
  17.     NEXT j
  18.  
  19. DATA 512,"string"
  20. DATA 288,"_float"
  21. DATA 264,"double"
  22. DATA 260,"single"
  23. DATA 132,"long"
  24. DATA 130,"integer"
  25.  
« Last Edit: November 27, 2020, 05:41:28 PM by Richard Frost »
It works better if you plug it in.

Online SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3232
    • Steve’s QB64 Archive Forum
Re: Query a variable ?
« Reply #4 on: November 27, 2020, 05:41:59 PM »
Look at _MEMsort.  It showcases how to use _MEM to decipher out all the possible types of a variable.  https://www.qb64.org/forum/index.php?topic=1601.0

https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline krovit

  • Forum Regular
  • Posts: 125
Re: Query a variable ?
« Reply #5 on: November 28, 2020, 07:14:30 AM »
Thank you all! You gave me excellent ideas to work on.

Clearly I decide the variables but in the TYPE / END TYPE structures I have really inserted many variables according to names that indicate their content (in this way I do not get lost in the thousands of lines of code).

Data entry takes place semi-automatically by assigning to all fields - at the end of the control of the keyboard control routine - the variable$(). Imagine dozens, if not hundreds of contents managed in a completely automatic way and that flow into variable$().

With a procedure as automatic as possible I want to assign that variable$() to the actual and real variable that was defined, and I need something that transforms variable$() according to the defined type.

From this arises the need to know the type of variables. Something like:

IF type(variable_defined) = INTEGER then variable_defined = val(variable$ ()) ELSE ...


___
The system I produced is able to create infinite (almost!) data entry grids simply by establishing what types of inputs I want on the screen. And obviously creates it in a graphic format consistent with the entire application.

In this way I can deal with numbers, words, phrases on any topic, from the shopping list to accounting calculations passing through the management of documents and deadlines ... practically (almost!) anything...

It's a lot - too much! - that I work there. It's nothing innovative as I see you and many others doing (it's in the old programming style, nothing revolutionary!) but I'm doing the impossible to make everything light, efficient, portable and adaptable on the fly for any need...

« Last Edit: November 28, 2020, 07:32:04 AM by krovit »
Nothing is easy, especially when it appears simple

Offline luke

  • QB64 Developer
  • Forum Regular
  • Posts: 243
Re: Query a variable ?
« Reply #6 on: November 28, 2020, 10:43:00 AM »
The following discussion ignores the existence of _MEM and PEEK/POKE because they're hacky and break the type system.

Theoretically speaking, QB64 is a statically typed language. The compiler needs to be able to determine the type of every variable, parameter, operator and constant at compile-time.

Of course if the compiler can work it out the human is supposed to be able to do so as well, but as mentioned you could potentially get confused if there's lots of variables.

Because all types are resolved at compile-time, the final program doesn't have any explicit knowledge of a variable's type (there's no table of variables and their types in the final binary), though of course where appropriate it knows to operate on two bytes or four bytes or whatever.

But that doesn't mean we couldn't include that information - recall the LEN function returns the size of a variable, that's evaluated at compile-time and just replaced with a simple integer constant in the binary. We could add a new function _TYPEOF(x) which is compile-time evaluated to a number that represents the type. For example, _TYPEOF(X%) = 1, _TYPEOF(Y&) = 2.

This gives meaning to a conditional like
Quote
IF type(variable_defined) = INTEGER then variable_defined = val(variable$ ()) ELSE
If we just interpret INTEGER as the value 1 (if we were being properly formal we'd add a new variable type to the language that holds types, but that's a bit of overkill for this).

Practically speaking this would probably work fine for numeric types, but poses problems if, say, strings are involved:
Code: [Select]
if _typeof(x) = string then
  x = "hello"
else
  x = 2
end if

Now you'll always get a compilation error because no matter the type of x one of the branches will have a type mismatch. Although only one branch will ever be executed, the compiler still wants to compile both.

This specific case could be solved by making this a pre-compiler ($IF) feature instead, and that's probably a better option for the situation posed in this thread. But if we persist with this idea a little more we can come up with something (I think) rather interesting:
Code: [Select]
T = typeof(x%)
If rnd > 0.5 then T = typeof(y&)
If T = INTEGER then print 1 else print 2
in this program we could never use a pre-compiler because the value of T is unknown until runtime (RND is really a stand-in for and kind of input or complex state).

Note that _mem gives you some of this: in some cases you can ask it what the type of the variable being wrapped is. But you can also go ahead and just treat an integer as a string, which utterly breaks any kind of formal type system.

Written on a phone at quarter to 3 in the morning, sorry for the inevitable typos.

Offline krovit

  • Forum Regular
  • Posts: 125
Re: Query a variable ?
« Reply #7 on: November 28, 2020, 11:19:27 AM »
Thank You, Luke!

From the mobile phone all this stuff?? Great!
And you made you understand very well.

I understand that there are difficulties and that sometimes they could be fatal to the program but from my point of view it is worth trying to implement these systems

you're writing from on the other side of the planet at 3 in the morning... thank you for your availability... I've always said: this community is really special

...Sweet dreams!

« Last Edit: November 28, 2020, 12:01:36 PM by krovit »
Nothing is easy, especially when it appears simple