# 1.0.0-Beta11

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!

## New Features

### [BL-236](https://ortussolutions.atlassian.net/browse/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](https://ortussolutions.atlassian.net/browse/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

```ini
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:

```ini
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):

```ini
n = 1_0_0_0_0_0_0_0_0_0
```

You can also place numeric separators in decimals

```ini
n = 3.141_592_653_59
```

and in the exponent of scientific notation

```undefined
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](https://ortussolutions.atlassian.net/browse/BL-457) Add static assignment modifier

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

```java
static foo = "bar"
```

which is sugar for

```java
static.foo = "bar"
```

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

### [BL-458](https://ortussolutions.atlassian.net/browse/BL-458) Add final modifier to classes

You can now use the `final` modifier in your classes

```java
final class {}
```

which is sugar for:

```java
class final {}
```

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

### [BL-459](https://ortussolutions.atlassian.net/browse/BL-459) final modifier for UDFs

Your UDFs can now also be declared as `final`

```java
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**.

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

### [BL-460](https://ortussolutions.atlassian.net/browse/BL-460) Add final assignment modifier for variables

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

```java
final foo = "bar"
```

this, of course, can be used with other modifiers

```java
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

```java
final lockDown = [ 1, 2, 3 ].toUnmodifiable()
```

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.

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

```

### [BL-469](https://ortussolutions.atlassian.net/browse/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 :zap:

### [BL-438](https://ortussolutions.atlassian.net/browse/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](https://ortussolutions.atlassian.net/browse/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](https://ortussolutions.atlassian.net/browse/BL-433) Allow the incorrect foo..bar syntax that Adobe allows for

[BL-446](https://ortussolutions.atlassian.net/browse/BL-446) Cache sets() and getOrSets() does not accept duration in seconds alongside Duration objects.

[BL-455](https://ortussolutions.atlassian.net/browse/BL-455) Enhance ClassMetadataVisitor

[BL-468](https://ortussolutions.atlassian.net/browse/BL-468) Enhance feature audit to track QoQ separate

[BL-456](https://ortussolutions.atlassian.net/browse/BL-456) Validate var outside of a function

[BL-463](https://ortussolutions.atlassian.net/browse/BL-463) Support Adob'e loose comma parsing in their generic tag-in-script syntax

[BL-465](https://ortussolutions.atlassian.net/browse/BL-465) Enhance errors for identifiers starting with numbers

[BL-470](https://ortussolutions.atlassian.net/browse/BL-470) File And Directory BIFs to auto-expand received paths

[BL-431](https://ortussolutions.atlassian.net/browse/BL-431) Support variable starting with number

## Bugs

[BL-461](https://ortussolutions.atlassian.net/browse/BL-461) Compatible encryption with lucee/acf

[BL-462](https://ortussolutions.atlassian.net/browse/BL-462) replace() and replaceNoCase() should accept "one" not "once" for the scope

[BL-464](https://ortussolutions.atlassian.net/browse/BL-464) tag comments not parsing inside output tag in template parsers

[BL-466](https://ortussolutions.atlassian.net/browse/BL-466) parsing fails with extra whitespace in closing output tag

[BL-467](https://ortussolutions.atlassian.net/browse/BL-467) \<cfset and \<bx:set fail if not followed by a space

[BL-472](https://ortussolutions.atlassian.net/browse/BL-472) Debugger breakpoints not working regression

[BL-473](https://ortussolutions.atlassian.net/browse/BL-473) BoxLang Error is not readable

[BL-454](https://ortussolutions.atlassian.net/browse/BL-454) Tag island Templating outputs in unexpected order
