21 comments

[ 2765 ms ] story [ 214 ms ] thread
Have any examples of languages that implement this?
IIRC, INTERCAL does implement it.
Some elements of Aspect Oriented Programming are comparable to the COMEFROM statement.

http://en.wikipedia.org/wiki/Aspect-oriented_programming#See...

Here's an AOP-style comefrom syntax you can play with by setting DrRacket's language to R5RS:

  (define-syntax comefrom
    (syntax-rules ()
      ((comefrom function expr ...)
       (let ((old-function function))
         (set! function
               (lambda args
                 (begin expr ...)
                 (apply old-function args)))))))
  
  (define (square x)
    (* x x))
  
  (define (hypotenuse a b)
    (sqrt (+ (square a) (square b))))
  
  (comefrom square
            (display "I'm a square!\n"))
  
  (hypotenuse 3 4)
The example in the Wikipedia article is more like this:

  (define-syntax comefrom
    (syntax-rules ()
      ((comefrom function)
       (call-with-current-continuation
        (lambda (here)
          (set! function here))))))
  
  (define (noop)
    ; Do nothing
    #t)
  
  (define (main)
    (let ((i 0))
      (comefrom noop)
      (if (< i 5)
          (begin
            (set! i (+ i 1))
            (display "Hello world!\n")
            (noop)))))
  
  (main)
To some extent any inversion of control style framework works like this. It can be more or less befuddling depending on the straightforwardness of the framework. Declarative style programming such as sql, xslt, or msbuild also tend to work this way, which can be maddening to debug.
What are some more obscure control flow structures? It's easy to think that eg conditionals, loops, goto, function calls are the only ones that exist. But there is also stuff like jump tables and co-routines for instance.
I don't know if it gets any more obscure than Scheme's call/cc, which is a building block for other control flow structures. You can use it for cool things like the Racket web server, where event-driven programming can be made to feel like sequential, procedural-style programming. You can also use it for sick mind twisters like ((call/cc call/cc) (call/cc call/cc))
I remember being shown call/cc briefly in CS 61A at Berkeley and then forgetting about it until recently when I saw an article on it while I was in the middle of writing an event-driven web application using Perl and Plack. I immediately saw how useful it would be and wished I had it available to use there.
Please explain :)
Good explanation here: http://lambda-the-ultimate.org/node/86#comment-3806

But you have to read it slowly.

Mine lisp-peen is too small.

Now, off to study!

Thanks, btw.

I don't think I ever really understood call/cc until I read Lisp in Small Pieces. The author makes a great effort to implement call/cc in each of the interpreters and compilers he presents, and examines the hairy issues that come up when you decide to support first-class continuations.

Highly recommended.

Conditions maybe?

They're what lies beyond exceptions: exceptions will unwind the stack looking for a handler (`catch` or the likes), and when found will execute that handler in its (the handler's) context (scope).

Conditions walk the stack instead of unwinding it, and execute the handler in their own context. This gives the handler the possibility of logging an error and bailing out, of course, but also of fixing the local data and resuming running the code[0], as if nothing had happened. A condition system essentially allows callees to reach into callers and ask them what to do, without having to lose any state or data.

This also gives more power to tools: without any specific instrumentation, a Smalltalk environment or a Common Lisp IDE can drop you at the error site (where the condition was signaled) without needing more than registering a condition handler when starting your code (if conditions are already handled by a condition handler in your stack, this default behavior won't happen until your handlers let the condition propagate further).

[0] Actual flexibility depends on the runtime, I'm not completely up to snuff with everything, I know in Common Lisp there's a concept of "restart": the one who signaled the condition or any of its callers can provide "restarts", which are essentially possible choices for resuming work. A log-parsing API could provide restarts to skip a corrupted or unreadable entry, to display a user prompt to ask him to "manually" parse the value or to provide the API with a value to use instead (could be a default, a placeholder, or a value obtained by calling the older log-parser you're trying to replace) (note: it's an inclusive or, the API provides all three and the developer using the API picks the one he wants depending on the situation). Or a dict's `get` method could signal on an invalid key and provide a restart making it return a default value of some sort.

In the original COBOL specification there is the infamous "ALTER X TO PROCEED TO Y" statement which modify a GOTO X in a GOTO Y.
COME FROM is the reason INTERCAL is among my favorite esoteric programming languages. That and the fact that its name is for "Compiler Language With No Pronounceable Acronym".

From Wikipedia: An actual example in INTERCAL would be too difficult to read

Gotta love it.

It's actually "An actual example in INTERCAL would be too difficult to read[citation needed]"

Some people have a wicked sense of humour

Reminds me of TWAIN

Toolkit Without An Interesting Name

You want to make $85 hourly and $7000 per month like me just working on laptop for few hours! Would you like to be your own boss!Opportunities like this don't come by often. Don't let this one pass you by! CashHuge. com