Code posting

One of Xojo’s forum guidelines I dislike is

Code should be provided in your reply directly, rather than links to code on other websites or blogs, in order to maintain the posts’ viability for a longer period.

I’ve come to dislike it because sometimes code examples require more than a handful of lines of code and posting a complete example application requires it be hosted somewhere else in order to link to it. Xojo’s forums have no way to post a long sample inline.

Longer samples posted with links in the forums post remains no more, or less, viable than it ever has when you do need to post more than a few lines of code.

Images and other content has the exact same issue. It has to be hosted elsewhere anyway.

Xojo edits get disabled quite rapidly after posting. It seems its about an hour and then the post is no longer editable. If there’s a correction to be made after this you cannot and then have to post all new code. For anyone who may not read the entire thread this can be a problem as they may see the first chunk of code and use it then complain it doesnt work or compile or whatever. And the auto, hopefully, notices this and posts new code.

So, unless its just a small amount of code I’m likely to post more substantial items on my blog or IfNotNil or linked to from there (since they also dont host the content for more substantial examples).

Full samples are on my servers – same as always.

And the other upside to if not nil is edits are enabled forever (so far). And should you ever want to remove the post you can. Its yours to do with as long as you want.

Enum extender

Tired of writing methods to convert enums to strings and back ?

This little tool lets you drag enum(s) from the IDE onto it and then select the text and paste it back in to the IDE

I will write two styles of conversions – one pair as extends and one as ToString/FromString

To paste the code back into the IDE see my previous post

You’ll find it here

Pasting plain text code

If, like me, you sometime munge text into code and then want to paste it into the IDE that can sometimes be a real chore

Unless you happen to know this little trick

If you have plain text lke

Public Function ToString(extends enumValue as Untitled) as String
  select case enumValue
    case Untitled.valueName
        return "valueName"
    case Untitled.valueName
        return "valueName"
    case Untitled.valueName
        return "valueName"
Else
 raise new UnsupportedOperationException
  end select
End Function


Public Function ToUntitled(extends stringValue as String) as Untitled
  select case stringValue
    case "valueName"
        return Untitled.valueName
    case "valueName"
        return Untitled.valueName
    case "valueName"
        return Untitled.valueName
  end select
Else
 raise new UnsupportedOperationException
End Function

Public Function Untitled_ToString( enumValue as Untitled) as String
  select case enumValue
    case Untitled.valueName
        return "valueName"
    case Untitled.valueName
        return "valueName"
    case Untitled.valueName
        return "valueName"
Else
 raise new UnsupportedOperationException
  end select
End Function


Public Function Untitled_FromString(stringValue as String) as Untitled
  select case stringValue
    case "valueName"
        return Untitled.valueName
    case "valueName"
        return Untitled.valueName
    case "valueName"
        return Untitled.valueName
Else
 raise new UnsupportedOperationException
  end select
End Function

and select it all and copy then, in the IDE select the MODULE, WINDOW, CLASS (not the methods group in any of those) and Paste

The downside here is that only the FIRST method gets pasted – but it does get pasted

So you have to do them one by one

But its better than nothing

Works well with a little helper app I’ll post later than writes methods to extend enums so its easy to convert them to/from strings

Who set that (and who wants to read it) ?

Sometimes you’d like to use what in other languages is referred to as a watchpoint. Some hardware support exists for this in Intel CPU’s but it is limited (there are only a handful or hardware watchpoints available.)

Or it could be done in software; but as noted on Wikipedia this is a ton slower.

Xojo really doesn’t support either type.

But, you can fake it by using computed properties. And since Xojo makes it easy to switch between a public property and a computed one WITHOUT having to update your code (this is a wonderful feature) you can quickly and easily put whatever break points and conditional watches you want IN your code and have much of the benefit of watchpoints.

If you have a public property that you want to see who is setting it simply

  1. select the property
  2. right click and select “Convert to computed property”

And now you can put a break point in the SET, or GET, code for that computed property.

With some creativity you could even get to being able to modify whether the break point is reached while watching your program execute.

Assigns

Xojo has this great feature. You can write sets of methods that can act like LValues. That is – ones that can have a value assigned to them. Or ones that occur on the LEFT of an assignment operator.

dim i as integer
i = 9 // <<< i is an LValue

What can I do with assigns ?

Well one of the things you can do is make methods behave like properties – regular or computed ones. So we can do something simple like

Class myClass
      Sub foo(assigns value as integer)
        // now do whatever we want with value
      End Sub
End Class

dim c as new myClass
c.foo = 9

This is nice but you can get the exact same effect with a public property or a computed property. So no real big deal here. You could have

