base libraries

Bulat Ziganshin bulat.ziganshin at gmail.com
Sun Nov 26 05:08:18 EST 2006


Hello Udo,

Saturday, November 25, 2006, 4:34:21 AM, you wrote:

>> the same function, in polymorphic way:
>> 
>> splitToBaseExt :: FilePathClass fp =>  fp -> (fp,fp)

>> this change in interface would be indistinguishable for 99% of us.

> Err, no.  99% of us _don't_ write flawless programs.  With every
> overloaded symbol you get worse error messages.  Have you ever used C++?
> Ever got a screenful of completely incomprehensible gobbledygook because
> you forgot a namespace qualification somewhere?  Go ahead with all these
> FooLike and BarAble classes and you get the same from Haskell (and then
> some, including exponential runtime of the type checker).

you shouldn't mix C++ template system with Haskell classes. C++ can't
check templates at the time where template defined that leads to
too late error messages. just imagine that improper definition of
'sum' will barks on each call site with a message that you can't use
(&&) on Ints. and complex types in such messages is just because
templates *don't* use C++ class system with its abstraction ability
and the whole type structure shows up in the message

if you want to argument against my idea, it's better to find situation
where Haskell classes bite you (and stop rely on false assumption that
something that is like C++ is automatically bad)

> Pathnames are short strings.  No need to optimize for performance,
> instead optimize for clarity.

let's say that 99% of programs don't need any optimization at all. so
there is no need in ByteString, Int and other stupid types. stop
polymorphism and use BigDecimal for any numeric data! :)

functional programming is widely recognized as strong but slow
approach. while now anyone who need to write efficient program will
probably select C++, things changes and we wrote more and more
efficient libraries - be it for integers, strings, arrays or
pathnames. I've broken the rule that archivers (like zip) should be
written in C++ and developed one with Haskell. in order to make this
program efficient, i've written several general-purpose libs that
don't existed before - such as serialization or packed string ones, or
I/O using unicode filenames

so, now i have a code that allows to write efficient programs dealing
with a very large number of files. next, Unix/Win works with
utf8/utf16 encoded filenames. so, efficient program should use natural
filename representation instead of converting to/from String

while we can develop a series of libraries that works with filenames
represented as Strings, UTF8 ByteStrings and so on, i think the right
way is to have one FilePath library that uses operations of some
typeclass. as long as you don't argue for restricting monad libraries
to IO monad, array libraries - to boxed arrays and numeric libraries -
to Integer, you should agree that functionality required only by *some*
developers, makes error messages more complex for the rest

moreover, i think that Haskell now is the best language for system
programming, such as developing mailer daemon, gaming server, or
transaction system. but lack of efficient networking, I/O and data
structure libraries makes development of system software sort of
do-it-yourself task


> An algebraic datatype reflecting the
> algebra of filenames would likely be even more clear, but defining a
> type class just to support different encodings is definitely
> overengineering and very likely a bad idea.  Remember, this ends with
> std::basic_ios< char, std::char_traits<char> > or worse.

yes, types are complex nowadays :)  you should look into my Streams
library which includes such type of beasts. it uses class-based,
multi-layered design in order to provide wide set of operations on
wide set of stream types with wide set of optional modifiers (such as Char
encoding or inter-thread locking). type classes allows here to split
functionality into smaller manageable pieces, that can be easily
replaced with 3rd-party libs. can you propose alternative design that
allow the same flexibility with a less cluttered type names? i think no.
the good news for you is that Haskell can infer types and constraints
so using very complex types don't need a tons of type constructors as
in C++

complex type names reflects *factorizing* of functionality and that is
the C++ templates idea that i reused in my Streams lib. instead of
defining a lot of independent getByte operations for each possible
stream type, i use a class here, and this allows the next,
serialization level, to work with any stream.

i think that type classes are underweighted in Haskell community
because it's not classical FP technique, and while we can't live
without standard classes, we develop too small number of our own ones.
or at least, not in all areas. besides of Monad or IArray classes, we
should think about collection classes (for which Stringable is just a
very partial case)


-- 
Best regards,
 Bulat                            mailto:Bulat.Ziganshin at gmail.com



More information about the Libraries mailing list