From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Pascal J. Bourguignon" Newsgroups: gmane.emacs.help Subject: Re: How to improve the readability of (any) LISP or any highlevel functional language to the level of FORTH ? Date: Thu, 06 Jan 2011 20:20:50 +0100 Organization: Informatimago Message-ID: <87bp3tdejx.fsf@kuiper.lan.informatimago.com> References: <80ceeca0-1d32-47d1-ba96-feb4d9729c3a@v17g2000yqv.googlegroups.com> <767329f7-d300-4090-93cb-717d70fbadc4@i17g2000vbq.googlegroups.com> <87ei8rdo38.fsf@kuiper.lan.informatimago.com> <4d25c5f5$0$23761$14726298@news.sunsite.dk> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1294344133 11748 80.91.229.12 (6 Jan 2011 20:02:13 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 6 Jan 2011 20:02:13 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Thu Jan 06 21:02:09 2011 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Paw1h-0002M3-0N for geh-help-gnu-emacs@m.gmane.org; Thu, 06 Jan 2011 21:02:02 +0100 Original-Received: from localhost ([127.0.0.1]:41037 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PavnI-00034m-A5 for geh-help-gnu-emacs@m.gmane.org; Thu, 06 Jan 2011 14:46:44 -0500 Original-Path: usenet.stanford.edu!news.tele.dk!news.tele.dk!small.news.tele.dk!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: comp.lang.functional, comp.lang.lisp, gnu.emacs.help, comp.lang.forth, comp.lang.prolog Original-Lines: 102 Original-X-Trace: individual.net rRW9tPIZgZWEFicwZNzZWQxG99pNoO49ra5kpfmNEcK2p6tRYD Cancel-Lock: sha1:NTU2Yjg1NWQ4ZWZlM2ZkYzRmN2Q5OWE1NGE3NjA5ZDU3OTkwMGMwOQ== sha1:hOnpNX/TIYrBweW/JmnSErQ2yXc= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) Original-Xref: usenet.stanford.edu comp.lang.functional:69133 comp.lang.lisp:297356 gnu.emacs.help:184072 comp.lang.forth:160404 comp.lang.prolog:44052 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:78267 Archived-At: Doug Hoffman writes: > 2) The following is one way (of many) to approach this in standard Forth: > > : quad f{ a b c -- root } > b FNEGATE b FDUP F* 4e a c F* F* F- FSQRT F+ 2e a F* F/ > ; > > -2e 7e 15e quad f. > -1.500000 > > Is it readable? Unless you're a Forther I would say no. But notice > the complete lack of parentheses and operator precedences to resolve. > Any competent Forther could quickly see exactly what is going on. Now, as a Forth programmer, ask yourself what you would have to do, to call an operator with a variable arity? In Postscript, there is a mark operator, to push a mark on the stack, so that a next operator of variable arity may collect a variable number of arguments, up to that mark. Then, as a Forth programmer, ask yourself what you would need to be able to parse a Forth expression containing unknown operators, ie. operators of unknown (possibly fixed, but also variable) arity?] If you consider a separate table giving the arity of the operators, then it is not unknown anymore. The only solution I know, is to use mark systematically: MARK MARK MARK MARK MARK b FNEGATE FDUP F* MARK 4e a c F* F- FSQRT F+ MARK 2e a F* F/ Then, we may add some syntactic sugar, replacing call the MARK operator '(', and adding gratuituous balanced ')' after each operator: (((((((b -) FDUP) f*) (4e a c F*) F-) FSQRT) F+) (2e a F*) F/) Finally, we may apply mechanically a recursive reverse: (defun rrev (x) (if (listp x) (mapcar 'rrev (reverse x)) x)) (rrev '(((((((b -) FDUP) f*) (4e a c F*) F-) FSQRT) F+) (2e a F*) F/)) (F/ (F* a 2e) (F+ (FSQRT (F- (F* c a 4e) (F* (FDUP (- b))))))) so it becomes readable again and you can see there's a bug in the Forth expression. Since the syntax become suddenly much simplier, we don't need to prefix operators with 'F' anymore. So we can write merely: (/ (* a 2) (+ (sqrt (- (* c a 4) (* (dup (- b))))))) Anyways, the great thing now, is that we have homoiconicity (notice how I used the parenthesised source expression as data passed to rrev), and we can process expressions without knowing the arity of the operators (the operators may even not be defined before we process expressions using them!). For example, we could now write: (derivate '(/ (* a 2) (+ (sqrt (- (* c a 4) (* (dup (- b))))))) 'a) and get: --> (- (/ 2 (sqrt (- (* 4 a c) (* b b)))) (/ (* 4 a c) (expt (sqrt (- (* 4 a c) (* b b))) 3/2))) and since this is one of the first applications of Lisp, you can see now the reasons and advantages why lisp has these parentheses. Of course, that doesn't preclude writing in lisp symbolic mathematic programs like maxima, providing the mathematical user with a more usual infix input and 2D output: http://www.informatimago.com/images/example-maxima.png > 3) We have available in Forth a FORmula TRANslator utility (it is not > part of the official ANS Forth standard). It could be applied in this > situation as follows: > > : quad2 f{ a b c -- root } > f' (-b + sqrt(b^2 - 4*a*c))/(2*a)' > ; There are also infix-to-lisp utilities to embed infix expressions in lisp program. If you had to implement a program with a lot of mathematical formula to copy from a book, I guess these utility would come handy. -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}.