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