twinBASIC Update: May 15, 2022

Highlights include a modern browser control for Microsoft Access (yes, you read that right) and a spirited discussion regarding attribute syntax.

twinBASIC Update: May 15, 2022

On April 23, 2021, I helped Wayne Phillips introduce the world to twinBASIC at the Access DevCon Vienna conference.  I boldly predicted that twinBASIC (along with the Monaco editor) would replace VBA and its outdated development environment by 2025.  With that goal in mind, this weekly update is my attempt to keep the project fresh in the minds of the VBA development community.

Every Sunday, I will be providing updates on the status of the project, linking to new articles discussing twinBASIC, and generally trying to increase engagement with the project.  If you come across items that should be included here, tweet me @NoLongerSet or email me at mike at nolongerset dot com.

Here are some links to get involved with the project:


WebView2 is Here!

The WebView2 control is now available.

To demonstrate it, Wayne added a new Sample project: Sample 0. WebView2 Examples:

If you open the sample and press F5, it will launch the following form that demonstrates a few uses of the WebView2 control:

Example 1. Web Browser

WaynesWorldWideWeb Browser.  Party time! Excellent!

Example 2. Virtual Folder Mapping

Instant local web server(-ish)!

Virtual Folder Mapping allows us to map a folder from your computer, to a virtual hostname.

This allows us to provide whole files to the WebView2 instance, without using a web server.

In this example, we've set up a virtual hostname of waynesworld.example, mapping to a folder that we've created containing the web application files, at:


Example 3.

Live HTML editing with an HTML-based Monaco code editor WebView2 control side-by-side with a second WebView2 control to preview the code in real-time:

Sample 9.

The official Access roadmap shows Modern Browser Control support scheduled for September 2022.

Or you could grab a copy of twinBASIC and build it yourself today!

Now, to be fair, this is still an early proof of concept, but...

...consider the concept proved!

Refer to my earlier article on creating an ActiveX control with twinBASIC for more details:

HOW TO: Create a Custom ActiveX Control with twinBASIC
Did you ever wish you could build a custom control for Microsoft Access forms and reports? With twinBASIC, that’s a 15-minute project.

Around the Web

The Flame Wars Cometh

Jason Peter Brown posted the following seemingly-innocuous "side note" in the discussion about changing the NotDispatchable keyword into an attribute:

Just a side note - it might just be me, but I find all the [ ] stuff in code very distracting. This is probably better as a new discussion topic, but I wonder if it would be possible to either:

A) Have a switch for toggling the display of [ ] block stuff (Attribute, InterfaceID, etc...), or

B) Have an option to show all [ ] stuff off to the side in a pane in the IDE as opposed to in the code window? E.g. when you move the caret into a new method, the pane would show the attributes, interfaceIDs, etc.. that are connected to that method.

The comment ignited a spirited pyro-skirmish, with more than 100 comments flooding in from a variety of users attempting to answer the following questions:

Attribute Syntax

Should it be:

  • [ Description ("Do something") ]
  • [ Description "Do something" ]
  • <Description("Do something")>
  • @Description "Do something"
  • /+ Description "Do something" +/
  • @[Description("Do something")]
  • Attribute Description = "Do something"
  • @Description("Do something")

I prefer the final syntax: @Description("Do something")

  1. It's illegal syntax in VBx, so no problems with backward compatibility
  2. The "at" symbol makes for a great mnemonic with the word "attribute"
  3. It lends itself to a natural reading of "Attribute Description is 'Do something'"

Attribute Position

Should it appear:

  • Before the block of code it modifies
  • Within the block of code it modifies (e.g., at the top of a Sub routine)
  • After the code it modifies (e.g., when the "block" of code is a single line)

I prefer it before the code it modifies.

Attribute Visibility

Should it be visible:

  • Always
  • Only when unfolded (i.e., can be hidden via code folding)
  • Never (i.e., modified only via the GUI)
  • Configurable

I prefer it to be foldable, perhaps with a shortcut key to fold/unfold all attributes.

Attribute Flexibility

Should attributes be allowed in-line or should they only work with blocks of code.  In other words, should something like the following be supported?

Public Sub Foo(Fizz As Long, @Out Buzz As Long, FizzBuzz As Long)
  • Attributes modify block code only
  • Attributes may be used in-line

I can see the use case for in-line attributes, so I think it makes sense to go with a syntax that will support them.

My Unsolicited Thoughts on Attributes

Voting Is a Bad Idea

About halfway through the conversation, Wayne proposed eventually putting it to a vote:

I can feel a vote coming :)    Once you guys have thrashed the ideas out some more, let's collectively pick our favourite options and put it to a vote.

While the conversation generated over 100 comments, those comments came from only eight different people–one of which was Wayne himself.  Now, to be fair, these are eight of the people who have spent the most time commenting on and discussing this project.  In other words, they understand the broader context much better than a bunch of Reddit randos stumbling on the project for the first time.

However, seven votes is an absurdly small sample size anywhere outside of Snow White's cottage.

I think the true value of having the discussion is for Wayne to gain the benefit of multiple perspectives.  Like it or not, the twinBASIC project is following the Benevolent Dictator for Life model.  The BDFL model has a rather impressive track record of success–see Python and Linux.  

Now, obviously, twinBASIC is not an open-source project like Python and Linux.  That said, a large part of what made those projects successful is that Guido van Rossum and Linus Torvalds each had a strong vision that guided their development.  

Wayne Phillips is carrying the vision for twinBASIC.  I suspect he has a direction that he is already leaning.  Whatever he picks, some people will be disappointed.  But what happens if you put it to a vote and the crowd of seven turns out to be not-so-wise?

