Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.misc > #2037 > unrolled thread

Wirth-ian languages

Started bybruce axtens <bugmagnet@outlook.com>
First post2014-04-28 16:23 +0000
Last post2014-04-29 05:37 -0700
Articles 14 on this page of 34 — 9 participants

Back to article view | Back to comp.lang.misc


Contents

  Wirth-ian languages bruce axtens <bugmagnet@outlook.com> - 2014-04-28 16:23 +0000
    Re: Wirth-ian languages Joe Hynes <theda@southpark.net> - 2014-04-28 17:31 +0000
      Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-04-28 18:47 +0000
        Re: Wirth-ian languages "BartC" <bc@freeuk.com> - 2014-04-28 20:35 +0100
          Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-04-28 20:18 +0000
            Re: Wirth-ian languages "James Harris" <james.harris.1@gmail.com> - 2014-04-28 22:50 +0100
              Re: Wirth-ian languages "BartC" <bc@freeuk.com> - 2014-04-29 00:03 +0100
                Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-04-28 23:51 +0000
                Re: Wirth-ian languages "James Harris" <james.harris.1@gmail.com> - 2014-04-29 07:59 +0100
                  Re: Wirth-ian languages "BartC" <bc@freeuk.com> - 2014-04-29 10:04 +0100
                    Re: Wirth-ian languages "James Harris" <james.harris.1@gmail.com> - 2014-04-29 11:33 +0100
                      Re: Wirth-ian languages "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-29 07:41 -0400
              Re: Wirth-ian languages "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-28 21:46 -0400
                Re: Wirth-ian languages "James Harris" <james.harris.1@gmail.com> - 2014-04-29 08:24 +0100
                  Re: Wirth-ian languages "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-29 07:33 -0400
                    Re: Wirth-ian languages "James Harris" <james.harris.1@gmail.com> - 2014-04-29 14:38 +0100
                      Re: Wirth-ian languages "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-30 21:28 -0400
                        Re: Wirth-ian languages "James Harris" <james.harris.1@gmail.com> - 2014-05-01 10:44 +0100
                Re: Wirth-ian languages "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-04-29 09:59 +0200
                  Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-04-29 15:51 +0000
                    Re: Wirth-ian languages "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-04-30 10:57 +0200
                      Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-04-30 15:47 +0000
                        Re: Wirth-ian languages "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-01 10:18 +0200
                          Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-05-01 16:56 +0000
                            Re: Wirth-ian languages "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-02 10:10 +0200
                  Re: Wirth-ian languages "BartC" <bc@freeuk.com> - 2014-04-30 18:27 +0100
                    Re: Wirth-ian languages "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-01 10:18 +0200
                      Re: Wirth-ian languages Kaz Kylheku <kaz@kylheku.com> - 2014-05-01 17:10 +0000
                        Re: Wirth-ian languages "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2014-05-02 09:22 +0200
    Re: Wirth-ian languages "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-28 20:59 -0400
      Re: Wirth-ian languages "Rod Pemberton" <dont_use_email@xnothavet.cqm> - 2014-04-28 21:10 -0400
      Re: Wirth-ian languages Nils M Holm <news2009@t3x.org> - 2014-04-29 07:52 +0000
      Re: Wirth-ian languages "BartC" <bc@freeuk.com> - 2014-04-29 09:45 +0100
    Re: Wirth-ian languages Jacko <jackokring@gmail.com> - 2014-04-29 05:37 -0700

Page 2 of 2 — ← Prev page 1 [2]


#2072

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2014-04-30 10:57 +0200
Message-ID<1pqfweefeeeee$.1c1g5eqx3n1ph.dlg@40tude.net>
In reply to#2066
On Tue, 29 Apr 2014 15:51:17 +0000 (UTC), Kaz Kylheku wrote:

> On 2014-04-29, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On Mon, 28 Apr 2014 21:46:00 -0400, Rod Pemberton wrote:
>>
>>> So, let's list some (what I recall right now...) of what I think
>>> C gets correct:
>>> 
>>> 1) pointers
>>
>> Since C did almost everything wrong. I will comment only on pointers, which 
>> is also an easy game. What is wrong with them:
>>
>> 1. Pointer types are improperly typed as they are matched by structure. 
>> Thus you cannot have two distinct pointer types for the same target type. 
>> The feature extremely important for building sorted containers and custom 
>> memory pools.
> 
> "Extremely" is a hyperbole, since people have developed these things in C
> without even so much a fleeting thought such as "I could use pointer type names
> based on name equivalence".

It is not about Turing-completeness of C, it is about pointer design. Yes,
people don't even aware of a possibility to automatically select the memory
pool based on the pointer type. Not possible, per wrong design.

> Any decent C compiler has a warnings for uninitialized locals,

Record fields, dynamically allocated objects?

Anyway, it is a halting problem. Trivially:

   int x;
   int * y;

   if (HALT (p)) y = &x;

So any such check must necessarily generate false negatives or false
positives.

And it is not in C programming culture to pay much attention to silly
compiler warnings, anyway.

> and any decent
> C programmer investigates what diagnostic options are available, and uses
> all of them that aren't nuisance stylistic warnings.

A little problem is that "decent C programmers" according this definition
probably don't exist. It is extremely difficult to hire a good C
programmer.

Anyway, a precaution that can be done by compiler but left to the
programmer is a language design fault, which C pointers are. 

>> 4. Pointer arithmetic is a low level hack which should not be there, 
>> because it does not make any sense for variable sized targets or advanced 
>> structures like graphs and trees.
> 
> Pointer arithmetic is necessary for managing variable-sized targets,
> like records that have multiple variant fields, all in the same linear
> memory block. These could be stuck into a graph structure.

No. If you need a pointer to the next element you don't have to compute it.
You just store it. Otherwise, see the position #1. If pointers were
properly designed as ADTs, there would be no problem to define arithmetic
on *some* of them as needed. Instead of that the language enforces blanket
garbage semantics on all of them. Which is a language design fault.
 
>> It also does not make sense on certain 
>> machine architecture which was and is a huge problem for ones with the 
>> machine word shorter than the physical memory space.
> 
> The demand for C toolchains killed those architectures, so that's not a problem
> any more.

So much for being "close to hardware"!
 
> This is not a "huge problem" in the world; on the contrary, it is a
> non-problem, now that cheap 64 bit machines are available to consumers.

Well, the balance between the cost of a CPU cycle vs. memory byte has
shifted towards CPU. It is difficult to say whether that will stay so. When
massively parallel architectures will arrive, the model of shared memory
will inevitable die. There is no way to share memory between thousands of
cores. This might shift the balance back, away from flat, isotropic memory
models...

>> 5. Confusing pointers with arrays is a huge problem that caused countless
>> issues throughout all life time of C. Recent example is OpenSSL.
> 
> No comment there. The tools and choice of tools and methods does deserve blame
> here.

Ah, but if you need tools on top of the language, that is a language fault
again. Tools is an answer to miserable languages we have to program in.

> What would constitute sufficient difficulty in the integer-pointer conversion?
> Sacrificing a goat for each instance?

Making meaningless conversions unnecessary?

