Interesting trade-off – perhaps the very same structures that reduce the need for debugging.
Speaking of which, is your Applescript environment struggling to evaluate maps filters and folds like these ?
If so, I wonder if it is shadowed by some 3rd party addition to your environment ? An OSAX ?
Simple mapping, filtering and reducing – as in Excel summary cells and derived rows or columns:
on double(x)
x * 2
end double
on sum(a, b)
a + b
end sum
-- TEST ----------------------------------------------------------------------
on run
set xs to enumFromTo(1, 10)
{map(double, xs), filter(even, xs), foldl(sum, 0, xs)}
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- enumFromTo :: Enum a => a -> a -> [a]
on enumFromTo(m, n)
if class of m is integer then
enumFromToInt(m, n)
else
enumFromToChar(m, n)
end if
end enumFromTo
-- enumFromToInt :: Int -> Int -> [Int]
on enumFromToInt(m, n)
if m ≤ n then
set lst to {}
repeat with i from m to n
set end of lst to i
end repeat
return lst
else
return {}
end if
end enumFromToInt
-- even :: Int -> Bool
on even(x)
x mod 2 = 0
end even
-- filter :: (a -> Bool) -> [a] -> [a]
on filter(f, xs)
tell mReturn(f)
set lst to {}
set lng to length of xs
repeat with i from 1 to lng
set v to item i of xs
if |λ|(v, i, xs) then set end of lst to v
end repeat
return lst
end tell
end filter
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- intercalate :: [a] -> [[a]] -> [a]
-- intercalate :: String -> [String] -> String
on intercalate(sep, xs)
concat(intersperse(sep, xs))
end intercalate
-- intersperse(0, [1,2,3]) -> [1, 0, 2, 0, 3]
-- intersperse :: Char -> String -> String
-- intersperse :: a -> [a] -> [a]
on intersperse(sep, xs)
set lng to length of xs
if lng > 1 then
set acc to {item 1 of xs}
repeat with i from 2 to lng
set acc to acc & {sep, item i of xs}
end repeat
if class of xs is string then
concat(acc)
else
acc
end if
else
xs
end if
end intersperse
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- unlines :: [String] -> String
on unlines(xs)
intercalate(linefeed, xs)
end unlines