Interesting critique of OCaml

View: New views
17 Messages — Rating Filter:   Alert me  

Interesting critique of OCaml

by Don Stewart-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

An interesting critique of OCaml.

http://enfranchisedmind.com/blog/2008/05/07/why-ocaml-sucks/

One phrase that stood out, regarding GHC's support for deforestation
transformations like build/foldr and stream fusion:

   "Haskell is doing data structure level optimizations with the ease
   that most other compiler do peephole instruction optimization. This
   is a non-trivial result."

Which I think really captures the joy of being able to write algebraic
and data structure transformations, via rewrite rules, without having to
extend the compiler -- all thanks to purity, laziness, and static
typing.

-- Don
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Interesting critique of OCaml

by Chad Scherrer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Don Stewart <dons <at> galois.com> writes:
[interesting quote...]
> Which I think really captures the joy of being able to write algebraic
> and data structure transformations, via rewrite rules, without having to
> extend the compiler -- all thanks to purity, laziness, and static
> typing.

This makes me wonder... Rewrite rules are certainly effective, and seem to be a
good place to point (one of many, of course) when asked why you'd want a
language with Haskell's characteristics. It seems like there should be an
argument to this effect:

1. You'd like be able to declare compile-time transformations like
  map f . map g = map (f . g)
without messing with the compiler

2. For x in [purity, laziness, static typing, higher-order functions]
  If you don't have x, here's what goes wrong (or can go wrong)

3. Of the very few languages with these characteristics, Haskell is the most
widely-used, and the most actively developed and researched.

Now, I don't know much about lisp, but aren't code transformations like this the
whole point of macros? What makes is difficult to do the same thing in this
context?

What about object-oriented languages? The problem with step 1 in the argument is
that it's already cast in a functional-programming framework. Is there a way to
recast it so OOP could play?

Thanks,
Chad

PS - the link now gives a "500 server error" - did our traffic overwhelm it? Is
the cafe the next slashdot? ;)

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Interesting critique of OCaml

by Achim Schneider :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Chad Scherrer <chad.scherrer@...> wrote:

> Don Stewart <dons <at> galois.com> writes:
>
[Stuff where I totally agree]
>
> Now, I don't know much about lisp, but aren't code transformations
> like this the whole point of macros? What makes is difficult to do
> the same thing in this context?
>
Proof of correctness, or even a graspable notion of correctness for the
whole semantics of the language. If you consider that hygienic macros
(that is, macros that don't make a mess of every concept you have of
"namespace") were introduced quite late, you might get a grasp on how
bravely and hackish they were designed.

> What about object-oriented languages? The problem with step 1 in the
> argument is that it's already cast in a functional-programming
> framework. Is there a way to recast it so OOP could play?
>
Yes, I suppose so, but you'll be left with Haskell with an OOP Syntax,
and a style of OOP that uses Objects mainly as closures, which isn't a
thing OOP coders regularly, or at all, do, to get the granularity of
replacements that is necessary to consider them useful in the first
run.

Some years or decades ahead, perhaps Haskell will not be able to avoid
being successful anymore, and that is the time where you'll see things
that look like Java, feel like Java, work like Java, but still use a
Haskell RTS.


--
(c) this sig last receiving data processing entity. Inspect headers for
past copyright information. All rights reserved. Unauthorised copying,
hiring, renting, public performance and/or broadcasting of this
signature prohibited.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of OCaml

by Andrew Coppin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Achim Schneider wrote:
> Some years or decades ahead, perhaps Haskell will not be able to avoid
> being successful anymore, and that is the time where you'll see things
> that look like Java, feel like Java, work like Java, but still use a
> Haskell RTS.
>  

I'm told they're calling it F#...

[No, I can't verify the truth of that claim. But every time I mention
Haskell, everybody goes "Haskell is obsolete. Everybody who even *wants*
functional programming in the first place will just use F# instead. The
end."]

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of OCaml

by Andrew Coppin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Chad Scherrer wrote:
> PS - the link now gives a "500 server error" - did our traffic overwhelm it? Is
> the cafe the next slashdot? ;)
>  

