Blog

BoxLang 1.0.0 Beta 11 Launched

Luis Majano August 23, 2024

Spread the word

Luis Majano

August 23, 2024

Spread the word


Share your thoughts

We have really kicked into gear with this release, tackling a whopping 26 tickets and delivering some of our most aggressive features to date. This update signifies a significant leap forward towards a stable release in the Fall. Thank you for your continued support and stay tuned for more exciting developments!

What is BoxLang?

BoxLang is a modern dynamic JVM language that can be deployed on multiple runtimes: operating system (Windows/Mac/*nix/Embedded), web server, lambda, iOS, android, web assembly, and more. BoxLang combines many features from different programming languages, including Java, ColdFusion, Python, Ruby, Go, and PHP, to provide developers with a modern and expressive syntax.

It is also a drop-in replacement for Adobe ColdFusion and Lucee Engines.

How to get started?

Visit our docs at https://boxlang.ortusbooks.com and get coding today. If you want to try it out on the web then go to our online REPL at https://try.boxlang.io. You can also checkout our YouTube playlist: https://www.youtube.com/playlist?list=PLNE-ZbNnndB-40LvAbeSeT2Oi3V2gm_B8

Release Notes

Here are the latest release notes: https://boxlang.ortusbooks.com/readme/release-history/1.0.0-beta11

New Features

BL-236 Phase I : Performance improvements for grammar and parser validation

We have been working with an amazing ANTLR expert: Jim Idle, and we have been able now after several months of hard work to merge in a complete update to our parsers. This has a massive performance increase between 5-10 times more performant than before. However, we are still not those, we have three more performance phases coming up!

BL-91 Support numeric literal separators in source code

We’ve added a small, but useful syntax to our BoxLang parser that comes from multiple other languages. Numeric placeholders allow you to place underscore characters (_) inside of a numeric literal for readability. Take a number like this

n = 1000000000

That’s 1 billion. Or was it 1 million? Or maybe it was 100 million… pauses to re-count.
With numeric place holders, your code can look like this:

n = 1_000_000_000

Ahh, so it was 1 billion! There’s no rules on where you can place the underscores, so long as they are INSIDE the number and not leading or trailing. Heck, this is valid (though pointless):

n = 1_0_0_0_0_0_0_0_0_0

You can also place numeric separators in decimals

n = 3.141_592_653_59

and in the exponent of scientific notation

1e2_345

These underscores are simply thrown away at compile time. They are not represented in the bytecode and will not appear anywhere in your running app. They are purely for readability in your source code.

BL-457 Add static assignment modifier

You can now use the static assignment modifier in your code:

static foo = "bar"

which is sugar for

static.foo = "bar"

and validate at runtime there is actually a static scope, or throw an exception.

BL-458 Add final modifier to classes

You can now use the final modifier in your classes

final class {}

which is sugar for:

class final {}

This means that your classes will not be able to be inherited from.

BL-459 final modifier for UDFs

Your UDFs can now also be declared as final

final function foo() {
}

which will set the function as final into the scope it gets registered into. Any additional function declarations with the same OR ATTEMPTS TO SET A VARIABLE OF THAT NAME will result in an error.

final function foo() {}
foo = "brad" // exception because foo is final

BL-460 Add final assignment modifier for variables

You can now add final assignment modifers to variables in your code:

final foo = "bar"

this, of course, can be used with other modifiers

final static foo = "bar"
final var foo = "baz"

The only 2 modifiers that can’t be used together are var and static since they represent different scopes.

When a variable is declared as final, the scope it is being set into will track a list of keys that are designated as final, and will prevent those keys from being modified in the future.

This is ONLY a feature of scopes. Structs and other struct-like container will not have a final concept.

The following example

final lockDown = [ 1, 2, 3 ].toImmutable()

cannot be mutated OR re-assigned.


You can see the Set of final keys for a scope via the meta object

variables.$bx.meta.finalKeySet

You can also remove keys from the set to make a variable no longer final.

final foo = "bar"
variables.$bx.meta.finalKeySet.clear() // Nothing is final in this scope now
foo = "baz" // no error

BL-469 DynamicInterop now filters non-callable methods when invoking and matching thus accelerating lookups considerably

This is a major update to our dynamic invocation with Java interop. We know only look at callable methods, where as before we looked at every single method on Java classes. This is a significant boost in performance when doing invocations and well, it also fixes a bug on ambiguity between same named methods with different visibility scopes. Relax and ride the lightning ⚡️

BL-438 Zip Utility & compress(), extract(), isZipFile() bifs

BoxLang now speaks Zip language. We have added zip and gzip capabilities to the core. This will allow us to leverage compression and extraction for modular activites, jar installations, logging, and much more. We have also created the following BIFS available to you:

  • compress( format, source, destination, [includeBaseFolder=true], overwrite=false ) - Compress a source to a destination using available compression formats.
  • extract( format, source, destination, [overwrite=false], [recurse=true], [filter], [entryPaths] ) - Extract a zip/gzip archive to a destination with nice options.
  • isZipFile( filepath ) : Determines if the passed file can be treated as a zip archive.

We support the following formats:

  • zip
  • gzip

More formats will be available for our +/++ subscribers.

Please note also that the filter arguments can be the following:

  • A valid regular expression string: ".*\.txt"
  • A BoxLang closure or lambda (name) => name.endsWith(".txt")
    • Receives the full path of the entry
  • A Java Predicate: (entry) -> entry.getName().endsWith(".txt")
    • Receives the ZipEntry object

In our next betas we will have a the Zip component which will allow you to do the following:

  • Compress Files
  • Extract Files
  • List File Entries
  • Delete File Entries
  • Read File Entries
  • Read Binary File Entries
  • Much More.

BL-447 java.math.BigInteger caster

We had a BigDecimal caster, now we have a BigInteger caster. Not only that, we can correctly coerce Java interop calls for BigDecimal and BigInteger.

Improvements

BL-433 Allow the incorrect foo..bar syntax that Adobe allows for

BL-446 Cache sets() and getOrSets() does not accept duration in seconds alongside Duration objects.

BL-455 Enhance ClassMetadataVisitor

BL-468 Enhance feature audit to track QoQ separate

BL-456 Validate var outside of a function

BL-463 Support Adob'e loose comma parsing in their generic tag-in-script syntax

BL-465 Enhance errors for identifiers starting with numbers

BL-470 File And Directory BIFs to auto-expand received paths

BL-431 Support variable starting with number

Bugs

BL-461 Compatible encryption with lucee/acf

BL-462 replace() and replaceNoCase() should accept "one" not "once" for the scope

BL-464 tag comments not parsing inside output tag in template parsers

BL-466 parsing fails with extra whitespace in closing output tag

BL-467 <cfset and <bx:set fail if not followed by a space

BL-472 Debugger breakpoints not working regression

BL-473 BoxLang Error is not readable

BL-454 Tag island Templating outputs in unexpected order

Add Your Comment

Recent Entries

Ortus Solutions Returns to CFCamp as Platinum Sponsor – Join Us to Redefine the Future with BoxLang!

Ortus Solutions Returns to CFCamp as Platinum Sponsor – Join Us to Redefine the Future with BoxLang!

We’re thrilled to announce that Ortus Solutions and BoxLang will once again join CFCamp as Platinum Sponsors for the 2025 edition. As passionate advocates of innovation in the CFML and modern JVM space, we’re proud to keep pushing boundaries—and this year is shaping up to be our biggest presence yet.

Day 1 Keynote by Luis Majano

CFCamp 2025 will kick off with a keynote delivered by none other than our CEO and BoxLang creator, Luis Majano. Join...

Cristobal Escobar
Cristobal Escobar
April 25, 2025
Must-See Into the Box 2025 Sessions for CommandBox Users!

Must-See Into the Box 2025 Sessions for CommandBox Users!

Power Up your CommandBox experience and practices at Into the Box 2025

Want to get hands-on with the new CommandBox features or learn how others are pushing it to the next level? These are the must-see sessions at ITB 2025 if you're a CommandBox user:

Maria Jose Herrera
Maria Jose Herrera
April 21, 2025
Must-See ITB 2025 Sessions for TestBox Users!

Must-See ITB 2025 Sessions for TestBox Users!

Are you a fan of TestBox or looking to level up your testing game in 2025? Whether you're just getting started with unit testing or you're already building advanced specs for ColdBox and BoxLang apps, Into the Box 2025 has an exciting lineup tailored just for you. Into the Box 2025 has an exciting lineup tailored just for you. With the recent launch of TestBox 6.3.0 we have amazing new tools, features and tips and tricks to get your testing experience to the next level, review our sessions and test like a pro efficiently and easy!

From hands-on testing strategies to BoxLang innovations, here are the sessions you won’t want to miss this May — and why they matter to you as a TestBox user.

Maria Jose Herrera
Maria Jose Herrera
April 17, 2025