Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Summary of recent changes #527

Open
daokoder opened this issue Oct 11, 2016 · 3 comments
Open

Summary of recent changes #527

daokoder opened this issue Oct 11, 2016 · 3 comments

Comments

@daokoder
Copy link
Owner

In the past months, I have put some thoughts in the language and virtual machine, and felt that both can be further simplified and cleaned in some aspects. So I have made some significant changes in both the language and virtual machine.

Changes in the language

The following are the main ones:

  • Removed function decorator and class decorator;
  • Improved concrete interface such that it can replace function and class decorators;
  • Removed support for syntax macros;
  • Removed support for customized processing of verbatim strings;
  • Changed index ranges from close-close to close-open ranges;

In the language, the most important change is the removal of function decorator and class decorator. After I have reconsidered the concrete interface feature, I found that proper use of concrete interfaces (with minor improvements) can emulate decorators to some extent, and considering the decorator is a matter of hacking on functions and classes, I don't think it is really necessary to keep the support for decorator in the language.

Consider the following example,

interface Callable
{
    routine ()( ... );
}
interface Callable for routine
{
    routine ()( ... as args ){
        io.writeln( "Callable<routine<>>()" );
        self( args, ... )
    }   
}

routine Test( par: string )
{
    io.writeln( "Test", par )
}
const T: Callable = Test;

T( "ABC" );

It defines a callable interface with a concrete interface for routine. The concrete interface implements a method that wraps around the routine just in the same way as the previous function decorator. As you can see, this syntax is cleaner than the decorator, and in fact, the internal implementation is also simpler.

There following is an example that (partially) emulate class decorators:

interface TestUnit
{
    routine Run()
}

interface Testing
{
    routine RunTest();
}
interface Testing for TestUnit
{
    routine RunTest(){
        io.writeln( "Testing<TestUnit>::Run()" )
        self.Run();
    }   
}

class OneTest
{
    routine Run(){
        io.writeln( "OneTest::Run()" )
    }   
}

var test: Testing = OneTest()

test.RunTest()

Now the syntax macro feature has also been removed. There are also a number of reasons for this. The two main reasons are that, first, I don't think it is good to allow mixing codes of different syntaxes; second, it has something to do with the visual programming language I am developing, it would be far easier and cleaner to support customized syntax in such visual languages than in purely textual languages. And Dao as the backend of this visual language, it is better to keep it light and clean. The support for customized verbatim processing was also removed for this reason.

Another important change that can affect the existing code is the changing of index ranges from close-close to close-open ranges. Such change has been suggested before, by @Night-walker I think, but at that time I wasn't convinced by its advantage. Now I think it worth making the change.

Changes in the internal implementation

The following are the main ones:

  • Changed DaoTypeBase to DaoTypeCore for type definition;
  • Added type checking and execution functions for standard operations to DaoTypeCore;
  • Added comparison and hashing functions to DaoTypeCore;
  • Added support for sandboxed vm-spaces that share nothing but the common core data and garbage collector;

The change to DaoTypeCore is mainly to make the internal implementation more organized and make it easier and more flexible to implement user defined types. Please see help::daovm.interface.extending for details.

The support for sandboxed vm-spaces is to make it possible to use independent Dao scripting engines in the same application. Also the new implementation DaoTypeCore makes such sandboxing more isolated and allows truly independent module loading (in order to support this, a module just needs to avoid using global variables).

@dumblob
Copy link

dumblob commented Oct 11, 2016

In general I like the changes. But I have few questions.

  1. How do the changes related to decorators (i.e. their removal and extension of concrete interface) affect aspect-oriented programming in Dao?
  2. How does embedding of another language code (e.g. C) directly into Dao code works if there are no verbatim strings any more? Is it still possible? How?

By the way I'm highly interested in the visual language you're working on as I'm looking for something with very good support for flow-based programming for one of my projects. And for performance reasons, the common approach of running e.g. map (in form of a method of an object - e.g. string in Dao) several times in a row with a tiny operation (e.g. io.stdio.read($all).chop().trim().replace('abc', 'def')) highly increases the overhead compared to only one loop and a compound processing in each iteration.

Yet bigger issue is with large data (usually infinite signals on input, i.e. infinite stream of samples) which can't be first read whole to the memory and then processed (as e.g. io.stdio.read($all).change('{{\r\n}}+', '\n').replace('abc\ndef', 'xyz') which would be optimally processed as a finite state automaton on an infinite input). In case your visual language will support flow-based-like programming. I.e. writing something like io.stdio.read().change('{{\r\n}}+', '\n').replace('abc\ndef', 'xyz') would not first finish read(), then start and finish change() and in then start and finish replace(), but rather process in a way, that read() change() replace() will run either in parallel or at least the data on the input will be chunked and the three methods will be run periodically on each chunk while maintaining the relationship on chunk boundaries to e.g. not falsely skip {{\r\n}}, because at the end of the chunk there was only \r, but in the upcoming chunk there is \n at the beginning.

@daokoder
Copy link
Owner Author

How do the changes related to decorators (i.e. their removal and extension of concrete interface) affect aspect-oriented programming in Dao?

Aspect-oriented programming is no longer supported. I think its applicability is a bit limited, and not worth the efforts and complication to support it. Also, with mixin, abstract and concrete interface etc., it should be possible to do things similar to aspect-oriented programming.

How does embedding of another language code (e.g. C) directly into Dao code works if there are no verbatim strings any more? Is it still possible? How?

No longer possible in Dao. I think this is something should be supported in a higher level, the visual programming level, where each block could have different syntax without parsing issues.

By the way I'm highly interested in the visual language you're working on as I'm looking for something with very good support for flow-based programming for one of my projects.

The one I am currently working on is block-based, with some similarity to Scratch. I have also considered to support flow based in the future, but it won't be like what you see in other flow based programming language where a program is represented as graph. I think such graph representation of programs has an obvious flaw, that is, the graph can easily become messy and unreadable as the program grows big.

@dumblob
Copy link

dumblob commented Oct 18, 2016

Thank you for the information.

I think such graph representation of programs has an obvious flaw, that is, the graph can easily become messy and unreadable as the program grows big.

Exactly that was the reason why I asked about your higher-level representation. I'm not satisfied with the messy flow diagrams and would like to have either some 1D representation (i.e. a programming language syntax) or 2D representation using so easy-to-use and easy-to-understand/intuitive building blocks, that it won't become messy. I'm though not aware of any of them. I'm following several projects which began with the same or very similar goals (Unison, Kodowa Eve, Blockspring, Kayia, pyspread). None of them achieved their very inital goals (because it's very complex topic and mainly they got stuck with other unsolved problems and therefore changed the project direction a bit).

I myself am thinking about high-level graph representing one level of a tree of graph nodes (i.e. like standard filesystems contain directories and files). Visually I would try to restrict positioning of nodes to a grid (I always ask myself "how would I do it with ncurses while minimizing user input - cursor movements and keystrokes" to constrain myself and come up with better visual design).

One more note - at best, I'd like to combine imperative/functional flow control (ifs, maps, cycles, etc.) with flow programming visualization. I think it's a similar either-or issue as with static (compile-time) types versus dynamic (run-time) types. This one is 1D imperative/functional-syntax representation versus 2D flow-graph representation. As Dao tries to solve the typing discrepancy with supporting both, I'd like the visual representation to support both in simplified/abstracted forms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants