/** This file is part of Shapes. ** ** Shapes is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** any later version. ** ** Shapes is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Shapes. If not, see . ** ** Copyright 2009, 2010, 2014, 2015 Henrik Tidefelt **/ ##lookin ..Shapes /** Define some function that uses the error mechanism to report bad input. ** ** (To make it simple we avoid a helper function, but this will clearly ** lead to a performance loss since the type and range of the argument will ** be checked over and over again.) ** ** By not using cond to check for the error conditions, it becomes clearer ** what is error-checking and what is normal evaluation. **/ factorial: \ i → { ![if [typeof i] ≠ Data..Type..§Integer [error 'type_mismatch VARNAME Data..Type..§Integer.name (indexof i) i]] ![if i < '0 [error 'out_of_range VARNAME `The factorial is not defined for negative values.´ (indexof i)]] [if i = '0 '1 i * [factorial i-'1]] } /** Define a new function, which captures and handles one of the errors that factorial may report. ** The implementation follows a pattern, so it can be learned even if it cannot be abstracted away ** in a function. **/ ext_factorial: \ i → (escape_continuation return (escape_continuation error (escape_continue return [factorial i])) >> \ ball → [Control..cond [Data..cons ball.kind = 'out_of_range '~1] [Data..cons ball.kind = 'dtmin [error 'misc VARNAME `Why on earth did we get a dtmin error here?!´]] [Data..cons true (escape_continue error ball)]]) /** Try the new function! **/ IO..•stdout << [ext_factorial '10] << "{n} IO..•stdout << [ext_factorial '~10] << "{n} /** But don't do this, since the type mismatch error will be re-thrown by ext_factorial: **/ |**IO..•stdout << [ext_factorial 10] << "{n}