Hell, I can't even get a TCP SYN-ACK packet out of it... :-/

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of OCaml

by Donnie Jones :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hello,


I pasted a copy of the article below for those that cannot access the site.

I would be interested to see an article on Haskell in the same light as this Ocaml article, aka a constructive criticism of Haskell. 

Enjoy!
__
Donnie

### Begin Article ###

Why Ocaml Sucks

Published by Brian at 6:49 pm under Functional Languages: Ocaml, Haskell

One of the ways to not fall into the blub fallacy is to regularly consider those ways in which your favorite language is inferior, and could be improved- preferrably radically improved. Now, it should come as a surprise to no one that my favorite language is (currently) Ocaml. So as an intellectual exercise I want to list at least some of the ways that Ocaml falls short as a language.

I will note that if you use this post as a reason to not use Ocaml, you are a fool and are missing the point of this post. With the possible exception of Haskell, no other language I know of comes close to getting all the things right that Ocaml gets right.

So, with that in mind, let's begin.

  1. Lack of Parallelism

    In case you haven't guessed it from reading this blog, I think parallelism is going to be the big problem for the next decade. And while Ocaml does have threads, it also has a big ol' global interpreter lock, so that only one thread can be executing Ocaml code at a time. Which severely limits the utility of threads, and severely limits the ability of Ocaml programmers to take advantage of multiple cores. Now, to give the INRIA team credit, the reason they have for this is a good one- we (programmers) still don't know for sure how to write multithreaded code safely (I have my suspicions, but I have no proof), and we had even less of an idea a decade and a half ago when the fundamentals of Ocaml were being decided. And supporting multithreaded code slows down the garbage collector. And, a decade and a half ago, multithreaded code was a lot less important, and multicore systems were rare and expensive. So this is mainly just Ocaml showing it's age. But still, if I were to pick the biggest shortcomming of Ocaml, this would be it.


  2. Printf

    You know what? Printf was a bad idea for C- having this special domain-specific language in what looks like strings to control formatting. It's even worse in Ocaml, where you have to add special kludges to the compiler to support it (at least the way Ocaml did it- there are smarter ways that don't require compiler kludges). You might think that "%3d" is a string in Ocaml, and sometimes you'd be right. But sometimes it's a (int -> '_a, '_b, '_c, '_a) format4. This horrid type (which is not a string) is necessary to encode the types of the arguments printf needs to be passed it.

    The one thing I know of that C++ did better than Ocaml was ditching printf. And the idea of iostreams even isn't that bad- except for the fact that they encouraged generations of C++ programmers to abuse operator overloading (hint to Bjarne Stroustrup: << and >> are not the I/O operators, they're the bit shift operators!), and they made the iostream classes exceptionally difficult to inherit from or extend. But a combination of C++ style iostream operators and Java style iostream classes would have worked so much better, and not required hacking the compiler. An even better idea might be some variant of functional unparsing.


  3. Lack of multi-file modules

    Ocaml has an exceptionally powerfull and flexible module and functor system, which stops rather annoyingly at the file level. Files are modules, and files (and modules) can contain other modules within them, but you can't collect several files into one big multi-file module. You especially can't say that certain files, while they may be visible to other modules within the multi-file module, aren't visible outside the multi-file module. This is especially useful if you want to factor out common base functionality from a library of modules into a shared module, but not productize it for export to the outside world. This limits the ability of the programmers to correctly structure large projects.

    The -for-pack arguments help fix a lot of this, sorta- but they require smarts in the build system and generally special .mli files to control visibility. It can be done, but it's not clean- it makes the build process a lot more complex, and important information about which files are externally visible or not is contained somewhere that is not in the source code. This could certainly be done a hell of a lot better than it is.


  4. Mutable data

    Mutable data is both a blessing and a curse. It is a blessing when learning the language, especially when you're coming from conventional imperative programming languages. Rather than having to learn what a lazy real time catenable dequeue is, and why you want one, you can just bang out a quick mutable doubly linked list and get the same behavior. I would argue that if you're coming from the imperative/OO world, it's easier to learn Ocaml than Haskell for precisely this reason.

    But this implies that mutable data is training wheels of a sort. And, like the fact that training wheels prevent you from going fast, mutable data prevents Ocaml from doing a lot of interesting and useful things. Many of Haskell's most interesting features- such as STM, easy multithreading, and deforrestation, and scrap your boilerplate, arise out of Haskell being purely applicative. Mutable data is holding Ocaml back.


  5. Strings

    This is more of a minor nit, but the representation of strings as a (compact) array of chars is stupid. It made sense of pointer-arithmetic C, not so much for Ocaml. The definition of chars as 8 bits prevents the internationalization of Ocaml beyond the European languages, and the representation is inefficient. The most important operations on strings are either iterating over all the characters in a string, or concatenating two strings. Random access and mutation is rare, unless you're using the string as a bit or byte array, which is encouraged by the nature of strings. Bit arrays should be first class types of themselves, with specialized internal representations, allowing strings to be optimized as strings. An unbalanced tree based structure would allow O(1) (and exceptionally fast) string concatenation while preserving the O(N) cost to iterate over all characters in a string. Also, strings are currently mutable data, and as described above, mutable data is teh sucketh. This is doubly so for strings, which can be profitably interned (and thus should be).


  6. Shift-reduce conflicts

    Shift-reduce conflicts happen in parser generators, especially LALR(1) parser generators like yacc and ocamlyacc, where there are situations where the parser doesn't know if the current expression is complete, or can still go on. The golden example of this is the "dangling else" problem of C and other languages, where you might see code like this:

        if (test1) then
    if (test2) then
    expr1
    else
    expr2

    The problem is that the parser, after it has finished parsing expr1 expression and looking at the else, doesn't know wether to shift it (making the else and expr2 part of the inner if) or reduce it (making the else part of the outer if).

    I strongly recommend everyone who is developing a language to write the initial syntax in a LALR(1) parser, and eliminate all shift-reduce (and especially reduce-reduce) conflicts while you still can, because every shift-reduce conflict is a bug waiting to happen. In the above example, based on indenting, it is very likely to be meant to be part of the outer if, but the parser is going to bind it to the wrong if, causing a bug. This is slightly less bad in Ocaml, where generally the bug will be a type error, but that doesn't mean it's good. And Ocaml has literally dozens of these suckers lying in wait to bite and unwary programmer. Even I get bitten by shift-reduce conflict generated bugs on a regular basis.

    A quick side digression for those who started yelling that the indentation should be significant to the compiler. Consider the output that would be caused by printing the following 3 C/Ocaml strings: "\n \tx\n", "\n \t x\n", and "\n\t x\n". Each one starts with a newline, ends with an x and a newline, and contains exactly two spaces and a tab in between. Now, what columns do the three x's end up in? The answer is "it depends upon which editor you're using to view the output with, and what configuration that editor has". I just spent a large chunk of this afternoon cleaning up a bunch of code written by a programmer who merrily mixed spaces and tabs, and used a different editor than I do. As a consequence, what looked neatly formatted to him looked like gibberish to me. And if two humans can't agree on whether a particular piece of code is well formatted or not, what hope does the computer have to figure out the situation? The solution is to eliminate the root cause of the problem (the shift-reduce conflicts), not add a new way to introduce subtle and hard to debug errors.


  7. Not_found

    One of the worst design decisions Ocaml has to have made is Not_found- this is the exception that's thrown whenever something isn't found. Tha'ts helpfull, isn't it? It's thrown by the Set and Map modules (and all their functor applications) the List module, various other data structure libraries, various regular expression libraries, and, as a rule, just about any random peice of code. And it contains absolutely no information as to what is not found, or what was being looked for. Or even what was doing the looking. At least Failure and Invalid_argument at least take a string argument, which is generally is the name the function that failed. So if you see the exception Invalid_argument("hd"), you know at least to be looking at calls to List.hd (or to other functions named "hd"). But Not_found? This is the sound of your hd hitting the desk, repeatedly.

  8. Exceptions

    And while I'm ragging on Not_found, let me rag on exceptions a bit. Exceptions are used way too commonly in Ocaml- OK, I'll give Failure, Invalid_argument, and Assertion_failure a pass, but basically Not_found and End_of_file should never, ever, be thrown. Return 'a option instead.

    This has non-trivial implications. For example, take the classic newbie ocaml "mistake"- write a function that reads in a file and returns the file as a list of strings, one string per line. Should be easy. We use input_line as to read a line, and write our code like:

    let read_file desc =
    let rec loop accum =
    try
    let line = input desc in
    loop (line :: accum)
    with
    | End_of_file -> List.rev accum
    in loop []
    ;;

    And they can't understand why this code blows up when they try to read a file with more than 30,000 lines in it. There are standard solutions to this- but they make the code uglier, and by far the best is to wrap the exception throwing code in an expression that turns the exception into an option, like:

    let read_file desc =
    let rec loop accum =
    let line =
    try
    Some(input desc)
    with
    | End_of_file -> None
    in
    match line with
    | Some s -> loop (s :: accum)
    | None -> List.rev accum
    in loop []
    ;;

    At which point you really have to raise the question of why input_string didn't just return string_option from the get-go.

    The other popular alternative is to use mutable data. Which is just trading off one problem set for another.

    There is, by the way, an interesting idea for expetion handling that's been raised recently (see here and here). The basic idea is that the current Ocaml syntax for declaring an exception handler is:

        try
    expr1
    with
    | Exception -> expr2

    where if expr1 doesn't throw an exception, the value of the hole expression is the value returned by expr1- otherwise, if it throws Exception, then the whole expression has the value expr2. This syntax is replaced by:

        try var = expr1 in
    expr2
    with
    | Exception -> expr3

    Here, if expr1 does not throw an exception, then the value of the whole expression is that of expr2 with variable var having the value of expr1, while if it throws Exception, then the value of the whole expression is then expr3. Note that exceptions are only caught in expr1- it's just that if an exception is caught, then expr2 is skipped as well. But this means that calls from within expr2 can be tail calls. Let's take a look at our read_file program, the newbie way, a third time, this time with our new exception syntax:

    let read_file desc =
    let rec loop accum =
    try line = input_line desc in
    loop (line :: accum)
    with | End_of_file -> List.rev accum
    in
    loop []
    ;;

    Since the tail call to loop is outside where we catch exceptions, it's a true tail call, and the function works "as expected". And the fact that we're using exceptions instead of options isn't that big of a deal anymore (Not_found still sucks, due to it's simple ubiquity and taciturnity). If someone with more time and/or camlp4 knowledge than I have wants to write this up as an extension, I'd be eternally gratefull.

    While I'm at it, would it be possible to have exceptions in the type system? I know Java tried this and everyone hated it, but Ocaml has two things that Java didn't- type inference and type variables. The type variables are nice because they allow you to deal with "unknown" exceptions- for example you could have a function of type (int -> int throws 'a) -> int throws 'a, meaning that you don't know (or care) what exceptions the passed-in funciton might throw, but that you throw the same exceptions (presumably by calling the passed-in function). Type inference also means you don't have to declare most of these cases, the compiler can infer what exceptions are thrown. This level of changes to the type system are highly unlikely, but a boy can dream, can't he?

  9. Deforrestation

    This really should be under the "mutable data is the sucketh" section, but oh well. Haskell has introduced a very interesting and (to my knowledge) unique layer of optimization, called deforrestation. Basically, what happens if that the ghc compiler recognizes and can optimize certain common sub-optimal data structure transformations. For example, it can convert map f (map g lst) into map (f . g) lst, where the peroid (.) is the function composition operator. There are a couple of obvious advantages to being able to do this- for example, by doing so we've eliminated an intermediate data structure, and created new opportunities for optimizing the combined f and g functions.

    But there are two things of serious interest to me about this. First of all, this is the first time I've seen optimizations at this level being this easily performed. Companies like Intel and IBM have thrown literally man-millenia at this problem, and the solutions they've come up with were limited and fragile (slight changes to the code would enable or disable the optimization). And yet the Haskell people implemented in one Simon Peyton Jones long weekend (also known as a couple of man months for mere mortals like you and I). The reason for this is that the real difficult is not actually implementing the transformation, or even detecting that the transformation might be applicable, it's proving that the transformation is correct, that the code after the transformation is applied behaves identically to the code before the transformation is applied. In langauges with mutable data, like Fortran and C++ (and Ocaml), this is decidedly non-trivial. In Haskell, you can dash off the proof that it's always correct on the back of a cocktail napkin- proving that it's correct in the general case for all lists and all functions. And that thus the compiler doesn't even need to check- once it detects that the pattern can be applied, it can just go ahead and apply it. Haskell is doing data structure level optimizations with the ease that most other compiler do peephole instruction optimization. This is a non-trivial result.

    The second important aspect of this is that it changes the concept of what optimization is, or should be. I forget which paper it was I was reading that said that optimization should really be called depessimization. That the programmer wants to introduce pessimizations- the programmer could do the above deforrestation himself, except that to do so would make maintainance more difficult, as it'd break module boundaries, or requires knowledge of how a particular module is implemented, or simply requires knowledge of widely seperated peices of code. The goal of the compiler, rather than striving to produce some "optimal" (and thus impossible to obtain) implementation, but simple to undo the pessimizations that the programmer has introduced in the name of maintainablity, modularity, readability, and/or simplicity. The programmer shouldn't have to worry about creating intermediate data structures, and should worry about corrupting his code in the name of performance- that's the compilers job (don't break your code, let the computer do that for you! :-).

    Needless to say, between the mutable data, the side effects, and the handling of exceptions, Ocaml isn't going get deforrestation any time soon.


  10. Limited standard library

    If writing monad tutorials is the cottage industry of Haskell programmers, than rewriting the standard library is Ocaml's cottage industry. You almost can't call yourself an Ocaml programmer if you haven't rewritten a goodly chunk of the standard library at least once. This is because every Ocaml programmer has a long list of functions that should (they think) be in the standard library but just aren't. The big ones for me are the lack of Int and Float modules ready for use by the Set and Map functors, the lack of an already-instantiated Map and Set modules for Strings, Ints, and Floats, and the lack of a list to set/map function. None of these are exactly hard to do, just annoying to have to constantly redo.

    Of course, the problem with this is the range and design patterns of Ocaml programmers- especially with comparison to languages like Java and C++, or even Ruby. The design patterns of a top-5% Java programmer is not all that different from the design philosophy of a bottom-30%'er. There may be differences in precisely what features are supported, and what names things are given may change, but the broad stroke designs will be similiar. The design patterns of Brian Hurt circa 2008 are radically different than the design patterns of Brian Hurt circa 2003. For example, were I to redo extlib now, it's be purely applicative, heavily functorized, lots of monads, and a fair bit of lazy evaluation, as opposed to the code I wrote in 2003.


  11. Slow lazy

    Speaking of lazy evaluation- Ocaml's built-in lazy evaluation is wicked slow. I've actually timed it, and it's like 130+ clock cycles of overhead to force a lazy value the first time, and over 70 clock cycles of overhead to force it the second and subsequent times (when all it has to do is return the cached value). Given that most of the good uses of lazy evaluation has it wrapping computations that are like 10 clock cycles long or so, the overhead of the lazy thunk dominates. In this era of Ruby programmers, this may not seem like much- but this overhead discourages Ocaml programmers from using lazy evaluation. Which is a shame, as anyone who has read Okasaki knows how frimping usefull it is.



Well, that's my list so far- subject to revision without notice. The vast majority of them qualify as picking nits- and they are. If you can damn with faint praise, then you should also be able to praise with faint damning- and this certainly qualifies as that. Most of the problems here only became apparent (or their solutions became apparent) long after Ocaml was mature and set. For example, it's only be recently that multi-threading has been a big deal. And the usefullness of monads and lazy evaluation for functional programming weren't understood until the late nineties/early 21st, a decade after Ocaml's formative years. So this whole post mostly amounts to whining that the Ocaml developers weren't even more insightfull and foresightfull than they were. And, compared to the major revisions Ocaml's "age-mates" Java and Perl have gone through, it's stood up well with the passing of time.

No lanuage is perfect, including Ocaml. And to continue to improve we must understand what has gone before- both what worked, and what didn't.

Popularity: 6% [?]

### End Article ###


On Thu, May 8, 2008 at 2:27 PM, Andrew Coppin <andrewcoppin@...> wrote:
Chad Scherrer wrote:
PS - the link now gives a "500 server error" - did our traffic overwhelm it? Is
the cafe the next slashdot? ;)
 

Hell, I can't even get a TCP SYN-ACK packet out of it... :-/


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of OCaml

by Darrin Thompson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/5/8 Donnie Jones <donnie@...>:
> I would be interested to see an article on Haskell in the same light as this
> Ocaml article, aka a constructive criticism of Haskell.
>

