Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: comment on this debugging trick? (David McBride) 2. Re: is Haskell practical? (Henk-Jan van Tuyl) 3. Re: comment on this debugging trick? (Dennis Raddle) 4. Re: comment on this debugging trick? (Jeffrey Brown) 5. Re: comment on this debugging trick? (Dennis Raddle) ---------------------------------------------------------------------- Message: 1 Date: Fri, 27 Nov 2015 14:05:58 -0500 From: David McBride <toa...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] comment on this debugging trick? Message-ID: <can+tr42qjubwduvwozk8tzc5q7quwiu3z3ahcvpclgespcw...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" If you compile with -prof you can use the traceStack function from Debug.Trace. That's something. On Fri, Nov 27, 2015 at 8:56 AM, Dennis Raddle <dennis.rad...@gmail.com> wrote: > When I design my code, I am aware of the properties I expect my internal > data representations to have, or I want input data to conform to my > expectations. For example, right now I'm writing code that reads MusicXML. > MusicXML is a crazy language, way too complicated for what it does, and the > music typesetters that export MusicXML all do their own idiosyncratic > things with it. I'm only reading the output of one typesetter, Sibelius, > and although I don't know the internals of Sibelius, I can make some > assumptions about what it's going to produce by a few examples, plus my > application doesn't use the full range of MusicXML. I don't need to handle > every case, is what I'm getting at. > > However, if I should have been wrong about my assumptions when I wrote the > code, I don't want my program to behave erratically. I want to find out > exactly what went wrong as soon as possible. > > Previously, I was including a lot of exception throwing, with each > exception having a unique message describing what had happened, and in > particular describing where in the code it is located so I can find the > problem spot > > If I throw generic error messages like "Error: problem parsing" and I have > many of those located in the code, I need the debugger to find it. Same if > I use things like "fromJust" or "head" > > I haven't had good experiences using the debugger. Maybe that's my fault, > but I like that I can locate my unique exceptions and that they are > descriptive. > > But a month ago I decided this system is pretty ugly. It bloats the code a > lot, and requires writing a lot of messages for situations that will > probably never occur. > > I am trying a different method now. I write the code so that surprising > behavior will result in a case or pattern exhaustion, which produces a run > time message with a file name and line number. I'm not sure why ghc gives > the location for a case exhaustion, but not something like "head". > > For example, instead of using head xs I can write > > x = case xs of {y:_ -> y} > > This is a little bloat but not too bad. Most of the time I'm actually > structuring cases and patterns, and it actually helps me to simplify code > to think of how to write it with the fewest cases and so that a case > exhaustion will indicate something pretty specific. > > Any comments welcome. > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151127/80d17e16/attachment-0001.html> ------------------------------ Message: 2 Date: Fri, 27 Nov 2015 20:34:12 +0100 From: "Henk-Jan van Tuyl" <hjgt...@chello.nl> To: "Haskell Beginners" <beginners@haskell.org>, "Dennis Raddle" <dennis.rad...@gmail.com> Subject: Re: [Haskell-beginners] is Haskell practical? Message-ID: <op.x8rxzf0bpz0j5l@alquantor> Content-Type: text/plain; charset=iso-8859-15; format=flowed; delsp=yes On Wed, 25 Nov 2015 13:37:30 +0100, Dennis Raddle <dennis.rad...@gmail.com> wrote: : > But what if someone came along and said, "Well, conciseness isn't all > that > important. Having to type more isn't much of a drawback -- it doesn't > really increase the time it takes to write a program once you consider > that > there is a greater time spent in requirements collection, overall design, > debugging, and documentation. The real drawback of concise/expressive > Haskell is the difficulty in understanding and using it fluently. > Ultimately Haskell is just mathematicians having fun, but not very > practical." It is not just the amount of work with the keyboard; it also takes more time thinking about details if you don't have the conciseness of Haskell. More necessary thinking and typing leads to more bugs, software engineering books talk about the number of bugs per 1000 lines of code being constant, independent of the level of the language. Take for instance the memory allocation in C: - you have to remember which macro you defined for the buffer size - check your input if it doesn't overflow your buffer - remember to free the memory at the right point(s) in your program - check that you don't use the pointer after the buffer has been freed The automatic memory allocation in Haskell doesn't just save you the typing for allocation and freeing, it saves a lot of thinking and checking. It prevents a lot of bugs and therefore, it saves testing and debugging time. Similar things can be said about other things that make Haskell programs more compact. There are other advantages when using Haskell, e.g. - better modularity, see the paper "Why functional programming matters"[0] - guaranteed pure functions make it easier to reason about the code. You can find more at the Haskell site[1]. Regards, Henk-Jan van Tuyl [0] http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf [1] https://wiki.haskell.org/Introduction#What.27s_good_about_functional_programming.3F -- Folding@home What if you could share your unused computer power to help find a cure? In just 5 minutes you can join the world's biggest networked computer and get us closer sooner. Watch the video. http://folding.stanford.edu/ ------------------------------ Message: 3 Date: Fri, 27 Nov 2015 12:51:02 -0800 From: Dennis Raddle <dennis.rad...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] comment on this debugging trick? Message-ID: <CAKxLvoq84dZ_B1iw-Z=dgmvqemby2duda5kuigsjlp5+tq1...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" On Fri, Nov 27, 2015 at 10:31 AM, Jeffrey Brown <jeffbrown....@gmail.com> wrote: > Elliot Cameron, very smart guy, once advised me to make illegal state > invalid. Jake Brownson, another, recommended trying to use Maybes and > Eithers instead of throwing exceptions. I'm having trouble coming up with > examples but I think they're both helpful. > > I think I know roughly what you are talking about, but there are places where unexpected input might result in something like an empty list. Suppose I need the head of that list under normal conditions. Maybe the list is produced by library code so I can't alter the data structures. That's the kind of situation I want to identify precisely and immediately. D -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151127/5f6f1627/attachment-0001.html> ------------------------------ Message: 4 Date: Fri, 27 Nov 2015 14:51:45 -0800 From: Jeffrey Brown <jeffbrown....@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] comment on this debugging trick? Message-ID: <caec4ma298edxxtcy9g31uuphmhylc-h8t6ythkzegyumty4...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" In parsing libraries for Haskell the "parse" function (or its equivalent) typically returns an Either. For instance there's parse :: Stream <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Prim.html#t:Stream> s Identity <http://hackage.haskell.org/package/transformers-0.4.1.0/docs/Data-Functor-Identity.html#t:Identity> t => Parsec <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Prim.html#t:Parsec> s () a -> SourceName <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Pos.html#t:SourceName>-> s -> Either <http://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either> ParseError <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Error.html#t:ParseError> a in Text.Parsec.Prim. This is an example of making invalid state impossible. parse could return a list of all possible parses, with the empty list signifying that parsing failed. But by using an Either, the case of failure can be distinguished as a Left. Haskell will know to treat the Left differently, and if you need an error report, that left can bubble (through multiple Either-returning functions, with some handy do-notation) up to the user without ever invoking an exception to the ordinary control flow. On Fri, Nov 27, 2015 at 12:51 PM, Dennis Raddle <dennis.rad...@gmail.com> wrote: > > > On Fri, Nov 27, 2015 at 10:31 AM, Jeffrey Brown <jeffbrown....@gmail.com> > wrote: > >> Elliot Cameron, very smart guy, once advised me to make illegal state >> invalid. Jake Brownson, another, recommended trying to use Maybes and >> Eithers instead of throwing exceptions. I'm having trouble coming up with >> examples but I think they're both helpful. >> >> > I think I know roughly what you are talking about, but there are places > where unexpected input might result in something like an empty list. > Suppose I need the head of that list under normal conditions. Maybe the > list is produced by library code so I can't alter the data structures. > That's the kind of situation I want to identify precisely and immediately. > > D > > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Jeffrey Benjamin Brown -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151127/e9d28423/attachment-0001.html> ------------------------------ Message: 5 Date: Fri, 27 Nov 2015 15:55:07 -0800 From: Dennis Raddle <dennis.rad...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] comment on this debugging trick? Message-ID: <cakxlvorxacfac_s61t3wqnewnw3cr7tx6_maafoybd06c72...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" On Fri, Nov 27, 2015 at 2:51 PM, Jeffrey Brown <jeffbrown....@gmail.com> wrote: > In parsing libraries for Haskell the "parse" function (or its equivalent) > typically returns an Either. For instance there's > > parse :: Stream > <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Prim.html#t:Stream> > s Identity > <http://hackage.haskell.org/package/transformers-0.4.1.0/docs/Data-Functor-Identity.html#t:Identity> > t > => Parsec > <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Prim.html#t:Parsec> > s > () a -> SourceName > <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Pos.html#t:SourceName>-> > s -> Either > <http://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either> > ParseError > <http://hackage.haskell.org/package/parsec-3.1.6/docs/Text-Parsec-Error.html#t:ParseError> > a > > in Text.Parsec.Prim. This is an example of making invalid state > impossible. parse could return a list of all possible parses, with the > empty list signifying that parsing failed. But by using an Either, the case > of failure can be distinguished as a Left. Haskell will know to treat the > Left differently, and if you need an error report, that left can bubble > (through multiple Either-returning functions, with some handy do-notation) > up to the user without ever invoking an exception to the ordinary control > flow. > I've used the Either monad for exception handling. Yes, I was using do notation. This current project is just for myself. Exceptions represent either bugs or malformed input. I can catch some of them in the IO monad so my program prints an error but keeps running and lets me try again. If the program crashes out, no big problem. I'm parsing MusicXML with Text.XML.Light. The XML is always well-formed. However *MusicXML* is not a well-defined language. Like, does every <note> element have a child element called <voice>? No guarantee I can find, yet it has been true in the examples I've tried with the only typesetter I'm using to generate MusicXML. I can get my program running quickly without bothering with the case that <voice> is absent. But if that case someday occurs, I want to know precisely and immediately. Yet I don't want to write a detailed error message for every violated assumption, of which there are dozens necessary. So my solution is to find these things with case exhaustions. The program crashes and I have to inspect the code, but no problem. D -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151127/588aab42/attachment.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 89, Issue 49 *****************************************