* How to cast an imperative loop into a readable recursive function ? @ 2010-12-03 1:50 Katalin Sinkov 2010-12-03 2:17 ` Paul Rubin 2010-12-03 2:48 ` RG 0 siblings, 2 replies; 9+ messages in thread From: Katalin Sinkov @ 2010-12-03 1:50 UTC (permalink / raw) To: help-gnu-emacs Background : This is strictly a style question about a solved problem. I wrote pseudocode in {} and converted to () and it worked. The line count of both pseudocodes was similar. regexp part was the one left as pseudocode in both. casting was also needed of string-to-integer. How to cast an imperative loop into a readable recursive function ? What questions to ask to guide thinking to it ? Here is the concrete problem. which is to find the nth character T_n in a string with erratic index reset and length of substring given. ie The string is preceeded by a value of start index s and length l (s=4,l=16)ab5csoikowlfg02c(s=39,l=23)rli3ubxvadf36ut8uguhijh(...)...### There can be gaps and the value of n is reset and usually greater but no need to make the assumption and the first one with the desired index is acceptable. ### denotes the end of the sequence. It is not guaranteed so a (message) should be echoed in the situation of error. I have written this as a loop and an (if test then else) inside it. Readablility is acceptable, however, I look for a lispy recursive style. (let ((char_skips (- n s) )) (while (not (= char_skips 0)) (progn (if (<= char_skips (+ l -1) ) (progn (forward-char char_skips) (setq char_skips 0)) (progn (forward-char l) (forward-search-regexp "(s=###l=###)" nil nil nil) ; put in an if and else block to test if FAIL (setq s (match-string 0)) (setq l (match-string 0)) (setq char_skips (- n s) ) ) ) ) ) ) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to cast an imperative loop into a readable recursive function ? 2010-12-03 1:50 How to cast an imperative loop into a readable recursive function ? Katalin Sinkov @ 2010-12-03 2:17 ` Paul Rubin [not found] ` <8a5ef1e1-aab3-47bd-80e3-081f8dc65b0e@c39g2000yqi.googlegroups.com> 2010-12-03 2:48 ` RG 1 sibling, 1 reply; 9+ messages in thread From: Paul Rubin @ 2010-12-03 2:17 UTC (permalink / raw) To: help-gnu-emacs Katalin Sinkov <lispstylist@gmail.com> writes: > How to cast an imperative loop into a readable recursive function ? > What questions to ask to guide thinking to it ? The functional-programming answer is that you rarely need explicit recursion. You can instead usually use higher-order functions like map and reduce, that are defined in terms of recursion. Maybe you want to read SICP, if you haven't done so already? > Here is the concrete problem. > which is to find the nth character T_n in a string with erratic index > reset and length of substring given. ie I'm sorry, I couldn't understand the problem description. ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <8a5ef1e1-aab3-47bd-80e3-081f8dc65b0e@c39g2000yqi.googlegroups.com>]
[parent not found: <84a24d31-6379-4b81-ac65-b0d8642ab7da@37g2000prx.googlegroups.com>]
* Re: How to cast an imperative loop into a readable recursive function ? [not found] ` <84a24d31-6379-4b81-ac65-b0d8642ab7da@37g2000prx.googlegroups.com> @ 2010-12-03 3:30 ` Paul Rubin [not found] ` <0c1c00c1-61ef-42be-a2d3-db1ff31035e8@29g2000yqq.googlegroups.com> 2010-12-03 9:44 ` Tim Bradshaw 1 sibling, 1 reply; 9+ messages in thread From: Paul Rubin @ 2010-12-03 3:30 UTC (permalink / raw) To: help-gnu-emacs Katalin Sinkov <lispstylist@gmail.com> writes: > what I forgot to mention was that it should be possible to view the > subseries problem in a way that I dont have to go thru a loop but use > recursive definitions. The problem is still very confusing, but it sounds to me like maybe you want something like (untested): (defun foo (n str) (let ((s ...) (l ...) (p ...) ;; after reading the (s=2 l=4) prefix above, ;; p points past the end of it (if (< n l) (aref str (+ p n)) (foo (- n l) (substring str (+ p l))))))) ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <0c1c00c1-61ef-42be-a2d3-db1ff31035e8@29g2000yqq.googlegroups.com>]
* Re: How to cast an imperative loop into a readable recursive function ? [not found] ` <0c1c00c1-61ef-42be-a2d3-db1ff31035e8@29g2000yqq.googlegroups.com> @ 2010-12-03 7:29 ` Paul Rubin 0 siblings, 0 replies; 9+ messages in thread From: Paul Rubin @ 2010-12-03 7:29 UTC (permalink / raw) To: help-gnu-emacs Katalin Sinkov <lispstylist@gmail.com> writes: >> (let ((s ...) (l ...) (p ...) >> ;;; s=start l=length p=?????? I don't mean p is actually a pointer, I just mean p is the offset after your (l=2 s=3) stuff that you matched with a regexp in your original example. > At some stage there will confusion and readability issue. > What strategies are there to grapple with this issue ? Why don't you read some of the Emacs library code? That is basically how I learned Lisp. Or, CL has a real package system so you can do more serious encapsulation. So you could read a CL book and apply the techniques to Emacs Lisp as best you can. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to cast an imperative loop into a readable recursive function ? [not found] ` <84a24d31-6379-4b81-ac65-b0d8642ab7da@37g2000prx.googlegroups.com> 2010-12-03 3:30 ` Paul Rubin @ 2010-12-03 9:44 ` Tim Bradshaw 1 sibling, 0 replies; 9+ messages in thread From: Tim Bradshaw @ 2010-12-03 9:44 UTC (permalink / raw) To: help-gnu-emacs On 2010-12-03 03:19:43 +0000, Katalin Sinkov said: > your iterate is again a loop, ie a non-functional construct Is it? Consider this form: (for (i 0 100) (print i)) This is iterative, right, I mean obviously. Except here's the definition of FOR: (defmacro for ((var min max) &body decls-and-forms) (let ((maxn (make-symbol "MAX")) (nextn (make-symbol "NEXT-1"))) `(let ((,maxn ,max)) (labels ((,nextn (,var) (when (= ,var ,maxn) (return-from ,nextn ,maxn)) (let ((,var ,var)) ,@decls-and-forms) (,nextn (1+ ,var))) (next () (,nextn (1+ ,var)))) (,nextn ,min))))) There seems to be no iteration there, and expanding (and renaming gensyms to make it clearer): (let ((max 100)) (labels ((next-1 (i) (when (= i max) (return-from next-1 max)) (let ((i i)) (print i)) (next-1 (1+ i))) (next () (next-1 (1+ i)))) (next-1 0))) No iteration there. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to cast an imperative loop into a readable recursive function ? 2010-12-03 1:50 How to cast an imperative loop into a readable recursive function ? Katalin Sinkov 2010-12-03 2:17 ` Paul Rubin @ 2010-12-03 2:48 ` RG 2010-12-03 3:12 ` Katalin Sinkov 1 sibling, 1 reply; 9+ messages in thread From: RG @ 2010-12-03 2:48 UTC (permalink / raw) To: help-gnu-emacs In article <ffc3587e-3cb3-41f6-9b2f-80a22d5095d1@e20g2000vbn.googlegroups.com>, Katalin Sinkov <lispstylist@gmail.com> wrote: > How to cast an imperative loop into a readable recursive function ? What is a readable function? Ignoring that part, you can always rewrite something like: (while condition ...) as (iterate loop () (when condition ... (loop))) where iterate is defined as: (defmacro iterate (name args &rest body) `(labels ((,name ,(mapcar 'first args) ,@body)) (,name ,@(mapcar 'second args)))) Is that what you meant? rg ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to cast an imperative loop into a readable recursive function ? 2010-12-03 2:48 ` RG @ 2010-12-03 3:12 ` Katalin Sinkov [not found] ` <7xk4jrmtmg.fsf@ruckus.brouhaha.com> [not found] ` <87ipzbpgft.fsf@kuiper.lan.informatimago.com> 0 siblings, 2 replies; 9+ messages in thread From: Katalin Sinkov @ 2010-12-03 3:12 UTC (permalink / raw) To: help-gnu-emacs On Dec 2, 6:48 pm, RG <rNOSPA...@flownet.com> wrote: > In article > <ffc3587e-3cb3-41f6-9b2f-80a22d509...@e20g2000vbn.googlegroups.com>, > Katalin Sinkov <lispstyl...@gmail.com> wrote: > > > How to cast an imperative loop into a readable recursive function ? > > What is a readable function? for a beginner like me, i was able to read those in McCarthy's paper, beautifully written recursive functions. > Ignoring that part, you can always rewrite something like: > > (while condition ...) > > as > > (iterate loop () > (when condition ... (loop))) > > where iterate is defined as: > > (defmacro iterate (name args &rest body) > `(labels ((,name ,(mapcar 'first args) ,@body)) > (,name ,@(mapcar 'second args)))) > > Is that what you meant? > I am sorry that this is not what I have in mind. I am thinking of how McCarthy wrote all those difficult concepts nicely as recursive functions. He dissected a problem ingeniously to not have to iterate. In my case, I have a pattern that is often interrupted by a reset of the index. It is trivial to go to nth character in a string because the indices are contiguous. However, in this case, the indices are often reset, but mercifully, although not necessary, the length of the contiguous index sequence is also given so we dont have to look for beginning paren at every step. Take a look at my lisp code. it can be modified simply to run it and it runs in an emacs "ide". ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <7xk4jrmtmg.fsf@ruckus.brouhaha.com>]
* Re: How to cast an imperative loop into a readable recursive function ? [not found] ` <7xk4jrmtmg.fsf@ruckus.brouhaha.com> @ 2010-12-03 3:22 ` Katalin Sinkov 0 siblings, 0 replies; 9+ messages in thread From: Katalin Sinkov @ 2010-12-03 3:22 UTC (permalink / raw) To: help-gnu-emacs On Dec 2, 7:18 pm, Paul Rubin <no.em...@nospam.invalid> wrote: > Katalin Sinkov <lispstyl...@gmail.com> writes: > > I am thinking of how McCarthy wrote all those difficult concepts > > nicely as recursive functions. He dissected a problem ingeniously to > > not have to iterate. > > If you like mathematical treatments, you might look for some of Richard > Bird's papers on program refinement. math would be an overkill and not needed. its issue of programming style. ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <87ipzbpgft.fsf@kuiper.lan.informatimago.com>]
* Re: How to cast an imperative loop into a readable recursive function ? [not found] ` <87ipzbpgft.fsf@kuiper.lan.informatimago.com> @ 2010-12-03 7:37 ` Katalin Sinkov 0 siblings, 0 replies; 9+ messages in thread From: Katalin Sinkov @ 2010-12-03 7:37 UTC (permalink / raw) To: help-gnu-emacs On Dec 2, 9:35 pm, "Pascal J. Bourguignon" <p...@informatimago.com> wrote: > Katalin Sinkov <lispstyl...@gmail.com> writes: > > Take a look at my lisp code. it can be modified simply to run it and > > it runs in an emacs "ide". > > No it does not. > > First, it's lacking a parenthesis. > > You should get paredit.el, and activate the paredit-mode to edit lisp > sources. See how lisp code is indented, and let emacs and paredit > indent it for you, and place the parentheses for you. This will produce > lisp code that is more readable, and you will be able to copy-and-paste > sexps "structurally", with much less risk of losing parentheses. > > Then, if we add the obvious missing parenthesis, and try to evaluate > your code: > > (let ((char_skips (- n s) )) > (while (not (= char_skips 0)) > (progn > (if (<= char_skips (+ l -1) ) > (progn > (forward-char char_skips) > (setq char_skips 0)) > (progn > (forward-char l) > > (forward-search-regexp "(s=###l=###)" nil nil nil) ; put in an if > ;; and else block to test if FAIL > (setq s (match-string 0)) > (setq l (match-string 0)) > > (setq char_skips (- n s) )))))) > > we get the following error: > > Debugger entered--Lisp error: (void-variable n) > (- n s) > (let ((char_skips ...)) (while (not ...) (progn ...))) > eval((let ((char_skips ...)) (while (not ...) (progn ...)))) > eval-last-sexp-1(nil) > eval-last-sexp(nil) > call-interactively(eval-last-sexp nil nil) > > If you want us to help, please provide working stand alone code, with > test data. > > (By the way, my emacs "23.2.1" doesn't have a forward-search-regexp > function). search-forward-regexp more later tomorrow > > -- > __Pascal Bourguignon__ http://www.informatimago.com/ > A bad day in () is better than a good day in {}. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-12-03 9:44 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-12-03 1:50 How to cast an imperative loop into a readable recursive function ? Katalin Sinkov 2010-12-03 2:17 ` Paul Rubin [not found] ` <8a5ef1e1-aab3-47bd-80e3-081f8dc65b0e@c39g2000yqi.googlegroups.com> [not found] ` <84a24d31-6379-4b81-ac65-b0d8642ab7da@37g2000prx.googlegroups.com> 2010-12-03 3:30 ` Paul Rubin [not found] ` <0c1c00c1-61ef-42be-a2d3-db1ff31035e8@29g2000yqq.googlegroups.com> 2010-12-03 7:29 ` Paul Rubin 2010-12-03 9:44 ` Tim Bradshaw 2010-12-03 2:48 ` RG 2010-12-03 3:12 ` Katalin Sinkov [not found] ` <7xk4jrmtmg.fsf@ruckus.brouhaha.com> 2010-12-03 3:22 ` Katalin Sinkov [not found] ` <87ipzbpgft.fsf@kuiper.lan.informatimago.com> 2010-12-03 7:37 ` Katalin Sinkov
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.