Extending + to do int plus list 1 point by alimoeeny 3230 days ago | 6 comments Hey guys, I am trying to extend + so that I can add an int to a list (each item of the list). So far I am using lib/extend.arc and I have:`````` (extend + args (and (isa (car args) 'int) (isa (cdr args) 'cons) (> (len (flat(cdr args))) 1)) (map [+ _ (car args)] (flat (cdr args)))) `````` and it works fine with 1D matrices (lists). But I want to preserve my matrix structures. Like, I want to do:`````` (+ 3 '((1 2) (3 4))) `````` and get ((4 5 ) (6 7)) instead I get (4 5 6 7) now.Any suggestions?
 3 points by fallintothis 3230 days ago | link This isn't exactly like your code, since I wasn't sure what you wanted it to do in the case of three or more arguments, but the important part is the alternative to map.`````` (extend + (n xs . rest) (and (number n) (acons xs) (no rest)) (treewise cons [only.orig _ n] xs)) arc> (+ 3 '((1 2) (3 4))) ((4 5) (6 7)) arc> (+ 3 '(1 2 3)) (4 5 6) arc> (+ 5 '((((((5))))))) ((((((10)))))) arc> (+ 3 '(1 2 3) '(4 5 6)) Error: "+: expects type as 2nd argument, given: (1 2 3 . nil); other arguments were: 3 (4 5 6 . nil)"``````-----
 3 points by rocketnia 3230 days ago | link After hammering on your approach a little, here's what I get. ^_^ I like to maintain the fact that Arc's '+ is left-associative, so I don't give myself as much leeway with the additional arguments.`````` ; We're going to have a meaning for number-plus-list, so we override ; the default number behavior, which assumes that only numbers can be ; added to numbers. (extend + args (let (a b) args (and number.a number.b)) (let (a b . rest) args (apply + (do.orig a b) rest))) (extend + args (let (a b) args (and cdr.args number.a alist.b)) (let (n xs . rest) args (apply + (map [+ n _] xs) rest))) `````` Saying (treewise cons [only.+ _ n] xs) is a bit more wordy than necessary here, but it's still a good way to accomplish (+ n xs) inline, without extending '+.Oh, hey, if 'treewise could tell that it had a cyclic data structure, it would also be a more robust option... but that's not the case yet. Should it be?-----
 1 point by fallintothis 3229 days ago | link I like to maintain the fact that Arc's '+ is left-associativeGood work!if 'treewise could tell that it had a cyclic data structure, it would also be a more robust optionDo you mean cyclic structure like this?`````` arc> (= xs (list 1)) (1) arc> (do1 nil (= (cdr xs) xs)) nil arc> (xs 1000) 1 `````` Never thought of that. I mean, the P part of the vanilla Arc REPL breaks on them, and I've never been compelled to use cycles. When are cyclic lists used? I guess if you're representing certain graphs?In a more general sense, I wear my opinion about treewise on my sleeve: http://arclanguage.org/item?id=12115.-----
 2 points by rocketnia 3228 days ago | link If the behavior were in a different utility named 'v+ or something, you wouldn't have a "two libraries extending the same case" conflict (just a "two libraries defining the same variable" one :-p ), and you'd also be able to have (v+ '(1 0 0) '(0 1 0)) be '(1 1 0) without conflicting with Arc's existing result of '(1 0 0 0 1 0).Using 'extend generally also has the drawback that existing code that expects to get an error from something like (+ 1 '(1 2 3)) won't get that error anymore. This is less of a problem when using a tagged type that people are very unlikely to be using already, but numbers and lists are especially common.For fun, here's an implementation. ^_^`````` (def v+ (first . rest) (iflet (second . rest) rest (apply v+ (v+binary first second) rest) first)) (def v+binary (a b) (err:+ "Can't " (tostring:write `(v+ ,a ,b)))) (extend v+binary (a b) (and number.a number.b) (+ a b)) (extend v+binary (n xs) (and number.n alist.xs) (map [v+ n _] xs)) (extend v+binary (xs n) (and alist.xs number.n) (map [v+ _ n] xs)) (extend v+binary (xs ys) (and alist.xs alist.ys (is len.xs len.ys)) (map v+ xs ys)) (extend v+binary (xs ys) (and single.xs alist.ys (~single ys)) (v+ car.xs ys)) (extend v+binary (xs ys) (and alist.xs (~single xs) single.ys) (v+ xs car.ys)) arc> (v+ '((1 0) (0 1)) '((2 0) (0 2))) ((3 0) (0 3)) arc> (v+ 1 2 '(10 20) '(100 200) '(20) 1) (134 244)``````-----