CadBerry Devlog 4: Namespaces and Libraries

CadBerry’s solution to libraries, importing files, and namespaces

Cameron Kroll
3 min readNov 17, 2021
Photo by James Harrison on Unsplash

How terrible would it be if you had to write an entire Python app in a single file? Having written apps before, I can tell you that the experience would be 💩!

Letting users spread code across multiple files is extremely important in any programming language. Not only does it simplify and compartmentalize projects, but it also lets programmers write libraries and share code so that nobody has to reinvent the wheel.

What does this have to do with CadBerry? A lot, actually. The version of GIL shipped with it on GitHub was a minimal version that lacked a bunch of important features, including the ability to import other GIL files. This week’s update (live now on the developer branch) addresses this, while also adding the first feature unique to the C++ version of GIL: namespaces.

Namespaces

Most programming languages have something like a namespace. Instead of having every function and variable name available at the same time, the programmer can pack them away in namespaces to prevent them from cluttering up the program.

The original C# GIL didn’t have anything like namespaces. The kinds of projects that the original GIL was designed to handle were small enough that it didn’t really matter if everything was in the same namespace. I wanted to future-proof this version, and the way I decided to implement imports requires something like namespaces, so I spent the extra 30 minutes and designed a namespace system.

I won’t go into the technical details, but because I implemented namespaces recursively, I still have a couple of problems to iron out. Take this example:

sequence SomeSequence 
{
N1::N2::S2 //You could also use "N1:N2" or even "N1:::::::N2"
}
namespace N1
{
sequence S1 {}
namespace N2
{
sequence S2 {}
}
}

In the above example, SomeSequence can access anything in N1 or N2, but N1 can only access N2 and N2 can only access other things inside of itself. My planned solution to this problem is adding a keyword to access the parent namespace and adding links between the namespaces in the Project class. GIL uses one or more colons to access namespaces, so from inside N2 that would look like $Super::$Super::SomeSequence. I’m open to feedback, though, so feel free to suggest your own ideas in the comments.

Importing files

Since the original GIL only had one global namespace, it dumped the contents of imported files into the same place as everything else. This can cause problems when two files define the same sequence or operation, and it makes using libraries more dangerous by increasing the risk of errors.

C++ GIL fixes ̶a̶l̶l some of these problems. This is one of the reasons I love this project! I get the opportunity to redesign GIL from scratch with all the lessons I learned from the first attempt.

In this version of GIL, files are imported into their own namespace with the same name as the file. I can see how everything being in its own namespace could be annoying, so as soon as I get external code integration set up, I will write a function to import a GIL file into the current namespace.

There’s only one problem with this approach. It only cares about file names, not paths. If you have Test.gil and src\Test.gil, they will be treated as the same file. Importing both files will overwrite the pointer to the first one, preventing you from accessing it and causing a memory leak. Speaking of which, that may need to be my next priority for GIL. Because of how fast I’m building it out, the program has likely picked up a bunch of memory leaks.

What’s next?

My next project is something else that’s exclusive to the C++ GIL. CIDARLAB’s Cello is an extremely useful tool for synthetic biology, but Verilog isn’t very user-friendly and I’d like to learn more about how it works under the hood. Because of this, I’m going to write an implementation of Cello that works inside of GIL, but with a C-style syntax. Here’s what I’m thinking it will look like:

bool SomeBool = false
bool AnotherBool = true
if (SomeBool | AnotherBool)
{
SomeGene
}

I don’t think this will be ready by next week, but there’s a chance it will be useable the week after. Either way, see you next week for the next devlog!

--

--