 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 02:03 AM, Darren New wrote:
> Eiffel did a nice job, but even there they never (AFAIK) actually
> implemented the spec.
FWIW, I thought they did. I don't have proof, however...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 02:08 AM, Darren New wrote:
> On 8/13/2012 9:22, Orchid Win7 v1 wrote:
>> Weirdly, both Java and C# actually /allow/ interfaces to inherit, thus
>> defeating the whole point of the exercise.
>
> Diamond inheritance isn't a problem if you don't have implementations.
>
> OK, so Thread declares void run(), and DistressedDamsel declares void
> run(). Why would those declarations conflict?
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?
>> It makes little to no sense in C#, a language which is already doomed
>> to be
>> horrifyingly inefficient before you've even written a single line of
>> code.
>
> It's becuase C# is a component-oriented language. It's designed to let
> people write code and release the object code and have others use it
> without recompiling.
>
> It's also not intrinsically inefficient. For example, Singularity uses
> it to write its kernels in.
According to the Great Language Shootout, C# Mono is 3x slower than C.
(Then again, Haskell is 2x slower...)
>> Arguably you could have the compiler detect where dynamic binding is
>> and is
>> not needed. That requires whole-program analysis, however.
>
> That's what Eiffel does.
Sure. Because Eiffel doesn't support dynamic linking.
>> No problem for
>> Haskell, but C# explicitly supports run-time loading of additional
>> code, so
>> there's no telling at compile-time what external code might do.
>
> Sure there is, because you recompile the code while it's running.
That sounds remarkably hard to get right...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 10:06, schrieb Invisible:
>> C# has a lot of these "if you DO mean it, say so in the code" things.
>> Which I, personally, think is pretty smart.
>
> If by "pretty smart" you mean "how /every/ programming language should
> work in the first place", then yes.
So, how many (mainstream) programming languages have you seen that
actually /do/ work this way?
C# is pretty "innovative" in that respect.
>>>> Yes. Well, what would you expect? A public method that returns a value
>>>> of a type you can't see the declaration of?
>>>
>>> Haskell lets you do exactly that, yes.
>>
>> I /think/ you should avoid trying to compare maintream languages'
>> features to those of Haskell.
>
> My point being that everybody acts like "oh, of /course/ you can't
> possibly do that", when in fact you can.
You can't with the conceptual approach used by C#. You know, the "I can
verify at compile time that the object referenced by variable X can do
A, B, C and D."
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.
> Besides, why should I avoid comparing things to Haskell? It's true that
> almost nobody has heard of it. But does that mean that it's OK for
> mainstream languages to be poor quality? I think not...
Andy, be fair. The fact that there's /someting/ programming language X
can't do that Haskell can doesn't mean that programming language X is
"poor quality".
I'd dare say C# is actually pretty /high/ quality (at least the language
per se; one might argue about its standard libraries); there's something
to the claim that it's kind of "Java done right".
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 11:17 AM, clipka wrote:
> So, how many (mainstream) programming languages have you seen that
> actually /do/ work this way?
>
> C# is pretty "innovative" in that respect.
If doing things right rather than copying the old kludges that everybody
else uses is "innovative", then sure...
>> My point being that everybody acts like "oh, of /course/ you can't
>> possibly do that", when in fact you can.
>
> You can't with the conceptual approach used by C#. You know, the "I can
> verify at compile time that the object referenced by variable X can do
> A, B, C and D."
>
> 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.
...and yet, in my Haskell snippet, a type is not exported, yet still you
can convert it to a string, because that interface is implemented.
Obviously /the compiler/ must be able to see the declaration for the
type. But that doesn't mean that /the programmer/ needs to.
> Andy, be fair. The fact that there's /someting/ programming language X
> can't do that Haskell can doesn't mean that programming language X is
> "poor quality".
No, that's true. I was really point pointing out that somebody says "X
*must* work this way", and, er, no, it doesn't. It could work
differently if you wanted it to. I guess it's a silly thing to argue
about though.
My real concerns about C# are that they seem to have added a feature for
everything, rather than step back and look for a simpler, more elegant
design that solves everything, not just the things they added specific
features for.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <ano### [at] anonymous org> wrote:
> Am 13.08.2012 19:26, schrieb Warp:
> >> Yeah, I don't know. I'm slowly coming around to the idea that maybe we
> >> should forget about all this "inheritance" stuff and focus on interfaces
> >> as the primary thing of interest...
> >
> > How would you implement a GUI library without using any kind of inheritance?
> By using /interfaces/ maybe?
Given that interfaces cannot contain member variables nor function
implementations (at least not in any language I know of), it would make
the GUI library *really* annoying to use because of all the required code
repetition. (For example, every time the library needs to know the
coordinates of the object on screen, it would have to call a function
declared in the interface, which the user would have to implement in his
own code to return those coordinates. It would also cripple any possibility
of using eg. a screen element that contains other screen elements, because
such an object would just be an interface and cannot contain anything.)
> You can argue that a class that implements an interface effectively
> "inherits" from it, but you can also argue against it. It's a matter of
> how exactly you define "inheritance".
Inheritance implements the OO concept of an "is-a" relationship. If a class
implements an interface, then it effectively has an "is-a" relationship to
it. (For example, if the interface is named, let's say, ButtonListener,
and you implement it, then your class "is-a" ButtonListener. You can give
an object of your class to anything that expects a ButtonListener. It doesn't
get any more straightforward and clear inheritance than that.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le_Forgeron <jgr### [at] free fr> wrote:
> >> I have to admit, Eiffel /does/ make the solution look very, very
> >> complicated. (I can't actually remember off-hand how the heck C++ does
> >> it...)
> >
> > Does what?
> Manage inheritances, including multiple inheritances.
In a single inheritance case the compiler simply internally builds a
data structure with all the data members of the entire inheritance
hierarchy one after another. The base class portion of the structure
looks identical to the one that would exist if you instantiated the
base class directly (and hence any function that deals with the base
class members can deal directly with the inherited class object).
If the class contains any virtual functions, then a virtual table pointer
will be added to the data structure (typically, though not necessarily,
at the beginning of it).
(If the base class did not contain any virtual functions but the derived
function does, it's perfectly possible for the 'this' pointer to change
in value when a base class method is called, in order to point to the
base class part of the structure. The base class member function will be
none the wiser, and work just right.)
In a (non-diamond) multiple inheritance case the same thing is done,
basically. The data of the base classes is just put one after the other
in the derived class' data structure (and the 'this' pointer is changed
as necessary when calling the base class member functions).
In a diamond inheritance situation you have a choice to make: Do you want
each of the multiple parents to be "independent" of each other (which
means that the data from the common parent class is kept separately),
or do you want them to share the data from the common parent class?
In the latter case the data from the common parent class is stored only
once in the most-derived class' data structure, and virtual table trickery
is used to make the in-between class methods to change the 'this' pointer
appropriately when calling the base class methods (or if the in-between
classes want to read/change the base class member variables directly).
(In the former case the in-between classes behave just like there was
no multiple inheritance at all, handling their own "local copy" of the
common base class.)
> >> I would have thought the indirect code jump is probably far more
> >> expensive than the space overhead.
> >
> > The additional space consumption is significant if you have eg. a class
> > that would otherwise be the size of a pointer (and you need to instantiate
> > millions of them). If you had forced virtual functions, it would double in
> > size.
> IIRC, C++ does not duplicates the class function members (not even
> pointers to them) in each instance. Only the actual class (as 1 pointer)
> is stored within each instance. The virtual function is just an index.
> The first virtual/inheritance cost a pointer in the class. The next are
> free.(in fact, with RTTI, even without inheritance, you might already
> have that pointer: so no additional cost)
But if your class were eg. the size of one pointer, then adding any virtual
functions would double its size.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le_Forgeron <jgr### [at] free fr> wrote:
> Vista, 7, 8... who cares, XP runs!
Not a good gaming platform anymore. (Microsoft wants XP to die, so they
refuse to update DirectX for it.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <ano### [at] anonymous org> wrote:
> As current widespread belief is that virtually all multiple inheritance
> use cases can be covered with the interface approach, it seems to make
> sense to avoid this extra overhead.
Only if you don't mind the need for code repetition with interfaces.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 10:31, schrieb Invisible:
> On 14/08/2012 02:01 AM, Darren New wrote:
>> On 8/13/2012 9:31, Orchid Win7 v1 wrote:
>>> I know that's what C++ does. But I got the impression that in C# this
>>> is a compile-time error.
>>
>> No. You just need to say "new" like I showed in the example. It's
>> probably an error or warning or something if you're recompiling a
>> subclass, overriding a superclass method that already exists, and you
>> don't say "new".
>
> So what happens if you say "override" on a method that isn't virtual?
Haven't done much C# programming lately, so currently I'm not that firm
on the various keywords, but if "override" is that keyword used to do
virtual method override and "new" is that keyword used to do static
method override, then you'd surely get a compile-time error, because
what you tell the compiler about your derived class doesn't fit what the
compiler knows about the parent class.
Makes a lot of sense, because trying to perform virtual method override
on a non-virtual method is a strong indicator that you don't know what
you're doing.
You need to get used to all those keywords, that's all.
>> It probably lets you return an opaque reference to
>> something you can't see the type of, but I doubt it lets you return a
>> type that you 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.
You've proven us wrong: We named a wrong reason for why the following
construct doesn't make any sense:
class Foobar
{
private class Bar; // (1)
public Bar foobar(); // (2)
}
Read this carefully, trying to understand it not just syntactically but
also what it means in the OO concept:
In (1), the "class Bar" tells us (and the compiler) that there is a
class named "Foobar::Bar", and the "private" keyword tells us (and the
compiler) that the mere /existance/ of this type is part of Foobar's
"hidden" implementation details, not to exposed to anything else.
In (2), the "Bar foobar()" tells us (and the compiler) that every Foobar
object provides an operation named "Foobar::foobar()" returning a value
of type "Bar", with the "public" keyword telling us (and the compiler)
that the operation is part of the official interface of the class, to be
exposed to the whole world.
Notice how (2) implies that the mere /existence/ of a class named
"Foobar::Bar" must also be part of the official interface. If the
implementation of Foobar is ever changed, the class "Foobar::Bar" must
still be retained in order to not break existing code using the class.
But in (1) we already specified that even the existence of the
"Foobar::Bar" class is just an implementation detail.
Of course it's perfectly possible to expose the existence of an inner
class without exposing its details. You just need to use the proper
keyword on the members of the inner class. (Not sure off the top of my
hat which one that is.)
> More usually, of course, you would export the /name/, but not its
> /definition/. But you /can/ decide to not export the type at all, and
> still return it as a result, or take it as an argument.
That's quite a stupid thing to do, because you then can't tell at
compile-time whether some other function expecting a parameter of type
"Bar" actually gets passed such a type when using (in C++ style pseudocode):
Foobar f;
ANY_TYPE x;
x = f.foobar();
...
f.barfoo(x);
>>> Or how "bool" isn't an
>>> enumeration, it's hard-coded. Or how you can make primitive types
>>> nullable,
>>> but you can't make reference types non-nullable. Or...
>>
>> It's a little complex, but it really isn't difficult. Why would you care
>> that bool isn't an enumeration?
>
> If you have real enumerations, why do you need a special-case for bool?
> To be, that just suggests that enumerations don't work properly.
In C#, it might have something to do that enums are far more powerful
than in other languages, possibly creating some overhead; you really
want to avoid that for the ubiquitous bool type. (Matter of fact, C#
enums are more like syntactical sugar for classes employing the Atom
design pattern, rather than a collection of integer constants.)
>> It's an excellent OO language that expects to have runtime and OS
>> support around. It's a pretty crappy safety-critical realtime functional
>> language.
>
> OK, whatever. I haven't really explored it all that much yet, but it
> doesn't appear to compare well to Eiffel.
I don't know Eiffel, but I'd be surprised if Eiffel could compete with
C# in what C# was designed for: Being a mainstream language for
mainstream PC desktop applications, running on a VM and providing decent
performance.
Of course, if you expect C# to be fit for stuff way outside this
ballpark, it's no surprise you'll be disappointed.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New <dne### [at] san rr com> wrote:
> On 8/13/2012 7:53, Warp wrote:
> > If diamond inheritance is the problem, then forbid diamond inheritance.
> It turns out that having everything descend from Object (and other tricks
> like that) turn out to be more useful than multiple inheritance.
Does Object contain member variables? If not, then I don't see the problem.
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.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 10:32, schrieb Invisible:
> On 14/08/2012 02:01 AM, Darren New wrote:
>> It's an excellent OO language that expects to have runtime and OS
>> support around.
>
> ...and yet, they claim it can be used for embedded systems, which don't
> even /have/ an OS?
You'd be surprised how many embedded systems /do/ have an OS.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 12:13 PM, Warp wrote:
> Le_Forgeron<jgr### [at] free fr> wrote:
>> Vista, 7, 8... who cares, XP runs!
>
> Not a good gaming platform anymore. (Microsoft wants XP to die, so they
> refuse to update DirectX for it.)
Valid point. But in a commercial setting, pretty irrelevant.
(Unless you happen to be a games developer, I suppose...)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> On 14/08/2012 12:13 PM, Warp wrote:
> > Le_Forgeron<jgr### [at] free fr> wrote:
> >> Vista, 7, 8... who cares, XP runs!
> >
> > Not a good gaming platform anymore. (Microsoft wants XP to die, so they
> > refuse to update DirectX for it.)
> Valid point. But in a commercial setting, pretty irrelevant.
It will become relevant when Microsoft inevitably stops supporting XP.
It might not happen next month, or even next year, but the clock is
ticking.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 12:46, schrieb Invisible:
> On 14/08/2012 11:17 AM, clipka wrote:
>
>> So, how many (mainstream) programming languages have you seen that
>> actually /do/ work this way?
>>
>> C# is pretty "innovative" in that respect.
>
> If doing things right rather than copying the old kludges that everybody
> else uses is "innovative", then sure...
That's exactly my ppint.
> My real concerns about C# are that they seem to have added a feature for
> everything, rather than step back and look for a simpler, more elegant
> design that solves everything, not just the things they added specific
> features for.
C# was never meant to win a design contest. It was meant to be a decent
everyday programming language.
Besides, there's no such thing as as an elegant design that solves
everything [with reasonable effort for the language user]. Many tasks
require certain common design patterns you don't want to re-implement
over and over again, so one way or another you'd end up adding layers on
top of that elegant design, which - because the elegant design doesn't
provide them out of the box - will often be far from elegant to use.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 13:00, schrieb Warp:
> clipka <ano### [at] anonymous org> wrote:
>> Am 13.08.2012 19:26, schrieb Warp:
>
>>>> Yeah, I don't know. I'm slowly coming around to the idea that maybe we
>>>> should forget about all this "inheritance" stuff and focus on interfaces
>>>> as the primary thing of interest...
>>>
>>> How would you implement a GUI library without using any kind of inheritance?
>
>> By using /interfaces/ maybe?
>
> Given that interfaces cannot contain member variables nor function
> implementations (at least not in any language I know of), it would make
> the GUI library *really* annoying to use because of all the required code
> repetition. (For example, every time the library needs to know the
> coordinates of the object on screen, it would have to call a function
> declared in the interface, which the user would have to implement in his
> own code to return those coordinates.
I guess you've heard of code re-use through delegation, no?
> It would also cripple any possibility
> of using eg. a screen element that contains other screen elements, because
> such an object would just be an interface and cannot contain anything.)
I have no idea what you're saying there. If you're saying what I'm
reading, it's plain nonsense.
>> You can argue that a class that implements an interface effectively
>> "inherits" from it, but you can also argue against it. It's a matter of
>> how exactly you define "inheritance".
>
> Inheritance implements the OO concept of an "is-a" relationship. If a class
> implements an interface, then it effectively has an "is-a" relationship to
> it. (For example, if the interface is named, let's say, ButtonListener,
> and you implement it, then your class "is-a" ButtonListener. You can give
> an object of your class to anything that expects a ButtonListener. It doesn't
> get any more straightforward and clear inheritance than that.)
In common parlance, "inheritance" means "multi-level inheritance" though
(and in the OP quoted above it was obviously meant that way), and a
single tier of interfaces and a single tier of implementing classes
doesn't really cut it.
I do agree that at least inheritance among interfaces would be nice to
have, but it's not entirely impossible to implement a GUI library even
without that.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Valid point. But in a commercial setting, pretty irrelevant.
>
> It will become relevant when Microsoft inevitably stops supporting XP.
>
> It might not happen next month, or even next year, but the clock is
> ticking.
What do you mean "when"? This has already happened.
http://en.wikipedia.org/wiki/Windows_XP
"Mainstream support ended 14 April 2009."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 13.08.2012 23:00, schrieb Le_Forgeron:
> Le 13/08/2012 22:22, clipka nous fit lire :
>>
>> As current widespread belief is that virtually all multiple inheritance
>> use cases can be covered with the interface approach, it seems to make
>> sense to avoid this extra overhead.
>
> When all you have is a hammer, everything is a nail.
>
> When you make the conception, once you know there can be only one true
> linear hierarchy of classes and interfaces on the side, you integrate it
> in your problem. You might even forbid yourself of thinking about
> multiple inheritances.
As I said, it's "current widespread belief"; I won't dare to make any
claims about its boolean value, but on the basis of this belief, the
decision to restrict multiple inheritance to interfaces is perfectly
logical.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 12:33 PM, clipka wrote:
> C# was never meant to win a design contest. It was meant to be a decent
> everyday programming language.
And surely starting with a solid design is the best way to do that.
> Besides, there's no such thing as as an elegant design that solves
> everything [with reasonable effort for the language user].
I disagree.
> Many tasks
> require certain common design patterns you don't want to re-implement
> over and over again, so one way or another you'd end up adding layers on
> top of that elegant design, which - because the elegant design doesn't
> provide them out of the box - will often be far from elegant to use.
Again, I do not agree.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 00:17, schrieb andrel:
>> When all you have is a hammer, everything is a nail.
>
> or a plank. You need planks too.
> or a thumb. Hammers are great to remind one of thumbs.
LOL!
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 13/08/2012 11:17 PM, andrel wrote:
> or a thumb. Hammers are great to remind one of thumbs.
My thumb almost hurts now...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 10:40, schrieb Invisible:
>> Diamond inheritance isn't a problem if you don't have implementations.
>>
>> OK, so Thread declares void run(), and DistressedDamsel declares void
>> run(). Why would those declarations conflict?
>
> 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?
Depends on the language. You could, for instance, have a syntax to
define a Thread::run() and a separate DistressedDamsel::run(); don't
know whether C# can do that though. Maybe, maybe not. I'd just make a
guess that Java can't do it.
> According to the Great Language Shootout, C# Mono is 3x slower than C.
> (Then again, Haskell is 2x slower...)
A factor of 3x compared to what is probably the fastest
more-or-less-high level language doesn't sound that bad to me, given how
much easier it is to program anything serious in it. (You don't want to
write a GUI program in C, do you?! You'd at least want C++)
>> Sure there is, because you recompile the code while it's running.
>
> That sounds remarkably hard to get right...
Ever heard of JIT-compilers?
All you need to do is mark the corresponding classes as not-yet-compiled
again.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>> OK, so Thread declares void run(), and DistressedDamsel declares void
>>> run(). Why would those declarations conflict?
>>
>> 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?
>
> Depends on the language. You could, for instance, have a syntax to
> define a Thread::run() and a separate DistressedDamsel::run(); don't
> know whether C# can do that though. Maybe, maybe not. I'd just make a
> guess that Java can't do it.
Is there /anything/ Java does right? ;-)
>> According to the Great Language Shootout, C# Mono is 3x slower than C.
>> (Then again, Haskell is 2x slower...)
>
> A factor of 3x compared to what is probably the fastest
> more-or-less-high level language doesn't sound that bad to me, given how
> much easier it is to program anything serious in it. (You don't want to
> write a GUI program in C, do you?! You'd at least want C++)
My point is, adding a low-level feature to shave off 0.02% runtime
overheard in a language which already has 200% overhead seems... odd.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 13:59, schrieb Invisible:
> On 14/08/2012 12:33 PM, clipka wrote:
>> C# was never meant to win a design contest. It was meant to be a decent
>> everyday programming language.
>
> And surely starting with a solid design is the best way to do that.
The C# design /is/ pretty solid for a modern language. Much more solid
at least than the current Java language (which has added tons of kludgy
stuff because they found their initial elegang solution wasn't that
elegant after all for plenty of use cases), or the newest C++
incarnation (which has added badly needed stuff - like smart pointers,
to name just one example - via templates, leading to a somewhat
cumbersome syntax for everyday stuff).
The reason for C# being pretty solid is precisely that they did /not/
aim for an elegant core language to add the other features on top, but
rather designed a language that provides all the features out of the
box, with a somewhat consistent syntax and all.
>> Besides, there's no such thing as as an elegant design that solves
>> everything [with reasonable effort for the language user].
>
> I disagree.
You're free to do that. Still, do you happen to know any counterexample?
(And if so, why aren't you using that language?)
>> Many tasks
>> require certain common design patterns you don't want to re-implement
>> over and over again, so one way or another you'd end up adding layers on
>> top of that elegant design, which - because the elegant design doesn't
>> provide them out of the box - will often be far from elegant to use.
>
> Again, I do not agree.
Again, a few counterexamples might give your disagreement a /bit/ more
weight.
Oh, and don't bother to mention Haskell in this context; you've done a
fair share of ranting about that language already to disqualify it for
the position of "an elegant design that solves everything [without
accumulating non-elegant layers of additional features]".
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 14:25, schrieb Invisible:
>>> According to the Great Language Shootout, C# Mono is 3x slower than C.
>>> (Then again, Haskell is 2x slower...)
>>
>> A factor of 3x compared to what is probably the fastest
>> more-or-less-high level language doesn't sound that bad to me, given how
>> much easier it is to program anything serious in it. (You don't want to
>> write a GUI program in C, do you?! You'd at least want C++)
>
> My point is, adding a low-level feature to shave off 0.02% runtime
> overheard in a language which already has 200% overhead seems... odd.
I wouldn't be surprised if your estimate of 0.02% is a good deal off the
mark.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> The C# design /is/ pretty solid for a modern language. Much more solid
> at least than the current Java language.
"More elegant than Java" is a bit like saying "cooler than the surface
of the Sun". :-P
> Oh, and don't bother to mention Haskell in this context; you've done a
> fair share of ranting about that language already to disqualify it for
> the position of "an elegant design that solves everything [without
> accumulating non-elegant layers of additional features]".
So what do you think Haskell solves inelegantly?
It's no secret that the libraries lack vast swathes of important
functionality, or that some of the build tools leave a lot to be
desired. But the core language itself? It isn't perfect, but it's a
damn-site more elegant than any other programming language I've ever
laid eyes on.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> >> Valid point. But in a commercial setting, pretty irrelevant.
> >
> > It will become relevant when Microsoft inevitably stops supporting XP.
> >
> > It might not happen next month, or even next year, but the clock is
> > ticking.
> What do you mean "when"? This has already happened.
> http://en.wikipedia.org/wiki/Windows_XP
> "Mainstream support ended 14 April 2009."
It still gets security patches, doesn't it?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 14:57, schrieb Invisible:
>> Oh, and don't bother to mention Haskell in this context; you've done a
>> fair share of ranting about that language already to disqualify it for
>> the position of "an elegant design that solves everything [without
>> accumulating non-elegant layers of additional features]".
>
> So what do you think Haskell solves inelegantly?
>
> It's no secret that the libraries lack vast swathes of important
> functionality, or that some of the build tools leave a lot to be
> desired. But the core language itself? It isn't perfect, but it's a
> damn-site more elegant than any other programming language I've ever
> laid eyes on.
That may well be true, and I actually believe it, but as soon as you
want to do some serious programming you'll /need/ more than that elegant
core; you'll need those libraries of which /you/ yourself said that
various of them suck for this and that reason and none of them gives you
exactly what you need.
An elegant core language may be nice to have, but if as a consequence it
takes you ages to get the job done, unless you make use of plenty
non-elegant language extensions or libraries, it doesn't /really/
qualify as "a simpler, more elegant design that solves everything".
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> So what do you think Haskell solves inelegantly?
>>
>> It's no secret that the libraries lack vast swathes of important
>> functionality, or that some of the build tools leave a lot to be
>> desired. But the core language itself? It isn't perfect, but it's a
>> damn-site more elegant than any other programming language I've ever
>> laid eyes on.
>
> That may well be true, and I actually believe it, but as soon as you
> want to do some serious programming you'll /need/ more than that elegant
> core; you'll need those libraries of which /you/ yourself said that
> various of them suck for this and that reason and none of them gives you
> exactly what you need.
>
> An elegant core language may be nice to have, but if as a consequence it
> takes you ages to get the job done, unless you make use of plenty
> non-elegant language extensions or libraries, it doesn't /really/
> qualify as "a simpler, more elegant design that solves everything".
Right. So you're saying the fact that nobody has sat down and written a
comprehensive set of libraries makes the language "non-elegant" and
"poorly designed"?
Seriously, what?
Haskell does not have the rich set of libraries that C# has because it
wasn't developed by a multi-billion dollar global mega corporation. It
was developed by three beardy guys in a shed on day. If it ever becomes
popular, we'll see more libraries being developed for it. If (as seems
more likely) it never becomes really popular, then we won't. But either
way, this has nothing to do with whether the language is well-designed
or not.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>>> Valid point. But in a commercial setting, pretty irrelevant.
>>>
>>> It will become relevant when Microsoft inevitably stops supporting XP.
>
>> What do you mean "when"? This has already happened.
>
>> "Mainstream support ended 14 April 2009."
>
> It still gets security patches, doesn't it?
Er... I'm not sure, actually. Perhaps so.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 2012-08-14 04:31, Invisible a écrit :
> On 14/08/2012 02:01 AM, Darren New wrote:
>
>> It probably lets you return an opaque reference to
>> something you can't see the type of, but I doubt it lets you return a
>> type that you 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.
Correct me if I'm wrong, but apart from showing that the standard
seemingly allows it, how would you use that in a real world scenario?
By exporting foobar, you intend to use it somewhere else in your code,
right? Which means there's another piece of code somewhere that expects
to receive something of type bar, without knowing what type bar actually is!
How does that work?
--
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/* flabreque */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/* @ */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/* gmail.com */}camera{orthographic location<6,1.25,-6>look_at a }
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 14/08/2012 13:11, Warp a écrit :
>> IIRC, C++ does not duplicates the class function members (not even
>> > pointers to them) in each instance. Only the actual class (as 1 pointer)
>> > is stored within each instance. The virtual function is just an index.
>> > The first virtual/inheritance cost a pointer in the class. The next are
>> > free.(in fact, with RTTI, even without inheritance, you might already
>> > have that pointer: so no additional cost)
> But if your class were eg. the size of one pointer, then adding any virtual
> functions would double its size.
Tetracapilli... if you compile with RTTI (default for most, including
gnu), an instance of an empty class is already the size of a pointer: to
the class description.
Adding any virtual function in such case would not increase the size of
the instance.
Also, remember that even if the root class is size of a pointer, its
children can only get the same size or larger. If every layer adds a
pointer, the second layer is already the size of two: one proper, one
from parent field (and a third for RTTI)
Removing RTTI <==> no dynamic_cast<>,... might break some code, yet it's
possible (for tight embedded system, including the Embedded C++ spec,
which are just PITA and was made for very low memory system).
In Embedded C++, there is no multiple inheritance, no C++ cast (neither
down or up), no mutable attribut, no namespace, no exception, no
templates and no stdio.
Usage of EC++ is low, but that's might already be too much. It's kind of
C on very fascist mode.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> 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
>
> Correct me if I'm wrong, but apart from showing that the standard
> seemingly allows it, how would you use that in a real world scenario?
>
> By exporting foobar, you intend to use it somewhere else in your code,
> right? Which means there's another piece of code somewhere that expects
> to receive something of type bar, without knowing what type bar actually
> is!
>
> How does that work?
Well, you're right in that you cannot write any code which explicitly
expects Bar. You can pass the result to any function that works with
/all/ types, or any function that works with any showable type. If the
module exported some functions that expect Bar as input, you can pass
the result to them. But you can't write that in a type signature,
which... yeah, is a bit silly.
My point wasn't so much that this is a something anybody is likely to
want to do. My point was a counter-example to the "that's obviously
impossible" argument. It's /not/ impossible at all.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
As with any language, my WTF list:
- Unsigned integers have names prefixed with "u", and signed integers
have no prefix. Except byte, which is the other way around: "byte" and
"sbyte". WTF?
- The "char" type works with Unicode. Well done. Oh, but wait... It only
stores 16 bits, and yet Unicode actually requires 24 bits to represent a
single code-point. So this "Unicode character" only actually covers the
Basic Multilingual Plane. FAIL!
- "As of C# 2.0, it is also possible to have an array in a structure."
(Erm, why the HELL would it not be possible to do that before??)
- "x & y" performs a Boolean-OR if the arguments are Bools, and a
bitwise-OR if they are integers. The same goes for all the other logical
operators. Except NOT, which has "!x" for Bools and "~x" for integers. WTF?
- "x + y" performs addition. Unless either argument is a string, in
which case the other is converted to a string as well (if not a string
already) and the strings are concatenated. Unless both arguments are
delegates, in which case they are concatenated. (I guess there's a
/reason/ the Java guys claim that operator overloading is evil!)
- Goto? Seriously? Well, I suppose /technically/ that's not actually a
WTF...
- Anonymous delegates /and/ lambda functions?
- A delegate is a thing which is called when an event is fired, but an
event /is/ a delegate?? (In fairness, this is probably a Wikibooks WTF
rather than anything to do with the design of C#.)
- Extension methods. Just... what??
- A non-generic queue is called Queue, and a generic queue is called
Queue<T>. And yet, for the other container types, the generic and
non-generic versions have completely different, unrelated names. (I
guess that's backwards compatibility for you... oh, wait.)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 2012-08-14 04:27, Invisible a écrit :
> Actually, I've never seen Windows 2000 used anywhere, ever. Not in
> people's homes, not in places of work. Indeed, if it weren't for that
> course my employer sent me on, I wouldn't even know it /exists/... It
> never seemed to be really popular.
>
My employer used it on all its desktops and laptops when they upgraded
from Windows 95. So from 2000 to 2005, or thereabouts, you had close to
400,000 users worldwide, in just one company.
My bank also _still_ uses it for the teller PCs. (I suppose bank
tellers are a dying breed, so they figured it was not worth it to
develop a new standard image to be deployed across the country...
--
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/* flabreque */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/* @ */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/* gmail.com */}camera{orthographic location<6,1.25,-6>look_at a }
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 2012-08-14 07:56, Invisible a écrit :
>>> Valid point. But in a commercial setting, pretty irrelevant.
>>
>> It will become relevant when Microsoft inevitably stops supporting XP.
>>
>> It might not happen next month, or even next year, but the clock is
>> ticking.
>
> What do you mean "when"? This has already happened.
>
> http://en.wikipedia.org/wiki/Windows_XP
>
> "Mainstream support ended 14 April 2009."
Corporate is NOT mainstream. You can bet your ass off that if Bank Of
America, HSBC, LuftHansa, or the Deptartment of Defense finds a weird
problem in XP, they still have ways fo making MS cough up a patch for them.
IBM still unofficially supports OS/2 for the same reason.
--
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/* flabreque */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/* @ */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/* gmail.com */}camera{orthographic location<6,1.25,-6>look_at a }
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le_Forgeron <lef### [at] free fr> wrote:
> Tetracapilli... if you compile with RTTI (default for most, including
> gnu), an instance of an empty class is already the size of a pointer: to
> the class description.
I don't know how to explain this more clearly than I have already done.
If a class has no virtual functions, it will have no vtable pointer.
RTTI has nothing to do with this.
If you have, for example, one int as its member, the size of the class
will be typically 4 bytes.
Now add a virtual function to the class: Suddenly its size is 8 bytes
(16 if compiling a 64-bit binary). The size of the class has doubled
(quadrupled in 64-bit systems).
This is the reason why vtables are added only to classes that have virtual
functions.
> In Embedded C++, there is no multiple inheritance, no C++ cast (neither
> down or up), no mutable attribut, no namespace, no exception, no
> templates and no stdio.
That sounds like a pretty useless C++.
(Why no namespaces or templates? What do those have anything to do with
embedded systems?)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> - Unsigned integers have names prefixed with "u", and signed integers
> have no prefix. Except byte, which is the other way around: "byte" and
> "sbyte". WTF?
Why would you expect bytes to be signed by default?
> - The "char" type works with Unicode. Well done. Oh, but wait... It only
> stores 16 bits, and yet Unicode actually requires 24 bits to represent a
> single code-point. So this "Unicode character" only actually covers the
> Basic Multilingual Plane. FAIL!
I'm assuming it uses UTF-16.
> - "x + y" performs addition. Unless either argument is a string, in
> which case the other is converted to a string as well (if not a string
> already) and the strings are concatenated. Unless both arguments are
> delegates, in which case they are concatenated. (I guess there's a
> /reason/ the Java guys claim that operator overloading is evil!)
Using operator+ for string concatenation is pretty common. I have never
had any kind of confusion with it. (You would have to come up with a
really artificial example to deliberately make it confusing.)
Automatically converting the right hand side to a string sounds more
dubious to me. Sounds like it may easily be done inadvertently, causing
all kinds of bugs.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 06:38 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> - Unsigned integers have names prefixed with "u", and signed integers
>> have no prefix. Except byte, which is the other way around: "byte" and
>> "sbyte". WTF?
>
> Why would you expect bytes to be signed by default?
I don't know about "default", but a consistent naming scheme would be
nice...
>> - The "char" type works with Unicode. Well done. Oh, but wait... It only
>> stores 16 bits, and yet Unicode actually requires 24 bits to represent a
>> single code-point. So this "Unicode character" only actually covers the
>> Basic Multilingual Plane. FAIL!
>
> I'm assuming it uses UTF-16.
Perhaps actual /strings/ allow storing all possible Unicode code-points.
However, char, the type of a single character, apparently covers the BMP
only. If you're going to go to all the trouble of actually supporting
Unicode, why not support the whole thing?
> Using operator+ for string concatenation is pretty common. I have never
> had any kind of confusion with it. (You would have to come up with a
> really artificial example to deliberately make it confusing.)
>
> Automatically converting the right hand side to a string sounds more
> dubious to me. Sounds like it may easily be done inadvertently, causing
> all kinds of bugs.
Yeah, sounds like more the sort of thing you'd expect in a scripting
language.
OTOH, it appears that it's the only autoconversion that can happen.
Pop quiz: if x is a string and y is a delegate, does it do delegate
concatenation or string concatenation?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 15:12, schrieb Invisible:
>>> So what do you think Haskell solves inelegantly?
>>>
>>> It's no secret that the libraries lack vast swathes of important
>>> functionality, or that some of the build tools leave a lot to be
>>> desired. But the core language itself? It isn't perfect, but it's a
>>> damn-site more elegant than any other programming language I've ever
>>> laid eyes on.
>>
>> That may well be true, and I actually believe it, but as soon as you
>> want to do some serious programming you'll /need/ more than that elegant
>> core; you'll need those libraries of which /you/ yourself said that
>> various of them suck for this and that reason and none of them gives you
>> exactly what you need.
>>
>> An elegant core language may be nice to have, but if as a consequence it
>> takes you ages to get the job done, unless you make use of plenty
>> non-elegant language extensions or libraries, it doesn't /really/
>> qualify as "a simpler, more elegant design that solves everything".
>
> Right. So you're saying the fact that nobody has sat down and written a
> comprehensive set of libraries makes the language "non-elegant" and
> "poorly designed"?
I did not say THAT.
What I did say is that if nobody has sat down and written a
comprehensive set of libraries, this prevents the lange from being a
language that "solves everything" - and, consequentially, from
qualifying as "a simpler, more elegant design that solves everything".
What I also did imply is that if anybody would indeed sit down and write
a comprehensive cover-all set of libraries, there would likely be quite
a number of them that would be non-elegant to use; and if those
libraries would form a part the language's way of "solving everything",
then THEY would disqualify the combo (core language + libraries) from
qualifying as that "simpler, more elegant design that solves everything".
> Haskell does not have the rich set of libraries that C# has because it
> wasn't developed by a multi-billion dollar global mega corporation. It
> was developed by three beardy guys in a shed on day. If it ever becomes
> popular, we'll see more libraries being developed for it. If (as seems
> more likely) it never becomes really popular, then we won't. But either
> way, this has nothing to do with whether the language is well-designed
> or not.
Right. But it has something to do with whether the language "solves
everything" [for practical purposes].
Can you easily model a state machine in Haskell? If not, then it doesn't
solve everything.
Can you easily write a GUI in Haskell? If not, then it doesn't solve
everything.
Can you easily write an OS kernel in Haskell? If not, then it doesn't
solve everything.
Just three things that immediately spring to my mind; I'm sure there's
gazillions of others out there.
As soon as you have libraries (or other language extensions) for all
conceivable purposes, we'll talk again - about elegancy then.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 14.08.2012 23:06, schrieb Orchid Win7 v1:
> Perhaps actual /strings/ allow storing all possible Unicode code-points.
> However, char, the type of a single character, apparently covers the BMP
> only. If you're going to go to all the trouble of actually supporting
> Unicode, why not support the whole thing?
Do you have any idea what "the whole thing" means in case of Unicode?
Hint: There's more to Unicode than just ~1 million code points with
glyphs mapped to some of them.
> Pop quiz: if x is a string and y is a delegate, does it do delegate
> concatenation or string concatenation?
Provided it doesn't raise an error, obviously you'll get string
concatenation, because you can't convert strings to delegates.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Perhaps actual /strings/ allow storing all possible Unicode code-points.
>> However, char, the type of a single character, apparently covers the BMP
>> only. If you're going to go to all the trouble of actually supporting
>> Unicode, why not support the whole thing?
>
> Do you have any idea what "the whole thing" means in case of Unicode?
>
> Hint: There's more to Unicode than just ~1 million code points with
> glyphs mapped to some of them.
Sure. But if you can't even /write down/ those code-points, that's kinda
limiting.
(It also strikes me that if the String type /can/ hold them all and Char
/can't/, that has interesting implications for trying to iterate over a
String one Char at a time...)
>> Pop quiz: if x is a string and y is a delegate, does it do delegate
>> concatenation or string concatenation?
>
> Provided it doesn't raise an error, obviously you'll get string
> concatenation,
Yes.
> because you can't convert strings to delegates.
No.
From what I can tell, it never tries to convert a string to anything
else, but it /does/ try to convert anything else to a string.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Right. So you're saying the fact that nobody has sat down and written a
>> comprehensive set of libraries makes the language "non-elegant" and
>> "poorly designed"?
>
> I did not say THAT.
>
> What I did say is that if nobody has sat down and written a
> comprehensive set of libraries, this prevents the lange from being a
> language that "solves everything" - and, consequentially, from
> qualifying as "a simpler, more elegant design that solves everything".
Haskell is an elegant, beautiful language. In the vast majority of
cases, it lets you write your application logic in a very concise,
reliable and maintainable way.
For a language to be /useful/, you need more than just the language. You
need libraries. You need a build system. You need packaging and
distribution. You need profiling and debugging tools. You need
documentation systems. And probably a number of other things too.
For the most part, Haskell lacks these. This does not change the fact
that the Haskell /language/ is elegant and beautiful.
I don't doubt that C# almost certainly has /far/ more plentiful
libraries. (As does Java, C++, C, Python, Ruby, or really /any/
programming language that mainstream programmers use.) That doesn't mean
that the design of the C# /language/ is clean or beautiful.
> What I also did imply is that if anybody would indeed sit down and write
> a comprehensive cover-all set of libraries, there would likely be quite
> a number of them that would be non-elegant to use
And why would that be the case?
> Right. But it has something to do with whether the language "solves
> everything" [for practical purposes].
I was referring only to the design of the language itself, not the
libraries that go with it, nor any of the various other tools required
to make a language generally useful. It's no secret that Haskell fails
spectacularly on that count.
> Can you easily model a state machine in Haskell? If not, then it doesn't
> solve everything.
This is trivial.
> Can you easily write a GUI in Haskell? If not, then it doesn't solve
> everything.
This could be made trivial, but currently it isn't supported
particularly well.
(E.g., writing a GTK application is fairly simple. Getting the GTK
libraries to work in the first place is not simple.)
> Can you easily write an OS kernel in Haskell? If not, then it doesn't
> solve everything.
This has been done at least once before.
Note also that there is now a project that lets you run the Haskell
runtime on bare metal (or rather, on the Xen virtualisation platform)
without an OS. Apparently this was developed as part of a commercial
system, so somebody is using it for real.
> As soon as you have libraries (or other language extensions) for all
> conceivable purposes, we'll talk again - about elegancy then.
Right, because how elegant a language is depends on how many libraries
it has. Oh, wait - no it doesn't.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 03:42 PM, Invisible wrote:
> - The "char" type works with Unicode. Well done. Oh, but wait... It only
> stores 16 bits, and yet Unicode actually requires 24 bits to represent a
> single code-point. So this "Unicode character" only actually covers the
> Basic Multilingual Plane. FAIL!
Oh great. Apparently "char" doesn't store a code-point at all, it stores
a code-unit.
For anything in the BMP, these are effectively the same thing. For
anything outside that range, *you* must manually write the code to
decode UTF-16 into actual code-points (which then do not fit into a "char").
Well done. :-P
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 13/08/2012 01:08 PM, Invisible wrote:
> I think perhaps my biggest criticism of C# is that there doesn't seem to
> be an introduction anywhere. I can read about isolated features of the
> language on MSDN, but nowhere can I seem to find a coherent introduction...
I downloaded the C# "language specification". Rather than being an
actual specification (which would usually be a dense, incomprehensible
document supplying a rigorous mathematical definition of the language
for use by compiler implementers), it seems that /this/ is the
comprehensible introduction that actually explains stuff. Weird...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 15.08.2012 10:11, schrieb Invisible:
>> Right. But it has something to do with whether the language "solves
>> everything" [for practical purposes].
>
> I was referring only to the design of the language itself, not the
> libraries that go with it, nor any of the various other tools required
> to make a language generally useful. It's no secret that Haskell fails
> spectacularly on that count.
I'm reiterating: I don't doubt that the Haskell /core language/ is
simple and elegant. I doubt that it "solves everything".
As soon as you've dealt with the "solves everything" part, we'll talk
again, and see if the "simple and elegant" also applies to that one. My
claim is that the combo isn't possible.
THAT is the point I'm trying to get through to you.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> I was referring only to the design of the language itself, not the
>> libraries that go with it, nor any of the various other tools required
>> to make a language generally useful. It's no secret that Haskell fails
>> spectacularly on that count.
>
> I'm reiterating: I don't doubt that the Haskell /core language/ is
> simple and elegant. I doubt that it "solves everything".
It solves every problem of core application logic. It doesn't solve the
problem of talking to the outside world. (That's the job of the
libraries, and once they currently don't do so well.)
> As soon as you've dealt with the "solves everything" part, we'll talk
> again, and see if the "simple and elegant" also applies to that one. My
> claim is that the combo isn't possible.
>
> THAT is the point I'm trying to get through to you.
You somehow believe that writing a bunch of libraries would make the
language no longer elegant?
Well, I guess since it's unlikely to ever happen, we'll never know...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 03:42 PM, Invisible wrote:
> As with any language, my WTF list:
On the other hand, it seems they certainly did a fair few things right.
It's messy in there, but it does have moments of hope.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/08/2012 03:42 PM, Invisible wrote:
> As with any language, my WTF list:
Enums. Urgh. An enumeration is supposed to be a type that can only take
on the specified set of values. Except that in C#, an enumeration can
take on /any/ integer value. It's just that some of these values also
have friendly names. *sigh*
What, no bitfield type? :-P
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 15.08.2012 09:56, schrieb Invisible:
>> Hint: There's more to Unicode than just ~1 million code points with
>> glyphs mapped to some of them.
>
> Sure. But if you can't even /write down/ those code-points, that's kinda
> limiting.
>
> (It also strikes me that if the String type /can/ hold them all and Char
> /can't/, that has interesting implications for trying to iterate over a
> String one Char at a time...)
As soon as you think of combining diacritics, you'll see that this type
of limitation is actually inevitable, even with a way to hold any
code-point value in a char: You can, for instance, hold the canonical
representation of Lowercase A + Acute Accent in a char (because it has a
dedicated code point, U+00E1), but you can't do the same with the
canonical representation of Lowercase A + Double Acute Accent (because
that's the sequence U+0061 U+030B) - or with the non-canonical
representation of A + Acute Accent, for that matter (U+0061 U+0301).
>>> Pop quiz: if x is a string and y is a delegate, does it do delegate
>>> concatenation or string concatenation?
>>
>> Provided it doesn't raise an error, obviously you'll get string
>> concatenation,
>
> Yes.
>
>> because you can't convert strings to delegates.
>
> No.
>
> From what I can tell, it never tries to convert a string to anything
> else, but it /does/ try to convert anything else to a string.
Yes, exactly.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Am 15.08.2012 11:46, schrieb Invisible:
> On 14/08/2012 03:42 PM, Invisible wrote:
>
>> - The "char" type works with Unicode. Well done. Oh, but wait... It only
>> stores 16 bits, and yet Unicode actually requires 24 bits to represent a
>> single code-point. So this "Unicode character" only actually covers the
>> Basic Multilingual Plane. FAIL!
>
> Oh great. Apparently "char" doesn't store a code-point at all, it stores
> a code-unit.
>
> For anything in the BMP, these are effectively the same thing. For
> anything outside that range, *you* must manually write the code to
> decode UTF-16 into actual code-points (which then do not fit into a
> "char").
Uh... why does this come as a surprise to you?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |