sponsor Vim development Vim logo Vim Book Ad

The ObjectSense Programming Language : An object-oriented reincarnation of VimL

 script karma  Rating 8/2, Downloaded by 225  Comments, bugs, improvements  Vim wiki

created by
Yiu Wing
script type
ObjectSense is a superset of VimL8, and has all the main features of a modern object-oriented language, such as data encapsulation, polymorphism, inheritance, etc.  On top of the language implementation, rose - a module manager is provided, which is also built into the language runtime.  It's very developer friendly, especially for those who already have a working knowledge of VimL8 can effortlessly expand their skills to code in ObjectSense.  

As a bonus feature, polyglot programming is easily doable in ObjectSense.  Currently vim8 and vim9 are supported, with minimal work the list can grow longer to include other languages, such as, python, ruby, lua, etc.  However, as far as the operating system is concerned, only Linux and MacOS are supported at the moment.  There is a user-defined command, UT, for doing unit tests of the current class.  It's very convenient for accessing class data in unit tests.  No need for finding workaround to the language barrier when accessing such data in white box testing.  Every component can be properly tested! Pure and simple!  By following a few simple conventions and thanks to the built-in modular mechanism in the language runtime, ObjectSense programs are very scalable and development work can be distributed comfortably among team members.

In a more programming linguistic point of view, ObjectSense is of imperative paradigm on the surface, but carries functional programming abilities.  In the language runtime, each object has its own data and functions, there's nothing shared.  An object is entirely in its own universe just like functional programming.  Because the lack of time, we haven't explored such property of the language much.  Hopefully, the community can shed new lights on such nice combination.

This is a strong demonstration of what VimL8 is capable of.  ObjectSense takes less than 5000 lines of code for the core of the language implementation.  Although it's a superset of an existing language, it's very hard to imagine using such little code for implementing a non-trivial programming language.  VimL8 has a lot of unrealised potentials, people really shouldn't jump off the bandwagon too quickly.

The best argument for vim9 is performance.  We have found a way kind of 'compile' or speedup the load time for ObjectSense. In practice, we could really compile such code into binary and wire it with the language runtime, and without asking developers to learn a completely new language, i.e., being 100% compatible with existing VimL8 syntax and have the acclaimed performance at the same time.  However, in our scenario ObjectSense performance issues have been tackled by the semi-compile approach, so no effort was directed to do the real compiling work which could bloat the code base exponentially.

Please download and untar the tarball, start from object/doc/readme.txt.
install details
1.  move the downloaded tarball to ~/.vim directory, and untar it
        mv onecloud-object-sense.tar.gz ~/.vim
        cd ~/.vim
        tar -xvf onecloud-object-sense.tar.gz

2.  open .vimrc and add a line
        so ~/.vim/object/ObjectSense.vim

3.  add the following in .vimrc for doing ObjectSense development
        const g:OBJECT_SENSE_DEV = 1

4.  to get a taste of the language, check out ~/.vim/object/demo subdirectories

rate this script Life Changing Helpful Unfulfilling 
script versions (upload new version)

Click on the package to download.

package script version date Vim version user release notes
onecloud-object-sense-2.0.0.tar.gz 2.0.0 2023-09-03 8.2 Yiu Wing This is a tremendous update, which really takes ObjectSense into another level and no other language has done before!  It can be the ultimate form of literate programming or even beyond literate programming.  We started out doing object-oriented programming in vimL, never thought would end up anything like this.

Now we can have functional, procedural, object-oriented, imperative, declarative, or any existing programming paradigms under one host language - vimL.  Polyglot programming can be as easy as abc.

A new directive Let is added to the language.  As a result, we no longer need to have CreateInstance calls when creating new objects.  Thusly, making ObjectSense very clean from vimL, only ObjectSense directives and annotations are required when expressing the language. Also there are other new directives added to aid with day to day programming chores from this release.