Class myClass
     Public foo as integer
End Class

dim c as new myClass
c.foo = 9

OR something like

Class myClass
      ComputedProperty foo
        // now do whatever we want with value
      End ComputedProperty
End Class

dim c as new myClass
c.foo = 9

You really cant tell which form was used. And thats actually a nice trick that not many other languages have.

But, since we can write ANY kind of method that uses Assigns as the last parameter we can do things that are not possible with public properties or computed properties.

So we could write a method that, given an integer and string key gets assigned a value that gets stored in a database.

Sub newPrice(partID as integer, partName as string, assigns newPrice as double)

and then use this elsewhere like

newPrice(123, "washer") = 49.95

Public properties and computed properties are usually where I start when writing code, and I’ll transition from a public property to a computed one and then to a get / set pair of methods as needs are revised.

Fortunately Xojo makes this transition easy because each of those can be swapped for the other without any impact on the rest of your code when they have the same signature. FOr instance, without examining the code you have no idea whether the following uses a public property, computed property, or setter method with assigns

dim c as new myClass
c.someProperty = 100

Why Xojo should focus on existing users

It used to be that as an existing user of REAL basic or REAL studio there was a discount when you updated. So instead of paying full price yearly you’d pay a reduced rate to update.

With that model new users, especially ones who bought the more expensive licenses, made sense to court since the revenue from them could potentially be higher. We’ll ignore that its costs more to sell to a brand new user.

But that changed some years ago and now there is no discount for an existing user to renew or a new user to buy a license.

And this is why I say Xojo should switch its focus from courting new users to existing users.

A new user has no investment in existing code. So its easy for a new user to look the tool over and just walk away without buying. An existing user already HAS some code base, large or small, and has a reason to want to update.

Existing users _should_, according to all the marketing people I know and have ever talked with, be easier to sell an update to than trying to sell to a new user. So it should be commensurately less costly to sell to existing users.

Since there’s no discount for existing license upgrades vs new licenses I really do not understand why Xojo wouldn’t focus on existing users and their needs instead of new users.

They stand to make at least the same amount of money if they can convince the same number of existing users to update vs selling to new users they have to “sell”. And maybe thats the rub ? Do they have a difficult time convincing new users to renew ?

I know that so far the people I have spoken to have said they have no compelling reason to update. OR “I would but I dont need all that API 2 stuff” – although “stuff” isnt the word usually used.

And this gets back to my original point. Xojo is pursuing things that do not focus on existing users needs and is doing so at their own financial peril. So they spend more money than they need to to court new users because existing users arent updating ?

Maybe the thing to do is ask existing users WHY they arent updating and tackle those problems rather than trying to just court more new users – who next year arent new users and maybe dont update so you need to court more new users … and so on and so on.

Your thoughts ?

A modest proposal

There are lots of things that strike me as curious.

One of them is that that despite so many people needing third party code, plugins, or other add ons that Xojo doesn’t seem to promote or cultivate those folks who help them make their product better.