> The code is not fragile and non-portable at the same time. Conversions between
> pointers and integers can be completely solid.
> 
> Example: the traditional return value of the POSIX function to indicate failure:
> -1 cast to (void *). (Nowadays hidden behind the symbol MAP_FAILURE).
> 
> Non portable it may be, but there isn't anything "fragile" about it.
> Fragility would be demonstrated by breaking, and that would just add up to
> non-portability.

Fragility is when small changes lead to heavy distributed maintenance
overhead in the client code base.

>> 7. Each object in C is assumed to be addressable, i.e. the &-operation is 
>> defined on each object.
> 
> Variables declared "register" cannot have this operation applied to them.
> 
> But even without this, the analysis is very easy for determining whether or not
> a declared object is subject to the & operator over its scope.

So, the program semantics and legality may depend on the outcome of
register optimization? That is again a language design fault.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#2078

FromKaz Kylheku <kaz@kylheku.com>
Date2014-04-30 15:47 +0000
Message-ID<20140430055029.933@kylheku.com>
In reply to#2072
On 2014-04-30, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> On Tue, 29 Apr 2014 15:51:17 +0000 (UTC), Kaz Kylheku wrote:
>
>> On 2014-04-29, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>>> On Mon, 28 Apr 2014 21:46:00 -0400, Rod Pemberton wrote:
>>>
>>>> So, let's list some (what I recall right now...) of what I think
>>>> C gets correct:
>>>> 
>>>> 1) pointers
>>>
>>> Since C did almost everything wrong. I will comment only on pointers, which 
>>> is also an easy game. What is wrong with them:
>>>
>>> 1. Pointer types are improperly typed as they are matched by structure. 
>>> Thus you cannot have two distinct pointer types for the same target type. 
>>> The feature extremely important for building sorted containers and custom 
>>> memory pools.
>> 
>> "Extremely" is a hyperbole, since people have developed these things in C
>> without even so much a fleeting thought such as "I could use pointer type names
>> based on name equivalence".
>
> It is not about Turing-completeness of C, it is about pointer design. Yes,
> people don't even aware of a possibility to automatically select the memory
> pool based on the pointer type. Not possible, per wrong design.

Indeed, C has very little compile-time polymorphism.

(The successor language C++ adds considerable compile-time polymorphism, while
maintaining strong backward compatibility. C++ hasn't completely succeeded in
displacing C.)

>> Any decent C compiler has a warnings for uninitialized locals,
>
> Record fields, dynamically allocated objects?

In C, an aggregate or struct field cannot be individually initialized, such
that others are left uninitialized.  If the object has an initializer, all
members are initialized.

