My (fb) posts about Rye-s failure handling have been somewhat controversial so far. Remember that I am just experimenting here. I know known solutions exist and I see no problem in implementing them in Rye if these experiments fail to produce a value. So far I am following the path and crossing the bridges that show-up before me ...
The return words, especially connected to handling of failures like ^fix and ^check had a side effect of flattening the code, which made the code visually and conceptually simpler.
Return words work on the level of functions. They provide an escape hatch out of whole function. But inside a local stream of pipe and op-words we don't have such an escape hatch. So we need to sometimes resort to code nesting sooner than we would want to.
I was looking at this example of Maybe monad in Ruby (using ruby-possibly library).
If I try to recreate this in Rye the word fix comes to mind. Rye has no null type so far and liberally uses failures where some other languages would return null.
Fix accepts a value and a block of code. If the value is failure it evaluates the block of code and returns the result. If not, it just returns the
first argument.
If Rye functions can't produce an expected value they return a failure. Failure is information (a rye value) and you can handle it as any other Rye value. Failures can hold a type, a message and a status code and can be nested. Rye has so far some helpful functions/patterns around failures, like check, fix and tidy. They come as ordinary and returning functions. Unhandled failure becomes an Error (in code) and must be fixed by programmer, by either handling a failure or otherwise.
But here we would have to use fix-either, and 2 of them, which makes code quite complex. Either in rye is like if-else and accepts 2 blocks of code, a true and a false block. Fix-either also accepts 2 blocks, a failure/fixing block and a non-failure block.
Code is not that long, but the productive path is now nested 2 levels deep, and this doesn't look nice to me at all. In general I think fix-either should be rarely or maybe never used ... future use will show.
I started thinking about the return words, but we don't have them on the level of collections of pipe-words (a pipe stream?). We can't for example use them and then set a number-of-friends word at the end of this particular stream, because they would return to the caller of our function in case of failure.
So I added the now so called skipping words, that work like return words, but on the level of one stream of pipe/op-words. So the code above becomes:
Skipping stops when the stream of pipe/op-words ends or when a left set-word is met. Here are some more examples from the Rye repl:
In the next days I will return to the web-app example. I mentioned returning words a lot in this post. You can see them in use in the webapp example #2. They are the words with ^ at the beginning.
Komentarji
Objavite komentar