Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So where's all the error handling? File IO in Java would be rife with exception handling and not without reason.


(with-open-file ...) is roughly equivalent to the java try-with-resources pattern. `(loop for num (readline stream nil) while num ...` means, roughly, "loop through the lines of 'stream', exiting the loop on EOF". If you're assuming the input files are well-formed, CL is just much more concise with a roughly equivalent level of robustness to what a Java programmer would right for this.


> If you're assuming the input files are well-formed

Seems like a big if. Lots of failure cases like file not found or bad permissions are handled with Java checked exception. The minimum Java app would have to cover those cases in some way.

Does CL just silently ignore these types of issues when you "code as you would professionally"? Seems like a lot of code is missing but maybe I'm just used to the verbosity.


In Common Lisp implementations these conditions are usually reported by default in some way.

  CL-USER > (with-open-file (s "~/foo.lisp")
              (read s))

  Error: The file #P"/Users/joswig/foo.lisp" does not exist.
    1 (continue) Try opening "~/foo.lisp" again.
    2 (abort) Return to top loop level 0.

  Type :b for backtrace or :c <option number> to proceed.
  Type :bug-form "<subject>" for a bug report template or :? for other options.
A non-interactive program might bring up such a dialog automatically.

When one would do actually application specific error handling, this could (depending on how much comfort is wanted) be much more complex, since Common Lisp has more features to handle and repair errors.


> Does CL just silently ignore these types of issues when you "code as you would professionally"?

Nah, it just compresses the default cases well, and it doesn't force you to check for errors (like with checked exceptions)[0]. See the already mentioned `with-open-file'[1] macro, which is essentially a wrapper around `open'[2] that implements "try with resources" pattern. The documentation of `open' shows all the interesting flags you can use to predefine some behavior (that's IIRC the equivalent of Java's wrappers around file readers/writers) - like what to do if a file exists or doesn't.

In case there is an error, either when opening or reading data, the relevant function will "signal a condition", which is Lisp for "throw an exception", except it's better :) [3]. Per documentation, it'll typically be a condition of type `file-error'[4] or `error'. CL standard doesn't specify subtypes of `file-error' further, but individual CL implementations can and do subclass `file-error' to allow for more granular identification and capture.

So, in short, the way you'd use this professionally would be to use `with-open-file', and use appropriate condition handlers and restarts to deal with any problems that occur.

--

[0] - Which I consider to be unfortunate. Checked exceptions got a bad rap, but they were a good idea. However, given the extremely fluid nature of Lisps in general (and CL in particular), fully checking for unhandled exceptions would likely run afoul of the halting problem...

[1] - http://clhs.lisp.se/Body/m_w_open.htm#with-open-file

[2] - http://clhs.lisp.se/Body/f_open.htm

[3] - It's a long topic but, TL;DR: signalling a condition does not automatically unwind the stack - it looks up the call stack for a handler, which then executes on top of existing stack, and can pick a way to recover from the problem - including unwinding the stack partially, and invoking recovery code defined there.

[4] - http://clhs.lisp.se/Body/e_file_e.htm#file-error


Yeah, I'd be interested to see a modern comparison, I'm thinking Java may have evolved somewhat to make up some of the distance to Lisp of the 2000s :D




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: