Path: news.daimi.aau.dk!news.uni-c.dk!uninett.no!news-feed.inet.tele.dk!cpk-news-hub1.bbnplanet.com!news.bbnplanet.com!news-xfer.netaxs.com!nntprelay.mathworks.com!fu-berlin.de!zrz.TU-Berlin.DE!not-for-mail From: Kai Petzke Newsgroups: comp.lang.beta Subject: Re: leaving a pattern? Date: Fri, 05 Sep 1997 16:30:53 +0200 Organization: Technical University Berlin, Germany Lines: 176 Message-ID: <3410179D.F2B8ADA@physik.tu-berlin.de> References: <5tguc5$r4n$1@gjallar.daimi.aau.dk> <5tiboo$2h6$1@gjallar.daimi.aau.dk> NNTP-Posting-Host: dial1-38.zrz.tu-berlin.de Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Mailer: Mozilla 3.01 (X11; I; Linux 2.0.30 i586) Xref: news.daimi.aau.dk comp.lang.beta:11254 > > In <5tguc5$r4n$1@gjallar.daimi.aau.dk> jojo@daimi.aau.dk (Johanna Wiederhold) writes: > > > > >transaction: > > > (# > > > abort :(# do leave transaction #); > > > ... > > > do > > > INNER > > > #); > > > > >[causes an] error message: > > > > >leave transaction > > >***** "leave P" or "restart P", where "P" is a pattern, > > > is only legal in the do-part of "P" > jlk@daimi.aau.dk (Jorgen Lindskov Knudsen) writes: > > > > Let us elaborate a little on your example: > > > > (# myTrans: @transaction; > > ... > > do ... > > myTrans.abort; > > ... > > #) > > > > This shows why...when executing myTrans.about, myTrans is not on the > > execution stack, leaving the semantics of 'leave transaction' > > undefined (what should it 'leave'). Erik Ernst wrote: > > But since we could simply do > > (# pv: ##object > do L: (# p: (# do leave L #) do p##->pv## #); > pv (* 'leave L', but the inserted item is not on the stack now *) > #) > > executing "homeless" leave/restart instructions is generally possible > anyway. Yep. Homeless leave/restart imperatives can occur in BETA. At the current state of the language, they cause the whole stack to unwind and the program to terminate with an error message. In a later version of the language, there might be a way added to catch such error conditions in a program. There is a problem, though, that nobody has mentioned so far: BETA supports separate compilating. At least in case of my BETA to C translator b2c, a short piece of code has to be added at the location of each label, that can be reached by a non-local LEAVE/RESTART. Otherwise, the run time system wouldn't be able to determine, where to actually continue the execution, if it finds a LEAVE or RESTART operation, that returns to an enclosing pattern, as in the following example: textList: List (# element:: text #); lst: ^textList; do (* set up the list not shown here *) L: lst.scan (# do (* Test for error conditions *) (if current.length=0 then 'Error: empty string in list!'->screen.putline; leave L; if); (* Further process the list element ... *) #); Separate compilation means, that we often cannot predict, if a LEAVE or RESTART is going to happen or not. The example above could be written as follows: textList: List (# element:: text #); lst: ^textList; do (* set up of the list not shown here *) L: <>; In that case, we have to add hunks for speculative LEAVE L and RESTART L operations, because we cannot know in advance, if such appear in the fragment, that will later fill the SLOT ListIntegrityCheck. However, labelled ObjectDescriptor and DoPart SLOTS are rarely found in other DoParts. So those speculative labels are rather seldom, too. The situation changes dramatically, if we allow LEAVE and RESTART from anywhere within a pattern. In that case, any SLOT (whether Attribute, DoPart or ObjectDescriptor, whether nested or not) in the Attribute section of a pattern would force a pair of speculative LEAVE and RESTART labels to be inserted. My opinion is, though, that LEAVE and RESTART should nonetheless be legal anywhere within a pattern. To avoid the problem with adding the LEAVE/RESTART hunks to any pattern, we might forbid LEAVE and RESTART, if they are not defined in the same Fragment, as the pattern or label, that is to be left or restarted. We might keep a couple exceptions, like labelled ObjectDescriptor slots, which I explained in my second example above. Another point is, that the Mjølner system currently seems to be unable to add the hunks for non-local leave or restart to the entire DO Part of a pattern. This is, why the following piece of code won't compile correctly: textList: List (# element:: text #); lst: ^textList; checkList: (# do lst.scan (# do (* Test for error conditions *) (if current.length=0 then 'Error: empty string in list!'->screen.putline; leave checkList; if); (* Further process the list element ... *) #); #); The "leave checkList" is non-local, and refers to a complete DO-PART, not a particular label. If the Mjølner system is not able to handle the non-local LEAVE/RESTART of a DO-PART correctly, it cannot handle the following either: checkList: (# abort: (# do leave checkList #); do ... #); > We don't have to use pattern variables, dynamic references > would do, of course. It just causes an 'attempt to leave basic > component' error message, because the stack unwinding machinery did > not find an appropriate object on the stack to stop at. Not really > worse than "divide by zero", and not better either.. Yes, exactly. > Another thing is that it ought to stop the current thread, not the > entire program, both when "divide by zero" and "leaving last > component" happens. I believe this will happen as soon as somebody > gets it implemented, though. That looks like a good idea. I would like to add failed runtime Qua Checks to that list as well. > So I think it should be allowed. Forbidding it is almost taking a > safety-by-obscurity approach, which is usually not a clean solution to > anything. And certain things _are_ easier to express with it, like > your example. I have used a similar construct as my "L"/"p" example > above several times, and it works nicely. Yep. I use the non-local LEAVE a lot, for example in an interactive application, where various errors could occur at different points during interpretation of a command, sometimes even during a recursive function. The "L"/"p" scheme shown by Erik is handy to create a "bomb", that bails out of the failed interpretation attempt nicely and returns to where it started. To have LEAVE/RESTART anywhere within an attribute section would even be more handy, though. -- Kai wpp@physik.tu-berlin.de