1.  A new programming construct called micro is introduced.  This feature is
    conceptually like lisp macro, which blends in the host language seamlessly
    and extends linguistic functionality on source code level.  Because the
    name macro is already taken by vim to mean something else, in order to
    avoid confusion and make the distinction of lisp macro, the word 'micro'
    is chosen to depict a small piece of code that can have special
    interpreting meaning other than the host language, which is vimL in here.

    However, unlike other lisp-like macros, there's no AST involve in our
    micro implementation, since vim doesn't use AST at runtime and its parser
    is hand-crafted.  As a result, ObjectSense requires developers to manually
    define the parser, and have the result presented as a vim statement that
    can be executed.  Nevertheless, because there's no host language or AST
    restriction, it can make the DSL much more expressive and have free style
    syntax.  It's a breeze to embed code from any programming language in
    ObjectSense.  VimL already has a tone of built-in functions to deal with
    strings, it shouldn't be too much effort for a workable DSL parser.
    Basically, what the parser does is to take an input of string and convert
    it into a vim statement.  The micro framework will execute the statement
    once it's returned from the parser.

    In lisp-like macros implementations, macros are often compiled, making
    them as effective as the host language.  However, the current
    implementation of micro is not compiled, it has some performance cost.
    Future work is planning to compile ObjectSense into vimL9 instructions
    while retaining it as a superset of vimL8 syntactically.  So vimL9 would
    act some kind of VM just like the famous JVM, and ObjectSense will provide
    compiler tools for micro/DSL implementations that need performance boost.
From a different perspective, micro puts a layer between the host language
    and the guest language, whereas lisp-like macros are sharing the same
    execution context directly with the host language.  Micro provides better
    protection to the host language runtime than traditional APIs and macros,
    because the interface between them are strictly available only through the
    guest language parser.  Also, micros can have richer expressiveness and
    abstraction than APIs and macros.

    In real project practice and as time progresses, it's very easy for APIs
    and macros to leak internal details to the client code.  However,
    abstraction through micro DSL would make it much harder to leak the
    encapsulating data, because they don't share the same runtime.
    Inherently, the side-effects for the usage of micros are much manageable
    albeit not immutable.

    Programmers can define their extensions to the language as they like by
    using micro.  The module dependency mechanism from rose also works with
    micro.  We can export APIs as well as micros in module description file
    Sense.ose.  However, the following example demonstrates only exporting
    micros, no functions, from MyClass.
        export mycompany.business.MyClass
        export mycompany.business.MyClass.!

    For the client code that uses micros from MyClass
        Import! mycompany.business.MyClass

    Notice <bang> or '!' version of Import was adapted to work with importing
    micros from a class.

    To create a new micro called Python with the interpreter defined in
    s:RunPython, we would have something like the following
        Micro Python s:RunPython

        function! s:RunPython(code, extra)
            " just print out whatever was in code
            echo a:code
            return ""

    To run Python micro, we could have,
        Python hello world
    Or define a function that would be interpreted by Python micro,
        Python! s:Greeting()
            This is greeting from python.

        call s:Greeting() "<--- print 'This is greeting from python'

    Variable expansion and string interpolating are taken place before
    invoking the interpreter for the micro.

2.  Introduced Let directive, the first letter is upper case L, for assigning
    and declaring new objects.  We have Dart 2.0 like syntax for create new
    objects with the Let directive.  For example,
        Let object = MyClass()

    This directive let us drop the use of global function CreateInstance, so
    being a superset of vimL, the semantics of the language can be defined by
    the ObjectSense language directives and annotations only, no exposure to
    any functions or other language constructs from vimL.

    The Let directive also supports static constants.  To define a static
    constant we have the following syntax, in Preload
        Class MyClass

        function! s:Preload()
            Let! GLOBAL_VAR = "this is a global variable"

    To access in another class, we have to borrow it first,
        Borrow! MyClass

        Class ClientCode

        function! s:Move()
            echo s:GLOBAL_VAR " <--- prints "this is a global variable"

    The Let directive also supports inline variable.  The following is an
    example use of such construct.
      Class MyClass

        function! s:Preload()
            Let >> context = "http context"

    To use the inline variable context in another class, we will have
        Borrow! MyClass

        Class ClientCode

        function! s:Demo()
            Let << context
            echo context " <--- prints "http context"
