Introducing BoxLang : A new JVM language for productivity and modularity!

ortussolutions 252 views 73 slides Jun 22, 2024
Slide 1
Slide 1 of 73
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73

About This Presentation

Just like life, our code must adapt to the ever changing world we live in. From one day coding for the web, to the next for our tablets or APIs or for running serverless applications. Multi-runtime development is the future of coding, the future is to be dynamic. Let us introduce you to BoxLang.

Dy...


Slide Content

The Future is
Dynamic
LED BY
Luis F. Majano

LUIS F. MAJANO
•CEO Ortus Solutions
•Computer Engineer
•Born in El Salvador
•USA since 1995
•Boqueron in progress
•www.ortussolutions.com
@lmajano @ortussolutions

BoxLang is a modular dynamic language for the JVM, aiming
to make your development more productive, expressive,
functional, and available everywhere. 
DYNAMIC : MODULAR : PRODUCTIVE

•New language and runtime for the JVM (Inspired by a polyglot team)
•We are in Open Beta, Stable release in Fall
•Scripting and templating language built-in
•Dynamic language with an optional type system
•Modern Java interop with none of the legacy, verbosity, and limitations
•Highly functional, context-aware closures, pure lambdas and more
•Application Framework with many concerns (events, caching, tasks, scheduling, async, etc)
•Small, lightweight, and modular
•Can reuse any Java or ColdFusion/CFML library
•Easy to learn
What is?

Who we are?

Who we are?
•Ortus is a professional open-source company
•Founded in 2006, USA
•Created all the major frameworks for the CFML eco-system
•Package manager, CLI, MVC, DI/AOP, Testing TDD/BDD, etc
•Manage over 300+ libraries
•18 years of servicing different software communities
•!USA, "El Salvador, and # Spain

•We did not wake up one day and said “Let’s make a language.”
•We are not that crazy! Well…. Maybe a little $
•The culmination of 18 years of open-source development
•We could not continue to innovate and create under current language vendors
•We need a way forward for us at Ortus, our clients, and community
•Dynamic languages on the JVM had not evolved recently
•A language of the times
Why?

Goals & Vision

Goals & Vision
•Be dynamic, modular, lightweight, and fast
•Be 100% interoperable with Java
•Be modern, functional, and fluent
(Think mixing CFML, Node, Kotlin, Java, and
Clojure)
•Modularity at its core
•Take advantage of the modern JVM
•TDD: Fully tested source code
•Be able to support multiple runtimes
•Have multiple transpilers
CFML -> BoxLang,
Groovy -> BoxLang
X -> BoxLang
•IDE and Tools
•Compete in today’s language environments

Key Features

Multi-Runtime Architecture

Multi-Runtime Architecture
Any OS
Docker MiniServerCommandBox Servlet Lambda Azure Android WebAssembly
Coming Soon Coming Soon Coming Soon
6 MB
9 MB 6 MB15 MB15 MB160 MB

AWS Lambda Runtime

try.boxlang.io

Wanna play?
•try.boxlang.io
•Internet playground for BoxLang
•First Production BoxLang application
•Powered by our AWS Lambda Runtime
•Skinnable
•Embeddable on any Site (Soon)

Wanna play?
64MB RAM
600 KB
6.5MB
<Your
Code>

AWS Lambda Runtime
•Every request can fire up its very own Lambda request
•That means:
•We never have to worry about how many instances we have
•We never have to worry about queueing
•We never have to worry about bad actors accessing other people’s files
•We can easily update our Lambda runtime and all instances will be
running new code
•Lambdas have tiers too (staging, production, development)
•Scale up as big or as small as we want

BoxLang Semantics

File Types

Scopes
// scripting + templates
name = “boxlang”
// Functions have a local + arguments + surrounding scopes
function save( name ){
var transactional = true
// pass scopes around
saveData( arguments )
}
// Treat scopes like maps
function getMemento(){
return variables
.filter( key, value -> !isCustomFunction( value ) )
}
// Classes have three encapsulation scopes
Class{
this.publicVar = “public”
variables.privateVar = “private”
static.field = 123
}
•All variables are inside of scopes
•Scopes backed by concurrent maps
•Each execution context can have different scopes
•Scripts
•Variables
•Functions
•Arguments, local, + surrounding scopes
•Classes
•This (public), variables (private), static
•Global Scopes
•Application, request, server, session, etc

Enhanced Types with Member functions
fruits = [ "apple", "bananas", "pears" ]
println( fruits.len() )
data = fruits
.append( "orange" )
.filter( item -> item.findNoCase( "an" ) )
.each( item -> println( item ) )
.toJSON()
"apple,bananas,pears"
.listToArray()
.filter( item -> item.findNoCase( "an" ) )
.each( item -> println( item ) )
person = { fname: "box", lname: "lang", age: 1 }
person.fullName = () => person.fname & person.lname
println( person.fullName() )
•All Java types plus:
•Arrays (1 based index - Human Based)
•Structs (ordered, unordered, weak, soft, etc)
•Queries (Typed Columns)
•DateTime (java.time)
•Numeric (float, short, int, double, bigdecimal)
•XML (Enhanced Maps)
•All auto-castable, dynamic and functional
•Fluent and Functional via member functions

Functions
// Java
public int sum( int a, int b){
return a + b;
}
// BoxLang no types
function sum( a, b ){
return a + b
}
// Optional types
Numeric function sum( numeric a, numeric b ){
return a + b
}
int function sum( int a, int b ){
return a + b
}
•All functions `public` by default
•All return types `any` by default
•All argument types `any` by default
•What is any????
•2 types of type inference
•Compile-Time
•Runtime
•Auto-casting
•Type promotions
•Type Coercion

Functions Arguments
// Java
Public void repeat( String str, int count, String separator ){}
repeat( “hello”, 2, “;” )
// BoxLang
repeat( required str, count:5, separator=“;” ){}
// Call with defaults
repeat( “hello” )
// Call with argument binding
myMap = { str : “test”, separator : “,” }
repeat( argumentCollection:myMap )
•Required arguments
•Default values
•Argument binding
•Structs (Maps)
•Arrays

Functions Variables
// Java
int a = 1;
String b = “xyz”;
Map test = new HashMap();
List<String> myList = new ArrayList();
// BoxLang
var a = 1
b = “xyz”
map = { age : 0, today : now() }
myList = [ “1”, 2, “3”, 4 ]
orderedMap = [ age : 0, today : now() ]
anotherFunction( local )
•No need to `var` in functions (automatic)
•All go into a `local` scope
•Inferred variables
•Mix types if you want
•Struct and array literals
•Ordered Struct literals

Variable re-assignments
// Java
int age = 30;
age = “MyAge”; // ERORR
// BoxLang
age = 30
age = “Thirty Years Old!”
final age = 800
•Variable re-assignments
•Changing values and types are ok!
•Unless you mark them as `final`

Variable casting
// Java
String name = (String) myMap.get( key );
Double seconds = 4;
Instant.now().toSeconds( seconds.toLongValue() );
// BoxLang
name = myMap.get( key )
println( name )
seconds = 4
Instant.now().toSeconds( 4 castAs “long” )
•Auto-casting detection
•Explicit casting if needed
•castAs operator

Variable Immutability/Mutability
myArray = [1,2,3,4]
myArray.append( more data )
myAsyncFunction( myArray.toImmutable() )
println( myArray )
myArray.toMutable().append( “hello” )
•`toImmutable()` memember method
•`toMutable()` as well
•Arrays
•Queries
•Structs

Null Coalescene Operator ?:
// Java
Int getLength( String myString ){
if( myString != null ){
return myString.length()
}
return 0;
}
function getLength( myString ){
return myString.length() ?: 0
}
•Any falsey expression can be used
•Entire left hand expression detection

String Interpolation
function toString(){
return “Song{id=“#id#”, title=“#title#”, author=“#author#”}
}
function buildTemplate(){
return “””{
Id : “#id#”,
Title : “#title#”,
Author : “#getAuthor(id)#”
}“””
}
myMap = { id: createUUID(), title: “title”, author: “Luis” }
buildTemplate( argumentCollection : myMap )
•Tired of string concatenation
•Not anymore!
•Anything between #expression#
•“”” For big strings!
•Combine with scopes to do bindings!

Closures & Lambdas & UDFs
function toString(){
return “Song{id=“#id#”, title=“#title#”, author=“#author#”}
}
variables.toString = variables. getString
function delayFunction(){
return () => dowork()
}
runAsync( () -> startWork() )
.then( result => computeMoreWork( result ) )
.then( result => sendOrder( result ) )
•Context-aware closures
•Pure functions: lambdas
•UDFs

Classes in Java are verbose

Ok, really verbose

Classes
Ok, mega verbose!

Classes
Class{
Property firstName;
Property lastName;
Property numeric age setter=false;
}
Person = new Person( “Luis”, “Majano”, “45” )
println( person.getFirstName() )
person.toJSON()
•Automatic constructor
•Automatic toString(), equals() and hashCode()
•Automatic getters and setters
•Automatic toJson()

$bx - MetaProgramming
Person = new Person()
writedump( person.$bx.meta )
callJavaClass( person.$bx.$class )
Class{
Property importantData;
Variables
.$bx
.registerChangeListener (
“importantData”,
(Key, newValue, oldValue) => clearCache()
)
}
myMap = { name : “Luis”, born : now() }
myMap
.$bx
.registerChangeListener ( (key, newValue, oldValue) => doSomething() )
•Available on ANY object
•Includes
•Metadata
•Class Representation
•Meta Methods
•Change listeners
•Inject properties
•Remove properties
•Inject methods
•Remove Method

Templating Language
•Made CFML famous
•Best of JSP, Blade and ColdFusion/CFML
•Create your own `<bx:MyTag>` easily
•Import collections of tags
•Use BIFs
•Nesting
•Data Encapsulation
•Much More
<bx:output>
<div class="bx-dump">
<table class="bx-tableSt" title="#posInCode#">
<caption
class="bx-dhSt"
role="button"
tabindex="0"
open
>
<strong>Query: #var.recordcount# rows<strong>
<caption>
<thead>
<tr>
<bx:loop array="#var.columnList.listToArray()#" item="column">
<th>#encodeForHTML( column )#<th>
<bx:loop>
<tr>
<thead>
<tbody>
<bx:loop query="#var#" item="row">
<tr>
<bx:loop array="#var.columnList.listToArray()#" index="column">
<td>#encodeForHTML( var[column] )#<td>
<bx:loop>
<tr>
<bx:loop>
<tbody>
<table>
<div>
<bx:output>

h}xnimport prefixrbjKvKb nKmerbortusc}oxlKngcruntimectypescex`eptionscLx`eptionBtilb0
h<vvv !hrowK}le templKte vvv0
h}xnoutput0
h}xnset is.1Lrror r vKr instKn`eof bortusc}oxlKngcruntimectypescex`eptionsc.oxMKngLx`eptionb0
htK}le }orOerrtst `ellpKOOingrt"t `ellspK`ingrtat titlerbxpos)nwoOexb0
h}xnif is.1Lrror0
htr0hth `olspKnrb=b0Lrrorn xen`oOeTor(!qMp vKrcget!ypep> >xhth0htr0
h}xnelse0
htr0hth `olspKnrb=b0Lrrorn xvKrcgetwlKssp>cget[Kmep>xhth0htr0
h}xnif0
htr0htO0qessKgehtO0htO0xen`oOeTor(!qMp vKrcgetqessKgep> >xhtO0htr0
h}xnif is.1Lrror0
htr0htO0/etKilhtO0htO0xen`oOeTor(!qMp vKrcget/etKilp> >xhtO0htr0
htr0htO0!Kg wongtexthtO0htO0
h}xnOump vKrrbxvKrcget!Kgwontextp>xb0
htO0htr0
h}xnif0
h}xnif vKrcgetwKusep> <r null 0
htr0htO0wKusehtO0htO0
h}xnOump vKrrbxvKrcgetwKusep>xb0
htO0htr0
h}xnif0
htr0htO0UtK`k!rK`ehtO0htO0
hpre0xen`oOeTor(!qMp Lx`eptionBtilcgetUtK`k!rK`eysUtringp vKr > >xhpre0
htO0htr0
htK}le0
h}xnoutput0

thewolle`tion r vKrC
ifp vKr instKn`eof twA)U`opet > {
thewolle`tion r vKrcget/umpHeysp>C
}
for p key in thewolle`tion > {
{{{
h}xnif []! iswustomTun`tionp vKr[ key ] > 0
htr0
hth
s`operbrowb
`lKssrb}xvOhUtb
vKlignrbtopb
0
xen`oOeTor(!qMp key >x
hth0
htO0
h}xnset Oumpp vKr[ key ] > 0
htO0
htr0
h}xnif0
{{{
}
Tag Islands
•Template anywhere in script
•Leverage the ```
•Great for emails, templating, you name it

BoxLang Framework

BoxLang Framework
RUNTIME
Application
Service
Async
Service
Cache
Service
Component
Service
Datasource
Service
Function
Service
Interceptor
Service
Module
Service
Scheduler
Service

Enterprise Caching Engine & Aggregator

Enterprise Caching Engine & Aggregator
•Inspired by CacheBox
•Enterprise Caching Engine
•Extensible
•Custom providers
•Custom object stores
•Listeners
•Stats
•Powers all internal caching

Application Framework

Application Framework
•Inspired by Java contexts
•Create infinite segregated applications in a single deployment by using one file
•Application.bx
•Life Cycle methods:
•applicationStart(), applicationEnd(), sessionStart(), sessionEnd(),
requestStart(), request(), requestEnd(), onError(), etc.
•Data Sources, class loading, application scopes, security, settings, etc.
•Sub applications
•Highly configurable and Highly portable

Scheduling & Task Framework

Scheduling & Task Framework
•Schedulers are portable, fluent, and human
•Write them in BoxLang or Java
•Task & Completable Futures framework from the JDK
•Access to any executor in Java
•Run schedules at the OS
•Importer from Adobe/Lucee (Soon)
•Task Visualizer (BoxLang Admin, BoxLang Debugger)

Modern Dynamic Language

Modern Dynamic Language
•Dynamically typed just like CFML, but we go further…
•JDK21+ Minimum
•Fully JSR-223 Compliant
•Clojure + BoxLang in development by Sean Corfield
•No reflection, we use InvokeDynamic for everything
•DynamicObject: Any Object can be Dynamic!
•All OO Constructs
•Interfaces, superinterfaces and default method implementations
•Abstract classes and methods
•Static scope and methods on classes and interfaces
•Use all-new JDK features and types
•Collection of Dynamic Casters and Helpers

BoxLang Tooling

Tooling Overview

Tooling Overview
•BoxLang IDE
•Language Debugger & LSP
•Run classes with a main()
•Run Scripts
•Run / Manage Servers
•Code Converters, Code Formatters
•Code Quality
•Visualizers

Tooling Overview
•CLI Tools
•REPL: CLI code execution
•Shebang Scripts: #!/usr/bin/env boxlang
•File Runner: Run files
•Schedule Runner: Run schedulers
•Transpiler: Convert CFML to BoxLang
•Compiler: BoxLang to Bytecode
•Feature Audit: BIF and Tag report usage
•Packager: Compile and package your modules or BoxLang apps

Tooling - BoxLang IDE
•Modern development flow
•Inline documentation
•Webservers panel
•Works for BL and CFML
•Run BL/CF code directly within VSCode
•Debugger & Language Server
•Committed to ongoing support and development -
new features are on the way!

Tooling - BoxLang Debugger
•Purpose built
•Integrates with VSCode via Microsoft’s DAP
•Can debug both the CLI runtime and web
server
•You’ll never use  writeDump()  again!

Tooling - BoxLang Language Server
•Built with BoxLang!
•The BoxLang runtime was built with the LSP in mind
•Full access to the BoxLang syntax parser/compiler
•Access to all BoxLang configuration, datasources,
mappings, etc…
•Extensible via BoxLang modules
•Foundational for modern language toolchains
•Intellisense
•Static analysis
•More coming soon…

Java Interop

Java Interop
•Interact with Java naturally
•It’s just part of the language; no more
separation
•Type inference, auto-casting, type
promotions and coercion
•Long -> Doubles, Doubles ->Longs, etc
•BoxLang Function -> Java Lambdas
•You can import, extend, implement, annotate
from Java
Java Interop

Java Interop
•Concept of object resolvers: java, bx, custom
•New BoxLang Scripting: MyScript.bxs
•Components become Classes: MyClass.bx
•All bx/bxm/bxs are runnable via the OS
•Classes can have a main() runnable
convention
•BoxLang annotations
Runnable Classes

Multi-Parsers

Multi-Parsers : BoxLang + CFML + ???
•Our way to split with the old and bring in the new
•Transpile CFML into BoxLang
•BoxLang is a NEW clean slate
•Compat module for Adobe/Lucee
•Multi-Step Compiler
•Bx -> Java Source -> ByteCode (DebugMode)
•Bx -> Bytecode (Almost done)
•In Planning
•Groovy to BoxLang
•??? To BoxLang
Choose your path wisely!
.cfc, .cfm
.bx, bxs, bxm

BL-AST
•AST Visitors for custom tooling
•Feature Audits
•Transpiler
•Pretty Printer
•Code Quality
•getClassMetadata()

Event-Driven Language

Event-Driven Language
•Interceptors for the language, application, and request
•The best way to scale the language
•Listen to the entire or specific language life-cycles
•Modules can listen/collaborate events
•boxAnnounce(), boxAnnounceAsync() : CompletableFuture
Event Channels
Event Producers
Event
Event
Event
Event Consumers
Event
Event
Event

Tested & Documented

Tested & Documented
•TDD/BDD at the core of the language
•3500+ Tests Already
•Test not only Java but BoxLang
•Native BoxLang Assert constructs built-in
•Fully Documented
•Generated API Docs
•boxlang.ortusbooks.com

Modular Since Birth

Modular Needs
Modern Runtimes Have Various Needs!

( and CFML/PHP/Python/Ruby/Etc paradigms are outdated )
•Web Applications - HTTP Request/Response Data
•Tasks and Queues - Watchers, Event Handling, Async
•Lambda and CLI - fast start and blazing speeds!
•iOS/Android - Low resource footprint, event handling
•Web Assembly – Transpilation and Sandboxing

BoxLang Modules
•Inspired by our HMVC Framework: ColdBox
•Core Runtime with lightest possible footprint
•Taps into the language life-cycle
•Write them in Java or BoxLang or Both!
•Executable as CLI packages
•Integrates with Maven/Gradle

BoxLang Modular By Design!
•Modular ecosystem, delivered by FORGEBOX (www.forgebox.io)
•Core modules for DBMS’, Alternate Runtimes ( e.g. Lambda ), Mail,
Encryption, CFML compatibility and more!
•Write your own functions, components ( tags ), schedulers, JDBC
Drivers, interceptions and more!
•Module has an isolated class loading machinery
•Boundless potential for community contribution and engagement!
•Foment third-party vendors
•FORGEBOX eCommerce Marketplace later this year

BoxLang Extends BoxLang
Influence core runtime behavior with BIFs, 

Member Functions, Tags, Interceptors, and More!

But there’s more!
•BoxLang is fully JSR-223 Compliant and Modular
•Allows ANY Java language to embed and use BoxLang
•Allows ANY JSR-223 compliant language to run in BoxLang
•Power of Modules: bx-jython
•Full Python runtime embedded into BoxLang
•Script, load python classes, modules, etc.

BoxLang Modules
Take control of your own runtime,
in your own language!

THANK YOU