|
|
Label: ♦english
♦news
fu
created at Friday, 2010-12-03, 07:24:16
10 Replies, 2184 Hits
Running time class creation has been recently supported. This is another new feature besides the meta-fields (see Summary of the recent development of Dao ) and function decorator to support writing more dynamic programs.
The basic syntax is the following:
c = class( name, parents, fields, methods ){ body }
All parameters are optional. Acceptable parameter types:
Some simple examples:
class1 = class(){}
class2 = class(){ var value = 0 } class3 = class(){ var value = 0 routine @class( v = 0 ){ value = v } # constructor } o1 = class1(); o2 = class2(); o3 = class3( 123 ) It is also possible to use type holder in such class body and class methods:
routine MakeClass( @TYPE, name = '' )
{ klass = class( name ){ var table : array<@TYPE> = [1,2,3]; } return klass; } itab = MakeClass( int ); ftab = MakeClass( float ); dtab = MakeClass( double ); it = itab(); ft = ftab(); dt = dtab(); io.writeln( it.table ); io.writeln( ft.table ); io.writeln( dt.table ); A more complex example:
class Base
{ var name = 'Base'; } routine CreateClass( name : string, value = 0 ) { io.writeln( name, value ); # @class for host class type rout = routine( self : @class ){ io.writeln( 'Extra()', self.index ); } # to be used as initializer/constructor init = routine( self : @class, txt : string ){ io.writeln( 'initialized by init' ); self.text = txt; } # klass = class( name, parents, fields, methods ){ core_class_body } klass=class( name, { 'Alias'=>Base }, { ('added', 789, $const, $public) }, { (name, init), ('Extra', rout) } ) { var index = value; var text = '---'; routine @class( id = 0 ){ index = id } routine Meth( id = 0 ){ io.writeln( 'Meth(id)', id, index, text, self.Alias ) } routine Meth( text : string ){ io.writeln( 'Meth(text)', self.name, self.added ) } } return klass; } klass1 = CreateClass( 'AA', 123 ); klass2 = CreateClass( 'BB', 456 ); obj1 = klass1( 'abcdef' ); obj2 = klass2( 123456 ); obj1.Meth(); obj2.Meth(); obj1.Meth( 'abc' ); obj2.Meth( 'def' ); obj1.Extra(); obj1.added = 987; io.writeln( obj1.added ); # error, accessing private member PS: based on the implementation of this feature, C++ like template will also be supported in the near future! Comments
fu commented at Sunday, 2010-12-12, 00:37:30
Now a preliminary implementation of template class support has just been finished and committed into the code repository (revision 124: a44524c5c240). An example of template class is add in the demo fold. Here is that example:
class Item<@V>
{ var value : @V; var next : Item; routine Item( v : @V ){ value = v } } class LinkList<@V,@T=int> { var first : Item<@V>; var last : Item<@V>; routine Append( value : @V ){ item = Item<@V>( value ); if( first == null ) first = item else last.next = item; last = item; } routine Print(){ item = first; io.writeln( item.value, item ); while( item.next != null ){ item = item.next; io.writeln( item.value, item ); } } } ll = LinkList<int>(); ll.Append(11); ll.Append(22); ll.Append(33); ll.Print();
Nightwalker commented at Monday, 2010-12-13, 00:25:24
I wonder if we should now organize the standard template library -- I already have some ideas... :)
fu commented at Monday, 2010-12-13, 19:09:26
Do you mean the built-in container types such as "list/map/..."? I am not sure about this. They behavior more like just type names, they do not instantiate in the same way as template classes do. Actually, they only instantiate their typing interfaces. Moreover, there are types such as "routine<...>" etc. which assume template like form, but are really just type names (typing interfaces). Anyway, I'd like to hear you ideas:)
Nightwalker commented at Monday, 2010-12-13, 22:36:55
No, my thought is to create a standard Dao library for useful template classes (no changes to the DaoVM itself). For instance, I've thought up few templates providing a high-level interface to mtlib : no explicit threads/mutexes, just function/variable wrappers (the idea was partially inspired by QtConcurrent ). While direct mtlib capabilities are required to organize flexible multithreading, high-level wrappers may be used for simpler, typical tasks (e.g., calculate the function asynchronously).
class SharedVariable<@T>
The next template, JoinVariable , is designed to be used as a thread function result. It can be accessed freely by any thread, but will implicitly join the function's thread if necessary. It's a direct analog of QFuture class -- the synchronized result of asynchronous function:
{ private var data: @T; var mtx: mutex = mtlib.mutex(); var owner: thread = null; public routine MTVariable(value: @T) { data = value; } routine value() { if (owner != null and owner != mtlib.self()) std.error('The variable is locked'); return data; } routine setvalue(value: @T) { if (owner != null and owner != mtlib.self()) std.error('The variable is locked'); data = value; } routine seize() { mtx.lock(); owner = mtlib.self(); } routine release() { if (owner == mtlib.self()) mtx.unlock(); } routine trylock() { if (mtx.trylock()) { owner = mtlib.self(); return 1; } else return 0; } }
class JoinVariable<@T>
Finally, ThreadFunction template encapsulating asynchronous function; its result is provided as a JoinVariable . Multiple parameters may be passed via tuple or list:
{ private data: @T; owner: thread = null; public routine JoinVariable(value: @T) { data = value; } routine seize() { owner = mtlib.self(); } routine value() { if (owner != null and owner != mtlib.self()) owner.join(); return data; } routine setvalue(value: @T) { if (owner != null and owner != mtlib.self()) owner.join(); data = value; } routine release() { if (owner == mtlib.self()) owner = null; } routine isowned() { return owner != null; } }
class ThreadFunction<@Arg, @Res>
But enough with multithreading. I also created CachedFunction template which represents a "pure" function whose result is cached in hash-map:
{ private var func: routine<@Arg=>@Res>; var res: JoinVariable<@Res>(); var fthread: thread; var isrunning = 0; routine run(param: @Arg) { res.sieze(); res.setvalue(proc(param)); res.release(); isrunning = 0; } public routine ThreadFunction(f: routine<@Arg=>@Res>, result: @Res) { func = r; res = JoinVariable<@Res>(result); } operator () (param: @Arg) { if (isrunning) std.error('The thread is still running'); fthread = mtlib.thread(run{param}); isrunning = 1; return res; } routine result() { return res; } } #AN EXAMPLE routine f(x: int) { #do something useful } func = ThreadFunction<@int>(f, 0); res = func(10); ... x = res.value(); #joins implicitly if needed
class CachedFunction<@Arg, @Res>
As you can see, such library may as well serve as a proving ground for various insane ideas :){ private func: routine<@Arg=>@Res>; hash: map<@Arg, @Res> = {:}; public routine CachedFunction(f: routine<@Arg=>@Res>) { func = f; } operator () (param: @Arg) { (found, key, value) = hash.find(param); if (found) return value; else { value = func(param); hash[param] = value; return value; } } }
fu commented at Tuesday, 2010-12-14, 03:03:36
OK, you are actually proposing create a new standard template library, I have thought you were talking about something already exists in Dao. I think you have a good point on the fact that it is better to have something ready-to-use for typical tasks. And as a proving ground, some nice (or insane in a nice way) idea could actually come out of it. Your examples are interesting.
Pompei2 commented at Monday, 2010-12-20, 08:51:27
Wow, this is a really hot new feature! Congratulations, I like it a lot!
Let me share the way of thoughts I had right now: It would be cool now to be able to add methods and attributes to a class at run-time. It fits well with this addition and makes the language more dynamic than most "modern" languages. Then I thought about the meta-fields, they do exactly this! It's just that they have a different syntax.
bla.bli() # Calling a "usual" method of an object.
bla->bli2() # Calling an "added" method by meta-field of an object. So what I am wondering right now is if it is a good idea (or a bad idea) to unify the syntax, such that syntactically and semantically to the user, meta fields "feel" just like usual attributes/methods. What do you think?
Pompei2 commented at Monday, 2010-12-20, 08:52:22
In reply to TheTrueNightWalker, I like your idea of a high-level standard library. Your examples show a very good use-case of it.
What I wonder is if whe should distribute (and manage) it with dao right away, or as a separate project. Also, we'd better define some guidelines (not hard rules) right at the beginning to help us decide what fits in and what not - just to keep it at a consistent abstraction level.
Nightwalker commented at Monday, 2010-12-20, 10:58:23
Nightwalker modified at Monday, 2010-12-20, 12:02:27
Not sure run-time field addition to a class is a good idea, as allowing this would make the concept of classes meaningless -- it would be just a primitive prototype-based OOP. Currently classes are used to specify the usage interface for objects. If new fields are added to a class after it has been stated, it becomes something else -- and the whole Dao typing system becomes useless here! I think meta-fields facility is a nicer and clearer solution to what you want.
fu commented at Monday, 2010-12-20, 19:44:56
Indeed, running time field addition or normal/meta field unification will render the typing system useless. It will also cause dilemma situations such as obj.field=1 , when field does not exist, what to do, raise an exception or add a new field automatically? Current distinction between . and -> will make it clear what's the proper interpretation for such statement, and make prototype-based OOP codes easily recognizable.
Pompei2 commented at Sunday, 2010-12-26, 00:44:07
Right, sounds scary but I always forget that Dao is strictly typed :-P Because it has a mix of features from both typed and untyped languages. Thank you for the clarifications.
|
fu: A little bit game development in Dao! Thanks to ClangDao, it has become very easy to create bindings for C/ C++ libraries. The latest one i ... (May.14,07:08) dao: Dao 1.2 Beta1 is released! After a very long time of development, the first beta release for Dao 1.2 is finally available ( http ... (May.06,23:37) fu: ... Just to mention: a couple of demos (including the 2000 line one) has been successfully ported to IPho ... (May.19,02:43) fu: ... Yes, it is getting mature, and more libraries and modules are coming out, hehe:) For GameKit, unfor ... (May.19,02:38) Pompei2: ... This is cool news and really shows that ClangDao is getting mature, thumbs up. Too bad for this litt ... (May.18,09:17) fu: ... Not completely, but mostly. New revisions will be regularly pushed to the repository on google code ( ... (May.08,22:38) Pompei2: ... If I understand it correctly, you want to completely switch? If so then: (May.08,08:46) |