After having survived the Mayan apocalypse and just before the year ends, and the US economy falls from the fiscal cliff into the pit of recession, here is a quick look at thirteen features of DWScript, so you don’t come into 2013 unaware 🙂
1. Supercharged memory management
ARC is trendy, but introduces cycles and weak references hell, GC is cool, but garbage collections stalls aren’t, deterministic memory management is fast and deterministic, but verbose and error-prone.
Why not have them all at the same time work together instead? That’s what you get in DWScript: ARC for immediate releases in simple cases, GC to collect cycles and avoid the weak reference, and manual deterministic release when you need it.
2. First-class dynamic arrays
Dynamic arrays are strongly typed, first-class dynamic arrays have methods to Add, Delete, etc. like a (T)List<T>.
And where automatic memory management absolves you from destructors most of the time, true dynamic arrays absolve you from requiring constructors for list and LIFO queues.
3. Type-inferenced variables
Why manually specify the type when the compiler can infer it for you and you get a strongly typed variable?
“var a := 2;” is the same as “var a : Integer; … a := 2;” would be in Delphi.
4. Combined field declaration and initialization
Also type inferenced, fields default values can absolve you from having to write a constructor in trivial cases.
5. Multiple helpers per type
Helpers aka extension methods can be a powerful way to add functionality to existing types. Having a limit of one-helper-per-type hamstrings them.
6. Multi-line strings
Whatever your strings or constants are used for, sometimes they need to span more than one line. When that happens, being able to absolve yourself from concatenating an obscure #13#10 is nice. Having a syntax that will allow you to properly indent those strings without introducing spurious indentation in the string is even better.
7. Lambda syntax
This applies to SmartPascal, where closures and anonymous methods are common, by leveraging type inference and a less verbose, yet not operator-soupy syntax, you can have a syntax far more compact, yet still statically and strongly typed. Enough to make one happy.
8. Custom language extensions
Sometimes it would be nice to introduce custom construct into your source code, with DWScript’s language extension mechanism you can do just that and take over the parser for a section of code, can be used to introduce asm or JSON capability.
9. Unicode-safe strings and iterations
Because sooner or later you’re going to end up parsing Chinese and your 16-bit-characters assumption are going to haunt you. Having Unicode-aware loops and no 8-bit or 16-bit Char type in the language avoids that.
10. Unified function pointers / delegate
Because life is too short for procedure vs procedure of object vs reference to procedure. Let the compiler figure it out.
11. Compile-time function evaluations and constant expressions
When something is constant, it’s constant, no? DWScript lets you use constant expressions to define constants, so that you can have a constant defined by just “Sin(PI/4)” rather than a magic number plus a comment to explain what that magic number is.
12. Partial classes
Partial classes allow you to support automatically-generated code more easily, including code generated from compile-time type information, or just make your classes more extensible, by design.
13. Deprecated
Feature #13 got deprecated and isn’t available anymore.
14. Being able to compile to HTML5+JavaScript
With SmartMobileStudio, Make your business logic cross-platform, cross-terrain and as ubiquitous as it can get these days. Run in mobile or desktop browsers, run server-side with node.js, or client-side with node-webkit as runtime environment.
I was just thinking how awesome it would been if these features would’ve been added to the Delphi compiler.
So, Eric, when will you apply for a position in the compiler team at Embarcadero? 🙂
How does point 11 work? Sin() is a pure function that will always return the same value for the same input, but how does the compiler know which functions are pure and which aren’t?
Currently it knows because you tell it, mainly through the iffStateLess flag for RegisterInternalXxxFunction.
It’s currently not available for functions declared in scripts, mostly because I still haven’t settled on how to best handle that. I would ideally want it to encompass functions you explicitly want evaluated at compile time even if they are stateful (f.i. to perform compile-time jobs or data retrieval).
At some point the compiler will probably perform it automatically through static analysis in simple cases, ie. when there are no loops and when the result values are simple, as you probably don’t want to automatically run at compile time a function that returns an array with a million decimals of PI f.i., even if that’s perfectly constant and stateless.