[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

catch-case

Taoufik Dachraoui

8/15/2015 11:32:00 AM

Hi

May be the following is useful for someone

(defmacro catch-case (form &rest cases)
(let ((r (gensym))
(a (loop for i in cases collect (cons (car i) (gensym))))
(b (loop for i in cases collect (cons (car i) (gensym)))))
`(let (,r ,@(loop for i in a collect (cdr i)))
(declare (special ,@(loop for i in b collect (cdr i))))
,(reduce #'(lambda (q p)
`(setq ,(cdr (assoc (car p) b))
(catch ,(car p) ,q (setq ,(cdr (assoc (car p) a)) t))))
(cons `(setq ,r ,form) (reverse cases)))
(cond
,@(loop for p in cases
collect `((null ,(cdr (assoc (car p) a)))
,(if (null (cdr p))
(cdr (assoc (car p) b))
(cadr p))))
(t ,r)))))

? (catch-case (throw 'a 5) ('a 2) ('b 3))
2
? (catch-case (throw 'b 10) ('a 2) ('b))
10


-Taoufik
15 Answers

The Peeler

6/5/2013 5:52:00 PM

0

On Wed, 05 Jun 2013 06:02:24 -0700, The Rectum, the resident psychopath of
sci and scj, FAKING his time zone again and IMPERSONATING his master, The
Peeler, wrote:


>>
>>This is what most Jewish people probably belief, because they follow
>>Rambam/Maimonides:
>
> Ram bam thank you maam! <G>

<BG> It's alright, poor handicapped little idiot! <pat> <pat>

--
Retarded, anal, subnormal and extremely proud of it: our resident
psychopath, The Retard (aka "The Rectum").

The Peeler

6/6/2013 12:46:00 AM

0

On Wed, 5 Jun 2013 19:51:59 +0200, The Peeler
<finishingoff@themoronicRevd.invalid> wrote:

>On Wed, 05 Jun 2013 06:02:24 -0700, The Rectum, the resident psychopath of
>sci and scj, FAKING his time zone again and IMPERSONATING his master, The
>Peeler, wrote:
>
>
>>>
>>>This is what most Jewish people probably belief, because they follow
>>>Rambam/Maimonides:
>>
>> Ram bam thank you maam! <G>
>
><BG> It's alright, I'm just a poor handicapped little Grik idiot! <pat> <pat>

<GB> YOU ARE Grik anus! <KICK> <KICK>

William James

8/15/2015 12:17:00 PM

0

Taoufik Dachraoui wrote:

> (loop for i in cases collect (cons (car i) (gensym)))

Let's translate that from CL (COBOL-Like) to a Lispy language.

Gauche Scheme:

(map (lambda (x) (cons (car x) (gensym))) cases)

--
The Ortagard school in Rosengard, an area of Malmo with close to 100% Muslim
immigrants, is burning yet again. Several police patrols are called out. But
Prime Minister Persson has already been escorted by special security police
into his bulletproof Volvo....
--- fjordman.blogspot.ca/2005/05/is-swedish-democracy-collapsing.html

Kaz Kylheku

8/15/2015 4:50:00 PM

0

On 2015-08-15, Taoufik Dachraoui <dachraoui.taoufik@gmail.com> wrote:
> Hi
>
> May be the following is useful for someone
>
(defmacro catch-case (form &rest cases)
(let ((r (gensym))
(a (loop for i in cases collect (cons (car i) (gensym))))
(b (loop for i in cases collect (cons (car i) (gensym)))))
`(let (,r ,@(loop for i in a collect (cdr i)))
(declare (special ,@(loop for i in b collect (cdr i))))
,(reduce #'(lambda (q p)
`(setq ,(cdr (assoc (car p) b))
(catch ,(car p) ,q (setq ,(cdr (assoc (car p) a)) t))))
(cons `(setq ,r ,form) (reverse cases)))
(cond
,@(loop for p in cases
collect `((null ,(cdr (assoc (car p) a)))
,(if (null (cdr p))
(cdr (assoc (car p) b))
(cadr p))))
(t ,r)))))
>
> ? (catch-case (throw 'a 5) ('a 2) ('b 3))

This is macro; why the quoting in the syntax?

(catch-case <try-expr> {(<sym> <catch-expr>)}*)

(Or do you expect the symbols to be the results of evaluation? That
seems overkill. A variant macro like catch-case* can be provided
to support that rare use case.)

Implementation:

(defmacro catch-case (try-expr &rest clauses)
(let ((normal-ret-sym (gensym))
(try-ret-tmp (gensym))
(catch-tmp (gensym)))
(labels ((expander (try-expr clauses)
(cond ((null clauses) try-expr)
((atom clauses) (error "catch-case: bad syntax"))
(t (destructuring-bind
(sym &optional (expr nil expr-present-p)) (first clauses)
(expander `(let* (,try-ret-tmp
(,catch-tmp (catch ',sym
(setf ,try-ret-tmp
,try-expr)
',normal-ret-sym)))
(if (eq ,catch-tmp ',normal-ret-sym)
,try-ret-tmp
,(if expr-present-p expr catch-tmp)))
(rest clauses)))))))
(expander try-expr clauses))))

Some tests:

[1]> (catch-case 42)
42
[2]> (catch-case nil)
NIL
[3]> (catch-case (throw 'x 42))

*** - THROW: there is no CATCHer for tag X
The following restarts are available:
ABORT :R1 Abort main loop
Break 1 [4]> :a
[5]> (catch-case 42 (a))
42
[6]> (catch-case (throw 'a 42) (a))
42
[7]> (catch-case 42 (a 1))
42
[8]> (catch-case (throw 'a 42) (a))
42
[9]> (catch-case (throw 'a 42) (a 1))
1
[10]> (catch-case (throw 'a 42) (a 1) (b 2) (c) (d 4))
1
[11]> (catch-case (throw 'b 42) (a 1) (b 2) (c) (d 4))
2
[12]> (catch-case (throw 'c 42) (a 1) (b 2) (c) (d 4))
42
[13]> (catch-case (throw 'd 42) (a 1) (b 2) (c) (d 4))
4
[14]> (catch-case (throw 'x 42) (a 1) (b 2) (c) (d 4))

*** - THROW: there is no CATCHer for tag X
The following restarts are available:
ABORT :R1 Abort main loop

Taoufik Dachraoui

8/15/2015 5:17:00 PM

0

Kaz Wrote
>This is macro; why the quoting in the syntax?

From CLHS

(catch tag form*) => result*

tag---a catch tag; evaluated.

? (let ((a 'x)) (catch-case (throw 'x 1) (a) ('b 3)))
1
? (let ((a 'x)) (catch-case (throw a 1) (a) ('b 3)))
1


-Taoufik

Kaz Kylheku

8/15/2015 5:30:00 PM

0

On 2015-08-15, Kaz Kylheku <kaz@kylheku.com> wrote:
> Implementation:
>
> (defmacro catch-case (try-expr &rest clauses)


We can probably simplify the implmentation considerably if we first invent
a different catch operator, and then target that.

I give you catch-if:


;;
;; - establish catch tag tag
;; - evaluate expr under this tag
;; - if expr throws tag, then bind the throw value to var,
;; and evaluate consequent such that var is visible to it.
;; - otherwise if alternative is present, bind the normal return
;; value of expr to var and evaluate alternative such that var is
;; visible to it.
;; - otherwise if alternative is missing, return the value of expr.
;;
(defmacro catch-if (tag expr var consequent &optional (alternative nil have-alt-p))
(let ((ret-var (gensym))
(catch-var (gensym))
(uniq (gensym)))
`(let* ((,ret-var ',uniq)
(,catch-var (catch ',tag (setf ,ret-var ,expr))))
(if (eq ,ret-var ',uniq)
(let ((,var ,catch-var)) ,consequent)
,(if have-alt-p
`(let ((,var ,ret-var)) ,alternative)
ret-var)))))

Tests:

[1]> (catch-if tag 42 var (list 'thrown var) (list 'returned var))
(RETURNED 42)
[2]> (catch-if tag (throw 'tag 42) var (list 'thrown var) (list 'returned var))
(THROWN 42)

Optinoal alternative:

[3]> (catch-if tag (throw 'tag 42) var (list 'thrown var))
(THROWN 42)
[4]> (catch-if tag 42 var (list 'thrown var))
42

Taoufik Dachraoui

8/15/2015 5:34:00 PM

0

Kaz wrote
>(defmacro catch-case (try-expr &rest clauses)
> (let ((normal-ret-sym (gensym))
> (try-ret-tmp (gensym))
> (catch-tmp (gensym)))
> (labels ((expander (try-expr clauses)
> (cond ((null clauses) try-expr)
> ((atom clauses) (error "catch-case: bad syntax"))
> (t (destructuring-bind
> (sym &optional (expr nil expr-present-p)) (first clauses)
> (expander `(let* (,try-ret-tmp
> (,catch-tmp (catch ,sym

I replaced ',sym by ,sym

> (setf ,try-ret-tmp
> ,try-expr)
> ',normal-ret-sym)))
> (if (eq ,catch-tmp ',normal-ret-sym)
> ,try-ret-tmp
> ,(if expr-present-p expr catch-tmp)))
> (rest clauses)))))))
> (expander try-expr clauses))))

I like your implementation, I will use it if you don't mind

Thanks

Taoufik

Kaz Kylheku

8/15/2015 6:21:00 PM

0

On 2015-08-15, Taoufik Dachraoui <dachraoui.taoufik@gmail.com> wrote:
> Kaz Wrote
>>This is macro; why the quoting in the syntax?
>
> From CLHS

I mean why the quoting in YOUR catch-case syntax? You're in the driver's seat,
as the macro writer.

Taoufik Dachraoui

8/15/2015 6:51:00 PM

0

I think this implementation is even better:

(defmacro catch-case (expr &rest clauses)
(let ((result (gensym)) (r (gensym)))
(labels ((foo (c)
(if (null c)
`((throw ',result ,expr))
`((setq ,r (catch ,(caar c)
,@(foo (cdr c))))
(throw ',result ,(if (null (cadar c)) r (cadar c)))))))
`(let (,r)
(declare (special ,r))
(catch ',result
,@(foo clauses))))))

-Taoufik

Taoufik Dachraoui

8/15/2015 7:00:00 PM

0

I wrote:
>I think this implementation is even better:

I am not sure what is the better implementation

-Taoufik