How ‘resolve have solved my problem
When I found Clojure, it was with the intention to implement a high concurrent application to manage provisioning commands for Huawei Equipments. Meanwhile I was learning about the concurrent toolset that comes with the language, then I found a small but not less important feature in Clojure: the use of symbols. After diving into this feature I discovered that the majority of Lisps dialects has it.
ADO $ 19203212 CWI CWT $
ADO $ 19200242 CPC PRIOR $ Y $
DEO $ 16200213 CNDC $ Y $
DEO $ 16200213 CNDC $ Y $
ADO $ 16200212 CCW $ Y $
The first word give a top level behaviour (ADO,DEO, etc), then, depending of the arguments (like CWI, CCW, etc) it should goes to specific function. Clearly, I had to write five different functions for the previous commands, but to avoid a direct dispatching (hard coded) I need something dynamics, before show the solutions, let me show you this idea of symbols in Clojure.
A symbol es just a string with certain constraints (like not start with a number), so a list in symbols is:
Note that I have used an apostrophe so Clojure do not interpret the list as a function invocation, which is the default behaviour for a list. I can count the members of the list with:
(count '(john peter mary)) => 3
There is a function that let me verify if something is a symbol:
(symbol? 'any-func)
==> true
==> other-func
==> #'clojure.string/split
==> true
And, finally, there is another function that allows me to create a symbol from a string:
(symbol "other-func")==> other-func
To complete the puzzle, there is another function that let me to resolve a symbol into the real value that is assigned, like a function:
(resolve 'clojure.string/split) ==> #'clojure.string/split
This means that the symbol ‘clojure.string/split is resolved (evaluated) to a function #’clojure.string/split . Putting together symbol and resolve functions I can build a string with the original command that finally resolves to the function and invoke that function, for example:
(resolve (symbol
(str "apic.request.deo/" fname)))
(resolve (symbol
(str "apic.request.deo/" fname)))
Where fname is built removing the variable (see below code) parts of every command. With the symbol, the execution is just an invocation following the rules of Lisp: (symbol-fn args)
The code(published as Gist) to create a string from the command, avoiding numbers and other stuff is :
Success!!. I avoided to maintain a list of dispatching functions, for every new command, the previous code told me if the symbol could not been resolved, is like Test Driven Development, for every pending code, an exception occurs and warned us that its was a pending function to implement. Thanks Clojure!
Comments
Post a Comment