 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 16/08/2012 12:02 AM, Darren New wrote:
> On 8/14/2012 3:17, clipka wrote:
>> If you want to give such guarantees, you can't handle variables of
>> types for
>> which you have no declaration, because obviously you can't tell
>> whether they
>> can do A, B, C and D or not.
>
> To be fair, I suspect Haskell just treats that declaration as if you're
> returning Object in C#. In other words, haskell I suspect doesn't let
> you return a value whose type you can't see, but instead of making that
> illegal, it essentially inserts a cast for you to an opaque supertype.
> (So to speak, of course, since Haskell isn't OO.)
You're probably write. (Depending on how you want to argue about the
semantics.) My point was just that "oh, it's /obviously/ impossible"
isn't actually so obvious.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Heh. And I thought Haskell was the only language stupid enough to
>> claim that
>> the reading the formal language specification is a good way to learn
>> how to
>> program with it...
>
> Most languages lack a formal spec. C# gets close. Hermes actually
> generates the compiler based on the formal spec, so yeah.
C# is supposedly an ISO standard, so there must be a published
specification for it. However, while the spec is the thing you want to
read if you're building a new implementation (e.g., Mono), it's usually
an utterly lousy way to learn how to actually /use/ a programming language.
(Although, as I discovered, the C# "spec" actually reads more like a
tutorial, so...)
> So show me a function that returns a value of a type I can't see.
>> module Foobar (Foo (..), foobar) where
>>
>> data Foo = Foo Int deriving Show
>> data Bar = Bar Int deriving Show
>>
>> foobar :: Foo -> Bar
>> foobar (Foo x) = Bar x
>>
>> Notice how Bar is not exported, yet foobar is exported, and its return
>> type
>> is Bar.
>
> So you declare foobar returning an interface that support Show, which is
> what you've done.
It still works if you take Show out. (Although in that case it becomes
even more pointless.)
My point isn't that this is a useful thing to do. It's just that it
doesn't necessarily /have/ to be impossible. C# /chose/ to make it
impossible - a not unreasonable choice, but not the /only/ choice.
>>> Well, actually, everything's an object.
>>
>> Except that no, no it isn't. Apparently only values of reference types
>> are considered "objects". :-P
>
> Uhhhh, no. Everything is an object.
>
>> You could /almost/ say "everything's a class", except that no, we have
>> enums and stuff which aren't considered "classes".
>
> Of course they're classes. If you want, you can even look up what their
> superclass is. For example, 23 is of class System.Integer32 or some such.
According to the spec document, any value of a value type is not
formally referred to as an "object"; that term is reserved for values of
reference type. Similarly, the term "class" is reserved to refer to
types declared with the "class" keyword.
Of course, with the C# unified type system, all types /behave/ as
classes in the usual OO sense (which is the point you're making). It's
just that the C# language spec does not /call/ then classes.
>> Right. So enumerations aren't integers, and that's why you define the
>> corresponding integer value of each case right there in the
>> definition? :-P
>
> They correspond to integers. They aren't integers. I *do* think Java did
> that one much better.
What, by not having enumerations at all?
>> If you have real enumerations, why do you need a special-case for bool?
>
> Because you have syntax in the language that uses specific types, like
> "if" statements.
Haskell has special if syntax, and yet Bool is defined in library code.
>> (The same argument applies to Haskell: Why the HELL did they special-case
>> the list type, when you can trivially define it manually? What there they
>> thinking??)
>
> They were thinking you needed special syntax.
You need special syntax for integers, and yet anybody that wants to can
define a new integer type. (E.g., I wrote a library that lets you deal
with "half integers" - numbers which are integers when multiplied by 2.)
What they /should/ have done is let you use what is now "list literal
syntax" for /any/ suitable container type. Unfortunately, they didn't.
And what's with [Int], anyway? Would List Int just be too readable?
> Hermes, for example, does not have a string type. But if you have an
> enum where each name is one character long, you can make an array of
> that value by sticking it inside quotes. Which I thought was kind of cute.
Nice. :-S
>> OK, whatever. I haven't really explored it all that much yet, but it
>> doesn't appear to compare well to Eiffel.
>
> What doesn't, C#? There are various things Eiffel does theoretically
> better, if they're actually implemented.
I doubt Eiffel has half as many libraries as C# though. Like most
well-designed languages, it never really took off.
(I'm guessing C# took off because it's explicitly designed to look like
one of the other badly-designed languages which is already wildly
popular...)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> So if a class tries to implement both interfaces, it can't provide
>> different
>> implementations for these two distinct methods merely because their names
>> clash?
>
> That depends on your language. Java? I don't think so. C#? Definitely.
> But then you can't invoke the interface call without specifying which
> one you mean, so there's no ambiguity.
From what I've seen, you can't just use the fully-qualified method
name, you have to actually cast the entire object to the type of the
interface first. Which seems rather necessarily long-winded...
>> According to the Great Language Shootout, C# Mono is 3x slower than C.
>
> So, an open source clone is slow, thus the version Microsoft uses that
> compiles down to optimized native code must be also?
According to Wikipedia, Mono /also/ does JIT compilation to native code.
(Although I agree it would be better if there were published benchmark
results for .NET itself.)
>>> Sure there is, because you recompile the code while it's running.
>> That sounds remarkably hard to get right...
>
> No harder than compiling it in the first place while it's running. Why
> is it harder to re-JIT than to JIT?
Because you have to make sure it actually happens, and uses up-to-date
information. It looks remarkably easy for this step to get missed under
sufficiently unusual conditions.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> So what do you think Haskell solves inelegantly?
>
> Does it do hierarchies of types (like windows) nicely, where you don't
> have to go back and fix every use of an object when you add another one
> to the hierarchy?
Yeah, you can do this.
> Does it interface well to low-level stuff without having to write wrappers?
Does /any/ high-level language do this?
Haskell lets you talk to low-level stuff fairly easily. It's not
trivial, but it's reasonably painless. (Depending on the complexity of
the thing you're trying to access.)
> Does it handle threads running on various address spaces (i.e.,
> distributed processing) well?
The language itself does not include this feature. You would have to use
some kind of library.
> How is it on the code generation part? Can you write programs that emit
> code that it then loads back in?
None of the extant implementations let you do this.
[Or rather, GHC is /supposed/ to support this, but I couldn't actually
get it to work.]
> Can you write programs that notice your
> SQL schema has changed and modifies the running program to account for
> that?
Since it's not possible to receive notifications for schema changes in
the first place, I don't see how this is feasible.
> Can you compile and distribute Haskell code, let other people use it,
> and then release new object code that is compatible with the existing
> code people already wrote and compiled without breaking things?
No.
Haskell is usually distributed in source form. Partly that's because the
community is small, and nobody has the resources to compile their code
for every target platform. Partly it's because most Haskell code is
open-source anyway. But partly it's because the extant Haskell
implementations have very poor object code compatibility.
> How elegantly does it interface to dynamic languages like javascript?
What do you mean by "interface"?
> How elegantly does it handle the types in SQL tables? Stuff like
> nullable big decimals? Strings in various locales?
Depends on which SQL library you use.
> How easy is it to parse and compile, such that you could do so on a
> keystroke by keystroke basis? When you make a mistake, is it easy for
> the compiler to pinpoint where you made the mistake? Is it easy for the
> IDE to know when it's safe to recompile the code or whether you're still
> typing?
The Leksah IDE compiles as you type, and highlights compilation errors
in near-realtime. (Like, there's a delay of a couple of seconds.)
Haskell's type inference can make pinpointing the actual error location
kinds tricky; you can counter this by adding more explicit type
signatures to your code. (This is arguably good practise anyway.)
More to the point, most of the questions above aren't about the language
itself, they're about all the supporting infrastructure that goes with a
language to make it useful. While these are obviously important things,
they aren't part of the core language.
For example, GHC has laughable binary compatibility. Every minor
point-release of the compiler generates incompatible object code. This
has nothing to do with language design, however. It's entirely possible
that some day somebody will write a rival compiler which has excellent
binary compatibility. The language itself does not make this impossible
or even difficult. It's just that with everybody distributing code in
source form, there's no real incentive for people to work towards this goal.
Similar remarks go for most of your points. There are languages like
Erlang where support for distributed processing is built-in. Haskell is
not such a language. On the other hand, we already have a library for
shared-memory synchronisation and communication between threads; it's
not inconceivable that some day somebody will extend it to work across
node boundaries. But whether this happens or not is not a property of
the language. The fact that the language is powerful enough for this to
support this is a property of the language.
In summary: If you're saying that C# has better tools and better
libraries for doing real-world stuff, then I have no argument. If you're
saying that the C# language design is superior, then I must disagree.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New <dne### [at] san rr com> wrote:
> I might have asked this before, but do you have any good (hopefully generic)
> examples of where MI really helps out?
It's not commonplace for sure, but I have had actual situations where
multiple inheritance has been useful (and also at least one situation
where multiple inheritance would have been useful but was not available
because the language, in this case Objective-C, didn't support it).
Coincidentally (or perhaps not) all the cases I remember have been related
to GUI programming.
These have been cases where I have had an object which should act as a
screen element (whatever the basic element may be called in a particular
GUI library) and also as another class, neither of which could have been
just an interface (because both base classes contained functionality of
their own).
(In the Objective-C case I had to get around the limitation by using
preprocessor macros which could be used to add the required member
variables and functions in all the classes that needed them. It was quite
ugly.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New <dne### [at] san rr com> wrote:
> > Even if it does, then the language could implicitly do with it what C++'s
> > virtual inheritance does. You can still forbid all other types of diamond
> > inheritance if you so wish.
> You could, but then it's getting weird.
What would be weird about it?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 16.08.2012 13:13, schrieb Invisible:
> More to the point, most of the questions above aren't about the language
> itself, they're about all the supporting infrastructure that goes with a
> language to make it useful. While these are obviously important things,
> they aren't part of the core language.
YES, EXACTLY! So much for the "solution to everything".
> In summary: If you're saying that C# has better tools and better
> libraries for doing real-world stuff, then I have no argument. If you're
> saying that the C# language design is superior, then I must disagree.
The point is, if it's the right tool for the right job, its design /is/
superior (for this job).
Design superiority isn't in elegant simplicity, but in how actually
useful it is - for a given purpose.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 16/08/2012 12:56 AM, Darren New wrote:
> On 8/15/2012 4:08, Invisible wrote:
>> I guess I'm used to using a programming language where a Char is...
>> well...
>> any valid Unicode code-point,
>
> You mean, you only use languages invented after Unicode had more than
> 65536 code points defined.
And when was that? About 10 years ago? :-P
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 16.08.2012 10:38, schrieb Invisible:
> I doubt Eiffel has half as many libraries as C# though. Like most
> well-designed languages, it never really took off.
I'd dare say, "like most (if not all) languages with well-intended
simple and elegant design" - and that it's /because/ of this design that
they never really took off. Because its simplicity limits its usefulness
for particular use cases, and the elegancy (of the whole smash) goes
down the drain once you add extensions (including, but not limited to,
libraries) to make it useful.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 16/08/2012 05:16 PM, clipka wrote:
> Am 16.08.2012 10:38, schrieb Invisible:
>
>> I doubt Eiffel has half as many libraries as C# though. Like most
>> well-designed languages, it never really took off.
>
> I'd dare say, "like most (if not all) languages with well-intended
> simple and elegant design" - and that it's /because/ of this design that
> they never really took off. Because its simplicity limits its usefulness
> for particular use cases, and the elegancy (of the whole smash) goes
> down the drain once you add extensions (including, but not limited to,
> libraries) to make it useful.
You keep saying this, and you keep being wrong. However, it is clear to
me that nothing I say is going to convince you otherwise, so there we are.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 16.08.2012 18:16, schrieb Orchid Win7 v1:
>> You mean, you only use languages invented after Unicode had more than
>> 65536 code points defined.
>
> And when was that? About 10 years ago? :-P
Sounds like a good estimate. Even a bit more, I'd guess.
Now that we have this sorted out, when was the last time someone
invented a language that's well-known today?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 16/08/2012 05:27 PM, clipka wrote:
> Am 16.08.2012 18:16, schrieb Orchid Win7 v1:
>
>>> You mean, you only use languages invented after Unicode had more than
>>> 65536 code points defined.
>>
>> And when was that? About 10 years ago? :-P
>
> Sounds like a good estimate. Even a bit more, I'd guess.
>
> Now that we have this sorted out, when was the last time someone
> invented a language that's well-known today?
Well, the entire .NET platform is somewhat newer than 10 years, so
presumably C# is about the same age.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 16.08.2012 18:38, schrieb Orchid Win7 v1:
> On 16/08/2012 05:27 PM, clipka wrote:
>> Am 16.08.2012 18:16, schrieb Orchid Win7 v1:
>>
>>>> You mean, you only use languages invented after Unicode had more than
>>>> 65536 code points defined.
>>>
>>> And when was that? About 10 years ago? :-P
>>
>> Sounds like a good estimate. Even a bit more, I'd guess.
>>
>> Now that we have this sorted out, when was the last time someone
>> invented a language that's well-known today?
>
> Well, the entire .NET platform is somewhat newer than 10 years, so
> presumably C# is about the same age.
While the .NET platform was indeed initially released in 2002, the
project had been officially announced as early as July 2000, so it is
safe to assume that work on it had started somewhat before 2000.
As for C#, according to Wikipedia it "Appeared in 2001", and development
had started as early as January 1999.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 4:13, Invisible wrote:
> Does /any/ high-level language do this?
Depends what you mean by "high level", but yes. Ada, C#, FORTH, a few others
here and there.
>> Does it handle threads running on various address spaces (i.e.,
>> distributed processing) well?
>
> The language itself does not include this feature. You would have to use
> some kind of library.
I guess being functional has some advantages here.
>> Can you write programs that notice your
>> SQL schema has changed and modifies the running program to account for
>> that?
>
> Since it's not possible to receive notifications for schema changes in the
> first place, I don't see how this is feasible.
You are allowed to poll. ;-)
>> Can you compile and distribute Haskell code, let other people use it,
>> and then release new object code that is compatible with the existing
>> code people already wrote and compiled without breaking things?
>
> No.
See, that's exactly the target market for C#. Or rather for .NET. C# is a
component-oriented language that happens to be OO. F# is a
component-oriented language that happens to be (somewhat) functional. Etc.
> Haskell is usually distributed in source form. Partly that's because the
> community is small, and nobody has the resources to compile their code for
> every target platform. Partly it's because most Haskell code is open-source
> anyway. But partly it's because the extant Haskell implementations have very
> poor object code compatibility.
And that's the sort of thing I'm talking about. :-)
>> How elegantly does it interface to dynamic languages like javascript?
>
> What do you mean by "interface"?
Can you invoke a javascript library as if it were written in Haskell? I.e.,
is it as easy to invoke something like javascript as it is to invoke
something like C?
> The Leksah IDE compiles as you type, and highlights compilation errors in
> near-realtime. (Like, there's a delay of a couple of seconds.)
Not bad.
> More to the point, most of the questions above aren't about the language
> itself, they're about all the supporting infrastructure that goes with a
> language to make it useful. While these are obviously important things, they
> aren't part of the core language.
Well, if your language can't handle dynamic loading or can't handle
object-code distribution, then these are inherent in the language. I.e., if
type inference is such that you have to do whole-program compilation for it
to work, then you can't link in new code at runtime.
> In summary: If you're saying that C# has better tools and better libraries
> for doing real-world stuff, then I have no argument. If you're saying that
> the C# language design is superior, then I must disagree.
Not superior. Superior at various tasks.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 4:13, Invisible wrote:
> Similar remarks go for most of your points. There are languages like Erlang
> where support for distributed processing is built-in. Haskell is not such a
> language. On the other hand, we already have a library for shared-memory
> synchronisation and communication between threads; it's not inconceivable
> that some day somebody will extend it to work across node boundaries.
But that's not all it takes to make it do what Erlang does. Erlang isn't
just "distributed processing." It's "reliable processing." Which means you
need to be able to (for example) start a new version of the code running
while not actually throwing away the stack of call frames that got you
there. You have to be able to have A call B call C call D, and have D say
"Oh, by the way, next time C returns, B should be calling the new version of
C, but only in those threads where C has actually returned. Oh, and don't
screw up B's local variables." That's the sort of thing that's really,
really hard to do in a library, unless you're running something like FORTH
that actually has access to the executing code.
How would you write a Haskell library that says "once each call to X
returns, replace that thread's version of X with new executable code,
without otherwise disturbing the thread that's running there"?
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 1:27, Invisible wrote:
> You're probably write. (Depending on how you want to argue about the
> semantics.) My point was just that "oh, it's /obviously/ impossible" isn't
> actually so obvious.
It obviously *is* impossible, if your definition of "type" is "collection of
values and the operators that transform them into other values."
If you return a private stack, it's not a stack unless I can call push and
pop on it. It's some other type that's just wrapping up a stack until you
unwrap it again.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 1:38, Invisible wrote:
> It still works if you take Show out. (Although in that case it becomes even
> more pointless.)
As it does in C#. You return Object.
> My point isn't that this is a useful thing to do. It's just that it doesn't
> necessarily /have/ to be impossible. C# /chose/ to make it impossible - a
> not unreasonable choice, but not the /only/ choice.
You're just arguing syntax at this point. If I return a value and there's
nothing you can do with that value that you can't do with every other value
of every other type, then you've returned Object. You haven't returned a
value of a private type - you've cast it to a value that has no operations
defined except assignment.
> According to the spec document, any value of a value type is not formally
> referred to as an "object"; that term is reserved for values of reference
> type. Similarly, the term "class" is reserved to refer to types declared
> with the "class" keyword.
Not you're picking nits.
> Of course, with the C# unified type system, all types /behave/ as classes in
> the usual OO sense (which is the point you're making). It's just that the C#
> language spec does not /call/ then classes.
Are they all subclasses of Object? How can you have a subclass of Object
that isn't in turn an object? :-)
>> They correspond to integers. They aren't integers. I *do* think Java did
>> that one much better.
>
> What, by not having enumerations at all?
No. Java has actual useful enums, which are basically classes with a finite
collection of named static instances created at compile-time.
>>> If you have real enumerations, why do you need a special-case for bool?
>>
>> Because you have syntax in the language that uses specific types, like
>> "if" statements.
>
> Haskell has special if syntax, and yet Bool is defined in library code.
So? bool is defined in library code too. System.Boolean in mscorlib.dll
>> Hermes, for example, does not have a string type. But if you have an
>> enum where each name is one character long, you can make an array of
>> that value by sticking it inside quotes. Which I thought was kind of cute.
>
> Nice. :-S
And then there's ACT.1, where a number like 534 is actually a big long
expression that is ((5 * 10 + 3) * 10) + 4. I.e., similarly to the way
Hermes does strings, ACT.1 does every literal including integers and floats.
"Int" is actually a source code library.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/15/2012 17:13, clipka wrote:
> You're presuming here that GUI item superclasses keep growing new functions.
> That's not a necessary prerequisite for a GUI library though.
No. It's just that *that* is one of the use cases that OO was intended to
solve. Of course if you're sure you're never going to have new superclass
methods, or that you're willing to update every subclass every time you add
one to the superclass, then you don't need inheritance. But having that
break between superclass and subclass, and between sibling subclasses (so
you can add a new subclass without changing every reference to a superclass
method to include a new case for that new subclass) is exactly the point of
dynamic dispatch.
>> I don't know of any language that implements inheritance and interfaces
>> that doesn't allow interfaces to inherit. Quite honestly, that would
>> make almost no sense.
>
> I totally agree that it's a good choice to not design a language that way.
> But still, even with such a language you /could/ write a GUI library.
I can write a GUI library in assembler. Or in C, faking OO. Or in C, not
faking OO. That doesn't mean it's easy.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 7:33, Warp wrote:
> These have been cases where I have had an object which should act as a
> screen element (whatever the basic element may be called in a particular
> GUI library) and also as another class, neither of which could have been
> just an interface (because both base classes contained functionality of
> their own).
Yeah, OK, fair enough. I can see that. It's sort of what the MVC pattern is
designed to get around, in a way.
Just as an amusement, I've found a very funky failure of inheritance at work.
We have a system that contains what we'll call documents. The business logic
loads a bunch of documents, and then the UI has a bunch of subclasses of
document that format the documents appropriately. (And the business document
instantiates the appropriate subclass by looking at flags in the data and
using factories and such.) All well and good. You have documents, and you
have SpreadhseetDocuments, PdfDocuments, VideoDocuments, TextDocuments,
etc., all of which make calls to the superclass to get the parameters and
then display the content appropriately.
Now we're doing a mechanism to let you edit documents, so we'll have
DraftDocuments. But we want SpreadsheetDocuments, VideoDocuments, etc to use
the data in the draft documents (which is stored in other tables, in funky
formats appropriate for editing, etc) for previews. But I can't instantiate
a VideoDocument with either a (final) Document or DraftDocument as the
superclass as appropriate, because it's Java. So I have to figure out a way
around that somehow.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 3:14, Invisible wrote:
> According to Wikipedia, Mono /also/ does JIT compilation to native code.
> (Although I agree it would be better if there were published benchmark
> results for .NET itself.)
You almost have to. But the GC and the JIT for Mono both suck compared to
the ones optimized by MS.
> Because you have to make sure it actually happens, and uses up-to-date
> information. It looks remarkably easy for this step to get missed under
> sufficiently unusual conditions.
At worst, every time you load new code, you throw away all the compiled code.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/16/2012 7:34, Warp wrote:
> Darren New<dne### [at] san rr com> wrote:
>>> Even if it does, then the language could implicitly do with it what C++'s
>>> virtual inheritance does. You can still forbid all other types of diamond
>>> inheritance if you so wish.
>
>> You could, but then it's getting weird.
>
> What would be weird about it?
What about diamond inheritance from Number or Enum or something like that?
There would be a bunch of cases where you could reasonably expect diamond
inheritance to work, or where there's one class under Object which is
nothing but some extra routines you want all *your* classes to inherit.
I.e., it's a very ad hoc rule that tells the programmer that the language
designer didn't know how to solve the problem but recognized it needed
solving. :-)
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 18/08/2012 05:34 AM, Darren New wrote:
> On 8/16/2012 3:14, Invisible wrote:
>> According to Wikipedia, Mono /also/ does JIT compilation to native code.
>> (Although I agree it would be better if there were published benchmark
>> results for .NET itself.)
>
> You almost have to. But the GC and the JIT for Mono both suck compared
> to the ones optimized by MS.
You have an actual citation for that?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 18/08/2012 05:10 AM, Darren New wrote:
> On 8/16/2012 4:13, Invisible wrote:
>> Does /any/ high-level language do this?
>
> Depends what you mean by "high level", but yes. Ada, C#, FORTH, a few
> others here and there.
I very much doubt that C# lets you trivially call arbitrary machine code.
>>> Can you write programs that notice your
>>> SQL schema has changed and modifies the running program to account for
>>> that?
>>
>> Since it's not possible to receive notifications for schema changes in
>> the first place, I don't see how this is feasible.
>
> You are allowed to poll. ;-)
In that case, yeah, it ought to be possible to build something that does
this. Nobody has, but somebody could.
>> Haskell is usually distributed in source form. Partly that's because the
>> community is small, and nobody has the resources to compile their code
>> for
>> every target platform. Partly it's because most Haskell code is
>> open-source
>> anyway. But partly it's because the extant Haskell implementations
>> have very
>> poor object code compatibility.
>
> And that's the sort of thing I'm talking about. :-)
And, as I wrote in the part you snipped, this is a property of the one
extant Haskell compiler. It's not necessarily intrinsic to the language
itself. Somebody could write a compiler that /does/ have good object
code compatibility. It's just that to date, it hasn't been a priority.
There's nothing about the /language design/ that makes this impossible.
On the other hand, if you're coding in BASIC, with line numbers and all,
then this pretty much /is/ impossible. Because BASIC is a very, very bad
language.
>>> How elegantly does it interface to dynamic languages like javascript?
>>
>> What do you mean by "interface"?
>
> Can you invoke a javascript library as if it were written in Haskell?
> I.e., is it as easy to invoke something like javascript as it is to
> invoke something like C?
Don't you need a web browser to run JavaScript code?
Regardless, invoking JS is, in principle, similar to invoking any other
foreign language. Once you work out how to call it, you'd need to write
at least some trivial wrappers to get it to work, and after that it's
pretty easy.
>> More to the point, most of the questions above aren't about the language
>> itself, they're about all the supporting infrastructure that goes with a
>> language to make it useful. While these are obviously important
>> things, they
>> aren't part of the core language.
>
> Well, if your language can't handle dynamic loading or can't handle
> object-code distribution, then these are inherent in the language. I.e.,
> if type inference is such that you have to do whole-program compilation
> for it to work, then you can't link in new code at runtime.
No.
If the /design/ of the language makes dynamic loading impossible, then
that's a language limitation. If the current /implementation/ of the
language does not support dynamic loading, then that's just an
implementation limitation.
And that's what I'm saying. Most of the stuff you can't do with Haskell
right now isn't because of poor language design. It's just that nobody
has built the tools or libraries required to do it. Some day these
things /could/ become possible, without changing the language.
> Not superior. Superior at various tasks.
From what I can see, C# is superior at migrating C++ code and letting
it integrate with old VB code...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 18/08/2012 05:14 AM, Darren New wrote:
> On 8/16/2012 4:13, Invisible wrote:
>> Similar remarks go for most of your points. There are languages like
>> Erlang
>> where support for distributed processing is built-in. Haskell is not
>> such a
>> language.
> But that's not all it takes to make it do what Erlang does. Erlang isn't
> just "distributed processing." It's "reliable processing." Which means
> you need to be able to (for example) start a new version of the code
> running while not actually throwing away the stack of call frames that
> got you there
> How would you write a Haskell library that says "once each call to X
> returns, replace that thread's version of X with new executable code,
> without otherwise disturbing the thread that's running there"?
You wouldn't be able to do this for arbitrary code. But if you insert a
suitable layer of indirection, it wouldn't be too hard. Haskell supports
first-class functions, after all. You can do crazy things with stuff
like continuation-passing and so on.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/18/2012 3:14, Orchid Win7 v1 wrote:
> I very much doubt that C# lets you trivially call arbitrary machine code.
You would be mistaken. It's no harder in C# to call COM or C code than it is
to do so from C++. Machine code? Well, you have to know the calling
convention, but sure, you can do that.
> In that case, yeah, it ought to be possible to build something that does
> this. Nobody has, but somebody could.
OK, so Haskell supports dynamic loading of code including declaring new
types? Funky.
> And, as I wrote in the part you snipped, this is a property of the one
> extant Haskell compiler. It's not necessarily intrinsic to the language
> itself. Somebody could write a compiler that /does/ have good object code
> compatibility. It's just that to date, it hasn't been a priority. There's
> nothing about the /language design/ that makes this impossible.
Sure. But some systems are designed to make this easy, and some aren't. For
example, it's a lot harder to write a C# compiler that does *not* have good
object code compatibility.
Of course any language can manage pretty much any function with enough
effort. Even BASIC can have good object-code compatibility if you work hard
enough at it. (I think they call it VB.NET, ;-) The question is how much
effort does it take, and how much does it look like part of the language
when you're done.
>>>> How elegantly does it interface to dynamic languages like javascript?
>>>
>>> What do you mean by "interface"?
>>
>> Can you invoke a javascript library as if it were written in Haskell?
>> I.e., is it as easy to invoke something like javascript as it is to
>> invoke something like C?
>
> Don't you need a web browser to run JavaScript code?
Why would you need a web browser?
> Regardless, invoking JS is, in principle, similar to invoking any other
> foreign language. Once you work out how to call it, you'd need to write at
> least some trivial wrappers to get it to work, and after that it's pretty easy.
Except that JS is dynamically-typed. So you can't write a wrapper to a JS
function. Plus, of *course* you *can* manage it. It's turing complete and
runs on the same machine. The point is whether it's easy to take a lazy
functional declarative language and conveniently invoke a stateful
dynamically-typed collection of functions and objects. I can't even imagine
how you'd write a wrapper for something like that, in terms of declaring it
and invoking it. I.e., I don't even know how you'd be able to write a
Haskell declaration of a javascript object, even assuming such library was
already written.
> And that's what I'm saying. Most of the stuff you can't do with Haskell
> right now isn't because of poor language design. It's just that nobody has
> built the tools or libraries required to do it. Some day these things
> /could/ become possible, without changing the language.
OK. It wasn't obvious to me that the design of the language was such that
you could have the things I was talking about.
>> Not superior. Superior at various tasks.
>
> From what I can see, C# is superior at migrating C++ code and letting it
> integrate with old VB code...
You barely even know how it works, and you've not written any significant
programs in it, so you're judging from a position of ignorance. :-)
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/18/2012 3:17, Orchid Win7 v1 wrote:
> You wouldn't be able to do this for arbitrary code.
And that's what I'm talking about. If you want your program to run 15 years
without ever stopping, you pretty much need to be able to replace arbitrary
bits of code, including type signatures, while you're running.
> But if you insert a
> suitable layer of indirection, it wouldn't be too hard. Haskell supports
> first-class functions, after all. You can do crazy things with stuff like
> continuation-passing and so on.
Sure, and Erlang translates into machine code instructions at some point. Or
hell, implement an Erlang interpreter in Haskell. This isn't an argument. :-)
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/18/2012 3:03, Orchid Win7 v1 wrote:
> On 18/08/2012 05:34 AM, Darren New wrote:
>> On 8/16/2012 3:14, Invisible wrote:
>>> According to Wikipedia, Mono /also/ does JIT compilation to native code.
>>> (Although I agree it would be better if there were published benchmark
>>> results for .NET itself.)
>>
>> You almost have to. But the GC and the JIT for Mono both suck compared
>> to the ones optimized by MS.
>
> You have an actual citation for that?
First google hit on "mono gc sucks"
http://phoronix.com/forums/showthread.php?26300-Mono-2-8-Is-Out-With-C-4-0-Better-Performance/page15
Later versions of Mono are much better than the first few generations, which
sucked so bad they realized they actually needed to fix it to be even usable
let alone competitive.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> You wouldn't be able to do this for arbitrary code.
>
> And that's what I'm talking about. If you want your program to run 15
> years without ever stopping, you pretty much need to be able to replace
> arbitrary bits of code, including type signatures, while you're running.
And if this was a problem for your application, you would write it in
such a way as to facilitate doing this.
Yes, it would be cooler if you could do it for /arbitrary/ code, but
with extant implementations, you'd have to do the next best thing.
(And, again, if somebody wanted this, you could probably come up with a
Haskell implementation that supports it natively. It's just that nobody
has. It would take some design work, but I think you could do it without
changing the language itself.)
>> But if you insert a
>> suitable layer of indirection, it wouldn't be too hard. Haskell supports
>> first-class functions, after all. You can do crazy things with stuff like
>> continuation-passing and so on.
>
> Sure, and Erlang translates into machine code instructions at some
> point. Or hell, implement an Erlang interpreter in Haskell. This isn't
> an argument. :-)
Implementing an Erlang interpreter in BBC BASIC would be hellishly
difficult. Doing it in Haskell wouldn't be all that hard. That's the
difference.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 18/08/2012 06:43 PM, Darren New wrote:
> On 8/18/2012 3:14, Orchid Win7 v1 wrote:
>> I very much doubt that C# lets you trivially call arbitrary machine code.
>
> You would be mistaken. It's no harder in C# to call COM or C code than
> it is to do so from C++. Machine code? Well, you have to know the
> calling convention, but sure, you can do that.
It's no harder to call C than to call Haskell, once you define where the
hell the function is and what arguments it's expecting. Your point?
>> In that case, yeah, it ought to be possible to build something that does
>> this. Nobody has, but somebody could.
>
> OK, so Haskell supports dynamic loading of code including declaring new
> types? Funky.
It's commonplace to write Haskell code which doesn't know exactly what
data types it's dealing with. Dynamically loading new types that didn't
exist at compile-time isn't really a problem, in principle. The only
real problem is that the current language implementation doesn't support
this well.
>> There's nothing about the /language design/ that makes this impossible.
>
> Sure. But some systems are designed to make this easy, and some aren't.
Fair enough.
> Of course any language can manage pretty much any function with enough
> effort. Even BASIC can have good object-code compatibility if you work
> hard enough at it. (I think they call it VB.NET, ;-)
VB isn't BASIC. VB is a language with a very slight resemblance to
BASIC, which has "basic" in its name. Really, it's an utterly separate
language.
And that's the point - any language can be made to support anything if
you TOTALLY CHANGE THE LANGUAGE. The question is whether you can do X, Y
or Z /without/ drastically changing the language.
> The question is how
> much effort does it take, and how much does it look like part of the
> language when you're done.
OK.
>> Don't you need a web browser to run JavaScript code?
>
> Why would you need a web browser?
JavaScript is a language invented for controlling web browsers. I don't
know of anything else that runs it.
> Except that JS is dynamically-typed.
And Haskell can't manage dynamically-typed code.
Oh, wait. Yes it can.
> The point is whether it's easy to take a
> lazy functional declarative language and conveniently invoke a stateful
> dynamically-typed collection of functions and objects. I can't even
> imagine how you'd write a wrapper for something like that, in terms of
> declaring it and invoking it.
"I can't imagine how this would be possible" isn't the same as "this is
not possible", as everyone is so fond of reminding me.
>> From what I can see, C# is superior at migrating C++ code and letting it
>> integrate with old VB code...
>
> You barely even know how it works, and you've not written any
> significant programs in it, so you're judging from a position of
> ignorance. :-)
I said that the design is overly complicated and cluttered. That it
lacked simplicity and elegance. Why would I need an encyclopaedic
knowledge of the language to say that?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/19/2012 3:26, Orchid Win7 v1 wrote:
> On 18/08/2012 06:43 PM, Darren New wrote:
>> On 8/18/2012 3:14, Orchid Win7 v1 wrote:
>>> I very much doubt that C# lets you trivially call arbitrary machine code.
>>
>> You would be mistaken. It's no harder in C# to call COM or C code than
>> it is to do so from C++. Machine code? Well, you have to know the
>> calling convention, but sure, you can do that.
>
> It's no harder to call C than to call Haskell, once you define where the
> hell the function is and what arguments it's expecting. Your point?
I'm not following. You said C# doesn't let you call machine code. I said it did.
And if Haskell tends to use things like lists extensively, or options, or
something like that, then yeah, it can be hard to pass such things across
computation boundaries, let alone lazy expressions. And of course if the C
isn't actually a function in the functional sense, I'm not sure how Haskell
handles it. For example, it's really not obvious how easy it would be to
invoke a C function that takes as one of its arguments a pointer to a function.
Note I'm not bashing Haskell. I'm simply pointing out the assertion that
Haskell does everything as well as every other language doesn't sound right
to me.
> It's commonplace to write Haskell code which doesn't know exactly what data
> types it's dealing with. Dynamically loading new types that didn't exist at
> compile-time isn't really a problem, in principle. The only real problem is
> that the current language implementation doesn't support this well.
OK, cool.
> VB isn't BASIC. VB is a language with a very slight resemblance to BASIC,
> which has "basic" in its name. Really, it's an utterly separate language.
Well, it's not Dartmouth basic, no. :-) But I was mainly kidding there.
>>> Don't you need a web browser to run JavaScript code?
>>
>> Why would you need a web browser?
>
> JavaScript is a language invented for controlling web browsers. I don't know
> of anything else that runs it.
There are lots of other applications that have incorporated javascript. For
example, MongoDB interprets javascript to decide how to do queries and build
indexes.
http://en.wikipedia.org/wiki/Comparison_of_server-side_JavaScript_solutions
And have you not heard of node.js?
>> Except that JS is dynamically-typed.
> And Haskell can't manage dynamically-typed code.
> Oh, wait. Yes it can.
OK. Again, I didn't know that. I thought Haskell is statically typed.
>> The point is whether it's easy to take a
>> lazy functional declarative language and conveniently invoke a stateful
>> dynamically-typed collection of functions and objects. I can't even
>> imagine how you'd write a wrapper for something like that, in terms of
>> declaring it and invoking it.
>
> "I can't imagine how this would be possible" isn't the same as "this is not
> possible", as everyone is so fond of reminding me.
I didn't say it's impossible. I said I can't imagine it. :-)
So how do you do it?
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/19/2012 3:13, Orchid Win7 v1 wrote:
>>> You wouldn't be able to do this for arbitrary code.
>>
>> And that's what I'm talking about. If you want your program to run 15
>> years without ever stopping, you pretty much need to be able to replace
>> arbitrary bits of code, including type signatures, while you're running.
>
> And if this was a problem for your application, you would write it in such a
> way as to facilitate doing this.
Except it's exponentially harder if your language doesn't support it.
For example, there's STM for C#. But it's tremendously harder to make it
work, because C# supports arbitrary mutations of variable values. You
*could* make it work, with enough strictures, but it's not worth it.
> (And, again, if somebody wanted this, you could probably come up with a
> Haskell implementation that supports it natively. It's just that nobody has.
> It would take some design work, but I think you could do it without changing
> the language itself.)
See STM on C#.
> Implementing an Erlang interpreter in BBC BASIC would be hellishly
> difficult. Doing it in Haskell wouldn't be all that hard. That's the
> difference.
We're not comparing Haskell to BBC BASIC. The point I'm making is that many
of the decisions in Erlang were made to support this sort of long-running
self-healing software. Yes, you could do the same thing in Haskell, but then
it would look like Erlang. I could do the same thing in C# by writing an
Erlang interpreter in C# and linking in a bunch of C code for the stuff that
C# can't do natively (like reboot the machine it's running on). But that's
not comparing language strengths. That's just asserting they're turing complete.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 19/08/2012 05:08 PM, Darren New wrote:
> On 8/19/2012 3:13, Orchid Win7 v1 wrote:
>>>> You wouldn't be able to do this for arbitrary code.
>>>
>>> And that's what I'm talking about. If you want your program to run 15
>>> years without ever stopping, you pretty much need to be able to replace
>>> arbitrary bits of code, including type signatures, while you're running.
>>
>> And if this was a problem for your application, you would write it in
>> such a way as to facilitate doing this.
>
> Except it's exponentially harder if your language doesn't support it.
No, it isn't.
It's exponentially harder IF YOUR LANGUAGE SUCKS. If you have a powerful
language, then adding new things is quite easy.
> For example, there's STM for C#. But it's tremendously harder to make it
> work, because C# supports arbitrary mutations of variable values. You
> *could* make it work, with enough strictures, but it's not worth it.
Well, no, that should be quite easy: You have a rule that inside a
transaction, you don't try to do anything observable to the outside
world. If you do, it won't work, and it will be your fault. Problem solved.
The trouble is, they tried to make it so that any arbitrary code can be
run in a transaction. That's impossible. Which is why it didn't work.
You might say "but almost all C# code would be disqualified!" But
remember, the purpose of a transaction is /only/ to coordinate threads.
You don't run the entire application inside STM, just the tiny bits
related to synchronisation.
> The point I'm making is that
> many of the decisions in Erlang were made to support this sort of
> long-running self-healing software. Yes, you could do the same thing in
> Haskell, but then it would look like Erlang.
Would it, now?
Adding features for distributed concurrency and hot code replacement
would make Haskell have crap syntax and weak typing?
No, I didn't think so. :-P
You're aware of the prior art on this subject, I assume? You know about
the project where they managed to actually implement typed message
sending and remote code execution? Transparently? Without altering the
Haskell language at all, just the compiler?
Sure, it didn't do /everything/ that Erlang does. It was only a
prototype. But it refutes the whole "it would make Haskell identical to
Erlang" argument.
> I could do the same thing
> in C# by writing an Erlang interpreter in C# and linking in a bunch of C
> code for the stuff that C# can't do natively (like reboot the machine
> it's running on). But that's not comparing language strengths. That's
> just asserting they're turing complete.
Being able to implement something is one thing. Being able to implement
it /easily/ is another. And that's the goal of designing a good
language: to make stuff easy.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>>> I very much doubt that C# lets you trivially call arbitrary machine
>>>> code.
>>>
>>> You would be mistaken. It's no harder in C# to call COM or C code than
>>> it is to do so from C++. Machine code? Well, you have to know the
>>> calling convention, but sure, you can do that.
>>
>> It's no harder to call C than to call Haskell, once you define where the
>> hell the function is and what arguments it's expecting. Your point?
>
> I'm not following. You said C# doesn't let you call machine code. I said
> it did.
No.
You said C# lets you call arbitrary machine code as easily as calling
another C# function. I said it doesn't.
> And if Haskell tends to use things like lists extensively, or options,
> or something like that, then yeah, it can be hard to pass such things
> across computation boundaries, let alone lazy expressions.
You cannot pass arbitrary Haskell expressions to C. You can only pass
primitive data types that C understands. (Things like int or long or
void*.) If C needs to access Haskell stuff, you write Haskell functions
that inspect the Haskell stuff and return something that C understands,
and then have C call that.
> And of course
> if the C isn't actually a function in the functional sense, I'm not sure
> how Haskell handles it.
If the code you're trying to call has no observable side effects (e.g.,
sinh() or something) then you mark it as a pure function. If it /does/
have observable side-effects, then you mark it as an I/O action, and
handle it the same way as any other I/O action. Really, it's not hard.
> For example, it's really not obvious how easy it
> would be to invoke a C function that takes as one of its arguments a
> pointer to a function.
Do you remember that time I used the C sort() function to work a Haskell
data structure? Do you remember how I don't even know all that much
about C, and yet it only took me about 20 minutes to figure it out?
Seriously, it's not "trivial". But it's pretty damned simple.
> Note I'm not bashing Haskell. I'm simply pointing out the assertion that
> Haskell does everything as well as every other language doesn't sound
> right to me.
And, as I keep pointing out, that isn't what I said. I said the core
language design is simple and clean. I didn't say it has a library for
every possible task. However, the language design itself doesn't rule
out any particularly large possibilities, as far as I can tell.
>> JavaScript is a language invented for controlling web browsers. I
>> don't know of anything else that runs it.
>
> There are lots of other applications that have incorporated javascript.
Really?
> For example, MongoDB interprets javascript to decide how to do queries
> and build indexes.
>
> And have you not heard of node.js?
I've /heard of/ node.js; I have no idea what it /is/ though.
>>> Except that JS is dynamically-typed.
>> And Haskell can't manage dynamically-typed code.
>> Oh, wait. Yes it can.
>
> OK. Again, I didn't know that. I thought Haskell is statically typed.
Haskell is statically typed. But there's a library for doing stuff with
dynamic types. Basically, it lets you convert any suitable value to a
special "Dynamic" type. You can then later try to cast it back to
something else, which succeeds iff that is actually the correct type.
You know, the usual deal.
At worst, if you wanted to talk to something dynamic, you could just
mark every single thing it touches is "type unknown" until you try to do
something with it. It isn't that hard.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 20.08.2012 10:31, schrieb Invisible:
> And, as I keep pointing out, that isn't what I said. I said the core
> language design is simple and clean.
The thing is that this is NOT what you said (or rather, what you
implied). Your claim was (or appeared to be) that Haskell is simple and
elegant AND a "solution for everything".
We keep disputing the latter, while you keep insisting on the former
(which we're not disputing in any way).
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> And, as I keep pointing out, that isn't what I said. I said the core
>> language design is simple and clean.
>
> The thing is that this is NOT what you said (or rather, what you
> implied). Your claim was (or appeared to be) that Haskell is simple and
> elegant AND a "solution for everything".
>
> We keep disputing the latter, while you keep insisting on the former
> (which we're not disputing in any way).
It seems the confusion here is "solution for everything".
It seems you guys think that I meant "every possible computing task that
can ever exist". Obviously Haskell does /not/ solve every such problem.
Indeed, it doesn't solve /most/ of them, due to the much-discussed
extreme lack of libraries. Want to load a JPEG image? Good luck with
that. I could come up with dozens of other examples off the top of my head.
What I meant was to contrast Haskell against C# and languages like it.
With most mainstream languages, somebody will be writing a program, and
find that some facet of it is really awkward to structure. Basically,
the language doesn't solve that well. So they invent yet another new
feature to solve that problem - or rather, to solve one particular
instance of it. And then later somebody else invents another, in
compatible, new feature to solve a slightly different instance of it.
And so, after a few decades, we have a feature-encrusted language which
/still/ doesn't solve all the problems.
The "problems" that I was discussing are not "can I interact with legacy
systems?" or "have I got good multimedia support?" or "does my toolchain
support distributed processing well?" Rather, I was talking about
problems such as "can I express the core application logic in a robust,
maintainable, bug-free way?"
Object-oriented programming was supposed to make everything polymorphic
and wonderful. But then they discovered the container problem, so they
invented generics. And then they figured out that sometimes, you want
multiple inheritance. So they invented multiple inheritance, and decided
to not use it and have "interfaces" instead, for no really defined
reason. And then they decided that having eight-billion interfaces like
"Runnable", "ScrollEventListener", "DragEventListener",
"CheckBoxEventListener" and so on was just stupid. So Eiffel invented
"agents", C# invented "delegates", and Java offered the "reflection
API"; all of them different attempts to solve the same language design
problem.
This is the kind of stuff I'm talking about. All these different
languages, all with lots and lots of "features" for trying to solve
stuff. And then there's Haskell, which consists of just 6 constructs in
the entire language, and solves all of it.
[OK, I take that back: Records with named fields is a joke in Haskell.
But the language solves everything /else/ pretty damned well.]
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 20.08.2012 13:02, schrieb Invisible:
> The "problems" that I was discussing are not "can I interact with legacy
> systems?" or "have I got good multimedia support?" or "does my toolchain
> support distributed processing well?" Rather, I was talking about
> problems such as "can I express the core application logic in a robust,
> maintainable, bug-free way?"
And here here we are maintaining that how best to express the core
application logic in a robust, maintainable, bug-free way depends on the
type of problem the application is supposed to solve.
If you are tied to a particular language, then for some problems you
WILL end up with writing libraries, metaprogramming tools and the like,
and you're actually no longer programming in that language - you're only
using it as glue code here and there. (Provided you do aim for that
robust, maintainable, bug-free way of expressing stuff of course.)
> Object-oriented programming was supposed to make everything polymorphic
> and wonderful. But then they discovered the container problem, so they
> invented generics. And then they figured out that sometimes, you want
> multiple inheritance. So they invented multiple inheritance, and decided
> to not use it and have "interfaces" instead, for no really defined
> reason. And then they decided that having eight-billion interfaces like
> "Runnable", "ScrollEventListener", "DragEventListener",
> "CheckBoxEventListener" and so on was just stupid. So Eiffel invented
> "agents", C# invented "delegates", and Java offered the "reflection
> API"; all of them different attempts to solve the same language design
> problem.
I think you're getting the order of events somewhat wrong here.
Anyway - at present it looks like function-oriented programming is
supposed to make everything functional and wonderful now. But what
problems will they discover (if they haven't done so already and you
just haven't heard of it yet)? I betcha there will be quite a few and
then some, just like with every other programming paradigm we've had so
far under the sky.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> And here here we are maintaining that how best to express the core
> application logic in a robust, maintainable, bug-free way depends on the
> type of problem the application is supposed to solve.
OK. But if you have an inflexible language, then you have only one way
to express your solution. And if that isn't a good way for a certain
problem, things get tricky. If you have a powerful and expressive
language with the flexibility to support multiple ways to solve the
problem, it's far more likely you can find one that works well. No?
> If you are tied to a particular language, then for some problems you
> WILL end up with writing libraries, metaprogramming tools and the like,
> and you're actually no longer programming in that language - you're only
> using it as glue code here and there. (Provided you do aim for that
> robust, maintainable, bug-free way of expressing stuff of course.)
And this is bad somehow?
> Anyway - at present it looks like function-oriented programming is
> supposed to make everything functional and wonderful now. But what
> problems will they discover (if they haven't done so already and you
> just haven't heard of it yet)? I betcha there will be quite a few and
> then some, just like with every other programming paradigm we've had so
> far under the sky.
From what I've seen, "every other programming paradigm so far" has been
ad hoc without much in the way of a strong, consistent theoretical basis.
I mean, take SQL. It solves only one problem, but it solves it so damned
well that it is basically the /only/ language of its type. And oh look,
it's based on a theoretical model. Funny coincidence, that...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 20.08.2012 16:34, schrieb Invisible:
>> Anyway - at present it looks like function-oriented programming is
>> supposed to make everything functional and wonderful now. But what
>> problems will they discover (if they haven't done so already and you
>> just haven't heard of it yet)? I betcha there will be quite a few and
>> then some, just like with every other programming paradigm we've had so
>> far under the sky.
>
> From what I've seen, "every other programming paradigm so far" has been
> ad hoc without much in the way of a strong, consistent theoretical basis.
Structured paradigm being ad-hoc? Don't think so. It's the result of
people wrecking their brain about what was wrong with their previous
coding approaches, and revolutionizing the world of software development
with essentially just ONE strong rule.
OO paradigm being ad-hoc? Don't think so either; it only got ad-hoc the
moment it left the realm of scientific studies and entered the realm of
real-world hype.
Finite state paradigm? DEFINITELY has a well-analyzed, theoretical basis.
Actually, I can't think of how a programming paradigm could be ad-hoc
without a consistent theoretical basis; I mean, that's why it is called
a /paradigm/ rather than just coding style or some such.
Maybe you're confusing programming paradigms with programming languages
here.
Yes, virtually ALL mainstream programming languages have something
ad-hoc-ish about them, in how they're not strictly adhering to any
single programming paradigm.
But wait... maybe that's why they ARE mainstream after all - because you
can mix & match different paradigms with just one language? You know,
solve the different parts of the software in the way that's most suited
to each one. Get around some problems with one paradigm by offering
alternative paradigms to base your software (or module) design on.
After all, for practical purposes it is perfectly irrelevant whether
your language is simple and elegant at its core - all that matters is
whether it can solve YOUR problems in a way that YOU can wrap your
brains around after a reasonable amount of training.
Oh, wait... you're probably right: C# sucks - for YOU. Because if
everything you're familiar with are dremel tools, the cassic cluttered
tool box will look extremely unelegant and inefficient to you.
Speaking of wrong tools for the job, here's a mandatory viewing. No, not
hammers this time:
http://www.youtube.com/watch?v=WxxG0faDT_M
> I mean, take SQL. It solves only one problem, but it solves it so damned
> well that it is basically the /only/ language of its type. And oh look,
> it's based on a theoretical model. Funny coincidence, that...
Yeah, strange though that they didn't use a functional paradigm for
those databases...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> From what I've seen, "every other programming paradigm so far" has been
>> ad hoc without much in the way of a strong, consistent theoretical basis.
> Actually, I can't think of how a programming paradigm could be ad-hoc
> without a consistent theoretical basis; I mean, that's why it is called
> a /paradigm/ rather than just coding style or some such.
>
> Maybe you're confusing programming paradigms with programming languages
> here.
Yeah, perhaps.
> Yes, virtually ALL mainstream programming languages have something
> ad-hoc-ish about them, in how they're not strictly adhering to any
> single programming paradigm.
The thing is, there /are/ programming languages which stick consistently
to one programming approach. Unfortunately, it tends to be the mish-mash
languages which have backwards compatibility to all the pre-existing
crap that tend to be popular.
> But wait... maybe that's why they ARE mainstream after all - because you
> can mix & match different paradigms with just one language? You know,
> solve the different parts of the software in the way that's most suited
> to each one. Get around some problems with one paradigm by offering
> alternative paradigms to base your software (or module) design on.
I would argue that it's just because they continue the poor design
choices that came before. Half the complexity in C++ is due to backwards
compatibility with C. Java and C# just copy the syntax from C++. Visual
Basic even has "basic" in the name. And so on.
> After all, for practical purposes it is perfectly irrelevant whether
> your language is simple and elegant at its core - all that matters is
> whether it can solve YOUR problems in a way that YOU can wrap your
> brains around after a reasonable amount of training.
Sure. And having a complicated, messy language which lacks internal
consistency makes it so much easier to learn. Oh, wait...
> http://www.youtube.com/watch?v=WxxG0faDT_M
When I hear [yet another] story about people storing XML in the database
rather than change the schema, this is what I think it sounds like.
>> I mean, take SQL. It solves only one problem, but it solves it so damned
>> well that it is basically the /only/ language of its type. And oh look,
>> it's based on a theoretical model. Funny coincidence, that...
>
> Yeah, strange though that they didn't use a functional paradigm for
> those databases...
Functional programming is a model of computation, but databases don't
compute anything. They just store stuff. Far more logical to use a model
of knowledge for that, no?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 21.08.2012 10:57, schrieb Invisible:
>> But wait... maybe that's why they ARE mainstream after all - because you
>> can mix & match different paradigms with just one language? You know,
>> solve the different parts of the software in the way that's most suited
>> to each one. Get around some problems with one paradigm by offering
>> alternative paradigms to base your software (or module) design on.
>
> I would argue that it's just because they continue the poor design
> choices that came before. Half the complexity in C++ is due to backwards
> compatibility with C. Java and C# just copy the syntax from C++.
Definitely NOT. They do copy the syntax from C (not C++) for the short
imperative snippets, but that's about it.
They also do make some features of their language /look/ akin to similar
C++ features, like C# generics vs. C++ templates. Again, they're totally
different breeds there though. Even exceptions are fundamentally
different, in that both Java and C# require the thrown exception to be
of a special type.
I don't know a single feature of the C++ language (aside from what's
also available in C) that also features in Java and/or C# in the same
way. Well, maybe line comments - but even the C++ line comments also
feature in C99.
>>> I mean, take SQL. It solves only one problem, but it solves it so damned
>>> well that it is basically the /only/ language of its type. And oh look,
>>> it's based on a theoretical model. Funny coincidence, that...
>>
>> Yeah, strange though that they didn't use a functional paradigm for
>> those databases...
>
> Functional programming is a model of computation, but databases don't
> compute anything. They just store stuff. Far more logical to use a model
> of knowledge for that, no?
See?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/20/2012 1:31, Invisible wrote:
> You said C# lets you call arbitrary machine code as easily as calling
> another C# function. I said it doesn't.
Assuming it uses one of the calling conventions that C# understands, then
yes, it does.
> You cannot pass arbitrary Haskell expressions to C. You can only pass
> primitive data types that C understands. (Things like int or long or void*.)
> If C needs to access Haskell stuff, you write Haskell functions that inspect
> the Haskell stuff and return something that C understands, and then have C
> call that.
So it's hard to call across the boundaries there.
>> And of course
>> if the C isn't actually a function in the functional sense, I'm not sure
>> how Haskell handles it.
>
> If the code you're trying to call has no observable side effects (e.g.,
> sinh() or something) then you mark it as a pure function. If it /does/ have
> observable side-effects, then you mark it as an I/O action, and handle it
> the same way as any other I/O action. Really, it's not hard.
OK, cool.
>> For example, it's really not obvious how easy it
>> would be to invoke a C function that takes as one of its arguments a
>> pointer to a function.
>
> Do you remember that time I used the C sort() function to work a Haskell
> data structure? Do you remember how I don't even know all that much about C,
> and yet it only took me about 20 minutes to figure it out?
>
> Seriously, it's not "trivial". But it's pretty damned simple.
OK. Again, note that I didn't say it's not easy. I said it's not obvious to
me how easy it is. I don't know Haskell very well, remember?
>>> JavaScript is a language invented for controlling web browsers. I
>>> don't know of anything else that runs it.
>>
>> There are lots of other applications that have incorporated javascript.
>
> Really?
I gave you a wikipedia link to a giant list, even! :-)
> Haskell is statically typed. But there's a library for doing stuff with
> dynamic types. Basically, it lets you convert any suitable value to a
> special "Dynamic" type. You can then later try to cast it back to something
> else, which succeeds iff that is actually the correct type. You know, the
> usual deal.
OK. Still a bit clunkier than C#. :-)
> At worst, if you wanted to talk to something dynamic, you could just mark
> every single thing it touches is "type unknown" until you try to do
> something with it. It isn't that hard.
It sounds more clunky than difficult.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/20/2012 4:02, Invisible wrote:
> Object-oriented programming was supposed to make everything polymorphic and
> wonderful.
Uh, no.
> But then they discovered the container problem, so they invented
> generics.
The container problem you describe is only a problem for statically typed
languages.
> they decided that having eight-billion interfaces like "Runnable",
> "ScrollEventListener", "DragEventListener", "CheckBoxEventListener" and so
> on was just stupid.
It was always stupid, and most languages don't need that.
> So Eiffel invented "agents", C# invented "delegates",
> and Java offered the "reflection API"; all of them different attempts to
> solve the same language design problem.
The reflection API has nothing to do with delegates or agents. Indeed, C#
has a reflection API also.
> This is the kind of stuff I'm talking about. All these different languages,
> all with lots and lots of "features" for trying to solve stuff. And then
> there's Haskell, which consists of just 6 constructs in the entire language,
> and solves all of it.
And Smalltalk, which also solves all of it with the same level of
constructs. But the stuff you're complaining about in C# isn't the core
language either. Threads and the reflection API aren't part of the "core
language" of C# either.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/20/2012 7:34, Invisible wrote:
> And this is bad somehow?
Yes. Quite a bit.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/20/2012 1:25, Invisible wrote:
> On 19/08/2012 05:08 PM, Darren New wrote:
>> On 8/19/2012 3:13, Orchid Win7 v1 wrote:
>>>>> You wouldn't be able to do this for arbitrary code.
>>>>
>>>> And that's what I'm talking about. If you want your program to run 15
>>>> years without ever stopping, you pretty much need to be able to replace
>>>> arbitrary bits of code, including type signatures, while you're running.
>>>
>>> And if this was a problem for your application, you would write it in
>>> such a way as to facilitate doing this.
>>
>> Except it's exponentially harder if your language doesn't support it.
>
> No, it isn't.
>
> It's exponentially harder IF YOUR LANGUAGE SUCKS. If you have a powerful
> language, then adding new things is quite easy.
OK, show me a Haskell library that lets me replace any function of the
language with a new version of that function, keeping the old function for
any lazy values that might refer to it, until all those lazy values have
turned strict.
Can you write a Haskell function that wraps every other Haskell function
declared? Maybe. I know a few languages like that. But it still doesn't
make adding that feature easy.
> Well, no, that should be quite easy: You have a rule that inside a
> transaction, you don't try to do anything observable to the outside world.
> If you do, it won't work, and it will be your fault. Problem solved.
Except that makes it useful for the areas in which C# is used, namely
calling library code. You can't know if the code you're calling does
something observable. That's the point.
> The trouble is, they tried to make it so that any arbitrary code can be run
> in a transaction. That's impossible. Which is why it didn't work.
Right. More to the point, they tried to make it so you could use arbitrary
library code for which you don't have the source inside a transaction.
> You might say "but almost all C# code would be disqualified!" But remember,
> the purpose of a transaction is /only/ to coordinate threads. You don't run
> the entire application inside STM, just the tiny bits related to
> synchronisation.
Right. But say the bit you want to synchronize is implemented in someone's
library, and they log a message when something fails.
>> The point I'm making is that
>> many of the decisions in Erlang were made to support this sort of
>> long-running self-healing software. Yes, you could do the same thing in
>> Haskell, but then it would look like Erlang.
>
> Would it, now?
>
> Adding features for distributed concurrency and hot code replacement would
> make Haskell have crap syntax and weak typing?
Well, I think "crap syntax" is debatable, but I'm tending to agree with you.
Weak typing? Most certainly.
> You're aware of the prior art on this subject, I assume? You know about the
> project where they managed to actually implement typed message sending and
> remote code execution? Transparently? Without altering the Haskell language
> at all, just the compiler?
That's not the main part of Erlang. You're talking about Erlang as if we
were talking about SQL and one of us is focusing on the fact that it's also
a functional language. That's not the point.
The fact that Erlang has remote code execution and sends messages is a
*result* of the Erlang design goals, not a fundamental property. (For
example, Hermes has the same design goals, and it doesn't support remote
execution in the language either.)
> Being able to implement something is one thing. Being able to implement it
> /easily/ is another. And that's the goal of designing a good language: to
> make stuff easy.
You keep asserting that it's easier in Haskell to do some of these things
than it is in Erlang or C#. But you've yet to actually provide any evidence
of this beyond vigorous assertions.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 26/08/2012 04:30 AM, Darren New wrote:
> On 8/20/2012 1:31, Invisible wrote:
>> You said C# lets you call arbitrary machine code as easily as calling
>> another C# function. I said it doesn't.
>
> Assuming it uses one of the calling conventions that C# understands,
> then yes, it does.
And if some machine code has the same calling convention as Haskell,
then it's trivial to call. Admittedly, no such code exists anywhere,
because the Haskell calling convention is insanely complicated and
changes every few years, but you see my point. :-P
>> You cannot pass arbitrary Haskell expressions to C. You can only pass
>> primitive data types that C understands. (Things like int or long or
>> void*.)
>> If C needs to access Haskell stuff, you write Haskell functions that
>> inspect
>> the Haskell stuff and return something that C understands, and then
>> have C
>> call that.
>
> So it's hard to call across the boundaries there.
Not so much "hard" as "non-trivial".
>>> And of course
>>> if the C isn't actually a function in the functional sense, I'm not sure
>>> how Haskell handles it.
>>
>> If the code you're trying to call has no observable side effects (e.g.,
>> sinh() or something) then you mark it as a pure function. If it /does/
>> have
>> observable side-effects, then you mark it as an I/O action, and handle it
>> the same way as any other I/O action. Really, it's not hard.
>
> OK, cool.
Three guesses how I/O actions are "really" implemented. ;-)
>> Haskell is statically typed. But there's a library for doing stuff with
>> dynamic types. Basically, it lets you convert any suitable value to a
>> special "Dynamic" type. You can then later try to cast it back to
>> something
>> else, which succeeds iff that is actually the correct type. You know, the
>> usual deal.
>
> OK. Still a bit clunkier than C#. :-)
What? C# doesn't ask you to write explicit upcasts and downcasts sometimes?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> You keep asserting that it's easier in Haskell to do some of these
> things than it is in Erlang or C#. But you've yet to actually provide
> any evidence of this beyond vigorous assertions.
And you keep asserting that Haskell is a bad language, without much
evidence either. :-P
Erlang is /obviously/ much better at hot code swapping than Haskell
currently is. This is not in debate. But you keep asserting that Haskell
/can never/ be as good as Erlang. Because it's somehow /impossible/ for
somebody to come up with a Haskell implementation that does what Erlang
does. You still haven't explained why that is.
Likewise, C#.Net gives you access to the entire .Net platform library.
This has vastly more functionality than what's available for Haskell.
This is because C# is MORE POPULAR than Haskell, and NOT because Haskell
is badly designed.
My argument was never about how much external stuff is available for
Haskell. My argument was that Haskell is a clean, simple language that
manages to solve the same problems that other languages can only solve
using a vast swathe of complicated "features" hard-wired into the language.
C# has methods and inheritance and subtype polymorphism and dynamic
dispatch and delegates and lambda abstractions and broken multiple
inheritance and reflection and... Haskell just has first-class
functions. Solves all of the above, with a fraction of the complexity.
It's simpler to explain, it's simpler to use, it's simpler to read.
That's what I'm talking about.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/26/2012 1:01, Orchid Win7 v1 wrote:
> On 26/08/2012 04:30 AM, Darren New wrote:
>> On 8/20/2012 1:31, Invisible wrote:
>>> You said C# lets you call arbitrary machine code as easily as calling
>>> another C# function. I said it doesn't.
>>
>> Assuming it uses one of the calling conventions that C# understands,
>> then yes, it does.
>
> And if some machine code has the same calling convention as Haskell, then
> it's trivial to call. Admittedly, no such code exists anywhere, because the
> Haskell calling convention is insanely complicated and changes every few
> years, but you see my point. :-P
I see your point. But you seem to be missing mine.
>
>>> You cannot pass arbitrary Haskell expressions to C. You can only pass
>>> primitive data types that C understands. (Things like int or long or
>>> void*.)
>>> If C needs to access Haskell stuff, you write Haskell functions that
>>> inspect
>>> the Haskell stuff and return something that C understands, and then
>>> have C
>>> call that.
>>
>> So it's hard to call across the boundaries there.
>
> Not so much "hard" as "non-trivial".
Well, yes. You have to restructure your Haskell code and basically re-write
it in C style in order to call it from C.
>>> Haskell is statically typed. But there's a library for doing stuff with
>>> dynamic types. Basically, it lets you convert any suitable value to a
>>> special "Dynamic" type. You can then later try to cast it back to
>>> something
>>> else, which succeeds iff that is actually the correct type. You know, the
>>> usual deal.
>>
>> OK. Still a bit clunkier than C#. :-)
>
> What? C# doesn't ask you to write explicit upcasts and downcasts sometimes?
Not for dynamic variables. And almost never for regular C# values either.
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 8/26/2012 1:51, Orchid Win7 v1 wrote:
>> You keep asserting that it's easier in Haskell to do some of these
>> things than it is in Erlang or C#. But you've yet to actually provide
>> any evidence of this beyond vigorous assertions.
>
> And you keep asserting that Haskell is a bad language, without much evidence
> either. :-P
No I didn't. I simply said a tiny elegant language where you can do
everything in libraries is usually not superior to a language designed for
the kind of coding you're doing.
> Erlang is /obviously/ much better at hot code swapping than Haskell
> currently is. This is not in debate. But you keep asserting that Haskell
> /can never/ be as good as Erlang.
It can't be as good at Erlang as what's built into Erlang. OK, granted,
Erlang may not be the best example, because it's a hacky kludge of a
language, but you know what I mean. Were Erlang not based on an interpreter
written in Prolog, taking the same concepts and building them into a
language (like Hermes or NIL perhaps) instead of having them as libraries is
superior.
> Because it's somehow /impossible/ for
> somebody to come up with a Haskell implementation that does what Erlang
> does. You still haven't explained why that is.
Because when you write a library, you get inefficiencies, you get different
people using different libraries, you get non-portability, and you get weird
type sorts of things, and incompatibilities between libraries. No, really.
That's what happens. I used to be a big fan of these very meta languages
(and I still am), but it turns out that once they're too meta, every program
takes tremendously more study to understand and modify.
There's a reason that LISP, Tcl, and FORTH didn't really take off any more
than Haskell did.
> Likewise, C#.Net gives you access to the entire .Net platform library. This
> has vastly more functionality than what's available for Haskell. This is
> because C# is MORE POPULAR than Haskell, and NOT because Haskell is badly
> designed.
No. It's because C# and .NET are *explicitly designed* to provide access to
vast libraries.
> My argument was never about how much external stuff is available for
> Haskell. My argument was that Haskell is a clean, simple language that
> manages to solve the same problems that other languages can only solve using
> a vast swathe of complicated "features" hard-wired into the language.
> C# has methods and inheritance and subtype polymorphism and dynamic dispatch
> and delegates and lambda abstractions and broken multiple inheritance and
> reflection and... Haskell just has first-class functions. Solves all of the
> above, with a fraction of the complexity. It's simpler to explain, it's
> simpler to use, it's simpler to read. That's what I'm talking about.
And the problem comes when you look at the use of a first class function and
try to figure out what is happening with it. And methods, inheritance,
subtype polymorphism, and dynamic dispatch are all the same thing. Delegates
and lambda abstractions are all the same thing. So you're listing a whole
bunch of ideas that let you express exactly what you mean precisely, and say
"but they're all subsumed by this really general mechanism."
Basically, you're saying "we could use a very simple and straight-forward
Haskell language, and replace methods and inheritance and subtype
polymorphism and ... and access to vast libraries with libraries that take
functions as function. But then those libraries would not only be as
complicated as the features you're decrying(*), but they'd also vary from
program to program. You'd never know whether the library you're using has
the same semantics, because it's not part of the standard and just a library.
(*) Yes, they would be, because a specific functionality built into the
compiler and language are going to be simpler than a hand-crafted library in
source code trying to provide the same functionality on top of a generic base.
It would be like driving a car with a mouse and keyboard. There's a reason
that all those "features" are there, and that reason is that they let you
say what you mean, instead of building a structure that says what you mean.
Why do we have while loops, for loops, recursion, if statements, case
statements, if then elseif and else, when all we really need is an if and a
goto?
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 26/08/2012 05:45 PM, Darren New wrote:
> (*) Yes, they would be, because a specific functionality built into the
> compiler and language are going to be simpler than a hand-crafted
> library in source code trying to provide the same functionality on top
> of a generic base.
This is really the central thing I disagree with.
STM is implementable as an external 3rd party library. (I have
personally done this.) And yet, it works beautifully.
Just because something isn't hard-wired, doesn't mean it has to work
badly or be hard to use.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New <dne### [at] san rr com> wrote:
> On 8/20/2012 4:02, Invisible wrote:
> > Object-oriented programming was supposed to make everything polymorphic and
> > wonderful.
> Uh, no.
What do you mean? Isn't *everything* in a pure OO language an object (that
can be inherited from and specialized)?
> > But then they discovered the container problem, so they invented
> > generics.
> The container problem you describe is only a problem for statically typed
> languages.
I'm not sure the problem is any better in dynamically typed languages.
In a statically typed language you get an error at compile time if you
try to put an object of the wrong type in a container. In a dynamically
typed language you get an error at runtime when you try to use it. Is this
really "better"? I wouldn't say so.
> > This is the kind of stuff I'm talking about. All these different languages,
> > all with lots and lots of "features" for trying to solve stuff. And then
> > there's Haskell, which consists of just 6 constructs in the entire language,
> > and solves all of it.
> And Smalltalk
Don't forget Lisp.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |