Q&A's, tips, howto's
-
Tim Johnson
- Posts: 253
- Joined: Thu Oct 07, 2004 7:21 pm
- Location: Palmer Alaska USA
Post
by Tim Johnson »
In python I'm used to doing something like this:
Code: Select all
funcs = {"one":func1,"two":func2} ## etc
## Called as:
funcs[task](arg1 arg2)
I did this in newlisp:
Code: Select all
(set 'funcs '(("int" do-int)("text" do-text)))
(define (do-int arg1 arg2)
(println "DO-INT - arg1: " arg1 " arg2: " arg2) )
(define (do-text arg1 arg2)
(println "DO-TEXT - arg1: " arg1 " arg2: " arg2))
## Function call:
(set 'arglst '("one" "two"))
(apply (lookup "text" funcs) arglst)
## => DO-TEXT - arg1: one arg2: two
If anyone thinks there is a better and more idiomatic way to do this, I would welcome comments.
thanks
tim
Programmer since 1987. Unix environment.
-
Sammo
- Posts: 180
- Joined: Sat Dec 06, 2003 6:11 pm
- Location: Loveland, Colorado USA
Post
by Sammo »
In 'funcs' you are storing the names of functions 'do-int' and 'do-text' but not the functions themselves. Writing it slightly differently,
Code: Select all
(define (do-int arg1 arg2)
(println "DO-INT - arg1: " arg1 " arg2: " arg2) )
(define (do-text arg1 arg2)
(println "DO-TEXT - arg1: " arg1 " arg2: " arg2) )
(set 'funcs
(list
(list "int" do-int)
(list "text" do-text) ))
you can code the following:
Code: Select all
((lookup "text" funcs) "one" "two")
or, perhaps more elegantly:
Code: Select all
(define (f key) (lookup key funcs))
((f "text") "one" "two")
-
Tim Johnson
- Posts: 253
- Joined: Thu Oct 07, 2004 7:21 pm
- Location: Palmer Alaska USA
Post
by Tim Johnson »
Hey, I like your approach. And taking it one step further using
'fn:
Code: Select all
(set 'funcs
(list
(list "int" (fn(arg1 arg2)(println "DO-INT - arg1: " arg1 " arg2: " arg2)))
(list "text" (fn(arg1 arg2)(println "DO-TEXT - arg1: " arg1 " arg2: " arg2)))))
(define (f key) (lookup key funcs))
((f "text") "one" "two")
Elegant indeed.
Thank you
tim
Programmer since 1987. Unix environment.
-
Tim Johnson
- Posts: 253
- Joined: Thu Oct 07, 2004 7:21 pm
- Location: Palmer Alaska USA
Post
by Tim Johnson »
And one more step, factoring out 'list calls by using eval in the dispatcher:
Code: Select all
(set 'callback-list
'(("int" (fn(arg1 arg2)
(println "heellllooo from the 'int handler")
(println arg1 " " arg2)))
("text" (fn(arg1 arg2)
(println "heellllooo from the 'text handler")
(println arg1 " " arg2)))))
(define (dispatcher key params)
(apply (eval(lookup key callback-list)) params))
(dispatcher "int" '("one" "two"))
(dispatcher "text" '("three" "four")
Results:
Code: Select all
heellllooo from the 'int handler
one two
heellllooo from the 'text handler
three four
Next step: Compose an anonymous function and either replace or add to
the callback list.
Cheers
tim
Programmer since 1987. Unix environment.
-
Lutz
- Posts: 5289
- Joined: Thu Sep 26, 2002 4:45 pm
- Location: Pasadena, California
-
Contact:
Post
by Lutz »
Here is another solution using a hash tree to hold the lambda fuctions:
Code: Select all
; create a hash
(define Func:Func)
; assign lambda expressions
(Func "int" (fn (x) (println "hello from int:" x)))
(Func "text" (fn (x) (println "hello from text:" x)))
; excute functions
((Func "int") 99)
((Func "text") "abc")
creates this output and return values:
Code: Select all
hello from int:99
99
hello from text:abc
"abc"
-
Tim Johnson
- Posts: 253
- Joined: Thu Oct 07, 2004 7:21 pm
- Location: Palmer Alaska USA
Post
by Tim Johnson »
I think that your method will make modification easier also.
Thanks very much Lutz.
I hadn't even considered hashes.
Programmer since 1987. Unix environment.