MS did this with VB from the outset. I dont know if the VB 1 team realied that they would never be able to supply 100% of the things that people wanted or just loved the idea of new custom controls in dll’s but they built that in early and its arguably one of the things that made VB so successful. (TIOBE lists VB at #6 still even after the release of VB.Net and several other efforts at moving VB out of the mainstream)

That said having a feature, like custom controls, isn’t the same as actually promoting it OR making it possible for third parties to access resources specific to their needs for creating custom add ons. MS was always very good at that and VB’s success speaks to that.

On the other hand while Xojo does have plugins there are only a very tiny handful of developers that anyone even knows about. MBS and Einhugur. There are a few other but the IDE doesn’t ship with samples or demo versions of any of them, no sample project or demos of them, and so a lot of people have no idea they exist.

Theres a really nice report writer that, once people realize they one, always gets recommended. So why isn’t it in the IDE as a default add on that maybe watermarks whatever you use it for until such time as you pay for a license ?

The IDE itself could have a lot of these add ons available for people to quickly and easily use – and that would go a long way towards promoting the third party market AND raising awareness that there even ARE such things available.

Beyond this there’ no single resource at Xojo that seems to be the point person for plugin authors to converse with. Nor anyone whose role is to find and secure new components for Xojo to include in its standard toolbox or as add ones they could ship demo version of.

Growing the third party markets isn’t just something that is good for third parties. Its good for Xojo as well because people looking at the tool see there are lots of things they can use with the tool to accomplish an ever widening range of tasks.

While having a web, ios, android, desktop and console targets widens the range of targes people can try to write their software for if the only things that can be created are whats in the box already OR “write your own” thats a decent impediment to actually deciding to write your software for other targets.

If, on the other hand, you can see that you can get a large set of add ons, custom controls and other things that will help you accomplish your task then that choice becomes a lot easier.

Come on Xojo. you can dedicate some time and effort to this and become VB for the 2020’s.

When characters arent characters

There are two “text handling” types in Xojo – String and Text.

And they vary quite a bit in how they handle textual data.

While strings use UTF-8 as their default encoding you still have to worry about what form of UTF-8 the characters in the string are in. Strings dont deal with “characters” in the way you and I perceive them.

For instance if you run this code

Dim s1 As String = "ü"
Dim s2 As String = &u75 + &u308

Break

What you see in the debugger as the text they hold is the same

But if you chnage this to


Dim s1 As String = "ü"

Dim s2 As String = &u75 + &u308

If s1 = s2 Then 
  Break
End If

what you will find is that while they appear to you and me to hold the same contents they are not “the same”. And this is because the first one uses one form of UTF-8 (composed characters) and the second uses a different form (decomposed characters)

And theres no built in mechanism to know one is in one form or the other nor any to convert one into the other 🙁

So years ago the “next” framework was created and a new type added – Text. And it deals with these issues much better. That same code, using text, looks like

Dim t1 As Text = "ü"
Dim t2 As Text = &u75 + &u308

If t1 = t2 Then
  Break
End If

but this time when you run you WILL hit the break point. Text handles the different forms seamlessly and you get the result you expect.

And the differences go further than this. When you split a string up into “characters” you get different numbers of characters from the two apparently equal strings. Not so with text.


Dim s1 As String = "ü"

Dim s2 As String = &u75 + &u308

If s1 = s2 Then 
  Break // wont stop here but you might expect it should
End If

Dim s1Chars() As String = s1.Split("")
Dim s2Chars() As String = s2.Split("")

Break // note that s1chars. ubound < s2chars.ubound
      // and the contents are totally different

Dim s1CodePoints() As UInt32
For i As Integer = 1 To s1.LenB
  s1CodePoints.Append AscB(s1.MidB(i,1))
Next
Dim s2CodePoints() As UInt32
For i As Integer = 1 To s2.LenB
  s2CodePoints.Append AscB(s2.MidB(i,1))
Next

Break // again the ubounds are different - this time they should be !

Dim t1 As Text = "ü"

Dim t2 As Text = &u75 + &u308

If t1 = t2 Then
  Break
End If

Dim t1Chars() As Text = t1.Split
Dim t2Chars() As Text = t2.Split

Break // note that t1Chars.ubound = t2Chars.ubound
      // and the chars are "the same" !!!!!!

Dim t1CodePoints() As UInt32
For Each cp As UInt32 In t1.Codepoints
  t1CodePoints.Append cp
Next
Dim t2CodePoints() As UInt32
For Each cp As UInt32 In t2.Codepoints
  t2CodePoints.Append cp
Next

Break // these should differ since one uses one form of utf-8
      //  and one uses a different one

Text just handles things seamlessly

With the transition to API 2 it will be a shame if String doesnt adopt some of these capabilities AND there’s no framework provided means to normalize string so they all use UTF-8 composed or decomposed so we can deal with the inconsistencies that can arise.

Var, dim, both. Or Neither ?

Recently there was a blog post on Xojo’s blog from Wayne Golding about how 2019r2 and newer accept VAR as a keyword to declare a variable. And they still accept the older DIM.

There are some issues with VAR IF you ever have to move your code to an older version. I know a lot of developers of commercial software that have to do this so they can continue to support their clients running older versions of various operating systems.

These people have stayed with the older DIM so they can easily move their code simply.

Adding VAR as a keyword has some issues though. While I agree that VAR is an awful parameter or variable name there is code that has used it that now suddenly won’t compile.

One thing I asked for was rather than adding a new keyword, with all the issues that can bring, that we just NOT have to put a DIM or VAR. Then we could write

dim foo as integer
var bar as double
d as date

In a compiler there is usually a “grammar” – a set of rules for what the compiler considers valid code and what it doesn’t. And somewhere in Xojo’s grammar there is a rule that says a variable declaration has to look a specific way. (This is a wild assed guess on my part not actual code since I do not have the code for this)

variableDecl :
      DIM listofVariablesAndTypes
    | VAR  listofVariablesAndTypes

and listofVariablesAndTypes is additional rules for how to declare one or more variables with default values in a single line. Making this grammar rule

variableDecl :
      DIM listofVariablesAndTypes
    | VAR  listofVariablesAndTypes
    | listofVariablesAndTypes

(or something like this) would make it so DIM and VAR are not required.

I’d find it handy.

How about you ?