André Thieme wrote: > greg schrieb: > > Ken Tilton wrote: > > > >> The reason I post macro expansions along with examples of the macro > >> being applied is so that one can see what code would have to be > >> written if I did not have the defskill macro to "write" them for me. > > > > It seems to me your brain is somewhat stuck on the use of macros. > > That you see it this way is normal. > A BASIC programmer would tell you the same thing. He can show you > solutions that don't use classes, methods or functions. > Some sweet gotos and gosubs are enough. > The idea is that macros save you tokens and allow you to experess > in a clearer way what you want to do. But in no case one "needs" > them to solve a programming problem. All what Kenny showed could > be done without his macro. It would just be a bit more complicated > and the resulting code wouldn't look good. > > > > You're looking at the expansion of your > > macro and assuming that you'd have to write all that > > code by hand if you didn't have macros. You're not > > thinking about alternative approaches, which could > > just as well be used in Lisp as well as Python, that > > are just as compact yet don't make use of macros. > > He wouldn't have to write the full expansion. With functional > programming he could also solve it, but then he would need > a funcall here, a lambda there. And his code would not look > so understandable anymore, because it is filled up with some > low level details. > > > I will take one of the first macro examples form "On Lisp". > Let's say for some reason you want to analyse some numbers > and do something depending on their sign. We want a function > "numeric if": > > def nif(num, pos, zero, neg): > if num > 0: > return pos > else: > if num == 0: > return zero > else: > return neg > > > In Lisp very similar: > (defun nif (num pos zero neg) > (case (truncate (signum num)) > (1 pos) > (0 zero) > (-1 neg))) > > > Now one example Graham gives is: > (mapcar #'(lambda (x) > (nif x 'p 'z 'n)) > '(0 2.5 -8)) > > which results in the list (Z P N). > You can do the same thing in Python. > But it gets hairier if we want to make function calls that > have side effects. > Let me add these three functions: > > (defun p () > (print "very positive") > "positive") > > (defun z () > (print "no no") > "zero") > > (defun n () > (print "very negative") > "negative") > > > And now see what happens: > > CL-USER> (mapcar #'(lambda (x) > (nif x (p) (z) (n))) > '(0 2.5 -8)) > > "very positive" > "no no" > "very negative" > "very positive" > "no no" > "very negative" > "very positive" > "no no" > "very negative" > ("zero" "positive" "negative") > > The messages were printed in each case. > To stop that I need lazy evaluation: > CL-USER> (mapcar #'(lambda (x) > (funcall > (nif x > #'(lambda () (p)) > #'(lambda () (z)) > #'(lambda () (n))))) > '(0 2.5 -8)) > > "no no" > "very positive" > "very negative" > ("zero" "positive" "negative") > > > I put the calls to the functions p, z and n into a function object. > In some languages it would look a bit cleaner, for example Ruby. > They have a single name space and don't need funcall and lambda is > shorter. But still, we need to add several tokens. Maybe Haskell has > built in support for that.
def p puts "very positive" "positive" end def z puts "no no" "zero" end def n puts "very negative" "negative" end def nif num, pos, zero, neg send( num>0 ? pos : (num==0 ? zero : neg) ) end [0, 2.5, -8].map{|x| nif x, :p, :z, :n} ### Another way ##### p = proc { puts "very positive" "positive" } z = proc { puts "no no" "zero" } n = proc { puts "very negative" "negative" } def nif num, pos, zero, neg ( num>0 ? pos : (num==0 ? zero : neg) ).call end [0, 2.5, -8].map{|x| nif x, p, z, n} -- http://mail.python.org/mailman/listinfo/python-list