The problem of partially initialized objects occurs when objects are
left uninitialized and then configured member by member.

  (This is, ironically, a big problem in C++, rather than C. In C++, when you
  define a constructor, that constructor takes all responsibility for
  initializing an object, and an atomic C-like initialization isn't possible.)

Dynamically allocated objects can be produced by a function that returns all
zero memory, like calloc, or your own wrapper for malloc.

   struct foo *p_dynamic_foo = calloc(sizeof *pf, 1);

   struct foo local_foo = { 0 }; /* all fields are initialized */

Another technique:

   static const struct foo blank_foo; /* "blank" static structure */

   struct foo *ptr = malloc(sizeof *pf);

   *ptr = blank; /* initialize allocated object by copying the blank */

(This two-step approach avoids relying on a pattern of a all-zero bits
producing 0.0 floating-point values and null pointers.)

> Anyway, it is a halting problem. Trivially:

A perfectly accurate diagnostic is not only equivalent to solving the Halting
problem, but it requires access to functions in external compilation units, and
knowledge whether the function in question is ever called, which could depend
on inputs to the program and events. In other words, it is in fact intractable.

The Halting Problem is primarily of academic importance; it requires that we
have a complete description of the entire program that is to be analyzed, and
its complete input.

But we do not need a perfectly accurate diagnostic for uninitialized variables
in the real world; a suspicion is enough.

>    int x;
>    int * y;
>
>    if (HALT (p)) y = &x;
>
> So any such check must necessarily generate false negatives or false
> positives.

If there is any suspicion that the variable is uninitialized, the case
can be made that it needs to be fixed. If a machine finds it hard to tell
whether the variable is uninitialized, a human being will also find it hard to
tell.

Even if HALT(p) (which is in a library somewhere) always returns true today,
so that the assignment always executes whenever this function is called,
someone could change the defnition of HALT so that it no longer always returns
true. When HALT changes, the above code does not get recompiled.

Generating a rational suspicion is easy; it doesn't require solving the Halting
Problem.  If it's obvious that the variable is used uninitialized, emit a
confident diagnostic. Otherwise if it is not obvious that the variable is
initialized, emit a "possibly uninitialized" warning. If your compiler is told
to treat warnings as errors, then the build fails.

There is no reason to have false negatives (neglect to identify suspicious cases).

When we fix the false positive with "int *y = NULL", we are at that point no
worse off than a language which forces this automatically, and we can still
leave variables uninitialized in cases that are obviously safe.

> And it is not in C programming culture to pay much attention to silly
> compiler warnings, anyway.

That is neither here nor there. Every language that has ever been popular has
had attracted the goofballs, and always will.  It is a social problem.

> Anyway, a precaution that can be done by compiler but left to the
> programmer is a language design fault, which C pointers are.

Not every precaution that can be done by the compiler *should* be done.

Static checking is bane of programming. Ideally, everything should be dynamic,
especially type and dispatch. Binding should always be as late as possible.

Write in a dynamic language, and leave C for the device drivers, codecs,
OS schedulers, etc.

>>> 4. Pointer arithmetic is a low level hack which should not be there, 
>>> because it does not make any sense for variable sized targets or advanced 
>>> structures like graphs and trees.
>> 
>> Pointer arithmetic is necessary for managing variable-sized targets,
>> like records that have multiple variant fields, all in the same linear
>> memory block. These could be stuck into a graph structure.
>
> No. If you need a pointer to the next element you don't have to compute it.
> You just store it. Otherwise, see the position #1.

But then you're dictating to me the memory layout.

Firstly, I don't like that; I'm the designer of my program, I choose the layout.

Now I can live with dictation of memory representations in a nice, high-level
language (e.g. Lisp: I don't care what a cons cell looks like on the heap).
But I still need a language or sub-language for those cases when I do want to
control the layout.

Secondly, what if this is a third-party memory-mapped file where the layout is
imposed?

When the programming language interferes with implementing third-party
requirements, it's a poor language (at least for the problem domain at hand).

> If pointers were
> properly designed as ADTs, there would be no problem to define arithmetic
> on *some* of them as needed. Instead of that the language enforces blanket
> garbage semantics on all of them. Which is a language design fault.

I've never seen pointer arithmetic happen by accident in C code.
This problem Just Doesn't Happen (TM). (Like, "Oops, how did that completely
pointless ++ get onto that ptr variable? I didn't write that!")

I've seen arithmetic wrongly used, of course, but it was used because the
programmer needed and intended it, which is a different problem. If incrementable
pointers were wrapped in an ADT, then the programmer would have used the ADT
in that situation.

That said, there are pointers in C that do not support arithmetic: pointers
to incomplete types.  One incomplete type is void: void * pointers do not
support pointer arithmetic. (Arithmetic on void * is a well-known GNU C
extension that is diagnosed if you tell GCC to stick to ISO C).

Other incomplete types beside "void" are incomplete arrays and incomplete
structure, the latter of which are very useful:

   struct foo *p;  /* no definition of struct foo in scope */
                   /* arithmetic on p not allowed */

Pointers to incomplete struct types are often used in library or module API's.
The client doesn't know what struct foo is, and cannot perform arithmetic
on pointers to struct foo.  The implementation code, of course, can.

(We are sure on a roll. Let's see what utter basics you don't know about C ...)

>> The demand for C toolchains killed those architectures, so that's not a problem
>> any more.
>
> So much for being "close to hardware"!

"C is close to the hardware" is simply the clueless mantra of those who haven't
ever seen the cover of an ISO standard.

C isn't that close to the hardware. There is no standard way to disable interrupts,
or read register R7, or peek at the return address that goes back to the
caller, or test the arithmetic overflow flag of the CPU, if it has one, ...

Now C is close *enough* to the hardware that low-level-ish operating system
code, including device drivers, can be ported between machines. E.g. a UART
driver developed on x86 Linux can work on MIPS, if the same peripheral chip is
available. Furthermore, that driver is not at any serious disadvantage compared
to one written in assembly language for either processor.

>> This is not a "huge problem" in the world; on the contrary, it is a
>> non-problem, now that cheap 64 bit machines are available to consumers.
>
> Well, the balance between the cost of a CPU cycle vs. memory byte has
> shifted towards CPU. It is difficult to say whether that will stay so. When
> massively parallel architectures will arrive, the model of shared memory
> will inevitable die. There is no way to share memory between thousands of
> cores. This might shift the balance back, away from flat, isotropic memory
> models...

There is no way to share memory between millions of machines on an internet,
yet they all use a TCP/IP stack written in C.

A massively parallel machine with many cores will still have local memories,
with some software that uses them conventionally.

>> What would constitute sufficient difficulty in the integer-pointer conversion?
>> Sacrificing a goat for each instance?
>
> Making meaningless conversions unnecessary?

So what then implements the requirements served by those conversions?
Converting a number to a pointer is something which is used because it is needed.

>>> 7. Each object in C is assumed to be addressable, i.e. the &-operation is 
>>> defined on each object.
>> 
>> Variables declared "register" cannot have this operation applied to them.
>> 
>> But even without this, the analysis is very easy for determining whether or not
>> a declared object is subject to the & operator over its scope.
>
> So, the program semantics and legality may depend on the outcome of
> register optimization?

The register storage class means that taking the address of the object is a
diagnosable constraint violation.

(It is additionally intended to be an optimization hint at the same time,
that access to the object should be fast.)

[toc] | [prev] | [next] | [standalone]


#2092

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2014-05-01 10:18 +0200
Message-ID<v76gg3ijutby.vdc53emm25e6$.dlg@40tude.net>
In reply to#2078
On Wed, 30 Apr 2014 15:47:10 +0000 (UTC), Kaz Kylheku wrote:

> If there is any suspicion that the variable is uninitialized, the case
> can be made that it needs to be fixed. If a machine finds it hard to tell
> whether the variable is uninitialized, a human being will also find it hard to
> tell.

All this is not needed if the language were properly designed. E.g. using
the principle of safest choice (by default, initialized or not?), require
everything explicitly initialized without default initialization defined
(e.g. for pointers). If the programmer wants to leave a variable not
initialized (once in a year), give him a keyword to state this.
 
>> Anyway, a precaution that can be done by compiler but left to the
>> programmer is a language design fault, which C pointers are.
> 
> Not every precaution that can be done by the compiler *should* be done.

Every, for economical reasons. Debugging is more expensive than design.
Maintenance is more expensive than debugging.

> Static checking is bane of programming. Ideally, everything should be dynamic,
> especially type and dispatch. Binding should always be as late as possible.

On the contrary. Late binding convert bugs into faults, e.g. type error
into constraint violation/message-not-understood etc. This is intolerable
from the software engineering POV.

From the CS POV, there no dynamic languages, only poor static languages.
You cannot have everything dynamic, you must stop the indirection
somewhere. If you put all objects that accept a given operation together,
that would constitute a perfectly static type. If that type is anonymous,
that is a language fault, the type is semantically there.

> Write in a dynamic language, and leave C for the device drivers, codecs,
> OS schedulers, etc.

Which implies that dynamic languages are incomplete. Why should anybody use
such a language. Wouldn't it better to design and use a decent language
instead?

>>>> 4. Pointer arithmetic is a low level hack which should not be there, 
>>>> because it does not make any sense for variable sized targets or advanced 
>>>> structures like graphs and trees.
>>> 
>>> Pointer arithmetic is necessary for managing variable-sized targets,
>>> like records that have multiple variant fields, all in the same linear
>>> memory block. These could be stuck into a graph structure.
>>
>> No. If you need a pointer to the next element you don't have to compute it.
>> You just store it. Otherwise, see the position #1.
> 
> But then you're dictating to me the memory layout.

Why? A pointer can point anywhere.

> Secondly, what if this is a third-party memory-mapped file where the layout is
> imposed?

You will need de-/serialize objects as with any other file. Memory-mapped
files is a hack, unless we consider a pure object-oriented OS, without
files, where everything is a persistent object. That would not be for C
anyway, nor for poor old Windows nor Linux.

>>> This is not a "huge problem" in the world; on the contrary, it is a
>>> non-problem, now that cheap 64 bit machines are available to consumers.
>>
>> Well, the balance between the cost of a CPU cycle vs. memory byte has
>> shifted towards CPU. It is difficult to say whether that will stay so. When
>> massively parallel architectures will arrive, the model of shared memory
>> will inevitable die. There is no way to share memory between thousands of
>> cores. This might shift the balance back, away from flat, isotropic memory
>> models...
> 
> There is no way to share memory between millions of machines on an internet,
> yet they all use a TCP/IP stack written in C.

So what? You are again confusing completeness in narrow Turing sense with
language design. We are talking about structuring the address space. The
address space of Internet is *not* flat and *not* isotropic. q.e.d.

> A massively parallel machine with many cores will still have local memories,
> with some software that uses them conventionally.

Yes, but the programmer of such systems will care about local memory barely
more than he presently cares about L2-cache.

>>> What would constitute sufficient difficulty in the integer-pointer conversion?
>>> Sacrificing a goat for each instance?
>>
>> Making meaningless conversions unnecessary?
> 
> So what then implements the requirements served by those conversions?
> Converting a number to a pointer is something which is used because it is needed.

It is never needed, because there is no proper method of obtaining such
numbers in first place. If the method exist, it is pointer-to-number and
back to pointer conversion. Which raises immediate question why number was
needed as a middleman? Because the language lacks means of handling
pointers as proper types and objects (e.g. in order to serialize them)?

All cases where numbers are converted to pointers are at some I/O boundary
and even then there always exist better ways.

>>>> 7. Each object in C is assumed to be addressable, i.e. the &-operation is 
>>>> defined on each object.
>>> 
>>> Variables declared "register" cannot have this operation applied to them.
>>> 
>>> But even without this, the analysis is very easy for determining whether or not
>>> a declared object is subject to the & operator over its scope.
>>
>> So, the program semantics and legality may depend on the outcome of
>> register optimization?
> 
> The register storage class means that taking the address of the object is a
> diagnosable constraint violation.

So must have been the class of addressable objects. If the programmer's
intent is to access the object via pointer, he should declare this in
advance. If he mistakenly takes a pointer to an object that is not intended
for aliasing, this is a serious bug, and must be flagged as such. Bugs
related to aliasing are extremely hard to debug. The principle of safest
choice.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#2112

FromKaz Kylheku <kaz@kylheku.com>
Date2014-05-01 16:56 +0000
Message-ID<20140501064151.690@kylheku.com>
In reply to#2092
On 2014-05-01, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> On Wed, 30 Apr 2014 15:47:10 +0000 (UTC), Kaz Kylheku wrote:
>
>> If there is any suspicion that the variable is uninitialized, the case
>> can be made that it needs to be fixed. If a machine finds it hard to tell
>> whether the variable is uninitialized, a human being will also find it hard to
>> tell.
>
> All this is not needed if the language were properly designed. E.g. using
> the principle of safest choice (by default, initialized or not?), require
> everything explicitly initialized without default initialization defined

Before C99, C had "declarations before statements" (like "Wirthian" languages).

If declarations have to follow statements, you sometimes have to write
code like this:

   int var;

   lock(&obj->lock_var);

   var = obj->memb;

I wrote something very similar to this just yesterday, inside
a USB driver.

If var had to be initialized, the compiler would still have to do all
the same analysis in order to optimize that away; it would have to
relize that the initial value has no "next use" in the flow graph.

This particular use goe away if we mix variable definitions with statements:

   lock(&obj->lock_var);
   int var = obj->memb;

This is supported in C starting with C99, and has been in C++ for a long
time (precisely because C++ objects with constructors do not support
this two-step initialization).

>> Static checking is bane of programming. Ideally, everything should be dynamic,
>> especially type and dispatch. Binding should always be as late as possible.
>
> On the contrary. Late binding convert bugs into faults, e.g. type error
> into constraint violation/message-not-understood etc. This is intolerable
> from the software engineering POV.

If you don't formalize late binding into the language, programmers
will reinvent it anyway, in an ad-hoc way.

Dynamic languages are well known for their productivity and robust
applications.

Whenever something falls down in computing, more often than not, some
statically typed trash is at the root cause.

> From the CS POV, there no dynamic languages, only poor static languages.

Complete nonsense. Languages are dynamic by default. All the pseudo-code
in CS textbooks and papers is essentially dynamic.

Statica analysis is just a way of classifying a certain subset of dynamic
programs: those which have the property that a type can be inferred for
every node in their graph (possibly after expanding that graph in the
face of "static polymorphism"), so that no expression has more than one type in
different run-time situations.

(Languages with explicit declarations for determining what type flows
into every node in the graph are obsolete dinosaurs; the state of the
art in static typing is inference.)

> You cannot have everything dynamic, you must stop the indirection
> somewhere.

Reductio ad 1 et 0.

Dynamic languages are supported by a kernel of run-time code that isn't
itself dynamic, and also by compiler generated code that isn't dynamic
either. It just "knows" that, say, two certain bits of a value are a
type tag: no other meta-tag tells it that.

Ultimately, bits are statically typed; we know that a bit cell has type "bit"
and only contains a 1 or 0; there is no need to check some other information to
verify.

> If you put all objects that accept a given operation together,
> that would constitute a perfectly static type.

Sure, a meaningless static type like "Object" which need not be mentioned int
the language.

>> Write in a dynamic language, and leave C for the device drivers, codecs,
>> OS schedulers, etc.
>
> Which implies that dynamic languages are incomplete. Why should anybody use
> such a language. Wouldn't it better to design and use a decent language
> instead?

They aren't. For instance Lisp machines were written entirely in Lisp,
interrupt-driven device drivers and all. There are nice implementatinos
of Lisp with good compilers. Whereas, say, Python or Ruby users call
C libraries for things like regex, crypto or image processing, Lisp
programmers use libraries written in Lisp for this, because the performance
is decent.

People don't write device drivers in Lisp nowadays though because platforms
dictate the methodology for those (so it is usually done in C).

Millions of programmers choose "incomplete" languages that don't even have
compilers, because they find them to be the right tool for the right job. They
have some ready-made framework, library and possibly "recipes" on how to
structure the major pieces together.

They aren't writing an device driver, so they don't care that they cannot.

However, a dynamic language can certainly be the "be all" system language
from the boostrap loader on up.

>>>>> 4. Pointer arithmetic is a low level hack which should not be there, 
>>>>> because it does not make any sense for variable sized targets or advanced 
>>>>> structures like graphs and trees.
>>>> 
>>>> Pointer arithmetic is necessary for managing variable-sized targets,
>>>> like records that have multiple variant fields, all in the same linear
>>>> memory block. These could be stuck into a graph structure.
>>>
>>> No. If you need a pointer to the next element you don't have to compute it.
>>> You just store it. Otherwise, see the position #1.
>> 
>> But then you're dictating to me the memory layout.
>
> Why? A pointer can point anywhere.

You're dictating that the pointer is *there* in the layout, rather than just
the next element itself (whereby we calculate the address of the element
ourselves, outside of the structure) That embedded pointer not even directly
possible if that layout is from a memory mapping that can be placed at any
address, and shared by processes.

>> Secondly, what if this is a third-party memory-mapped file where the layout is
>> imposed?
>
> You will need de-/serialize objects as with any other file.

Screw that; I want memory mapped!

> Memory-mapped files is a hack,

That is neither here nor there; they exist, developers sometimes want them.
They have measurable, demonstrable benefits. (As well as shortcomings.)

>>> Well, the balance between the cost of a CPU cycle vs. memory byte has
>>> shifted towards CPU. It is difficult to say whether that will stay so. When
>>> massively parallel architectures will arrive, the model of shared memory
>>> will inevitable die. There is no way to share memory between thousands of
>>> cores. This might shift the balance back, away from flat, isotropic memory
>>> models...
>> 
>> There is no way to share memory between millions of machines on an internet,
>> yet they all use a TCP/IP stack written in C.
>
> So what? You are again confusing completeness in narrow Turing sense with
> language design.

I am not confusing anything. I know all all about Turing equivalence not
being expressivity equivalence. (And have had to hit numerous people on
Usenet over the head with that over twenty years.)

I didn't claim that C is an expressive language for writing an application
for a thousand cores that do not share memory well.

However, I think C will will end up used for programming parts of that system,
and perhaps even parts of the run-time support for whatever language is used
at the high level for harnessing those cores.

That machine will still need to to mundane things like boot up, or
push packets to and from some ethernet controller with DMA and interrupts,
etc.

C you there!  :)

> We are talking about structuring the address space. The
> address space of Internet is *not* flat and *not* isotropic. q.e.d.

But you can get 64 kilobyte pieces of thanks to a popular C library! :)