http://www.drmaciver.com/2008/02/tell-us-why-your-language-sucks/

--
Darrin
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

RE: Interesting critique of OCaml

by Timothy Docker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

| An interesting critique of OCaml.
|
| http://enfranchisedmind.com/blog/2008/05/07/why-ocaml-sucks/

Interesting to me is that my pet ocaml peeve is not there: namely the
lack of convenient operator overloading. Admittedly I only used ocaml
for 6 months, but I never adapted to needing to write (+) for ints, and
(.+) for floats.

>From the F# documentation it would appear that F# does have overloaded
numerical operators, at least. I'm not sure how these fit into its type
system however. (Their type is documented as "overloaded").

Tim

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Interesting critique of OCaml

by Michael Vanier :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Actually, it's (+) for ints and (+.) for floats.  Which kind of proves your point.

Mike

Tim Docker wrote:

> | An interesting critique of OCaml.
> |
> | http://enfranchisedmind.com/blog/2008/05/07/why-ocaml-sucks/
>
> Interesting to me is that my pet ocaml peeve is not there: namely the
> lack of convenient operator overloading. Admittedly I only used ocaml
> for 6 months, but I never adapted to needing to write (+) for ints, and
> (.+) for floats.
>
>>From the F# documentation it would appear that F# does have overloaded
> numerical operators, at least. I'm not sure how these fit into its type
> system however. (Their type is documented as "overloaded").
>
> Tim
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@...
> http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by Andrew Coppin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Darrin Thompson wrote:
> 2008/5/8 Donnie Jones <donnie@...>:
>  
>> I would be interested to see an article on Haskell in the same light as this
>> Ocaml article, aka a constructive criticism of Haskell.
>>
>>    
>
> http://www.drmaciver.com/2008/02/tell-us-why-your-language-sucks/
>  

