Add and Mul

Started by Jeremy Dunn, February 23, 2009, 07:43:54 PM

Previous topic - Next topic

Jeremy Dunn

Some possible enhancements to add and mul:



ADD



When supplied with a single vector return the sum of all of the elements

(add (1 2 3 4)) -> 10



When supplied with an integer and T return the continued sum of the digits of the integer.

(add 7898 T) -> 7+8+9+8 = 32  3+2 = 5



MUL



When supplied with a single positive integer return the factorial of that integer.

(mul 3) -> 6



When supplied with a single negative integer return the double-factorial of the absolute value of the integer.

(mul -7) -> 105



When supplied with a single vector return the product of the elements.

(mul (1 2 3 4)) -> 24



When supplied with an integer and T the continued product of the integer digits is returned.

(mul 463 T) -> 4*6*3 = 72 7*2 = 14

Kazimir Majorinc

#1
Interesting ideas. I implemented jeremy-add and jeremy-mul, so if someone need it now he can use it.


(set 'println= (lambda-macro(x)(println x "=" (eval x))))

(set 'jeremy-add
     (lambda()
       (let ((L (args)))
         (cond
               ;(jeremy-add 7898 'true)
               ((= (last L) true)
                   (let ((result 0))
                        (dostring(c (string (first L)))
                           (inc result (int (char c))))
                        (if (> result 9)
                            (jeremy-add result true)
                            result)))
               
               ;(jeremy-add '(1 2 3 4))
               ((list? (first L)) (apply add (first L)))
               
               ;(jeremy-add 17 18)
               (true (apply add L))))))
                         
(println= (jeremy-add 17 18))
(println= (jeremy-add 7898 true))
(println= (jeremy-add '(1 2 3 4)))


(set 'factorial
     (lambda(n)
       (let((result 1))
         (when (> n 0)
            (for(i 1 n 1)
                (set 'result (* result i))))
          result)))
         
(set 'double-factorial
     (lambda(n)
       (let((result 1))
        (when (> n 0)
         (for(i n 1 -2)
            (set 'result (* result i))))
         result)))


(set 'jeremy-mul
     (lambda()
       (let ((L (args)))
         (cond ;(jeremy-mul '(1 2 3 4))
               ((list? (first L)) (apply mul (first L)))
         
               ;(jeremy-mul 463 'true)
               ((= (last L) true)
                       (let ((result 1))
                              (dostring(c (string (first L)))
                                 (set 'result (* result (int (char c)))))
                              (if (> result 9)
                                  (jeremy-mul result true)
                                  result)))
         
               ;(jeremy-mul 3)
               ((and (= (length L) 1)
                     (> (first L) 0))
                (factorial (first L)))
               
               ;(jeremy-mul -7)
               ((and (= (length L) 1)
                     (< (first L) 0))
                (double-factorial (abs (first L))))
               
               ;(jeremy-mul 1 3 5 7 9)
                (true (apply mul L))))))
               
(println)
(println= (jeremy-mul 1 3 5 7 9))
(println= (jeremy-mul 3))
(println= (jeremy-mul -7))
(println= (jeremy-mul '(1 2 3 4)))
(println= (jeremy-mul 55 true))

; RESULTS

; (jeremy-add 17 18)=35
; (jeremy-add 7898 true)=5
; (jeremy-add '(1 2 3 4))=10
;
; (jeremy-mul 1 3 5 7 9)=945
; (jeremy-mul 3)=6
; (jeremy-mul -7)=105
; (jeremy-mul '(1 2 3 4))=24
; (jeremy-mul 55 true)=0
;




No thoroughly tried and tested, but bugs can be easily fixed.



As library, it is OK, as a part of the core language, I'm not so sure, because overloading has, beside advantages, some disadvantages as well. Disadvantage is that it is frequently harder to read and understand programs with overloaded operators, because one has to think in terms "if that (add a b) is meant on the usual way, then ... and if it is meant on sum-of-digit-way ..." And not only human, but meta programs and interpreter have harder job to understand overloaded version - that's why more specific versions of the functions are necessarily bit faster.
http://kazimirmajorinc.com/\">WWW site; http://kazimirmajorinc.blogspot.com\">blog.

Jeremy Dunn

#2
Kaz, you're so quick on the draw! Thanks for the fast typing. Yes, I agree that overloading can get crazy sometimes but it is nice to have common operations that are very closely related under one roof. In multiplication for instance, factorials, product of elements of vector all share a commonality that I don't think is too off base. Most of the suggestions involve only the use of a single argument which visually should be different enough to alert you that something is going on. But everyone has their own style and preference.