Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

This forum is meant for questions and discussions about the X# language and tools
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Phil Hepburn »

Hi Robert and TEAM,

I have been researching .NET multi dimensional arrays, made by the STATIC method in the Array class - these are called "CreateInstance".

I have attached an image or two to give you an idea of what I was doing when I came across the issue.
ZeroBase_02.jpg
ZeroBase_02.jpg (134.67 KiB) Viewed 735 times
The methods of Get Lower/Upper Bounds seem to ignore any settings on the Project regarding "Use Zero Based Arrays". No matter what '__ARRAYBASE__" is set to I get the .NET standard of 0,0,0 and 1,2,3 for my lower and upper bounds.
ZeroBase_04.jpg
ZeroBase_04.jpg (87.21 KiB) Viewed 735 times
ZeroBase_05.jpg
ZeroBase_05.jpg (18.83 KiB) Viewed 735 times
I have a feeling that the X# compiler may only be handling the cases where arrays are declared using the syntax 'String[]' and 'INT[]'. Hopefully 'String[,]' and 'String[,,]' make correctly base 2D and 3D arrays.

Sorry if this causes you some hassle, I don't think one based arrays will ever 'go away' ! :evil: :angry:
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Frank Maraite »

Hi Phil,

it's quit simple: .NET doesn't know anything about /az, __ARRAYBASE__ or things like that.

This is a workaround to use 1-based arrays but only has effect to X# code. Everything inside .NET is 0-based. Everything behind every language is at least 0-based. The first element is always pointer+0. As long as you call .NET methods you will get 0-based results.

The earlier you change your mind to 0-based thinking the less issues you will get. As I said the last days you only confuse yourself when doing tricky things.

0-based thinking is widely used in normal life too. Think about a newly born child. It lives in day zero, week zero, month zero and year zero. After 24 hours we say it is 1 day old, but still zero weeks. It lives in it's year one and we say it is zero years old. And when it turned into it's second year we say it is one year old.

Frank
User avatar
Chris
Posts: 4922
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Chris »

Hi Frank,

True, but on the other hand, if we have a 31 element long array representing days of January, it's not very intuitive thinking that aDay[10] represents the 11th day!

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Frank Maraite »

Hi Chris,

but looking at real code: do you really have code like this? I think in most situations we have loops where it doesn't matter. Or we do what we should do: hide the internal representation. In your example I would have a method like

Code: Select all

METHOD GetDayByNumber( number as int ) AS Day
RETURN JanuaryDays[number-1]
and a use like

Code: Select all

LOCAL Day as Day
Day := GetDayByNumber( 11 )
Frank
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Phil Hepburn »

Hey guys!

You are missing my point altogether. I am NOT voting for one way or another, in what I posted, but pointing out what looks to me like a "BIG issue" for X#. If there exists a Project property to set Zero Based Arrays to 0/1 for .NET arrays, then it ought to apply to all such arrays, no matter how the X# code or syntax creates the arrays. (I am not talking about VO related arrays.)

I feel that as things are at the moment it is possible to have some .NET arrays operating as one based and others (made from the STATIC methods for CreateInstance) operating as zero based. VERY confusing. This situation needs addressing in my view of things.

Personally Frank, I would go with ZERO based all the way for .NET arrays, and collections like Lists - simply because it seems the safest way forward if we are to embrace .NET. I also would like the default setting for any new X# project to be ZERO based - at the moment is seems as if it is 'one based'.

I don't think logically trying to justify things makes any sense. Birthdays, houses in streets etc., etc.. If you study low level programming it seems that ' 0 ' (zero) is the first unused state of the hardware and/or register / memory, and back in the old days when memory stuff was small / scarce, they tried not to waste resources. I am now trying to think back to 1980 when we programmed the Z80 chip - it was all there - obvious !

For your interest Frank, I always include in my 'ClickStart' eNotes a chapter zero, just to remember good old Don, as he used to try and justify having a zero based syntax ;-0)