Impressive. He thought of a whole bunch of stuff I hadn't thought of.

While I'm here - I'm aware of how you control importing [or not] from
the Prelude. Is there a way that I can, for example, import all the
stuff like the basic types, classes, etc., but *not* all the
list-related stuff? Or is the Prelude not that modular?

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by Brent Yorgey :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Fri, May 9, 2008 at 10:02 AM, Andrew Coppin <andrewcoppin@...> wrote:
Darrin Thompson wrote:
2008/5/8 Donnie Jones <donnie@...>:
 
I would be interested to see an article on Haskell in the same light as this
Ocaml article, aka a constructive criticism of Haskell.

   

http://www.drmaciver.com/2008/02/tell-us-why-your-language-sucks/
 

Impressive. He thought of a whole bunch of stuff I hadn't thought of.

While I'm here - I'm aware of how you control importing [or not] from the Prelude. Is there a way that I can, for example, import all the stuff like the basic types, classes, etc., but *not* all the list-related stuff? Or is the Prelude not that modular?

Not only is the Prelude not that modular, there's not really any mechanism to make it so.  There's no way to partition an export list in such a way that whole chunks of it can be imported/not imported at a go.  Would that be a nice feature?  I don't know, possibly.

-Brent

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by David Roundy-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, May 09, 2008 at 11:35:32AM -0400, Brent Yorgey wrote:

> On Fri, May 9, 2008 at 10:02 AM, Andrew Coppin <andrewcoppin@...>
> wrote:
> > While I'm here - I'm aware of how you control importing [or not] from the
> > Prelude. Is there a way that I can, for example, import all the stuff like
> > the basic types, classes, etc., but *not* all the list-related stuff? Or is
> > the Prelude not that modular?
>
> Not only is the Prelude not that modular, there's not really any mechanism
> to make it so.  There's no way to partition an export list in such a way
> that whole chunks of it can be imported/not imported at a go.  Would that be
> a nice feature?  I don't know, possibly.

Ordinary functions are easily split off from the Prelude.  The only tricky
bit is classes and class instances, and that's a Hard Problem, as far as I
can tell.  And, of course, "only" is quite an understatement here.
--
David Roundy
Department of Physics
Oregon State University
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by Andrew Coppin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Brent Yorgey wrote:

>
> On Fri, May 9, 2008 at 10:02 AM, Andrew Coppin
> <andrewcoppin@... <mailto:andrewcoppin@...>> wrote:
>
>     While I'm here - I'm aware of how you control importing [or not]
>     from the Prelude. Is there a way that I can, for example, import
>     all the stuff like the basic types, classes, etc., but *not* all
>     the list-related stuff? Or is the Prelude not that modular?
>
>
> Not only is the Prelude not that modular, there's not really any
> mechanism to make it so.  There's no way to partition an export list
> in such a way that whole chunks of it can be imported/not imported at
> a go.  Would that be a nice feature?  I don't know, possibly.

