RFC: Add HasCallStack constraint to partial Data.List functions.

Andreas Abel andreas.abel at ifi.lmu.de
Tue Jun 1 18:50:43 UTC 2021


On 6/1/21 2:57 AM, Henrik Nilsson wrote:
 >> But every now and
 >> then the reason, say, a list is non-empty is just a little bit too
 >> subtle to capture in a reasonable way ..., and the use of functions
 >> like foldl1 is entirely appropriate, along with a comment in the code
 >> explaining why it is safe.

A bit off topic (my apologies for the hijacking), but if you my fellow 
Haskellers think you understand when the use of such a partial function 
is safe, I challenge you to look at:

   https://gitlab.haskell.org/ghc/ghc/-/issues/19917

I thought that e.g. `last (x : xs)` can never throw the error 
`Prelude.last: empty list` but I had to learn otherwise...

(So my conviction is that `List.head`, `List.last` and the like should 
be eradicated entirely and any step that brings us closer to this goal 
gets my approval.)

On 2021-06-01 11:20, Ryan Trinkle via Libraries wrote:
> Hi Henrik,
> 
> Regarding making systemic improvements less likely: I don't think we
> should choose to bear costs, simply because the pain of those costs may
> potentially motivate us to come up with something better.  If Oleg's
> proposed solution actually makes it *harder* for -xc improvements to be
> made, then I would certainly agree that we shouldn't use it as a stopgap.
> 
> Regarding teaching: although I don't want to usurp the role of the
> educator - and it would be fantastic to get some input from actual
> educators on this thread - I don't think we should simply say that
> because these things exist, their teachability is important.  Let's let
> people tell us, specifically, that they consider `head` to be important
> to teaching students, and why, and then we can make sure it's suitable
> for them.
> 
> I agree that partiality is sometimes necessary in real-world code,
> although we have gotten very far at Obsidian with banning partial
> functions like foldl1 in favor of explicit calls to `error`, which are
> typically O(1) more work for the developer, and effectively encodes the
> comment you mentioned for why it is safe (i.e. by saying why the error
> ought to be impossible).  That also means that, when the developer is
> wrong about the impossibility of the condition, which seems to be a
> fairly common occurrence, there is at least some hope of tracking down
> the production error message to something meaningful.
> 
> 
> Best,
> 
> Ryan
> 
> On 6/1/21 2:57 AM, Henrik Nilsson wrote:
>> Hi,
>>
>> Ryan Trinkle wrote:
>>
>>> I certainly agree that a more systemic solution would be preferable.
>>> However, none have been forthcoming in the 15 or so years I've been
>>> using Haskell.
>>
>> The sad irony of changes like the proposed one is, of course, that they
>> make a systematic solution less likely to happen (the systematic
>> solution in this case being some engineering effort around the existing
>> -xc mechanism to lower the cost and hassle of using it, which seems to
>> be the reason is it judged not to suffice at present).
>>
>>> I agree with your point about education, but I do wonder whether these
>>> functions should be taught at all.  What is their purpose, really?
>>> I've found little downside (and a lot of upside) to simply never
>>> using any of these functions.  (The times when I get bitten by them
>>> are when they are used in libraries I use.)
>>
>> I'd personally not like to suggest to educators what they should or
>> should not teach: the context, specific learning goals, and students
>> vary widely.
>>
>> In any case, these functions have been in Haskell since its inception,
>> and so are deeply ingrained in books, literature, and code.
>>
>> Moreover, I do not find functions like (!!) or foldl1 to be unreasonable
>> at all. List indexing is as reasonable as array indexing. And foldl1 and
>> foldr1 are very useful when folding over lists where the type of the
>> elements have no neutral element.
>>
>> In my day to day work, we also avoid using these partial functions
>> whenever we can, and usually it is not that difficult. But every now and
>> then the reason, say, a list is non-empty is just a little bit too
>> subtle to capture in a reasonable way (benefit outweighing the cost)
>> by a suitable design and/or at the type level, and the use of functions
>> like foldl1 is entirely appropriate, along with a comment in the code
>> explaining why it is safe.
>>
>> Hécate wrote:
>>
>>> I think the vast majority of the functions presented in this proposal
>>> have a total counterpart, whether it is a function or a code pattern.
>>> We have NonEmpty in `base`, as well as ExceptT/MonadError and
>>> Exceptions to allow us to mimic such a cul-de-sac in the code with
>>> appropriate annotations around it.
>>
>> While NonEmpty is useful on occasion, many operations on them
>> of course returns a possibly empty list, and then the original
>> problem is back.
>>
>> And having to resort to monadic code when it is completely clear
>> that a piece of code using, say, a foldl1 or (!!) is safe, can be
>> quite costly (major refactoring could be implied) as well as
>> obscuring the nature and purpose of the code.
>>
>> So, again, while partial functions obviously should be use with
>> great care, they certainly have perfectly legitimate uses in
>> a practical setting in most languages in wide-spread use, including
>> Haskell, and I'd again be somewhat wary of "tell the user: Don't use
>> that function!" as Henning phrased it.
>>
>> Artem Pelenitsyn wrote:
>>
>>> As for educational uses, it's been clear for a while now that
>>> industrial uses are at odds with educational ones (and both may be
>> at > odds with research ones). In my opinion, we can't hold back one for
>>> another. Rather, we need to figure out the right story for both.
>>> There's a (seemingly) valid industrial use case for the HasCallStack
>>> mechanism in base that is not covered by -xc, as explained by others
>>> above. As for education, two possible avenues are 1) to explore
>>> custom "educational" Preludes (tried by several people, the
>> CodeWorld > project first comes to mind), and 2) custom error
>> messages, which are > being reworked just as we speak by Richard,
>> Alfredo and others.
>>
>> Different preludes for different classes of users are brought up from
>> time to time.
>>
>> I think there are significant down-sides to this. And further, I am not
>> at all convinced that "industrial users" are such a homogeneous group
>> that they'd all agree on what they'd want in the prelude.
>>
>> Both of these suggest than rather than a separate prelude for
>> education/beginners, the standard prelude should be kept simple/be
>> left alone, and groups with specific needs and sufficient knowledge
>> should pay the price for using refined preludes if they make
>> an informed choice that the benefits of doing so outweigh the costs.
>>
>> But I digress.
>>
>> /Henrik
>>
>>
>>
>> This message and any attachment are intended solely for the addressee
>> and may contain confidential information. If you have received this
>> message in error, please contact the sender and delete the email and
>> attachment.
>> Any views or opinions expressed by the author of this email do not
>> necessarily reflect the views of the University of Nottingham. Email
>> communications with the University of Nottingham may be monitored
>> where permitted by law.
>>
>>
>>
>>
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
> 
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
> 


More information about the Libraries mailing list