twinbasic / lang-design

Language Design for twinBASIC
MIT License
11 stars 1 forks source link

Add syntax for file-level `References` statement and enforce single file projects for backwards compatibility #12

Open Greedquest opened 3 years ago

Greedquest commented 3 years ago

Bit of a radical idea here, but hear me out. I've been thinking about when tB supports multiple files in a project, won't that be great we can split all the modules back out and save ourselves scrolling through hundreds of lines of code. But then I thought, we have a real opportunity here; why have two ways of organising classes and modules in your project that are functionally equivalent; having multiple types declared in a file or single types over multiple files a la VBA? Why waste the chance to make these two different approaches mean different things?

So my proposal is this - keep all your classes & standard modules in one file to emulate a classic VBA project. But then use multiple files to represent other VBA projects that can reference each other. By default files in the same tB project will not be able to see inside one another, but they can explicitly Reference / import other files. So you'd write code like this:

File1.twin

Public Class Myclass
    Private value As Long
    Public Sub New(initialValue As Long8)
        value = initialValue
    End Sub
End Class

'other things ...

File2.twin

References File1 'this imports the contents of File1, similar to Add Reference -> File1.xlam

Module MyModule
    Public Sub TestMyclass ()
        Dim obj As File1.MyClass = New File1.MyClass(555)
    End Sub
End Module

Splitting classes across multiple files to emulate the classic approach and reduce scrolling is really a problem with navigation which should hopefully be solved by:

  1. Getting to grips with VSC and its navigation features (much better than VBE/ whatever VB6 had I imagine)
  2. Improvements to the language support like syntax based code block folding
  3. If importing other files is this easy, I imagine former VB* "projects" shrinking and being subdivided by common functionality, so a tB project (package) comprises several sub-projects (modules), each of which is smaller than a typical VBA project and so the navigation issue isn't so great.
    • Basically anything in a RD '@Folder("Parent.Subfolder") would probably be lumped in a single twin file, and imported/referenced in a main project entry point file.

Additional context Now this is just a brainstorm, totally up for discussion - I'm sure the implementation would lead to a lot of complexity, off the top of my head:

  1. What happens to the references dialog, needed for back compat. Is it an implicit global reference across all files in a project, or just an alternative to the References keyword I propose to ease the transition from VB6 (both for coders and for the tB author)
  2. Name clashes, right now references and names are resolved in a hierarchy of redefining, how would that look for a file referencing another project?
  3. Does this have a COM parallel. Do you need to enforce strict single file for back compat?
  4. VB attributes like exposed, are they relevant, or would some new syntax be used for specifying which components of a module can be referenced elsewhere

However I'm basing this proposal off python and countless other languages which have solved this issue previously - although python is a particular focus because:

The simplest implementation is really just a copy-paste of exposed code inside a namespace scoping block, and could be developed from there...

WaynePhillipsEA commented 3 years ago

To me, it really sounds like you want Namespace support. And I think Namespaces could be possible in tB, AND be made COM compatible via generating one type library per namespace (all could be bundled into a single DLL file for example). Circular references between the Namespaces could be a problem though -- needs some tests.

bclothier commented 3 years ago

I do think namespace and consequently the ability to have statements to import references would be immensely valuable. I really dislike the global references which also leads to problems (which did you want, Word.Range or Excel.Range? Better disambiguate!).

However, I am a bit worried about the idea of separating type libraries by namespaces because of the fact that if we export a type library for consumption, we may be more inclined to export a single type library simply because it's easier to handle from VB6 or VBA hosts. In my view, references in VB6/VBA project are expensive and because they are dumb WRT demanding full path and are quite fragile, it creates a powerful incentive to just make one big type library just to not have to add more references than necessary. If that problem can be solved/worked around, then I'm fine with one type library per namespace. Otherwise, I probably would want to control which object get exposed to the single type library (perhaps by using attributes) and use namespaces simply as logical partitioning that does not effect the presentation in the type library.