3.  Switch statements are supported now, which can take different operators
    which are compatible with vim operator, see :h expr4, there's one more
    operator, instanceof, added to support type checking.
        Switch object instanceof
            Case v:t_string echo "this is a string"
            Case MyClass echo "this my class"
            Default echo "not recognised class from object: " . string(object)

4.  Refine control over module dependency, making the mechanism more workable
    with real-life projects.  Before sourcing ObjectSense.vim, users can set
    g:PRIVILEGED_MODULES variable to allow 3 or less modules that have the
    privilege to add dependent modules at runtime.

5.  For more examples, see demo/micro directory.

6.  The next release will focus on supporting Nvim.  Hopefully, ObjectSense
    can bring vim and nvim plugin developers under the same roof again.
onecloud-object-sense-1.1.5.tar.gz 1.1.5 2023-01-01 8.2 Yiu Wing 1.  Supported the granularity of export level down to each accessible function
    of a class for a module without compromising performance. Three are three
    levels of access rights are supported in module export, namely, they are
    package, class, and function.

    For the export function to work, we have to export its class first, and
    then the function export of a class follows either explicit rule or
    implicit rule.  If there's no explicit rule specified for an export class,
    then all the functions for that class will be implicitly exported.
    Otherwise, only those explicitly specified functions will be exported.

    There are three levels of access controls for a class.  The first one is
    module export which is available for all the modules.  This is equivalent
    of 'open' for Swift.  The next one is internally available within a module
    this is where 'accessible' is specified for a function, which is the
    equivalent of 'internal' for Swift.  The third one is private access
    within a class, for functions that have no 'accessible' annotation
    attached but have a 's:' in front of the function name.

2.  Support adding pluggable commands to rose.  First at all, developer use
    the 'command' attribute to define the command name and command callback in
    Sense.ose.  For example:
        command bundle  mycompany.object.bundle.BundleCommand

    defines a command called 'bundle', and have the BundleCommand in the
    above package as the command callback which inherits a new export class
    object.RoseCommand and implement the details in function s:Execute(...).

3.  Introduced a new export class SenseParser which helps customised attributes
    to be defined by developers to store module specific data or settings.
    This works very much like command attribute.  First at all, define the
    attribute name and the parser to the attribute.
    For example
        parser cockpit  mycompany.object.cockpit.CockpitParser

    define an attribute called 'cockpit', which will have its data parsed by
    CockpitParser.  It has three methods, namely, s:OnCommence, s:Process and
    s:OnCompletion.  The first method is called before the parsing.  The
    second one is called by the framework when parsing each line of attribute
    data.  The final one is invoked when finished parsing Sense.ose file.

4.  Supported export class for inheritance.

5.  Support loading multiple modules in QuickStart.

6.  Added bash command line completion for rose.

7.  Fixed some bugs in module accessibility.

8.  Adding more test cases.                                                      
onecloud-object-sense-1.1.4.tar.gz 1.1.4 2022-09-10 8.2 Yiu Wing 1. 'rose test' is able to give a line-based test coverage report and
    highlight the lines that are not covered by test

    For example, run the test coverage on rose package that comes with ObjectSense,
        cd object
        rose test rose -c
    Open the browser and visit the generated html.

2.  supported polyglot in QuickStart

3.  introduce UnitTestBelow directive which prevents loading unit test code in
     production environment

4.  refactor quite a few number of variable and function names

5.  tighten up some loose logic and fixed a bunch of bugs

6.  provide object.Runtime class to work with the modules at runtime
onecloud-object-sense-1.1.3.tar.gz 1.1.3 2022-08-14 8.2 Yiu Wing Initial upload
ip used for rating:

If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
Vim at Github