[Haskell-cafe] New type of expressions containing (error ...) includes noisy implicit parameter

Christopher Allen cma at bitemyapp.com
Sat Feb 13 23:32:47 UTC 2016


There's another problem I discovered with HasCallStack. The implicit
parameter constraint breaks sharing behavior for examples that use bottom.

Observe:

$ ghci
GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/callen/.ghci
Prelude> let myList = [1, 2, id 1] :: [Integer]
Prelude> let myList' = myList ++ undefined
Prelude> :sprint myList'
myList' = _
Prelude> head myList'
1
Prelude> :sprint myList'
myList' = _
Prelude> :t myList'
myList' :: (?callStack::GHC.Stack.Types.CallStack) => [Integer]
Prelude> take 2 myList'
[1,2]
Prelude> :sprint myList'
myList' = _


$ stack ghci
Run from outside a project, using implicit global project config
Using resolver: lts-5.1 from implicit global project's config file:
/home/callen/.stack/global-project/stack.yaml
Error parsing targets: The specified targets matched no packages.
Perhaps you need to run 'stack init'?
Warning: build failed, but optimistically launching GHCi anyway
Configuring GHCi with the following packages:
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Ok, modules loaded: none.
Prelude> let myList = [1, 2, id 1] :: [Integer]
Prelude> let myList' = myList ++ undefined
Prelude> :sprint myList'
myList' = _
Prelude> head myList'
1
Prelude> :sprint myList'
myList' = 1 : _
Prelude> take 2 myList'
[1,2]
Prelude> :sprint myList'
myList' = 1 : 2 : _


Now I have to re-examine everywhere we've used bottoms and :sprint together
in the book, which includes the chapters on lists, folds, and
non-strictness. And it isn't just about our book, what about all the other
learning resources and tutorials? :sprint was hard enough for new people to
understand to begin with.

It is very disheartening that people do not take this more seriously.

On Sat, Feb 13, 2016 at 3:33 PM, Christopher Allen <cma at bitemyapp.com>
wrote:

