From ... Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed.stueberl.de!news.netway.at!nmaster.kpnqwest.net!nnum.kpnqwest.net!EU.net!nreader2.kpnqwest.net.POSTED!not-for-mail Newsgroups: comp.lang.lisp Subject: Re: The Parentheses Myth (was Re: new free web book on Common Lisp) References: <3CF691B4.8090609@markwatson.com> <3CF6B7FC.8659346B@nyc.rr.com> Mail-Copies-To: never From: Erik Naggum Message-ID: <3231925655526163@naggum.net> Organization: Naggum Software, Oslo, Norway Lines: 102 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Sat, 01 Jun 2002 13:07:38 GMT X-Complaints-To: newsmaster@KPNQwest.no X-Trace: nreader2.kpnqwest.net 1022936858 193.71.199.50 (Sat, 01 Jun 2002 15:07:38 MET DST) NNTP-Posting-Date: Sat, 01 Jun 2002 15:07:38 MET DST Xref: archiver1.google.com comp.lang.lisp:34272 * David Golden | I sometimes wonder if one merely changed that opening-paren-position bit | of lisp syntax, without worrying about infix v.s. prefix, would thousands | of c programmers suddenly "get" lisp... (It seems to work quite well for | what a c programmer would think of as programs, but what a c programmer | would think of as data structures look a bit funny...) This is in fact quite easy to automate. To give the feel for this way of writing the code, I have taken the liberty to convert a roman-numeral parser to the new style. Please note that this was made a lot easier because I now write my code in Common Salt syntax instead of just Common Lisp. In Common Salt, <> and () are both list operators, but <> hold an evaluatable form (or an XML-style "element"), whereas () simply hold a list as data. (This is at one level mere syntax -- the point is to support different "readers" in each element; the "readers" of macros and special operators know how to parse the rest of their input, but if you ask for it, you get more information.) E.g., ) (<= start end> 0) ( > <+ roman <1+ start> end digit unit half cont fail>>) (t fail>)>> Why Common Salt? Common Salt is NaCl, the Next Advancement in Common Lisp. ^ has the same function as \ in Common Lisp. \ got in the way too much. Now, this can easily be turned into the not-quite-prefix syntax: in-package (:cl-user) defun (parse-roman-digit-sequence, (count, roman, start, end, digit, unit, half, cont, fail), cond ((< (count, 0), funcall (fail, nil)), (= (start, end), 0), (equalp (char (roman, start), second (unit)) + (first (digit), parse-roman-digit-sequence (1- (count), roman, 1+ (start), end, digit, unit, half, cont, fail))), (t funcall (cont, roman, start, end, cdr (digit), cdr (unit), cdr (half), fail)))) defun (parse-old-roman-digit, (roman, start, end, digit, unit, half, fail), cond ((= (start end) 0), (null (digit), funcall (fail, nil)), (equalp (char (roman, start), first (half)) + (* (first (digit), 5), parse-old-roman-digit (roman, 1+ (start), end, digit, unit, cons (nil, cdr (half)), fail))), (t parse-roman-digit-sequence (4, roman, start, end, digit, unit, half, #'parse-old-roman-digit, fail)))) defun (parse-new-roman-digit, (roman, start, end, digit, unit, half, fail), cond ((= (start, end) 0), (null (digit), funcall (fail, nil)), (and (< (1+ (start), end), equalp (char (roman, start), second (unit)), equalp (char (roman, 1+ (start)), first (unit))) + (* (first (digit), 9), parse-new-roman-digit (roman, + (2, start), end, cdr (digit), cdr (unit), cdr (half), fail))), (and (< (1+ (start), end), equalp (char (roman, start), second (unit)), equalp (char (roman, 1+ (start)), first (half))) + (* (first (digit), 4), parse-new-roman-digit (roman, + (2, start), end, cdr (digit), cdr (unit), cdr (half), fail))), (equalp (char (roman, start), first (half)), + (* (first (digit), 5), parse-new-roman-digit (roman, 1+ (start), end, digit, cons (nil, cdr (unit)), cons (nil, cdr (half)), fail))), (t parse-roman-digit-sequence (3, roman, start, end, digit, unit, half, #'parse-new-roman-digit, fail)))) defun (parse-roman-integer, (roman, &key, (start, 0), end, old-style), "Return the integer represented by the valid roman numeral, or nil. Old-style uses four consecutive digits of a unit, while new-style uses the next smaller unit before the unit or half-unit.", setq (end, or (end, length (roman))), when (< (-1, start, end, 1+ (length (roman))), flet (((parse-failure, (value), return-from (parse-roman-integer, value))), funcall (if (old-style, #'parse-old-roman-digit, #'parse-new-roman-digit), roman, start, end, '(1000, 100, 10, 1), '(nil, #\M, #\C, #\X, #\I), '(nil, #\D, #\L, #\V), #'parse-failure)))) I sort of feel like I have just re-invented Dylan, but I mostly hope people are _really_ scared. (There are probably mistakes in the above. If you go look for them, you prove several interesting things about your psychology and realize that posting about it is yet another mistake.) -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief. 70 percent of American adults do not understand the scientific process.