strange result with map and apply

Q&A's, tips, howto's

strange result with map and apply

Postby fdb » Sat Apr 26, 2014 9:57 pm

Code: Select all
> (map (apply +) '((0 1 2) (3 4 5)))
((0 1 2) (3 4 5))
> (map (fn(x) (apply + x)) '((0 1 2) (3 4 5)))
(3 12)


Why doesn't the first example work?
fdb
 
Posts: 47
Joined: Sat Nov 09, 2013 8:49 pm

Re: strange result with map and apply

Postby bairui » Sat Apr 26, 2014 11:13 pm

With:

Code: Select all
(map (apply max) '((0 1 2) (3 4 5)))


we see the expected error:

ERR: missing argument in function max

I don't know why we don't see this with the + function, but the solution to both cases is to use curry:

Code: Select all
(map (curry apply +) '((0 1 2) (3 4 5)))
bairui
 
Posts: 64
Joined: Sun May 06, 2012 2:04 am
Location: China

Re: strange result with map and apply

Postby Lutz » Sun Apr 27, 2014 1:47 pm

Like in Scneme (+) or (apply +) evaluates to 0. So your map expression maps 0 onto two lists.
Using a number as operator is implicit resting. 0 gives you back the whole list.
Try also (map (apply *) '((0 1 2) (3 4 5))) to prove the point. Like in Scheme (*) gives 1.

So using curry for what you want is the right thing.
Lutz
 
Posts: 5276
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

Re: strange result with map and apply

Postby bairui » Mon Apr 28, 2014 1:19 am

Ah, that makes sense. Thanks, Lutz.
bairui
 
Posts: 64
Joined: Sun May 06, 2012 2:04 am
Location: China

Re: strange result with map and apply

Postby fdb » Mon Apr 28, 2014 9:49 pm

Thanks a lot bairui and Luts! Hadn't used curry before.

Another question i just encountered is how to change all items in a list in one go, for example:

Code: Select all
(set-ref-all "2" '(("1" "2" "3") ("4")) (int $it))
(("1" 2 "3") ("4"))


Works but i want to change all the strings to integers in one go but couldn't find an expression which matches
all the strings, see below some examples i tried but didn't work
Code: Select all
> (set-ref-all '((*)) '(("1" "2" "3") ("4")) (int $it))
nil
> (set-ref-all '(?) '(("1" "2" "3") ("4")) (int $it))
nil
> (set-ref-all '(*) '(("1" "2" "3") ("4")) (int $it))
nil
> (set-ref-all '(+) '(("1" "2" "3") ("4")) (int $it))
nil
> (set-ref-all ? '(("1" "2" "3") ("4")) (int $it))
nil
> (set-ref-all * '(("1" "2" "3") ("4")) (int $it))
nil

fdb
 
Posts: 47
Joined: Sat Nov 09, 2013 8:49 pm

Re: strange result with map and apply

Postby cormullion » Tue Apr 29, 2014 11:04 am

How about:

Code: Select all
(set-ref-all '(*) '(("1" "2" "3") ("4")) (map int $it) match)
;-> ((1 2 3) (4))


I admit that match is the one area in newLISP that I always fail to get right in the first few attempts... :)
cormullion
 
Posts: 2037
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W

Re: strange result with map and apply

Postby bairui » Tue Apr 29, 2014 12:54 pm

Not as veratile as cormullion's match solution, but works for the given example:

Code: Select all
(map (curry map int) '(("1" "2" "3") ("4")))
bairui
 
Posts: 64
Joined: Sun May 06, 2012 2:04 am
Location: China

Re: strange result with map and apply

Postby fdb » Tue Apr 29, 2014 7:19 pm

Thx!

I understood the function from bairui directly (why didn't i think of that..) but i had to look in the documentation to understand cormullion's solution and then i saw in the documentation this example:
(set-ref-all '(oranges *) data (list (first $it) (apply + (rest $it))) match) ....

Great docs, just have to read them more carefully next time.
fdb
 
Posts: 47
Joined: Sat Nov 09, 2013 8:49 pm


Return to newLISP in the real world

Who is online

Users browsing this forum: No registered users and 1 guest

cron