Closed MangoIV closed 2 months ago
There is already a standalone package on ekmett/placeholder. It just needs to be published on hackage.
Additionally, adding the
-fdefer-typed-holes
flag has one (minor?major?) drawback: I can now no longer use typed holes as an error alongside with typed holes as a warning.
This. That's why I never considered typed holes as an alternative for todo
, I'm an ardent adept of hole-driven development, so suppressing the warning is not an option for me. I feel that holes are much more widerly used for HDD than for -fdefer-typed-holes
.
@MangoIV thanks for the proposal, I greatly appreciate all work and effort you put into it.
...it's quite a good testimony of how cumbersome any substantial improvements, many of which are even somewhat universally agreed on, will be, just for the reason of them creating a lot of churn in the ecosystem. Mind that this is no criticism but instead a pledge for a more glorious future after the
base
split.
I'm not quite sure what you refer by "the base
split" and how it would help to evolve base
faster. If anything, splitting ghc-internal
is to make base
more stable by excluding the volatile GHC component.
While the fact that CLC votes against vox populi might be perceived by some as worrying, I strongly believe that it's not. Let me remind that everyone wishing to affect CLC decisions is most welcome to nominate themselves at the next CLC elections (which is January 2025) and help us together make the world a better place to write Haskell.
There is already a standalone package on ekmett/placeholder. It just needs to be published on hackage.
It has now been published: https://hackage.haskell.org/package/placeholder
Thanks to @MangoIV and @ekmett for making this idea into a package
Dear Haskell core library committee.
Currently there are multiple ways of describing something as unimplemented
Relude
placeholders or the todo packageproblems of the above solutions
base
:undefined
:error
:todo
, it doesn't seem worth adding an alternativePrelude
or even add a dependency just for the sake of thisThat's why propose a function
todo
that has the following properties:"todo remains in code"
in groupx-todo
so that it can be used withWError
for e.g. CIundefined
base:Prelude
implementation of the solution
try it out in a separate module, as such:
This implementation will work from
>= ghc981
impact
on hoogle I currently find 4 functions which this would break, two of which have similar semantics to this one, making it improbable that they will be found in code out there.
Another advantage of this function is that there will be no need of a
*-compat
package because code that does contain this function is not supposed to live anywhere or compile with more than the compiler than thebase
version this is going to be shipped with supports.I will obviously run a proper impact assessment though.
why I think this belongs in
Prelude
The main reason I think this belongs into
Prelude
is because it is not possible to replace this with the same level of simplicity with any other solutionmixins
or add new imports; Additionally already having to add an additional dependency to use this, would, I think, be too much effort for many people to use itGHC
, they are not supported first class byGHC
, with the advent of the{-# WARNING -#}
we have first class support for these kinds of things that don't add any additional overheaderror
andundefined
don't haveWARNING
s attached to them and I don't think they should have; they have been as they are for a long time, it would impose a great cost to change their semantics; even though it is debatable whether you should, people useundefined
in their code to signify unreachable or permanently unimplemented parts of their code, if we want to add a warning, I think it should be on something that clearly tells the programmer and the reader of the code "this is not done yet"I think this will also have the positive impact of offering a real alternative to dangerous uses of
undefined
also look at
rust std's
todo!
andunimplemented!
macrosrendered docs
some more screenshots
how it looks, loading a module using
todo
intoGHCi
:how it looks when trying to load a module using
todo
with{-# OPTIONS_GHC -Werror=x-todo #-}
intoGHCi
:Amendment to this proposal (28 Mar 2024)
After what I consider a very productive and diverse discussion, I think the most prominent conclusion is that this might not make the jump into
Prelude
all at once. I still want to proceed with this proposal for the following two reasons:base
Prelude
eventually; this seems to be only possible when something has been inbase
for a long time and one has to start at some point ;)a new module,
Debug.Placeholder
Develop.Placeholder
There will be a new module
Debug.Placeholder
Develop.Placeholder
that will contain both thetodo
function as described above and implemented in ekmett'splaceholder
library (thank you for throwing this together) (except some improvements I will propose wrt type applications)TODO
pattern synonym as is implemented in theplaceholder
library (except some improvements I will propose wrt type applications)These implementations include many useful improvements to the function described above, which is really awesome.
The name of the module is justified as follows:
Control
or the like because it's only temporarily, you do something with the definitions in the process of programming, but don't really intend to keep the definitions@tbidne has proposed the namespaceDebug
is the namespace that I think most fits the semantics of these functions intuitively, after all,todo
is something you insert in the code while "writing code" which is closest to "debugging", I'd sayDevelop
which I think is the most fitting until nowNote: if people think that the proposed namespace is incorrect, I would like to hear convincing arguments and am happy to adjust accordingly.
out of scope for this proposal
While there were some really nice suggestions to make the proposal "more complete", I will consider the following out of scope for this proposal while expressing the strong intention to later add them in a follow-up proposal:
{u,U}nimplemented
function and patterns: the reason why I want to avoid them for now is that they will spark additional discussions on whether you really need both of these and what the semantics of them should really be, whether they require warnings, etc.{unimplemented,todo}IO
variations of these: the reason why I want to avoid these is that I think it will spark discussion on whether we will need these in the case of onlytodo
existing, as it may never remain in codeDevelop
that will export many useful functions that you need only for work-in-progress code, such as thetodo
family of functions as well as thetrace*
family of functions