Page 1 of 1
Add and Mul
Posted: Tue Feb 24, 2009 3:43 am
by 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
Re: Add and Mul
Posted: Tue Feb 24, 2009 8:42 am
by Kazimir Majorinc
Interesting ideas. I implemented
jeremy-add and
jeremy-mul, so if someone need it now he can use it.
Code: Select all
(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.
Posted: Wed Feb 25, 2009 3:11 am
by Jeremy Dunn
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.