Arc Forumnew | comments | leaders | submit | taodach's commentslogin
1 point by taodach 5468 days ago | link | parent | on: Pattern matching

I liked the idea to use the form (:type var typename) like (:type x '(unsigned-byte 32)) and then replace funcall by typep (this was hinted to me by Greg Pfeil in openmcl-devel).

  (defun match-destruc (pat seq)
  (cond
    ((null pat) nil)
    ((symbolp pat) `(,pat (if (symbolp ,seq) ,seq (return-from nil nil))))
    ((atom pat)
     (list `(,pat
	     (if (atom ,seq) ,seq (return-from nil nil)))))
    ((eq :type (car pat))
     (list `(,(second pat)
	     (if (and (atom ,seq) (typep ,seq ,(third pat)))
		 ,seq (return-from nil nil)))))
    (t
     (let ((r 
	    (let* ((p (car pat))
		   (var (gensym))
		   (rec (if (null (cdr pat))
			    nil
			    (cons `(,var (if (consp ,seq) (cdr ,seq)
					     (return-from nil nil)))
				  (match-destruc (cdr pat) var)))))
	      (if (atom p)
		  (cons `(,p (if (consp ,seq) (car ,seq)
				 (return-from nil nil))) rec)
		  (if (eq (car p) :type)
		      (cons `(,(second p) 
			      (if (and (consp ,seq) 
				       (typep (car ,seq) ,(third p)))
				  (car ,seq) 
				  (return-from nil nil))) rec)
		      (append (match-destruc 
			       p 
			       `(if (consp ,seq)
				    (car ,seq)
				    (return-from nil nil)))
			      rec))))))
       (if (null (cdr pat))
	   (cons `(,(gensym) ; dummy (should be declared to ignore)
		   (if (not (and (consp ,seq) (null (cdr ,seq))))
		       (return-from nil nil)))
		 r)
	   r)))))
Usage: ? (with-match-destruc (a (b c) (d (:type e 'symbol)) f) (2 (3 4) (5 x) 6) (list a b c d e f))

Please note that the complexity of match-destruc is O(n) and the generated code is also O(n)

Taoufik

-----

2 points by rocketnia 5467 days ago | link

I disagree with that change. You've made this...

  (:type var '(unsigned-byte 32))
...do what this used to do...

  (:type var (lambda (x) (typep x '(unsigned-byte 32))))
...but I don't think there's a replacement for this:

  (:type var (lambda (x) (and (numberp x) (<= 10 x))))
Maybe you should have both a (:type var 'symbol) form and a (:test var #'symbolp) form. ^_^

-----

1 point by taodach 5469 days ago | link | parent | on: Pattern matching

Can someone write this in Arc?

-----

1 point by rocketnia 5468 days ago | link

I did, but then my computer ate it! ><;; Sorry, I don't think I have time to try again. Maybe someone else will?

Here's a bit of a Rosetta Stone to help you out, or at least to give you an idea of how it would look:

  ; Common Lisp
  (let* ((a #'list)
         (b 1)
         (c 2))
    (begin nil
      (cond
        (a (funcall a 3 4 5))
        (b (return-from nil nil))
        (t 6))))
  
  ; Arc
  (withs (a list
          b 1
          c 2)
    (point foo
      (if a (a 3 4 5)
          b (foo nil)
            6)))
The rest should be a straightforward process of finding Arc functions that do the same things as the Common Lisp functions do. Here are some useful links for that: http://files.arcfn.com/doc/ http://files.arcfn.com/doc/fnindex.html They're a bit out-of-date in a couple of places though. :/

-----

1 point by taodach 5469 days ago | link | parent | on: Pattern matching

How do I format correctly the message body?

-----

1 point by aw 5469 days ago | link

Indent code blocks with two spaces to have them formatted as code.

http://arclanguage.org/formatdoc

-----