MiniD 2 - Tentative Release Candidate 1
davidl
davidl at 126.com
Wed Dec 10 19:21:42 PST 2008
在 Wed, 10 Dec 2008 21:52:01 +0800,Jarrett Billingsley <jarrett.billingsley at gmail.com> 写道:
> On Wed, Dec 10, 2008 at 3:15 AM, davidl <davidl at 126.com> wrote:
>> 在 Wed, 10 Dec 2008 13:52:18 +0800,Jarrett Billingsley <jarrett.billingsley at gmail.com> 写道:
>>
>> It's cool it could be used in that syntax. But I find nowhere of docs describing this feature?
>> Do I miss something?
>
> Yeah, you do. I gave you a link in my last post. See at the end? Go
> there and read all about it.
>
Ah, I thought it were another page I've read carefully. Yet that was actually a page that I read
by skim. I should have read it up carefully. Sorry for that.
>> MDCL stack overflowed out, maybe mdcl should do something to protect itself from stack overflowing.
>
> Maybe it should ;)
>
Of course it's your responsibility to improve it. :D And a commercial quality MiniD interpreter should
not overflow out. :D
>> I'm trying to use coroutine foreach in a class.
>>
>> class count
>> {
>> x =3
>> function opApply(m) = coroutine function opApply(m)
>> {
>> yield()
>> for(i: 1 .. m.x + 1)
>> yield(i)
>> }
>>
>> }
>> global c= count()
>> foreach(v;c.opApply(c))
>> writeln(v) // prints 1 through 4
>>
>> it causes of runtime error: Error: opApply(7): Attempting to access field 'x' from a value of type 'null'
>
> Well yeah. Where is your coroutine getting the value 'm'? It's not.
> So it gets 'null'.
>
>> The problem here is I misuseing the function definition.
>> function opApply(m) = coroutine function opApply() works OK.
>
> Yes, because of upvalues. When you take the parameter off the
> coroutine, 'm' then refers to the local variable in the outer
> function.
>
>> But that's inconsistent from a strong type user's view. Because the left part is function with 1 arg, right part
>> is a coroutine function without any arg. That's pretty error-prone for newbies.
>
> And coroutines and iterators are pretty advanced. So I'm not so sure
> I much mind what the newbies think ;)
>
That's not true. All about compiler is easeing developers. Why not issue a compiler
error/warning when it reaches some code like:
function opApply(m) = coroutine function opApply(m)
1. the local var m shadows the arg m _in 1 declaration_
2. this could be a general mistake which could possibly be made by people with
a strong type programming background
Probing this kind of code seems troublesome, I will be glad to see MiniD can give an error
on this kind of code someday.
> Actually you're again doing it wrong. You don't have to manually pass
> the object to be iterated to opApply, it's already passed as 'this'.
> The following:
>
> class count
> {
> x = 3
>
> function opApply()
> {
> local m = this
>
> return (coroutine function()
> {
> yield()
>
> for(i: 1 .. m.x + 1)
> yield(i)
> }).opApply() // hee hee
> }
> }
>
> global c = count()
>
> foreach(v; c)
> writeln(v) // prints 1 through 4
>
> Works without having to call c.opApply directly.
>
> What I did in the method there is a trick - if you want one opApply to
> actually iterate over another object, you can just return the values
> from _its_ opApply. I put 'this' in m so that the coroutine could
> access it (because functions can't access their outer function's
> 'this'). I then create the coroutine function and call opApply on it,
> returning those values, so the foreach loop ends up iterating over the
> coroutine.
>
That's pretty tricky. But the syntax of following is cleaner if possible:
class count
{
x = 3
coroutine function opApply() //mark it as a coroutine function.
{
yield()
for(i: 1 .. :x + 1)
yield(i)
}
}
global c = count()
foreach(v; c)
writeln(v) // prints 1 through 4
It's pretty sad "coroutine function" in a whole doesn't work.
But still opApply() = coroutine function() still not work
You do it: function f()=coroutine function()
I think if MiniD is able to do the syntax I proposed, I wouldn't have those bunch
questions about foreach on a coroutine function.
And People won't expect do foreach on a coroutine in most cases if that syntax comes
true. Because for most people, a coroutine opApply is more intuitive than a coroutine
with an opApply method available.
And I think it's practicle for MiniD compiler decide what to do, because MiniD can
probe that if the opApply method is coroutine or not. If it's coroutine function, than
implicitly a coroutine context created. Also the first yield is quite weird for me.
class count
{
x = 3
function opApply() = coroutine function() //mark it as a coroutine function.
{
yield() // I hope that we could get rid of the first yield, is that for something special or else?
for(i: 1 .. :x + 1)
yield(i)
}
}
global c = count()
foreach(v; c)
writeln(v) // current it prints nothing. I don't know what it's actually going here.
More information about the Digitalmars-d-announce
mailing list