D - Random comments/suggestions/bugs
- Andy Friesen (24/24) Dec 29 2002 I happened upon this language just yesterday. I think I'm in love. :>
- Burton Radons (13/37) Dec 29 2002 Hm. On the one hand, I do a lot of dispatching to lists of delegates;
- Andy Friesen (76/126) Dec 29 2002 At the core, a coroutine is basically a function that stores its state
- Mark Evans (5/8) Dec 29 2002 P.S. You can go back several months and read my posts here about the Ic...
I happened upon this language just yesterday. I think I'm in love. :> First, the bad news. This little snippet can crash the compiler: alias void delegate() SimpleDelegate; SimpleDelegate[] funcarray; .... funcarray[](); The error message is: Assertion failure: '!ident' on line 1812 in file 'mtype.c' I'm not sure whether it should be legal D or not, but it probably shouldn't crash the compiler in either case. :) Second up, there's no explicit scope operator like C++ has, so there's no way to call a global function from within a class that has a method by the same name. The most obvious example is the toString function in the string module. Copying C++ is an unappealing option, since D's only scope operator is a period, which would be a tad ambigious, not to mention ugly. Lastly, a few tiny suggestions. How about coroutines? They have a way of reducing the complexity of state machines. Python implements coroutines as iterators, which you can use in a for statement. Templates that accept a variable number of arguments would be nice too, though the syntax might start to get weird at that point. (arrays of types?) Anyway, thanks for finally letting me stop bouncing between begging for -- Andy Friesen
Dec 29 2002
Andy Friesen wrote:I happened upon this language just yesterday. I think I'm in love. :> First, the bad news. This little snippet can crash the compiler: alias void delegate() SimpleDelegate; SimpleDelegate[] funcarray; .... funcarray[](); The error message is: Assertion failure: '!ident' on line 1812 in file 'mtype.c' I'm not sure whether it should be legal D or not, but it probably shouldn't crash the compiler in either case. :)Hm. On the one hand, I do a lot of dispatching to lists of delegates; on the other hand, there's no speed benefit in the compiler optimising it for us, and the return from the operation isn't clear (a list of the return value, as with map?).Second up, there's no explicit scope operator like C++ has, so there's no way to call a global function from within a class that has a method by the same name. The most obvious example is the toString function in the string module. Copying C++ is an unappealing option, since D's only scope operator is a period, which would be a tad ambigious, not to mention ugly.Use the module name you used to import: import string; ... string.toStringz (xxx); If the symbol exists in this module, alias it into something more explicit in the global scope or import your own module and use that name.Lastly, a few tiny suggestions. How about coroutines? They have a way of reducing the complexity of state machines. Python implements coroutines as iterators, which you can use in a for statement.You'll need to be more explicit about what they are, how you think they'd work in a D context, what they'd be capable of.
Dec 29 2002
Burton Radons wrote:Andy Friesen wrote:At the core, a coroutine is basically a function that stores its state somewhere other than the stack so that one can later "resume" the function after it returns. for (int i=0; i<10; i++) return i; // won't work, but it'd be nice A better explanation, and an inventive C implementation can be found at http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html To paraphrase, it's sometimes useful to have two functions that jump back and forth, instead of having one strictly call the other. Writing one of the functions as a state machine is one way to solve this problem. Coroutines are a better way. :) (it's also easy to use them for quick n' dirty cooperative threading) As for how they could work in D, I think Python has the right idea. "somewhere other than the stack" would be an iterator object. (one with a method to fetch the next value) Internally, local variables are stored within the iterator itself. A StopIteration exception is raised when the coroutine function has completed whatever it's doing. This (rather bizzare) Python function produces the fibonacci sequence, for example: def fib(): a = 0 b = 1 while True: yield b c = a + b a = b b = c The actual function returns an iterator, which one would hold onto, calling its next() method when desired. f = fib() i = 0 try: while i < 10: print f.next() i += 1 except StopIteration: This particular coroutine goes on forever, so the exception handling in this example is extraneous. It's left in for clarity. The trickiest part of doing this in D is the iterator itself. One way is to have a "special" template interface for iterators. coroutine int fib() { int a = 0; int b = 1; int c = b; while (true) { yield b; c = a + b; a = b; b = c; } } instance Iterator(int) IntIter; IntIter.Iterator f = fib(); try { for (int i=0; i < 10; i++) printf("%i\n", f.next()); } catch (StopIteration) { } I think an Iterator.atend() method would be better than throwing an exception, as exceptions imply some kind of error condition, which isn't really the case. "return" could be used instead of "yield", but it may be better to distinguish the two. On a slightly related note, iterators could be provided for arrays and such as well, allowing a foreach() construct to be added to the language easily. The downsides are pretty obvious -- having a "magical" template interface built into the language, and the compiler complexity imposed by having some locals on the stack, and other locals stored in an iterator. whew! -- Andy FriesenI happened upon this language just yesterday. I think I'm in love. :> First, the bad news. This little snippet can crash the compiler: alias void delegate() SimpleDelegate; SimpleDelegate[] funcarray; .... funcarray[](); The error message is: Assertion failure: '!ident' on line 1812 in file 'mtype.c' I'm not sure whether it should be legal D or not, but it probably shouldn't crash the compiler in either case. :)Hm. On the one hand, I do a lot of dispatching to lists of delegates; on the other hand, there's no speed benefit in the compiler optimising it for us, and the return from the operation isn't clear (a list of the return value, as with map?).Second up, there's no explicit scope operator like C++ has, so there's no way to call a global function from within a class that has a method by the same name. The most obvious example is the toString function in the string module. Copying C++ is an unappealing option, since D's only scope operator is a period, which would be a tad ambigious, not to mention ugly.Use the module name you used to import: import string; ... string.toStringz (xxx); If the symbol exists in this module, alias it into something more explicit in the global scope or import your own module and use that name.Lastly, a few tiny suggestions. How about coroutines? They have a way of reducing the complexity of state machines. Python implements coroutines as iterators, which you can use in a for statement.You'll need to be more explicit about what they are, how you think they'd work in a D context, what they'd be capable of.
Dec 29 2002
P.S. You can go back several months and read my posts here about the Icon language, which supports coroutines natively. They have their uses. http://www.cs.arizona.edu/icon/ http://unicon.sourceforge.net/index.html MarkAt the core, a coroutine is basically a function that stores its state somewhere other than the stack so that one can later "resume" the function after it returns.
Dec 29 2002