fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

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

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

  • Phil Hepburn
  • Phil Hepburn's Avatar Topic Author
  • Offline
  • Posts: 737
  • Karma: 7
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.



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.





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:
Attachments:

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #2

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

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #3

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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

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

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
METHOD GetDayByNumber( number as int ) AS Day
RETURN JanuaryDays[number-1]

and a use like
LOCAL Day as Day
Day := GetDayByNumber( 11 )

Frank

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #5

  • Phil Hepburn
  • Phil Hepburn's Avatar Topic Author
  • Offline
  • Posts: 737
  • Karma: 7
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.

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #6

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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #7

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

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #8

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

Please Log in or Create an account to join the conversation.

Last edit: by Frank Maraite. Reason: results were wrong I think

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #9

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

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #10

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

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #11

Phil,

you could show us how to avoid issues like you have. You could show us the basic rules:

- avoid magic numbers. Use defines or consts or computed variables instead.

- define a business oriented interface and put the data representation behind, like
interface IDays
   method GetDayByNumber( number as int ) as Day
end interface

class Days implement IDays
private property _Days as Day[]
   method IDays.GetDayByNumber( number as int ) as Day ; return _Days[number-1]
end class

Later on you can change from array to collection without change any other line of code outside the class definition.

- and of course show the intense use of unit tests to verify it works as intended even after the change to collections.

BTW: you can define an indexed access inside the Days class (and IDays interface of course) by an indexed property where you can do the -1 thing. Look for the special property names 'item' or 'self'. With that you can use Days with the same index syntax as real arrays.

Frank

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #12

  • Phil Hepburn
  • Phil Hepburn's Avatar Topic Author
  • Offline
  • Posts: 737
  • Karma: 7
Good morning Frank,

It is all very interesting what you write, however, I have been given a topic by Meinhard, on which I must deliver a session in April 2018 at Cologne.

The session title is "From Arrays to Collections", in which I must have explanatory material on what Arrays and Collections really are and how we can code them in X#.

I can't ignore that fact that a Project setting of 'Use Zero Based Arrays' exists and what impact that then has on our code that we write. Or what happens if the setting get changed further down the development path.

You can actually create and use Arrays without a need to refer to indices at all, but that is not really the point. We have to cover what exists.

Take a look at this image - lines 162 through 166 and see how we can access each and every array element of a three dimensional array without needing to use a single index directly.



The methods used in the lines numbered 147 through 157 are all part of the .NET Framework and are part of the System.Array class. It is the 'Get Bound' methods which seem to be unaware of the Project 0/1 setting.

On a personal note, I try to never use Arrays unless I have no choice, even then there are smarter ways to use them. But we must make sure that what is there works correctly in X# I feel. And that we have a reasonable understanding of how things work.

Best regards,
Phil.
Wales, UK.
Attachments:

Please Log in or Create an account to join the conversation.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #13

  • wriedmann
  • wriedmann's Avatar
  • Offline
  • Posts: 1423
  • Karma: 6
Hi Frank, hi Karl,

I have adapted my function (or better, extension method) better to the VO equivalent (but kept it 0-based):
static method SubStr( self cString as string, nStart as int, nLen as int ) as string
// 0-based!!!
local nStringLen as int
local cReturn as string
	
nStringLen := cString:Length	
if nStart < 0
  if ( nStart * -1 ) >= nStringLen
    nStart := 0
  else
    nStart := nStringLen + nStart
  endif
endif
if nLen >= ( nStart + nStringLen )
  cReturn := cString:SubString( nStart )
else
  cReturn := cString:Substring( nStart, nLen )
endif
	
return cReturn

I don't like to check string lengths before retrieving a substring, I prefer the VO behavior.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Last edit: by wriedmann.

Some forms of ARRAY do not get their bases set to 0/1 as in Project settings !? 1 year 4 months ago #14

  • Phil Hepburn
  • Phil Hepburn's Avatar Topic Author
  • Offline
  • Posts: 737
  • Karma: 7
Frank, Wolfgang, guys,

Whatever happened to the original thread title ?

No the wonder some of us find it difficult to find stuff we remember reading in the past :P

Regards,
Phil.

Please Log in or Create an account to join the conversation.

  • Page:
  • 1