From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,703c4f68db81387d X-Google-Thread: 109fba,703c4f68db81387d X-Google-Thread: 115aec,703c4f68db81387d X-Google-Thread: f43e6,703c4f68db81387d X-Google-Attributes: gid103376,gid109fba,gid115aec,gidf43e6,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!news.glorb.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.rcn.net!news.rcn.net.POSTED!not-for-mail NNTP-Posting-Date: Mon, 28 Mar 2005 15:19:44 -0600 Sender: jsa@rigel.goldenthreadtech.com Newsgroups: comp.lang.ada,comp.lang.c++,comp.realtime,comp.software-eng Subject: Re: Teaching new tricks to an old dog (C++ -->Ada) References: <4229bad9$0$1019$afc38c87@news.optusnet.com.au> <1110032222.447846.167060@g14g2000cwa.googlegroups.com> <871xau9nlh.fsf@insalien.org> <3SjWd.103128$Vf.3969241@news000.worldonline.dk> <87r7iu85lf.fsf@insalien.org> <1110052142.832650@athnrd02> <1110284070.410136.205090@o13g2000cwo.googlegroups.com> <395uqaF5rhu2mU1@individual.net> <1111607633.301232.62490@z14g2000cwz.googlegroups.com> <1111628011.160315.134740@o13g2000cwo.googlegroups.com> <1111794348.874993.298340@g14g2000cwa.googlegroups.com> <1111827755.497376.232760@z14g2000cwz.googlegroups.com> From: jayessay Organization: Tangible Date: 28 Mar 2005 16:24:52 -0500 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 209.6.25.79 X-Trace: sv3-M224gD+zjuMtB0Li/D/+RUug9+BpmGpLWI5qZGyiX7MCjDxDIRYxgpkwfboU8eADp8bmXw65hEjFCrV!WZ2Bx+P/1iiX2c2RivAtBTmKJyzo0KmrRr8quOJ6R2v2Rk0cwHtQzmXtBzrHkx0LK6ONJOCALZSH X-Complaints-To: abuse@rcn.net X-DMCA-Complaints-To: abuse@rcn.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news1.google.com comp.lang.ada:10095 comp.lang.c++:47684 comp.realtime:1795 comp.software-eng:5432 Date: 2005-03-28T16:24:52-05:00 List-Id: Hyman Rosen writes: > Jerry Coffin wrote: > > I see. So what is it that (you incorrectly believe) the C preprocessor > > can do that a Lisp macro can't do? > > Can Lisp macros manipulate the text of the macro arguments? They don't manipulate text at all, but they _do_ manipulate the _un_evaluated forms passed to them. Here is a "top 5" list of why Lisp macros aren't anything like C preprocessor stuff. At the bottom I give an example. Top five reasons why Lisp macros are not similar to the C/C++ preprocessor in any meaningful sense. Number 5: The/a cpp is a, well, preprocessor. Typically a separate program even. While you could dilute the meaning here to the point where a compiler is a preprocessor for a linker is a processor for a loader is a preprocessor for a cpu etc., the typical meaning is that such things perform minor transformations on a block of input and had the result to the primary processor. Lisp macros are tightly bound up with both the definition of the total language and any implmentation of it. Also expansion time is interwoven with compilation, interpretation, or explicit evaluation. They are available and can be defined during any phase: compile, load, and execute/runtime. Number 4: The/a cpp is not Turing complete. Lisp macros are Turing complete. Number 3: The/a cpp processes text, typically from a text stream such as (most typically) a text file. Lisp macros process _data structures_. In particular the syntax trees output from the parser. Text is long gone before macros are involved at all. Number 2: The/a cpp doesn't know or have any access to the full language, user defined functions, or its environment. Lisp macros are just Lisp functions which can make use of the entire language, and any other user defined functions and macros in libraries or the running image. They also have access to their lexical environment information (such as type and profile information) as well as any public aspects of the global system/application. And the Number 1 reason why Lisp macros are not similar to the C/C++ preprocessor in any meaningful sense: Jerry Coffin thinks they are. ;-) and just to make sure :-) :-) ----------------------------- The astute reader will have noticed that it is C++ _templates_ which are slighly similar to Lisp macros. And they would be right. Templates are significantly less expressive and mind numbingly painful to use in comparison, but they are Turing complete and you can do some interesting things with them. For example, while it might take several pages of code, I think it is _physically_ possible (i.e., humanly doable not just theoretically doable) to achieve the (somewhat contrived) following example with templates. Note: I don't see how you can do this _in_ Ada at all. Allow a user/programmer to define a dictionary like object while ensuring at compile time that the size of the table implementing it is a prime number. (defun small-primep (n) (and (< 0 n most-positive-fixnum) (the-primes :from n :to n))) (deftype prime () `(and integer (satisfies small-primep))) (defmacro define-dictionary ((name &key (size 101) (test #'eql) (hash #'sxhash)) &body body) (assert (symbolp name) nil "Dictionary names must be symbols. ~A is of type ~A" name (type-of name)) (assert (typep size 'prime) nil (prime-failure-message size name)) `(defvar ,name ,(if body `(let ((it (make-hash-table :test ,test :size ,size :hash-function ,hash))) ,@(mapcar #'(lambda (p) `(setf (gethash ,(car p) it) ,(cdr p))) body) it) `(make-hash-table :test ,test :size ,size :hash-function ,hash)))) (defun prime-failure-message (n name) (concatenate 'string (format nil "Dictionary ~A: " name) (cond ((not (integerp n)) (format nil "~A of type ~A is not a number" n (type-of n))) ((< n 0) (format nil "~A < 0; Dictionary sizes must > 0 and prime numbers" n)) ((> n most-positive-fixnum) (format nil "Dictionary sizes must be prime numbers < ~A" most-positive-fixnum)) (t (format nil "~A is not prime; Next prime larger than ~A is ~A" n n (first (the-primes :from n :to (+ 1000 n)))))))) At _compile_ time (define-dictionary (foo :size 20)) produces: Error: Dictionary FOO: 20 is not prime; Next prime larger than 20 is 23 (define-dictionary (foo :size 23) (1 . "one") (2 . "two") (3 . "three")) Compiles, passes checks and produces the dictionary with the given entries. This generates the following code: (DEFVAR FOO (LET ((IT (MAKE-HASH-TABLE :TEST # :SIZE 23 :HASH-FUNCTION #))) (SETF (GETHASH 1 IT) "one") (SETF (GETHASH 2 IT) "two") (SETF (GETHASH 3 IT) "three") IT)) /Jon -- 'j' - a n t h o n y at romeo/charley/november com