I believe FORTRAN is or definitely started with one base. And the Algol 60 I started on could be set by the user / programmer. I often used to use -40 for good scientific reasons, for what I was doing.

So lets at least have X# doing one thing 'fully' by sorting out 'CreateInstance'.

Hope this helps explain things. I am NOT trying to do anything 'fancy' or 'Tricky'. Quite the reverse in fact - I am trying to help explain to Forum guys / user, what is there already.

I am not confusing myself, the confusion is already built into the current compiler it would seem to my research. SORRY Robert, but it was my research findings today :unsure:

I have to be able to get this stuff straight ready for Cologne and my session on Arrays to Collections.

Regards,
Phil.
User avatar
Chris
Posts: 4922
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Chris »

Hi Frank,

Fair enough! But, see, you did not use 0-based indexing for when calling the method, you used 1-based, which is the natural thing to do :)

In my opinion, the only reason for using 0-based arrays/collections etc is absolute speed, saving the last CPU cycle, which made a lot of sense when the c language was invented, but is probably irrelevant nowadays in high level application development. Similar for example for string indexing, it's very counter intuitive using cString:Substr(2) in order to get a substring starting from the 3rd character...

Unfortunately in .Net we are stuck with this design decision by MS, which my guess is that was dictated by the c/c++ guys in the company... But I agree with you, since this is how everything works in .Net, it's probably a good idea to change our mind and always use 0-based indexing, because it will be more consistent. But I really, really hate this :)

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Frank Maraite »

Phil,

from the Vulcan help file:
This option does not affect how the assembly being compiled is used from other applications. When the /az option is not used, the compiler generates code to subtract 1 from the array index in order to provide 1-based array indexing semantics at the language level. When the /az option is used, the compiler does not adjust array indexes. Either way, the resulting arrays are always 0-based at the IL level, which allows compatibility with all other .NET languages.
That's all, and that's what I wanted to explain: the X# compiler has no chance to influence the return value of Array.GetLowerBound(). The array itself is always 0-based with all implications.

The easiest way is to follow the .NET way. Accept that if you like it or not.

BTW: Just now I'm working on code based on 2-dim-arrays that I wrote 2007. It was my first code in Vulcan. I want to enhance this code. But what I'm doing now is: I do write unit tests first to be sure nothing happens later. These hours of (for some people meaningless) work will save me much more hours in the future. And let we sleep well!

Frank
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Frank Maraite »

Hi Chris,

no one prevents you from doing
STATIC METHOD SubStr( SELF s AS STRING, startIndex AS INT ) AS STRING
RETURN s:Substring( startIndex-1, 1 )
STATIC METHOD SubStr( SELF s AS STRING, startIndex AS INT, length AS INT ) AS STRING
RETURN s:Substring( startIndex-1, length )
and then
? "Abc":SubStr(2) // "bc" I hope :-)
? "Abc":SubString(1) // "bc" I hope :-)
? "Abc":SubStr(2,1) // "b" I hope :-)
? "Abc":SubString(1,1) // "b" I hope :-)
Frank
FFF
Posts: 1581
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by FFF »

Frank Maraite wrote:? "Abc":SubStr(2) // "bc" I hope :-)
? "Abc":SubString(1) // "bc" I hope :-)
? "Abc":SubStr(2,1) // "b" I hope :-)
? "Abc":SubString(1,1) // "b" I hope :-)
That i'd call for desaster ;) - took me some time to see the difference, and there are days, when you i'm sleepier than now...
Doubt, a unit test will cater for these <s,cr>

Karl
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !?

Post by Frank Maraite »

Karl,

it's simple: SubStr is the VO name and SubString is the .NET name. So if you have VO code there is no need to change something.

Should copy the static methods and call them SubStr2 and SubStr3 to have the same naming as the strongly typed VO versions.

If you want to call the .NET equivalent you have to change the index by -1.

And of course well done unit test catch up all kinds of these silly things.

Frank
Post Reply