Author Topic: _mapcar (recursive)  (Read 2911 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 812
_mapcar (recursive)
« on: February 14, 2017, 07:21:47 AM »
Hi swampers,
I was trying to practice (again) with recursions, so I tried to come up with something simple. Like applying a function to every element in the list and return the list of the results (same as mapcar). So heres my attempt:
Code - Auto/Visual Lisp: [Select]
  1. ; Simulating (mapcar) recursively:
  2. ; (_mapcar strcase '("a" "b" "c" "d" "e"))
  3. (defun _mapcar ( foo L )
  4.   (if (cdr L)
  5.     (cons (foo (car L)) (_mapcar foo (cdr L)))
  6.     (foo (car L))
  7.   )
  8. )  

But as you can see the problem I'm getting is:
Code: [Select]
_$ (_mapcar strcase '("a" "b" "c" "d" "e"))
("A" "B" "C" "D" . "E")
_$

So do you have any ideas how to properly construct this recursion?


EDIT:
I've seem to found a fix with changing the:
Code: [Select]
(foo (car L))to:
Code: [Select]
(list (foo (car L)))
Soo:
Code: [Select]
_$ (_mapcar strcase '("a" "b" "c" "d" "e"))
("A" "B" "C" "D" "E")
_$

Also Its interesting that theres no need to quote the function if its provided as an argument to another (just to avoid the eval).
Code: [Select]
_$ (_mapcar (lambda (x) (strcat (strcase x) (strcase x T))) '("a" "b" "c" "d" "e"))
("Aa" "Bb" "Cc" "Dd" "Ee")
_$

« Last Edit: February 14, 2017, 07:37:48 AM by Grrr1337 »
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: _mapcar (recursive)
« Reply #1 on: February 14, 2017, 09:02:56 AM »
Hint: cond, null, atom.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: _mapcar (recursive)
« Reply #2 on: February 14, 2017, 09:28:14 AM »
Hint: cond, null, atom.
Thanks for the hint, MP !
It really makes more sence using these functions within a recursion:
Code - Auto/Visual Lisp: [Select]
  1. ; Simulating (mapcar) recursively:
  2. ; _$ (_mapcar strcase '("a" "b" "c" "d" "e"))
  3. ; ("A" "B" "C" "D" "E")
  4. ; _$ (_mapcar (lambda (x) (strcat (strcase x) (strcase x T))) '("a" "b" "c" "d" "e"))
  5. ; ("Aa" "Bb" "Cc" "Dd" "Ee")
  6. ; _$
  7. (defun _mapcar ( foo L )
  8.   (cond
  9.     ( (null L) '() )
  10.     ( (atom L) (foo L) )
  11.     ( (cons (foo (car L)) (_mapcar foo (cdr L))) )
  12.   ); cond
  13. ); defun _mapcar

EDIT: and just tried the iterative way to inspect the difference:

Code - Auto/Visual Lisp: [Select]
  1. ; mapcar - Iterative
  2. ; _$ (_mapcar strcase '("a" "b" "c" "d" "e"))
  3. ; ("A" "B" "C" "D" "E")
  4. ; _$ (_mapcar (lambda (x) (strcat (strcase x) (strcase x T))) '("a" "b" "c" "d" "e"))
  5. ; ("Aa" "Bb" "Cc" "Dd" "Ee")
  6. ; _$
  7. (defun _mapcar ( foo L / rtn )
  8.   (while L
  9.     (setq rtn (cons (foo (car L)) rtn))
  10.     (setq L (cdr L))
  11.   ); while
  12.   (reverse rtn)
  13. ); defun _mapcar

The iterative seems easier to write, but the disadvantage would be that you could not dig into all of the list's attoms and apply some function to them (if a nested list is provided).
Example:
Code - Auto/Visual Lisp: [Select]
  1. (defun _mapcar ( foo L )
  2.   (cond
  3.     ( (null L) '() )
  4.     ( (atom L) (foo L) )
  5.     (
  6.       (cons
  7.         (if (atom (car L)) (foo (car L)) (_mapcar foo (car L)))
  8.         (_mapcar foo (cdr L))
  9.       )
  10.     )
  11.   ); cond
  12. ); defun _mapcar
  13. _MAPCAR
  14. _$ (_mapcar (lambda (x) (strcat (strcase x) (strcase x T))) '(("a") (("b")) ((("c"))) (("d" "e"))))
  15. (("Aa") (("Bb")) ((("Cc"))) (("Dd" "Ee")))
  16. _$
« Last Edit: February 14, 2017, 09:41:52 AM by Grrr1337 »
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: _mapcar (recursive)
« Reply #3 on: February 14, 2017, 12:30:44 PM »
Example:
Code - Auto/Visual Lisp: [Select]
  1. (defun _mapcar ( foo L )
  2.   (cond
  3.     ( (null L) '() )
  4.     ( (atom L) (foo L) )
  5.     (
  6.       (cons
  7.         (if (atom (car L)) (foo (car L)) (_mapcar foo (car L)))
  8.         (_mapcar foo (cdr L))
  9.       )
  10.     )
  11.   ); cond
  12. ); defun _mapcar
  13. _MAPCAR
  14. _$ (_mapcar (lambda (x) (strcat (strcase x) (strcase x T))) '(("a") (("b")) ((("c"))) (("d" "e"))))
  15. (("Aa") (("Bb")) ((("Cc"))) (("Dd" "Ee")))
  16. _$

 :wink:
Code - Auto/Visual Lisp: [Select]
  1. (defun nMapcar ( f l )
  2.     (cond
  3.         (   (null l) l)
  4.         (   (atom l) (f l))
  5.         (   (cons (nMapcar f (car l)) (nMapcar f (cdr l))))
  6.     )
  7. )

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: _mapcar (recursive)
« Reply #4 on: February 14, 2017, 02:25:31 PM »
:wink:
Code - Auto/Visual Lisp: [Select]
  1. (defun nMapcar ( f l )
  2.     (cond
  3.         (   (null l) l)
  4.         (   (atom l) (f l))
  5.         (   (cons (nMapcar f (car l)) (nMapcar f (cdr l))))
  6.     )
  7. )
This is very cleverly written! Thanks, Lee!  :yay!:
Honestly I didn't realised that here we'd come up with this nested mapcar function, although this was in my TODO subfuncitions list.

The main task for me was to understand on how to create a recursion and how it works.. so this was the simpliest example I could think of.
Now the conclusion I'm doing is:
To be successful in this - you have to start the recursive function from scratch (practice on writing), and being able to visualise how the code evaluates - so it digs to the verry bottom.
I've read several times tutorials about recursions - but it will take me some time for becomming good at this.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg