# Common Lisp conditions

**URL:** <https://www.ruby-forum.com/t/common-lisp-conditions/161110>\
**Category:** Ruby\
**Created:** [February 23, 2009, 3:00pm UTC](https://www.ruby-forum.com/t/common-lisp-conditions/161110 "2009-02-23T15:00:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [February 23, 2009, 3:00pm UTC](https://www.ruby-forum.com/t/common-lisp-conditions/161110/1 "2009-02-23T15:00:41Z")

</div>

Hi,

So far as the search engine on this newsgroup is concerned, there’s  
been no discussion about including a Common Lisp-style condition  
system in a future version of Ruby. For information about these, [1]  
is a good readable resource.

For those who don’t know what they offer above normal exception-  
handling (as we know it in Ruby, Java, C++, …), conditions need not  
be errors and they need not unwind the stack. A low-level function  
can signal that something is wrong, and provide multiple ways of  
handling it (which is appropriate, because the handling code is low-  
level). A high-level function can receive the signal and choose which  
low-level handler to run, or can “handle” it itself or ignore it (the  
latter two options being what’s available in Ruby etc.). Another good  
example is low-level code issuing a warning and higher-level code  
deciding whether to print it. It’s _very_ elegant.

For those who _do_ know about Common Lisp conditions, is there any  
appetite for them in Ruby? I see great positives and no negatives.  
They don’t seem at all un-Ruby-like; in fact the relationship between  
high- and low-level code reminds me of the elegance of blocks and  
yield.

After a small amount of thought, I haven’t come up with a suitable  
syntax. That’s probably because I haven’t used the things, only read  
about them.

Just curious about people’s thoughts, and quietly hopeful for Ruby  
2.0 🙂

Gavin

[1]  
[http://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html](http://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html)

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [February 25, 2009, 9:23pm UTC](https://www.ruby-forum.com/t/common-lisp-conditions/161110/2 "2009-02-25T21:23:32Z")

</div>

Gavin S. wrote:

> So far as the search engine on this newsgroup is concerned, there’s  
> been no discussion about including a Common Lisp-style condition  
> system in a future version of Ruby.  
> […]  
> For those who _do_ know about Common Lisp conditions, is there any  
> appetite for them in Ruby? I see great positives and no negatives.  
> They don’t seem at all un-Ruby-like; in fact the relationship between  
> high- and low-level code reminds me of the elegance of blocks and  
> yield.

They seem to work very well in Ola B.'s new language Ioke  
([http://Ioke.Org/](http://Ioke.Org/)), which borrows heavily from Ruby. So, I agree:  
they would fit very well. Replacing Exceptions with Conditions could  
probably even be done in a (somewhat) backwards-compatible way. Maybe  
they could replace throw/catch, too.

> After a small amount of thought, I haven’t come up with a suitable  
> syntax. That’s probably because I haven’t used the things, only read  
> about them.

I just tried converting the example from Practical Common Lisp, but it  
isn’t too pretty. I hope that’s because I mis-translated the original  
procedural Common Lisp into pseudo-OO Ruby and not because my chosen  
syntax is ugly.

```
class MalformedLogEntryError < RuntimeError
  def initialize text
    @text = text
  end
  attr_reader :text
end

class LogEntryParser
  def parse_log_entry text
    error MalformedLogEntryError.new(text) unless 

```

text.wellformed\_log\_entry?  
LogEntry.new( … )  
restart use\_value(value)  
value  
restart reparse\_entry(fixed\_text)  
parse\_log\_entry fixed\_text  
end  
end

```
class LogfileParser
  def parse_log_file file
    File.each_line(file).map do |line|
      begin
        @log_entry_parser.parse_log_entry text
      restart skip_log_entry
        nil
      end
    end
  end
end

class LogAnalyzer
  def main
    find_all_logs.each do |log|
      analyze_log log
    end
  handle MalformedLogEntryError
    restart skip_log_entry
  end

  def analyze_log log
    @logfile_parser.parse_log_file(log).each do |entry|
      analyze_entry entry
    end
  end
end

class StrictLogAnalyzer # Annotates malformed entries instead of 

```

ignoring  
def main  
super  
handle MalformedLogEntryError =\> c  
MalformedLogEntry.new(c.text)  
end  
end

jwm

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [February 25, 2009, 11:20pm UTC](https://www.ruby-forum.com/t/common-lisp-conditions/161110/3 "2009-02-25T23:20:42Z")

</div>

Gavin S. wrote:

> So far as the search engine on this newsgroup is concerned, there’s  
> been no discussion about including a Common Lisp-style condition  
> system in a future version of Ruby.  
> […]  
> For those who _do_ know about Common Lisp conditions, is there any  
> appetite for them in Ruby? I see great positives and no negatives.  
> They don’t seem at all un-Ruby-like; in fact the relationship between  
> high- and low-level code reminds me of the elegance of blocks and  
> yield.

They seem to work very well in Ola B.'s new language Ioke  
([http://Ioke.Org/](http://Ioke.Org/)), which borrows heavily from Ruby. So, I agree:  
they would fit very well. Replacing Exceptions with Conditions could  
probably even be done in a (somewhat) backwards-compatible way. Maybe  
they could replace throw/catch, too.

> After a small amount of thought, I haven’t come up with a suitable  
> syntax. That’s probably because I haven’t used the things, only read  
> about them.

[Supersede: my original article had an example translation of the code  
example from the book Practical Common Lisp, but my translation was,  
for lack of a better word, bullshit. So I deleted it.]

jwm

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [February 27, 2009, 10:28pm UTC](https://www.ruby-forum.com/t/common-lisp-conditions/161110/4 "2009-02-27T22:28:20Z")

</div>

On Feb 27, 8:03 am, Christopher D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Exceptions don’t need to be errors in Ruby, though conventionally they  
> are used for that and throw/catch for similar non-errors. As far as  
> the additional functionality of conditions, its not that hard to  
> implement at least what I see as the most important one (restarts) on  
> top of Ruby’s existing exception-handling using continuations, e.g.,  
> in Ruby 1.8 (and, I would presume, Ruby 1.9 with the addition of  
> “require ‘continuation’” at the top:
> 
> [code snipped]

That’s very impressive and interesting, Christopher. Thanks!

Gavin

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [February 26, 2009, 10:05pm UTC](https://www.ruby-forum.com/t/common-lisp-conditions/161110/5 "2009-02-26T22:05:34Z")

</div>

On 2/23/09, Gavin S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> can signal that something is wrong, and provide multiple ways of  
> high- and low-level code reminds me of the elegance of blocks and
> 
> [1]  
> [Beyond Exception Handling: Conditions and Restarts](http://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html)

Exceptions don’t need to be errors in Ruby, though conventionally they  
are used for that and throw/catch for similar non-errors. As far as  
the additional functionality of conditions, its not that hard to  
implement at least what I see as the most important one (restarts) on  
top of Ruby’s existing exception-handling using continuations, e.g.,  
in Ruby 1.8 (and, I would presume, Ruby 1.9 with the addition of  
“require ‘continuation’” at the top:

# This code is untested on any but the demo case at the end.

class Condition \< Exception

FAIL = Object.new

def self.alert(\*args)  
block = (block\_given? ? lambda { |c| yield c } : nil)  
callcc { |cont| raise self.new(cont, block, \*args) }  
end

def initialize(c, block, \*args)  
@continuation = c  
@restarts = {}  
block.call(self) if block  
end

def add\_restart(restart\_name, &block)  
@restarts[restart\_name] = lambda do |\*args|  
result=block.call(self, \*args)  
@continuation.call(\*result) unless result==FAIL  
nil  
end  
self  
end

def restarts  
@restarts.dup  
end

def restart(restart\_name, \*args)  
@restarts[restart\_name].call(\*args) if @restarts.include?  
restart\_name  
end  
end

class BadValueCondition \< Condition  
attr\_reader :value

def initialize(c, block, val, \*args)  
@value = val  
super  
end  
end

def process\_value(val)  
if (val.div 2) == (val.quo 2)  
BadValueCondition.alert(val)  
else  
val.to\_s  
end  
end

def process(range)  
range.map { |val| process\_value(val) }.compact  
rescue BadValueCondition =\> c  
c.add\_restart(:ignore) {}  
c.add\_restart(:substitute\_warning) { |c, \*args| “Bad: #{c.value}” }  
raise  
end

[:ignore, :substitute\_warning].each do |strategy|  
begin  
puts “\n—\nDemonstrating restart #{strategy.inspect}”  
arr = process(1…10)  
puts arr.join(“\n”)  
rescue BadValueCondition =\> c  
c.restart(strategy)  
raise  
end  
end
