Instr <> IndexOf

Nope. Some methods have default behaviors (docs should reflect it) like, in left() when count > number of chars it assumes number of chars and don’t raise exceptions.

1 Like

That’s terrible. Just give me all the characters you can, don’t throw an exception!!!

1 Like

An argument could be made for either behavior. Your implementation might not behave gracefully if you didn’t get the number of characters you intended. One could argue that if this is important, you could write code to handle that. One could argue that a database error or filesystem error is something that must be handled, whereas an incorrect number of characters returned may not even be an error.

I don’t feel strongly about the issue one way or another. I think I’d prefer it not to throw an exception, but I’m not complaining that it does.

Coming from C#, VB.NET, and JavaScript, I would have found this an incredibly annoying inconsistency, and I think that would be true of most any other language I’m aware of other than maybe VB6 and VBScript, and IIRC those were consistently 1-based by default. I remember reorienting myself to 0-based everything when we made the transition from classic ASP to ASP.NET and the .NET framework generally, and I found it a fairly easy transition because it was consistent.

Yes, one can become inured to a mix of 0 and 1-based framework (and just about anything else!), but it was ultimately just another excuse for language snobs to snub Xojo on the scientific grounds that it’s weird. Maybe cleaning up a few things (and with a lot less breaking changes, than, say, the transition from Python 2 to Python 3) will boost Xojo’s market share a couple of points. Which, sadly, means maybe it will double or triple it, lol.


Amusingly, VB.NET has a namespace full of VB6 compatibility functions that no one has used in at least a decade. Our corporate style guide wanted us to not use those, but to make the same framework calls you would use in any other .NET language. Otherwise C# coders who don’t know VB.NET would find it much harder to understand what our code was doing. So it was, e.g., Convert.ToDateTime() rather than CDate(), etc. And yes, String.IndexOf() rather than Instr().

I will confess though that on the other side of the coin, Microsoft has a damned annoying habit of introducing some functionality that is supposed to be the Second Coming and then four or five years later when it’s well-cemented into your code base, declaring it Old and Lousy and introducing something New and Improved. A good example was .NET Remoting, which gave way to Windows Communication Framework, which gave way to … well, you get the picture. .NET Core itself, and .NET 5+, seemed to be rearranging namespaces just to break things, when it came to their web framework. This is, in fact part of the reason for my interest in Xojo.

So I’m not unsympathetic to the concerns about API 2. Doing something like this every 10 or 20 years is arguably necessary. Doing it every every 3 or 4, not so much. Making up your mind is a feature, too. I regard this API2 less as dithering than clearing out cruft and inconsistency.

Again, throwing an exception is pretty universal these days. Many would argue that sweeping errors under the rug hides bugs, subtle and otherwise.

IDK about Xojo offhand but in .NET you can do Substring(startPos) without the length and it will just give you the rest of the string, if that’s what you actually want. Or you can write a wrapper or extension method that behaves how you want it to. But IMO you should have to deliberately ask for such things.

C# Substring throws range exceptions while Xojo equivalent Middle() assumes default behaviors:


using System;
public class Program
	public static void Main()
		string s = "123";
		Console.WriteLine("Result [" + s.Substring(4) + "]");

Run-time exception (line 8): startIndex cannot be larger than length of string.
Parameter name: startIndex

Stack Trace:

[System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
Parameter name: startIndex]
   at System.String.Substring(Int32 startIndex, Int32 length)
   at System.String.Substring(Int32 startIndex)
   at Program.Main() :line 8


Var s As String = "123"
System.DebugLog "Result [" + s.Middle(4) + "]"

Result []

Anyone want to wager whether the “fix” for this was to essentially do what @JulianS suggested in the 3rd post of this thread… except it’s called IndexOf, and uses Instr internally?

Yes, you can do that. But if you need performance, that is a no go I guess.

1 Like