Do you accept the vote at face value, choosing an option that may be bad for the project in the long run?  Or do you ignore the voters' will, thus alienating a few of your most ardent supporters?  The best case scenario is that the voters' preferences line up with Wayne's.  But what if they don't?!

Wayne, I recommend you read all the comments, empatheize with all the perspectives, consider your long-term vision for the project, and do what you think is best.  No need for a vote.

And if you're still not sure what to do, just go with what I wrote up there 👆. 😁

The Problem with Custom Attributes Conceptually

During the course of the thread, a few people brought up the idea of allowing developers to create custom attributes.  

If I understood correctly, what they were talking about was very similar to the Python "decorators" concept as demonstrated in this StackOverflow answer:

3.8 ≤ Python
@property and @functools.lru_cache have been combined into @cached_property.

import functools
class MyClass:
   def foo(self):
       print("long calculation here")
       return 21 * 2

Interestingly, the Python mailing list had a similar pyro-skirmish over what syntax to use for the decorator feature.  (The more things change, the more they stay the same.)

Now, I understand the appeal of attributes (a.k.a. the decorator pattern).

When used properly, they make the code:

  • Easier to read
  • Faster to write
  • Have a higher signal to noise ratio

The problem with attributes–at least as I've used them in other languages–is that they make the code:

  • Harder to understand
  • Harder to debug
  • More brittle

How can the same feature make code both easier to read and harder to understand?  This seems like a contradiction.  Take the Python example above.  The foo method is decorated with the cached_property attribute.  It's easy to read this code and know–based on the attribute name "cached_property"–that the value will be calculated only once and then returned from memory on future calls.

But in order to understand how that actually happens, you have to go to the cached_property decorator code.  And that code won't have any references to the method foo.  Rather, it will treat the method generically.  This is a very powerful concept...but it is not a beginner topic.

In many cases, the alternative to attributes is more boilerplate code.  

While boilerplate code has many disadvantages, potential for introducing errors, takes time to write, etc., it is generally easier to follow than generics-based code.

And what happens when you have multiple custom attributes?  What order are they executed in?  What if your custom attributes have custom attributes?  What if one attribute changes in such a way that it becomes incompatiblie with other custom attributes when applied to the same instance of an object?

If one is not careful, the well-intentioned efforts to create SOLID code result in a different kind of spaghetti.  And one that's even harder, if not impossible, to step through with a debugger.


Here are the updates from the past week.  You can also find this information by visiting the GitHub twinBASIC IDE issues page.

twinBASIC IDE -- BETA RELEASE · Issue #772 · WaynePhillipsEA/twinbasic
As discussed in #763, I&#39;ve been busy working for the last few weeks on a new IDE, specifically designed for the twinBASIC compiler. Here are the details for installing the current BETA release ...

NOTE: Development of the twinBASIC VSCode extension is paused until 2023 so that efforts can be focused on the new IDE.  


BETA 39 is now available:


BETA 38 is now available:

  • fixed: LoadRes* functions were broken in DLL builds
  • fixed: generated ActiveX controls could not expose events to the host
  • added: attribute [ EventInterfaceId("{GUID}") ] for controlling the generated source event interface GUID
  • added: RaiseEventByName function in the VBA library (similar to CallByName)
  • improved: WebView2 control now supports deferred events to circumvent the re-entrancy limitations of the WebView API
  • added: Sample9. ActiveX Control WebView2 + Monaco


BETA 37 is now available:

  • fixed: using Implements with a class that has a Friend member caused compiler instability during editing [jpbro]


BETA 36 is now available:

  • improved: Sample 0 (WebView2) with a form demonstrating how to integrate the Monaco editor into your application, and using 2 WebViews side-by-side
  • fixed: adding an event from the form designer inserts into the wrong place if the form has no parameterless Sub New defined
  • improved: for some wellknown filetypes, the IDE now provides syntax highlighting via the built-in monaco editor support (for javascript/typescript/html/css/json/xml/ini)
  • fixed: (regression) execution of properties triggered from the locals/watches window should not allow errors to propagate to the IDE during debugging
  • fixed: stepping through code that switches to another file could sometimes not bring the active line into view due to codeLens data not being ready
  • fixed: codegen error for set-assignments on UDT array fields [ dynamic array vs Dynamic variant array gives codegen request to report error #834 ]


BETA 35 is now available:


BETA 34 is now available:

  • improved: Sample 0 (WebView2) with a form demonstrating Virtual Folder Mapping and some javascript integration


BETA 33 is now available:


BETA 32 is now available:

  • added: WebView2Package, offering the new WebView2 control
  • added: Sample 0, offering the first demo of the WebView2 control
  • improved: StrConv now supports vbUTF8 and vbFromUTF8 enumeration values [ handling of locales & invariant #201#issuecomment-1018823414 ]
  • fixed: Escape and Return keys not raising Key events in WinNativeForms::TextBox
  • fixed: issue when trying to open a recent project that has since been moved or deleted [ IDE -- BETA RELEASE #772#issuecomment-1117609489 ]
  • fixed: restarting the compiler would sometimes cause the active editor to lose error diagnostic markers
  • fixed: Settings validation error when project name contained an underscore [ error when namespace contains underscore _ #832 ]
  • fixed: importing a VBP project with non-ASCII filenames problem [ in Project Explorer #830 ]
  • fixed: saving of Settings when no export path was set [ IDE -- BETA RELEASE #772#issuecomment-1118628569 ]
  • fixed: declared interfaces were generating psuedo coclasses in generated type libraries

More WebView2 examples and documentation coming tomorrow.

All original code samples by Mike Wolfe are licensed under CC BY 4.0