Ask HN: How should a programming language accommodate disabled programmers?
173 pointsby evincarofautumn116 comments
-- (1)
fix f = let x = f x in x
Because it has better memory usage; the definition you provided is translated to the following STG: -- (2)
fix f = let x = fix f in f x
So whereas #1 is a thunk that refers to itself, #2 is a recursive function, and importantly not tail-recursive. someFunction =
do { foo
; mx <- bar
; y <- case mx of { Just x -> do { baz
; pure (quux x)
}
; Nothing -> do { fnord
; blurch
}
}
; xyzz y
}
I find it nice enough to read, particularly because it leads to rapidly increasing indentation and consequently discourages deeply nested code, but it’s a bit of a pain to edit & diff. I would write the above like this: someFunction = do
foo
mx <- bar
y <- case mx of
Just x -> do
baz
pure (quux x)
Nothing -> do
fnord
blurch
xyzz y
This prefix delimiter style is actually fairly standard in Haskell not for “do” notation, but for records and lists, since Haskell doesn’t allow a final trailing comma in these structures: list :: [Text]
list =
[ "this"
, "that"
, "the other thing"
]
data Numbers = Numbers
{ numI :: Int
, numF :: Double
, numS :: Text
}
record = Numbers
{ numI = 1
, numF = 1.0
, numS = "one"
} read eval print loop
stdin read
some_environment eval
pretty print
loop
[1, 2, 3] [4, 5, 6] \(+) zip_with
do (each_index) -> i, x {
if (x = 7) {
"Lucky seven!" say
} else {
["Value at index ", i show, " is ", x show]
concat say
}
}
To expand on that, for those in the audience:
In Haskell, a functor is a type constructor (like “list”, “optional”, “future”, “I/O request”, &c.) with a way to map a function over it, covariantly, in a way that preserves its structure—i.e. without changing the shape of the container or structure of the action represented by the constructor, just the contained elements or produced result.
This is based on the more general notion of a functor in mathematics, which is a mapping between categories. The Haskell version is much more constrained, though: it only maps between Haskell types, and it’s parametric (iow completely generic), not just any old mapping.
While in C++, a functor is a completely different thing: an object that can be called like a function. It’s thus equivalent to a closure, where the object fields are the captured values. And that sounds like the description being used here.