> Holes and bottoms are wildly different. Bottoms are considerably more
> useful which I think you'd find if you ran down a list of examples and
> tried both in each circumstance. This would force even more rewriting than
> present circumstances.
>
> >'undefined' is nasty and has to be used with care
>
> Ya, we tell them that. We also tell them that programs intended to be
> executed outside of a learning/development environment should be total (we
> explain totality and partiality).
>
> On Sat, Feb 13, 2016 at 3:08 PM, Matthew Pickering <
> matthewtpickering at gmail.com> wrote:
>
>> Maybe it would be better to introduce _ rather than using undefined
>> for holes in programs. This sidesteps this issue, provides useful
>> information to guide the implementation and causes an error when code
>> is compiled so programs aren't unexpectedly partial.
>>
>> It is perhaps not idiomatic to use undefined, even in development
>> these days. It is much easier (imo) to use holes and
>> -fdefer-type-errors.
>>
>> 'undefined' is nasty and has to be used with care; CallStacks exist as
>> a bit of a safety net. I've not read your book but I'm not convinced
>> it should be emphasised so much in the first chapters of an elementary
>> Haskell textbook.
>>
>> On Sat, Feb 13, 2016 at 8:52 PM, Christopher Allen <cma at bitemyapp.com>
>> wrote:
>> > Replying to a few here.
>> >
>> > Gigante:
>> >
>> >>Just a question: how do you manage the type of simple arithmetic
>> >> expressions like 1 + 1? I mean, the type contains a constraint there.
>> >> Prelude> :t 1 + 1
>> >> 1 + 1 :: Num a => a
>> >
>> > Earlier versions of the book intentionally juked this or concreted the
>> type
>> > of numbers to Integer, but HaskellForMac defenestrated that with the
>> > always-on type showing so now we've had an explanation along the lines
>> you
>> > suggest for a few months now. We know how to adapt - we've tested the
>> book
>> > extensively. What we need is the implementation not to expose irrelevant
>> > magic/noise in ways that could leak into the first chapter with Haskell
>> code
>> > in it.
>> >
>> >
>> > Seidel:
>> >
>> >>If your readers are using :t they must already know about simple types
>> > like Integer, [], and, ->, so the new things are HasCallStack and =>.
>> >
>> > You'd bloody think as we're careful when we introduce :t, but we get
>> tickets
>> > from people using HaskellForMac[1] that get confused because they are
>> shown
>> > the types of expressions too early. Now we're careful in how we
>> introduce
>> > _any_ expressions.
>> >
>> > Fisking your attempt:
>> >
>> >> => is just like -> except
>> >
>> > They don't know what either of those things are or what they mean in the
>> > second chapter because this is the _first_ chapter with any Haskell
>> code.
>> > They're just beginning to see how Haskell code might be kinda like the
>> > lambdas in the lambda calculus chapter.
>> >
>> >> the compiler fills in the argument by
>> >
>> > We do explain what a compiler and interpreter are, but they won't know
>> what
>> > it means for it to fill in an argument. They don't know why it needs to
>> fill
>> > in an argument. Where did the argument come from?
>> >
>> >>  HasCallStack tells the compiler
>> >
>> > How? Why? Why do they need to care? What's a HasCallStack? Keep in mind
>> they
>> > don't know types, typeclasses, or anything else.
>> >
>> >> that the expression needs a call-stack
>> >
>> > Still don't know what a call, stack, or call-stack are.
>> >
>> >> because it might crash.
>> >
>> > Why does that change the type? We can construct bottoms like `let x in
>> x`
>> > that crash the program without changing the type.
>> >
>> >> >So HasCallStack => [Integer] is a [Integer]
>> >
>> > What makes this even more obnoxious is that when we finally do introduce
>> > typeclasses and constraints, we talk about constraining a _type
>> variable_
>> > and now you've baked this magic in they cannot possibly be explained at
>> all
>> > in the book.
>> >
>> >> that might crash and produce a stack-trace
>> >
>> > First bit they might pick up from context, they don't know what a stack
>> > trace is. Bonus round: when you explain things "from first principles",
>> you
>> > can't duck the fact that it's actually a call graph when explaining a
>> > "stack" trace or call stack. Now you have to explain why/how it gets
>> > flattened from one representation into the other.
>> >
>> >
>> > Oliver had it when he said,
>> >
>> >>"What's a call stack?"
>> >
>> > They don't know what a stack, a call, or the combination thereof is. We
>> had
>> > planned to address these issues in the (much later) chapters that cover
>> > profiling and errors. Because that's when they're relevant. This hasn't
>> been
>> > relevant the entire span of the book. It _never_ mattered that you
>> didn't
>> > get a stack trace from bottoms. In practice, does it suck? Sure! But
>> they're
>> > not practitioners yet! I am (I use Haskell for my 9-5 and have done for
>> a
>> > year and a half) and it still hasn't mattered to me. The only time I've
>> > really wanted a stack trace is when this mechanism would not have been
>> > available to me to begin with.
>> >
>> >
>> > Gamari / amindfv
>> >> I don't have a copy of GHC 8 atm to test this with: is an expression
>> like
>> >> this now illegal?
>> >>
>> >> x :: Int
>> >> x = undefined
>> >>
>> >>This is still valid. The change in GHC 8.0 is merely that GHC will infer
>> >>a CallStack constraint instead of solving it in-place if asked to infer
>> >>a type for a let binding whose RHS demands a callstack.
>> >
>> > We have readers use the REPL _a lot_. Not only to load code but also
>> > free-standing expressions in the REPL when experimenting and learning.
>> Type
>> > assignment in the REPL is noisy and we have to write around some pretty
>> > gnarly width limitations (40-60 cols). This breaks the examples where
>> we're
>> > combining bottom and type inference to explore how terms and types
>> interact.
>> >
>> > I am less disturbed by `HasCallStack =>` than I was by the inferred
>> type of
>> > ($).
>> >
>> >
>> > I know designing around pedagogical limitations like this is tedious but
>> > imagine doing it for 900-1,200 pages (formatting varies) of tutorial and
>> > exercises, then getting unpleasant surprises right as the book is about
>> to
>> > be done.
>> >
>> >
>> > Sorry about the messy thread all.
>> >
>> >
>> > [1]: http://haskellformac.com/
>> >
>> >
>> > On Sat, Feb 13, 2016 at 1:48 PM, Bryan Richter <b at chreekat.net> wrote:
>> >>
>> >> On Sat, Feb 13, 2016 at 09:18:07AM -0800, Eric Seidel wrote:
>> >> > Here's what the GHCi session should look like.
>> >> >
>> >> > > $ ghci
>> >> > > GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/  :? for
>> help
>> >> > > Loaded GHCi configuration from /home/callen/.ghci
>> >> > > Prelude> let myList = [1..5 :: Integer]
>> >> > > Prelude> let myList' = myList ++ undefined
>> >> > > Prelude> :t myList'
>> >> > > myList' :: HasCallStack => [Integer]
>> >>
>> >> What use case is satisfied by providing this information? How does it
>> >> benefit the Haskell programmer? How do I use it?
>> >>
>> >> _______________________________________________
>> >> Haskell-Cafe mailing list
>> >> Haskell-Cafe at haskell.org
>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> >>
>> >
>> >
>> >
>> > --
>> > Chris Allen
>> > Currently working on http://haskellbook.com
>> >
>> > _______________________________________________
>> > Haskell-Cafe mailing list
>> > Haskell-Cafe at haskell.org
>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> >
>>
>
>
>
> --
> Chris Allen
> Currently working on http://haskellbook.com
>



-- 
Chris Allen
Currently working on http://haskellbook.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20160213/e5c20c18/attachment.html>


More information about the Haskell-Cafe mailing list