Len operator accepts illegal parameters.

BlitzMax Forums/BlitzMax Programming/Len operator accepts illegal parameters.

Fabian.(Posted 2007) [#1]
Strict
Framework brl.blitz

Local A:Byte ; WriteStdout Len A + "~n"     'accepts bytes
Local B:Short ; WriteStdout Len B + "~n"    'accepts short integers
Local C:Int ; WriteStdout Len C + "~n"      'accepts normal integers
Local D:Long ; WriteStdout Len D + "~n"     'accepts long integers
Local E:Float ; WriteStdout Len E + "~n"    'accepts floats
Local F:Double ; WriteStdout Len F + "~n"   'accepts double floats
Local G ( ) ; WriteStdout Len G + "~n"      'accepts functions
Local H Ptr ; WriteStdout Len H + "~n"      'accepts pointers
The Len operator seems to be able to operate on everything! However I think it only makes sense to operate on strings an arrays. This is probably a bug, isn't it?


marksibly(Posted 2007) [#2]
No,

It's kind of like 'SizeOf' - except it's 'NumberOf'.


Fabian.(Posted 2007) [#3]
Okey, but could you then update the help text in the documentation for Len? It currently says that it only works for strings and arrays. You could mention that Len returns the number of elements in an expression or something like this.


Fabian.(Posted 2007) [#4]
When I completely exert the theory that
It's kind of like 'SizeOf' - except it's 'NumberOf'.
I come to the result that this
Strict
Framework brl.blitz

Local O:T = New T
WriteStdout Len O + "~n"

Type T
  Field A
  Field B
  Field C
EndType
should print 3 and not 1, since there're three fields in that type.

Just look at this:
Strict
Framework brl.blitz

Local O:T = New T
WriteStdout SizeOf O + "~n"

Type T
  Field A
  Field B
  Field C
EndType
It prints 12 and not 4. This means that if you make SizeOf operating on objects it returns the size of the object itself and not the size of the variable pointing to that object. Therefore I think if Len operates on objects it should return the number of fields in that object and not the number of variables where it operates on (which is always one).


H&K(Posted 2007) [#5]
The first example is telling you how many Type Ts are in o
The second is telling you how many Bytes are in O

Seems alright to me


Fabian.(Posted 2007) [#6]
In the following table I listed some operations you can do with Len and SizeOf. You'll notice that if you multiply the result of the left side by four you'll get the result of the right side, since four is the number of bytes needed to store an integer. The only exception is when operating on user defined types:
                        |
    Len-operator:       |    SizeOf-operator:
                        |
------------------------+------------------------
 Local N                | Local N
 Print Len N            | Print SizeOf N
------------------------+------------------------
 Local N [ 1 ]          | Local N [ 1 ]
 Print Len N            | Print SizeOf N
------------------------+------------------------
 Local N [ 2 ]          | Local N [ 2 ]
 Print Len N            | Print SizeOf N
------------------------+------------------------
 Local N [ 3 ]          | Local N [ 3 ]
 Print Len N            | Print SizeOf N
------------------------+------------------------
 Local O:T = New T      | Local O:T = New T
 Print Len O            | Print SizeOf O
                        |
 Type T                 | Type T
   Field A              |   Field A
   Field B              |   Field B
   Field C              |   Field C
 EndType                | EndType
When operating on non-object variables SizeOf returns the number of bytes which are needed for the variable. However when operating on object variables SizeOf returns the number of bytes which are needed by the object. Therefore I'd expect Len to do as well: On non-object variables it should return the number of variables (always one) and on objects it should return the number of members/elements in the object.


H&K(Posted 2007) [#7]
Why?

If I ask for the lenght of a book, which is madeup of type word, I word expect the answer to be really Big.

If I ask for the length of a book in type book, the anwser should be one.

When operating on non-object variables SizeOf returns the number of bytes which are needed for the variable. However when operating on object variables SizeOf returns the number of bytes which are needed by the object
That should be AND, cos its doing the same. That is sizeof is returning the number of bytes in both situations.

And Len is also doing the same in both situations.

On standard Types/objects it returns the number of types (always one) and on user defined Tpyes/objects it should also return the number types, also one


Fabian.(Posted 2007) [#8]
That should be AND, cos its doing the same. That is sizeof is returning the number of bytes in both situations.
The number of bytes - that's right. But the number of bytes of what? This differs depending on the expression's type.
On standard Types/objects it returns the number of types (always one) and on user defined Tpyes/objects it should also return the number types, also one
An array is an object, too - so:
Strict
Framework brl.blitz

Local N [ 2 ]
WriteStdout Len N + "~n"
What? It returns 2, however I've got only 1 array -> there's only one array stored in the variable N!


H&K(Posted 2007) [#9]
The [X] means give me that many of these in that.

So len will tell you how many. Without the brackets Bmax assumes you want one of them, and so Len returns 1.

Now you might be right. But I dont think so. And I might be right, but you dont think so. And I dont think we can convince the other otherwise.

So the two of us might as well sutup, and just see where the public vote goes. (Knowing here itll be 50/50)


Fabian.(Posted 2007) [#10]
Okey, and I'd if the vote stays at 50/50, the current behaviour should stay. But nevertheless I think this doesn't make sense.


SculptureOfSoul(Posted 2007) [#11]
Len is working as intended I'm sure. I'm not sure why you are so actively trying to find bugs where they don't exist, Fabian.

An array is not an object per se - it's really a pointer to the head of a list of objects stored in a contiguous block of memory along with some information on how many of those objects it contains. Hence, calling len on an array let's you know how many objects that array has space reserved for.

I say, quit trying to change the trivialities of the language. You could better spend your time either programming something or moving to a language who's idiosyncrasies better fit your perceptions of what a language should be.


marksibly(Posted 2007) [#12]
Actually, I don't mind Fabian complaining about these issues - it makes me think more about the way I've done things.

I now think it was big mistake putting Len 'in the language' at all - it should be in 'Retro' along with Left, Right, Mid and all those old style functions.

The 'returns 1' behaviour is completely useless, but at the time it kind of made sense in terms of Len being a 'NumberOf' equivalent for 'SizeOf'.

'.length' is the way to go - but live and learn!


SculptureOfSoul(Posted 2007) [#13]
Ouch, I got told off by the big man himself ;).

I was just worried that all of this "trivial" complaining might cause a loss of motivation or in some other way inhibit your desire to keep improving the language. Actually, I'm quite glad to hear that you are open to criticism/suggestions - that is the high road and bodes best for the language.

So does this mean we can re-open the discussions regarding multi-threading, overloading, and the myriad of other requests without incurring your wrath? :)

I promise I won't ask about Max3D ;).


marksibly(Posted 2007) [#14]

Ouch, I got told off by the big man himself ;).


Not told off at all!

Len, Asc, and Chr just happen to be ugly bits of the language I'm not particularly proud of, and it's good to be reminded that it's not just me that has a problem with them!


SculptureOfSoul(Posted 2007) [#15]
Well no, not told off I guess. Bad choice of words. I was just trying to do you a favor and quell what I thought was trivial complaints that would just get under your skin (like the brief uproar about Max2 surely did, I imagine.)

Anyhow, it's good to see you around the forums more.


Fabian.(Posted 2007) [#16]
@Marksibly, well, actually I agree Len should be a function. However, it isn't possible and not just because BMX doesn't support function overloading - even if Max2 would ever support this, you'd still have no way to implement it as proper function. You would have to write the Len function to accept strings. Ok, so far. Then you could overload it to also accept arrays - one dimensional arrays, and here's the problem: Len should also work for two dimensional arrays (which is not the same variable data type), so you'd need to overload it a second time, for three dim arrays you'd need to overload the third time, for four dims the fourth, for five the fifth and so on...
Actually it is impossible to implement Len as function, even in Max2, which would support function overloading, so you decided right when implementing it as operator into the language, since you decided not to do the impossible. And this is the reason why I'd like to see Len as operator: everything else is impossible or would need too much work for too poor results.

I think if you permanently want to implement Len as function, you'd have to work a lot and would be still not contented with what you have done.

BlitzMax is great as it is. I can't imagine saying I don't like BMX just because Len is an operator, I don't have any problems with that. I don't say it's great that Len is an operator, but I can't complain about that, since I can't imagine how it would be possible that Len is a function.

Therefore I'm also not that interested in changing Len's behaviour when operating on user defined types. SculptureOfSoul has convinced me of that Len's current behaviour should stay when he said:
quit trying to change the trivialities of the language
I'd really wish that you also stop this - I don't want to say that I don't like to have new additions to the language, like multi threading, function overloading and so on, but these would be additions, not changes.

Don't get me wrong, BlitzMax is the greatest language I've ever seen, but I just worry about that you say you'd like to change so many things.


Curtastic(Posted 2007) [#17]
Len, Asc, and Chr just happen to be ugly bits of the language I'm not particularly proud of, and it's good to be reminded that it's not just me that has a problem with them!


Same here, I only use them because they are recognised by the IDE as keywords and I can press F1 for quick help. (which actually is a big deal to me) I guess the IDE can't do that for .length unless the it knew your variable types


Tachyon(Posted 2007) [#18]
I agree with Curtastic: after reading Mark's post I checked and I use a ton of Len/Asc/Chr/Left/Mid/Right functions in my project. If these are not the preferred solution for BlitzMax then I would highly recommend BRL add documentation to the "Basic Compatibility" module to show us how to wean ourselves off of these functions and on to proper OO techniques.


TomToad(Posted 2007) [#19]
Tachyon, strings are nothing more than an array of type Byte. You can use array methods in place of the retro commands.
Local MyString:String = "abcdefg"
Print "Len()"
Print Len(MyString)
Print MyString.length

Print "Asc()"
Print Asc(Left(MyString,1))
Print MyString[0]

Print "Left()"
Print Left(MyString,3)
Print MyString[..3]

Print "Mid()"
Print Mid(MyString,2,3)
Print MyString[1..4]

Print "Right()"
Print Right(MyString,3)
Print MyString[MyString.length-3..]

I'm having a little trouble with getting Chr() to work properly as an array.


Fabian.(Posted 2007) [#20]
Tachyon, strings are nothing more than an array of type Byte.
Except that they're arrays of Shorts, since they store unicode ;-)
I'm having a little trouble with getting Chr() to work properly as an array.
Try this:
Local N = 65
Local Text$ = Chr N
===== Does the same as =====
Local N = 65
Local Text$ = String.FromShorts ( Short Ptr Varptr N , 1 )
(Not the same like Short arrays, but it replaces the Chr operator)