>> A massively parallel machine with many cores will still have local memories,
>> with some software that uses them conventionally.
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

See, some software: not all.

> Yes, but the programmer of such systems will care about local memory barely
> more than he presently cares about L2-cache.

The programmers of some kinds of applications already don't care about this
on boxes with just a handful of cores (perhaps one).

>>>> What would constitute sufficient difficulty in the integer-pointer conversion?
>>>> Sacrificing a goat for each instance?
>>>
>>> Making meaningless conversions unnecessary?
>> 
>> So what then implements the requirements served by those conversions?
>> Converting a number to a pointer is something which is used because it is needed.
>
> It is never needed, because there is no proper method of obtaining such
> numbers in first place.

Yes there is; system documentation, data sheets.

> If the method exist, it is pointer-to-number and
> back to pointer conversion. Which raises immediate question why number was
> needed as a middleman?

Simply for the pragmatic reason that addresses on digital, binary computers are
numbers.

This can be abstracted away for objects that need not have a concrete,
particular address.

> All cases where numbers are converted to pointers are at some I/O boundary
> and even then there always exist better ways.

No, not all cases have to do with I/O.

Sometimes C programs use "spare bits" in pointers for additional information.

Some concurrent algorithms rely on this (like lock-free linked lists), and also
implementations of dynamic languages that are written in C.

