

(Ab)Using Language Features: The Common Lisp Condition System - jmdavis
http://www.dawnofthedata.com/2014/05/abusing-langauge-features-common-lisp.html

======
howeyc
This was something I really loved during my time in Common Lisp. This was a
gem that I was hoping would make it into Clojure, but I think around version
1.3 they decided to abandon the idea and add a library to "make anything
throwable" which totally missed the point in my opinion.

Are there any other languages that allow the calling scope to specify how
lower-level functions handle errors without unwinding the stack?

~~~
kbenson
Perl 6 allows for handling exception in a same-scope CATCH block, so you can
try to recover. It can probably be mixed with their phasers[1] in interesting
ways. Also of interest might be control exceptions[2].

1:
[http://perlcabal.org/syn/S04.html#Phasers](http://perlcabal.org/syn/S04.html#Phasers)

2:
[http://perlcabal.org/syn/S04.html#Control_Exceptions](http://perlcabal.org/syn/S04.html#Control_Exceptions)

~~~
draegtun
Here is an interesting perl6 example which works in Rakudo:

    
    
      $ perl6
    
      > $*PERL<name>;
      rakudo
    
      > $*PERL<compiler><ver>;
      2014.03.01
    
      > { CONTROL { print 1; $_.resume }; print 2; warn; say 3 }
      213
    

ref:
[https://news.ycombinator.com/item?id=7192294](https://news.ycombinator.com/item?id=7192294)

For a perl5 Condition System see this implementation -
[https://metacpan.org/pod/ConditionSystem](https://metacpan.org/pod/ConditionSystem)

~~~
mst
That one's still exception based. You wanted

[http://p3rl.org/Worlogog::Incident](http://p3rl.org/Worlogog::Incident)
[http://p3rl.org/Worlogog::Restart](http://p3rl.org/Worlogog::Restart)

which uses Return::MultiLevel to do stack unwinds that can pass through
try/catch constructs.

------
chaitanya
Interesting abuse of the Lisp Condition system.

If you'd like to read more, an excellent introduction to the Common Lisp
condition system is given in Practical Common Lisp:
[http://www.gigamonkeys.com/book/beyond-exception-handling-
co...](http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-
and-restarts.html)

And I wrote a tutorial on Common Lisp restarts, using them in a non-trivial
real world example:
[http://chaitanyagupta.com/lisp/restarts.html](http://chaitanyagupta.com/lisp/restarts.html)

------
reikonomusha
Here[0] is another example of extreme abuse of the condition system in order
to construct "dynamic data pipelines" in Lisp. Roughly, it provides the
ability of sending data to different parts of the call stack, and then
returning back to continue processing. It can do all of this without any
explicit use of variables, or without passing state around.

[0] PDF: [https://bitbucket.org/tarballs_are_good/dynamic-
collect/src/...](https://bitbucket.org/tarballs_are_good/dynamic-
collect/src/10d87a2d838ed6db568c8c826b7dea292e214795/dynamic-
collect.pdf?at=default)

------
Grue3
The post probably should've mentioned reader macros, since this is how you do
this sort of stuff "normally".

~~~
jmdavis
I originally had a section about reader macros but I ended up cutting it since
the article was running a little long.

Reader macros are great, but they work best when a token can unambiguously be
recognized by the reader as using some "special syntax" (usually involves a
'#' and then another dispatch character preceding the new syntax).

This is great when you're coming up with a brand-new syntax. But if you're
trying to match something that already exists, it's not easy

------
eudox
It's nice seeing Common Lisp posts on the front page.

~~~
pjmlp
Yes, even if the industry usage is not big, learning about other languages is
always a good way to improve our skills.

~~~
Dewie
If anything we tend to hear more about Scheme(s) on HN than Common Lisp, which
is even less associated with 'industry' (to my knowledge).

------
tolmasky
This reminds me of using _doesNotRecognizeToSelector:_ / _methodForSelector:_
in Objective-C to do similar tricks. For example, you can wire up a color
class to respond to any hexColor selector by catching the unimplemented ones:

    
    
        NSColor * color = [Colors h00FF00];
    

You can then parse the selector string when the runtime doesn't find an
appropriate method for it. As with all these tricks, it is of course
incredibly slower than just doing GetHexColor(char * hexString), but where's
the fun in that right.

------
rcthompson
This reminds me of Perl's AUTOLOAD, only for variable binding instead of
functions.

