Come From

The opposite of a GoTo statement.


History

Encountered on a list of joke assembly language instructions around 1971 by AlistairCockburn. (<http://www.fortran.com/fortran/come_from.html>)

Published in 1984. From the C-InterCal manual (<http://www.muppetlabs.com/~breadbox/intercal-man/s04.html#4.14>):

The earliest known description of the COME FROM statement in the computing literature is in R. L. Clark, "A Linguistic contribution to GOTO-less programming," Commun. ACM 27 (1984), pp. 349-350, part of the famous April Fools issue of CACM. The subsequent rush by language designers to include the statement in their languages was underwhelming, one might even say nonexistent. It was therefore decided that COME FROM would be an appropriate addition to C-INTERCAL.

In Donald Knuth's article Structured Programming with go to Statements Donald E. Knuth December 1974 ACM Computing Surveys (CSUR), Volume 6 Issue 4

he mentions the COME FROM statement, and refers to the article mentioned above as:

Clark, R. Lawrence. "A linguistic contribution to GOTO-less programming," Datamation 19, 12 (December 1973), 62-63

Implemented by C-INTERCAL (<http://www.muppetlabs.com/~breadbox/intercal/home.html>).


It got a wonderful new semantic in Threaded InterCal! The original Intercal stated:

      It is an error for more than one COME FROM 
      to refer to the same (label).
This restriction was suspended in Threaded InterCal.


Is ComeFrom an ExceptionPattern?

No

These references to exceptions as implementing ComeFrom surprise me. I first encountered ComeFrom around 1971 on a list of joke assembler language instructions (along with "move and wrap core", and "move and wrap secretary"). I encountered it occasionally on such joke lists over the years, but never again until IvarJacobson brought it up again as a way of implementing his 'extension' mechanism in UseCases. Not everyone in the room seemed to recognize that he was simultaneously saying extensions are not implementable.

At the risk of describing the painfully obvious, exceptions do not say where they are coming from. In fact, that is their purpose in life - to not say where they are coming from. ComeFrom has as its purpose in life exactly to state where it is coming from, although the named spot in the program is supposed to be blissfully unaware of it. So ComeFrom and ExceptionHandling are about as different as you could ask for, you sure couldn't implement exceptions with ComeFrom.

I just couldn't stand to watch silently any longer. -- AlistairCockburn

Very much so. "ComeTo?" is probably a more accurate description of an exception handler. To raise an exception, you "JustSayGo." ComeAgain??

Agreed. Don't know about all the roots of ComeFrom, but it was fairly well established (as a joke, at least) by the time I encountered it around 1977 (consistent with an INTERCAL origin, if that's taken as 1972; this is frankly the first I'd heard of INTERCAL as such). At Dartmouth (home of BASIC), this was used in structured-programming arguments: ComeFrom was asserted to be isomorphic to GoTo, in that the one could be mechanically translated to the other (it's true for many cases, but I haven't thought about this since so take it with a grain of salt).

ComeFrom wasn't in the first version of INTERCAL; it is an addition in the C-INTERCAL version. Strangely enough, it turned out to be one of the most useful statements in INTERCAL...

In any case, exceptions cannot be implemented with either ComeFrom or GoTo, not even non-local GoTo (by contrast, by the way, to a great many other programming constructs of greater political correctness). The equivalent flow control can be roughly implemented with label variables or setjmp/longjmp, but the mapping of that to a ComeFrom extension is not something I've thought about. -- JimPerry


Is there anything else like ComeFrom?

Setting breakpoints in a debugger implements a dynamic ComeFrom.

AspectOrientedProgramming and the Advice systems in some Lisps have been described as "structured ComeFrom."

And then there's the inverted CASE statement. Kind of a "computed" COME FROM.

As in "I'm here, so x must have a value of 7"? I've seen a lot code that effectively did that. Very nice when combined with multi-value switches. You get a holographic effect where the information about what the program is doing at any given line of code is spread throughout the entire program.

You can do something like that in INTERCAL, since you can use the ABSTAIN/REINSTATE mechanism to enable or disable a specific COME FROM statement.

There is now an CLC-INTERCAL compiler that has real computed COME FROM. You can COME FROM a variable, then assign to this variable... For example:

 PLEASE REINSTATE (9)
 (8) DO .1 <- #8
 (9) PLEASE COME FROM (1009)
 DO ABSTAIN (9)
 (1000) DO COME FROM .1
 .........
 (1009) DO .1 <- #0

There is now a new proposed (: term called GoHere, which is followed by an expression describing conditions for its execution. Like GoHere When Finished, Finished is Boolean true/false. Other examples at GoHere :)


What if 2 ComeFrom's reference the same location?

In C-INTERCAL, it is an error if two COME FROM's point to the same location. But there's also a parallel INTERCAL, which does the RightThing and continues execution at both COME FROM's, in parallel.

Note that this form of ComeFrom is strictly more powerful than GoTo. One might have a GoTo which took a list of destinations.

How about a COME FROM that takes several sources and implements a thread rendez-vous/termination? That might be an interesting extension to Parallel INTERCAL.


It is said that CallWithCurrentContinuation is a generalization of GoTo. Any ideas how a similar generalization of ComeFrom would look?

I guess a (replace/call/cc cont value) function would be the functional counterpart. Its workings are simple - replace all references to cont (i.e. destructibly change the internal continuation state) so that it refers to the current continuation, then resume the original continuation in cont with the specified value. Dynamic redefinition of functions actually gives pretty much the same functionality, but limits the From's to function entry points. Then again, replace/call/cc is also limited in only accepting previously saved continuations. If you need to ComeFrom the middle of functions, modifying the function's source shouldn't be too hard though - decompile, insert GoTo, wrap in define, eval at its worst (although that solution uses GoTo, not ComeFrom).


Why can't we have an if statement that works the other way round? As an example:

 {
    x := x + 1;
 } else {
    x := x - 1;
 } if (x mod 2 == 0) 
This will increase x if it will be odd afterwards; it decreases x if this makes it even. I think you mean the other way round. What do you want to get when x = 2?

Basically, what you seem to be looking for is something that will do:

  doFoo();
  if !resultOkay {
     undoFoo();
     doBar();
  }
If you want these kind of things, you should use the PrologLanguage, or perhaps the StructuredQueryLanguage. An example in both:
  doStuff :-
    doFoo,
    resultOkay.

doStuff :- doBar.

BEGIN SAVEPOINT beforeFoo; doFoo; IF NOT resultOkay THEN ROLLBACK TO SAVEPOINT beforeFoo; doBar; END IF; COMMIT; END;
Of course, the rollback only applies to the contents of your tables.

Don't be silly; SQL doesn't have a IF statements!

{Actually, it does. See, for example, http://technet.microsoft.com/en-us/library/ms182717.aspx }


Both cases in the above example are equivalent... If (x mod 2 == 0), then (x + 1) and (x - 1) are both odd. The same logic holds if the value that x "would have" post-operationally is used.

No, they're not equivalent. The 'PostCondition' is tested only once. I read the above as:

  x++;
  if (x mod 2 == 0)
    return x;
  else
    x--; // undoing the x++
    x--; // the wanted effect
    return x;
So the above should increase odd numbers, making them even, and would decrease even numbers, making them odd (which is not the claimed behaviour, BTW). Of course the simple example given can be redone with a regular if, but I think the requested feature is a valid one. Even though the PerlLanguage does have its post-ifs and post-unlesses, I don't think they work any different than the regular ones.


I just realized that ComeFrom looks an awful lot as a low-level version of the "cross-cutting" that products like AspectJ ( http://aspectj.org ) allow. In fact, one could do AspectOrientedProgramming in INTERCAL in this way: by adding a module that COME FROMs labels in the original program, the new module (aspect) can immediately enhance the program without textually changing it.

-- StephanHouben

It's interesting that you should say this, since Todd Proebsting (of Microsoft Research) dismissed AOP as "The Ultimate Come From" at the LL2 Conference at MIT. Actually, I hadn't grokked AOP until I thought about what he said, so it seems to me like a very useful comment. This is why (IMO) you really have to have really good editor support for AOP to be useful.

-- Cullen J. O'Neill


A potential use for ComeFrom is in reversible computing (http://www.ai.mit.edu/~cvieri/reversible.html ). In a reversible instruction set it makes sense that the GoTo should have a symmetrical partner, the ComeFrom. GoTos are otherwise messy to handle in a reversible context because any instruction might serve as a target for a jump making it difficult to execute backwards.

-- Dan Piponi


A useful extension is the DontComeFrom? statement as in:

 if (x > 7) don't come from 100


If ComeFrom is the pendant to GoTo then I wonder, how the pendants for GoSub? (aka JumpSubRoutine) and ReturnFromSubRoutine? might look like. One might call them ComeFromCaller? (placed at the top of a 'subroutine') and ReturningFrom? <label> (at the calling site after the call). The remaining question then is, how to figure out, where the 'caller' of the ComeFromCaller? is. I conjecture, that this can (if at all) only be done by nondeterministically trying all callers and choosing only that (those?) which leads to a valid (i.e. matching) ReturningFrom?.

-- GunnarZarncke

I'd suggest something like this:

CALLED FROM lines... Yanks control here after any of the lines in lines... have been executed. If more than one CALLED FROM refers to the same line, I suppose you could spawn more threads, or call it an error.

RETURN FROM line1 VIA line2 After line2 has been executed, if a CALLED WITH statement has yanked control after line1, yank control here.

A compiler could easily (I think) implement these two by matching RETURN FROM's to CALLED FROM yank points, and just push the correct return address on the return stack and simply COME FROM a line just after the yank point and pushing of the return address, but before the next line in the program.

Example (assuming global variables)

 1 var1 = 2
 <--- Here, control is yanked to line 100, CALLED WITH
 2 RETURN FROM 1 VIA 101
 3 RETURN FROM 2 VIA 101
 4 PRINT var1 // var1 should be 2+42+42 (two applications of the subroutine)

... More code, followed by the subroutine: 100 CALLED FROM 1, 2 101 var1 = var1 + 42 <-- Here control would be yanked back to line 2 or 3, depending on which return point is on the return stack

Optionally, the CALLED WITH statement could implement a multi-threaded rendez-vous mechanism. And obviously, the RETURN FROM can be on any source line. It should be possible to use an inner part of a subroutine as a different subroutine, something like this:

 2 var1 = 3
 3 RETURN FROM 2 VIA 300
 4 PRINT var1, var2 // Should print 3, 7 (2*3+1)
 5 var2 = 4
 6 RETURN FROM 5 VIA 300
 7 PRINT var2 // Should print 5 (4+1)

.. Lots of code

100 CALLED FROM 2 101 var2 = 2*var1 200 CALLED FROM 5 201 var2 = var2 + 1 300.. Do more stuff

Which is kind of a cool ability. Not sure how to use it though ;-)

--SimonBrenner (using a friend's ssh host as socks proxy, since the code word doesn't work from my IP!)

Actually, I think it might be more like this:

   (1) DO NOThing here
   (2) PRINT (RETURN FROM 101)

(100) COME FROM 1 (101) .1 + .2

That is, it inspects the result of the statement, and allows the COME FROM line to access it.

Hmmm... Perhaps we should first figure out what call/cc and functions are in terms of gotos, then switch the GoTos with ComeFroms.

    (1) push (1); goto (1000) // Push the return onto the stack; GOTO the subroutine.
    ... code code code
    (1000) code code code
    ....

if (recursive_case) { (1009) push (1009); goto (1000) } (1010) goto pop() // Pop the stack and go to that address.

I think we could (?) have that become
     (1) push (1); comefrom (1010) // 

(1000) comefrom pop(); ... code code code (1009) {push (1009); comefrom (1010)} if that would make the recursive case true. (1010) // whatever
Trouble is, I don't know how this handles multiple subroutines, or even whether it makes sense. Possibly, we need to make it more along the lines of "Called From", as proposed above.

I think that part of the problem is that ComeFrom is an inherently hypothetical concept, in the sense that a programming language has to figure out a lot of suppose this were the case, then would this happen sort of things. The simplest being:

     if (a == b) COME FROM label;
and more complex examples including
     if (a == b) {
        COME FROM label1;
        COME FROM label2;
     }
     if (c == d) :label1;
and when mixed with things like the "do this if doing it makes the condition true, otherwise revert it and do this instead" inverted if statement, it becomes just plain confusing.


[insert obligatory reference(s) to Craps tables and/or the 'three universal lies' joke here]


An example of ComeFrom, widely used in wikis, is found in the list of BackLinks. It is an example of the fact that one may arrive at a computing venue from many other venues. BackLinks and its counterpart, ForwardLinks, are two structures which tie the current page via hyperlinks to other pages in a NamedRelationship?. -- DonaldNoyes.20080729.1106.m06


For an actual useful application, I've seen a "come from" instruction suggested as a security enhancement. These instructions would serve as "landing pads" to ensure that jumps were to valid locations, a jump to an instruction that is not the matched come-from instruction would be an error.

Functions would need a landing pad instruction with looser restrictions, but this would still force exploits to use the actual intended function entry points. Exploits that jump into the middle of code would require modifying that code.

There are other uses for such a kind of "landing pad", where nothing checks for their presence, but instead assumes them. This can be used by a compiler to perform optimizations involving "inner blocks".

Something like this has appeared a couple of times in practice, such as Google NativeClient? requiring basic blocks to be aligned on k-byte boundaries and restricting jump instructions to target those boundaries; indirect branching must explicitly mask off the low bits of the branch address or fail verification.

In a different vein, the @PreviousPageType directive in ASP.Net (http://msdn.microsoft.com/en-us/library/ms228169%28v=vs.100%29.aspx) is used to obtain a statically-typed version of POST data when the page class defining the form and the class receiving the POST are distinct.


CategoryBranchingAndFlow


EditText of this page (last edited October 5, 2014) or FindPage with title or text search