Off-Topic: Quake II Ported to HTML5

I haven’t used Delphi since version 7, so my information may be dated
(and possibly not entirely accurate). I do remember that using Delphi
was the single most painful experience in my programming career. As I
recall, the main issues were:

  • Manual memory management. W. T. F?
  • Pointer types needing to be named before they are used. WTF?
  • Variables declared at the top of a function instead of at the point
    where they are used.
  • Little or no metaprogramming facilities.
  • In general, simple tasks being needlessly complicated.

These are just complaints when comparing Delphi to C++. A truly modern
language will have to do better than C++.On 4/7/2010 17:27, Mason Wheeler wrote:

I can’t say much about Java, C# or D, but why doesn’t Delphi qualify?


Rainer Deyke - rainerd at eldwood.com

D, a statically typed language, can do the same thing at compile time.
IRRC, the syntax looks like this:

class C {
void opDispatch(string methodName)(int arg) {
// Note ‘methodName’ is a compile-time constant.
writefln("%s called with arg %d", methodName, arg);
}
}

void f() {
c = new C();
c.f(5); // Calls opDispatch.
}On 4/7/2010 17:28, David Olofson wrote:

On Thursday 08 April 2010, at 01.02.14, Bill Kelly wrote:

But, like Smalltalk (messageNotUnderstood), Ruby provides a
hook to handle messages sent to a class for which no existing
method can be found to respond to the message. (method_missing)

Now, that’s real interesting…!


Rainer Deyke - rainerd at eldwood.com

I think any modern statically-typed language needs to include at least
some level of type inference. There is no reason why a statically typed
language would require /any/ type declarations.On 4/7/2010 18:40, Bill Kelly wrote:

Whereas, cluttering a dynamic language across the board with
type declarations for the purpose of catching a certain category
of mistakes at compile time, is not a trade-off I would find
appealing.


Rainer Deyke - rainerd at eldwood.com

I haven’t used Delphi since version 7, so my information may be dated
(and possibly not entirely accurate). I do remember that using Delphi
was the single most painful experience in my programming career. As I
recall, the main issues were:

  • Manual memory management. W. T. F?

Yes, and it does it a lot better job of it than C/C++. Honestly, I don’t see
why so many people are so afraid of manual memory management, unless
of course their only experience with it is in C++. (That could traumatize
pretty much anyone.) But it means no memory or thread overhead from a
garbage collector GC, and with the new FastMM memory manager
(introduced since the D7 days) allocations and frees are very, very fast
and fragmentation is almost nonexistent, which means the supposed
performance gains of compacting GC don’t really add up to much.

  • Pointer types needing to be named before they are used. WTF?

Umm… no they don’t. You can declare a variable as a pointer to a
type without needing a name for the pointer type.

  • Variables declared at the top of a function instead of at the point
    where they are used.

…which makes them a lot easier to find since they’re in a known
location.

  • Little or no metaprogramming facilities.

I’d answer this one, but I don’t really know what you mean by
metaprogramming. It means different things in different contexts.
Care to elaborate? (And if you’re talking about generics, Delphi
didn’t have them in D7, but it does now.)

  • In general, simple tasks being needlessly complicated.

That’s very general and hard to answer. All I can say is that I’ve
never personally found anything that’s less complicated in C++
than it is in Delphi. Quite the opposite, most of the time.

These are just complaints when comparing Delphi to C++. A truly modern
language will have to do better than C++.

You apparently have a much higher opinion of C++ than I do. I
tend to regard it as “not necessarily the worst language ever
created, but definitely the worst ever to be taken seriously.”>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

Whereas, cluttering a dynamic language across the board with
type declarations for the purpose of catching a certain category
of mistakes at compile time, is not a trade-off I would find
appealing.

I think any modern statically-typed language needs to include at least
some level of type inference. There is no reason why a statically typed
language would require /any/ type declarations.

Again, because the types are there to make the code easier for us to
understand. Maybe you don’t need any type declarations when you’re
writing it and everything’s fresh in your mind, but try coming back to it
a year or two later. You look it over and you have no idea what any
of the variables represent!

Some degree of type inference /almost/ makes sense for primitives
(“OK, this is definitely a string, and this parameter is a number… is it an
integer or a float? Hard to tell; it’s only assigning integers here, but
that doesn’t prove anything…”) but when you start working with objects
that have properties and methods and polymorphism, type declarations
are essential for the coder’s sanity.>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5
On 4/7/2010 18:40, Bill Kelly wrote:

Rainer Deyke wrote:

Reflecting on a couple decades of programming in C and about
half that for C++ , I still find it hard to pin down or quantify
precisely why i feel more productive in dynamic languages.

I don’t think it’s any great mystery. You’re comparing modern languages
with C (which barely more high level than assembly) and C++ (which is
powerful but incredibly arcane).

What I mean is, my attempts at explaining this non-mystery rarely
have seemed to persuade anyone who is emotionally or philosophically
attached to static-typing-as-key-mechanism-to-catch-mistakes-at-
compile-time.

I have the same problem. Unless the people have experienced on their on the
benefits
their will rarely understand them.

Once I saw a comment on a Lisp book, that was very interesting. “If you
program in Basic
all your life, how can you know what you are missing?”

I tend to defend polyglot programming, use the better tool for the job. In
ever other profession,
people use different sets of tools, why should computing be any different?On Thu, Apr 8, 2010 at 2:40 AM, Bill Kelly wrote:

On 4/7/2010 17:02, Bill Kelly wrote:


Paulo

I haven’t used Delphi since version 7, so my information may be dated
(and possibly not entirely accurate). I do remember that using Delphi
was the single most painful experience in my programming career. As I
recall, the main issues were:

  • Manual memory management. W. T. F?

Yes, and it does it a lot better job of it than C/C++. Honestly, I don’t
see
why so many people are so afraid of manual memory management, unless
of course their only experience with it is in C++. (That could traumatize
pretty much anyone.) But it means no memory or thread overhead from a
garbage collector GC, and with the new FastMM memory manager
(introduced since the D7 days) allocations and frees are very, very fast
and fragmentation is almost nonexistent, which means the supposed
performance gains of compacting GC don’t really add up to much.

What about loosing track who is the real owner of a given pointer?

This is specially an issue in projects developed in multi sites (> 300
developers) across the
globe with many contractors coming in and out of the project. This is a
typical setup of many
big projects.

  • Little or no metaprogramming facilities.

I’d answer this one, but I don’t really know what you mean by
metaprogramming. It means different things in different contexts.
Care to elaborate? (And if you’re talking about generics, Delphi
didn’t have them in D7, but it does now.)

Metaprogramming is the ability to modify the code on the fly. To manipulate
code as if it was data. This is a very powerful concept and allows for very
neat
abstractions.

On C++ case, template metaprogramming is what allows the implementation of
numeric libraries that can outperform Fortran optimized ones, like Blitz++.

In case you aren’t aware, the memory model of C and C++ don’t allow the
usage
of certain optimization algorithms, and this is one of the reasons why
Fortran code
can outperform C for numerical computing stuff.On Thu, Apr 8, 2010 at 5:37 AM, Mason Wheeler wrote:

----- Original Message ----
From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5


Paulo

  • Manual memory management. W. T. F?

Yes,

And that automatically disqualifies it as a modern language, full stop.

and it does it a lot better job of it than C

Care to elaborate?

The way I see it, all manual memory management is equal. You manually
call some function (or use some other facility) to release your memory.
You can encapsulate the call in some other function, but you can’t
eliminate it.

/C++.

C++ does not require manual memory management. Allows it, sure. That’s
not a drawback.

  • Pointer types needing to be named before they are used. WTF?

Umm… no they don’t. You can declare a variable as a pointer to a
type without needing a name for the pointer type.

As I recall (and my memory could be faulty), type equivalence is by
name, not structure. Sure, you can declare a variable as a pointer,
but it won’t be assignment-compatible with any other pointers declared
elsewhere, which makes the functionality useless.

  • Variables declared at the top of a function instead of at the point
    where they are used.

…which makes them a lot easier to find since they’re in a known
location.

It’s useless extra typing, which is the main problem with the "classic"
statically typed languages that the dynamic languages have managed to
fix. Compare:

Python:

def f():
x = g()
h(x)

Pascal:

procedure f;
var x: Integer;
begin
x = g();
h(x);
end;

The Pascal version uses fully twice as many lines of code, and they’re
longer too.

  • Little or no metaprogramming facilities.

I’d answer this one, but I don’t really know what you mean by
metaprogramming. It means different things in different contexts.
Care to elaborate? (And if you’re talking about generics, Delphi
didn’t have them in D7, but it does now.)

You have to write N similar function/classes/records according to some
pattern. Does the language force you to write them individually by
hand, or is there a way to generate them automatically from the pattern?

Generics are just the beginning.On 4/7/2010 21:37, Mason Wheeler wrote:

----- Original Message ----
From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5


Rainer Deyke - rainerd at eldwood.com

I think any modern statically-typed language needs to include at least
some level of type inference. There is no reason why a statically typed
language would require /any/ type declarations.

Again, because the types are there to make the code easier for us to
understand. Maybe you don’t need any type declarations when you’re
writing it and everything’s fresh in your mind, but try coming back to it
a year or two later. You look it over and you have no idea what any
of the variables represent!

Some degree of type inference /almost/ makes sense for primitives
(“OK, this is definitely a string, and this parameter is a number… is it an
integer or a float? Hard to tell; it’s only assigning integers here, but
that doesn’t prove anything…”) but when you start working with objects
that have properties and methods and polymorphism, type declarations
are essential for the coder’s sanity.

I think there’s definitely a place for type declaration where they help
to clarify, which is somewhere between “occasionally” and “rarely”.
Type declarations should be optional, not eliminated entirely.

Examples where type declarations would be just a waste of space
(pseudo-code):

foo = new Foo();
// Whatever could the type of ‘foo’ be? Maybe ‘Foo’?

def max(x, y):
return x > y ? x : y;
// What’s the type of ‘x’ and ‘y’? Trick question; the function
// works for a wide range of types. What’s the return type? I don’t
// know, maybe the common type of ‘x’ and ‘y’? Not so hard, is it?

def call_logged(f, args):
rv = f(args);
log(“Function finished, returning %s.”, rv);
return rv;
// I don’t know the type of ‘rv’. I also don’t care.On 4/7/2010 21:42, Mason Wheeler wrote:

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5


Rainer Deyke - rainerd at eldwood.com

  • Manual memory management. W. T. F?

Yes,

And that automatically disqualifies it as a modern language, full stop.

That sentiment pretty well sums up a huge part of what’s wrong with
modern programming. People think that important tasks ought to be
done for them instead of learning how to do them right, so they take
what should be their own responsibility and hand it off to some
bloated library that’s not capable of doing it correctly. Anyone who
can’t manage memory themselves is incompetent, pure and simple,
and anyone who can but chooses not to for tasks more complicated
than scripts is a jerk who’s wasting my system resources. There’s
no good reason why half the programs on my computer should use
anywhere near as much RAM as they do, if only the people who
wrote them had some idea as to how to do it right.

and it does it a lot better job of it than C

Care to elaborate?

The way I see it, all manual memory management is equal. You manually
call some function (or use some other facility) to release your memory.
You can encapsulate the call in some other function, but you can’t
eliminate it.

All memory management is manual anyway. In a garbage-collected
program, you still have to do certain things and write your code in certain
ways, specifically to make sure that some references end up being
unreachable so the GC can clean them up. The only difference is that
in a GC’d language, there’s no Free command, which means that even if
you do correctly make a reference unreachable, the object it refers to is
still sitting around using up memory and bloating your program’s footprint
until the GC gets around to cleaning it up, whenever that may be.

/C++.

C++ does not require manual memory management. Allows it, sure. That’s
not a drawback.

What do you mean by that? Sure, you can encapsulate it in some other
function (smart pointers, for example), but you can’t eliminate it.

  • Pointer types needing to be named before they are used. WTF?

Umm… no they don’t. You can declare a variable as a pointer to a
type without needing a name for the pointer type.

As I recall (and my memory could be faulty), type equivalence is by
name, not structure. Sure, you can declare a variable as a pointer,
but it won’t be assignment-compatible with any other pointers declared
elsewhere, which makes the functionality useless.

Depends on the compiler settings. You’re kind of close, but it’s nowhere
near as strict as you make it out to be. And even if it was, that doesn’t
make the functionality useless. The standard idiom is to declare a named
pointer type right next to the declaration of the record it points to, so that
any code that uses the unit with the record declaration gets the pointer
declaration as well, and there’s no confusion.

But why are you using pointers in the first place? That’s generally
considered bad form, unless you have to interface with libraries written
in C or something like that.

  • Variables declared at the top of a function instead of at the point
    where they are used.

…which makes them a lot easier to find since they’re in a known
location.

It’s useless extra typing, which is the main problem with the "classic"
statically typed languages that the dynamic languages have managed to
fix. Compare:

Python:

def f():
x = g()
h(x)

Pascal:

procedure f;
var x: Integer;
begin
x = g();
h(x);
end;

The Pascal version uses fully twice as many lines of code, and they’re
longer too.

Mmhmm. But there’s a good reason for it. In Python, you could do that,
and call g(), which returns a dictionary, and pass the result to h(), which
expects a number. In Pascal, the compiler makes sure you don’t do that.
BTW why not just write it like this?

procedure f;
begin
h(g());
end;

  • Little or no metaprogramming facilities.

I’d answer this one, but I don’t really know what you mean by
metaprogramming. It means different things in different contexts.
Care to elaborate? (And if you’re talking about generics, Delphi
didn’t have them in D7, but it does now.)

You have to write N similar function/classes/records according to some
pattern. Does the language force you to write them individually by
hand, or is there a way to generate them automatically from the pattern?

Generics are just the beginning.

Delphi 2009 introduced generics and anonymous methods (closures), which
allows for some very interesting metaprogramming, especially when you mix
the two and create anonymous methods with generic type parameters. And
D2010 added some extremely rich RTTI (reflection) support, which makes
it possible to genericize certain tasks even further. The development team
is working pretty hard on this, and I’m pretty sure they’ll have even more
cool stuff to play with in this area for D2011, when it comes out.>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

I think there’s definitely a place for type declaration where they help
to clarify, which is somewhere between “occasionally” and “rarely”.
Type declarations should be optional, not eliminated entirely.

Examples where type declarations would be just a waste of space
(pseudo-code):

foo = new Foo();
// Whatever could the type of ‘foo’ be? Maybe ‘Foo’?

Maybe. On a side note, this is a prime example of why case
sensitivity is evil. Anyone who writes code like that, (or declares
HWND hwnd, like I see in SDL a few places) ought to be taken
out and shot. Repeatedly.

def max(x, y):
return x > y ? x : y;
// What’s the type of ‘x’ and ‘y’? Trick question; the function
// works for a wide range of types. What’s the return type? I don’t
// know, maybe the common type of ‘x’ and ‘y’? Not so hard, is it?

This means that you can’t tell what the return type of a function is just
by looking at its interface. It’s a serious problem in Python. So much
for abstraction and encapsulation, or design by contract…

def call_logged(f, args):
rv = f(args);
log(“Function finished, returning %s.”, rv);
return rv;
// I don’t know the type of ‘rv’. I also don’t care.

Your format string indicates that rv is a string, or something that can
be implicitly converted to a string. And it had better be, or you end
up with a runtime error. But since you can’t check the return type
of f() without looking through its code, (and potentially the code of
every routine it calls as well, and so on,) have fun verifying that.
Heaven help you if you pass it a function pointer (of indeterminate
return type, of course) that it calls for its result!>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

I’m sorry Mason! Don’t shoot me! :slight_smile:

Jonny DOn Thu, Apr 8, 2010 at 5:06 AM, Mason Wheeler wrote:

----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

I think there’s definitely a place for type declaration where they help
to clarify, which is somewhere between “occasionally” and “rarely”.
Type declarations should be optional, not eliminated entirely.

Examples where type declarations would be just a waste of space
(pseudo-code):

foo = new Foo();
// Whatever could the type of ‘foo’ be? Maybe ‘Foo’?

Maybe. On a side note, this is a prime example of why case
sensitivity is evil. Anyone who writes code like that, (or declares
HWND hwnd, like I see in SDL a few places) ought to be taken
out and shot. Repeatedly.

def max(x, y):
return x > y ? x : y;
// What’s the type of ‘x’ and ‘y’? Trick question; the function
// works for a wide range of types. What’s the return type? I don’t
// know, maybe the common type of ‘x’ and ‘y’? Not so hard, is it?

This means that you can’t tell what the return type of a function is just
by looking at its interface. It’s a serious problem in Python. So much
for abstraction and encapsulation, or design by contract…

def call_logged(f, args):
rv = f(args);
log(“Function finished, returning %s.”, rv);
return rv;
// I don’t know the type of ‘rv’. I also don’t care.

Your format string indicates that rv is a string, or something that can
be implicitly converted to a string. And it had better be, or you end
up with a runtime error. But since you can’t check the return type
of f() without looking through its code, (and potentially the code of
every routine it calls as well, and so on,) have fun verifying that.
Heaven help you if you pass it a function pointer (of indeterminate
return type, of course) that it calls for its result!


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Delphi 2009 introduced generics and anonymous methods (closures), which
allows for some very interesting metaprogramming, especially when you mix
the two and create anonymous methods with generic type parameters. And
D2010 added some extremely rich RTTI (reflection) support, which makes
it possible to genericize certain tasks even further. The development team
is working pretty hard on this, and I’m pretty sure they’ll have even more
cool stuff to play with in this area for D2011, when it comes out.

Available only on Windows…

Pascal related languages have a speciall place on my heart, specially
because Turbo Pascal
and Delphi were my main languages on the MS-DOS/Windows 3.x days, but
nowadays I wonder
if it is still significant.

I think that the world would have been a better place if the Pascal family
have won the hearts of developers,
because had it been the case, we would have much more productive
environments not riddled with pointer
errors and buffer overflows.

But besides Borland/Code Gear/Embarcadero no one else seems to bother. Here
in Europe all Delphi based
consultancy projects are legacy work, the new projects are done in Java/.Net
environments. This leads to our
higher level language discussions, plus the hybrid static/native solutions
that these runtimes do offer.On Thu, Apr 8, 2010 at 1:56 PM, Mason Wheeler wrote:


Paulo

Delphi 2009 introduced generics and anonymous methods (closures), which
allows for some very interesting metaprogramming, especially when you mix
the two and create anonymous methods with generic type parameters. And
D2010 added some extremely rich RTTI (reflection) support, which makes
it possible to genericize certain tasks even further. The development team
is working pretty hard on this, and I’m pretty sure they’ll have even more
cool stuff to play with in this area for D2011, when it comes out.

Available only on Windows…

For the moment. Delphi 2011 (due out later this year; apparently someone at Embarcadero thought car model year numbering would make it cooler) will be cross-platform.

Pascal related languages have a speciall place on my heart, specially because Turbo Pascal
and Delphi were my main languages on the MS-DOS/Windows 3.x days, but nowadays I wonder
if it is still significant.

That’s a very legitimate concern. Borland screwed up repeatedly in its handling of the language, and we’re all still suffering for that. But Embarcadero is taking its development very seriously and things are really getting back on track.

Also, http://www.IsDelphiDead.com/

I think that the world would have been a better place if the Pascal family have won the hearts of developers,
because had it been the case, we would have much more productive environments not riddled with pointer
errors and buffer overflows.

Oh, definitely. The C family is guilty of a whole lot of stuff, but probably its most grievous sin is not producing crappy code, but making people think that that’s supposed to be normal!

But besides Borland/Code Gear/Embarcadero no one else seems to bother. Here in Europe all Delphi based
consultancy projects are legacy work, the new projects are done in Java/.Net environments. This leads to our
higher level language discussions, plus the hybrid static/native solutions that these runtimes do offer.

Oh, definitely not all of them. The Delphi community’s pretty strong in Europe, probably stronger than it is in the US. I recently got an invitation to submit papers for a Delphi-themed programming conference in Germany. Still mulling that one over. It might be fun, but the whole “ich spreche kein deutch” (sp?) thing has me a bit nervous. (Too bad it’s not in Spain!) :PFrom: pjmlp@progtools.org (Paulo Pinto)
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5
On Thu, Apr 8, 2010 at 1:56 PM, Mason Wheeler <@Mason_Wheeler> wrote:

What about loosing track who is the real owner of a given pointer?

This is specially an issue in projects developed in multi sites (> 300 developers) across the
globe with many contractors coming in and out of the project. This is a typical setup of many
big projects.

It’s pretty easy to keep track of who owns what by not transferring ownership unless it’s absolutely necessary. If you need to use shared ownership, Delphi provides interfaced objects with reference-counting to make it safe. And if memory does get leaked, or an object gets double-freed or used after it was destroyed, the FastMM memory manager has built-in facilities for detecting this and reporting it to you, with a full stack trace if you want, making such issues trivial to track down and fix.

http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple>From: Paulo Pinto

Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

  • Manual memory management. W. T. F?

Yes,

And that automatically disqualifies it as a modern language, full stop.

That sentiment pretty well sums up a huge part of what’s wrong with
modern programming. People think that important tasks ought to be
done for them instead of learning how to do them right, so they take
what should be their own responsibility and hand it off to some
bloated library that’s not capable of doing it correctly.

We’re talking about /memory management/. The following is a very common
idiom, perhaps the most common resource management idiom:

x = alloc_resource()

free_resource(x)
// End of block.

It’s also a stupid idiom because it clutters the code. This following
is much better:

x = alloc_resource()

// End of block - ‘x’ is automatically freed.

Why shouldn’t this be automated? It’s an absolutely trivial task!
There is no way a language facility could mess this up! If you can’t
trust your compiler to produce optimal code in this case, then you can’t
trust your compiler at all.

Now, if you want to free ‘x’ before the end of the block - fine, do
that. Nobody’s stopping you. But the case where ‘x’ is freed at the
end of the block is common enough to deserve special treatment.

What do you mean by that? Sure, you can encapsulate it in some other
function (smart pointers, for example), but you can’t eliminate it.

I mean this:
{
some_ptr p = create();
} // Resource automatically freed at end of scope.

Programming is the process of automating tasks. You don’t want to
create machine code from hand, so you write a compiler to do it for you.
You don’t want to insert the algorithm for calculating the square root
a dozen times in your program, so you write a function to calculate the
square root for you and call that function a dozen times. You don’t
want to write a dozen allocate/free pairs in your program, so you write
a RAII type that automatically frees the resource for you.

The question isn’t if the language automates the task. The question is
if the language gives you the facilities to automate the task.

As I recall (and my memory could be faulty), type equivalence is by
name, not structure. Sure, you can declare a variable as a pointer,
but it won’t be assignment-compatible with any other pointers declared
elsewhere, which makes the functionality useless.

Depends on the compiler settings. You’re kind of close, but it’s nowhere
near as strict as you make it out to be. And even if it was, that doesn’t
make the functionality useless. The standard idiom is to declare a named
pointer type right next to the declaration of the record it points to, so that
any code that uses the unit with the record declaration gets the pointer
declaration as well, and there’s no confusion.

More useless typing. Even more useless typing if you want a pointer to
a pointer, or a pointer to an array, or an array of pointers, or a
pointer to an array of pointers, etc…

But why are you using pointers in the first place? That’s generally
considered bad form, unless you have to interface with libraries written
in C or something like that.

I was modifying a program that uses pointers. Nothing in the world
could convince me to start a program in Delphi from scratch.

It’s useless extra typing, which is the main problem with the "classic"
statically typed languages that the dynamic languages have managed to
fix. Compare:

Python:

def f():
x = g()
h(x)

Pascal:

procedure f;
var x: Integer;
begin
x = g();
h(x);
end;

The Pascal version uses fully twice as many lines of code, and they’re
longer too.

Mmhmm. But there’s a good reason for it. In Python, you could do that,
and call g(), which returns a dictionary, and pass the result to h(), which
expects a number. In Pascal, the compiler makes sure you don’t do that.

Do you see me advocating dynamic typing anywhere? Here is the
equivalent in D:

void f() {
auto x = f();
g(x);
}

It’s larger than the Python version, but much smaller than the Pascal
version. It’s also statically typed.

BTW why not just write it like this?

procedure f;
begin
h(g());
end;

Because it’s a minimal example meant to demonstrate something, not an
actual piece of code.On 4/8/2010 05:56, Mason Wheeler wrote:

----- Original Message ----
From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5


Rainer Deyke - rainerd at eldwood.com

def max(x, y):
return x > y ? x : y;
// What’s the type of ‘x’ and ‘y’? Trick question; the function
// works for a wide range of types. What’s the return type? I don’t
// know, maybe the common type of ‘x’ and ‘y’? Not so hard, is it?

This means that you can’t tell what the return type of a function is just
by looking at its interface. It’s a serious problem in Python. So much
for abstraction and encapsulation, or design by contract…

If you understand what the function does, you know its return type. If
you don’t understand what the function does, maybe you shouldn’t be
using it at all.

def call_logged(f, args):
rv = f(args);
log(“Function finished, returning %s.”, rv);
return rv;
// I don’t know the type of ‘rv’. I also don’t care.

Your format string indicates that rv is a string, or something that can
be implicitly converted to a string.

Actually it just requires that ‘rv’ can be streamed, but close enough.

And it had better be, or you end
up with a runtime error.

Nope, it’s checked at compile time.On 4/8/2010 06:06, Mason Wheeler wrote:

----- Original Message ----
From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5


Rainer Deyke - rainerd at eldwood.com

The following is a very common idiom, perhaps the most
common resource management idiom:

x = alloc_resource()

free_resource(x)
// End of block.

It’s also a stupid idiom because it clutters the code. This following
is much better:

x = alloc_resource()

// End of block - ‘x’ is automatically freed.

Why shouldn’t this be automated? It’s an absolutely trivial task!
There is no way a language facility could mess this up!

x = construct_object()
ObjectContainer.Add(x)

//End of block - ‘x’ is automatically… oops!

If you can’t trust your compiler to produce optimal code in this
case, then you can’t trust your compiler at all.

Nope. I just gave a trivial example that can break any compiler’s
ability to keep track of it. In fact, if you pass an object reference
as a parameter to any function, the task the compiler has to
perform to figure out whether or not it’s safe to destroy the object
after the function returns can easily become equivalent to the
Halting Problem. It’s something you just can’t automate.

Now, if you want to free ‘x’ before the end of the block - fine, do
that. Nobody’s stopping you. But the case where ‘x’ is freed at the
end of the block is common enough to deserve special treatment.

What do you mean by that? Sure, you can encapsulate it in some other
function (smart pointers, for example), but you can’t eliminate it.

I mean this:
{
some_ptr p = create();
} // Resource automatically freed at end of scope.

Programming is the process of automating tasks. You don’t want to
create machine code from hand, so you write a compiler to do it for you.
You don’t want to insert the algorithm for calculating the square root
a dozen times in your program, so you write a function to calculate the
square root for you and call that function a dozen times. You don’t
want to write a dozen allocate/free pairs in your program, so you write
a RAII type that automatically frees the resource for you.

The question isn’t if the language automates the task. The question is
if the language gives you the facilities to automate the task.

Well, I don’t like RAII. I think it’s a fundamentally flawed pattern that only
got invented at all because the C++ object model is badly flawed. But
if you simply can’t live without it, Barry Kelly (the Delphi compiler chief)
went and created a smart pointer implementation based on Delphi’s
Generics. So yes, the language does give you the facility to automate
it.

http://blog.barrkel.com/2008/09/smart-pointers-in-delphi.html

Depends on the compiler settings. You’re kind of close, but it’s nowhere
near as strict as you make it out to be. And even if it was, that doesn’t
make the functionality useless. The standard idiom is to declare a named
pointer type right next to the declaration of the record it points to, so that
any code that uses the unit with the record declaration gets the pointer
declaration as well, and there’s no confusion.

More useless typing. Even more useless typing if you want a pointer to
a pointer, or a pointer to an array, or an array of pointers, or a
pointer to an array of pointers, etc…

I’m sorry, but that’s extremely vague and sounds more like ranting than
anything useful. How is writing out information that makes a program
easier to read when you come back to it (or when someone else has
to maintain it) “useless”?

But why are you using pointers in the first place? That’s generally
considered bad form, unless you have to interface with libraries written
in C or something like that.

I was modifying a program that uses pointers. Nothing in the world
could convince me to start a program in Delphi from scratch.

Aha! Now it all begins to make sense. You had a bad experience in
Delphi because you were working with a bad Delphi program. You
ought to blame the original author, though, not the language. There’s
no language I’ve ever heard of that makes it any harder to write crap
in. Incompetent code monkeys can write crap in any language. But
Delphi’s strength is that, even though it doesn’t make writing bad code
harder, it does make writing good code easier. (And it definitely
makes reading good code easier. You can’t say that about anything
from the C family.)>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

def max(x, y):
return x > y ? x : y;
// What’s the type of ‘x’ and ‘y’? Trick question; the function
// works for a wide range of types. What’s the return type? I don’t
// know, maybe the common type of ‘x’ and ‘y’? Not so hard, is it?

This means that you can’t tell what the return type of a function is just
by looking at its interface. It’s a serious problem in Python. So much
for abstraction and encapsulation, or design by contract…

If you understand what the function does, you know its return type. If
you don’t understand what the function does, maybe you shouldn’t be
using it at all.

You’re still thinking like a code writer and not a code reader. Of course
you understand what the function does when you create it! But what if I
created it a year ago, then I went and took another job somewhere else,
and you get a CR to fix a bug that eventually takes you into the routine,
and you’ve never seen it before. Don’t you want as much explicit
information presented to you as possible, to aid you in figuring out what
this function is doing? With real code these days now spending more
than 60% of its life cycle in maintenance, not development, you’re
approaching this from a very counterproductive paradigm.

I think that’s the biggest sin of modern ultra-high-level languages:
promoting the dangerous fantasy that the ability to create code quickly
is good, important and desirable. That sounds nice in theory, but in
the real world the ability to read code, to easily figure out its meaning,
and to catch errors as early as possible are all much more important,
and writing code quickly usually comes at the expense of one or more
of these three.>----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

This is what unit tests are for.

I won’t allow anyone on my projects to avoid writing unit tests.

Don’t you know what a function does? Look at the unit test.

What you say might be true for legacy code, but for new code, all code
should be tested.

Even better, follow TDD principles, only write code that is also tested.–
Paulo

On Thu, Apr 8, 2010 at 11:27 PM, Mason Wheeler wrote:

----- Original Message ----

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5

From: Rainer Deyke
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5
def max(x, y):
return x > y ? x : y;
// What’s the type of ‘x’ and ‘y’? Trick question; the function
// works for a wide range of types. What’s the return type? I don’t
// know, maybe the common type of ‘x’ and ‘y’? Not so hard, is it?

This means that you can’t tell what the return type of a function is
just

by looking at its interface. It’s a serious problem in Python. So much
for abstraction and encapsulation, or design by contract…

If you understand what the function does, you know its return type. If
you don’t understand what the function does, maybe you shouldn’t be
using it at all.

You’re still thinking like a code writer and not a code reader. Of course
you understand what the function does when you create it! But what if I
created it a year ago, then I went and took another job somewhere else,
and you get a CR to fix a bug that eventually takes you into the routine,
and you’ve never seen it before. Don’t you want as much explicit
information presented to you as possible, to aid you in figuring out what
this function is doing? With real code these days now spending more
than 60% of its life cycle in maintenance, not development, you’re
approaching this from a very counterproductive paradigm.

I think that’s the biggest sin of modern ultra-high-level languages:
promoting the dangerous fantasy that the ability to create code quickly
is good, important and desirable. That sounds nice in theory, but in
the real world the ability to read code, to easily figure out its meaning,
and to catch errors as early as possible are all much more important,
and writing code quickly usually comes at the expense of one or more
of these three.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org