Tn the implementation of the TXR language, every value is a C pointer
of type val, which is a typedef for obj_t *.

Pointers are relied upon to have an alignment of at least four bytes,
which leaves the least significant two bits open for use as a type tag.

So "fixnum" integers can be represented directly inside the pointer
value, as well as characters.

The tag is chosen such that the value 0 (bits 00) denote a heaped object. 
That means that the pointer can be dereferenced directly.

>>>>> 7. Each object in C is assumed to be addressable, i.e. the &-operation is 
>>>>> defined on each object.
>>>> 
>>>> Variables declared "register" cannot have this operation applied to them.
>>>> 
>>>> But even without this, the analysis is very easy for determining whether or not
>>>> a declared object is subject to the & operator over its scope.
>>>
>>> So, the program semantics and legality may depend on the outcome of
>>> register optimization?
>> 
>> The register storage class means that taking the address of the object is a
>> diagnosable constraint violation.
>
> So must have been the class of addressable objects. If the programmer's
> intent is to access the object via pointer, he should declare this in
> advance. If he mistakenly takes a pointer to an object that is not intended
> for aliasing, this is a serious bug, and must be flagged as such.

The Wirthian language commit a serious offense in this regard compared to C.
In Pascal and its ilk, you can change a procdure's conventional by-value
argument to a VAR argument. When the program is recompiled, calls to that
procedure now silently "steal" references to variables and may modify them.

C++ also has this in the form of references.

In C we at least have a loud and clear syntax that the address is being
taken: the & operator (though it can be hidden behind a macro).

Having to explicitly declare a permission for an address to be taken isn't such
a bad idea, but it can have downsizes. For instance, your program could really
benefit from taking the address of a variable in some third-party library.
Ooops, it is not declared for that!

In C we have the const qualifier whose behavior is such that the address of a
const qualified object is a pointer to a const-qualified type.  When this
pointer is dereferenced, the resulting lvalue cannot be assigned; it is not
modifiable.  This provides a reasonable middle ground: allow the address, but
one that gives rise to only read-only aliases.

> Bugs
> related to aliasing are extremely hard to debug. The principle of safest
> choice.

If that's the best way to write the program, then it is no harder to debug
than it has to be.

[toc] | [prev] | [next] | [standalone]


#2135

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2014-05-02 10:10 +0200
Message-ID<dpbh4lif541g$.1wok0ymoxov71.dlg@40tude.net>
In reply to#2112
On Thu, 1 May 2014 16:56:50 +0000 (UTC), Kaz Kylheku wrote:

> On 2014-05-01, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On Wed, 30 Apr 2014 15:47:10 +0000 (UTC), Kaz Kylheku wrote:
>>
>>> Static checking is bane of programming. Ideally, everything should be dynamic,
>>> especially type and dispatch. Binding should always be as late as possible.
>>
>> On the contrary. Late binding convert bugs into faults, e.g. type error
>> into constraint violation/message-not-understood etc. This is intolerable
>> from the software engineering POV.
> 
> If you don't formalize late binding into the language, programmers
> will reinvent it anyway, in an ad-hoc way.

Sure, but that does not change the point: bind as early as you can. If the
earliest possible point is run-time, be it so.

> Dynamic languages are well known for their productivity and robust
> applications.

Just wait they arrive in your car's ECU...

>> If you put all objects that accept a given operation together,
>> that would constitute a perfectly static type.
> 
> Sure, a meaningless static type like "Object" which need not be mentioned int
> the language.

The Universe as a whole is a meaningless thing.
 
>>> Write in a dynamic language, and leave C for the device drivers, codecs,
>>> OS schedulers, etc.
>>
>> Which implies that dynamic languages are incomplete. Why should anybody use
>> such a language. Wouldn't it better to design and use a decent language
>> instead?
> 
> They aren't. For instance Lisp machines were written entirely in Lisp,
> interrupt-driven device drivers and all. There are nice implementatinos
> of Lisp with good compilers. Whereas, say, Python or Ruby users call
> C libraries for things like regex, crypto or image processing, Lisp
> programmers use libraries written in Lisp for this, because the performance
> is decent.
> 
> People don't write device drivers in Lisp nowadays though because platforms
> dictate the methodology for those (so it is usually done in C).

Thus dynamic language are unsuitable for the existing computational strata.
You have a choice, either you change the hardware (where are infamous
Lisp-machines?) or you ditch garbage languages.

> Millions of programmers choose "incomplete" languages that don't even have
> compilers, because they find them to be the right tool for the right job.

Millions of programmers are unqualified for the job. And the industry of
software design as a whole is a joke, for numerous reasons from economical
and legal to the sad fact that software development is not really
engineering and CS is not a science. 

>>>>>> 4. Pointer arithmetic is a low level hack which should not be there, 
>>>>>> because it does not make any sense for variable sized targets or advanced 
>>>>>> structures like graphs and trees.
>>>>> 
>>>>> Pointer arithmetic is necessary for managing variable-sized targets,
>>>>> like records that have multiple variant fields, all in the same linear
>>>>> memory block. These could be stuck into a graph structure.
>>>>
>>>> No. If you need a pointer to the next element you don't have to compute it.
>>>> You just store it. Otherwise, see the position #1.
>>> 
>>> But then you're dictating to me the memory layout.
>>
>> Why? A pointer can point anywhere.
> 
> You're dictating that the pointer is *there* in the layout, rather than just
> the next element itself (whereby we calculate the address of the element
> ourselves, outside of the structure)

"next element itself" is a much stricter dictate and implementation burden.
If it weren't so, and you could always have "the next thing", just as you
wanted, you would be no need pointers in first place!

>>> Secondly, what if this is a third-party memory-mapped file where the layout is
>>> imposed?
>>
>> You will need de-/serialize objects as with any other file.
> 
> Screw that; I want memory mapped!

How do you ensure that object's representation in the memory is same? 

Deserialization is a process of doing this. Your pointer arithmetic is
deserialization of pointer object from some numeric media. What you argue
for, is merely performing deserialization each time you access serialized
(as a number) pointer. Not always the best strategy.

>>>>> What would constitute sufficient difficulty in the integer-pointer conversion?
>>>>> Sacrificing a goat for each instance?
>>>>
>>>> Making meaningless conversions unnecessary?
>>> 
>>> So what then implements the requirements served by those conversions?
>>> Converting a number to a pointer is something which is used because it is needed.
>>
>> It is never needed, because there is no proper method of obtaining such
>> numbers in first place.
> 
> Yes there is; system documentation, data sheets.

That does not require either pointer or conversions. E.g. in Ada

   type Processor_Status_Register is record ...; -- Whatever

   PS : Processor_Status_Register;
   for PS'Address use 16#FFFF_FFAC#;  -- No pointers, no conversions

>> If the method exist, it is pointer-to-number and
>> back to pointer conversion. Which raises immediate question why number was
>> needed as a middleman?
> 
> Simply for the pragmatic reason that addresses on digital, binary computers are
> numbers.

No, they are not. The proper statement is that there exist mappings address
to number and back. Which mapping is not even a bijection, on most
machines.

Merely fact that finiteness of any computer allows you to map anything
there to number does not make anything number. In that sense any program is
integer. Does that help?

>> All cases where numbers are converted to pointers are at some I/O boundary
>> and even then there always exist better ways.
> 
> No, not all cases have to do with I/O.
> 
> Sometimes C programs use "spare bits" in pointers for additional information.

But these are not *numbers*. These are records, bit-fields etc.
 
>>>>>> 7. Each object in C is assumed to be addressable, i.e. the &-operation is 
>>>>>> defined on each object.
>>>>> 
>>>>> Variables declared "register" cannot have this operation applied to them.
>>>>> 
>>>>> But even without this, the analysis is very easy for determining whether or not
>>>>> a declared object is subject to the & operator over its scope.
>>>>
>>>> So, the program semantics and legality may depend on the outcome of
>>>> register optimization?
>>> 
>>> The register storage class means that taking the address of the object is a
>>> diagnosable constraint violation.
>>
>> So must have been the class of addressable objects. If the programmer's
>> intent is to access the object via pointer, he should declare this in
>> advance. If he mistakenly takes a pointer to an object that is not intended
>> for aliasing, this is a serious bug, and must be flagged as such.
> 
> The Wirthian language commit a serious offense in this regard compared to C.

Nope. C's parameters are broken, you should never be able to update an
immutable input parameter. If the parameter is mutable, that must have an
effect on the caller. Either this or that, by-copy vs. by-value is
irrelevant.

But the point stands: pointers introduce aliasing per intent and making all
objects capable of being aliased is a language design fault.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#2080

From"BartC" <bc@freeuk.com>
Date2014-04-30 18:27 +0100
Message-ID<Coa8v.127640$t%4.123890@fx04.am4>
In reply to#2056

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:1965jbmywu22u$.9o9wv0bq5csu$.dlg@40tude.net...
> On Mon, 28 Apr 2014 21:46:00 -0400, Rod Pemberton wrote:
>
>> So, let's list some (what I recall right now...) of what I think
>> C gets correct:
>>
>> 1) pointers
>
> Since C did almost everything wrong.

Are you taking account of the fact that C is a low-level language? If not, 
then you can argue that any assembly language does everything 'wrong'.

> I will comment only on pointers, which
> is also an easy game. What is wrong with them:
>
> 1. Pointer types are improperly typed as they are matched by structure.
> Thus you cannot have two distinct pointer types for the same target type.
> The feature extremely important for building sorted containers and custom
> memory pools.

If you can't trust yourself to not get the two types mixed up, then you can 
wrap the target in a struct type.

> 2. Pointers are not initialized with null, as they must for safety 
> reasons.
> Neither are they checked for null when dereferenced.

They often are checked for null (usually by the memory management of the 
hardware). Doing an explicit runtime check, except during debugging, would 
defeat the purpose of using C in the first place. And there are many pointer 
invalid values other than null.

> 6. Pointers are easily converted to integers and many C programmers
> consider such conversions OK, which leads to extremely fragile and
> non-portable code.

Conversion of integers /to/ pointers is more of a problem, or would be in 
the hands of a programmer who had no idea what he or she is doing. But 
usually there is a reason for it.

> 7. Each object in C is assumed to be addressable, i.e. the &-operation is
> defined on each object. This was tolerable half century ago,
> notwithstanding that K&R were seemingly unaware of Boolean and packed
> arrays. But now it is a heavy burden with machines of hundreds of 
> registers
> and many leveled cache.

If an object is legally addressable, that why not make that assumption? The 
implementer can take care of that if someone wants to use & on something 
(for objects that would otherwise only exist in registers, or not at all).

If you mean packed arrays of bit values, then the language has never allowed 
individual bits to be addressable.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#2093

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2014-05-01 10:18 +0200
Message-ID<1oz1ou4obfdrc.ihri7rhvc8gt$.dlg@40tude.net>
In reply to#2080
On Wed, 30 Apr 2014 18:27:08 +0100, BartC wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:1965jbmywu22u$.9o9wv0bq5csu$.dlg@40tude.net...
>> On Mon, 28 Apr 2014 21:46:00 -0400, Rod Pemberton wrote:
>>
>>> So, let's list some (what I recall right now...) of what I think
>>> C gets correct:
>>>
>>> 1) pointers
>>
>> Since C did almost everything wrong.
> 
> Are you taking account of the fact that C is a low-level language? If not, 
> then you can argue that any assembly language does everything 'wrong'.

Oh, but this is different. Firstly, of course, you should define the
"level". Presumably it is a level of abstraction away, but from what?

Often repeated proposition that C is close to the hardware = not really
abstracts the machine, is plain wrong. Most of C primitives do not really
match the hardware architecture. In that sense C is by no means low-level.
It is quite high-level in fact. It might have been low-level for PDP, in
the time when the myth was established. There is little low-level in C in
this sense now. C has an assorted set of abstractions, poorly chosen ones.
This alone does make C low level, it does it wrong. Note that an assembly
language does not suffer this problem as it indeed matches the hardware.

If you consider "level" related to some abstract programming paradigm, yes,
C is very low-level because it lacks a lot of things, starting with a
decent type system, means of encapsulation etc. This, again, is not really
comparable to assembly languages. Some of them have higher level features
like macro capacities (AKA generic programming) missing in C. E.g. MACRO-11
assembly was arguably higher level than C in some aspects (and lower in
others).

>> I will comment only on pointers, which
>> is also an easy game. What is wrong with them:
>>
>> 1. Pointer types are improperly typed as they are matched by structure.
>> Thus you cannot have two distinct pointer types for the same target type.
>> The feature extremely important for building sorted containers and custom
>> memory pools.
> 
> If you can't trust yourself to not get the two types mixed up, then you can 
> wrap the target in a struct type.

But that won't be a pointer anymore.

This is another language fault that you don't have a pointer interface
abstracted. You cannot define a type and dress it as a pointer. But this is
a "second" layer of faults C didn't even close to, because it lacks any
use-defined type altogether.

>> 2. Pointers are not initialized with null, as they must for safety reasons.
>> Neither are they checked for null when dereferenced.
> 
> They often are checked for null (usually by the memory management of the 
> hardware).

Maybe, but we are talking about the language. Whatever the hardware does or
not is irrelevant. After all C does not have exceptions to deal with
run-time checks.

>> 6. Pointers are easily converted to integers and many C programmers
>> consider such conversions OK, which leads to extremely fragile and
>> non-portable code.
> 
> Conversion of integers /to/ pointers is more of a problem, or would be in 
> the hands of a programmer who had no idea what he or she is doing. But 
> usually there is a reason for it.

Language design fault is that reason.

>> 7. Each object in C is assumed to be addressable, i.e. the &-operation is
>> defined on each object. This was tolerable half century ago,
>> notwithstanding that K&R were seemingly unaware of Boolean and packed
>> arrays. But now it is a heavy burden with machines of hundreds of 
>> registers and many leveled cache.
> 
> If an object is legally addressable, that why not make that assumption?

Sorry, I cannot decode this. "Legally" means according to the language? If
X is legally addressable, it is not an assumption it is a fact that X is
addressable.

> If you mean packed arrays of bit values, then the language has never allowed 
> individual bits to be addressable.

Because it didn't have them. The language designers didn't care, there is
no arrays in C anyway. And since in PDP you indeed could address literally
everything, even a machine register, they, likely, unconsciously projected
this to every machine, if they thought about that, which I doubt.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#2113

FromKaz Kylheku <kaz@kylheku.com>
Date2014-05-01 17:10 +0000
Message-ID<20140501095725.877@kylheku.com>
In reply to#2093
On 2014-05-01, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> On Wed, 30 Apr 2014 18:27:08 +0100, BartC wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
>> news:1965jbmywu22u$.9o9wv0bq5csu$.dlg@40tude.net...
>>> On Mon, 28 Apr 2014 21:46:00 -0400, Rod Pemberton wrote:
>>>
>>>> So, let's list some (what I recall right now...) of what I think
>>>> C gets correct:
>>>>
>>>> 1) pointers
>>>
>>> Since C did almost everything wrong.
>> 
>> Are you taking account of the fact that C is a low-level language? If not, 
>> then you can argue that any assembly language does everything 'wrong'.
>
> Oh, but this is different. Firstly, of course, you should define the
> "level". Presumably it is a level of abstraction away, but from what?

As a starting point, a good "rough" definition of a low level of abstraction
means that programs for diverse appliactions look the same.

If I look at the insides of a text editor, cryptographic library, image
recognition, device driver, or game, and they all look like approximately the
same cruft (for instance a column of machine language instructions), then they
are at a low level of abstraction compared to their application domains.

A very good definition of Abstraction Level comes from the Tunes project:

http://tunes.org/wiki/abstraction_20level.html

Especially the criterion in the last paragraph.

"A set of programs is more high-level than another one if for each problem
solved by the second set of programs, there exist a higher-level program that
solves the same problem in the first set."

A "program" can be taken to represent not necessarily an executable sitting
on your disk, but a procedure, machine language instruction or any capsule
of computation.

So the criterion explains why machine language is low level. For any given
problem solved using machine language, the same "set of programs" is applied:
the same bag of machine instructions. This is why the solutions look the same.
If I see 25 lines of disassembly listing, I have no clue whether I'm looking at
a text editor, device driver, or image recognition code, since it's just a
combination of the "programs": the little routines in the instruction set like
"compare that register to that other one".

> Often repeated proposition that C is close to the hardware = not really
> abstracts the machine, is plain wrong. Most of C primitives do not really
> match the hardware architecture.  In that sense C is by no means low-level.

Level is really a lattice. There is some ideal awy of expressing what I'm
doing. And multiple, though diverse, directions away from that are "lower
level".

Processing data with Unix piping and text manipulation is often at an
inappropriate level for that data. It's low-level in some sense in that it
never gets away from the irrelevant details of how the printed representation
of the data is delimited, and the code doesn't really express whatis going
on; it just says "I'm a mass of shell cruft that has to be read in painstaking
detail to decode what is going on".

[toc] | [prev] | [next] | [standalone]


#2134

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2014-05-02 09:22 +0200
Message-ID<hiq5gnxt58ok.pwmzb31qbz48$.dlg@40tude.net>
In reply to#2113
On Thu, 1 May 2014 17:10:29 +0000 (UTC), Kaz Kylheku wrote:

> On 2014-05-01, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On Wed, 30 Apr 2014 18:27:08 +0100, BartC wrote:
>>
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
>>> news:1965jbmywu22u$.9o9wv0bq5csu$.dlg@40tude.net...
>>>> On Mon, 28 Apr 2014 21:46:00 -0400, Rod Pemberton wrote:
>>>>
>>>>> So, let's list some (what I recall right now...) of what I think
>>>>> C gets correct:
>>>>>
>>>>> 1) pointers
>>>>
>>>> Since C did almost everything wrong.
>>> 
>>> Are you taking account of the fact that C is a low-level language? If not, 
>>> then you can argue that any assembly language does everything 'wrong'.
>>
>> Oh, but this is different. Firstly, of course, you should define the
>> "level". Presumably it is a level of abstraction away, but from what?
> 
> As a starting point, a good "rough" definition of a low level of abstraction
> means that programs for diverse appliactions look the same.
> 
> If I look at the insides of a text editor, cryptographic library, image
> recognition, device driver, or game, and they all look like approximately the
> same cruft (for instance a column of machine language instructions), then they
> are at a low level of abstraction compared to their application domains.

And why is it lower level? If the programs look same, that presumes that
means they deploy are suitable for solving diverse problems (or that the
computational power of the observer (human) is not suitable to distinguish
them properly).

This can be both lower and higher level. It depends on how the observed
uniformity was achieved. If it was through generalization, that would be
higher level. If it was through decomposition into lower-level primitives
it could be lower level. As an extreme example consider a program in the
God's language:

   Do it!

Is it low or high level?

> A very good definition of Abstraction Level comes from the Tunes project:
> 
> http://tunes.org/wiki/abstraction_20level.html
> 
> Especially the criterion in the last paragraph.
> 
> "A set of programs is more high-level than another one if for each problem
> solved by the second set of programs, there exist a higher-level program that
> solves the same problem in the first set."

This is merely a constraint to make things comparable, because it would
make no sense to talk about a "higher-level" thing that does not solve the
problems of interest in first place.

> A "program" can be taken to represent not necessarily an executable sitting
> on your disk, but a procedure, machine language instruction or any capsule
> of computation.
> 
> So the criterion explains why machine language is low level. For any given
> problem solved using machine language, the same "set of programs" is applied:
> the same bag of machine instructions. This is why the solutions look the same.
> If I see 25 lines of disassembly listing, I have no clue whether I'm looking at
> a text editor, device driver, or image recognition code, since it's just a
> combination of the "programs": the little routines in the instruction set like
> "compare that register to that other one".

No. You just said that human sensing operates a language different from
machine language. Which is why a human has difficulty recognizing meaning
of machine code. There is nothing *here*, that makes machine language lower
level.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#2050

From"Rod Pemberton" <dont_use_email@xnothavet.cqm>
Date2014-04-28 20:59 -0400
Message-ID<op.xe1zoyii6zenlw@localhost>
In reply to#2037
On Mon, 28 Apr 2014 12:23:05 -0400, bruce axtens <bugmagnet@outlook.com>  
wrote:

> Is it fair to say that most of the Wirth-ian programming languages are
> either dead or in palliative care? Delphi seems to be about the only
> thing left with any life in it. Am I missing anything?
>

I think it's dead.  Most people on other newsgroups seem to argue
against me though when I say language 'X' or 'Y' or 'Z' is dead.
Other than BASIC, I think the languages of our era (being presumptuous
here) learned are dead: COBOL, FORTAN, Pascal, LISP, PL/I, Forth,
Ada, etc.  BASIC still seems to have a life in limited situations,
e.g, industrial machines, hobbyists.

Whenever I point out that nearly all the newer languages use or have
used C as an intermediate representation, or as assembly, or derived
their internal code from compiled C code, I get attacked on that one
too, even though it's true.  I can cite many of them.

C and C++ and various derivatives, like Java, "won" the language wars.
The other languages you see are all modern creations to handle various
modern issues: internet, websites, etc.  IMO, the TIOBE index confirms
this.  C and derivatives are the majority.  Most others are insignificant.

As a high-level language, I liked Pascal for the most part.  It had
some wierd stuff in it too though.  It was well structured.  The problem
with Pascal, almost three decades ago when I learned it, was it had two
serious problems.  The first was that it didn't have pointers.  This
was safe, but really complicated programming certain solutions.  Others
have pointed out (pun-intended) that Pascal has pointers today.  The
second was that there was no ability to access low-level features of
the machine.  This was a problem in the era of cheap, personal, home
computers.  You were trapped inside a box which couldn't control the
computer using Pascal.  That's fine for some applications, but mostly
just prevented programmers from using their machines.  Even BASIC of
that era provided mechanisms to do that, although they were custom to
each version of BASIC.


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#2051

From"Rod Pemberton" <dont_use_email@xnothavet.cqm>
Date2014-04-28 21:10 -0400
Message-ID<op.xe1z8das6zenlw@localhost>
In reply to#2050
On Mon, 28 Apr 2014 20:59:12 -0400, Rod Pemberton  
<dont_use_email@xnothavet.cqm> wrote:

> I think it's dead.  Most people on other newsgroups seem to argue
> against me though when I say language 'X' or 'Y' or 'Z' is dead.
> Other than BASIC, I think the languages of our era (being presumptuous
> here) learned are dead: COBOL, FORTAN, Pascal, LISP, PL/I, Forth,

Delete "learned", editing error.

RP

[toc] | [prev] | [next] | [standalone]


#2055

FromNils M Holm <news2009@t3x.org>
Date2014-04-29 07:52 +0000
Message-ID<bs942mFbgnkU1@mid.individual.net>
In reply to#2050
Rod Pemberton <dont_use_email@xnothavet.cqm> wrote:
> I think it's dead.  Most people on other newsgroups seem to argue
> against me though when I say language 'X' or 'Y' or 'Z' is dead.
> Other than BASIC, I think the languages of our era (being presumptuous
> here) learned are dead: COBOL, FORTAN, Pascal, LISP, PL/I, Forth,
> Ada, etc.  BASIC still seems to have a life in limited situations,
> e.g, industrial machines, hobbyists.

I think it is even worse. Every language todays either looks like C
or it is *wrong*. Because The Industry demands programmers that are
well-trained in C-like languages, and dealing with something that does
not increase your market value is *wrong*. So other languages are only
used by lunatics and academics. This seems to be the consent among
contemporary software developers, and this is sad, because it kills
creativity, diversity, and innovation.

-- 
Nils M Holm  < n m h @ t 3 x . o r g >  www.t3x.org

[toc] | [prev] | [next] | [standalone]


#2057

From"BartC" <bc@freeuk.com>
Date2014-04-29 09:45 +0100
Message-ID<WEJ7v.226243$hB4.80959@fx20.am4>
In reply to#2050
"Rod Pemberton" <dont_use_email@xnothavet.cqm> wrote in message 
news:op.xe1zoyii6zenlw@localhost...
> On Mon, 28 Apr 2014 12:23:05 -0400, bruce axtens <bugmagnet@outlook.com> 
> wrote:

> As a high-level language, I liked Pascal for the most part.  It had
> some wierd stuff in it too though.  It was well structured.  The problem
> with Pascal, almost three decades ago when I learned it, was it had two
> serious problems.  The first was that it didn't have pointers.  This
> was safe, but really complicated programming certain solutions.  Others
> have pointed out (pun-intended) that Pascal has pointers today.

It certainly had pointers when I used it in the late 70s. What it didn't 
have was a proper array type (you had to define fixed bounds for an array, 
which made it incompatible with an array with different bounds) and proper 
string handling.

> The
> second was that there was no ability to access low-level features of
> the machine.  This was a problem in the era of cheap, personal, home
> computers.  You were trapped inside a box which couldn't control the
> computer using Pascal.

These problems would have been easy to fix.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#2062

FromJacko <jackokring@gmail.com>
Date2014-04-29 05:37 -0700
Message-ID<c2ed1b83-f58b-4c91-bec4-39560fa5d94a@googlegroups.com>
In reply to#2037
I'm using free Pascal at the moment. Things I like about it are not having all the makefile and command line stuff getting in the way of doing things. The units feature is very good at this. The IDE is a bit limited, but not so much as to cause real problems. It's all text based, and includes a Free Vision (Turbo Vision clone) for simple text based "GUI" stuff.

It supports various dialects, but the default is just fine. There are a few simplifications (or complications) based around declaring pointer types with self reference, and procedural and functional types, but otherwise quite nice. Minor irritations on naming parameters in forward declarations, and the necessity to use semicolons to separate different typed parameters in definitions, when commas are just as syntax unique.

There are OpenGL units, and quite a few other nice utility units, full unlimited length ANSI strings, and nice object features. It's basically TP7 with some minor syntax changes, and it has support for many cross compilation targets, with a nice c.h file converter.

I like C and Java too, but Java is far too complex to run a fast IDE, and C has very little in the way of controllable error code generation. I try not to use pointers when arrays will do, and consider that a good optimizer will do much of the ++ and the like when appropriate optimization is selected.

Old does not mean useless, in fact I'm very happy to see such a language tool available.

Cheers Jacko

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.misc


csiph-web