Skip to content

Xel v0.13.0

Latest
Compare
Choose a tag to compare
@github-actions github-actions released this 09 Jun 12:13
· 6 commits to master since this release

Xel Runtime v0.13.0 Release Notes: Introducing the xel:object Module for Powerful Object Manipulation and Enhanced Core Stability!

We are excited to announce the release of Xel v0.13.0! This release marks a significant step forward in Xel's data manipulation capabilities with the introduction of the brand new xel:object module. This module empowers you to dynamically create, manipulate, and query objects, a fundamental data structure, directly within your Xel scripts.

Before v0.13.0, while Xel supported creating object literals (e.g., { hello: "world" }), there was no way to directly manipulate these objects using built-in functions. The xel:object module fills this critical gap, significantly enhancing the flexibility and expressiveness of the language.

Building on previous feature modules such as xel:time in v0.8.0, xel:threads in v0.9.0, xel:native in v0.10.0, and on OOP support via v0.12.0's integrated class system, this release represents the next evolution in Xel's core capabilities.

Beyond the new xel:object module, this release incorporates essential bug fixes addressing object comparison and string representation, greatly improving the stability and reliability of Xel.

🚀 Major Features & Enhancements

  1. New Native xel:object Module: Empowering Dynamic Object Manipulation!

    • Purpose: Provides a comprehensive suite of functions for creating, modifying, and querying object literals.

    • Availability: Access these capabilities via import("xel:object").

    • Functions:

      • object.create([initialObject]): Creates a new, empty object. Optionally, you can initialize it with properties from an existing object.

      • object.set(obj, key, value): Sets the value of the property key on the given object obj. If the key doesn't exist, it's added. If value is omitted, the property key is set to nil.

      • object.get(obj, key): Retrieves the value of the property key from the object obj. Returns nil if the property doesn't exist.

      • object.keys(obj): Returns an array containing all the keys (property names) of the object obj as an array of strings.

      • object.values(obj): Returns an array containing all the values of the properties in the object obj. The order corresponds to the order of keys returned by object.keys().

      • object.delete(obj, key): Removes the property key from the object obj. Returns the object. If the property didn't exist, nothing happens.

      • object.has(obj, key): Checks if the object obj has a property with the name key. Returns true if the property exists, false otherwise.

      • object.merge(obj1, obj2): Creates a new object that is a combination of obj1 and obj2. Properties in obj2 overwrite properties in obj1 if they have the same key. The result is a merged object, not a modification to the original.

      • object.clone(obj): Creates a new object that is a shallow copy of obj. Changes to properties in the cloned object will not affect the original. This ensures that data is copied, not simply referenced.

      • object.pick(obj, keys): Creates a new object containing only the properties specified in the keys array. If a key doesn't exist in obj, it's simply omitted from the result. This is useful for creating subsets of object properties.

      • object.omit(obj, keys): Creates a new object containing all properties from obj except those specified in the keys array. This is the inverse of object.pick.

      • object.entries(obj): Returns an array of arrays, where each inner array represents a key-value pair. The first element of each inner array is the key (a string), and the second element is the corresponding value. This is useful for iterating over object properties.

      • object.isEmpty(obj): Checks if the object obj has any properties. Returns true if it's empty, false otherwise.

      • object.equal(obj1, obj2): Performs a deep comparison of obj1 and obj2. Returns true if the objects are structurally identical (same keys and values), false otherwise.

    • Examples:

      • The example/box/main.xel script provides a fundamental introduction to the xel:object module, demonstrating core functions like creating, setting, getting, and deleting properties.
      • The example/box/extended.xel script showcases a wider range of functionality, including merge, clone, pick, omit, and other functions, and helps developers unlock the full power of Xel's object handling.

🛠️ Improvements & Fixes

  • Critical Fix: Accurate Object Comparison (equalRuntimeValues.go)

    • Problem: Previous versions of Xel had a bug in the equal() function, which caused incorrect comparisons of objects, especially when they contained nested objects.
    • Solution: The internal equalRuntimeValues function, which underpins object.equal(), has been completely rewritten to recursively compare object properties, ensuring accurate deep comparisons.
    • Impact: The object.equal() function is now reliable for comparing objects, even with complex nested structures.
    • Recommendation: We highly recommend upgrading to this version to avoid potential errors in object comparisons.
  • Preventing Infinite Loops in Object Printing (stringify.go)

    • Problem: As with other languages, the internal stringify function (used by print() and other functions that convert values to strings) could enter an infinite recursion loop when attempting to print objects with circular references (where an object contains a reference to itself, directly or indirectly).
    • Solution: We've implemented cycle detection in the stringify function. When a circular reference is encountered, stringify will now output a "[Circular *n: path]" message indicating the circular dependency's origin instead of crashing the runtime. The depth is also limited to prevent stack overflows, displaying "[Maximum depth exceeded]" if reached.
    • Impact: Xel can now gracefully handle objects with circular references without crashing.

Core Runtime & Architectural Changes

  • Integration of the new xel/modules/object package as a built-in native module, immediately accessible via import("xel:object").

Upgrade Notes

  • This release includes a major new module (xel:object) and crucial bug fixes.
  • No breaking changes are expected for existing scripts. However, please review object comparisons if you are using the object.equal() function, as the behavior is now significantly more accurate.

Getting Started

  1. Update to Xel v0.13.0: Download the latest binary from our GitHub Releases page.
  2. Explore the xel:object Module:
    • Add const object = import("xel:object") to your scripts.
    • Start with the example/box/main.xel script to understand core functionalities. Then, explore example/box/extended.xel for advanced usage patterns.
  3. Review Object Comparisons: If your existing scripts use the equal() function, ensure that they are working correctly with the improved comparison logic.

Acknowledgements

A huge thank you to @dev-kas for the continued dedication to improving Xel, especially for the development of the xel:object module and the critical bug fixes in this release!


Xel v0.13.0 empowers you with powerful object manipulation capabilities and delivers enhanced core stability. We are incredibly excited to see the innovative solutions you'll build with these new tools! Happy scripting!