Well, if the Prelude was split into several seperate modules, you could
import just the modules you wanted. That sounds pretty easy to me. [I
mean, apart from the minor detail that no current implementation works
this way...]

By default, if you don't ask for anything, your module automatically
imports "Prelude". What if we made Prelude a module that just imports
and re-exports several other modules - Prelude.Types, Prelude.Classes,
Prelude.List (or rather, a subset of Data.List). Then if a module
imports Prelude, or anything under Prelude, it turns off the automatic
import, similar to the current system.

Of course, I guess all this isn't likely to happen any time soon... I'm
just throwing ideas out there.

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by David Roundy-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, May 09, 2008 at 05:19:05PM +0100, Andrew Coppin wrote:

> Brent Yorgey wrote:
> >
> >On Fri, May 9, 2008 at 10:02 AM, Andrew Coppin
> ><andrewcoppin@... <mailto:andrewcoppin@...>> wrote:
> >
> >    While I'm here - I'm aware of how you control importing [or not]
> >    from the Prelude. Is there a way that I can, for example, import
> >    all the stuff like the basic types, classes, etc., but *not* all
> >    the list-related stuff? Or is the Prelude not that modular?
> >
> >
> >Not only is the Prelude not that modular, there's not really any
> >mechanism to make it so.  There's no way to partition an export list
> >in such a way that whole chunks of it can be imported/not imported at
> >a go.  Would that be a nice feature?  I don't know, possibly.
>
> Well, if the Prelude was split into several seperate modules, you could
> import just the modules you wanted. That sounds pretty easy to me. [I
> mean, apart from the minor detail that no current implementation works
> this way...]
>
> By default, if you don't ask for anything, your module automatically
> imports "Prelude". What if we made Prelude a module that just imports
> and re-exports several other modules - Prelude.Types, Prelude.Classes,
> Prelude.List (or rather, a subset of Data.List). Then if a module
> imports Prelude, or anything under Prelude, it turns off the automatic
> import, similar to the current system.
>
> Of course, I guess all this isn't likely to happen any time soon... I'm
> just throwing ideas out there.

It's pretty easy (albeit tedious) to do this for yourself (except that you
wouldn't automatically turn off the import of Prelude, and you'd still
suffer from the instances disease).

module Prelude.Types ( Int, Double, Char, String ) where

import Prelude

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by Andrew Coppin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Roundy wrote:
> It's pretty easy (albeit tedious) to do this for yourself (except that you
> wouldn't automatically turn off the import of Prelude, and you'd still
> suffer from the instances disease).
>
> module Prelude.Types ( Int, Double, Char, String ) where
>
> import Prelude
>  

Sounds like a Hackage project for any suitable-bored persons. :-)

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

Re: Re: Interesting critique of Haskell

by Henning Thielemann :: Rate this Message: