catch is broken

Started by eddier, January 20, 2005, 08:27:16 AM

Previous topic - Next topic

eddier


(define (f x y)
 (if (= 0 x)
  (throw "x can't be zero")
  (+ x y)))

> (catch (f 0 2) 'result)
true
>result
"x can't be zero"
> (catch (f 1 1) 'result)
true
> result
2


catch is always returning true.



Eddie

Lutz

#1
Nothing is broken ;)



When using catch with two parameters it only returns 'nil' when an error returns, else it always returns 'true' with the result of the function in the resuult parameter.



Only when using catch with one parameter it will return the function result directly.



The new 1-parameter syntax was introduced in 8.3.3. See manual.



Lutz

eddier

#2
I'm not sure I understand?



Notice that catch returned true in both of the circumstances above.



If this is normal behaviour, how do I force throw to thrown an error condition? Shouldn't the throw clause force an error condition for catch? Otherwise, how is this useful for catching user defined errors?



Eddie

Lutz

#3
'catch' with 2 parameters is for catching error conditions. In your example an error condition never occurs.



To distinguish between error condition or finish without error, 'catch' with two parameters returns true or nil.



'throw' is a user intended interruption of a block of code. Error conditions are only thrown by errors.



'catch' with with 2 parameters gives you both: the signalling of an error and the deliberate interruption of a block of code.



'catch' with 1 parameter is a shorter more 'functional' form using 'catch exclusively to write early returns from functions/loops/blocks without catching the error (like usual code).



Lutz

eddier

#4
I think I'm confussing "error-event" and the "throw catch" for the same thing.



This is a bit confussing to me. It seems like if a throw occured, then it would signal an error. How can I make a user defined error it would work like throw in C++, Java, Python, Perl, etc, use throw.



I would like to catch errors like the following

(define (func x y)
 (if (= x 0) (what-ever-makes-an-error-condition "X can't be zero") (+ x y)))


So that if x is 0, then I get an error condition, i.e. (catch (func 0 x) 'result) => nil.



Eddie

Lutz

#5
There is no way to throw user defined errors at this moment. 'throw' is seen as a 'normal' interruption of program flow.



Perhaps we could introduce something like: (error user-message), which is also 'catch'ed, but as an error condition, not as a normal interruption like 'throw'. If no 'catch' is present (error ...) would just behave like a normal error and perhaps have a special error number, and could also be handled with (error-event ...)



Lutz

eddier

#6
Thanks Lutz!



I looked at error-event, but it was not what I was looking for. I see now that the throw catch is to be used as "break" and/or "return" in "C." Right?



Eddie

Lutz

#7
Yes, it is used like a 'break' or 'return' in a procedural language and 'catch' kind of puts a 'functional' wrapper around it. The difference is that the 'throw' could be deeply nested and returns can be from (begin ...)  blocks too not only user defined functions.



(define (func ...)

    (sub ...))



(define (sub ...)

...

(if (...) (throw p))

...

q

)



(catch (func x y z))  ; will return p or q



What you where looking for is a new (error user-message) which throws a traditional error condition, which is handled like any other error in newLISP. I think that can be done.



Lutz

eddier

#8
Thanks!



Oh by the way, If you wanted to update your SMTP library. I don't know if you should, but on Linux/Unix boxes, you could add cc and other fields if you need.



(define (sendmail to from subject body)
  (string
   (exec "/usr/bin/sendmail -t"
(format "To: %snFrom: %snSubject: %snn%s."
to from subject body))))


At least this works for our server.



Eddie

Lutz

#9
Works nice on my FreeBSD ISP too, I guess most UNIX system have sendmail. and it can be even shorter without the 'string'



(define (sendmail to from subject body)
   (exec "/usr/bin/sendmail -t"
    (format "To: %snFrom: %snSubject: %snn%s"
       to from subject body))))


The return value will be 'true' or 'nil'. I will put this as an 'exec' example in the manual and into the Code-Snippets page on newlisp.org.



ps: I am also not sure if the '.' at the end of the format string is really required? I think sendmail will append the protocol dot:  n.n by itself.

eddier

#10
I kind of got the impression that older versions of sendmail had to have the "." but I'm not sure.



Eddie