(reference "System" "System.Web")
(using "System" "System.Web" "System.Net" "System.IO")
(= key "xxx")
(= url "http://30boxes.com/api/api.php")
(defmacro defapi (function-name api)
`(defun ,function-name ()
(= method-url (new uri (format string "{0}?method={1}&apiKey={2}" url
,api key)))
(= request (create webrequest method-url))
(= response (getresponse request))
(= reader (new streamreader (getresponsestream response)))
(= result (readtoend reader))
result))
When I tried invoking the defapi macro I kept getting this:
System.NullReferenceException: Object reference not set to an instance
of an object.
at LSharp.Runtime.Call(String method, Cons arguments)
at LSharp.Runtime.Apply(Object function, Object arguments,
Environment environment)
at LSharp.Runtime.Eval(Object expression, Environment environment)
at LSharp.Functions.Eval(Cons args, Environment environment)
at LSharp.Runtime.Apply(Object function, Object arguments,
Environment environment)
at LSharp.Runtime.Eval(Object expression, Environment environment)
at LSharp.TopLoop.Run(TextReader reader, TextWriter writer,
TextWriter error)
But using macroexpand everything seems to be fine. I've even managed to
get it to work by using the following code
;;; The following is an alternative to (defapi 'test-ping "test.Ping"))
(eval (macroexpand defapi 'test-ping "test.Ping"))
(test-ping)
Can anyone point out what I'm doing wrong?
Dan
By contrast, (defapi test-ping "test.Ping") seems to succeed.
BTW, if you know C# and have access to Visual Studio 2005, I strongly
recommend using them for debugging. You can trace inside the
interpreter to see what the interpreter is doing with your code and why
it is failing. The exceptions that are thrown often aren't very clear
by themselves.
Also, the change I proposed in a previous thread, overriding
Cons.ToString to show the contents of the Cons, makes Visual Studio
debugging substantially easier. When you look at variables in the
debugger after you apply this change, they show things like (+ 2 (- 3
1)) instead of showing LSharp.Cons and forcing you to expand the cars
and cdrs to see what's inside.
--
C: Why does the sun set?
D: It's because hot air rises. The sun's hot in the middle of the day, so it rises high in the
sky. In the evening then, it cools down and sets.
C: Why does it go from east to west?
D: Solar wind.
+27 82 567 6207
http://pieterbreed.blogspot.com/
It did seem a little odd though that macroexpand evaluates the
arguments that you pass to whereas just calling the macro does not. For
example:
>(defmacro m1 (arg)
(tostring arg))
>(m1 (now datetime)) ;; This calls ToString on the "(now datetime)" Cons
"LSharp.Cons"
>(macroexpand m1 (now datetime)) ;; This calls ToString on the returned DateTime object
"31/08/2006 12:16:20"
But I guess it does makes sense when you consider that macroexpand is
just a function so it behaves just like any other function in this
respect, whereas a macro call is a special form that does not evaluate
its arguments. I even checked CLISP and found that it works in a sort
of similar way (although you don't pass the macro name and arguments
separately you pass an entire _quoted_ method call).