comp.lang.ada
 help / color / mirror / Atom feed
* Heartbleed
@ 2014-04-11  2:39 Charles H. Sampson
  2014-04-11  7:59 ` Heartbleed Maciej Sobczak
                   ` (2 more replies)
  0 siblings, 3 replies; 144+ messages in thread
From: Charles H. Sampson @ 2014-04-11  2:39 UTC (permalink / raw)


     According to Wikipedia, the Heartbleed bug in OpenSSL is caused by
two errors: Lack of bounds checking and failure to verify that the
heartbeat request was valid. Whom does one express one's indignation to?
The insistence of many in our "profession" on using C and its decendents
is the reason I qualify the word "profession" when writing about
software developers. Acting on a message without validating it is
equally incomprenhensible to me. The former is a "profession"-wide
problem. For the latter, someone needs a severe rebuke on his next
performance review, at the least.

     It so happens that for the last project I worked on, I was
responsible for TCP/IP communication. Every incoming message was fully
validated, including validating all components of the message body. The
only response to an invalid message was a negative acknowledgement to
the sender. It never occurred to me to do it any other way. Haven't the
problems associated with acting on invalid input of any sort been known
for decades?

                        Charlie
-- 
Nobody in this country got rich on his own.  You built a factory--good.
But you moved your goods on roads we all paid for.  You hired workers we
all paid to educate. So keep a big hunk of the money from your factory.
But take a hunk and pay it forward.  Elizabeth Warren (paraphrased)

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-11  2:39 Heartbleed Charles H. Sampson
@ 2014-04-11  7:59 ` Maciej Sobczak
  2014-04-11 10:50   ` Heartbleed Pascal J. Bourguignon
  2014-04-12  1:46   ` Heartbleed Charles H. Sampson
  2014-04-11 12:43 ` Heartbleed kalvin.news
  2014-04-18 17:24 ` Heartbleed - attacks? Alan Browne
  2 siblings, 2 replies; 144+ messages in thread
From: Maciej Sobczak @ 2014-04-11  7:59 UTC (permalink / raw)


W dniu piątek, 11 kwietnia 2014 04:39:18 UTC+2 użytkownik Charles H. Sampson napisał:

> According to Wikipedia, the Heartbleed bug in OpenSSL is caused by
> two errors: Lack of bounds checking and failure to verify that the
> heartbeat request was valid. Whom does one express one's indignation to?

The following page answers your question:

http://www.openssl.org/source/license.html

The part written in CAPITAL LETTERS is specifically focused on this.

> The insistence of many in our "profession" on using C and its decendents
> is the reason I qualify the word "profession" when writing about
> software developers.

Every general statement has some exceptions. Even though *in general* you are right, in this particular case things work a bit differently. OpenSSL is ntended as a common component that is used by everybody else. In order to achieve this you need to choose the technology that is a common denominator, both in terms of the ability to link with it and in terms of the availability of toolchains.
Now, you might argue that is is possible to write the library in Ada in such a way that it can be reused from other languages, it is not easy to do so, especially if you take into account the (un)availability of language runtime. The biggest issue, however, is the availability of compilers.

Saying that this stuff should have been written in Ada is pointless.

> Acting on a message without validating it is
> equally incomprenhensible to me.

That's right.

> For the latter, someone needs a severe rebuke on his next
> performance review, at the least.

I am not aware of performance reviews for people who voluntarily contribute on their free time. Not sure if that was the case for this particular piece of code, but anyway, read the license again. The fact that somebody wrote crappy piece of code is part of the whole problem - the other part is that we (yes, the whole world) choose to use it. Who is to blame?

> It so happens that for the last project I worked on, I was
> responsible for TCP/IP communication.

Put it in your CV, then.

-- 
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-11  7:59 ` Heartbleed Maciej Sobczak
@ 2014-04-11 10:50   ` Pascal J. Bourguignon
  2014-04-12  1:46   ` Heartbleed Charles H. Sampson
  1 sibling, 0 replies; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-11 10:50 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> W dniu piątek, 11 kwietnia 2014 04:39:18 UTC+2 użytkownik Charles H. Sampson napisał:
>
>> According to Wikipedia, the Heartbleed bug in OpenSSL is caused by
>> two errors: Lack of bounds checking and failure to verify that the
>> heartbeat request was valid. Whom does one express one's indignation to?
>
> The following page answers your question:
>
> http://www.openssl.org/source/license.html
>
> The part written in CAPITAL LETTERS is specifically focused on this.
>
>> The insistence of many in our "profession" on using C and its decendents
>> is the reason I qualify the word "profession" when writing about
>> software developers.
>
> Every general statement has some exceptions. Even though *in general*
> you are right, in this particular case things work a bit
> differently. OpenSSL is ntended as a common component that is used by
> everybody else. In order to achieve this you need to choose the
> technology that is a common denominator, both in terms of the ability
> to link with it and in terms of the availability of toolchains.
> Now, you might argue that is is possible to write the library in Ada
> in such a way that it can be reused from other languages, it is not
> easy to do so, especially if you take into account the
> (un)availability of language runtime. The biggest issue, however, is
> the availability of compilers.
>
> Saying that this stuff should have been written in Ada is pointless.


Yes, there's nothing magical in C, one can write libc in any language.

Furthermore, the C standard all define such constructs as illegal,
errors or leave their semantics as undefined.

Therefore the problem is not with the language, but much more with the
C programmers and C compiler programmers, because it would be perfectly
valid a compiler, one that would add run-time bound checks (in addition
to compilation time errors or warnings), with the associated
("undefined" by the language, but defined by the specific C
implementation/compiler) corresponding exception processing.

(And given the memory caches and pilelined processor architectures we
have nowadays, it wouldn't even have any noticeable performance hit).



>> Acting on a message without validating it is
>> equally incomprenhensible to me.
>
> That's right.
>
>> For the latter, someone needs a severe rebuke on his next
>> performance review, at the least.
>
> I am not aware of performance reviews for people who voluntarily
> contribute on their free time. Not sure if that was the case for this
> particular piece of code, but anyway, read the license again. The fact
> that somebody wrote crappy piece of code is part of the whole problem
> - the other part is that we (yes, the whole world) choose to use
> it. Who is to blame?

Definitely.

That said, we get to see and know it's a piece of shit: we've got the
freedom to do so.  With proprietary software, it's the same, only we
don't know it.

But when you want to write correct code, you explode the dead lines and
get fired long before you can complete it.


-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-11  2:39 Heartbleed Charles H. Sampson
  2014-04-11  7:59 ` Heartbleed Maciej Sobczak
@ 2014-04-11 12:43 ` kalvin.news
  2014-04-11 19:33   ` Heartbleed Simon Clubley
  2014-04-18 17:24 ` Heartbleed - attacks? Alan Browne
  2 siblings, 1 reply; 144+ messages in thread
From: kalvin.news @ 2014-04-11 12:43 UTC (permalink / raw)


As a (embedded) C programmer, I have seen over and over again similar problems appearing in the code I maintain. Also, I do make similar mistakes ie. miss the bounds checking in the functions as I (wrongly) assume that the bounds have been checked in upper levels which will eventually use my functions. Not to mention crappy pointer trickery. I do blame C in many respects, that it allows unsafe constructs and allows sloppy coding practices. I am also surprised (actually dissapointed) that C is used so widely. In my opinion, as a C programmer, C should not be allowed to be used at all. C is broken, C is bad. C++ is also broken and C++ is bad. I would like to see that programmers would adopt to something more secure programming language, which would make creating buggy and sloppy software a bit harder. Whether it is Ada or something else.

- KalvinK

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-11 12:43 ` Heartbleed kalvin.news
@ 2014-04-11 19:33   ` Simon Clubley
  2014-04-12  4:58     ` Heartbleed Shark8
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-11 19:33 UTC (permalink / raw)


On 2014-04-11, kalvin.news@gmail.com <kalvin.news@gmail.com> wrote:
> As a (embedded) C programmer, I have seen over and over again similar
> problems appearing in the code I maintain. Also, I do make similar mistakes
> ie. miss the bounds checking in the functions as I (wrongly) assume that
> the bounds have been checked in upper levels which will eventually use my
> functions. Not to mention crappy pointer trickery. I do blame C in many
> respects, that it allows unsafe constructs and allows sloppy coding
> practices. I am also surprised (actually dissapointed) that C is used so
> widely. In my opinion, as a C programmer, C should not be allowed to be
> used at all. C is broken, C is bad. C++ is also broken and C++ is bad. I
> would like to see that programmers would adopt to something more secure
> programming language, which would make creating buggy and sloppy software a
> bit harder. Whether it is Ada or something else.
>

I strongly agree with this.

C, even in 2014, is used for critical libraries so there's clearly a
place for a simpler language with comparable functionality to C, but
with the functionality done in a type safe way.

Sadly, I agree with a previous post that it's unlikely to be Ada because
of the vast range of systems these libraries run on and because of the
major issues around getting Ada (which in this context really means GNAT)
to run in a new environment.

What may be a viable option would be if a simpler Wirth style language
existed and whose compiler generated object code compatible with gcc
and used binutils for it's assembling/linking phase. That compiler would
be written in plain C making it easier to bring up in a new environment
with foreign compilers.

For the libraries C is being used for and for which the security issues
exist, you don't need a huge Ada style runtime with a huge Ada style
language functionality that's damned difficult to port to a new
environment.

However, to stand a chance of displacing C you need a compiler which runs
in the same range of environments as C does and you need libraries written
using this language to be _easily_ callable from C and the other languages
which currently use C libraries. That's the reality anyone wanting to
replace C is facing.

BTW, once you have people exposed to type safe programming, then maybe
you can introduce them to Ada for the large projects. One of the major
revelations for me over Heartbleed was seeing people discuss the need
for a safer language and immediately jump to languages like Java.

The idea that there might be a option in between, a traditional compiled
language which offered type safe functionality simply didn't seem to
occur to them. It's as if C, C++ and Java are the only languages most
people seem to have heard about.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-11  7:59 ` Heartbleed Maciej Sobczak
  2014-04-11 10:50   ` Heartbleed Pascal J. Bourguignon
@ 2014-04-12  1:46   ` Charles H. Sampson
  1 sibling, 0 replies; 144+ messages in thread
From: Charles H. Sampson @ 2014-04-12  1:46 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> wrote:

> W dniu pi?tek, 11 kwietnia 2014 04:39:18 UTC+2 u?ytkownik Charles H. Sampson
>  napisa?:
> 
> > It so happens that for the last project I worked on, I was
> > responsible for TCP/IP communication.
> 
> Put it in your CV, then.

     No point. That was the last project ever that I worked on. ;-)

                                Charlie
-- 
Nobody in this country got rich on his own.  You built a factory--good.
But you moved your goods on roads we all paid for.  You hired workers we
all paid to educate. So keep a big hunk of the money from your factory.
But take a hunk and pay it forward.  Elizabeth Warren (paraphrased)


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-11 19:33   ` Heartbleed Simon Clubley
@ 2014-04-12  4:58     ` Shark8
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
                         ` (3 more replies)
  0 siblings, 4 replies; 144+ messages in thread
From: Shark8 @ 2014-04-12  4:58 UTC (permalink / raw)


On 11-Apr-14 13:33, Simon Clubley wrote:
> On 2014-04-11, kalvin.news@gmail.com <kalvin.news@gmail.com> wrote:
>> As a (embedded) C programmer, I have seen over and over again similar
>> problems appearing in the code I maintain. Also, I do make similar mistakes
>> ie. miss the bounds checking in the functions as I (wrongly) assume that
>> the bounds have been checked in upper levels which will eventually use my
>> functions. Not to mention crappy pointer trickery. I do blame C in many
>> respects, that it allows unsafe constructs and allows sloppy coding
>> practices. I am also surprised (actually dissapointed) that C is used so
>> widely. In my opinion, as a C programmer, C should not be allowed to be
>> used at all. C is broken, C is bad. C++ is also broken and C++ is bad. I
>> would like to see that programmers would adopt to something more secure
>> programming language, which would make creating buggy and sloppy software a
>> bit harder. Whether it is Ada or something else.
>>
>
> I strongly agree with this.
>
> C, even in 2014, is used for critical libraries so there's clearly a
> place for a simpler language with comparable functionality to C, but
> with the functionality done in a type safe way.
>
> Sadly, I agree with a previous post that it's unlikely to be Ada because
> of the vast range of systems these libraries run on and because of the
> major issues around getting Ada (which in this context really means GNAT)
> to run in a new environment.

Well, there are several of us who are looking into ameliorate that 
condition w/ new open-source compilers.

> What may be a viable option would be if a simpler Wirth style language
> existed and whose compiler generated object code compatible with gcc
> and used binutils for it's assembling/linking phase.

Oberon?

> That compiler would be written in plain C making it easier to bring up
> in a new environment with foreign compilers.

I disagree; the compilers we build should *not* be dependent on C. -- 
There are too many easy-to-make errors, mistakes, and 
implementation-dependencies to really ensure that such a compiler is 
good. Indeed, I would argue that we need compilers built on 
formal-methods and verified to be correct.

> For the libraries C is being used for and for which the security issues
> exist, you don't need a huge Ada style runtime with a huge Ada style
> language functionality that's damned difficult to port to a new
> environment.

I wonder about that; is the runtime that difficult to port? What about 
having "staged" runtimes, with minimal, reduced, and nominal 
functionality? (Perhaps using the restriction pragmas...)

Also, couldn't such a system be made so that the *really* system 
dependent stuff is all hidden in a package-body and [relatively] easy to 
port?

eg
Minimal : No tasking or protected objects, or unconstrained functions 
allowed.
Reduced : No Tasking and Protected objects; but unconstrained functions 
are allowed.
Normal  : Everything.

> However, to stand a chance of displacing C you need a compiler which runs
> in the same range of environments as C does and you need libraries written
> using this language to be _easily_ callable from C and the other languages
> which currently use C libraries. That's the reality anyone wanting to
> replace C is facing.

I don't know -- it might be time for professionals concerned w/ security 
to make a clean break and just use something else -- Eiffel is, from 
what I understand, ideal for library-writing with its heavy emphasis on 
interfaces [and design by contract].

> BTW, once you have people exposed to type safe programming, then maybe
> you can introduce them to Ada for the large projects. One of the major
> revelations for me over Heartbleed was seeing people discuss the need
> for a safer language and immediately jump to languages like Java.

Hm, good point.
Ada has some *REALLY* good features when it comes to 
programming-in-the-large -- the YF-22 integration is astounding:
12 major avionics subsystems, across 650 Ada modules containing millions 
of lines of code, coded in 8 geographically distinct locations, took 
*three days!*

Source: http://archive.adaic.com/docs/present/engle/comments/tsld033.htm

> The idea that there might be a option in between, a traditional compiled
> language which offered type safe functionality simply didn't seem to
> occur to them. It's as if C, C++ and Java are the only languages most
> people seem to have heard about.

Yeah -- that's rather disgusting. I blame the prevalence of c-style 
languages as well as universities 'targeting' them (that is to say 
ignoring non-C-style languages).

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  4:58     ` Heartbleed Shark8
@ 2014-04-12  7:15       ` Nasser M. Abbasi
  2014-04-12  9:28         ` Heartbleed Georg Bauhaus
                           ` (3 more replies)
  2014-04-12 18:22       ` Heartbleed Yannick Duchêne (Hibou57)
                         ` (2 subsequent siblings)
  3 siblings, 4 replies; 144+ messages in thread
From: Nasser M. Abbasi @ 2014-04-12  7:15 UTC (permalink / raw)


On 4/11/2014 11:58 PM, Shark8 wrote:

> Yeah -- that's rather disgusting. I blame the prevalence of c-style
> languages as well as universities 'targeting' them (that is to say
> ignoring non-C-style languages).
>

It is all about libraries, not the language itself.

At school, Matlab is used for everything in engineering.
Everyone knows that Matlab as a language is not robust
and not safe by any means (it has no typing and no
protection against making simple and silly errors that
can take long time to find)

But it is the main tool used to write all types of
engineering and scientific tools in engineering.
Python also is weakly typed.  R is also the same. Same
for Javascript, etc... Mathematica the same, no
typing, but lots of useful packages and commands build
into it.

Many languages used today are weakly typed, not safe,
and one can easily produce programs full of bugs
using them.

They are used, simply because they come with ready to
use and large number of useful packages to do all sorts
of things, and many allow one to easily make plots and
visualization on the fly.

C++ these days is used by many for numerical computation,
even more than Fortran, though I think Ada is a much
better language for this due to its strong typing
and subtype system, but Ada has almost no useful numerical
libraries ready to use. Nothing close to what C++ has
these days. In Ada, one has to write many things from
scratch.

Until this is fixed in Ada, it would make no difference how
safe and robust Ada as a language is. You can make Ada
100% more safe than it is today, and it will still not be
used and adopted by the masses. It is like having a very
powerful and safe car, but with no gas.  Not very useful.

What Ada needs is CRAN like package collection site, as
with R or CTAN package collection site as with Latex. A
place one can go to find and use Ada standard packages.
That would help. But this requires large community
and lots of resources to do. Ada also need much larger
standard libraries build into it.

my 2 cents on the subject.

--Nasser

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
@ 2014-04-12  9:28         ` Georg Bauhaus
  2014-04-12  9:33         ` Heartbleed Georg Bauhaus
                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-12  9:28 UTC (permalink / raw)


On 12/04/14 09:15, Nasser M. Abbasi wrote:
> Until this is fixed in Ada, it would make no difference how
> safe and robust Ada as a language is.

One trend in language design seems to be adding the "usual suspects"
of current compiler research to popular languages. Traits, generic
classes, nullable, async, lambdas, optional static type checking
... as present in the Hack language, for example, which is PHP so
amended.

Facebook has bought famous C++/D people and others to help
them with languages. Nothing like Ada is involved, I guess.
But a lot of money and (perceived) popularity are in it.

Maybe Ada would have to overcome its reputation and offer
a model of a good fundamental type system (for scalar types)
that, if added to C, fixes a number of issues in C. Using this
dialect, then, neither C programmers nor Ada programmers would
lose face or have to swallow pride.

I.e., let embedded programming drop "int", also add better arrays
to C arrays and most CVEs will be gone for good!

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
  2014-04-12  9:28         ` Heartbleed Georg Bauhaus
@ 2014-04-12  9:33         ` Georg Bauhaus
  2014-04-12 11:42         ` Heartbleed Pascal J. Bourguignon
  2014-04-12 14:58         ` Heartbleed Dennis Lee Bieber
  3 siblings, 0 replies; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-12  9:33 UTC (permalink / raw)


On 12/04/14 09:15, Nasser M. Abbasi wrote:

> Until this is fixed in Ada, it would make no difference how
> safe and robust Ada as a language is. You can make Ada
> 100% more safe than it is today, and it will still not be
> used and adopted by the masses.

One trend in language design seems to be adding the "usual suspects"
of current compiler research to popular languages. Traits, generic
classes, nullable, async, lambdas, optional static type checking
... as present in the Hack language, for example, which is PHP so
amended.

Facebook has hired famous C++/D people and others to help
them with languages. Nothing like Ada is involved, I guess.
But a lot of money and popularity are in it.

Maybe Ada would have to overcome its reputation and just offer
a model of a good fundamental type system (for scalar types)
that, if added to C, fixes a number of issues in C. Using this
dialect, then, neither C programmers nor Ada programmers would
lose face or have to swallow pride.

I.e., let the embedded programming profession drop "int",
also add better arrays to C and most CVEs will be gone for good!



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
  2014-04-12  9:28         ` Heartbleed Georg Bauhaus
  2014-04-12  9:33         ` Heartbleed Georg Bauhaus
@ 2014-04-12 11:42         ` Pascal J. Bourguignon
  2014-04-12 15:37           ` Heartbleed Nasser M. Abbasi
  2014-04-12 18:39           ` Heartbleed Simon Wright
  2014-04-12 14:58         ` Heartbleed Dennis Lee Bieber
  3 siblings, 2 replies; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-12 11:42 UTC (permalink / raw)


"Nasser M. Abbasi" <nma@12000.org> writes:

> Python also is weakly typed.  

You're wrong.  Compare:

    [pjb@kuiper :0.0 web]$ python
    Python 2.7.3 (default, Jan  2 2013, 13:56:14) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> "abc"+2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: cannot concatenate 'str' and 'int' objects
    >>> 


with:

    [pjb@kuiper :0.0 tmp]$ cd /tmp ; cat a.c && gcc -o a a.c && ./a
    #include <stdio.h>
    int main(){
        printf("%s\n","abc"+2);
        return 0;
    }
    c
    [pjb@kuiper :0.0 tmp]$ 



What you mean is that Python is a late STRONGLY typed programming
language, while C is a early WEAKLY typed programming language.

Other languages are even more STRONGLY late typed programming languages
(eg Common Lisp).   There are also good early strongly typed programming
language like Haskell.   But strongly late dynamically typed programming
languages are probably better for mission critical systems, since they
can adapt dynamically the type of the values at run-time, instead of
crashing.


-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
                           ` (2 preceding siblings ...)
  2014-04-12 11:42         ` Heartbleed Pascal J. Bourguignon
@ 2014-04-12 14:58         ` Dennis Lee Bieber
  2014-04-12 18:28           ` Heartbleed Yannick Duchêne (Hibou57)
  3 siblings, 1 reply; 144+ messages in thread
From: Dennis Lee Bieber @ 2014-04-12 14:58 UTC (permalink / raw)


On Sat, 12 Apr 2014 02:15:44 -0500, "Nasser M. Abbasi" <nma@12000.org>
declaimed the following:

>Python also is weakly typed.  R is also the same. Same

	Python is very strongly typed... But the .names/ referring to objects
are not typed.

	X = 1
	X = 3.14
	Y = X

translates into:

	Create an integer object with the value 1 somewhere in memory (small
integers tend to be cached, so the object may already exist); attach the
name X to that object

	Create a float object with the value 3.14 somewhere in memory; remove
the name X from the integer object (which, if no other names are attached,
is now free to be garbage collected) and attach it to the float object

	Attach the name Y to the object that currently has the name X; the
object now has two names attached

	No operations in Python will ever change the type of the object itself.
You can only transform the value by creating a new object

	Z = int(Y)

obtain the value of the object to which the name Y is attached, convert
that value to an integer creating a new integer object somewhere in memory,
attach the name Z to that object.

>>> X = 1
>>> id(X)
4473416L
>>> X = 3.14
>>> id(X)
4534928L
>>> id(1)
4473416L
	Cached small integer, same object as first assignment

>>> Y = X
>>> id(Y)
4534928L
>>> id(X)
4534928L
	X and Y are two names for the same object

>>> Z = int(Y)
>>> id(Z)
4473368L
>>> id(3)
4473368L
>>> 
	Cached small integer
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 11:42         ` Heartbleed Pascal J. Bourguignon
@ 2014-04-12 15:37           ` Nasser M. Abbasi
  2014-04-12 18:56             ` Heartbleed Pascal J. Bourguignon
  2014-04-12 18:39           ` Heartbleed Simon Wright
  1 sibling, 1 reply; 144+ messages in thread
From: Nasser M. Abbasi @ 2014-04-12 15:37 UTC (permalink / raw)


On 4/12/2014 6:42 AM, Pascal J. Bourguignon wrote:
> "Nasser M. Abbasi" <nma@12000.org> writes:
>
>> Python also is weakly typed.
>
> You're wrong.  Compare:

How can I be wrong when in Python variables do not even have
types, only values do.

But any way, I was comparing it to Ada strong variable type
system.  

>>> a=float(1);
>>> b=int(1);
>>> c=a+b;

The above will not even compile in Ada. Mixing apples and
oranges.

Python is not a language I would use to write robust
software that if failed, people can die as a result. Lets
leave it here.

--Nasser



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  4:58     ` Heartbleed Shark8
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
@ 2014-04-12 18:22       ` Yannick Duchêne (Hibou57)
  2014-04-12 18:38       ` Heartbleed Simon Clubley
  2014-04-12 22:01       ` Heartbleed Yannick Duchêne (Hibou57)
  3 siblings, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 18:22 UTC (permalink / raw)


Le Sat, 12 Apr 2014 06:58:29 +0200, Shark8 <OneWingedShark@gmail.com> a  
écrit:
>> That compiler would be written in plain C making it easier to bring up
>> in a new environment with foreign compilers.
>
> I disagree; the compilers we build should *not* be dependent on C. --  
> There are too many easy-to-make errors, mistakes, and  
> implementation-dependencies to really ensure that such a compiler is  
> good. Indeed, I would argue that we need compilers built on  
> formal-methods and verified to be correct.

That's precisely the case, there are formally specified subsets of C (some  
large enough to cover near to all of C) and obviously, formal models for  
these subsets of C.

I don't really enjoy it, because it relies on Coq (which relies on OCaml,  
… unsafe to me), here is still the most famous formally verified C  
compiler with a formal C model: http://compcert.inria.fr/ (requires Coq  
and OCaml).

I however believe formal methods with Ada and/or SML (this one is the most  
easy path to me), is more human friendly than formal methods with C. It  
also has a benefit, in case a formally developed piece of software, is  
tweaked without formal methods any more (it will surely breaks something,  
still less than with C).


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 14:58         ` Heartbleed Dennis Lee Bieber
@ 2014-04-12 18:28           ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 18:28 UTC (permalink / raw)


Le Sat, 12 Apr 2014 16:58:42 +0200, Dennis Lee Bieber  
<wlfraed@ix.netcom.com> a écrit:

> On Sat, 12 Apr 2014 02:15:44 -0500, "Nasser M. Abbasi" <nma@12000.org>
> declaimed the following:
>
>> Python also is weakly typed.  R is also the same. Same
>
> 	Python is very strongly typed... But the .names/ referring to objects
> are not typed.

It also has to be statically checked, otherwise this is useless.

-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  4:58     ` Heartbleed Shark8
  2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
  2014-04-12 18:22       ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-12 18:38       ` Simon Clubley
  2014-04-12 20:24         ` Heartbleed Yannick Duchêne (Hibou57)
                           ` (3 more replies)
  2014-04-12 22:01       ` Heartbleed Yannick Duchêne (Hibou57)
  3 siblings, 4 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-12 18:38 UTC (permalink / raw)


On 2014-04-12, Shark8 <OneWingedShark@gmail.com> wrote:
> On 11-Apr-14 13:33, Simon Clubley wrote:
>>
>> C, even in 2014, is used for critical libraries so there's clearly a
>> place for a simpler language with comparable functionality to C, but
>> with the functionality done in a type safe way.
>>
>> Sadly, I agree with a previous post that it's unlikely to be Ada because
>> of the vast range of systems these libraries run on and because of the
>> major issues around getting Ada (which in this context really means GNAT)
>> to run in a new environment.
>
> Well, there are several of us who are looking into ameliorate that 
> condition w/ new open-source compilers.
>

Will these new compilers be easy to port to a new environment or will
the size and functionality of the Ada language make porting a major task ?

>> What may be a viable option would be if a simpler Wirth style language
>> existed and whose compiler generated object code compatible with gcc
>> and used binutils for it's assembling/linking phase.
>
> Oberon?
>

Something based on one of the Oberon variants is _exactly_ the kind of
thing I was thinking of. I would modify some of the syntax elements to
make them more Ada like however.

You know, Oberon-14 sounds like a nice name for a new programming
language. :-)

>> That compiler would be written in plain C making it easier to bring up
>> in a new environment with foreign compilers.
>
> I disagree; the compilers we build should *not* be dependent on C. -- 
> There are too many easy-to-make errors, mistakes, and 
> implementation-dependencies to really ensure that such a compiler is 
> good. Indeed, I would argue that we need compilers built on 
> formal-methods and verified to be correct.
>

Careful; you need to think of the big picture here.

The goal here is to replace C when writing libraries which are used on
a vast range of platforms (like OpenSSL). That simply isn't going to
happen unless the compiler runs on the same range of platforms C compilers
currently run on and unless the code generator in the compiler generates 
code for the same range of targets the C compilers currently do.

You can have all the nice formally verifiable capable implementation
languages you want, but that does nothing to challenge C's status in the
market place unless the above conditions are met. This is _exactly_
the situation we are in with Ada right now and why everyone uses C instead
of Ada or SPARK.

Also, you only need to implement the core compiler in C; the RTL and
support libraries for the language can be pretty much implemented in the
language itself.

You can assume there's a C compiler and binutils on the host platform,
but you can't really assume much else.

>> For the libraries C is being used for and for which the security issues
>> exist, you don't need a huge Ada style runtime with a huge Ada style
>> language functionality that's damned difficult to port to a new
>> environment.
>
> I wonder about that; is the runtime that difficult to port? What about 
> having "staged" runtimes, with minimal, reduced, and nominal 
> functionality? (Perhaps using the restriction pragmas...)
>
> Also, couldn't such a system be made so that the *really* system 
> dependent stuff is all hidden in a package-body and [relatively] easy to 
> port?
>
> eg
> Minimal : No tasking or protected objects, or unconstrained functions 
> allowed.
> Reduced : No Tasking and Protected objects; but unconstrained functions 
> are allowed.
> Normal  : Everything.
>

People like Luke who have tried this in the past always seem to run up
against various random issues which can make things seem fragile. I've
read Luke's change logs in the past and have seen how much effort he's
expended trying to get it running on just one or two bare metal platforms.

>> However, to stand a chance of displacing C you need a compiler which runs
>> in the same range of environments as C does and you need libraries written
>> using this language to be _easily_ callable from C and the other languages
>> which currently use C libraries. That's the reality anyone wanting to
>> replace C is facing.
>
> I don't know -- it might be time for professionals concerned w/ security 
> to make a clean break and just use something else -- Eiffel is, from 
> what I understand, ideal for library-writing with its heavy emphasis on 
> interfaces [and design by contract].
>

That simply, absolutely, is not going to happen.

The only chance you have of displacing C is to allow libraries written in
your new language to be linked against just as easily as C libraries
currently can be.

No corporation or other entity is going to throw away all it's existing
code just to use a new library. Either libraries written in your new
language can be made to fit into the existing application code base or
the new library will not be used in any major way.

For a specific example: if you want to write a new SSL library in, say,
Oberon-14, it has to plug into the existing code which uses the existing
OpenSSL library or it simply will _not_ get used. This includes your new
library needing to run on the vast range of platforms the OpenSSL library
runs on, including those el-cheapo ADSL modems/routers and other commodity
devices.

That's the real world reality you are up against if you want to replace C.

However, once you have your foot in the door, you can then start gradually
using your new type safe language in more and more libraries and even
application code.

In that way, people don't have to start making major investments just to
try out your new language. This means it's much more likely they are
going to explore libraries written in it if they feel like they can stay
in control of the process and feel they can easily reverse the process
if it doesn't work out as expected.

>> BTW, once you have people exposed to type safe programming, then maybe
>> you can introduce them to Ada for the large projects. One of the major
>> revelations for me over Heartbleed was seeing people discuss the need
>> for a safer language and immediately jump to languages like Java.
>
> Hm, good point.
> Ada has some *REALLY* good features when it comes to 
> programming-in-the-large -- the YF-22 integration is astounding:
> 12 major avionics subsystems, across 650 Ada modules containing millions 
> of lines of code, coded in 8 geographically distinct locations, took 
> *three days!*
>
> Source: http://archive.adaic.com/docs/present/engle/comments/tsld033.htm
>
>> The idea that there might be a option in between, a traditional compiled
>> language which offered type safe functionality simply didn't seem to
>> occur to them. It's as if C, C++ and Java are the only languages most
>> people seem to have heard about.
>
> Yeah -- that's rather disgusting. I blame the prevalence of c-style 
> languages as well as universities 'targeting' them (that is to say 
> ignoring non-C-style languages).
>

I already knew about this at some level, but it was quite interesting
actually seeing it happen on the technical forums/discussion groups
over the last few days.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 11:42         ` Heartbleed Pascal J. Bourguignon
  2014-04-12 15:37           ` Heartbleed Nasser M. Abbasi
@ 2014-04-12 18:39           ` Simon Wright
  2014-04-12 19:15             ` Heartbleed Pascal J. Bourguignon
  1 sibling, 1 reply; 144+ messages in thread
From: Simon Wright @ 2014-04-12 18:39 UTC (permalink / raw)


"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

> But strongly late dynamically typed programming languages are probably
> better for mission critical systems, since they can adapt dynamically
> the type of the values at run-time, instead of crashing.

If the system designers have thought about what to do under such
circumstances so that the system can carry on, OK,

If not, the system is operating outside its design envelope, which I
think is equivalent to the Ada "erroneous behaviour; so you don't know
_what_ it will do, and the best response is probably to fall back to a
pre-planned recovery mode. Or, as you say, to crash; which has at least
the virtue, during development, of making it obvious that there's a
problem to be fixed.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 15:37           ` Heartbleed Nasser M. Abbasi
@ 2014-04-12 18:56             ` Pascal J. Bourguignon
  2014-04-12 20:29               ` Heartbleed Yannick Duchêne (Hibou57)
                                 ` (2 more replies)
  0 siblings, 3 replies; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-12 18:56 UTC (permalink / raw)


"Nasser M. Abbasi" <nma@12000.org> writes:

> On 4/12/2014 6:42 AM, Pascal J. Bourguignon wrote:
>> "Nasser M. Abbasi" <nma@12000.org> writes:
>>
>>> Python also is weakly typed.
>>
>> You're wrong.  Compare:
>
> How can I be wrong when in Python variables do not even have
> types, only values do.
>
> But any way, I was comparing it to Ada strong variable type
> system.  

That's the whole point.  

Typing values instead of typing variables is stronger.

When you have a system where all the values are typed, if there's a bug
(either because the language allows unsafe operations, or because
there's a bug in the system, or because there's a hardware failure), you
still have the assurance that only operations valid for this type of
value can be applied to it.

And the specific operation applied is dispatched at run-time, depending
on the type of value we encounter at run-time.  





>>>> a=float(1);
>>>> b=int(1);
>>>> c=a+b;
>
> The above will not even compile in Ada. Mixing apples and
> oranges.
>
> Python is not a language I would use to write robust
> software that if failed, people can die as a result. Lets
> leave it here.

IIRC, Ariane 5 software was written in Ada.
http://www.di.unito.it/~damiani/ariane5rep.html
In a language like lisp or python, the arithmetic operations that can't
produce fixnums automatically produce bignums, and all the code will
automatically handle bignums once the magnitudes require them.

Similarly, the Mars Climate Orbiter bug occured in statically typed
programming language: variables containing different units were still of
the same floating point data type.  
http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure

A dynamically strongly typed-value programming language such as Lisp or
Python would have used objects containing both the magnitude and the
unit, and an operation mixing objects of different units would have
involved an automatic unit conversion.


In both cases, the customer could still consider that a bug exist (in
the case of Ariane 5 it was a specification "bug", so…), in that
operations could become slower than expected, but with  dynamically
typed-value system, you would still get correct results.  And in a
control system, it is better to generate correct control commands at
half the expected rate, than to crash or produce  bad control commands
at the initially specified rate.


-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:39           ` Heartbleed Simon Wright
@ 2014-04-12 19:15             ` Pascal J. Bourguignon
  2014-04-12 19:18               ` Heartbleed Pascal J. Bourguignon
                                 ` (3 more replies)
  0 siblings, 4 replies; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-12 19:15 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> "Pascal J. Bourguignon" <pjb@informatimago.com> writes:
>
>> But strongly late dynamically typed programming languages are probably
>> better for mission critical systems, since they can adapt dynamically
>> the type of the values at run-time, instead of crashing.
>
> If the system designers have thought about what to do under such
> circumstances so that the system can carry on, OK,
>
> If not, the system is operating outside its design envelope, which I
> think is equivalent to the Ada "erroneous behaviour; so you don't know
> _what_ it will do, and the best response is probably to fall back to a
> pre-planned recovery mode. Or, as you say, to crash; which has at least
> the virtue, during development, of making it obvious that there's a
> problem to be fixed.

The Ariane 5 and Mars Climate Orbiter are proof that this is not the
right methodology.  Those systems were specified, developed with crashes
and erroneous behaviour during development, and all bugs were obvious
(to the point of making big explosions).  Oops, too late!


There are life-or-death systems that needs to continue running, even in
a degrated mode, whatever happens, whatever bug they may still contain
once deployed. 

Statically checked, variable-typed languages aren't up to the job for
those systems.

There will always be bugs remaining, even in tested and more
importantly, even in proven software!  Cf. for example, the Deep Space 1
RAX software, written in Lisp, and proven!  Despite the proof, a bug
remained.  If it had been a statically checked programming language, it
would have meant a terminal dead-lock or a crash (what else to do with a
static language when we reach a state that has been proved impossible?).
But since it was a dynamic programming language, (with very late
binding, including a on-board compiler), it was debugged and patched
remotely, as a last ressort solution.


-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 19:15             ` Heartbleed Pascal J. Bourguignon
@ 2014-04-12 19:18               ` Pascal J. Bourguignon
  2014-04-12 20:40               ` Heartbleed Yannick Duchêne (Hibou57)
                                 ` (2 subsequent siblings)
  3 siblings, 0 replies; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-12 19:18 UTC (permalink / raw)


"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

> There will always be bugs remaining, even in tested and more
> importantly, even in proven software!  Cf. for example, the Deep Space 1
> RAX software, written in Lisp, and proven!  Despite the proof, a bug
> remained.  If it had been a statically checked programming language, it
> would have meant a terminal dead-lock or a crash (what else to do with a
> static language when we reach a state that has been proved impossible?).
> But since it was a dynamic programming language, (with very late
> binding, including a on-board compiler), it was debugged and patched
> remotely, as a last ressort solution.

Reference:

Formal Analysis of the Remote Agent Before and After Flight
http://spinroot.com/spin/Doc/rax.pdf

-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:38       ` Heartbleed Simon Clubley
@ 2014-04-12 20:24         ` Yannick Duchêne (Hibou57)
  2014-04-12 21:48           ` Heartbleed Simon Clubley
  2014-04-17  6:15         ` Heartbleed Jacob Sparre Andersen
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 20:24 UTC (permalink / raw)


Le Sat, 12 Apr 2014 20:38:48 +0200, Simon Clubley  
<clubley@remove_me.eisner.decus.org-earth.ufp> a écrit:
>> I wonder about that; is the runtime that difficult to port? What about
>> having "staged" runtimes, with minimal, reduced, and nominal
>> functionality? (Perhaps using the restriction pragmas...)
>>
>> Also, couldn't such a system be made so that the *really* system
>> dependent stuff is all hidden in a package-body and [relatively] easy to
>> port?
>>
>> eg
>> Minimal : No tasking or protected objects, or unconstrained functions
>> allowed.
>> Reduced : No Tasking and Protected objects; but unconstrained functions
>> are allowed.
>> Normal  : Everything.
>>
>
> People like Luke who have tried this in the past

Who's Luke ?


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:56             ` Heartbleed Pascal J. Bourguignon
@ 2014-04-12 20:29               ` Yannick Duchêne (Hibou57)
  2014-04-12 20:34               ` Heartbleed Dmitry A. Kazakov
  2014-04-12 21:57               ` Heartbleed Niklas Holsti
  2 siblings, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 20:29 UTC (permalink / raw)


Le Sat, 12 Apr 2014 20:56:32 +0200, Pascal J. Bourguignon  
<pjb@informatimago.com> a écrit:
> IIRC, Ariane 5 software was written in Ada.
> http://www.di.unito.it/~damiani/ariane5rep.html
> In a language like lisp or python, the arithmetic operations that can't
> produce fixnums automatically produce bignums, and all the code will
> automatically handle bignums once the magnitudes require them.

It also has to be predictable, and bignums may not be.

Also about Ariane 5' flight 501, failure was more due by bypassed required  
re‑validation than due to Ada: new more powerful engine, however same  
software without re‑validation… it had to be wrong with an overflow sooner  
or later.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:56             ` Heartbleed Pascal J. Bourguignon
  2014-04-12 20:29               ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-12 20:34               ` Dmitry A. Kazakov
  2014-04-12 20:47                 ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-15 10:02                 ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-12 21:57               ` Heartbleed Niklas Holsti
  2 siblings, 2 replies; 144+ messages in thread
From: Dmitry A. Kazakov @ 2014-04-12 20:34 UTC (permalink / raw)


On Sat, 12 Apr 2014 20:56:32 +0200, Pascal J. Bourguignon wrote:

> In a language like lisp or python, the arithmetic operations that can't
> produce fixnums automatically produce bignums, and all the code will
> automatically handle bignums once the magnitudes require them.

And then you send a the bignum garbage to the 12-bit ADC actuator? Good
luck with that.

> In both cases, the customer could still consider that a bug exist (in
> the case of Ariane 5 it was a specification "bug", so…), in that
> operations could become slower than expected, but with  dynamically
> typed-value system, you would still get correct results.

No, they are incorrect because violate the contract derived from the
physical system being controlled.

It is a common delusion that mathematically correct results are correct
when dealing with a physical system. They are no longer the model according
to which calculations are performed is adequate. Outside these constraints,
the model is garbage and numerically correct results are garbage as well.

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

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 19:15             ` Heartbleed Pascal J. Bourguignon
  2014-04-12 19:18               ` Heartbleed Pascal J. Bourguignon
@ 2014-04-12 20:40               ` Yannick Duchêne (Hibou57)
  2014-04-12 20:44               ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-12 21:31               ` Heartbleed Niklas Holsti
  3 siblings, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 20:40 UTC (permalink / raw)


Le Sat, 12 Apr 2014 21:15:17 +0200, Pascal J. Bourguignon  
<pjb@informatimago.com> a écrit:
> There will always be bugs remaining, even in tested and more
> importantly, **even in proven software!**

Are you really sure? Can you point to at least one example please (except  
bad specifications)? Unless there is a soundness issue (some checker has  
this issue, and are known to has one, but the most famous ones don't) or  
else a specification error, I really can't see how. Note a specification  
error will fail with a dynamic language too: a dynamic language will do  
the wrong thing if you tell it to do the wrong thing, it won't guess and  
fix it‑self on your behalf. So, the only remaining possible case of  
“broken formally verified software” which is relevant here, is the one  
with a formal verifier which has soundness issues (possibly the so called  
Pollack-inconsistency, which is a human/formal‑system interface issue).  
Still note you can check a proof with different systems, and there are  
standard appearing to help in that matter. Ex. OpenTheory, a standard to  
import/export HOL proofs in a raw format, not human readable, but fully  
machine checkable. If the proof of a theory is checked with say, two or  
three different enough systems, it's very unlikely there is a issue with  
the proof.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 19:15             ` Heartbleed Pascal J. Bourguignon
  2014-04-12 19:18               ` Heartbleed Pascal J. Bourguignon
  2014-04-12 20:40               ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-12 20:44               ` Yannick Duchêne (Hibou57)
  2014-04-12 21:31               ` Heartbleed Niklas Holsti
  3 siblings, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 20:44 UTC (permalink / raw)


Le Sat, 12 Apr 2014 21:15:17 +0200, Pascal J. Bourguignon  
<pjb@informatimago.com> a écrit:

> Cf. for example, the Deep Space 1
> RAX software, written in Lisp, and proven!  Despite the proof, a bug
> remained.

What kind of bug was this? What was the system used to prove it? Also, was  
this an implementation derived from a theory, or an implementation proved  
importing a model of the implementation and language? What Lisp dialect?


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 20:34               ` Heartbleed Dmitry A. Kazakov
@ 2014-04-12 20:47                 ` Yannick Duchêne (Hibou57)
  2014-04-12 20:53                   ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-15 10:02                 ` Heartbleed Yannick Duchêne (Hibou57)
  1 sibling, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 20:47 UTC (permalink / raw)


Le Sat, 12 Apr 2014 22:34:49 +0200, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:
> It is a common delusion that mathematically correct results are correct
> when dealing with a physical system.

Exactly! Software (and even more hardware) science has to deal with  
specific restrictions, which are unknown from maths.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 20:47                 ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-12 20:53                   ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 20:53 UTC (permalink / raw)


Le Sat, 12 Apr 2014 22:47:47 +0200, Yannick Duchêne (Hibou57)  
<yannick_duchene@yahoo.fr> a écrit:

> Le Sat, 12 Apr 2014 22:34:49 +0200, Dmitry A. Kazakov  
> <mailbox@dmitry-kazakov.de> a écrit:
>> It is a common delusion that mathematically correct results are correct
>> when dealing with a physical system.
>
> Exactly! Software (and even more hardware) science has to deal with  
> specific restrictions, which are unknown from maths.

Sorry, should have said “pure maths” and not maths as a whole, as you can  
model physical and software constraints.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 19:15             ` Heartbleed Pascal J. Bourguignon
                                 ` (2 preceding siblings ...)
  2014-04-12 20:44               ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-12 21:31               ` Niklas Holsti
  3 siblings, 0 replies; 144+ messages in thread
From: Niklas Holsti @ 2014-04-12 21:31 UTC (permalink / raw)


On 14-04-12 21:15 , Pascal J. Bourguignon wrote:
> Simon Wright <simon@pushface.org> writes:
> 
>> "Pascal J. Bourguignon" <pjb@informatimago.com> writes:
>>
>>> But strongly late dynamically typed programming languages are probably
>>> better for mission critical systems, since they can adapt dynamically
>>> the type of the values at run-time, instead of crashing.
>>
>> If the system designers have thought about what to do under such
>> circumstances so that the system can carry on, OK,
>>
>> If not, the system is operating outside its design envelope, which I
>> think is equivalent to the Ada "erroneous behaviour; so you don't know
>> _what_ it will do, and the best response is probably to fall back to a
>> pre-planned recovery mode. Or, as you say, to crash; which has at least
>> the virtue, during development, of making it obvious that there's a
>> problem to be fixed.
> 
> The Ariane 5 and Mars Climate Orbiter are proof that this is not the
> right methodology.  Those systems were specified, developed with crashes
> and erroneous behaviour during development, and all bugs were obvious
> (to the point of making big explosions).  Oops, too late!

Your irony makes it hard to understand what you really mean.

So what would have been a better approach for the Ariane 5? As I
understand it, the catastrophic failure was not due to any SW technology
issue, but to the human choice of the wrong recovery action for a
particular run-time error (value out of range) which occurred in
different circumstances in the Ariane 4 and the Ariane 5. Nothing to do
with static typing, all to do with FMECA and proper requirements management.

How would the use of any other typing style have prevented the failure?
It seems to me that (given the choice of recovery action) the only
alternative would be not to detect the out-of-range value, which could
create other failure modes.

As for the Mars Climate Orbiter, the reason for that failure was a
mix-up of physical units of data: the producer and consumer assumed
different units, leading to "controlled but unintended flight into
atmosphere". That would have been difficult to prevent with any typing
scheme. Even if the concept of type in the programming language would
have included physical units, the data were computed in one program and
then transferred as input for another program, breaking the
type-checking chain. A failure of interface control and documentation.

> There are life-or-death systems that needs to continue running, even in
> a degrated mode, whatever happens, whatever bug they may still contain
> once deployed. 

"Whatever bug" is a bit unrealistic. But then, it depends on how far you
are willing to degrade the behaviour :-)

> Statically checked, variable-typed languages aren't up to the job for
> those systems.

That seems to be disproved by current and long practice. Remembering
that nothing is perfect, of course.

> There will always be bugs remaining, even in tested and more
> importantly, even in proven software!  Cf. for example, the Deep Space 1
> RAX software, written in Lisp, and proven!  Despite the proof, a bug
> remained.  If it had been a statically checked programming language, it
> would have meant a terminal dead-lock or a crash (what else to do with a
> static language when we reach a state that has been proved impossible?).

The usual: raise an exception to abandon that computation and to discard
the weird (part of) the state, then continue, if necessary in a degraded
mode.

Even if the SW is 100% correct, HW failures (for example,
radiation-induced bit-flips) can create unexpected states, and the SW
must have some resiliency for that. But some bit-flips are recoverable
only by reboot, whether the language is static or dynamic.

> But since it was a dynamic programming language, (with very late
> binding, including a on-board compiler), it was debugged and patched
> remotely, as a last ressort solution.

The programming language and compiler location are mostly irrelevant to
that. Software in spacecraft is routinely debugged remotely (but usually
not interactively) and patched in flight, whatever the language and
whether it is compiled to machine code or to some VM code. The most that
can be said IMO is that using a VM helps to isolate the code running in
the VM (perhaps less trusted) from the code running natively (perhaps
more trusted).

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 20:24         ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-12 21:48           ` Simon Clubley
  0 siblings, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-12 21:48 UTC (permalink / raw)


On 2014-04-12, Yannick Duchêne <yannick_duchene@yahoo.fr> wrote:
> Le Sat, 12 Apr 2014 20:38:48 +0200, Simon Clubley  
><clubley@remove_me.eisner.decus.org-earth.ufp> a écrit:
>>> I wonder about that; is the runtime that difficult to port? What about
>>> having "staged" runtimes, with minimal, reduced, and nominal
>>> functionality? (Perhaps using the restriction pragmas...)
>>>
>>> Also, couldn't such a system be made so that the *really* system
>>> dependent stuff is all hidden in a package-body and [relatively] easy to
>>> port?
>>>
>>> eg
>>> Minimal : No tasking or protected objects, or unconstrained functions
>>> allowed.
>>> Reduced : No Tasking and Protected objects; but unconstrained functions
>>> are allowed.
>>> Normal  : Everything.
>>>
>>
>> People like Luke who have tried this in the past
>
> Who's Luke ?
>

Luke A. Guest. He's done work on getting GNAT running in bare metal mode
on the ARM and (IIRC) PIC32 architectures.

This appears to be Luke's GitHub repository list:

https://github.com/Lucretia?tab=repositories

(BTW, I think the cat is cute. :-))

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:56             ` Heartbleed Pascal J. Bourguignon
  2014-04-12 20:29               ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-12 20:34               ` Heartbleed Dmitry A. Kazakov
@ 2014-04-12 21:57               ` Niklas Holsti
  2014-04-13 13:08                 ` Heartbleed Georg Bauhaus
  2 siblings, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-04-12 21:57 UTC (permalink / raw)


On 14-04-12 20:56 , Pascal J. Bourguignon wrote:
> 
> IIRC, Ariane 5 software was written in Ada.

Still is, I believe, but irrelevant to the failure AIUI.

> http://www.di.unito.it/~damiani/ariane5rep.html
> In a language like lisp or python, the arithmetic operations that can't
> produce fixnums automatically produce bignums, and all the code will
> automatically handle bignums once the magnitudes require them.

But, as I understand it, that out-of-range value was then to be put into
some HW or telemetry field with a fixed size; the bignum would have to
be converted to a fixnum; the out-of-range error would happen (one
hopes), and there we are again.

> Similarly, the Mars Climate Orbiter bug occured in statically typed
> programming language: variables containing different units were still of
> the same floating point data type.  
> http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure
> 
> A dynamically strongly typed-value programming language such as Lisp or
> Python would have used objects containing both the magnitude and the
> unit, and an operation mixing objects of different units would have
> involved an automatic unit conversion.

Except that the data were produced in one program and then given as
input to another program, breaking the type-checking chain.

Moreover, I don't see how you can be sure that a Lisp or Python
implementation *would* have used run-time unit tags. And finally, as
GNAT now shows, unit checking can be done statically with types, which
is always IMO better for this kind of systems.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12  4:58     ` Heartbleed Shark8
                         ` (2 preceding siblings ...)
  2014-04-12 18:38       ` Heartbleed Simon Clubley
@ 2014-04-12 22:01       ` Yannick Duchêne (Hibou57)
  2014-04-18 17:58         ` Heartbleed Alan Browne
  3 siblings, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-12 22:01 UTC (permalink / raw)


Le Sat, 12 Apr 2014 06:58:29 +0200, Shark8 <OneWingedShark@gmail.com> a  
écrit:

>> BTW, once you have people exposed to type safe programming, then maybe
>> you can introduce them to Ada for the large projects. One of the major
>> revelations for me over Heartbleed was seeing people discuss the need
>> for a safer language and immediately jump to languages like Java.
>
> Hm, good point.
> Ada has some *REALLY* good features when it comes to  
> programming-in-the-large -- the YF-22 integration is astounding:
> 12 major avionics subsystems, across 650 Ada modules containing millions  
> of lines of code, coded in 8 geographically distinct locations, took  
> *three days!*
>
> Source: http://archive.adaic.com/docs/present/engle/comments/tsld033.htm

While Ada certainly played an important role in this success story,  
another as much important role was certainly humans… how did they  
communicate between each others? I mean, what documentation techniques and  
systems was used? Was the style guide(s) homogeneous or heterogeneous? Did  
they used some kind of maps to handle the big lines before diving into the  
details?

I would enjoy a lot to know the answers to these questions.

-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 21:57               ` Heartbleed Niklas Holsti
@ 2014-04-13 13:08                 ` Georg Bauhaus
  2014-04-13 13:55                   ` Heartbleed Pascal J. Bourguignon
  0 siblings, 1 reply; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-13 13:08 UTC (permalink / raw)


On 12/04/14 23:57, Niklas Holsti wrote:

> Moreover, I don't see how you can be sure that a Lisp or Python
> implementation *would* have used run-time unit tags. And finally, as
> GNAT now shows, unit checking can be done statically with types, which
> is always IMO better for this kind of systems.

The suggestions consistently make me wonder how the generalization
- from: having fixed one error (with the help of an on-board Lisp
   compiler and remote programming)
- to: a universal, "oraculous" error handling capability of Lisp
   programs slips the attention of its promoters.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-13 13:08                 ` Heartbleed Georg Bauhaus
@ 2014-04-13 13:55                   ` Pascal J. Bourguignon
  2014-04-13 15:13                     ` Heartbleed Dennis Lee Bieber
  0 siblings, 1 reply; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-13 13:55 UTC (permalink / raw)


Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> writes:

> On 12/04/14 23:57, Niklas Holsti wrote:
>
>> Moreover, I don't see how you can be sure that a Lisp or Python
>> implementation *would* have used run-time unit tags. And finally, as
>> GNAT now shows, unit checking can be done statically with types, which
>> is always IMO better for this kind of systems.
>
> The suggestions consistently make me wonder how the generalization
> - from: having fixed one error (with the help of an on-board Lisp
>   compiler and remote programming)
> - to: a universal, "oraculous" error handling capability of Lisp
>   programs slips the attention of its promoters.

That's the difference between what the tools make easy vs. what the
tools render difficult to do.

To dig a swimming pool, you can choose between a spoon and a bulldozer too.

-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-13 13:55                   ` Heartbleed Pascal J. Bourguignon
@ 2014-04-13 15:13                     ` Dennis Lee Bieber
  2014-04-13 15:36                       ` Heartbleed Nasser M. Abbasi
  0 siblings, 1 reply; 144+ messages in thread
From: Dennis Lee Bieber @ 2014-04-13 15:13 UTC (permalink / raw)


On Sun, 13 Apr 2014 15:55:14 +0200, "Pascal J. Bourguignon"
<pjb@informatimago.com> declaimed the following:


>
>To dig a swimming pool, you can choose between a spoon and a bulldozer too.

	I'd recommend a back-hoe... Bulldozers aren't all that good for actual
digging...
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-13 15:13                     ` Heartbleed Dennis Lee Bieber
@ 2014-04-13 15:36                       ` Nasser M. Abbasi
  0 siblings, 0 replies; 144+ messages in thread
From: Nasser M. Abbasi @ 2014-04-13 15:36 UTC (permalink / raw)


On 4/13/2014 10:13 AM, Dennis Lee Bieber wrote:
> On Sun, 13 Apr 2014 15:55:14 +0200, "Pascal J. Bourguignon"
> <pjb@informatimago.com> declaimed the following:
>
>
>>
>> To dig a swimming pool, you can choose between a spoon and a bulldozer too.
>
> 	I'd recommend a back-hoe... Bulldozers aren't all that good for actual
> digging...
>

And it will be even better if the control system software for
this back-hoe engine and its loader hydraulic Power system
were written in Ada just to be extra safe :)

--Nasser


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 20:34               ` Heartbleed Dmitry A. Kazakov
  2014-04-12 20:47                 ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-15 10:02                 ` Yannick Duchêne (Hibou57)
  2014-04-15 12:35                   ` Heartbleed Dmitry A. Kazakov
  1 sibling, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-15 10:02 UTC (permalink / raw)


Le Sat, 12 Apr 2014 22:34:49 +0200, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:
> It is a common delusion that mathematically correct results are correct
> when dealing with a physical system.

Here is a related quote, from “Is computer science a branch of  
mathematics?”
http://math.stackexchange.com/questions/649408/is-computer-science-a-branch-of-mathematics/649526#649526
>It is not uncommon to hear ideas along the lines that
>  * Computer science is computer programming without practical  
> constraints
>   * Theoretical computer science is computer science without physical  
> constraints
>   * Mathematics is computer science without finiteness constraints


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-15 10:02                 ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-15 12:35                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 144+ messages in thread
From: Dmitry A. Kazakov @ 2014-04-15 12:35 UTC (permalink / raw)


On Tue, 15 Apr 2014 12:02:24 +0200, Yannick Duchêne (Hibou57) wrote:

> Le Sat, 12 Apr 2014 22:34:49 +0200, Dmitry A. Kazakov  
> <mailbox@dmitry-kazakov.de> a écrit:
>> It is a common delusion that mathematically correct results are correct
>> when dealing with a physical system.
> 
> Here is a related quote, from “Is computer science a branch of  
> mathematics?”
> http://math.stackexchange.com/questions/649408/is-computer-science-a-branch-of-mathematics/649526#649526
>>It is not uncommon to hear ideas along the lines that
>>  * Computer science is computer programming without practical  
>> constraints

I would say CS is science without programming.

>>   * Theoretical computer science is computer science without physical  
>> constraints

A science without engineering.

>>   * Mathematics is computer science without finiteness constraints

No. There is discrete mathematics, number theory, groups, linear
programming and optimization problems which are all about constraints.

Functional analysis (real numbers) and Peano arithmetic (integers) are
infinite => incomputable.

---------------------
BTW, there would be no problem to use a bignum library in Ada, if that were
useful. But for automation and control bignum is of little use, because it
would be a source of additional errors, such as violation of range,
accuracy, time, space constraints, such systems typically have.

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

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:38       ` Heartbleed Simon Clubley
  2014-04-12 20:24         ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-17  6:15         ` Jacob Sparre Andersen
  2014-04-17 15:55           ` Heartbleed Shark8
  2014-04-17 21:01           ` Heartbleed Simon Clubley
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
  2014-05-14  9:39         ` Heartbleed gvdschoot
  3 siblings, 2 replies; 144+ messages in thread
From: Jacob Sparre Andersen @ 2014-04-17  6:15 UTC (permalink / raw)


Simon Clubley wrote:

> The goal here is to replace C when writing libraries which are used on
> a vast range of platforms (like OpenSSL). That simply isn't going to
> happen unless the compiler runs on the same range of platforms C
> compilers currently run on and unless the code generator in the
> compiler generates code for the same range of targets the C compilers
> currently do.

Would something as simple as having the choice of compiling to C be
enough?  Then you could always generate a C library/application for a
target without direct support.

I will not claim that I expect it to be easy to target any random C
compiler, but it might be doable.

I can't tell if it would help replacing C or cement C's status as the
defacto standard programming language.

Greetings,

Jacob
-- 
"So this is how liberty dies, with thunderous applause..."

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17  6:15         ` Heartbleed Jacob Sparre Andersen
@ 2014-04-17 15:55           ` Shark8
  2014-04-17 21:01           ` Heartbleed Simon Clubley
  1 sibling, 0 replies; 144+ messages in thread
From: Shark8 @ 2014-04-17 15:55 UTC (permalink / raw)


On 17-Apr-14 00:15, Jacob Sparre Andersen wrote:
> Simon Clubley wrote:
>
>> The goal here is to replace C when writing libraries which are used on
>> a vast range of platforms (like OpenSSL). That simply isn't going to
>> happen unless the compiler runs on the same range of platforms C
>> compilers currently run on and unless the code generator in the
>> compiler generates code for the same range of targets the C compilers
>> currently do.
>
> Would something as simple as having the choice of compiling to C be
> enough?  Then you could always generate a C library/application for a
> target without direct support.
>
> I will not claim that I expect it to be easy to target any random C
> compiler, but it might be doable.
>
> I can't tell if it would help replacing C or cement C's status as the
> defacto standard programming language.
>
> Greetings,
>
> Jacob

I think doing this would only cement further dependence on C; but I'll 
admit that's just a completely unsubstantiated "Wild-Assed Guess".



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17  6:15         ` Heartbleed Jacob Sparre Andersen
  2014-04-17 15:55           ` Heartbleed Shark8
@ 2014-04-17 21:01           ` Simon Clubley
  2014-04-17 21:51             ` Heartbleed Shark8
  2014-04-18  1:29             ` Heartbleed Yannick Duchêne (Hibou57)
  1 sibling, 2 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-17 21:01 UTC (permalink / raw)


On 2014-04-17, Jacob Sparre Andersen <jacob@jacob-sparre.dk> wrote:
> Simon Clubley wrote:
>
>> The goal here is to replace C when writing libraries which are used on
>> a vast range of platforms (like OpenSSL). That simply isn't going to
>> happen unless the compiler runs on the same range of platforms C
>> compilers currently run on and unless the code generator in the
>> compiler generates code for the same range of targets the C compilers
>> currently do.
>
> Would something as simple as having the choice of compiling to C be
> enough?  Then you could always generate a C library/application for a
> target without direct support.
>

That takes care of the code generation/target platform selection part of
the compiler (if potentially not handling debugging issues [*]) but it
doesn't tackle the issue of the range of platforms the compiler itself
runs on.

If the compiler's implementation language isn't available on the same
range of host/development platforms as C is then you still have the
same issues as above and people are not going to use your new compiler.

I've thought about this a bit more over the last day or so and issues
like this are why I keep (sadly) coming back to C as the implementation
language for the core compiler itself although the libraries and the
run time library could be written in the language itself.

If you want to replace C, you can either (1) take the idealistic approach,
which so far has shown no real signs of succeeding even though we have
had Ada available for truly free use (in the form of the FSF compiler)
for a long time now, or (2) you can take a more pragmatic approach.

(And if it makes you feel better, the Fortran compiler in gcc is not
written in Fortran... :-))

[*] If you generate C code, then you also have the issue of making
sure any debugger uses the original source code and not the generated
C code. I don't know if it's possible to insert the required debugging
data into C code in the same way as you can with assembly code intended
for gas.

> I will not claim that I expect it to be easy to target any random C
> compiler, but it might be doable.
>
> I can't tell if it would help replacing C or cement C's status as the
> defacto standard programming language.
>

It wouldn't be a programming language any more when used as the output of
a code generator. It would simply be the generated representation of the
program in the same way as the gas (GNU assembler) output from gcc is the
generated representation of the program compiled with gcc.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 21:01           ` Heartbleed Simon Clubley
@ 2014-04-17 21:51             ` Shark8
  2014-04-17 21:54               ` Heartbleed Alan Jump
  2014-04-18  1:29             ` Heartbleed Yannick Duchêne (Hibou57)
  1 sibling, 1 reply; 144+ messages in thread
From: Shark8 @ 2014-04-17 21:51 UTC (permalink / raw)


Is there a reason that C as the 'core' component would be any better 
than, say, FORTH?


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 21:51             ` Heartbleed Shark8
@ 2014-04-17 21:54               ` Alan Jump
  2014-04-17 22:02                 ` Heartbleed Adam Beneschan
  2014-04-17 22:35                 ` Heartbleed Simon Clubley
  0 siblings, 2 replies; 144+ messages in thread
From: Alan Jump @ 2014-04-17 21:54 UTC (permalink / raw)


On Thursday, April 17, 2014 2:51:34 PM UTC-7, Shark8 wrote:
> Is there a reason that C as the 'core' component would be any better 
> 
> than, say, FORTH?

Not in my mind, since CPUs don't care about the human-readable language...all they care about is the bytecode the compiler generates.

- -
73 de N5ILN
Alan


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 21:54               ` Heartbleed Alan Jump
@ 2014-04-17 22:02                 ` Adam Beneschan
  2014-04-17 22:35                 ` Heartbleed Simon Clubley
  1 sibling, 0 replies; 144+ messages in thread
From: Adam Beneschan @ 2014-04-17 22:02 UTC (permalink / raw)


On Thursday, April 17, 2014 2:54:56 PM UTC-7, Alan Jump wrote:
> On Thursday, April 17, 2014 2:51:34 PM UTC-7, Shark8 wrote:
> 
> > Is there a reason that C as the 'core' component would be any better 
> > than, say, FORTH?
> 
> Not in my mind, since CPUs don't care about the human-readable language...all they care about is the bytecode the compiler generates.

Wait, I thought we were talking about C ... how do "human-readable languages" fit into the discussion?

                            -- Adam


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 21:54               ` Heartbleed Alan Jump
  2014-04-17 22:02                 ` Heartbleed Adam Beneschan
@ 2014-04-17 22:35                 ` Simon Clubley
  2014-04-17 22:55                   ` Heartbleed Jeffrey Carter
                                     ` (2 more replies)
  1 sibling, 3 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-17 22:35 UTC (permalink / raw)


On 2014-04-17, Alan Jump <alan.jump@gmail.com> wrote:
> On Thursday, April 17, 2014 2:51:34 PM UTC-7, Shark8 wrote:
>> Is there a reason that C as the 'core' component would be any better 
>> 
>> than, say, FORTH?
>

Are there FORTH compilers for every platform a C compiler runs on ?

If you want to implement a mainstream library such as OpenSSL in a new
safer language (such as Oberon-14), then your new library needs to be
compilable on every platform the C version of OpenSSL is currently
compilable on.

That means your compiler (ie: Oberon-14) for this new library needs to
be written in a language which allows it to run on the same platform as
the platform's existing C compiler [*].

If it isn't then it won't get used (or at least in any meaningful way)
because people will just use the version of the OpenSSL library which
_does_ build on all the platforms they want to develop their application
code on.

The only compiler implementation language I can think of which matches
the above criteria is C.

I really don't know how many times I am going to have to repeat this. :-)

If you think I am wrong, then, while telling me I am wrong :-), please
also tell me why Ada isn't in much more wider use than it currently is.

> Not in my mind, since CPUs don't care about the human-readable language...all
> they care about is the bytecode the compiler generates.
>

I hope the above helps explain what the real core issue is here.

[*] (This isn't sufficient, but it's a required pre-requisite. You also
have the additional issue of supported target platforms as well in a
cross compiler setup but that's not a function of the chosen compiler
implementation language.)

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 22:35                 ` Heartbleed Simon Clubley
@ 2014-04-17 22:55                   ` Jeffrey Carter
  2014-04-18  8:48                     ` Heartbleed Simon Clubley
  2014-04-18  1:38                   ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-18 21:17                   ` Heartbleed Shark8
  2 siblings, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-17 22:55 UTC (permalink / raw)


On 04/17/2014 03:35 PM, Simon Clubley wrote:
>
> If you think I am wrong, then, while telling me I am wrong :-), please
> also tell me why Ada isn't in much more wider use than it currently is.

Let's see, there's an Ada compiler that uses ANSI C as its intermediate 
language. So there's an Ada compiler that targets every platform that C targets. 
Clearly the number of targets that a language has a compiler for is not the issue.

-- 
Jeff Carter
"I didn't squawk about the steak, dear. I
merely said I didn't see that old horse
that used to be tethered outside here."
Never Give a Sucker an Even Break
103


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 21:01           ` Heartbleed Simon Clubley
  2014-04-17 21:51             ` Heartbleed Shark8
@ 2014-04-18  1:29             ` Yannick Duchêne (Hibou57)
  2014-04-18 10:42               ` Heartbleed J-P. Rosen
  1 sibling, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-18  1:29 UTC (permalink / raw)


Le Thu, 17 Apr 2014 23:01:39 +0200, Simon Clubley  
<clubley@remove_me.eisner.decus.org-earth.ufp> a écrit:

> (And if it makes you feel better, the Fortran compiler in gcc is not
> written in Fortran... :-))

It may help to feel even better to know the first validated Ada compiler  
ever, was written in SETL :-P . I personally see no requirement for an Ada  
compiler to be written in Ada. A statically typed and modular sufficiently  
high level language may be as much fine as Ada.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 22:35                 ` Heartbleed Simon Clubley
  2014-04-17 22:55                   ` Heartbleed Jeffrey Carter
@ 2014-04-18  1:38                   ` Yannick Duchêne (Hibou57)
  2014-04-18 14:59                     ` Heartbleed Nasser M. Abbasi
  2014-04-18 21:17                   ` Heartbleed Shark8
  2 siblings, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-18  1:38 UTC (permalink / raw)


Le Fri, 18 Apr 2014 00:35:47 +0200, Simon Clubley  
<clubley@remove_me.eisner.decus.org-earth.ufp> a écrit:

> […]
>
> The only compiler implementation language I can think of which matches
> the above criteria is C.
>
> I really don't know how many times I am going to have to repeat this. :-)
>
> If you think I am wrong, then, while telling me I am wrong :-), please
> also tell me why Ada isn't in much more wider use than it currently is.

Because of the crowd and the economy.

Most people enjoy to follow the crowd whether or not it's for good,  
otherwise most people just become frightened of being isolated, and that's  
even more true with people which would like to become famous in some way.  
Then students prefers to study a language for which there are job offers.  
Recently (I don't know the exact date), the university in the town I live  
in, decided to give up with learning Ada, in favour of C/C++, for this  
exact reason.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 22:55                   ` Heartbleed Jeffrey Carter
@ 2014-04-18  8:48                     ` Simon Clubley
  2014-04-18 18:02                       ` Heartbleed Jeffrey Carter
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-18  8:48 UTC (permalink / raw)


On 2014-04-17, Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> wrote:
> On 04/17/2014 03:35 PM, Simon Clubley wrote:
>>
>> If you think I am wrong, then, while telling me I am wrong :-), please
>> also tell me why Ada isn't in much more wider use than it currently is.
>
> Let's see, there's an Ada compiler that uses ANSI C as its intermediate 
> language. So there's an Ada compiler that targets every platform that C targets. 
> Clearly the number of targets that a language has a compiler for is not the issue.
>

Actually it is.

Two points:

(1) Will that compiler itself run on all the platforms C compilers will
run on ?

(2) You have to pay for that compiler and the compilers people can choose
for alternative languages are free of charge.

Yannick is right - people tend to go with what they think will give them
a job in the marketplace. That means if you want people to try out your
language you have to make it as easy as the current options to obtain
and use on your chosen platform.

It also means you have to make it easy to integrate libraries written in
this new language into code people have written in other languages which
they think will get them a job.

Don't forget how Linux took off. A lot of students had _free_ access to
this new thing called Linux and could play with it while still learning
the skills they needed to get a job. However, once in a job, those same
people, now familiar with Linux, started using it for small non-critical
jobs and as it proved itself, started using it more and more until we got
to where we are today with Linux.

If you want to replace C with something safer, that is exactly the same
path you are going to have to take.

I think there's a _big_ culture gap in this newsgroup between what you
know and what is required for a C replacement to really take off.

I think many of you are so used to working on highly critical systems
which simply cannot fail, along with all the support infrastructure and
support costs that implies, that you simply do not see the very different
world and mindset which is required to get a new language established.

There is a definite place for something which is not as rich as Ada but
is better than C and can be used for the jobs C is currently used for.

As I have said before, if you can get a direct C replacement established
(for example, my hypothetical Oberon-14) which can be used on a large
range of platforms, then once you have got people into a certain type-safe
mindset, you can start introducing them to Ada for the large projects.

And in the meantime, with this direct C replacement, we could get people
writing some critical libraries which don't have stupid buffer overflow
and other bugs.

Ada's a good language, but it's the whole ecosystem around Ada and the
difficulty of getting Ada compilers running on a large range of platforms
which has stopped it from being as widely used as it should be.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18  1:29             ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-18 10:42               ` J-P. Rosen
  0 siblings, 0 replies; 144+ messages in thread
From: J-P. Rosen @ 2014-04-18 10:42 UTC (permalink / raw)


Le 18/04/2014 03:29, Yannick Duchêne (Hibou57) a écrit :
> I personally see no requirement for an Ada compiler to be written in
> Ada. A statically typed and modular sufficiently high level language may
> be as much fine as Ada.
There is no requirement of course, but some good reasons to write a
compiler in its own language:

1) There is in general a commonality between a language, its
representation, and the structures it handles best. Representing the
language with its own structures is generally appropriate.

2) It makes porting the compiler to other machines easier (description
of why is to be found in any good book about compilation)

3) Compiling the compiler with itself is an excellent test: the 2nd
compilation should be identical to the third compilation, or there is
something wrong...

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18  1:38                   ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-18 14:59                     ` Nasser M. Abbasi
  2014-04-18 17:12                       ` Heartbleed Alan Browne
  2014-04-18 17:30                       ` Heartbleed J-P. Rosen
  0 siblings, 2 replies; 144+ messages in thread
From: Nasser M. Abbasi @ 2014-04-18 14:59 UTC (permalink / raw)


On 4/17/2014 8:38 PM, Yannick Duchêne (Hibou57) wrote:
> Le Fri, 18 Apr 2014 00:35:47 +0200, Simon Clubley
> <clubley@remove_me.eisner.decus.org-earth.ufp> a écrit:
>

>> If you think I am wrong, then, while telling me I am wrong :-), please
>> also tell me why Ada isn't in much more wider use than it currently is.
>
> Because of the crowd and the economy.
>...
> Recently (I don't know the exact date), the university in the town I live
> in, decided to give up with learning Ada, in favour of C/C++, for this
> exact reason.
>
>

But these are the effects of Ada not being used, and the
causes?

Or may be it is a cycle. Ada not being used as much, schools
stop teaching it, and school stop teaching it causes Ada not
being used much.

As I said before many times, the cause of Ada not being popular,
is lack of many useful packages organized and standardized
in some way, to do many useful things, and not the language
itself.


--Nasser

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 14:59                     ` Heartbleed Nasser M. Abbasi
@ 2014-04-18 17:12                       ` Alan Browne
  2014-04-18 17:30                       ` Heartbleed J-P. Rosen
  1 sibling, 0 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-18 17:12 UTC (permalink / raw)


On 2014.04.18, 10:59 , Nasser M. Abbasi wrote:
> On 4/17/2014 8:38 PM, Yannick Duchêne (Hibou57) wrote:
>> Le Fri, 18 Apr 2014 00:35:47 +0200, Simon Clubley
>> <clubley@remove_me.eisner.decus.org-earth.ufp> a écrit:
>>
>
>>> If you think I am wrong, then, while telling me I am wrong :-),
>>> please also tell me why Ada isn't in much more wider use than it
>>> currently is.
>>
>> Because of the crowd and the economy. ... Recently (I don't know
>> the exact date), the university in the town I live in, decided to
>> give up with learning Ada, in favour of C/C++, for this exact
>> reason.
>>
>>
>
> But these are the effects of Ada not being used, and the causes?
>
> Or may be it is a cycle. Ada not being used as much, schools stop
> teaching it, and school stop teaching it causes Ada not being used
> much.

Yes: The anti-Hygrade effect.

	(A Canadian wiener brand; tagline:
        "More people eat Hygrade because they're fresher -
         they're fresher because more people eat them."

Ada's formalism is a put off for people who just want to get a program
up and running.  Ada is not for casual programming of any kind and for
serious programming it takes more planning and design - the good things
for aerospace and other safety-first systems that people do not have
patience for in more general apps.

So they turn to C.  Blech code follows.

      Weinberg's Second Law: If builders built buildings the way
      programmers wrote programs, then the first woodpecker that came
      along would destroy civilization.

> As I said before many times, the cause of Ada not being popular, is
> lack of many useful packages organized and standardized in some way,
> to do many useful things, and not the language itself.

That's true to a degree but the real reason is C dominance.

-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed - attacks?
  2014-04-11  2:39 Heartbleed Charles H. Sampson
  2014-04-11  7:59 ` Heartbleed Maciej Sobczak
  2014-04-11 12:43 ` Heartbleed kalvin.news
@ 2014-04-18 17:24 ` Alan Browne
  2 siblings, 0 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-18 17:24 UTC (permalink / raw)


On 2014.04.10, 22:39 , Charles H. Sampson wrote:
>       According to Wikipedia, the Heartbleed bug in OpenSSL is caused by
> two errors: Lack of bounds checking and failure to verify that the
> heartbeat request was valid. Whom does one express one's indignation to?
> The insistence of many in our "profession" on using C and its decendents
> is the reason I qualify the word "profession" when writing about
> software developers. Acting on a message without validating it is
> equally incomprenhensible to me. The former is a "profession"-wide
> problem. For the latter, someone needs a severe rebuke on his next
> performance review, at the least.
>
>       It so happens that for the last project I worked on, I was
> responsible for TCP/IP communication. Every incoming message was fully
> validated, including validating all components of the message body. The
> only response to an invalid message was a negative acknowledgement to
> the sender. It never occurred to me to do it any other way. Haven't the
> problems associated with acting on invalid input of any sort been known
> for decades?

As far as the above may be (is) true, according to this article:
http://bits.blogs.nytimes.com/2014/04/16/study-finds-no-evidence-of-heartbleed-attacks-before-the-bug-was-exposed/?src=me

There were no "attacks" due to heartbleed.

OTOH, a 19 year old in London, ON, has been arrested for accessing some 
900 people's tax info via the Canadian Revenue Agency (aka: taxman) tax 
filing servers using the HB exploit.

Whether this attack was made after HB was announced (and before the CRA 
closed their web portal) is not clear to me.  Looks to me like a 
"bright" kid screwing around without intended malice is being ground up 
by the RCMP just so they can say justice is being done.  (aka: closing 
the barn door after the horses have fled).

-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 14:59                     ` Heartbleed Nasser M. Abbasi
  2014-04-18 17:12                       ` Heartbleed Alan Browne
@ 2014-04-18 17:30                       ` J-P. Rosen
  2014-04-18 18:04                         ` Heartbleed Jeffrey Carter
  1 sibling, 1 reply; 144+ messages in thread
From: J-P. Rosen @ 2014-04-18 17:30 UTC (permalink / raw)


Le 18/04/2014 16:59, Nasser M. Abbasi a écrit :
> As I said before many times, the cause of Ada not being popular,
> is lack of many useful packages organized and standardized
> in some way, to do many useful things, and not the language
> itself.
<rant>
The cause of Ada not being popular is that it has been designed to force
people to THINK and do things cleanly. People prefer wild hacking and
long debugging sessions to sitting back in one's chair and analyzing the
problem.
</rant>

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 22:01       ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-18 17:58         ` Alan Browne
  0 siblings, 0 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-18 17:58 UTC (permalink / raw)


On 2014.04.12, 18:01 , Yannick Duchêne (Hibou57) wrote:
> Le Sat, 12 Apr 2014 06:58:29 +0200, Shark8 <OneWingedShark@gmail.com> a
> écrit:
>
>>> BTW, once you have people exposed to type safe programming, then maybe
>>> you can introduce them to Ada for the large projects. One of the major
>>> revelations for me over Heartbleed was seeing people discuss the need
>>> for a safer language and immediately jump to languages like Java.
>>
>> Hm, good point.
>> Ada has some *REALLY* good features when it comes to
>> programming-in-the-large -- the YF-22 integration is astounding:
>> 12 major avionics subsystems, across 650 Ada modules containing
>> millions of lines of code, coded in 8 geographically distinct
>> locations, took *three days!*
>>
>> Source: http://archive.adaic.com/docs/present/engle/comments/tsld033.htm
>
> While Ada certainly played an important role in this success story,
> another as much important role was certainly humans… how did they
> communicate between each others? I mean, what documentation techniques
> and systems was used? Was the style guide(s) homogeneous or
> heterogeneous? Did they used some kind of maps to handle the big lines
> before diving into the details?
>
> I would enjoy a lot to know the answers to these questions.

Ada is an element to the described success.  Before a line of code is 
written, requirements and specs must be written and ICD's agree'd upon; 
many, many, many details need to be agreed to before software code 
design begins.

Also, databuses have evolved tremendously - reducing the wiring and 
eliminating often bizarre timings on board aircraft/weapons systems and 
making everyone use similar data types and structures throughout.

Further, back in the 80's, the internet and e-mail were not yet common 
as a means to sharing requirements, specs, test plans and ICD's.   Now 
such can be edited by teams in realtime w/o worrying about which copy of 
the Word file is up to date - everyone sees one single evolving copy no 
matter where and when they are.

(I recall our one of nav systems integrated on a USAF aircraft where it 
had to output waypoint and position data in different formats to 
different systems over the same databus (using different A-429 labels). 
  But in one case two destination systems used the same data label but 
different representations of position (semi-circles for one of them and 
radians for the other IIRC).  Ugly solution: the LSBit of each lat/long 
pair (separate labels) was set to a 0 or 1 to distinguish which format. 
  The target systems would use that 'data' bit to accept or ignore the 
data. (The 2 bit sign matrix having been used (wrongly) to signal some 
other state)).

It only took a conference call to make the ICD change.  But down the 
pike, when our system and their systems were integrated into other 
aircraft, we and they had to change code again and again and again for 
each new integration.

Imagine the above for many dozen parameters on similar data buses ...

-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18  8:48                     ` Heartbleed Simon Clubley
@ 2014-04-18 18:02                       ` Jeffrey Carter
  2014-04-18 20:31                         ` Heartbleed Yannick Duchêne (Hibou57)
  0 siblings, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-18 18:02 UTC (permalink / raw)


On 04/18/2014 01:48 AM, Simon Clubley wrote:
>
> (2) You have to pay for that compiler and the compilers people can choose
> for alternative languages are free of charge.

This, I think, I a valid part of the reason for C's dominance: there is a free C 
compiler for almost every platform. While there are free Ada compilers for the 
most common platforms, there are far more platforms without a free Ada compiler 
than platforms without a free C compiler.

-- 
Jeff Carter
"C++ is vast and dangerous, a sort of Mordor of
programming languages."
Jason R. Fruit
120

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 17:30                       ` Heartbleed J-P. Rosen
@ 2014-04-18 18:04                         ` Jeffrey Carter
  2014-04-18 18:34                           ` Heartbleed Simon Clubley
                                             ` (2 more replies)
  0 siblings, 3 replies; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-18 18:04 UTC (permalink / raw)


On 04/18/2014 10:30 AM, J-P. Rosen wrote:
> <rant>
> The cause of Ada not being popular is that it has been designed to force
> people to THINK and do things cleanly. People prefer wild hacking and
> long debugging sessions to sitting back in one's chair and analyzing the
> problem.
> </rant>

Yes. Or as I like to put it, Ada is a software-engineering language, and only 2% 
(in my experience) of developers are software engineers. The remaining 98% are 
not going to like Ada; they like hack-away languages like C.

-- 
Jeff Carter
"C++ is vast and dangerous, a sort of Mordor of
programming languages."
Jason R. Fruit
120

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:04                         ` Heartbleed Jeffrey Carter
@ 2014-04-18 18:34                           ` Simon Clubley
  2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
  2014-04-18 21:35                             ` Heartbleed Dennis Lee Bieber
  2014-04-18 18:37                           ` Heartbleed Alan Browne
  2014-04-18 22:56                           ` Heartbleed Nasser M. Abbasi
  2 siblings, 2 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-18 18:34 UTC (permalink / raw)


On 2014-04-18, Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> wrote:
> On 04/18/2014 10:30 AM, J-P. Rosen wrote:
>> <rant>
>> The cause of Ada not being popular is that it has been designed to force
>> people to THINK and do things cleanly. People prefer wild hacking and
>> long debugging sessions to sitting back in one's chair and analyzing the
>> problem.
>> </rant>
>
> Yes. Or as I like to put it, Ada is a software-engineering language, and only 2% 
> (in my experience) of developers are software engineers. The remaining 98% are 
> not going to like Ada; they like hack-away languages like C.
>

I agree with both of you, but the fact remains those same people are
writing the critical/common libraries used in a wide range of software
and hardware products.

So how about a language which doesn't have all the software engineering
requirements Ada does, but still comes with some type safety, has
a level of functionality comparable to C, uses a syntax which makes
it far less likely for people to make silly syntax related mistakes and
runs on far more platforms than Ada compilers do ?

You probably won't be able to use this language for creating enormous
applications, but that isn't what it would be designed for and such a
language should be much more "hackable" than Ada (while still bringing
some Ada style benefits to the table).

Now all we need is someone with the energy and time to design and promote
this language. :-) (Not me I'm afraid; I have a full time job. :-))

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:04                         ` Heartbleed Jeffrey Carter
  2014-04-18 18:34                           ` Heartbleed Simon Clubley
@ 2014-04-18 18:37                           ` Alan Browne
  2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
  2014-04-18 20:49                             ` Heartbleed Shark8
  2014-04-18 22:56                           ` Heartbleed Nasser M. Abbasi
  2 siblings, 2 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-18 18:37 UTC (permalink / raw)


On 2014.04.18, 14:04 , Jeffrey Carter wrote:
> On 04/18/2014 10:30 AM, J-P. Rosen wrote:
>> <rant>
>> The cause of Ada not being popular is that it has been designed to force
>> people to THINK and do things cleanly. People prefer wild hacking and
>> long debugging sessions to sitting back in one's chair and analyzing the
>> problem.
>> </rant>
>
> Yes. Or as I like to put it, Ada is a software-engineering language, and
> only 2% (in my experience) of developers are software engineers. The
> remaining 98% are not going to like Ada; they like hack-away languages
> like C.


Ada is to programming as the metric system is to most Americans.


-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:02                       ` Heartbleed Jeffrey Carter
@ 2014-04-18 20:31                         ` Yannick Duchêne (Hibou57)
  2014-04-18 23:16                           ` Heartbleed Pascal J. Bourguignon
  0 siblings, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-18 20:31 UTC (permalink / raw)


Le Fri, 18 Apr 2014 20:02:22 +0200, Jeffrey Carter  
<spam.jrcarter.not@spam.not.acm.org> a écrit:

> On 04/18/2014 01:48 AM, Simon Clubley wrote:
>>
>> (2) You have to pay for that compiler and the compilers people can  
>> choose
>> for alternative languages are free of charge.
>
> This, I think, I a valid part of the reason for C's dominance: there is  
> a free C compiler for almost every platform. While there are free Ada  
> compilers for the most common platforms, there are far more platforms  
> without a free Ada compiler than platforms without a free C compiler.

That's because an Ada compiler is far more complex to design. This may be  
another rational for a standard Ada minimal *frozen* *subset* (not a new  
language) without every thing which is finally a derived form of the most  
fundamental constructs with additional limitations: I would say keeping  
core type definitions (ranges, enumerations, arrays) with discriminated  
record, package and package hierarchy, renaming declarations, C foreign  
interface, a library reduced to unavoidable system interface and memory  
allocation, optional tasking, access types with some cut‑off, and no more  
(no tagged types, no interface types, no DbC, may be no exception  
handlers, no generics, …). This still won't disallow to use SPARK (or  
other formal systems) with it ;-) .

As a summary, core type systems, package hierarchy, renaming, basic system  
interface. Would already be a lot of added value compared to C.

Any stupidities in this message may be forgiven, I wrote this straight  
away as it came to my mind (red‑face).

-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:37                           ` Heartbleed Alan Browne
@ 2014-04-18 20:45                             ` Jeffrey Carter
  2014-04-18 21:06                               ` Heartbleed Alan Browne
  2014-04-18 20:49                             ` Heartbleed Shark8
  1 sibling, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-18 20:45 UTC (permalink / raw)


On 04/18/2014 11:37 AM, Alan Browne wrote:
>
> Ada is to programming as the metric system is to most Americans.

Not really. As more than 95% of the world's population demonstrate, the average 
person can understand the metric system. My experience is that the average 
developer cannot understand the concepts underlying Ada.

-- 
Jeff Carter
"C++ is vast and dangerous, a sort of Mordor of
programming languages."
Jason R. Fruit
120


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:34                           ` Heartbleed Simon Clubley
@ 2014-04-18 20:45                             ` Jeffrey Carter
  2014-04-18 21:35                             ` Heartbleed Dennis Lee Bieber
  1 sibling, 0 replies; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-18 20:45 UTC (permalink / raw)


On 04/18/2014 11:34 AM, Simon Clubley wrote:
>
> I agree with both of you, but the fact remains those same people are
> writing the critical/common libraries used in a wide range of software
> and hardware products.

Precisely. If civil engineering were done like software engineering, we'd have 
construction workers designing bridges and deciding what materials to use to 
build them. We don't allow that for our physical infrastructure, and we 
shouldn't allow it for the infrastructure that supports most of our commerce. 
Until we get to that point there will be no improvement in the situation, no 
matter what language you design.

> So how about a language which doesn't have all the software engineering
> requirements Ada does, but still comes with some type safety, has
> a level of functionality comparable to C, uses a syntax which makes
> it far less likely for people to make silly syntax related mistakes and
> runs on far more platforms than Ada compilers do ?

Unless it has all the failings of C, coders will continue to use C. To coders, 
those failings are desirable qualities.

-- 
Jeff Carter
"C++ is vast and dangerous, a sort of Mordor of
programming languages."
Jason R. Fruit
120


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:37                           ` Heartbleed Alan Browne
  2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
@ 2014-04-18 20:49                             ` Shark8
  2014-04-18 21:07                               ` Heartbleed Alan Browne
  1 sibling, 1 reply; 144+ messages in thread
From: Shark8 @ 2014-04-18 20:49 UTC (permalink / raw)


On 18-Apr-14 12:37, Alan Browne wrote:
>
> Ada is to programming as the metric system is to most Americans.

I completely disagree -- Ada is about thinking about your problem and 
doing things correctly... not, strictly speaking, "consistency for 
consistency's sake".

Metric does jack-shit for you in ensuring that your unit conversions are 
accurate, or that you're using the correct units at all ("I'd like a 
kilogram of meters, please").



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
@ 2014-04-18 21:06                               ` Alan Browne
  2014-04-18 22:20                                 ` Heartbleed Jeffrey Carter
  0 siblings, 1 reply; 144+ messages in thread
From: Alan Browne @ 2014-04-18 21:06 UTC (permalink / raw)


On 2014.04.18, 16:45 , Jeffrey Carter wrote:
> On 04/18/2014 11:37 AM, Alan Browne wrote:
>>
>> Ada is to programming as the metric system is to most Americans.
>
> Not really. As more than 95% of the world's population demonstrate, the
> average person can understand the metric system. My experience is that
> the average developer cannot understand the concepts underlying Ada.

1. '... to most Americans.'

2. 'twas a joke son, a joke I say.


-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 20:49                             ` Heartbleed Shark8
@ 2014-04-18 21:07                               ` Alan Browne
  0 siblings, 0 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-18 21:07 UTC (permalink / raw)


On 2014.04.18, 16:49 , Shark8 wrote:
> On 18-Apr-14 12:37, Alan Browne wrote:
>>
>> Ada is to programming as the metric system is to most Americans.
>
> I completely disagree -- Ada is about thinking about your problem and
> doing things correctly... not, strictly speaking, "consistency for
> consistency's sake".
>
> Metric does jack-shit for you in ensuring that your unit conversions are
> accurate,

If you stick to metric there are no unit conversions other than scale.

or that you're using the correct units at all ("I'd like a
> kilogram of meters, please").


1. 'twas a joke son, a joke.




-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-17 22:35                 ` Heartbleed Simon Clubley
  2014-04-17 22:55                   ` Heartbleed Jeffrey Carter
  2014-04-18  1:38                   ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-18 21:17                   ` Shark8
  2014-04-19 18:59                     ` Heartbleed Simon Clubley
  2 siblings, 1 reply; 144+ messages in thread
From: Shark8 @ 2014-04-18 21:17 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1490 bytes --]

On 17-Apr-14 16:35, Simon Clubley wrote:
> Are there FORTH compilers for every platform a C compiler runs on ?

Probably.
And even if there's not, FORTH is apparently really, /really/ easy to 
bootstrap.

 From the attached text-file:

> Why then would you want to learn FORTH?  There are several very good
> reasons. […]
>
> Secondly FORTH has a peculiar bootstrapping property.  By that I
> mean that after writing a little bit of assembly to talk to the
> hardware and implement a few primitives, all the rest of the language
> and compiler is written in FORTH itself.

So then, we could construct a FORTH-emitting compiler to bootstrap to a 
new system and have only to bootstrap FORTH (most of which we could 
write in itself) with those few [assembly] primitives.

Yes, it's a bit indirect -- but I don't see why most of that can't be 
generally automated into what is essentially a template --
(1)  Enter these basic parameters (native int-size, endianness, etc)
(2)  Fill in these basic assembly functions
(3)  Compile.
  (a) Spit out the Forth.
  (b) Feed the Forth emission of the compiler's own source to the FORTH.
  (c) Thus obtaining a compiler which runs on the new system.
  (d) Feed the compiler's own source to the Forth-bootstrap.
(4)  You now have a native and self-hosting Ada compiler.

Another option would be to have a component for describing the new 
hardware-target [in VHDL] and using that to target/emit.

In either case, targeting a new system should be EASY.

[-- Attachment #2: www.eecs.wsu.edu/~hauser/teaching/Arch-F07/handouts/jonesforth.s.txt --]
[-- Type: text/plain, Size: 82779 bytes --]

/*	A sometimes minimal FORTH compiler and tutorial for Linux / i386 systems. -*- asm -*-
	By Richard W.M. Jones <rich@annexia.org> http://annexia.org/forth
	This is PUBLIC DOMAIN (see public domain release statement below).
	$Id: jonesforth.S,v 1.45 2007/10/22 18:53:13 rich Exp $

	gcc -m32 -nostdlib -static -Wl,-Ttext,0 -Wl,--build-id=none -o jonesforth jonesforth.S
*/
	.set JONES_VERSION,45
/*
	INTRODUCTION ----------------------------------------------------------------------

	FORTH is one of those alien languages which most working programmers regard in the same
	way as Haskell, LISP, and so on.  Something so strange that they'd rather any thoughts
	of it just go away so they can get on with writing this paying code.  But that's wrong
	and if you care at all about programming then you should at least understand all these
	languages, even if you will never use them.

	LISP is the ultimate high-level language, and features from LISP are being added every
	decade to the more common languages.  But FORTH is in some ways the ultimate in low level
	programming.  Out of the box it lacks features like dynamic memory management and even
	strings.  In fact, at its primitive level it lacks even basic concepts like IF-statements
	and loops.

	Why then would you want to learn FORTH?  There are several very good reasons.  First
	and foremost, FORTH is minimal.  You really can write a complete FORTH in, say, 2000
	lines of code.  I don't just mean a FORTH program, I mean a complete FORTH operating
	system, environment and language.  You could boot such a FORTH on a bare PC and it would
	come up with a prompt where you could start doing useful work.  The FORTH you have here
	isn't minimal and uses a Linux process as its 'base PC' (both for the purposes of making
	it a good tutorial). It's possible to completely understand the system.  Who can say they
	completely understand how Linux works, or gcc?

	Secondly FORTH has a peculiar bootstrapping property.  By that I mean that after writing
	a little bit of assembly to talk to the hardware and implement a few primitives, all the
	rest of the language and compiler is written in FORTH itself.  Remember I said before
	that FORTH lacked IF-statements and loops?  Well of course it doesn't really because
	such a lanuage would be useless, but my point was rather that IF-statements and loops are
	written in FORTH itself.

	Now of course this is common in other languages as well, and in those languages we call
	them 'libraries'.  For example in C, 'printf' is a library function written in C.  But
	in FORTH this goes way beyond mere libraries.  Can you imagine writing C's 'if' in C?
	And that brings me to my third reason: If you can write 'if' in FORTH, then why restrict
	yourself to the usual if/while/for/switch constructs?  You want a construct that iterates
	over every other element in a list of numbers?  You can add it to the language.  What
	about an operator which pulls in variables directly from a configuration file and makes
	them available as FORTH variables?  Or how about adding Makefile-like dependencies to
	the language?  No problem in FORTH.  How about modifying the FORTH compiler to allow
	complex inlining strategies -- simple.  This concept isn't common in programming languages,
	but it has a name (in fact two names): "macros" (by which I mean LISP-style macros, not
	the lame C preprocessor) and "domain specific languages" (DSLs).

	This tutorial isn't about learning FORTH as the language.  I'll point you to some references
	you should read if you're not familiar with using FORTH.  This tutorial is about how to
	write FORTH.  In fact, until you understand how FORTH is written, you'll have only a very
	superficial understanding of how to use it.

	So if you're not familiar with FORTH or want to refresh your memory here are some online
	references to read:

	http://en.wikipedia.org/wiki/Forth_%28programming_language%29

	http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm

	http://wiki.laptop.org/go/Forth_Lessons

	http://www.albany.net/~hello/simple.htm

	Here is another "Why FORTH?" essay: http://www.jwdt.com/~paysan/why-forth.html

	Discussion and criticism of this FORTH here: http://lambda-the-ultimate.org/node/2452

	ACKNOWLEDGEMENTS ----------------------------------------------------------------------

	This code draws heavily on the design of LINA FORTH (http://home.hccnet.nl/a.w.m.van.der.horst/lina.html)
	by Albert van der Horst.  Any similarities in the code are probably not accidental.

	Some parts of this FORTH are also based on this IOCCC entry from 1992:
	http://ftp.funet.fi/pub/doc/IOCCC/1992/buzzard.2.design.
	I was very proud when Sean Barrett, the original author of the IOCCC entry, commented in the LtU thread
	http://lambda-the-ultimate.org/node/2452#comment-36818 about this FORTH.

	And finally I'd like to acknowledge the (possibly forgotten?) authors of ARTIC FORTH because their
	original program which I still have on original cassette tape kept nagging away at me all these years.
	http://en.wikipedia.org/wiki/Artic_Software

	PUBLIC DOMAIN ----------------------------------------------------------------------

	I, the copyright holder of this work, hereby release it into the public domain. This applies worldwide.

	In case this is not legally possible, I grant any entity the right to use this work for any purpose,
	without any conditions, unless such conditions are required by law.

	SETTING UP ----------------------------------------------------------------------

	Let's get a few housekeeping things out of the way.  Firstly because I need to draw lots of
	ASCII-art diagrams to explain concepts, the best way to look at this is using a window which
	uses a fixed width font and is at least this wide:

 <------------------------------------------------------------------------------------------------------------------------>

	Secondly make sure TABS are set to 8 characters.  The following should be a vertical
	line.  If not, sort out your tabs.

		|
	        |
	    	|

	Thirdly I assume that your screen is at least 50 characters high.

	ASSEMBLING ----------------------------------------------------------------------

	If you want to actually run this FORTH, rather than just read it, you will need Linux on an
	i386.  Linux because instead of programming directly to the hardware on a bare PC which I
	could have done, I went for a simpler tutorial by assuming that the 'hardware' is a Linux
	process with a few basic system calls (read, write and exit and that's about all).  i386
	is needed because I had to write the assembly for a processor, and i386 is by far the most
	common.  (Of course when I say 'i386', any 32- or 64-bit x86 processor will do.  I'm compiling
	this on a 64 bit AMD Opteron).

	Again, to assemble this you will need gcc and gas (the GNU assembler).  The commands to
	assemble and run the code (save this file as 'jonesforth.S') are:

	gcc -m32 -nostdlib -static -Wl,-Ttext,0 -Wl,--build-id=none -o jonesforth jonesforth.S
	cat jonesforth.f - | ./jonesforth

	If you want to run your own FORTH programs you can do:

	cat jonesforth.f myprog.f | ./jonesforth

	If you want to load your own FORTH code and then continue reading user commands, you can do:

	cat jonesforth.f myfunctions.f - | ./jonesforth

	ASSEMBLER ----------------------------------------------------------------------

	(You can just skip to the next section -- you don't need to be able to read assembler to
	follow this tutorial).

	However if you do want to read the assembly code here are a few notes about gas (the GNU assembler):

	(1) Register names are prefixed with '%', so %eax is the 32 bit i386 accumulator.  The registers
	    available on i386 are: %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp and %esp, and most of them
	    have special purposes.

	(2) Add, mov, etc. take arguments in the form SRC,DEST.  So mov %eax,%ecx moves %eax -> %ecx

	(3) Constants are prefixed with '$', and you mustn't forget it!  If you forget it then it
	    causes a read from memory instead, so:
	    mov $2,%eax		moves number 2 into %eax
	    mov 2,%eax		reads the 32 bit word from address 2 into %eax (ie. most likely a mistake)

	(4) gas has a funky syntax for local labels, where '1f' (etc.) means label '1:' "forwards"
	    and '1b' (etc.) means label '1:' "backwards".  Notice that these labels might be mistaken
	    for hex numbers (eg. you might confuse 1b with $0x1b).

	(5) 'ja' is "jump if above", 'jb' for "jump if below", 'je' "jump if equal" etc.

	(6) gas has a reasonably nice .macro syntax, and I use them a lot to make the code shorter and
	    less repetitive.

	For more help reading the assembler, do "info gas" at the Linux prompt.

	Now the tutorial starts in earnest.

	THE DICTIONARY ----------------------------------------------------------------------

	In FORTH as you will know, functions are called "words", and just as in other languages they
	have a name and a definition.  Here are two FORTH words:

	: DOUBLE DUP + ;		\ name is "DOUBLE", definition is "DUP +"
	: QUADRUPLE DOUBLE DOUBLE ;	\ name is "QUADRUPLE", definition is "DOUBLE DOUBLE"

	Words, both built-in ones and ones which the programmer defines later, are stored in a dictionary
	which is just a linked list of dictionary entries.

	<--- DICTIONARY ENTRY (HEADER) ----------------------->
	+------------------------+--------+---------- - - - - +----------- - - - -
	| LINK POINTER           | LENGTH/| NAME	      | DEFINITION
	|			 | FLAGS  |     	      |
	+--- (4 bytes) ----------+- byte -+- n bytes  - - - - +----------- - - - -

	I'll come to the definition of the word later.  For now just look at the header.  The first
	4 bytes are the link pointer.  This points back to the previous word in the dictionary, or, for
	the first word in the dictionary it is just a NULL pointer.  Then comes a length/flags byte.
	The length of the word can be up to 31 characters (5 bits used) and the top three bits are used
	for various flags which I'll come to later.  This is followed by the name itself, and in this
	implementation the name is rounded up to a multiple of 4 bytes by padding it with zero bytes.
	That's just to ensure that the definition starts on a 32 bit boundary.

	A FORTH variable called LATEST contains a pointer to the most recently defined word, in
	other words, the head of this linked list.

	DOUBLE and QUADRUPLE might look like this:

	  pointer to previous word
	   ^
	   |
	+--|------+---+---+---+---+---+---+---+---+------------- - - - -
	| LINK    | 6 | D | O | U | B | L | E | 0 | (definition ...)
	+---------+---+---+---+---+---+---+---+---+------------- - - - -
           ^       len                         padding
	   |
	+--|------+---+---+---+---+---+---+---+---+---+---+---+---+------------- - - - -
	| LINK    | 9 | Q | U | A | D | R | U | P | L | E | 0 | 0 | (definition ...)
	+---------+---+---+---+---+---+---+---+---+---+---+---+---+------------- - - - -
           ^       len                                     padding
           |
           |
	  LATEST

	You should be able to see from this how you might implement functions to find a word in
	the dictionary (just walk along the dictionary entries starting at LATEST and matching
	the names until you either find a match or hit the NULL pointer at the end of the dictionary);
	and add a word to the dictionary (create a new definition, set its LINK to LATEST, and set
	LATEST to point to the new word).  We'll see precisely these functions implemented in
	assembly code later on.

	One interesting consequence of using a linked list is that you can redefine words, and
	a newer definition of a word overrides an older one.  This is an important concept in
	FORTH because it means that any word (even "built-in" or "standard" words) can be
	overridden with a new definition, either to enhance it, to make it faster or even to
	disable it.  However because of the way that FORTH words get compiled, which you'll
	understand below, words defined using the old definition of a word continue to use
	the old definition.  Only words defined after the new definition use the new definition.

	DIRECT THREADED CODE ----------------------------------------------------------------------

	Now we'll get to the really crucial bit in understanding FORTH, so go and get a cup of tea
	or coffee and settle down.  It's fair to say that if you don't understand this section, then you
	won't "get" how FORTH works, and that would be a failure on my part for not explaining it well.
	So if after reading this section a few times you don't understand it, please email me
	(rich@annexia.org).

	Let's talk first about what "threaded code" means.  Imagine a peculiar version of C where
	you are only allowed to call functions without arguments.  (Don't worry for now that such a
	language would be completely useless!)  So in our peculiar C, code would look like this:

	f ()
	{
	  a ();
	  b ();
	  c ();
	}

	and so on.  How would a function, say 'f' above, be compiled by a standard C compiler?
	Probably into assembly code like this.  On the right hand side I've written the actual
	i386 machine code.

	f:
	  CALL a			E8 08 00 00 00
	  CALL b			E8 1C 00 00 00
	  CALL c			E8 2C 00 00 00
	  ; ignore the return from the function for now

	"E8" is the x86 machine code to "CALL" a function.  In the first 20 years of computing
	memory was hideously expensive and we might have worried about the wasted space being used
	by the repeated "E8" bytes.  We can save 20% in code size (and therefore, in expensive memory)
	by compressing this into just:

	08 00 00 00		Just the function addresses, without
	1C 00 00 00		the CALL prefix.
	2C 00 00 00

	On a 16-bit machine like the ones which originally ran FORTH the savings are even greater - 33%.

	[Historical note: If the execution model that FORTH uses looks strange from the following
	paragraphs, then it was motivated entirely by the need to save memory on early computers.
	This code compression isn't so important now when our machines have more memory in their L1
	caches than those early computers had in total, but the execution model still has some
	useful properties].

	Of course this code won't run directly on the CPU any more.  Instead we need to write an
	interpreter which takes each set of bytes and calls it.

	On an i386 machine it turns out that we can write this interpreter rather easily, in just
	two assembly instructions which turn into just 3 bytes of machine code.  Let's store the
	pointer to the next word to execute in the %esi register:

		08 00 00 00	<- We're executing this one now.  %esi is the _next_ one to execute.
	%esi -> 1C 00 00 00
		2C 00 00 00

	The all-important i386 instruction is called LODSL (or in Intel manuals, LODSW).  It does
	two things.  Firstly it reads the memory at %esi into the accumulator (%eax).  Secondly it
	increments %esi by 4 bytes.  So after LODSL, the situation now looks like this:

		08 00 00 00	<- We're still executing this one
		1C 00 00 00	<- %eax now contains this address (0x0000001C)
	%esi -> 2C 00 00 00

	Now we just need to jump to the address in %eax.  This is again just a single x86 instruction
	written JMP *(%eax).  And after doing the jump, the situation looks like:

		08 00 00 00
		1C 00 00 00	<- Now we're executing this subroutine.
	%esi -> 2C 00 00 00

	To make this work, each subroutine is followed by the two instructions 'LODSL; JMP *(%eax)'
	which literally make the jump to the next subroutine.

	And that brings us to our first piece of actual code!  Well, it's a macro.
*/

/* NEXT macro. */
	.macro NEXT
	lodsl
	jmp *(%eax)
	.endm

/*	The macro is called NEXT.  That's a FORTH-ism.  It expands to those two instructions.

	Every FORTH primitive that we write has to be ended by NEXT.  Think of it kind of like
	a return.

	The above describes what is known as direct threaded code.

	To sum up: We compress our function calls down to a list of addresses and use a somewhat
	magical macro to act as a "jump to next function in the list".  We also use one register (%esi)
	to act as a kind of instruction pointer, pointing to the next function in the list.

	I'll just give you a hint of what is to come by saying that a FORTH definition such as:

	: QUADRUPLE DOUBLE DOUBLE ;

	actually compiles (almost, not precisely but we'll see why in a moment) to a list of
	function addresses for DOUBLE, DOUBLE and a special function called EXIT to finish off.

	At this point, REALLY EAGLE-EYED ASSEMBLY EXPERTS are saying "JONES, YOU'VE MADE A MISTAKE!".

	I lied about JMP *(%eax).  

	INDIRECT THREADED CODE ----------------------------------------------------------------------

	It turns out that direct threaded code is interesting but only if you want to just execute
	a list of functions written in assembly language.  So QUADRUPLE would work only if DOUBLE
	was an assembly language function.  In the direct threaded code, QUADRUPLE would look like:

		+------------------+
		| addr of DOUBLE  --------------------> (assembly code to do the double)
		+------------------+                    NEXT
	%esi ->	| addr of DOUBLE   |
		+------------------+

	We can add an extra indirection to allow us to run both words written in assembly language
	(primitives written for speed) and words written in FORTH themselves as lists of addresses.

	The extra indirection is the reason for the brackets in JMP *(%eax).

	Let's have a look at how QUADRUPLE and DOUBLE really look in FORTH:

	        : QUADRUPLE DOUBLE DOUBLE ;

		+------------------+
		| codeword         |		   : DOUBLE DUP + ;
		+------------------+
		| addr of DOUBLE  ---------------> +------------------+
		+------------------+               | codeword         |
		| addr of DOUBLE   |		   +------------------+
		+------------------+	   	   | addr of DUP   --------------> +------------------+
		| addr of EXIT	   |		   +------------------+            | codeword      -------+
		+------------------+	   %esi -> | addr of +     --------+	   +------------------+   |
						   +------------------+	   |	   | assembly to    <-----+
						   | addr of EXIT     |    |       | implement DUP    |
						   +------------------+	   |	   |	..	      |
									   |	   |    ..            |
									   |	   | NEXT             |
									   |	   +------------------+
									   |
									   +-----> +------------------+
										   | codeword      -------+
										   +------------------+   |
										   | assembly to   <------+
										   | implement +      |
										   | 	..            |
										   | 	..            |
										   | NEXT      	      |
										   +------------------+

	This is the part where you may need an extra cup of tea/coffee/favourite caffeinated
	beverage.  What has changed is that I've added an extra pointer to the beginning of
	the definitions.  In FORTH this is sometimes called the "codeword".  The codeword is
	a pointer to the interpreter to run the function.  For primitives written in
	assembly language, the "interpreter" just points to the actual assembly code itself.
	They don't need interpreting, they just run.

	In words written in FORTH (like QUADRUPLE and DOUBLE), the codeword points to an interpreter
	function.

	I'll show you the interpreter function shortly, but let's recall our indirect
	JMP *(%eax) with the "extra" brackets.  Take the case where we're executing DOUBLE
	as shown, and DUP has been called.  Note that %esi is pointing to the address of +

	The assembly code for DUP eventually does a NEXT.  That:

	(1) reads the address of + into %eax		%eax points to the codeword of +
	(2) increments %esi by 4
	(3) jumps to the indirect %eax			jumps to the address in the codeword of +,
							ie. the assembly code to implement +

		+------------------+
		| codeword         |
		+------------------+
		| addr of DOUBLE  ---------------> +------------------+
		+------------------+               | codeword         |
		| addr of DOUBLE   |		   +------------------+
		+------------------+	   	   | addr of DUP   --------------> +------------------+
		| addr of EXIT	   |		   +------------------+            | codeword      -------+
		+------------------+	   	   | addr of +     --------+	   +------------------+   |
						   +------------------+	   |	   | assembly to    <-----+
					   %esi -> | addr of EXIT     |    |       | implement DUP    |
						   +------------------+	   |	   |	..	      |
									   |	   |    ..            |
									   |	   | NEXT             |
									   |	   +------------------+
									   |
									   +-----> +------------------+
										   | codeword      -------+
										   +------------------+   |
									now we're  | assembly to    <-----+
									executing  | implement +      |
									this	   | 	..            |
									function   | 	..            |
										   | NEXT      	      |
										   +------------------+

	So I hope that I've convinced you that NEXT does roughly what you'd expect.  This is
	indirect threaded code.

	I've glossed over four things.  I wonder if you can guess without reading on what they are?

	.
	.
	.

	My list of four things are: (1) What does "EXIT" do?  (2) which is related to (1) is how do
	you call into a function, ie. how does %esi start off pointing at part of QUADRUPLE, but
	then point at part of DOUBLE.  (3) What goes in the codeword for the words which are written
	in FORTH?  (4) How do you compile a function which does anything except call other functions
	ie. a function which contains a number like : DOUBLE 2 * ; ?

	THE INTERPRETER AND RETURN STACK ------------------------------------------------------------

	Going at these in no particular order, let's talk about issues (3) and (2), the interpreter
	and the return stack.

	Words which are defined in FORTH need a codeword which points to a little bit of code to
	give them a "helping hand" in life.  They don't need much, but they do need what is known
	as an "interpreter", although it doesn't really "interpret" in the same way that, say,
	Java bytecode used to be interpreted (ie. slowly).  This interpreter just sets up a few
	machine registers so that the word can then execute at full speed using the indirect
	threaded model above.

	One of the things that needs to happen when QUADRUPLE calls DOUBLE is that we save the old
	%esi ("instruction pointer") and create a new one pointing to the first word in DOUBLE.
	Because we will need to restore the old %esi at the end of DOUBLE (this is, after all, like
	a function call), we will need a stack to store these "return addresses" (old values of %esi).

	As you will have seen in the background documentation, FORTH has two stacks, an ordinary
	stack for parameters, and a return stack which is a bit more mysterious.  But our return
	stack is just the stack I talked about in the previous paragraph, used to save %esi when
	calling from a FORTH word into another FORTH word.

	In this FORTH, we are using the normal stack pointer (%esp) for the parameter stack.
	We will use the i386's "other" stack pointer (%ebp, usually called the "frame pointer")
	for our return stack.

	I've got two macros which just wrap up the details of using %ebp for the return stack.
	You use them as for example "PUSHRSP %eax" (push %eax on the return stack) or "POPRSP %ebx"
	(pop top of return stack into %ebx).
*/

/* Macros to deal with the return stack. */
	.macro PUSHRSP reg
	lea -4(%ebp),%ebp	// push reg on to return stack
	movl \reg,(%ebp)
	.endm

	.macro POPRSP reg
	mov (%ebp),\reg		// pop top of return stack to reg
	lea 4(%ebp),%ebp
	.endm

/*
	And with that we can now talk about the interpreter.

	In FORTH the interpreter function is often called DOCOL (I think it means "DO COLON" because
	all FORTH definitions start with a colon, as in : DOUBLE DUP + ;

	The "interpreter" (it's not really "interpreting") just needs to push the old %esi on the
	stack and set %esi to the first word in the definition.  Remember that we jumped to the
	function using JMP *(%eax)?  Well a consequence of that is that conveniently %eax contains
	the address of this codeword, so just by adding 4 to it we get the address of the first
	data word.  Finally after setting up %esi, it just does NEXT which causes that first word
	to run.
*/

/* DOCOL - the interpreter! */
	.text
	.align 4
DOCOL:
	PUSHRSP %esi		// push %esi on to the return stack
	addl $4,%eax		// %eax points to codeword, so make
	movl %eax,%esi		// %esi point to first data word
	NEXT

/*
	Just to make this absolutely clear, let's see how DOCOL works when jumping from QUADRUPLE
	into DOUBLE:

		QUADRUPLE:
		+------------------+
		| codeword         |
		+------------------+		   DOUBLE:
		| addr of DOUBLE  ---------------> +------------------+
		+------------------+       %eax -> | addr of DOCOL    |
	%esi ->	| addr of DOUBLE   |		   +------------------+
		+------------------+	   	   | addr of DUP      |
		| addr of EXIT	   |		   +------------------+
		+------------------+               | etc.             |

	First, the call to DOUBLE calls DOCOL (the codeword of DOUBLE).  DOCOL does this:  It
	pushes the old %esi on the return stack.  %eax points to the codeword of DOUBLE, so we
	just add 4 on to it to get our new %esi:

		QUADRUPLE:
		+------------------+
		| codeword         |
		+------------------+		   DOUBLE:
		| addr of DOUBLE  ---------------> +------------------+
top of return	+------------------+       %eax -> | addr of DOCOL    |
stack points ->	| addr of DOUBLE   |	   + 4 =   +------------------+
		+------------------+	   %esi -> | addr of DUP      |
		| addr of EXIT	   |		   +------------------+
		+------------------+               | etc.             |

	Then we do NEXT, and because of the magic of threaded code that increments %esi again
	and calls DUP.

	Well, it seems to work.

	One minor point here.  Because DOCOL is the first bit of assembly actually to be defined
	in this file (the others were just macros), and because I usually compile this code with the
	text segment starting at address 0, DOCOL has address 0.  So if you are disassembling the
	code and see a word with a codeword of 0, you will immediately know that the word is
	written in FORTH (it's not an assembler primitive) and so uses DOCOL as the interpreter.

	STARTING UP ----------------------------------------------------------------------

	Now let's get down to nuts and bolts.  When we start the program we need to set up
	a few things like the return stack.  But as soon as we can, we want to jump into FORTH
	code (albeit much of the "early" FORTH code will still need to be written as
	assembly language primitives).

	This is what the set up code does.  Does a tiny bit of house-keeping, sets up the
	separate return stack (NB: Linux gives us the ordinary parameter stack already), then
	immediately jumps to a FORTH word called QUIT.  Despite its name, QUIT doesn't quit
	anything.  It resets some internal state and starts reading and interpreting commands.
	(The reason it is called QUIT is because you can call QUIT from your own FORTH code
	to "quit" your program and go back to interpreting).
*/

/* Assembler entry point. */
	.text
	.globl _start
_start:
	cld
	mov %esp,var_S0		// Save the initial data stack pointer in FORTH variable S0.
	mov $return_stack_top,%ebp // Initialise the return stack.
	call set_up_data_segment

	mov $cold_start,%esi	// Initialise interpreter.
	NEXT			// Run interpreter!

	.section .rodata
cold_start:			// High-level code without a codeword.
	.int QUIT

/*
	BUILT-IN WORDS ----------------------------------------------------------------------

	Remember our dictionary entries (headers)?  Let's bring those together with the codeword
	and data words to see how : DOUBLE DUP + ; really looks in memory.

	  pointer to previous word
	   ^
	   |
	+--|------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          | EXIT       |
	+---------+---+---+---+---+---+---+---+---+------------+--|---------+------------+------------+
           ^       len                         pad  codeword      |
	   |							  V
	  LINK in next word				points to codeword of DUP
	
	Initially we can't just write ": DOUBLE DUP + ;" (ie. that literal string) here because we
	don't yet have anything to read the string, break it up at spaces, parse each word, etc. etc.
	So instead we will have to define built-in words using the GNU assembler data constructors
	(like .int, .byte, .string, .ascii and so on -- look them up in the gas info page if you are
	unsure of them).

	The long way would be:

	.int <link to previous word>
	.byte 6			// len
	.ascii "DOUBLE"		// string
	.byte 0			// padding
DOUBLE: .int DOCOL		// codeword
	.int DUP		// pointer to codeword of DUP
	.int PLUS		// pointer to codeword of +
	.int EXIT		// pointer to codeword of EXIT

	That's going to get quite tedious rather quickly, so here I define an assembler macro
	so that I can just write:

	defword "DOUBLE",6,,DOUBLE
	.int DUP,PLUS,EXIT

	and I'll get exactly the same effect.

	Don't worry too much about the exact implementation details of this macro - it's complicated!
*/

/* Flags - these are discussed later. */
	.set F_IMMED,0x80
	.set F_HIDDEN,0x20
	.set F_LENMASK,0x1f	// length mask

	// Store the chain of links.
	.set link,0

	.macro defword name, namelen, flags=0, label
	.section .rodata
	.align 4
	.globl name_\label
name_\label :
	.int link		// link
	.set link,name_\label
	.byte \flags+\namelen	// flags + length byte
	.ascii "\name"		// the name
	.align 4		// padding to next 4 byte boundary
	.globl \label
\label :
	.int DOCOL		// codeword - the interpreter
	// list of word pointers follow
	.endm

/*
	Similarly I want a way to write words written in assembly language.  There will quite a few
	of these to start with because, well, everything has to start in assembly before there's
	enough "infrastructure" to be able to start writing FORTH words, but also I want to define
	some common FORTH words in assembly language for speed, even though I could write them in FORTH.

	This is what DUP looks like in memory:

	  pointer to previous word
	   ^
	   |
	+--|------+---+---+---+---+------------+
	| LINK    | 3 | D | U | P | code_DUP ---------------------> points to the assembly
	+---------+---+---+---+---+------------+		    code used to write DUP,
           ^       len              codeword			    which ends with NEXT.
	   |
	  LINK in next word

	Again, for brevity in writing the header I'm going to write an assembler macro called defcode.
	As with defword above, don't worry about the complicated details of the macro.
*/

	.macro defcode name, namelen, flags=0, label
	.section .rodata
	.align 4
	.globl name_\label
name_\label :
	.int link		// link
	.set link,name_\label
	.byte \flags+\namelen	// flags + length byte
	.ascii "\name"		// the name
	.align 4		// padding to next 4 byte boundary
	.globl \label
\label :
	.int code_\label	// codeword
	.text
	//.align 4
	.globl code_\label
code_\label :			// assembler code follows
	.endm

/*
	Now some easy FORTH primitives.  These are written in assembly for speed.  If you understand
	i386 assembly language then it is worth reading these.  However if you don't understand assembly
	you can skip the details.
*/

	defcode "DROP",4,,DROP
	pop %eax		// drop top of stack
	NEXT

	defcode "SWAP",4,,SWAP
	pop %eax		// swap top two elements on stack
	pop %ebx
	push %eax
	push %ebx
	NEXT

	defcode "DUP",3,,DUP
	mov (%esp),%eax		// duplicate top of stack
	push %eax
	NEXT

	defcode "OVER",4,,OVER
	mov 4(%esp),%eax	// get the second element of stack
	push %eax		// and push it on top
	NEXT

	defcode "ROT",3,,ROT
	pop %eax
	pop %ebx
	pop %ecx
	push %eax
	push %ecx
	push %ebx
	NEXT

	defcode "-ROT",4,,NROT
	pop %eax
	pop %ebx
	pop %ecx
	push %ebx
	push %eax
	push %ecx
	NEXT

	defcode "2DROP",5,,TWODROP // drop top two elements of stack
	pop %eax
	pop %eax
	NEXT

	defcode "2DUP",4,,TWODUP // duplicate top two elements of stack
	mov (%esp),%eax
	mov 4(%esp),%ebx
	push %ebx
	push %eax
	NEXT

	defcode "2SWAP",5,,TWOSWAP // swap top two pairs of elements of stack
	pop %eax
	pop %ebx
	pop %ecx
	pop %edx
	push %ebx
	push %eax
	push %edx
	push %ecx
	NEXT

	defcode "?DUP",4,,QDUP	// duplicate top of stack if non-zero
	movl (%esp),%eax
	test %eax,%eax
	jz 1f
	push %eax
1:	NEXT

	defcode "1+",2,,INCR
	incl (%esp)		// increment top of stack
	NEXT

	defcode "1-",2,,DECR
	decl (%esp)		// decrement top of stack
	NEXT

	defcode "4+",2,,INCR4
	addl $4,(%esp)		// add 4 to top of stack
	NEXT

	defcode "4-",2,,DECR4
	subl $4,(%esp)		// subtract 4 from top of stack
	NEXT

	defcode "+",1,,ADD
	pop %eax		// get top of stack
	addl %eax,(%esp)	// and add it to next word on stack
	NEXT

	defcode "-",1,,SUB
	pop %eax		// get top of stack
	subl %eax,(%esp)	// and subtract it from next word on stack
	NEXT

	defcode "*",1,,MUL
	pop %eax
	pop %ebx
	imull %ebx,%eax
	push %eax		// ignore overflow
	NEXT

/*
	In this FORTH, only /MOD is primitive.  Later we will define the / and MOD words in
	terms of the primitive /MOD.  The design of the i386 assembly instruction idiv which
	leaves both quotient and remainder makes this the obvious choice.
*/

	defcode "/MOD",4,,DIVMOD
	xor %edx,%edx
	pop %ebx
	pop %eax
	idivl %ebx
	push %edx		// push remainder
	push %eax		// push quotient
	NEXT

/*
	Lots of comparison operations like =, <, >, etc..

	ANS FORTH says that the comparison words should return all (binary) 1's for
	TRUE and all 0's for FALSE.  However this is a bit of a strange convention
	so this FORTH breaks it and returns the more normal (for C programmers ...)
	1 meaning TRUE and 0 meaning FALSE.
*/

	defcode "=",1,,EQU	// top two words are equal?
	pop %eax
	pop %ebx
	cmp %ebx,%eax
	sete %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "<>",2,,NEQU	// top two words are not equal?
	pop %eax
	pop %ebx
	cmp %ebx,%eax
	setne %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "<",1,,LT
	pop %eax
	pop %ebx
	cmp %eax,%ebx
	setl %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode ">",1,,GT
	pop %eax
	pop %ebx
	cmp %eax,%ebx
	setg %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "<=",2,,LE
	pop %eax
	pop %ebx
	cmp %eax,%ebx
	setle %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode ">=",2,,GE
	pop %eax
	pop %ebx
	cmp %eax,%ebx
	setge %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "0=",2,,ZEQU	// top of stack equals 0?
	pop %eax
	test %eax,%eax
	setz %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "0<>",3,,ZNEQU	// top of stack not 0?
	pop %eax
	test %eax,%eax
	setnz %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "0<",2,,ZLT	// comparisons with 0
	pop %eax
	test %eax,%eax
	setl %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "0>",2,,ZGT
	pop %eax
	test %eax,%eax
	setg %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "0<=",3,,ZLE
	pop %eax
	test %eax,%eax
	setle %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "0>=",3,,ZGE
	pop %eax
	test %eax,%eax
	setge %al
	movzbl %al,%eax
	pushl %eax
	NEXT

	defcode "AND",3,,AND	// bitwise AND
	pop %eax
	andl %eax,(%esp)
	NEXT

	defcode "OR",2,,OR	// bitwise OR
	pop %eax
	orl %eax,(%esp)
	NEXT

	defcode "XOR",3,,XOR	// bitwise XOR
	pop %eax
	xorl %eax,(%esp)
	NEXT

	defcode "INVERT",6,,INVERT // this is the FORTH bitwise "NOT" function (cf. NEGATE and NOT)
	notl (%esp)
	NEXT

/*
	RETURNING FROM FORTH WORDS ----------------------------------------------------------------------

	Time to talk about what happens when we EXIT a function.  In this diagram QUADRUPLE has called
	DOUBLE, and DOUBLE is about to exit (look at where %esi is pointing):

		QUADRUPLE
		+------------------+
		| codeword         |
		+------------------+		   DOUBLE
		| addr of DOUBLE  ---------------> +------------------+
		+------------------+               | codeword         |
		| addr of DOUBLE   |		   +------------------+
		+------------------+	   	   | addr of DUP      |
		| addr of EXIT	   |		   +------------------+
		+------------------+	   	   | addr of +        |
						   +------------------+
					   %esi -> | addr of EXIT     |
						   +------------------+

	What happens when the + function does NEXT?  Well, the following code is executed.
*/

	defcode "EXIT",4,,EXIT
	POPRSP %esi		// pop return stack into %esi
	NEXT

/*
	EXIT gets the old %esi which we saved from before on the return stack, and puts it in %esi.
	So after this (but just before NEXT) we get:

		QUADRUPLE
		+------------------+
		| codeword         |
		+------------------+		   DOUBLE
		| addr of DOUBLE  ---------------> +------------------+
		+------------------+               | codeword         |
	%esi ->	| addr of DOUBLE   |		   +------------------+
		+------------------+	   	   | addr of DUP      |
		| addr of EXIT	   |		   +------------------+
		+------------------+	   	   | addr of +        |
						   +------------------+
						   | addr of EXIT     |
						   +------------------+

	And NEXT just completes the job by, well, in this case just by calling DOUBLE again :-)

	LITERALS ----------------------------------------------------------------------

	The final point I "glossed over" before was how to deal with functions that do anything
	apart from calling other functions.  For example, suppose that DOUBLE was defined like this:

	: DOUBLE 2 * ;

	It does the same thing, but how do we compile it since it contains the literal 2?  One way
	would be to have a function called "2" (which you'd have to write in assembler), but you'd need
	a function for every single literal that you wanted to use.

	FORTH solves this by compiling the function using a special word called LIT:

	+---------------------------+-------+-------+-------+-------+-------+
	| (usual header of DOUBLE)  | DOCOL | LIT   | 2     | *     | EXIT  |
	+---------------------------+-------+-------+-------+-------+-------+

	LIT is executed in the normal way, but what it does next is definitely not normal.  It
	looks at %esi (which now points to the number 2), grabs it, pushes it on the stack, then
	manipulates %esi in order to skip the number as if it had never been there.

	What's neat is that the whole grab/manipulate can be done using a single byte single
	i386 instruction, our old friend LODSL.  Rather than me drawing more ASCII-art diagrams,
	see if you can find out how LIT works:
*/

	defcode "LIT",3,,LIT
	// %esi points to the next command, but in this case it points to the next
	// literal 32 bit integer.  Get that literal into %eax and increment %esi.
	// On x86, it's a convenient single byte instruction!  (cf. NEXT macro)
	lodsl
	push %eax		// push the literal number on to stack
	NEXT

/*
	MEMORY ----------------------------------------------------------------------

	As important point about FORTH is that it gives you direct access to the lowest levels
	of the machine.  Manipulating memory directly is done frequently in FORTH, and these are
	the primitive words for doing it.
*/

	defcode "!",1,,STORE
	pop %ebx		// address to store at
	pop %eax		// data to store there
	mov %eax,(%ebx)		// store it
	NEXT

	defcode "@",1,,FETCH
	pop %ebx		// address to fetch
	mov (%ebx),%eax		// fetch it
	push %eax		// push value onto stack
	NEXT

	defcode "+!",2,,ADDSTORE
	pop %ebx		// address
	pop %eax		// the amount to add
	addl %eax,(%ebx)	// add it
	NEXT

	defcode "-!",2,,SUBSTORE
	pop %ebx		// address
	pop %eax		// the amount to subtract
	subl %eax,(%ebx)	// add it
	NEXT

/*
	! and @ (STORE and FETCH) store 32-bit words.  It's also useful to be able to read and write bytes
	so we also define standard words C@ and C!.

	Byte-oriented operations only work on architectures which permit them (i386 is one of those).
 */

	defcode "C!",2,,STOREBYTE
	pop %ebx		// address to store at
	pop %eax		// data to store there
	movb %al,(%ebx)		// store it
	NEXT

	defcode "C@",2,,FETCHBYTE
	pop %ebx		// address to fetch
	xor %eax,%eax
	movb (%ebx),%al		// fetch it
	push %eax		// push value onto stack
	NEXT

/* C@C! is a useful byte copy primitive. */
	defcode "C@C!",4,,CCOPY
	movl 4(%esp),%ebx	// source address
	movb (%ebx),%al		// get source character
	pop %edi		// destination address
	stosb			// copy to destination
	push %edi		// increment destination address
	incl 4(%esp)		// increment source address
	NEXT

/* and CMOVE is a block copy operation. */
	defcode "CMOVE",5,,CMOVE
	mov %esi,%edx		// preserve %esi
	pop %ecx		// length
	pop %edi		// destination address
	pop %esi		// source address
	rep movsb		// copy source to destination
	mov %edx,%esi		// restore %esi
	NEXT

/*
	BUILT-IN VARIABLES ----------------------------------------------------------------------

	These are some built-in variables and related standard FORTH words.  Of these, the only one that we
	have discussed so far was LATEST, which points to the last (most recently defined) word in the
	FORTH dictionary.  LATEST is also a FORTH word which pushes the address of LATEST (the variable)
	on to the stack, so you can read or write it using @ and ! operators.  For example, to print
	the current value of LATEST (and this can apply to any FORTH variable) you would do:

	LATEST @ . CR

	To make defining variables shorter, I'm using a macro called defvar, similar to defword and
	defcode above.  (In fact the defvar macro uses defcode to do the dictionary header).
*/

	.macro defvar name, namelen, flags=0, label, initial=0
	defcode \name,\namelen,\flags,\label
	push $var_\name
	NEXT
	.data
	.align 4
var_\name :
	.int \initial
	.endm

/*
	The built-in variables are:

	STATE		Is the interpreter executing code (0) or compiling a word (non-zero)?
	LATEST		Points to the latest (most recently defined) word in the dictionary.
	HERE		Points to the next free byte of memory.  When compiling, compiled words go here.
	S0		Stores the address of the top of the parameter stack.
	BASE		The current base for printing and reading numbers.

*/
	defvar "STATE",5,,STATE
	defvar "HERE",4,,HERE
	defvar "LATEST",6,,LATEST,name_SYSCALL0 // SYSCALL0 must be last in built-in dictionary
	defvar "S0",2,,SZ
	defvar "BASE",4,,BASE,10

/*
	BUILT-IN CONSTANTS ----------------------------------------------------------------------

	It's also useful to expose a few constants to FORTH.  When the word is executed it pushes a
	constant value on the stack.

	The built-in constants are:

	VERSION		Is the current version of this FORTH.
	R0		The address of the top of the return stack.
	DOCOL		Pointer to DOCOL.
	F_IMMED		The IMMEDIATE flag's actual value.
	F_HIDDEN	The HIDDEN flag's actual value.
	F_LENMASK	The length mask in the flags/len byte.

	SYS_*		and the numeric codes of various Linux syscalls (from <asm/unistd.h>)
*/

//#include <asm-i386/unistd.h>	// you might need this instead
#include <asm/unistd.h>

	.macro defconst name, namelen, flags=0, label, value
	defcode \name,\namelen,\flags,\label
	push $\value
	NEXT
	.endm

	defconst "VERSION",7,,VERSION,JONES_VERSION
	defconst "R0",2,,RZ,return_stack_top
	defconst "DOCOL",5,,__DOCOL,DOCOL
	defconst "F_IMMED",7,,__F_IMMED,F_IMMED
	defconst "F_HIDDEN",8,,__F_HIDDEN,F_HIDDEN
	defconst "F_LENMASK",9,,__F_LENMASK,F_LENMASK

	defconst "SYS_EXIT",8,,SYS_EXIT,__NR_exit
	defconst "SYS_OPEN",8,,SYS_OPEN,__NR_open
	defconst "SYS_CLOSE",9,,SYS_CLOSE,__NR_close
	defconst "SYS_READ",8,,SYS_READ,__NR_read
	defconst "SYS_WRITE",9,,SYS_WRITE,__NR_write
	defconst "SYS_CREAT",9,,SYS_CREAT,__NR_creat
	defconst "SYS_BRK",7,,SYS_BRK,__NR_brk

	defconst "O_RDONLY",8,,__O_RDONLY,0
	defconst "O_WRONLY",8,,__O_WRONLY,1
	defconst "O_RDWR",6,,__O_RDWR,2
	defconst "O_CREAT",7,,__O_CREAT,0100
	defconst "O_EXCL",6,,__O_EXCL,0200
	defconst "O_TRUNC",7,,__O_TRUNC,01000
	defconst "O_APPEND",8,,__O_APPEND,02000
	defconst "O_NONBLOCK",10,,__O_NONBLOCK,04000

/*
	RETURN STACK ----------------------------------------------------------------------

	These words allow you to access the return stack.  Recall that the register %ebp always points to
	the top of the return stack.
*/

	defcode ">R",2,,TOR
	pop %eax		// pop parameter stack into %eax
	PUSHRSP %eax		// push it on to the return stack
	NEXT

	defcode "R>",2,,FROMR
	POPRSP %eax		// pop return stack on to %eax
	push %eax		// and push on to parameter stack
	NEXT

	defcode "RSP@",4,,RSPFETCH
	push %ebp
	NEXT

	defcode "RSP!",4,,RSPSTORE
	pop %ebp
	NEXT

	defcode "RDROP",5,,RDROP
	addl $4,%ebp		// pop return stack and throw away
	NEXT

/*
	PARAMETER (DATA) STACK ----------------------------------------------------------------------

	These functions allow you to manipulate the parameter stack.  Recall that Linux sets up the parameter
	stack for us, and it is accessed through %esp.
*/

	defcode "DSP@",4,,DSPFETCH
	mov %esp,%eax
	push %eax
	NEXT

	defcode "DSP!",4,,DSPSTORE
	pop %esp
	NEXT

/*
	INPUT AND OUTPUT ----------------------------------------------------------------------

	These are our first really meaty/complicated FORTH primitives.  I have chosen to write them in
	assembler, but surprisingly in "real" FORTH implementations these are often written in terms
	of more fundamental FORTH primitives.  I chose to avoid that because I think that just obscures
	the implementation.  After all, you may not understand assembler but you can just think of it
	as an opaque block of code that does what it says.

	Let's discuss input first.

	The FORTH word KEY reads the next byte from stdin (and pushes it on the parameter stack).
	So if KEY is called and someone hits the space key, then the number 32 (ASCII code of space)
	is pushed on the stack.

	In FORTH there is no distinction between reading code and reading input.  We might be reading
	and compiling code, we might be reading words to execute, we might be asking for the user
	to type their name -- ultimately it all comes in through KEY.

	The implementation of KEY uses an input buffer of a certain size (defined at the end of this
	file).  It calls the Linux read(2) system call to fill this buffer and tracks its position
	in the buffer using a couple of variables, and if it runs out of input buffer then it refills
	it automatically.  The other thing that KEY does is if it detects that stdin has closed, it
	exits the program, which is why when you hit ^D the FORTH system cleanly exits.

     buffer			      bufftop
	|				 |
	V				 V
	+-------------------------------+--------------------------------------+
	| INPUT READ FROM STDIN ....... | unused part of the buffer            |
	+-------------------------------+--------------------------------------+
	                  ^
			  |
		       currkey (next character to read)

	<---------------------- BUFFER_SIZE (4096 bytes) ---------------------->
*/

	defcode "KEY",3,,KEY
	call _KEY
	push %eax		// push return value on stack
	NEXT
_KEY:
	mov (currkey),%ebx
	cmp (bufftop),%ebx
	jge 1f			// exhausted the input buffer?
	xor %eax,%eax
	mov (%ebx),%al		// get next key from input buffer
	inc %ebx
	mov %ebx,(currkey)	// increment currkey
	ret

1:	// Out of input; use read(2) to fetch more input from stdin.
	xor %ebx,%ebx		// 1st param: stdin
	mov $buffer,%ecx	// 2nd param: buffer
	mov %ecx,currkey
	mov $BUFFER_SIZE,%edx	// 3rd param: max length
	mov $__NR_read,%eax	// syscall: read
	int $0x80
	test %eax,%eax		// If %eax <= 0, then exit.
	jbe 2f
	addl %eax,%ecx		// buffer+%eax = bufftop
	mov %ecx,bufftop
	jmp _KEY

2:	// Error or end of input: exit the program.
	xor %ebx,%ebx
	mov $__NR_exit,%eax	// syscall: exit
	int $0x80

	.data
	.align 4
currkey:
	.int buffer		// Current place in input buffer (next character to read).
bufftop:
	.int buffer		// Last valid data in input buffer + 1.

/*
	By contrast, output is much simpler.  The FORTH word EMIT writes out a single byte to stdout.
	This implementation just uses the write system call.  No attempt is made to buffer output, but
	it would be a good exercise to add it.
*/

	defcode "EMIT",4,,EMIT
	pop %eax
	call _EMIT
	NEXT
_EMIT:
	mov $1,%ebx		// 1st param: stdout

	// write needs the address of the byte to write
	mov %al,emit_scratch
	mov $emit_scratch,%ecx	// 2nd param: address

	mov $1,%edx		// 3rd param: nbytes = 1

	mov $__NR_write,%eax	// write syscall
	int $0x80
	ret

	.data			// NB: easier to fit in the .data section
emit_scratch:
	.space 1		// scratch used by EMIT

/*
	Back to input, WORD is a FORTH word which reads the next full word of input.

	What it does in detail is that it first skips any blanks (spaces, tabs, newlines and so on).
	Then it calls KEY to read characters into an internal buffer until it hits a blank.  Then it
	calculates the length of the word it read and returns the address and the length as
	two words on the stack (with the length at the top of stack).

	Notice that WORD has a single internal buffer which it overwrites each time (rather like
	a static C string).  Also notice that WORD's internal buffer is just 32 bytes long and
	there is NO checking for overflow.  31 bytes happens to be the maximum length of a
	FORTH word that we support, and that is what WORD is used for: to read FORTH words when
	we are compiling and executing code.  The returned strings are not NUL-terminated.

	Start address+length is the normal way to represent strings in FORTH (not ending in an
	ASCII NUL character as in C), and so FORTH strings can contain any character including NULs
	and can be any length.

	WORD is not suitable for just reading strings (eg. user input) because of all the above
	peculiarities and limitations.

	Note that when executing, you'll see:
	WORD FOO
	which puts "FOO" and length 3 on the stack, but when compiling:
	: BAR WORD FOO ;
	is an error (or at least it doesn't do what you might expect).  Later we'll talk about compiling
	and immediate mode, and you'll understand why.
*/

	defcode "WORD",4,,WORD
	call _WORD
	push %edi		// push base address
	push %ecx		// push length
	NEXT

_WORD:
	/* Search for first non-blank character.  Also skip \ comments. */
1:
	call _KEY		// get next key, returned in %eax
	cmpb $'\\',%al		// start of a comment?
	je 3f			// if so, skip the comment
	cmpb $' ',%al
	jbe 1b			// if so, keep looking

	/* Search for the end of the word, storing chars as we go. */
	mov $word_buffer,%edi	// pointer to return buffer
2:
	stosb			// add character to return buffer
	call _KEY		// get next key, returned in %al
	cmpb $' ',%al		// is blank?
	ja 2b			// if not, keep looping

	/* Return the word (well, the static buffer) and length. */
	sub $word_buffer,%edi
	mov %edi,%ecx		// return length of the word
	mov $word_buffer,%edi	// return address of the word
	ret

	/* Code to skip \ comments to end of the current line. */
3:
	call _KEY
	cmpb $'\n',%al		// end of line yet?
	jne 3b
	jmp 1b

	.data			// NB: easier to fit in the .data section
	// A static buffer where WORD returns.  Subsequent calls
	// overwrite this buffer.  Maximum word length is 32 chars.
word_buffer:
	.space 32

/*
	As well as reading in words we'll need to read in numbers and for that we are using a function
	called NUMBER.  This parses a numeric string such as one returned by WORD and pushes the
	number on the parameter stack.

	The function uses the variable BASE as the base (radix) for conversion, so for example if
	BASE is 2 then we expect a binary number.  Normally BASE is 10.

	If the word starts with a '-' character then the returned value is negative.

	If the string can't be parsed as a number (or contains characters outside the current BASE)
	then we need to return an error indication.  So NUMBER actually returns two items on the stack.
	At the top of stack we return the number of unconverted characters (ie. if 0 then all characters
	were converted, so there is no error).  Second from top of stack is the parsed number or a
	partial value if there was an error.
*/
	defcode "NUMBER",6,,NUMBER
	pop %ecx		// length of string
	pop %edi		// start address of string
	call _NUMBER
	push %eax		// parsed number
	push %ecx		// number of unparsed characters (0 = no error)
	NEXT

_NUMBER:
	xor %eax,%eax
	xor %ebx,%ebx

	test %ecx,%ecx		// trying to parse a zero-length string is an error, but will return 0.
	jz 5f

	movl var_BASE,%edx	// get BASE (in %dl)

	// Check if first character is '-'.
	movb (%edi),%bl		// %bl = first character in string
	inc %edi
	push %eax		// push 0 on stack
	cmpb $'-',%bl		// negative number?
	jnz 2f
	pop %eax
	push %ebx		// push <> 0 on stack, indicating negative
	dec %ecx
	jnz 1f
	pop %ebx		// error: string is only '-'.
	movl $1,%ecx
	ret

	// Loop reading digits.
1:	imull %edx,%eax		// %eax *= BASE
	movb (%edi),%bl		// %bl = next character in string
	inc %edi

	// Convert 0-9, A-Z to a number 0-35.
2:	subb $'0',%bl		// < '0'?
	jb 4f
	cmp $10,%bl		// <= '9'?
	jb 3f
	subb $17,%bl		// < 'A'? (17 is 'A'-'0')
	jb 4f
	addb $10,%bl

3:	cmp %dl,%bl		// >= BASE?
	jge 4f

	// OK, so add it to %eax and loop.
	add %ebx,%eax
	dec %ecx
	jnz 1b

	// Negate the result if first character was '-' (saved on the stack).
4:	pop %ebx
	test %ebx,%ebx
	jz 5f
	neg %eax

5:	ret

/*
	DICTIONARY LOOK UPS ----------------------------------------------------------------------

	We're building up to our prelude on how FORTH code is compiled, but first we need yet more infrastructure.

	The FORTH word FIND takes a string (a word as parsed by WORD -- see above) and looks it up in the
	dictionary.  What it actually returns is the address of the dictionary header, if it finds it,
	or 0 if it didn't.

	So if DOUBLE is defined in the dictionary, then WORD DOUBLE FIND returns the following pointer:

    pointer to this
	|
	|
	V
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          | EXIT       |
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+

	See also >CFA and >DFA.

	FIND doesn't find dictionary entries which are flagged as HIDDEN.  See below for why.
*/

	defcode "FIND",4,,FIND
	pop %ecx		// %ecx = length
	pop %edi		// %edi = address
	call _FIND
	push %eax		// %eax = address of dictionary entry (or NULL)
	NEXT

_FIND:
	push %esi		// Save %esi so we can use it in string comparison.

	// Now we start searching backwards through the dictionary for this word.
	mov var_LATEST,%edx	// LATEST points to name header of the latest word in the dictionary
1:	test %edx,%edx		// NULL pointer?  (end of the linked list)
	je 4f

	// Compare the length expected and the length of the word.
	// Note that if the F_HIDDEN flag is set on the word, then by a bit of trickery
	// this won't pick the word (the length will appear to be wrong).
	xor %eax,%eax
	movb 4(%edx),%al	// %al = flags+length field
	andb $(F_HIDDEN|F_LENMASK),%al // %al = name length
	cmpb %cl,%al		// Length is the same?
	jne 2f

	// Compare the strings in detail.
	push %ecx		// Save the length
	push %edi		// Save the address (repe cmpsb will move this pointer)
	lea 5(%edx),%esi	// Dictionary string we are checking against.
	repe cmpsb		// Compare the strings.
	pop %edi
	pop %ecx
	jne 2f			// Not the same.

	// The strings are the same - return the header pointer in %eax
	pop %esi
	mov %edx,%eax
	ret

2:	mov (%edx),%edx		// Move back through the link field to the previous word
	jmp 1b			// .. and loop.

4:	// Not found.
	pop %esi
	xor %eax,%eax		// Return zero to indicate not found.
	ret

/*
	FIND returns the dictionary pointer, but when compiling we need the codeword pointer (recall
	that FORTH definitions are compiled into lists of codeword pointers).  The standard FORTH
	word >CFA turns a dictionary pointer into a codeword pointer.

	The example below shows the result of:

		WORD DOUBLE FIND >CFA

	FIND returns a pointer to this
	|				>CFA converts it to a pointer to this
	|					   |
	V					   V
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          | EXIT       |
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
						   codeword

	Notes:

	Because names vary in length, this isn't just a simple increment.

	In this FORTH you cannot easily turn a codeword pointer back into a dictionary entry pointer, but
	that is not true in most FORTH implementations where they store a back pointer in the definition
	(with an obvious memory/complexity cost).  The reason they do this is that it is useful to be
	able to go backwards (codeword -> dictionary entry) in order to decompile FORTH definitions
	quickly.

	What does CFA stand for?  My best guess is "Code Field Address".
*/

	defcode ">CFA",4,,TCFA
	pop %edi
	call _TCFA
	push %edi
	NEXT
_TCFA:
	xor %eax,%eax
	add $4,%edi		// Skip link pointer.
	movb (%edi),%al		// Load flags+len into %al.
	inc %edi		// Skip flags+len byte.
	andb $F_LENMASK,%al	// Just the length, not the flags.
	add %eax,%edi		// Skip the name.
	addl $3,%edi		// The codeword is 4-byte aligned.
	andl $~3,%edi
	ret

/*
	Related to >CFA is >DFA which takes a dictionary entry address as returned by FIND and
	returns a pointer to the first data field.

	FIND returns a pointer to this
	|				>CFA converts it to a pointer to this
	|					   |
	|					   |	>DFA converts it to a pointer to this
	|					   |		 |
	V					   V		 V
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          | EXIT       |
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
						   codeword

	(Note to those following the source of FIG-FORTH / ciforth: My >DFA definition is
	different from theirs, because they have an extra indirection).

	You can see that >DFA is easily defined in FORTH just by adding 4 to the result of >CFA.
*/

	defword ">DFA",4,,TDFA
	.int TCFA		// >CFA		(get code field address)
	.int INCR4		// 4+		(add 4 to it to get to next word)
	.int EXIT		// EXIT		(return from FORTH word)

/*
	COMPILING ----------------------------------------------------------------------

	Now we'll talk about how FORTH compiles words.  Recall that a word definition looks like this:

		: DOUBLE DUP + ;

	and we have to turn this into:

	  pointer to previous word
	   ^
	   |
	+--|------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          | EXIT       |
	+---------+---+---+---+---+---+---+---+---+------------+--|---------+------------+------------+
           ^       len                         pad  codeword      |
	   |							  V
	  LATEST points here				points to codeword of DUP

	There are several problems to solve.  Where to put the new word?  How do we read words?  How
	do we define the words : (COLON) and ; (SEMICOLON)?

	FORTH solves this rather elegantly and as you might expect in a very low-level way which
	allows you to change how the compiler works on your own code.

	FORTH has an INTERPRET function (a true interpreter this time, not DOCOL) which runs in a
	loop, reading words (using WORD), looking them up (using FIND), turning them into codeword
	pointers (using >CFA) and deciding what to do with them.

	What it does depends on the mode of the interpreter (in variable STATE).

	When STATE is zero, the interpreter just runs each word as it looks them up.  This is known as
	immediate mode.

	The interesting stuff happens when STATE is non-zero -- compiling mode.  In this mode the
	interpreter appends the codeword pointer to user memory (the HERE variable points to the next
	free byte of user memory -- see DATA SEGMENT section below).

	So you may be able to see how we could define : (COLON).  The general plan is:

	(1) Use WORD to read the name of the function being defined.

	(2) Construct the dictionary entry -- just the header part -- in user memory:

    pointer to previous word (from LATEST)			+-- Afterwards, HERE points here, where
	   ^							|   the interpreter will start appending
	   |							V   codewords.
	+--|------+---+---+---+---+---+---+---+---+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      |
	+---------+---+---+---+---+---+---+---+---+------------+
                   len                         pad  codeword

	(3) Set LATEST to point to the newly defined word, ...

	(4) .. and most importantly leave HERE pointing just after the new codeword.  This is where
	    the interpreter will append codewords.

	(5) Set STATE to 1.  This goes into compile mode so the interpreter starts appending codewords to
	    our partially-formed header.

	After : has run, our input is here:

	: DOUBLE DUP + ;
	         ^
		 |
		Next byte returned by KEY will be the 'D' character of DUP

	so the interpreter (now it's in compile mode, so I guess it's really the compiler) reads "DUP",
	looks it up in the dictionary, gets its codeword pointer, and appends it:

									     +-- HERE updated to point here.
									     |
									     V
	+---------+---+---+---+---+---+---+---+---+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        |
	+---------+---+---+---+---+---+---+---+---+------------+------------+
                   len                         pad  codeword

	Next we read +, get the codeword pointer, and append it:

											  +-- HERE updated to point here.
											  |
											  V
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          |
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+
                   len                         pad  codeword

	The issue is what happens next.  Obviously what we _don't_ want to happen is that we
	read ";" and compile it and go on compiling everything afterwards.

	At this point, FORTH uses a trick.  Remember the length byte in the dictionary definition
	isn't just a plain length byte, but can also contain flags.  One flag is called the
	IMMEDIATE flag (F_IMMED in this code).  If a word in the dictionary is flagged as
	IMMEDIATE then the interpreter runs it immediately _even if it's in compile mode_.

	This is how the word ; (SEMICOLON) works -- as a word flagged in the dictionary as IMMEDIATE.

	And all it does is append the codeword for EXIT on to the current definition and switch
	back to immediate mode (set STATE back to 0).  Shortly we'll see the actual definition
	of ; and we'll see that it's really a very simple definition, declared IMMEDIATE.

	After the interpreter reads ; and executes it 'immediately', we get this:

	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      | DUP        | +          | EXIT       |
	+---------+---+---+---+---+---+---+---+---+------------+------------+------------+------------+
                   len                         pad  codeword					       ^
												       |
												      HERE
	STATE is set to 0.

	And that's it, job done, our new definition is compiled, and we're back in immediate mode
	just reading and executing words, perhaps including a call to test our new word DOUBLE.

	The only last wrinkle in this is that while our word was being compiled, it was in a
	half-finished state.  We certainly wouldn't want DOUBLE to be called somehow during
	this time.  There are several ways to stop this from happening, but in FORTH what we
	do is flag the word with the HIDDEN flag (F_HIDDEN in this code) just while it is
	being compiled.  This prevents FIND from finding it, and thus in theory stops any
	chance of it being called.

	The above explains how compiling, : (COLON) and ; (SEMICOLON) works and in a moment I'm
	going to define them.  The : (COLON) function can be made a little bit more general by writing
	it in two parts.  The first part, called CREATE, makes just the header:

						   +-- Afterwards, HERE points here.
						   |
						   V
	+---------+---+---+---+---+---+---+---+---+
	| LINK    | 6 | D | O | U | B | L | E | 0 |
	+---------+---+---+---+---+---+---+---+---+
                   len                         pad

	and the second part, the actual definition of : (COLON), calls CREATE and appends the
	DOCOL codeword, so leaving:

								+-- Afterwards, HERE points here.
								|
								V
	+---------+---+---+---+---+---+---+---+---+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 | DOCOL      |
	+---------+---+---+---+---+---+---+---+---+------------+
                   len                         pad  codeword

	CREATE is a standard FORTH word and the advantage of this split is that we can reuse it to
	create other types of words (not just ones which contain code, but words which contain variables,
	constants and other data).
*/

	defcode "CREATE",6,,CREATE

	// Get the name length and address.
	pop %ecx		// %ecx = length
	pop %ebx		// %ebx = address of name

	// Link pointer.
	movl var_HERE,%edi	// %edi is the address of the header
	movl var_LATEST,%eax	// Get link pointer
	stosl			// and store it in the header.

	// Length byte and the word itself.
	mov %cl,%al		// Get the length.
	stosb			// Store the length/flags byte.
	push %esi
	mov %ebx,%esi		// %esi = word
	rep movsb		// Copy the word
	pop %esi
	addl $3,%edi		// Align to next 4 byte boundary.
	andl $~3,%edi

	// Update LATEST and HERE.
	movl var_HERE,%eax
	movl %eax,var_LATEST
	movl %edi,var_HERE
	NEXT

/*
	Because I want to define : (COLON) in FORTH, not assembler, we need a few more FORTH words
	to use.

	The first is , (COMMA) which is a standard FORTH word which appends a 32 bit integer to the user
	memory pointed to by HERE, and adds 4 to HERE.  So the action of , (COMMA) is:

							previous value of HERE
								 |
								 V
	+---------+---+---+---+---+---+---+---+---+-- - - - - --+------------+
	| LINK    | 6 | D | O | U | B | L | E | 0 |             |  <data>    |
	+---------+---+---+---+---+---+---+---+---+-- - - - - --+------------+
                   len                         pad		              ^
									      |
									new value of HERE

	and <data> is whatever 32 bit integer was at the top of the stack.

	, (COMMA) is quite a fundamental operation when compiling.  It is used to append codewords
	to the current word that is being compiled.
*/

	defcode ",",1,,COMMA
	pop %eax		// Code pointer to store.
	call _COMMA
	NEXT
_COMMA:
	movl var_HERE,%edi	// HERE
	stosl			// Store it.
	movl %edi,var_HERE	// Update HERE (incremented)
	ret

/*
	Our definitions of : (COLON) and ; (SEMICOLON) will need to switch to and from compile mode.

	Immediate mode vs. compile mode is stored in the global variable STATE, and by updating this
	variable we can switch between the two modes.

	For various reasons which may become apparent later, FORTH defines two standard words called
	[ and ] (LBRAC and RBRAC) which switch between modes:

	Word	Assembler	Action		Effect
	[	LBRAC		STATE := 0	Switch to immediate mode.
	]	RBRAC		STATE := 1	Switch to compile mode.

	[ (LBRAC) is an IMMEDIATE word.  The reason is as follows: If we are in compile mode and the
	interpreter saw [ then it would compile it rather than running it.  We would never be able to
	switch back to immediate mode!  So we flag the word as IMMEDIATE so that even in compile mode
	the word runs immediately, switching us back to immediate mode.
*/

	defcode "[",1,F_IMMED,LBRAC
	xor %eax,%eax
	movl %eax,var_STATE	// Set STATE to 0.
	NEXT

	defcode "]",1,,RBRAC
	movl $1,var_STATE	// Set STATE to 1.
	NEXT

/*
	Now we can define : (COLON) using CREATE.  It just calls CREATE, appends DOCOL (the codeword), sets
	the word HIDDEN and goes into compile mode.
*/

	defword ":",1,,COLON
	.int WORD		// Get the name of the new word
	.int CREATE		// CREATE the dictionary entry / header
	.int LIT, DOCOL, COMMA	// Append DOCOL  (the codeword).
	.int LATEST, FETCH, HIDDEN // Make the word hidden (see below for definition).
	.int RBRAC		// Go into compile mode.
	.int EXIT		// Return from the function.

/*
	; (SEMICOLON) is also elegantly simple.  Notice the F_IMMED flag.
*/

	defword ";",1,F_IMMED,SEMICOLON
	.int LIT, EXIT, COMMA	// Append EXIT (so the word will return).
	.int LATEST, FETCH, HIDDEN // Toggle hidden flag -- unhide the word (see below for definition).
	.int LBRAC		// Go back to IMMEDIATE mode.
	.int EXIT		// Return from the function.

/*
	EXTENDING THE COMPILER ----------------------------------------------------------------------

	Words flagged with IMMEDIATE (F_IMMED) aren't just for the FORTH compiler to use.  You can define
	your own IMMEDIATE words too, and this is a crucial aspect when extending basic FORTH, because
	it allows you in effect to extend the compiler itself.  Does gcc let you do that?

	Standard FORTH words like IF, WHILE, ." and so on are all written as extensions to the basic
	compiler, and are all IMMEDIATE words.

	The IMMEDIATE word toggles the F_IMMED (IMMEDIATE flag) on the most recently defined word,
	or on the current word if you call it in the middle of a definition.

	Typical usage is:

	: MYIMMEDWORD IMMEDIATE
		...definition...
	;

	but some FORTH programmers write this instead:

	: MYIMMEDWORD
		...definition...
	; IMMEDIATE

	The two usages are equivalent, to a first approximation.
*/

	defcode "IMMEDIATE",9,F_IMMED,IMMEDIATE
	movl var_LATEST,%edi	// LATEST word.
	addl $4,%edi		// Point to name/flags byte.
	xorb $F_IMMED,(%edi)	// Toggle the IMMED bit.
	NEXT

/*
	'addr HIDDEN' toggles the hidden flag (F_HIDDEN) of the word defined at addr.  To hide the
	most recently defined word (used above in : and ; definitions) you would do:

		LATEST @ HIDDEN

	'HIDE word' toggles the flag on a named 'word'.

	Setting this flag stops the word from being found by FIND, and so can be used to make 'private'
	words.  For example, to break up a large word into smaller parts you might do:

		: SUB1 ... subword ... ;
		: SUB2 ... subword ... ;
		: SUB3 ... subword ... ;
		: MAIN ... defined in terms of SUB1, SUB2, SUB3 ... ;
		HIDE SUB1
		HIDE SUB2
		HIDE SUB3

	After this, only MAIN is 'exported' or seen by the rest of the program.
*/

	defcode "HIDDEN",6,,HIDDEN
	pop %edi		// Dictionary entry.
	addl $4,%edi		// Point to name/flags byte.
	xorb $F_HIDDEN,(%edi)	// Toggle the HIDDEN bit.
	NEXT

	defword "HIDE",4,,HIDE
	.int WORD		// Get the word (after HIDE).
	.int FIND		// Look up in the dictionary.
	.int HIDDEN		// Set F_HIDDEN flag.
	.int EXIT		// Return.

/*
	' (TICK) is a standard FORTH word which returns the codeword pointer of the next word.

	The common usage is:

	' FOO ,

	which appends the codeword of FOO to the current word we are defining (this only works in compiled code).

	You tend to use ' in IMMEDIATE words.  For example an alternate (and rather useless) way to define
	a literal 2 might be:

	: LIT2 IMMEDIATE
		' LIT ,		\ Appends LIT to the currently-being-defined word
		2 ,		\ Appends the number 2 to the currently-being-defined word
	;

	So you could do:

	: DOUBLE LIT2 * ;

	(If you don't understand how LIT2 works, then you should review the material about compiling words
	and immediate mode).

	This definition of ' uses a cheat which I copied from buzzard92.  As a result it only works in
	compiled code.  It is possible to write a version of ' based on WORD, FIND, >CFA which works in
	immediate mode too.
*/
	defcode "'",1,,TICK
	lodsl			// Get the address of the next word and skip it.
	pushl %eax		// Push it on the stack.
	NEXT

/*
	BRANCHING ----------------------------------------------------------------------

	It turns out that all you need in order to define looping constructs, IF-statements, etc.
	are two primitives.

	BRANCH is an unconditional branch. 0BRANCH is a conditional branch (it only branches if the
	top of stack is zero).

	The diagram below shows how BRANCH works in some imaginary compiled word.  When BRANCH executes,
	%esi starts by pointing to the offset field (compare to LIT above):

	+---------------------+-------+---- - - ---+------------+------------+---- - - - ----+------------+
	| (Dictionary header) | DOCOL |            | BRANCH     | offset     | (skipped)     | word       |
	+---------------------+-------+---- - - ---+------------+-----|------+---- - - - ----+------------+
								   ^  |			      ^
								   |  |			      |
								   |  +-----------------------+
								  %esi added to offset

	The offset is added to %esi to make the new %esi, and the result is that when NEXT runs, execution
	continues at the branch target.  Negative offsets work as expected.

	0BRANCH is the same except the branch happens conditionally.

	Now standard FORTH words such as IF, THEN, ELSE, WHILE, REPEAT, etc. can be implemented entirely
	in FORTH.  They are IMMEDIATE words which append various combinations of BRANCH or 0BRANCH
	into the word currently being compiled.

	As an example, code written like this:

		condition-code IF true-part THEN rest-code

	compiles to:

		condition-code 0BRANCH OFFSET true-part rest-code
					  |		^
					  |		|
					  +-------------+
*/

	defcode "BRANCH",6,,BRANCH
	add (%esi),%esi		// add the offset to the instruction pointer
	NEXT

	defcode "0BRANCH",7,,ZBRANCH
	pop %eax
	test %eax,%eax		// top of stack is zero?
	jz code_BRANCH		// if so, jump back to the branch function above
	lodsl			// otherwise we need to skip the offset
	NEXT

/*
	LITERAL STRINGS ----------------------------------------------------------------------

	LITSTRING is a primitive used to implement the ." and S" operators (which are written in
	FORTH).  See the definition of those operators later.

	TELL just prints a string.  It's more efficient to define this in assembly because we
	can make it a single Linux syscall.
*/

	defcode "LITSTRING",9,,LITSTRING
	lodsl			// get the length of the string
	push %esi		// push the address of the start of the string
	push %eax		// push it on the stack
	addl %eax,%esi		// skip past the string
 	addl $3,%esi		// but round up to next 4 byte boundary
	andl $~3,%esi
	NEXT

	defcode "TELL",4,,TELL
	mov $1,%ebx		// 1st param: stdout
	pop %edx		// 3rd param: length of string
	pop %ecx		// 2nd param: address of string
	mov $__NR_write,%eax	// write syscall
	int $0x80
	NEXT

/*
	QUIT AND INTERPRET ----------------------------------------------------------------------

	QUIT is the first FORTH function called, almost immediately after the FORTH system "boots".
	As explained before, QUIT doesn't "quit" anything.  It does some initialisation (in particular
	it clears the return stack) and it calls INTERPRET in a loop to interpret commands.  The
	reason it is called QUIT is because you can call it from your own FORTH words in order to
	"quit" your program and start again at the user prompt.

	INTERPRET is the FORTH interpreter ("toploop", "toplevel" or "REPL" might be a more accurate
	description -- see: http://en.wikipedia.org/wiki/REPL).
*/

	// QUIT must not return (ie. must not call EXIT).
	defword "QUIT",4,,QUIT
	.int RZ,RSPSTORE	// R0 RSP!, clear the return stack
	.int INTERPRET		// interpret the next word
	.int BRANCH,-8		// and loop (indefinitely)

/*
	This interpreter is pretty simple, but remember that in FORTH you can always override
	it later with a more powerful one!
 */
	defcode "INTERPRET",9,,INTERPRET
	call _WORD		// Returns %ecx = length, %edi = pointer to word.

	// Is it in the dictionary?
	xor %eax,%eax
	movl %eax,interpret_is_lit // Not a literal number (not yet anyway ...)
	call _FIND		// Returns %eax = pointer to header or 0 if not found.
	test %eax,%eax		// Found?
	jz 1f

	// In the dictionary.  Is it an IMMEDIATE codeword?
	mov %eax,%edi		// %edi = dictionary entry
	movb 4(%edi),%al	// Get name+flags.
	push %ax		// Just save it for now.
	call _TCFA		// Convert dictionary entry (in %edi) to codeword pointer.
	pop %ax
	andb $F_IMMED,%al	// Is IMMED flag set?
	mov %edi,%eax
	jnz 4f			// If IMMED, jump straight to executing.

	jmp 2f

1:	// Not in the dictionary (not a word) so assume it's a literal number.
	incl interpret_is_lit
	call _NUMBER		// Returns the parsed number in %eax, %ecx > 0 if error
	test %ecx,%ecx
	jnz 6f
	mov %eax,%ebx
	mov $LIT,%eax		// The word is LIT

2:	// Are we compiling or executing?
	movl var_STATE,%edx
	test %edx,%edx
	jz 4f			// Jump if executing.

	// Compiling - just append the word to the current dictionary definition.
	call _COMMA
	mov interpret_is_lit,%ecx // Was it a literal?
	test %ecx,%ecx
	jz 3f
	mov %ebx,%eax		// Yes, so LIT is followed by a number.
	call _COMMA
3:	NEXT

4:	// Executing - run it!
	mov interpret_is_lit,%ecx // Literal?
	test %ecx,%ecx		// Literal?
	jnz 5f

	// Not a literal, execute it now.  This never returns, but the codeword will
	// eventually call NEXT which will reenter the loop in QUIT.
	jmp *(%eax)

5:	// Executing a literal, which means push it on the stack.
	push %ebx
	NEXT

6:	// Parse error (not a known word or a number in the current BASE).
	// Print an error message followed by up to 40 characters of context.
	mov $2,%ebx		// 1st param: stderr
	mov $errmsg,%ecx	// 2nd param: error message
	mov $errmsgend-errmsg,%edx // 3rd param: length of string
	mov $__NR_write,%eax	// write syscall
	int $0x80

	mov (currkey),%ecx	// the error occurred just before currkey position
	mov %ecx,%edx
	sub $buffer,%edx	// %edx = currkey - buffer (length in buffer before currkey)
	cmp $40,%edx		// if > 40, then print only 40 characters
	jle 7f
	mov $40,%edx
7:	sub %edx,%ecx		// %ecx = start of area to print, %edx = length
	mov $__NR_write,%eax	// write syscall
	int $0x80

	mov $errmsgnl,%ecx	// newline
	mov $1,%edx
	mov $__NR_write,%eax	// write syscall
	int $0x80

	NEXT

	.section .rodata
errmsg: .ascii "PARSE ERROR: "
errmsgend:
errmsgnl: .ascii "\n"

	.data			// NB: easier to fit in the .data section
	.align 4
interpret_is_lit:
	.int 0			// Flag used to record if reading a literal

/*
	ODDS AND ENDS ----------------------------------------------------------------------

	CHAR puts the ASCII code of the first character of the following word on the stack.  For example
	CHAR A puts 65 on the stack.

	EXECUTE is used to run execution tokens.  See the discussion of execution tokens in the
	FORTH code for more details.

	SYSCALL0, SYSCALL1, SYSCALL2, SYSCALL3 make a standard Linux system call.  (See <asm/unistd.h>
	for a list of system call numbers).  As their name suggests these forms take between 0 and 3
	syscall parameters, plus the system call number.

	In this FORTH, SYSCALL0 must be the last word in the built-in (assembler) dictionary because we
	initialise the LATEST variable to point to it.  This means that if you want to extend the assembler
	part, you must put new words before SYSCALL0, or else change how LATEST is initialised.
*/

	defcode "CHAR",4,,CHAR
	call _WORD		// Returns %ecx = length, %edi = pointer to word.
	xor %eax,%eax
	movb (%edi),%al		// Get the first character of the word.
	push %eax		// Push it onto the stack.
	NEXT

	defcode "EXECUTE",7,,EXECUTE
	pop %eax		// Get xt into %eax
	jmp *(%eax)		// and jump to it.
				// After xt runs its NEXT will continue executing the current word.

	defcode "SYSCALL3",8,,SYSCALL3
	pop %eax		// System call number (see <asm/unistd.h>)
	pop %ebx		// First parameter.
	pop %ecx		// Second parameter
	pop %edx		// Third parameter
	int $0x80
	push %eax		// Result (negative for -errno)
	NEXT

	defcode "SYSCALL2",8,,SYSCALL2
	pop %eax		// System call number (see <asm/unistd.h>)
	pop %ebx		// First parameter.
	pop %ecx		// Second parameter
	int $0x80
	push %eax		// Result (negative for -errno)
	NEXT

	defcode "SYSCALL1",8,,SYSCALL1
	pop %eax		// System call number (see <asm/unistd.h>)
	pop %ebx		// First parameter.
	int $0x80
	push %eax		// Result (negative for -errno)
	NEXT

	defcode "SYSCALL0",8,,SYSCALL0
	pop %eax		// System call number (see <asm/unistd.h>)
	int $0x80
	push %eax		// Result (negative for -errno)
	NEXT

/*
	DATA SEGMENT ----------------------------------------------------------------------

	Here we set up the Linux data segment, used for user definitions and variously known as just
	the 'data segment', 'user memory' or 'user definitions area'.  It is an area of memory which
	grows upwards and stores both newly-defined FORTH words and global variables of various
	sorts.

	It is completely analogous to the C heap, except there is no generalised 'malloc' and 'free'
	(but as with everything in FORTH, writing such functions would just be a Simple Matter
	Of Programming).  Instead in normal use the data segment just grows upwards as new FORTH
	words are defined/appended to it.

	There are various "features" of the GNU toolchain which make setting up the data segment
	more complicated than it really needs to be.  One is the GNU linker which inserts a random
	"build ID" segment.  Another is Address Space Randomization which means we can't tell
	where the kernel will choose to place the data segment (or the stack for that matter).

	Therefore writing this set_up_data_segment assembler routine is a little more complicated
	than it really needs to be.  We ask the Linux kernel where it thinks the data segment starts
	using the brk(2) system call, then ask it to reserve some initial space (also using brk(2)).

	You don't need to worry about this code.
*/
	.text
	.set INITIAL_DATA_SEGMENT_SIZE,65536
set_up_data_segment:
	xor %ebx,%ebx		// Call brk(0)
	movl $__NR_brk,%eax
	int $0x80
	movl %eax,var_HERE	// Initialise HERE to point at beginning of data segment.
	addl $INITIAL_DATA_SEGMENT_SIZE,%eax	// Reserve nn bytes of memory for initial data segment.
	movl %eax,%ebx		// Call brk(HERE+INITIAL_DATA_SEGMENT_SIZE)
	movl $__NR_brk,%eax
	int $0x80
	ret

/*
	We allocate static buffers for the return static and input buffer (used when
	reading in files and text that the user types in).
*/
	.set RETURN_STACK_SIZE,8192
	.set BUFFER_SIZE,4096

	.bss
/* FORTH return stack. */
	.align 4096
return_stack:
	.space RETURN_STACK_SIZE
return_stack_top:		// Initial top of return stack.

/* This is used as a temporary input buffer when reading from files or the terminal. */
	.align 4096
buffer:
	.space BUFFER_SIZE

/*
	START OF FORTH CODE ----------------------------------------------------------------------

	We've now reached the stage where the FORTH system is running and self-hosting.  All further
	words can be written as FORTH itself, including words like IF, THEN, .", etc which in most
	languages would be considered rather fundamental.

	I used to append this here in the assembly file, but I got sick of fighting against gas's
	crack-smoking (lack of) multiline string syntax.  So now that is in a separate file called
	jonesforth.f

	If you don't already have that file, download it from http://annexia.org/forth in order
	to continue the tutorial.
*/

/* END OF jonesforth.S */

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:34                           ` Heartbleed Simon Clubley
  2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
@ 2014-04-18 21:35                             ` Dennis Lee Bieber
  2014-04-18 22:20                               ` Heartbleed Jeffrey Carter
  1 sibling, 1 reply; 144+ messages in thread
From: Dennis Lee Bieber @ 2014-04-18 21:35 UTC (permalink / raw)


On Fri, 18 Apr 2014 18:34:36 +0000 (UTC), Simon Clubley
<clubley@remove_me.eisner.decus.org-Earth.UFP> declaimed the following:


>So how about a language which doesn't have all the software engineering
>requirements Ada does, but still comes with some type safety, has

	Wasn't that called Pascal? Or Modula-2?

>a level of functionality comparable to C, uses a syntax which makes
>it far less likely for people to make silly syntax related mistakes and

	Well, okay -- the Wirth languages still have dangling ELSE problems...
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 21:35                             ` Heartbleed Dennis Lee Bieber
@ 2014-04-18 22:20                               ` Jeffrey Carter
  2014-04-18 22:41                                 ` Heartbleed Adam Beneschan
  0 siblings, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-18 22:20 UTC (permalink / raw)


On 04/18/2014 02:35 PM, Dennis Lee Bieber wrote:
>
> 	Well, okay -- the Wirth languages still have dangling ELSE problems...

I'm pretty sure Wirth got rid of the dangling "else" problem in Modula.

-- 
Jeff Carter
"C++ is vast and dangerous, a sort of Mordor of
programming languages."
Jason R. Fruit
120

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 21:06                               ` Heartbleed Alan Browne
@ 2014-04-18 22:20                                 ` Jeffrey Carter
  2014-04-19 14:04                                   ` Heartbleed Alan Browne
  0 siblings, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-18 22:20 UTC (permalink / raw)


On 04/18/2014 02:06 PM, Alan Browne wrote:
> On 2014.04.18, 16:45 , Jeffrey Carter wrote:
>>
>> Not really. As more than 95% of the world's population demonstrate, the
>> average person can understand the metric system. My experience is that
>> the average developer cannot understand the concepts underlying Ada.
>
> 1. '... to most Americans.'

Most Americans can understand the metric system if they have to. The US military 
takes typical Americans and has them working exclusively in metric in short order.

> 2. 'twas a joke son, a joke I say.

I know. That never stopped me before.

-- 
Jeff Carter
"C++ is vast and dangerous, a sort of Mordor of
programming languages."
Jason R. Fruit
120

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 22:20                               ` Heartbleed Jeffrey Carter
@ 2014-04-18 22:41                                 ` Adam Beneschan
  2014-04-19 15:53                                   ` Heartbleed Dennis Lee Bieber
  0 siblings, 1 reply; 144+ messages in thread
From: Adam Beneschan @ 2014-04-18 22:41 UTC (permalink / raw)


On Friday, April 18, 2014 3:20:39 PM UTC-7, Jeffrey Carter wrote:
> On 04/18/2014 02:35 PM, Dennis Lee Bieber wrote:
> 
> >
> 
> > 	Well, okay -- the Wirth languages still have dangling ELSE problems...
> 
> 
> 
> I'm pretty sure Wirth got rid of the dangling "else" problem in Modula.

Yes, or at least he did in Modula-2.  

http://www.modula2.org/reference/ifstatements.php

                           -- Adam

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 18:04                         ` Heartbleed Jeffrey Carter
  2014-04-18 18:34                           ` Heartbleed Simon Clubley
  2014-04-18 18:37                           ` Heartbleed Alan Browne
@ 2014-04-18 22:56                           ` Nasser M. Abbasi
  2014-04-19  4:27                             ` Heartbleed tmoran
  2 siblings, 1 reply; 144+ messages in thread
From: Nasser M. Abbasi @ 2014-04-18 22:56 UTC (permalink / raw)


On 4/18/2014 1:04 PM, Jeffrey Carter wrote:
> On 04/18/2014 10:30 AM, J-P. Rosen wrote:
>> <rant>
>> The cause of Ada not being popular is that it has been designed to force
>> people to THINK and do things cleanly. People prefer wild hacking and
>> long debugging sessions to sitting back in one's chair and analyzing the
>> problem.
>> </rant>
>

> Yes. Or as I like to put it, Ada is a software-engineering language, and only 2%
> (in my experience) of developers are software engineers. The remaining 98% are
> not going to like Ada; they like hack-away languages like C.
>

If you really want to hack, then there is a new language with
just the right name:

http://en.wikipedia.org/wiki/Hack_%28programming_language%29

"Hack is a programming language for the HipHop Virtual Machine
  (HHVM) invented by Facebook."

It sounds fun: Facebook, HipHop, hacking, Virtual Machine, and
PHP, all mixed together. What more hacking can a programmer ask
for?

I just had an idea: Make a version of Ada with a compiler switch
to remove all type checking!  This might be the key to making
Ada popular? :)

--Nasser

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 20:31                         ` Heartbleed Yannick Duchêne (Hibou57)
@ 2014-04-18 23:16                           ` Pascal J. Bourguignon
  2014-04-19 18:29                             ` Heartbleed Simon Clubley
  2014-04-21 22:50                             ` Heartbleed Randy Brukardt
  0 siblings, 2 replies; 144+ messages in thread
From: Pascal J. Bourguignon @ 2014-04-18 23:16 UTC (permalink / raw)


"Yannick Duchêne (Hibou57)" <yannick_duchene@yahoo.fr> writes:

> That's because an Ada compiler is far more complex to design. This may
> be another rational for a standard Ada minimal *frozen* *subset* (not
> a new language) without every thing which is finally a derived form of
> the most fundamental constructs with additional limitations.


This rational could have been valid 20 years or 30 years ago, when
proprietary software was more common, and free software was less
numerous and of more difficult access.  Also, at a time, when a full Ada
compiler would take 90% of the usual computer RAM, and 12 floppies.  At
the same time, the first C compiler for Macintosh took only 2 floppies.
And 30 years ago there were tens of different processors, and hundreds
of different OSes, which made it very difficult to provide a compiler
running everywhere.



BUT  not anymore.

Nowadays, you type apt-get install gcc or apt-get install gnat and the
compiler is fetched from the Internet, and it doesn't make a difference
if it takes 8 MB or 80 MB. 

Nowadays, there are only two processors: Intel on desktop and ARM on
mobile, and there remains only ONE system: Unix (Linux on desktop Linux
and Android, Darwin (BSD) on desktop MacOSX and iOS).  

And user machines have gigabytes of RAM and terabytes of hard disk, more
than enough for any compiler and run-time.



Therefore not only is access to free(dom) software easier, but you
usually don't even have to port it to your system, since it already
targets it.


There should be no difficulty anymore to spread Ada or any other good
language or software.

What is needed for that however is a end-user "killer" application, an
application that users want to install on their system and that will
bring as dependency the language run-time it's written with onto all the
systems.  And if this application is not perfect, but good enough to
motivate users to improve it, it's even better, since they they'll
install the compiler to be able to patch it.


For example, this is I got Haskell installed on my systems, for programs
such as darcs or pandoc.

( Of course, the reverse is also true: I try to avoid installing
applications written in languages I don't want to install on my system
:-/ )


-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 22:56                           ` Heartbleed Nasser M. Abbasi
@ 2014-04-19  4:27                             ` tmoran
  0 siblings, 0 replies; 144+ messages in thread
From: tmoran @ 2014-04-19  4:27 UTC (permalink / raw)


> I just had an idea: Make a version of Ada with a compiler switch
> to remove all type checking!  This might be the key to making
> Ada popular? :)

  Remove all checking at both compile and run time (if indeed there's any
distinction).  What programmer wants a compiler that disses him?  If the
code seems weird, it must be that the programmer is being fiendishly
clever.  And you can't sell a program that won't compile!


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages (was: Heartbleed)
  2014-04-12 18:38       ` Heartbleed Simon Clubley
  2014-04-12 20:24         ` Heartbleed Yannick Duchêne (Hibou57)
  2014-04-17  6:15         ` Heartbleed Jacob Sparre Andersen
@ 2014-04-19 11:50         ` Ludovic Brenta
  2014-04-19 12:46           ` Oberon and Wirthian languages Georg Bauhaus
                             ` (5 more replies)
  2014-05-14  9:39         ` Heartbleed gvdschoot
  3 siblings, 6 replies; 144+ messages in thread
From: Ludovic Brenta @ 2014-04-19 11:50 UTC (permalink / raw)


Simon Clubley writes:
>>> What may be a viable option would be if a simpler Wirth style
>>> language existed and whose compiler generated object code compatible
>>> with gcc and used binutils for it's assembling/linking phase.
>>
>> Oberon?
>
> Something based on one of the Oberon variants is _exactly_ the kind of
> thing I was thinking of. I would modify some of the syntax elements to
> make them more Ada like however.
>
> You know, Oberon-14 sounds like a nice name for a new programming
> language. :-)

The problem I have with Oberon and its descendants is that they removed
the subrange types from Modula-2 (they are similar to Ada's subtypes of
numeric types).  Also, TTBOMK, no Wirthian language allows the
programmer to define new numeric types from scratch and make them
incompatible at compile-time (i.e. requiring explicit type conversion).
According to John McCormick's famous reseach paper[1], the most
desirable features of a programming language are, in order of
importance:

- Modeling of scalar objects.
     Strong typing.
     Range constraints.
     Enumeration types.
- Parameter modes that reflect the problem rather than the mechanism.
- Named parameter association.
- Arrays whose indices do not have to begin at zero.
- Representation clauses for device registers (record field selection
  rather than bit masks).
- Higher level of abstraction for tasking (rendezvous rather than
  semaphores).
- Exception handling.

And personally, I share his opinion :)

So, Oberon-14 or whatever its name is should not only reinstate
subranges but also allow the definition of incompatible scalar types.
If it did support all of the desirable features above then it would
effectively almost become Ada :)

Notable features absent from that list include generics, type extension,
dynamic dispatching, subtypes of non-scalar types, nested subprograms
and overloading.  A subset of Ada omitting these features would require
a compiler and run-time system much simpler than full Ada and still
bring huge benefits to the safety of programming.  Access types are
required no matter what :/

[1] http://archive.adaic.com/projects/atwork/trains.html

-- 
Ludovic Brenta.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
@ 2014-04-19 12:46           ` Georg Bauhaus
  2014-04-19 19:17             ` Simon Clubley
  2014-04-19 16:35           ` Oberon and Wirthian languages (was: Heartbleed) Yannick Duchêne (Hibou57)
                             ` (4 subsequent siblings)
  5 siblings, 1 reply; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-19 12:46 UTC (permalink / raw)


On 19/04/14 13:50, Ludovic Brenta wrote:
> Access types are required no matter what :/

Parasail (and some other experimental languages, I think) seem
to tackle pointing with the help of components marked "optional",
accompanied by specially designed definitions for copying, moving, and
swapping. This combination is said to prevent the dangers of pointers.

http://parasail-programming-language.blogspot.de/2012/08/a-pointer-free-path-to-object-oriented.html



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 22:20                                 ` Heartbleed Jeffrey Carter
@ 2014-04-19 14:04                                   ` Alan Browne
  0 siblings, 0 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-19 14:04 UTC (permalink / raw)


On 2014.04.18, 18:20 , Jeffrey Carter wrote:
> On 04/18/2014 02:06 PM, Alan Browne wrote:
>> On 2014.04.18, 16:45 , Jeffrey Carter wrote:
>>>
>>> Not really. As more than 95% of the world's population demonstrate, the
>>> average person can understand the metric system. My experience is that
>>> the average developer cannot understand the concepts underlying Ada.
>>
>> 1. '... to most Americans.'
>
> Most Americans can understand the metric system if they have to. The US
> military takes typical Americans and has them working exclusively in
> metric in short order.

I know.  The metric system has been the primary system ow W&M in the US 
since before 1900.  But they plugged in an exception for commerce and of 
course that killed broad adoption.  Post WW-II the US military went 
metric to make cooperation with other countries easier.  Exceptions 
include navigation terms (nautical miles, knots) for the floaters and 
fliers.

But no.  Most Americans do not function well in metric in everyday 
situations.  I get blank stares when I use kilograms - then "what's that 
in ounces" and litres.  They're (sometimes) able to deal with metres 
("that's about a yard, right?").

>
>> 2. 'twas a joke son, a joke I say.
>
> I know. That never stopped me before.
>


-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 22:41                                 ` Heartbleed Adam Beneschan
@ 2014-04-19 15:53                                   ` Dennis Lee Bieber
  0 siblings, 0 replies; 144+ messages in thread
From: Dennis Lee Bieber @ 2014-04-19 15:53 UTC (permalink / raw)


On Fri, 18 Apr 2014 15:41:40 -0700 (PDT), Adam Beneschan
<adambeneschan@gmail.com> declaimed the following:

>On Friday, April 18, 2014 3:20:39 PM UTC-7, Jeffrey Carter wrote:
>> On 04/18/2014 02:35 PM, Dennis Lee Bieber wrote:
>> 
>> >
>> 
>> > 	Well, okay -- the Wirth languages still have dangling ELSE problems...
>> 
>> 
>> 
>> I'm pretty sure Wirth got rid of the dangling "else" problem in Modula.
>
>Yes, or at least he did in Modula-2.  
>
>http://www.modula2.org/reference/ifstatements.php
>
>                           -- Adam

	Okay... I was working from memory... 
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages (was: Heartbleed)
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
  2014-04-19 12:46           ` Oberon and Wirthian languages Georg Bauhaus
@ 2014-04-19 16:35           ` Yannick Duchêne (Hibou57)
  2014-04-19 19:32             ` Simon Clubley
  2014-04-19 16:53           ` Georg Bauhaus
                             ` (3 subsequent siblings)
  5 siblings, 1 reply; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-19 16:35 UTC (permalink / raw)


Le Sat, 19 Apr 2014 13:50:11 +0200, Ludovic Brenta  
<ludovic@ludovic-brenta.org> a écrit:

> Simon Clubley writes:
>>>> What may be a viable option would be if a simpler Wirth style
>>>> language existed and whose compiler generated object code compatible
>>>> with gcc and used binutils for it's assembling/linking phase.
>>>
>>> Oberon?
>>
>> Something based on one of the Oberon variants is _exactly_ the kind of
>> thing I was thinking of. I would modify some of the syntax elements to
>> make them more Ada like however.
>>
>> You know, Oberon-14 sounds like a nice name for a new programming
>> language. :-)
>
> The problem I have with Oberon and its descendants is that they removed
> the subrange types from Modula-2 (they are similar to Ada's subtypes of
> numeric types).  Also, TTBOMK, no Wirthian language allows the
> programmer to define new numeric types from scratch and make them
> incompatible at compile-time (i.e. requiring explicit type conversion).
> According to John McCormick's famous reseach paper[1], the most
> desirable features of a programming language are, in order of
> importance:
>
> - Modeling of scalar objects.
>      Strong typing.
>      Range constraints.
>      Enumeration types.
> - Parameter modes that reflect the problem rather than the mechanism.
> - Named parameter association.
> - Arrays whose indices do not have to begin at zero.
> - Representation clauses for device registers (record field selection
>   rather than bit masks).
> - Higher level of abstraction for tasking (rendezvous rather than
>   semaphores).
> - Exception handling.
>
> And personally, I share his opinion :)

I personally do to :-)

What's also interesting in this ordered list, is exception handling moved  
at the last position. However, an `Halt` statement or similar, with  
something like the “last‑chance handler” GNAT has, would be unavoidable.

The other interesting point, is as you mentioned, is that it does not  
suggest a new language, just an Ada subset (added it's access type which  
is not listed).


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
  2014-04-19 12:46           ` Oberon and Wirthian languages Georg Bauhaus
  2014-04-19 16:35           ` Oberon and Wirthian languages (was: Heartbleed) Yannick Duchêne (Hibou57)
@ 2014-04-19 16:53           ` Georg Bauhaus
  2014-04-19 17:32           ` Simon Wright
                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-19 16:53 UTC (permalink / raw)


On 19/04/14 13:50, Ludovic Brenta wrote:
> According to John McCormick's famous reseach paper[1], the most
> desirable features of a programming language are, in order of
> importance:
>
> - Modeling of scalar objects.
>       Strong typing.
>       Range constraints.
>       Enumeration types.
> - Parameter modes that reflect the problem rather than the mechanism.
> - Named parameter association.
> - Arrays whose indices do not have to begin at zero.
> - Representation clauses for device registers (record field selection
>    rather than bit masks).
> - Higher level of abstraction for tasking (rendezvous rather than
>    semaphores).
> - Exception handling.
>
> And personally, I share his opinion:)


The most important finding that McCormick's list represents is that
they are *not* an opinion! The evidence is one rare exception in that
its production exhibits many traits of valid data.

The type system *is* actually better that that against which
it has been compared. It is not just opined to be better.

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
                             ` (2 preceding siblings ...)
  2014-04-19 16:53           ` Georg Bauhaus
@ 2014-04-19 17:32           ` Simon Wright
  2014-04-19 17:35           ` Jeffrey Carter
  2014-04-21 13:06           ` Oberon and Wirthian languages (was: Heartbleed) Simon Clubley
  5 siblings, 0 replies; 144+ messages in thread
From: Simon Wright @ 2014-04-19 17:32 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> writes:

> Notable features absent from that list include generics, type
> extension, dynamic dispatching, subtypes of non-scalar types, nested
> subprograms and overloading.

Looking at the dates, I suspect that type extension & dynamic
dispatching weren't a part of Ada for most if not all of the period over
which the evidence was gathered.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
                             ` (3 preceding siblings ...)
  2014-04-19 17:32           ` Simon Wright
@ 2014-04-19 17:35           ` Jeffrey Carter
  2014-04-19 18:06             ` Yannick Duchêne (Hibou57)
  2014-04-19 18:53             ` Shark8
  2014-04-21 13:06           ` Oberon and Wirthian languages (was: Heartbleed) Simon Clubley
  5 siblings, 2 replies; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-19 17:35 UTC (permalink / raw)


On 04/19/2014 04:50 AM, Ludovic Brenta wrote:
>
> So, Oberon-14 or whatever its name is should not only reinstate
> subranges but also allow the definition of incompatible scalar types.
> If it did support all of the desirable features above then it would
> effectively almost become Ada :)

That would make the language unsuitable for its intended purpose of replacing C 
for S/W like OpenSSL.

My experience (unfortunately on more than one example) of Ada designed and 
written by coders is that they eschew user-defined numeric types and numeric 
subtypes. They pick a few numeric types, predefined if at all possible, and use 
them for everything, just like C.

-- 
Jeff Carter
"It's all right, Taggart. Just a man and a horse being hung out there."
Blazing Saddles
34

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 17:35           ` Jeffrey Carter
@ 2014-04-19 18:06             ` Yannick Duchêne (Hibou57)
  2014-04-19 18:53             ` Shark8
  1 sibling, 0 replies; 144+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2014-04-19 18:06 UTC (permalink / raw)


Le Sat, 19 Apr 2014 19:35:46 +0200, Jeffrey Carter  
<spam.jrcarter.not@spam.not.acm.org> a écrit:

> On 04/19/2014 04:50 AM, Ludovic Brenta wrote:
>>
>> So, Oberon-14 or whatever its name is should not only reinstate
>> subranges but also allow the definition of incompatible scalar types.
>> If it did support all of the desirable features above then it would
>> effectively almost become Ada :)
>
> That would make the language unsuitable for its intended purpose of  
> replacing C for S/W like OpenSSL.
>
> My experience (unfortunately on more than one example) of Ada designed  
> and written by coders is that they eschew user-defined numeric types and  
> numeric subtypes. They pick a few numeric types, predefined if at all  
> possible, and use them for everything, just like C.

An efficient defense against this mistake is AdaControl.

Another way is to explain it's not just about check and that's as much  
about expressiveness.


-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 23:16                           ` Heartbleed Pascal J. Bourguignon
@ 2014-04-19 18:29                             ` Simon Clubley
  2014-04-21 22:50                             ` Heartbleed Randy Brukardt
  1 sibling, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-19 18:29 UTC (permalink / raw)


On 2014-04-18, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> "Yannick Duchêne (Hibou57)" <yannick_duchene@yahoo.fr> writes:
>
>> That's because an Ada compiler is far more complex to design. This may
>> be another rational for a standard Ada minimal *frozen* *subset* (not
>> a new language) without every thing which is finally a derived form of
>> the most fundamental constructs with additional limitations.
>
>
> This rational could have been valid 20 years or 30 years ago, when
> proprietary software was more common, and free software was less
> numerous and of more difficult access.  Also, at a time, when a full Ada
> compiler would take 90% of the usual computer RAM, and 12 floppies.  At
> the same time, the first C compiler for Macintosh took only 2 floppies.
> And 30 years ago there were tens of different processors, and hundreds
> of different OSes, which made it very difficult to provide a compiler
> running everywhere.
>
>
>
> BUT  not anymore.
>
> Nowadays, you type apt-get install gcc or apt-get install gnat and the
> compiler is fetched from the Internet, and it doesn't make a difference
> if it takes 8 MB or 80 MB. 
>

[I can't tell if you are trolling or if you actually mean this. :-)]

Of course, it makes a difference. Designing a compiler for a language
the size of Ada 2012 is a huge undertaking.

Designing a compiler for a language the size of a Oberon variant is,
by contrast, a much simpler task.

That 80MB download doesn't come out of thin air. Someone has to sit down
and write the source code which compiles to that 80MB download.

> Nowadays, there are only two processors: Intel on desktop and ARM on
> mobile, and there remains only ONE system: Unix (Linux on desktop Linux
> and Android, Darwin (BSD) on desktop MacOSX and iOS).  
>

Sorry, but that is completely wrong.

What about MVS (or whatever it's called these days) ?

What about the various versions of Windows (both client and server) ?

What about processors like PowerPC and the various MIPS cores ?

What about differences caused by the different userland libraries ?

What about target support for the vast range of embedded systems
(including bare metal and the various RTOS options) as well as the
various embedded processors ?

> And user machines have gigabytes of RAM and terabytes of hard disk, more
> than enough for any compiler and run-time.
>
>
>
> Therefore not only is access to free(dom) software easier, but you
> usually don't even have to port it to your system, since it already
> targets it.
>

You should compare the Ada supported host and target platforms with the
C supported host and target platforms.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 17:35           ` Jeffrey Carter
  2014-04-19 18:06             ` Yannick Duchêne (Hibou57)
@ 2014-04-19 18:53             ` Shark8
  2014-04-19 20:08               ` Simon Clubley
  1 sibling, 1 reply; 144+ messages in thread
From: Shark8 @ 2014-04-19 18:53 UTC (permalink / raw)


On 19-Apr-14 11:35, Jeffrey Carter wrote:
> On 04/19/2014 04:50 AM, Ludovic Brenta wrote:
>>
>> So, Oberon-14 or whatever its name is should not only reinstate
>> subranges but also allow the definition of incompatible scalar types.
>> If it did support all of the desirable features above then it would
>> effectively almost become Ada :)
>
> That would make the language unsuitable for its intended purpose of
> replacing C for S/W like OpenSSL.
>
> My experience (unfortunately on more than one example) of Ada designed
> and written by coders is that they eschew user-defined numeric types and
> numeric subtypes. They pick a few numeric types, predefined if at all
> possible, and use them for everything, just like C.

One of the problems is that specs have become dependent on C and C-ish 
terminology as an example, let us examine the basic definitions in TLS:

> 6.2.1.  Fragmentation
>
>    The record layer fragments information blocks into TLSPlaintext
>    records carrying data in chunks of 2^14 bytes or less.  Client
>    message boundaries are not preserved in the record layer (i.e.,
>    multiple client messages of the same ContentType MAY be coalesced
>    into a single TLSPlaintext record, or a single message MAY be
>    fragmented across several records).
>
>       struct {
>           uint8 major;
>           uint8 minor;
>       } ProtocolVersion;
>
>       enum {
>           change_cipher_spec(20), alert(21), handshake(22),
>           application_data(23), (255)
>       } ContentType;
>
>       struct {
>           ContentType type;
>           ProtocolVersion version;
>           uint16 length;
>           opaque fragment[TLSPlaintext.length];
>       } TLSPlaintext;

As we can see here the 'length' should not be "uint16", but instead:
	Range 0..2**14 {with a Size specification of 16 bits.}
Another illustration comes from the enumerations; for "ContentType" 
there are 4 possibilities, which means we could fit them into a 2-bit 
field -- but the size is unintuitively specified by the null-enumeration 
with a value of 255.

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 21:17                   ` Heartbleed Shark8
@ 2014-04-19 18:59                     ` Simon Clubley
  2014-04-19 19:21                       ` Heartbleed Shark8
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-19 18:59 UTC (permalink / raw)


On 2014-04-18, Shark8 <OneWingedShark@gmail.com> wrote:
> This is a multi-part message in MIME format.
> --------------000402060401050003010207
> Content-Type: text/plain; charset=windows-1252; format=flowed
> Content-Transfer-Encoding: 8bit
>
> On 17-Apr-14 16:35, Simon Clubley wrote:
>> Are there FORTH compilers for every platform a C compiler runs on ?
>
> Probably.
> And even if there's not, FORTH is apparently really, /really/ easy to 
> bootstrap.
>

[Enormous snip. :-)]

I've saved this posting and added it to my list to things to read at
some time in the future.

However, you should be aware that Forth is completely alien to me;
it's one language I've never even written a Hello World in. :-)

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 12:46           ` Oberon and Wirthian languages Georg Bauhaus
@ 2014-04-19 19:17             ` Simon Clubley
  2014-04-19 19:25               ` Shark8
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-19 19:17 UTC (permalink / raw)


On 2014-04-19, Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> wrote:
> On 19/04/14 13:50, Ludovic Brenta wrote:
>> Access types are required no matter what :/
>
> Parasail (and some other experimental languages, I think) seem
> to tackle pointing with the help of components marked "optional",
> accompanied by specially designed definitions for copying, moving, and
> swapping. This combination is said to prevent the dangers of pointers.
>
> http://parasail-programming-language.blogspot.de/2012/08/a-pointer-free-path-to-object-oriented.html
>

From what I can tell from that page, they still appear to be implemented
as pointers but it's just that this isn't directly visible at user code
level.

I wonder where I've heard of the concept of type checked pointers
before ? :-) (IOW, look at the author's name; I didn't see that until
well into the page.)

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-19 18:59                     ` Heartbleed Simon Clubley
@ 2014-04-19 19:21                       ` Shark8
  0 siblings, 0 replies; 144+ messages in thread
From: Shark8 @ 2014-04-19 19:21 UTC (permalink / raw)


On 19-Apr-14 12:59, Simon Clubley wrote:
> On 2014-04-18, Shark8 <OneWingedShark@gmail.com> wrote:
>> This is a multi-part message in MIME format.
>> --------------000402060401050003010207
>> Content-Type: text/plain; charset=windows-1252; format=flowed
>> Content-Transfer-Encoding: 8bit
>>
>> On 17-Apr-14 16:35, Simon Clubley wrote:
>>> Are there FORTH compilers for every platform a C compiler runs on ?
>>
>> Probably.
>> And even if there's not, FORTH is apparently really, /really/ easy to
>> bootstrap.
>>
>
> [Enormous snip. :-)]
>
> I've saved this posting and added it to my list to things to read at
> some time in the future.
>
> However, you should be aware that Forth is completely alien to me;
> it's one language I've never even written a Hello World in. :-)
>
> Simon.

Yeah, my experience falls into a little bit of tinkering, though not 
much more than Hello World, and writing a Forth interpreter.

If you're interested, this magnet-link shows a really interesting "over 
the shoulder" view of Forth coding to a text-processing facility:

magnet:?xt=urn:btih:FA7ADCC14412BF2C39ECCB67F26D8269C51BA32F&dn=ots_ots-01.mpg&tr=http%3a%2f%2ftracker.amazonaws.com%3a6969%2fannounce



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 19:17             ` Simon Clubley
@ 2014-04-19 19:25               ` Shark8
  0 siblings, 0 replies; 144+ messages in thread
From: Shark8 @ 2014-04-19 19:25 UTC (permalink / raw)


On 19-Apr-14 13:17, Simon Clubley wrote:
> On 2014-04-19, Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> wrote:
>> On 19/04/14 13:50, Ludovic Brenta wrote:
>>> Access types are required no matter what :/
>>
>> Parasail (and some other experimental languages, I think) seem
>> to tackle pointing with the help of components marked "optional",
>> accompanied by specially designed definitions for copying, moving, and
>> swapping. This combination is said to prevent the dangers of pointers.
>>
>> http://parasail-programming-language.blogspot.de/2012/08/a-pointer-free-path-to-object-oriented.html
>>
>
>  From what I can tell from that page, they still appear to be implemented
> as pointers but it's just that this isn't directly visible at user code
> level.
>
> I wonder where I've heard of the concept of type checked pointers
> before ? :-) (IOW, look at the author's name; I didn't see that until
> well into the page.)
>
> Simon.

Tucker Taft? Who the heck is that? Nobody on comp.lang.ada is familiar 
with that guy. ;)

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages (was: Heartbleed)
  2014-04-19 16:35           ` Oberon and Wirthian languages (was: Heartbleed) Yannick Duchêne (Hibou57)
@ 2014-04-19 19:32             ` Simon Clubley
  2014-04-19 22:30               ` Dennis Lee Bieber
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-19 19:32 UTC (permalink / raw)


On 2014-04-19, Yannick Duchêne <yannick_duchene@yahoo.fr> wrote:
>
> The other interesting point, is as you mentioned, is that it does not  
> suggest a new language, just an Ada subset (added it's access type which  
> is not listed).
>

Warning: if you market this as Ada version 2, then it will fail.
(There's too much negative feeling towards Ada in the market place.)

I don't see this as another Ada. I see this as starting from a Oberon
level of functionality with some Ada style features and syntax added
to make it more robust and functional.

This is no different from the cross pollination that takes place
between programming languages all the time, but it doesn't make it
Ada.

The goal would be to make something safer than C (and which can
replace C); creating the next Ada is not the goal.

However, if you get them used to this way of thinking, you can then
introduce them more easily at a later date to Ada for the large system
projects.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 18:53             ` Shark8
@ 2014-04-19 20:08               ` Simon Clubley
  2014-04-19 22:16                 ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-19 20:08 UTC (permalink / raw)


On 2014-04-19, Shark8 <OneWingedShark@gmail.com> wrote:
> On 19-Apr-14 11:35, Jeffrey Carter wrote:
>> On 04/19/2014 04:50 AM, Ludovic Brenta wrote:
>>>
>>> So, Oberon-14 or whatever its name is should not only reinstate
>>> subranges but also allow the definition of incompatible scalar types.
>>> If it did support all of the desirable features above then it would
>>> effectively almost become Ada :)
>>
>> That would make the language unsuitable for its intended purpose of
>> replacing C for S/W like OpenSSL.
>>
>> My experience (unfortunately on more than one example) of Ada designed
>> and written by coders is that they eschew user-defined numeric types and
>> numeric subtypes. They pick a few numeric types, predefined if at all
>> possible, and use them for everything, just like C.
>

Fine. Let them keep writing their code using uint16 and friends (for now).
There are still other things we can do to make their code more robust
in a new language and if it helps ease the transition then I don't really
have a problem with that to begin with. We can still add support for
user defined datatypes so it's waiting when they are ready to use them.

Note that this is very much a pragmatic view and certainly not what
I would prefer, but if you make the learning barrier for a new language
too high then they are not going to try it out.

> One of the problems is that specs have become dependent on C and C-ish 
> terminology as an example, let us examine the basic definitions in TLS:
>
>> 6.2.1.  Fragmentation
>>
>>    The record layer fragments information blocks into TLSPlaintext
>>    records carrying data in chunks of 2^14 bytes or less.  Client
>>    message boundaries are not preserved in the record layer (i.e.,
>>    multiple client messages of the same ContentType MAY be coalesced
>>    into a single TLSPlaintext record, or a single message MAY be
>>    fragmented across several records).
>>
>>       struct {
>>           uint8 major;
>>           uint8 minor;
>>       } ProtocolVersion;
>>
>>       enum {
>>           change_cipher_spec(20), alert(21), handshake(22),
>>           application_data(23), (255)
>>       } ContentType;
>>
>>       struct {
>>           ContentType type;
>>           ProtocolVersion version;
>>           uint16 length;
>>           opaque fragment[TLSPlaintext.length];
>>       } TLSPlaintext;

This is probably seen as pseudocode so the layout is clear as possible
to the greatest number of people. I suspect that every Ada user here
would be able to read the above and know exactly what would be required
of a Ada version of this.

>
> As we can see here the 'length' should not be "uint16", but instead:
> 	Range 0..2**14 {with a Size specification of 16 bits.}

The problem is that the above lays out the on the wire structure, but
says nothing about the valid length values other than in the surrounding
text.

> Another illustration comes from the enumerations; for "ContentType" 
> there are 4 possibilities, which means we could fit them into a 2-bit 
> field -- but the size is unintuitively specified by the null-enumeration 
> with a value of 255.
>

I suspect they are probably worried about bit alignment issues if
they do that. However, have another look at the above; it actually
says nothing explicit about the size of the enum. It just appears to
assume it's a single byte based on the upper limit.

BTW, in my opinion, one of the things which would be absolutely
non-negotiable in a new language would be the required treating of each
enum declaration as it's own data type instead of as integers as C
currently does.

That would not reduce the hackability of any half decent code, but it
would help to reduce errors.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 20:08               ` Simon Clubley
@ 2014-04-19 22:16                 ` Simon Clubley
  0 siblings, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-19 22:16 UTC (permalink / raw)


On 2014-04-19, Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
> On 2014-04-19, Shark8 <OneWingedShark@gmail.com> wrote:
>>
>> As we can see here the 'length' should not be "uint16", but instead:
>> 	Range 0..2**14 {with a Size specification of 16 bits.}
>
> The problem is that the above lays out the on the wire structure, but
> says nothing about the valid length values other than in the surrounding
> text.
>

Just to clarify: "the above" refers to the uint16 in the struct from
the specification, not to your Range statement.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages (was: Heartbleed)
  2014-04-19 19:32             ` Simon Clubley
@ 2014-04-19 22:30               ` Dennis Lee Bieber
  2014-04-19 22:35                 ` Oberon and Wirthian languages Alan Browne
  0 siblings, 1 reply; 144+ messages in thread
From: Dennis Lee Bieber @ 2014-04-19 22:30 UTC (permalink / raw)


On Sat, 19 Apr 2014 19:32:42 +0000 (UTC), Simon Clubley
<clubley@remove_me.eisner.decus.org-Earth.UFP> declaimed the following:

>
>I don't see this as another Ada. I see this as starting from a Oberon
>level of functionality with some Ada style features and syntax added
>to make it more robust and functional.
>
>This is no different from the cross pollination that takes place
>between programming languages all the time, but it doesn't make it
>Ada.
>
	Call it Titania... Oberon's partner in "A Midsummer Night's Dream"
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-19 22:30               ` Dennis Lee Bieber
@ 2014-04-19 22:35                 ` Alan Browne
  0 siblings, 0 replies; 144+ messages in thread
From: Alan Browne @ 2014-04-19 22:35 UTC (permalink / raw)


On 2014.04.19, 18:30 , Dennis Lee Bieber wrote:
> On Sat, 19 Apr 2014 19:32:42 +0000 (UTC), Simon Clubley
> <clubley@remove_me.eisner.decus.org-Earth.UFP> declaimed the following:
>
>>
>> I don't see this as another Ada. I see this as starting from a Oberon
>> level of functionality with some Ada style features and syntax added
>> to make it more robust and functional.
>>
>> This is no different from the cross pollination that takes place
>> between programming languages all the time, but it doesn't make it
>> Ada.
>>
> 	Call it Titania... Oberon's partner in "A Midsummer Night's Dream"


We need a law against programming language proliferation.


-- 
"Big data can reduce anything to a single number,
  but you shouldn’t be fooled by the appearance of exactitude."
      -Gary Marcus and Ernest Davis, NYT, 2014.04.07



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages (was: Heartbleed)
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
                             ` (4 preceding siblings ...)
  2014-04-19 17:35           ` Jeffrey Carter
@ 2014-04-21 13:06           ` Simon Clubley
  2014-04-21 18:13             ` Simon Clubley
  2014-04-21 18:16             ` Jeffrey Carter
  5 siblings, 2 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-21 13:06 UTC (permalink / raw)


On 2014-04-19, Ludovic Brenta <ludovic@ludovic-brenta.org> wrote:
> Simon Clubley writes:
>>>> What may be a viable option would be if a simpler Wirth style
>>>> language existed and whose compiler generated object code compatible
>>>> with gcc and used binutils for it's assembling/linking phase.
>>>
>>> Oberon?
>>
>> Something based on one of the Oberon variants is _exactly_ the kind of
>> thing I was thinking of. I would modify some of the syntax elements to
>> make them more Ada like however.
>>

[Note: There's a Ada language lawyer question below for those of you
who like such things. :-)]

>> You know, Oberon-14 sounds like a nice name for a new programming
>> language. :-)
>
> The problem I have with Oberon and its descendants is that they removed
> the subrange types from Modula-2 (they are similar to Ada's subtypes of
> numeric types).  Also, TTBOMK, no Wirthian language allows the
> programmer to define new numeric types from scratch and make them
> incompatible at compile-time (i.e. requiring explicit type conversion).

I can't speak for all Wirth style languages, but that's certainly true
for Oberon-2 and it was true for things like the dialects of Pascal
I have used in the past.

In Oberon-2 however, if you create two record types, each with a single
INTEGER within the record, then you can't assign one record to the other:

obc -o typetest typetest.m
"typetest.m", line 25: record type 'rectype2' is needed on the RHS of this
assignment
>       rec2            := rec1;
>                          ^^^^
> This expression has record type 'rectype1'

I got round to double checking this today with the very latest version
of the the Oxford Oberon-2 compiler, which I wanted to do before posting.
You also can't perform a plain assignment which would result in the
loss of data by moving a integer into a smaller sized integer.

This is unlike how Free Pascal apparently behaves, BTW. From:

	http://www.freepascal.org/docs-html/ref/refsu5.html

|Free Pascal does automatic type conversion in expressions where different kinds
|of integer types are used. 

I'm going by the documentation as I have never used Free Pascal (and
after reading the above I'm not exactly motivated to try it now. :-))

The suggestion of a Oberon variant as a base was to choose something
as close to C as possible, which would then have some basic Ada style
functionality added into it.

> According to John McCormick's famous reseach paper[1], the most
> desirable features of a programming language are, in order of
> importance:
>
> - Modeling of scalar objects.
>      Strong typing.
>      Range constraints.
>      Enumeration types.
> - Parameter modes that reflect the problem rather than the mechanism.
> - Named parameter association.
> - Arrays whose indices do not have to begin at zero.

Agree with all those, and they are something I would want to see in a
C replacement language.

> - Representation clauses for device registers (record field selection
>   rather than bit masks).

Getting rid of C style masks should be a major goal and the above is
required but not sufficient.

To remove all the usage cases for C style masks, we would need atomic
access to registers when using bit fields and a way to update a specified
list of bit fields at the same time (in a read register/modify bitfields
/write back to register operation); either in code:

        atomic using uart0.config1
                .flag1  := 0;
                .enable := 1;
                .txdis  := 0;
        end atomic;

(I'm not too sure about the leading dots however.)

or with a Atomic attribute on the register in question. The problem with
a Atomic attribute is that the bit fields would be updated in isolation
if the statements were separate and this is sometimes _not_ what you want
as well as being far less efficient than C style masks.

Using the above construct allows you to update a subset of related bit
fields as one operation.

Language lawyer question time:

What I have not checked however is if a record assignment in Ada to a bit
field record variable marked as Atomic would result in all the bit fields
listed in the assignment being _guaranteed_ to be updated at the same time
or whether there would just be a atomic update of each component in
isolation.

(Unfortunately, as I need my bare metal code to run on a large range of
platforms, it's usually written in C so I've not actually tried to write
the above construct. Cohen appears to be silent on the issue and the
Ada 95 RM didn't help either.)

Any Ada language lawyers around who could answer the above question ?

> - Higher level of abstraction for tasking (rendezvous rather than
>   semaphores).

Tasking should not be a part of a C replacement language. You want
something which is going to be able to replace, in existing applications,
libraries written in C.

> - Exception handling.
>

Exception handling would be nice, but it would have to be a local to the
current module exceptions model only. How would you push the exception
back to the caller when the caller could be written in any language ?

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages (was: Heartbleed)
  2014-04-21 13:06           ` Oberon and Wirthian languages (was: Heartbleed) Simon Clubley
@ 2014-04-21 18:13             ` Simon Clubley
  2014-04-21 18:45               ` Oberon and Wirthian languages Shark8
  2014-04-21 18:16             ` Jeffrey Carter
  1 sibling, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-21 18:13 UTC (permalink / raw)


On 2014-04-21, Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
> On 2014-04-19, Ludovic Brenta <ludovic@ludovic-brenta.org> wrote:
>> - Representation clauses for device registers (record field selection
>>   rather than bit masks).
>
> Getting rid of C style masks should be a major goal and the above is
> required but not sufficient.
>

That's C style masks for device registers, BTW. There's still a requirement
for masks for general operations.

In addition to your list, there one additional thing I forgot to mention.

I would allow some way of specifying that a struct/record (or some of
it's components) is of a specific endian type and then allowing the compiler
to generate the code itself to handle the big/little endian conversion
as required.

It's absolutely crazy that in 2014 we are still writing code which requires
that knowledge to be manually encoded within the program code itself
(in the form of macros) instead of just placing that information within
the data type which is where it belongs.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-21 13:06           ` Oberon and Wirthian languages (was: Heartbleed) Simon Clubley
  2014-04-21 18:13             ` Simon Clubley
@ 2014-04-21 18:16             ` Jeffrey Carter
  2014-04-22  0:34               ` Simon Clubley
  1 sibling, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-21 18:16 UTC (permalink / raw)


On 04/21/2014 06:06 AM, Simon Clubley wrote:
>
> What I have not checked however is if a record assignment in Ada to a bit
> field record variable marked as Atomic would result in all the bit fields
> listed in the assignment being _guaranteed_ to be updated at the same time
> or whether there would just be a atomic update of each component in
> isolation.

If you have a record:

type Register_Info is record
    A : Boolean;
    ...
end record;

for Register_Info use record
    A at 0 range 0 .. 0;
    ...
end record;

and an atomic object of the type:

Register : Register_Info;
pragma Atomic (Register);

If the compiler accepts the pragma, then assignment to Register (as opposed to 
its components) is atomic:

Register := (A => True, ...);

Though the best bet is to do it and check the generated code.

-- 
Jeff Carter
"I like it when the support group complains that they have
insufficient data on mean time to repair bugs in Ada software."
Robert I. Eachus
91


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-21 18:13             ` Simon Clubley
@ 2014-04-21 18:45               ` Shark8
  2014-04-21 23:26                 ` Randy Brukardt
  0 siblings, 1 reply; 144+ messages in thread
From: Shark8 @ 2014-04-21 18:45 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1079 bytes --]

On 21-Apr-14 12:13, Simon Clubley wrote:
> It's absolutely crazy that in 2014 we are still writing code which requires
> that knowledge to be manually encoded within the program code itself
> (in the form of macros) instead of just placing that information within
> the data type which is where it belongs.

Filly agreed.
In Barns's /Ada 2005/ book there was a CD (which I have unfortunately 
lost) which had several interesting PDFs, one of which dealt with 
handling endian-independent records via specification clauses [attached: 
bitorder.pdf], there's another paper [I don't recall if it was on the CD 
or not] which expand on it to do wholesale byte reversals [attached: 
Endian-Independent Paper] of an outermost record.

So it's not unaddressed in Ada, but it is a little awkward; I think some 
of these could be helped by Ada 2012 aspects though [Size & Bit_Order on 
the component types]. (There's also the question of what happens when a 
component type of the opposite Bit_Order is included... that may be 
answered in the LRM, but I simply don't recall reading it.)

[-- Attachment #2: www.sigada.org/ada_letters/sept2005/Endian-Independent Paper.pdf --]
[-- Type: application/pdf, Size: 54491 bytes --]

[-- Attachment #3: www.ada-auth.org/ai-files/grab_bag/bitorder.pdf --]
[-- Type: application/pdf, Size: 53526 bytes --]

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-18 23:16                           ` Heartbleed Pascal J. Bourguignon
  2014-04-19 18:29                             ` Heartbleed Simon Clubley
@ 2014-04-21 22:50                             ` Randy Brukardt
  1 sibling, 0 replies; 144+ messages in thread
From: Randy Brukardt @ 2014-04-21 22:50 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3643 bytes --]

"Pascal J. Bourguignon" <pjb@informatimago.com> wrote in message 
news:87ha5q1b4l.fsf@kuiper.lan.informatimago.com...
> "Yannick Duchêne (Hibou57)" <yannick_duchene@yahoo.fr> writes:
>
>> That's because an Ada compiler is far more complex to design. This may
>> be another rational for a standard Ada minimal *frozen* *subset* (not
>> a new language) without every thing which is finally a derived form of
>> the most fundamental constructs with additional limitations.
>
>
> This rational could have been valid 20 years or 30 years ago, when
> proprietary software was more common, and free software was less
> numerous and of more difficult access.  Also, at a time, when a full Ada
> compiler would take 90% of the usual computer RAM, and 12 floppies.  At
> the same time, the first C compiler for Macintosh took only 2 floppies.
> And 30 years ago there were tens of different processors, and hundreds
> of different OSes, which made it very difficult to provide a compiler
> running everywhere.

That's certainly not true (of the full compiler size). The Janus/Ada 
compiler never took more than 4 floppies on any machine (it's in at most 
four parts, so it would have been impossible to run it otherwise), at least 
until the hard disk became the standard and the floppies were only a 
delivery mechanism. (And that was a lot more recent than you think. :-) It 
still only takes four PC floppies (Claw takes 4 more if distributed that 
way).

There were a few machines with microscopic sized floppies (I recall one that 
only held 90K), but I don't recall any compilers for any languages that 
worked on those floppies. Almost everybody required the 8" floppies (240K 
per disk in lowest density) or more capacity than that.

And the Macintosh was irrelevant at the time; almost all effort went to 
machines running CP/M-80 (including the Apple II emulator boards -- we sold 
several thousand compilers on that) and later MS-DOS. The full 
implementation of Ada for MS-DOS certainly didn't take more the 4 floppies - 
it could be run on a machine with only floppy drives (need two floppies, 
through, and the swapping made it impractical for long). If one had 8" 
double-sided floppies - 1.2M, that fit the entire compiler nicely. Indeed, I 
didn't get a machine with a hard disk until relatively late (when they got 
big enough to be practical); a pair of high-density floppies was more 
flexible in that one could replace one at any time and effectively have as 
much space as one needed. (10M hard disks had no such ability!).

> BUT  not anymore.
>
> Nowadays, you type apt-get install gcc or apt-get install gnat and the
> compiler is fetched from the Internet, and it doesn't make a difference
> if it takes 8 MB or 80 MB.

What's "apt-get"? It doesn't do anything on Windows or on my phone. ;-)

> Nowadays, there are only two processors: Intel on desktop and ARM on
> mobile, and there remains only ONE system: Unix (Linux on desktop Linux
> and Android, Darwin (BSD) on desktop MacOSX and iOS).
>
> And user machines have gigabytes of RAM and terabytes of hard disk, more
> than enough for any compiler and run-time.

True enough. It's no longer necessary to make a compiler that fits in very 
limited RAM. That being the primary expertise of RRS, we're no longer 
relevant. But so what? There are literally thousands of targets, once one 
considers all of the bare machine variants and the dozens of RTOS's in use.

You seem to think everyone can build on top of Linux, but certification 
requirements (and practical matters like what the customers are running) 
make that very untrue.

                                Randy.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-21 18:45               ` Oberon and Wirthian languages Shark8
@ 2014-04-21 23:26                 ` Randy Brukardt
  2014-04-22  0:21                   ` Simon Clubley
  2014-04-22  5:48                   ` Shark8
  0 siblings, 2 replies; 144+ messages in thread
From: Randy Brukardt @ 2014-04-21 23:26 UTC (permalink / raw)


"Shark8" <OneWingedShark@gmail.com> wrote in message 
news:mHd5v.110220$nm4.61317@fx27.iad...
...
> So it's not unaddressed in Ada, but it is a little awkward; I think some
> of these could be helped by Ada 2012 aspects though [Size & Bit_Order on
> the component types]. (There's also the question of what happens when a
> component type of the opposite Bit_Order is included... that may be
> answered in the LRM, but I simply don't recall reading it.)

The RM definitely describes what happens in the alternative bit-order. 
Unfortunately, the description will probably give you a headache. All of the 
stuff about "machine scalars" relates to this subject. It's not an easy 
subject at all.

                              Randy.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-21 23:26                 ` Randy Brukardt
@ 2014-04-22  0:21                   ` Simon Clubley
  2014-04-22  5:48                   ` Shark8
  1 sibling, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-22  0:21 UTC (permalink / raw)


On 2014-04-21, Randy Brukardt <randy@rrsoftware.com> wrote:
> "Shark8" <OneWingedShark@gmail.com> wrote in message 
> news:mHd5v.110220$nm4.61317@fx27.iad...
> ...
>> So it's not unaddressed in Ada, but it is a little awkward; I think some
>> of these could be helped by Ada 2012 aspects though [Size & Bit_Order on
>> the component types]. (There's also the question of what happens when a
>> component type of the opposite Bit_Order is included... that may be
>> answered in the LRM, but I simply don't recall reading it.)
>
> The RM definitely describes what happens in the alternative bit-order. 
> Unfortunately, the description will probably give you a headache. All of the 
> stuff about "machine scalars" relates to this subject. It's not an easy 
> subject at all.
>

Shark8's message has not shown up at Eternal September, so I am replying
to Randy's extract above.

I did know about the bit ordering options in Ada, but thanks. The
"absolutely crazy" comment was directed towards what we have to do
in C and the fact I would like to see something much better in any
C language replacement.

BTW, stuff like this is exactly the kind of thing we could introduce into
a new language without reducing the "hackability" that many C programmers
seem to look for in their language choice (as people here have reminded
me several times over the last few days :-)).

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-21 18:16             ` Jeffrey Carter
@ 2014-04-22  0:34               ` Simon Clubley
  2014-04-22  3:01                 ` Jeffrey Carter
                                   ` (2 more replies)
  0 siblings, 3 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-22  0:34 UTC (permalink / raw)


On 2014-04-21, Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> wrote:
> On 04/21/2014 06:06 AM, Simon Clubley wrote:
>>
>> What I have not checked however is if a record assignment in Ada to a bit
>> field record variable marked as Atomic would result in all the bit fields
>> listed in the assignment being _guaranteed_ to be updated at the same time
>> or whether there would just be a atomic update of each component in
>> isolation.
>
> If you have a record:
>
> type Register_Info is record
>     A : Boolean;
>     ...
> end record;
>
> for Register_Info use record
>     A at 0 range 0 .. 0;
>     ...
> end record;
>
> and an atomic object of the type:
>
> Register : Register_Info;
> pragma Atomic (Register);
>
> If the compiler accepts the pragma, then assignment to Register (as opposed to 
> its components) is atomic:
>
> Register := (A => True, ...);
>

Thank you. It was not at all 100% clear from the RM if Ada offered the
_guarantee_ that if you had, say, 3 components in a record assignment
for a atomic bitfield record, that the record assignment would be treated
as one atomic operation instead of 3 atomic operations (one for each
component).

> Though the best bet is to do it and check the generated code.
>

Unfortunately, that only tells you how one compiler implemented it and
doesn't say anything about if such behaviour is mandatory in the standard.

Thanks for the clarification above,

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22  0:34               ` Simon Clubley
@ 2014-04-22  3:01                 ` Jeffrey Carter
  2014-04-22 23:31                   ` Randy Brukardt
  2014-04-22  6:41                 ` Simon Wright
  2014-04-22 23:30                 ` Randy Brukardt
  2 siblings, 1 reply; 144+ messages in thread
From: Jeffrey Carter @ 2014-04-22  3:01 UTC (permalink / raw)


On 04/21/2014 05:34 PM, Simon Clubley wrote:
>
> Unfortunately, that only tells you how one compiler implemented it and
> doesn't say anything about if such behaviour is mandatory in the standard.

Unless there's a check for this in the ACATS, you'll want to make sure your 
compiler complies as well as compiles.

-- 
Jeff Carter
"I like it when the support group complains that they have
insufficient data on mean time to repair bugs in Ada software."
Robert I. Eachus
91

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-21 23:26                 ` Randy Brukardt
  2014-04-22  0:21                   ` Simon Clubley
@ 2014-04-22  5:48                   ` Shark8
  1 sibling, 0 replies; 144+ messages in thread
From: Shark8 @ 2014-04-22  5:48 UTC (permalink / raw)


On 21-Apr-14 17:26, Randy Brukardt wrote:
> All of the stuff about "machine scalars" relates to this subject. It's
> not an easy subject at all.

Yeah, I had the feeling it wouldn't be /easy/... I was, however, hoping 
it wouldn't be overly difficult.

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22  0:34               ` Simon Clubley
  2014-04-22  3:01                 ` Jeffrey Carter
@ 2014-04-22  6:41                 ` Simon Wright
  2014-04-22 12:25                   ` Simon Clubley
  2014-04-22 23:30                 ` Randy Brukardt
  2 siblings, 1 reply; 144+ messages in thread
From: Simon Wright @ 2014-04-22  6:41 UTC (permalink / raw)


Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:

> Thank you. It was not at all 100% clear from the RM if Ada offered the
> _guarantee_ that if you had, say, 3 components in a record assignment
> for a atomic bitfield record, that the record assignment would be treated
> as one atomic operation instead of 3 atomic operations (one for each
> component).

Are there CPUs that offer bit-field atomicity? Single bits, maybe. And
what about the fact that these are probably to memory-mapped I/O, and
the device registers may only offer byte/word/longword access?

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22  6:41                 ` Simon Wright
@ 2014-04-22 12:25                   ` Simon Clubley
  2014-04-22 19:13                     ` Niklas Holsti
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-22 12:25 UTC (permalink / raw)


On 2014-04-22, Simon Wright <simon@pushface.org> wrote:
> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:
>
>> Thank you. It was not at all 100% clear from the RM if Ada offered the
>> _guarantee_ that if you had, say, 3 components in a record assignment
>> for a atomic bitfield record, that the record assignment would be treated
>> as one atomic operation instead of 3 atomic operations (one for each
>> component).
>
> Are there CPUs that offer bit-field atomicity? Single bits, maybe. And
> what about the fact that these are probably to memory-mapped I/O, and
> the device registers may only offer byte/word/longword access?

Actually, yes, it's quite common to have a small part of memory which
is bit addressable on some 8-bit microcontrollers.

However, that isn't the concern here.

In general memory mapped I/O you have to do a register read/modify bit
field/register write sequence in units of the register size.

Consider a atomic record with 3 bit fields called A, B and C.

Now consider a Ada record assignment statement which sets the values of
the 3 bit fields. The question is how is the assignment to the 3 bit
fields turned into code ?

Is it something like this (which is how it looks in C with masks):

	ldr	r2, [r3, #register_offset]
				-- Load device register contents into r2
				-- r3 contains device base address
	orr	r2, r2, #1	-- Set bit field A to 1
	{Additional code here to modify bitfields B and C}
	str	r2, [r3, #register_offset]
				-- Write all changes to device register at once

or is the Ada compiler allowed to do this:

	ldr	r2, [r3, #register_offset]
	orr	r2, r2, #1			-- Set bit field A to 1
	str	r2, [r3, #register_offset]	-- Update bit field A only

	ldr	r2, [r3, #register_offset]
	{Code here to modify bitfield B}
	str	r2, [r3, #register_offset]	-- Update bit field B only

	ldr	r2, [r3, #register_offset]
	{Code here to modify bitfield C}
	str	r2, [r3, #register_offset]	-- Update bit field C only

Ie: performs a atomic update of each bit field, but treats each component
as a different update operation.

Some devices _require_ the first option in order to work correctly and it
wasn't clear from reading the Ada 95 RM that it was _guaranteed_ a
assignment to a atomic bit field record would result in code which looked
like the first option above.

You also then have additional issues around wanting to, say, update bit
fields B and C at the same time while preserving the current value of
bit field A (which is where my "atomic using" suggestion comes in for
a C replacement language).

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22 12:25                   ` Simon Clubley
@ 2014-04-22 19:13                     ` Niklas Holsti
  2014-04-22 20:46                       ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-04-22 19:13 UTC (permalink / raw)


On 14-04-22 15:25 , Simon Clubley wrote:
> On 2014-04-22, Simon Wright <simon@pushface.org> wrote:
>
> In general memory mapped I/O you have to do a register read/modify bit
> field/register write sequence in units of the register size.
> 
> Consider a atomic record with 3 bit fields called A, B and C.
> 
> Now consider a Ada record assignment statement which sets the values of
> the 3 bit fields. The question is how is the assignment to the 3 bit
> fields turned into code ?

If the record variable Rec has the Atomic aspect, then by the Ada RM any
assignment Rec := expr must write Rec exactly once, indivisibly, and
this write should (per implementation advice) be implemented by a single
store instruction. This applies whatever the right-hand-side expr is.

Note, however, that if the right-hand-side expr includes some references
to (i.e. reads of) Rec, then there is no guarantee that the read-write
sequence as a whole is indivisible.

> Is it something like this (which is how it looks in C with masks):

Here one should separate between C 2011 on the one hand and earlier C
standards on the other. (For C 2011 my reference is the "final" draft
N1570, which is on the web.)

In C 2011, a "compound assignment is a read-modify-write operation with
memory_order_seq_cst memory order semantics". That is, in C 2011 an
update like "v &= mask", where v is an _Atomic variable, is an atomic
*update* with respect to other C threads (but perhaps not with respect
to other memory bus activity; I admit to an incomplete understanding
here). Note that this is rather different from the meaning of the Atomic
aspect in Ada, which only makes each read indivisible, and each write
indivisible, but does not guarantee indivisibility of some
read-modify-write sequence.

In earlier C standards such as the 1999 standard, the only concept of
atomicity was the predefined type sig_atomic_t, which corresponds
closely to the Ada Atomic aspect, that is, the whole variable can be
read or written with one memory access.

> 	ldr	r2, [r3, #register_offset]
> 				-- Load device register contents into r2
> 				-- r3 contains device base address
> 	orr	r2, r2, #1	-- Set bit field A to 1
> 	{Additional code here to modify bitfields B and C}
> 	str	r2, [r3, #register_offset]
> 				-- Write all changes to device register at once

Yes, this looks like an Ada assignment of the form

   Tmp := Rec;
   Rec := (A => 1, B => expr1, C => expr2, D => Tmp.D, E => Tmp.E, ...);

where Rec has aspect Atomic and assuming that the compiler was able to
optimize out the "no effect" expressions for the unchanged components D,
E, .... Note that the following "simpler" assignment

   Rec := (A => 1, B => expr1, C => expr2, D => Rec.D, E => Rec.E, ...);

cannot give the code above -- the two (or more) uses of Rec in the
aggregate force the code to read (load) Rec two (or more) times, because
an Atomic variable is also Volatile. (That is how I understand it, but
I'm not entirely sure if each appearance of an object's name in the
source code as a primary implies the evaluation of the object and
therefore a "read" of the object.) This assumes a reasonable
implementation of the Volatile aspect.

> or is the Ada compiler allowed to do this:
> 
> 	ldr	r2, [r3, #register_offset]
> 	orr	r2, r2, #1			-- Set bit field A to 1
> 	str	r2, [r3, #register_offset]	-- Update bit field A only
> 
> 	ldr	r2, [r3, #register_offset]
> 	{Code here to modify bitfield B}
> 	str	r2, [r3, #register_offset]	-- Update bit field B only
> 
> 	ldr	r2, [r3, #register_offset]
> 	{Code here to modify bitfield C}
> 	str	r2, [r3, #register_offset]	-- Update bit field C only

No, three stores to Rec can result only if the source code contains
three assignments to Rec as a whole, or some assignments to components
of Rec.

> Ie: performs a atomic update of each bit field,

In what sense do you call these bit-field updates "atomic"?

Yes, the entire record variable is read with one memory access and
written with one memory access; this is the Atomic aspect in Ada and C 1999.

But no, they are not "atomic read-modify-write updates" in the sense of
C 2011 _Atomic, or in the sense of Ada protected operations. I assume,
as usual, that instruction sequences such as those above are not
indivisible.

> You also then have additional issues around wanting to, say, update bit
> fields B and C at the same time while preserving the current value of
> bit field A (which is where my "atomic using" suggestion comes in for
> a C replacement language).

The _Atomic qualifier of C 2011 might be used to make that whole update
atomic, with respect to C threads, if all the modified bits are set to
0, or all are set to 1, because then the update can be coded as one C
compound assignment (Rec &= mask, or Rec |= mask, respectively). But if
some bits are set to 0 and others to 1, then the update cannot be one C
compound assignment beause both an "and" and an "or" operation are required.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22 19:13                     ` Niklas Holsti
@ 2014-04-22 20:46                       ` Simon Clubley
  2014-04-22 23:38                         ` Randy Brukardt
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-22 20:46 UTC (permalink / raw)


On 2014-04-22, Niklas Holsti <niklas.holsti@tidorum.invalid> wrote:
> On 14-04-22 15:25 , Simon Clubley wrote:
>>
>> In general memory mapped I/O you have to do a register read/modify bit
>> field/register write sequence in units of the register size.
>> 
>> Consider a atomic record with 3 bit fields called A, B and C.
>> 
>> Now consider a Ada record assignment statement which sets the values of
>> the 3 bit fields. The question is how is the assignment to the 3 bit
>> fields turned into code ?
>
> If the record variable Rec has the Atomic aspect, then by the Ada RM any
> assignment Rec := expr must write Rec exactly once, indivisibly, and
> this write should (per implementation advice) be implemented by a single
> store instruction. This applies whatever the right-hand-side expr is.
>
> Note, however, that if the right-hand-side expr includes some references
> to (i.e. reads of) Rec, then there is no guarantee that the read-write
> sequence as a whole is indivisible.
>
>> Is it something like this (which is how it looks in C with masks):
>
> Here one should separate between C 2011 on the one hand and earlier C
> standards on the other. (For C 2011 my reference is the "final" draft
> N1570, which is on the web.)
>

I was recently pointed to this document over in comp.arch.embedded and
it's on my list of things to read but I have not yet done that.
My knowledge of C comes from versions of C prior to C 2011.

> In C 2011, a "compound assignment is a read-modify-write operation with
> memory_order_seq_cst memory order semantics". That is, in C 2011 an
> update like "v &= mask", where v is an _Atomic variable, is an atomic
> *update* with respect to other C threads (but perhaps not with respect
> to other memory bus activity; I admit to an incomplete understanding
> here).

I admit I have not read the C 2011 standard yet, but I don't see how
protecting against other memory bus activity is possible when you have
interrupts active (unless you turn off interrupts during the update
sequence).

Declaring something as "_Atomic" doesn't change the fact it's still a
read/modify/write sequence which is generated for most processors.

> Note that this is rather different from the meaning of the Atomic
> aspect in Ada, which only makes each read indivisible, and each write
> indivisible, but does not guarantee indivisibility of some
> read-modify-write sequence.
>

And I don't see how the C 2011 version does either when the same variable
is referenced in both a interrupt handler and the main program.

> In earlier C standards such as the 1999 standard, the only concept of
> atomicity was the predefined type sig_atomic_t, which corresponds
> closely to the Ada Atomic aspect, that is, the whole variable can be
> read or written with one memory access.
>
>> 	ldr	r2, [r3, #register_offset]
>> 				-- Load device register contents into r2
>> 				-- r3 contains device base address
>> 	orr	r2, r2, #1	-- Set bit field A to 1
>> 	{Additional code here to modify bitfields B and C}
>> 	str	r2, [r3, #register_offset]
>> 				-- Write all changes to device register at once
>
> Yes, this looks like an Ada assignment of the form
>
>    Tmp := Rec;
>    Rec := (A => 1, B => expr1, C => expr2, D => Tmp.D, E => Tmp.E, ...);
>
> where Rec has aspect Atomic and assuming that the compiler was able to
> optimize out the "no effect" expressions for the unchanged components D,
> E, .... Note that the following "simpler" assignment
>
>    Rec := (A => 1, B => expr1, C => expr2, D => Rec.D, E => Rec.E, ...);
>
> cannot give the code above -- the two (or more) uses of Rec in the
> aggregate force the code to read (load) Rec two (or more) times, because
> an Atomic variable is also Volatile. (That is how I understand it, but
> I'm not entirely sure if each appearance of an object's name in the
> source code as a primary implies the evaluation of the object and
> therefore a "read" of the object.) This assumes a reasonable
> implementation of the Volatile aspect.
>

Ok, now that's interesting. I would not have assumed the compiler would
do the read multiple times in this specific case.

I would have assumed the Volatile attribute would be satisfied in this
specific case by doing the read _once_ at the start of the generated
code and only generating code to modify the A, B and C bitfields
before writing everything back in one step by using a single store
opcode.

>> or is the Ada compiler allowed to do this:
>> 
>> 	ldr	r2, [r3, #register_offset]
>> 	orr	r2, r2, #1			-- Set bit field A to 1
>> 	str	r2, [r3, #register_offset]	-- Update bit field A only
>> 
>> 	ldr	r2, [r3, #register_offset]
>> 	{Code here to modify bitfield B}
>> 	str	r2, [r3, #register_offset]	-- Update bit field B only
>> 
>> 	ldr	r2, [r3, #register_offset]
>> 	{Code here to modify bitfield C}
>> 	str	r2, [r3, #register_offset]	-- Update bit field C only
>
> No, three stores to Rec can result only if the source code contains
> three assignments to Rec as a whole, or some assignments to components
> of Rec.
>

Good. That's what I thought/hoped, but I wasn't 100% sure after reading
the Ada 95 RM.

>> Ie: performs a atomic update of each bit field,
>
> In what sense do you call these bit-field updates "atomic"?
>

When the update is done using a single store to update all the changes
to the device register in one non-interruptible opcode.

It's also what I understand the Ada 95 RM to mean as well.

Thank you for having taken the time to write the detailed analysis above;
it was very helpful seeing another person's understanding of these issues.

Thanks,

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22  0:34               ` Simon Clubley
  2014-04-22  3:01                 ` Jeffrey Carter
  2014-04-22  6:41                 ` Simon Wright
@ 2014-04-22 23:30                 ` Randy Brukardt
  2014-04-23 12:17                   ` Simon Clubley
  2 siblings, 1 reply; 144+ messages in thread
From: Randy Brukardt @ 2014-04-22 23:30 UTC (permalink / raw)


"Simon Clubley" <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote in 
message news:lj4de1$jql$1@dont-email.me...
...
>> If the compiler accepts the pragma, then assignment to Register (as 
>> opposed to
>> its components) is atomic:
>>
>> Register := (A => True, ...);
>
> Thank you. It was not at all 100% clear from the RM if Ada offered the
> _guarantee_ that if you had, say, 3 components in a record assignment
> for a atomic bitfield record, that the record assignment would be treated
> as one atomic operation instead of 3 atomic operations (one for each
> component).

It's not quite a guarentee, as it's Implementation Advice (C.6(22-23/2). The 
reason for it being IA is simply that we can't use undefined terms like 
"load" and "store" in normative wording. In this case, IA is actually 
stronger because we can say directly what we mean without defining it 
exactly. In theory, implementations are supposed to document all cases where 
they do not follow Implementation Advice, so you should be able to determine 
for a particular implementation as to whether it is followed.

I don't think there could be an absolute guarantee, as the idea of a load or 
store might not make sense on a data-flow machine (or some other exotic 
design). I would guess that implementers do this in virtually all cases. As 
Jeff said, if it is really critical, you have a verify the code.

                                    Randy.




^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22  3:01                 ` Jeffrey Carter
@ 2014-04-22 23:31                   ` Randy Brukardt
  0 siblings, 0 replies; 144+ messages in thread
From: Randy Brukardt @ 2014-04-22 23:31 UTC (permalink / raw)


"Jeffrey Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:lj4m1o$uao$1@dont-email.me...
> On 04/21/2014 05:34 PM, Simon Clubley wrote:
>>
>> Unfortunately, that only tells you how one compiler implemented it and
>> doesn't say anything about if such behaviour is mandatory in the 
>> standard.
>
> Unless there's a check for this in the ACATS, you'll want to make sure 
> your compiler complies as well as compiles.

The ACATS cannot require examination of code, so it's not possible to check 
for this. And the ACATS isn't allowed to check for whether or not 
Implementation Advice is followed (the ACATS is not about "goodness" of an 
implementation).

                          Randy.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22 20:46                       ` Simon Clubley
@ 2014-04-22 23:38                         ` Randy Brukardt
  2014-04-23 12:16                           ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Randy Brukardt @ 2014-04-22 23:38 UTC (permalink / raw)


"Simon Clubley" <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote in 
message news:lj6kfg$jhs$1@dont-email.me...
...
> Ok, now that's interesting. I would not have assumed the compiler would
> do the read multiple times in this specific case.
>
> I would have assumed the Volatile attribute would be satisfied in this
> specific case by doing the read _once_ at the start of the generated
> code and only generating code to modify the A, B and C bitfields
> before writing everything back in one step by using a single store
> opcode.

C.6(20):

The external effect of a program (see 1.1.3) is defined to include each read 
and update of a volatile or atomic object. The implementation shall not 
generate any memory reads or updates of atomic or volatile objects other 
than those specified by the program.

I see two reads of Rec in the original source code. The above rule means 
that an Ada compiler must NOT combine those reads for convinience; it must 
do EXACTLY what's in the source code. If you only want one read, you have to 
restructure so there is only one explicit read.

There was a long discussion about this some years ago, and the conclusion 
was that combining operations in particular is not allowed for volatile 
objects (and all atomic objects are also volatile).

                                     Randy.




^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22 23:38                         ` Randy Brukardt
@ 2014-04-23 12:16                           ` Simon Clubley
  2014-04-23 20:55                             ` Simon Wright
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-23 12:16 UTC (permalink / raw)


On 2014-04-22, Randy Brukardt <randy@rrsoftware.com> wrote:
> "Simon Clubley" <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote in 
> message news:lj6kfg$jhs$1@dont-email.me...
> ...
>> Ok, now that's interesting. I would not have assumed the compiler would
>> do the read multiple times in this specific case.
>>
>> I would have assumed the Volatile attribute would be satisfied in this
>> specific case by doing the read _once_ at the start of the generated
>> code and only generating code to modify the A, B and C bitfields
>> before writing everything back in one step by using a single store
>> opcode.
>
> C.6(20):
>
> The external effect of a program (see 1.1.3) is defined to include each read 
> and update of a volatile or atomic object. The implementation shall not 
> generate any memory reads or updates of atomic or volatile objects other 
> than those specified by the program.
>
> I see two reads of Rec in the original source code. The above rule means 
> that an Ada compiler must NOT combine those reads for convinience; it must 
> do EXACTLY what's in the source code. If you only want one read, you have to 
> restructure so there is only one explicit read.
>
> There was a long discussion about this some years ago, and the conclusion 
> was that combining operations in particular is not allowed for volatile 
> objects (and all atomic objects are also volatile).
>

Thanks for the feedback.

From a technical viewpoint, I can see exactly what you are saying and
can understand and agree with your reasoning for the general case.

However, from a practical viewpoint the example statement was just used to
update a subset of bitfields in the register at the same time so one read
would be sufficient. I am also very aware of device registers which either
return different results on different reads or treat a read as an
acknowledge.

In the C language replacement discussion I proposed an "atomic using" syntax
which would replace C style bitmasks for updating device registers and would
guarantee a single read register/apply modifications as required/write
register back in one opcode sequence.

I wonder if we need something like that for Ada proper so we don't have
to read the register into a temporary variable first in order to guarantee
a single register read and a single register write while updating a subset
of bitfields in the register.

Having to use a temporary variable to guarantee a update of, say, a couple
of bitfields (out of a possible large number of bitfields) at the same time
just feels as if it isn't elegant.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-22 23:30                 ` Randy Brukardt
@ 2014-04-23 12:17                   ` Simon Clubley
  0 siblings, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-23 12:17 UTC (permalink / raw)


On 2014-04-22, Randy Brukardt <randy@rrsoftware.com> wrote:
> "Simon Clubley" <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote in 
> message news:lj4de1$jql$1@dont-email.me...
>>
>> Thank you. It was not at all 100% clear from the RM if Ada offered the
>> _guarantee_ that if you had, say, 3 components in a record assignment
>> for a atomic bitfield record, that the record assignment would be treated
>> as one atomic operation instead of 3 atomic operations (one for each
>> component).
>
> It's not quite a guarentee, as it's Implementation Advice (C.6(22-23/2). The 
> reason for it being IA is simply that we can't use undefined terms like 
> "load" and "store" in normative wording. In this case, IA is actually 
> stronger because we can say directly what we mean without defining it 
> exactly. In theory, implementations are supposed to document all cases where 
> they do not follow Implementation Advice, so you should be able to determine 
> for a particular implementation as to whether it is followed.
>
> I don't think there could be an absolute guarantee, as the idea of a load or 
> store might not make sense on a data-flow machine (or some other exotic 
> design). I would guess that implementers do this in virtually all cases. As 
> Jeff said, if it is really critical, you have a verify the code.
>

Ok, those are some interesting insights.

Thanks, Randy.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-23 12:16                           ` Simon Clubley
@ 2014-04-23 20:55                             ` Simon Wright
  2014-04-24  0:20                               ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Wright @ 2014-04-23 20:55 UTC (permalink / raw)


Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:

> I wonder if we need something like that for Ada proper so we don't
> have to read the register into a temporary variable first in order to
> guarantee a single register read and a single register write while
> updating a subset of bitfields in the register.
>
> Having to use a temporary variable to guarantee a update of, say, a
> couple of bitfields (out of a possible large number of bitfields) at
> the same time just feels as if it isn't elegant.

But hardware isn't (usually) elegant! If what the hardware designer
wants is for you to read the register, change the values you need to in
the local copy, then write the modified value back, that's what the code
should do, surely, without relying on compiler magic with obscure
pragmas to make it happen? (Ada's pragma Atomic is quite obscure enough
already!)


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-23 20:55                             ` Simon Wright
@ 2014-04-24  0:20                               ` Simon Clubley
  2014-04-24 13:05                                 ` Niklas Holsti
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-24  0:20 UTC (permalink / raw)


On 2014-04-23, Simon Wright <simon@pushface.org> wrote:
> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:
>
>> I wonder if we need something like that for Ada proper so we don't
>> have to read the register into a temporary variable first in order to
>> guarantee a single register read and a single register write while
>> updating a subset of bitfields in the register.
>>
>> Having to use a temporary variable to guarantee a update of, say, a
>> couple of bitfields (out of a possible large number of bitfields) at
>> the same time just feels as if it isn't elegant.
>
> But hardware isn't (usually) elegant! If what the hardware designer
> wants is for you to read the register, change the values you need to in
> the local copy, then write the modified value back, that's what the code
> should do, surely, without relying on compiler magic with obscure
> pragmas to make it happen? (Ada's pragma Atomic is quite obscure enough
> already!)

The problem is the compiler does this automatically when you use C style
masks, but you have to do the work manually when you try to write clean
code by using record bitfields (in Ada) or bitfield structs (in C) and
need to do the read/write exactly once and want to update more than one
of the bitfields at the same time.

This whole discussion started when someone suggested that in a C
replacement language we should drop the use of masks when possible
in favour of a bitfield approach. I _strongly_ agree with this, but
neither C or Ada, as they stand, make it easy to do this.

I proposed the following syntax for a C replacement language:

        atomic using uart0.config1
                .flag1  := 0;
                .enable := 1;
                .txdis  := 0;
        end atomic;

(I'm not too sure about the leading dots however.)

which would be a direct replacement for the use of C style masks when
modifying registers and would update the bitfields listed while
preserving the other unlisted bitfields and would guarantee only one
read and one write to the register.

The code above is a _lot_ safer and cleaner than using masks but to do
that in C or Ada at the moment requires the use of temporary variables
which is not clean as the above approach (or an approach like it).

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-24  0:20                               ` Simon Clubley
@ 2014-04-24 13:05                                 ` Niklas Holsti
  2014-04-24 18:51                                   ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-04-24 13:05 UTC (permalink / raw)


On 14-04-24 03:20 , Simon Clubley wrote:
> On 2014-04-23, Simon Wright <simon@pushface.org> wrote:
>> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes:
>>
>>> I wonder if we need something like that for Ada proper so we don't
>>> have to read the register into a temporary variable first in order to
>>> guarantee a single register read and a single register write while
>>> updating a subset of bitfields in the register.
>>>
>>> Having to use a temporary variable to guarantee a update of, say, a
>>> couple of bitfields (out of a possible large number of bitfields) at
>>> the same time just feels as if it isn't elegant.
>>
>> But hardware isn't (usually) elegant! If what the hardware designer
>> wants is for you to read the register, change the values you need to in
>> the local copy, then write the modified value back, that's what the code
>> should do, surely, without relying on compiler magic with obscure
>> pragmas to make it happen? (Ada's pragma Atomic is quite obscure enough
>> already!)
> 
> The problem is the compiler does this automatically when you use C style
> masks,

Not really so, for the most common forms of C. AIUI, before C 2011 there
was no way in C to declare that a particular variable or type should be
"atomic" in the sense of being read and written indivisibly; this was
only possible by using the predefined integer type sig_atomic_t.

The C 1999 standard requires sig_atomic_t to be at least 8 bits wide, so
it may be uncomfortably narrow on some machines. Of course, reasonable C
compilers make sig_atomic_t be the widest type for which the target
machine allows atomic load/store. On the other hand, some 32-bit
machines have 16-bit I/O control registers, so a 32-bit sig_atomic_t
would be too wide to be used for I/O control!

Even qualifying the type or variable as volatile does not help, because
volatility does not imply atomicity.

> but you have to do the work manually when you try to write clean
> code by using record bitfields (in Ada) or bitfield structs (in C) and
> need to do the read/write exactly once and want to update more than one
> of the bitfields at the same time.
> 
> This whole discussion started when someone suggested that in a C
> replacement language we should drop the use of masks when possible
> in favour of a bitfield approach. I _strongly_ agree with this, but
> neither C or Ada, as they stand, make it easy to do this.
> 
> I proposed the following syntax for a C replacement language:
> 
>         atomic using uart0.config1
>                 .flag1  := 0;
>                 .enable := 1;
>                 .txdis  := 0;
>         end atomic;

This resembles the Pascal "with" statement, which is like an Ada "use"
statement for the record variable: the record components are directly
visible (without qualification) in the scope of the "with" statement.

I would prefer a more general, expression-based solution: extend the
aggregate notation with a form which combines an expression of a
composite type, which provides the initial component values, and a
partial aggregate, which uses named association to set new values for
some of the components. This would be similar to an extension aggregate,
but would override the initial values of some components, not combine an
ancestor part with an extension part.

For example, assume that the variables A and B are of a record type with
the components x and y and some more components, Then, instead of the
three statements

   B   := A;
   B.x := 42;
   B.y := False;

we could say something like

   B := (A overriding x => 42, y => False);

(The "overriding" keyword is a bit misleading here, because it implies
that the left-hand operand (A) overrides the right-hand aggregate, while
the opposite should happen. Oh well.)

This form of aggregate could implement the "atomic using", for example:

   uart0.config1 := (uart0.config1
      overriding flag1 => 0, enable => 1, txdis => 0);

Declaring uart0.config1 as atomic provides the single-read, single-write
property in this assignment.

This "overriding aggregate" would be useful in other ways, too, by
making some temporary variables unnecessary. Perhaps it would be
especially useful in contract aspects, where temporaries cannot be declared.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-24 13:05                                 ` Niklas Holsti
@ 2014-04-24 18:51                                   ` Simon Clubley
  2014-04-24 20:11                                     ` Niklas Holsti
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-24 18:51 UTC (permalink / raw)


On 2014-04-24, Niklas Holsti <niklas.holsti@tidorum.invalid> wrote:
> On 14-04-24 03:20 , Simon Clubley wrote:
>> On 2014-04-23, Simon Wright <simon@pushface.org> wrote:
>>>
>>> But hardware isn't (usually) elegant! If what the hardware designer
>>> wants is for you to read the register, change the values you need to in
>>> the local copy, then write the modified value back, that's what the code
>>> should do, surely, without relying on compiler magic with obscure
>>> pragmas to make it happen? (Ada's pragma Atomic is quite obscure enough
>>> already!)
>> 
>> The problem is the compiler does this automatically when you use C style
>> masks,
>
> Not really so, for the most common forms of C. AIUI, before C 2011 there
> was no way in C to declare that a particular variable or type should be
> "atomic" in the sense of being read and written indivisibly; this was
> only possible by using the predefined integer type sig_atomic_t.
>

Sorry, I probably wasn't clear enough.

What I meant was that if you write (in C) something like:

	device_register = (device_register & mask1) | mask2;

while accessing a volatile register then gcc generates exactly one read
and exactly one write and the size of the access is the size of the
device_register declaration.

This is true at least on ARM and I have never seen any complaints about
it being untrue on other architectures.

> The C 1999 standard requires sig_atomic_t to be at least 8 bits wide, so
> it may be uncomfortably narrow on some machines. Of course, reasonable C
> compilers make sig_atomic_t be the widest type for which the target
> machine allows atomic load/store. On the other hand, some 32-bit
> machines have 16-bit I/O control registers, so a 32-bit sig_atomic_t
> would be too wide to be used for I/O control!
>
> Even qualifying the type or variable as volatile does not help, because
> volatility does not imply atomicity.
>

That's interesting. I wonder if this is a case of gcc implementing the
"expected" behaviour and there's now a large set of code which relies on
this "expected" behaviour.

>> but you have to do the work manually when you try to write clean
>> code by using record bitfields (in Ada) or bitfield structs (in C) and
>> need to do the read/write exactly once and want to update more than one
>> of the bitfields at the same time.
>> 
>> This whole discussion started when someone suggested that in a C
>> replacement language we should drop the use of masks when possible
>> in favour of a bitfield approach. I _strongly_ agree with this, but
>> neither C or Ada, as they stand, make it easy to do this.
>> 
>> I proposed the following syntax for a C replacement language:
>> 
>>         atomic using uart0.config1
>>                 .flag1  := 0;
>>                 .enable := 1;
>>                 .txdis  := 0;
>>         end atomic;
>
> This resembles the Pascal "with" statement, which is like an Ada "use"
> statement for the record variable: the record components are directly
> visible (without qualification) in the scope of the "with" statement.
>
> I would prefer a more general, expression-based solution: extend the
> aggregate notation with a form which combines an expression of a
> composite type, which provides the initial component values, and a
> partial aggregate, which uses named association to set new values for
> some of the components. This would be similar to an extension aggregate,
> but would override the initial values of some components, not combine an
> ancestor part with an extension part.
>
> For example, assume that the variables A and B are of a record type with
> the components x and y and some more components, Then, instead of the
> three statements
>
>    B   := A;
>    B.x := 42;
>    B.y := False;
>
> we could say something like
>
>    B := (A overriding x => 42, y => False);
>
> (The "overriding" keyword is a bit misleading here, because it implies
> that the left-hand operand (A) overrides the right-hand aggregate, while
> the opposite should happen. Oh well.)
>

Although I agree the syntax needs changing, I do like the general
idea behind this suggestion.

> This form of aggregate could implement the "atomic using", for example:
>
>    uart0.config1 := (uart0.config1
>       overriding flag1 => 0, enable => 1, txdis => 0);
>
> Declaring uart0.config1 as atomic provides the single-read, single-write
> property in this assignment.
>

Yes, it certainly does.

> This "overriding aggregate" would be useful in other ways, too, by
> making some temporary variables unnecessary. Perhaps it would be
> especially useful in contract aspects, where temporaries cannot be declared.
>

It will be interesting to see if Randy and company have any comments on
this syntax.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-24 18:51                                   ` Simon Clubley
@ 2014-04-24 20:11                                     ` Niklas Holsti
  2014-04-25  1:37                                       ` Randy Brukardt
  0 siblings, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-04-24 20:11 UTC (permalink / raw)


On 14-04-24 21:51 , Simon Clubley wrote:
> On 2014-04-24, Niklas Holsti <niklas.holsti@tidorum.invalid> wrote:
>> On 14-04-24 03:20 , Simon Clubley wrote:
>>> On 2014-04-23, Simon Wright <simon@pushface.org> wrote:
>>>>
>>>> But hardware isn't (usually) elegant! If what the hardware designer
>>>> wants is for you to read the register, change the values you need to in
>>>> the local copy, then write the modified value back, that's what the code
>>>> should do, surely, without relying on compiler magic with obscure
>>>> pragmas to make it happen? (Ada's pragma Atomic is quite obscure enough
>>>> already!)
>>>
>>> The problem is the compiler does this automatically when you use C style
>>> masks,
>>
>> Not really so, for the most common forms of C. AIUI, before C 2011 there
>> was no way in C to declare that a particular variable or type should be
>> "atomic" in the sense of being read and written indivisibly; this was
>> only possible by using the predefined integer type sig_atomic_t.
>>
> 
> Sorry, I probably wasn't clear enough.

Nor was I, see below...

> What I meant was that if you write (in C) something like:
> 
> 	device_register = (device_register & mask1) | mask2;
> 
> while accessing a volatile register then gcc generates exactly one read
> and exactly one write and the size of the access is the size of the
> device_register declaration.
> 
> This is true at least on ARM and I have never seen any complaints about
> it being untrue on other architectures.

Gcc usually does the right thing, which is good. But gcc on ARM has no
reason to do otherwise, because the "load;and;or;store" instruction
sequence is also the shortest and fastest implementation of this C
statement.

IIRC, your original question was if the Ada RM *guarantees* single
load/store instructions; my point above was that the C standard (pre
2011) guarantees it only for the type sig_atomic_t.

To be very precise, C 1999 says only that sig_atomic_t "can be accessed
as an atomic entity, even in the presence of asynchronous interrupts".
There is no mention of single load/store instructions. In principle, a C
compiler could implement read (write) of sig_atomic_t by several load
(store) instructions, executed with interrupts disabled. But I don't
know of any C compiler that does that.

> That's interesting. I wonder if this is a case of gcc implementing the
> "expected" behaviour and there's now a large set of code which relies on
> this "expected" behaviour.

That's "Situation Normal" for C :-). For this case (accessing device
registers), it is usually good enough because programs that depend on it
are not expected to work on different machines without rewriting these
parts of the program.

>> For example, assume that the variables A and B are of a record type with
>> the components x and y and some more components, Then, instead of the
>> three statements
>>
>>    B   := A;
>>    B.x := 42;
>>    B.y := False;
>>
>> we could say something like
>>
>>    B := (A overriding x => 42, y => False);
>>
>> (The "overriding" keyword is a bit misleading here, because it implies
>> that the left-hand operand (A) overrides the right-hand aggregate, while
>> the opposite should happen. Oh well.)
>>
> 
> Although I agree the syntax needs changing, I do like the general
> idea behind this suggestion.

Thanks. Perhaps the syntax (A and then x => 42, y => False) is a little
better.

I also considered using "others" in a new way:

   (x => 42, y => False, others => all A)

or

   (x => 42, y => False, all others => A)

but for some reason I feel that "A" should come first, and the changed
components after.

> It will be interesting to see if Randy and company have any comments on
> this syntax.

Overload resolution may be an issue. I think it could be based purely on
the "initial values" part ("A" in the examples above) and could ignore
the named component associations.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-24 20:11                                     ` Niklas Holsti
@ 2014-04-25  1:37                                       ` Randy Brukardt
  2014-04-25 21:33                                         ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Randy Brukardt @ 2014-04-25  1:37 UTC (permalink / raw)


"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:brt9ftFrnkaU1@mid.individual.net...
> On 14-04-24 21:51 , Simon Clubley wrote:
...
>> It will be interesting to see if Randy and company have any comments on
>> this syntax.

Not really, other than that someone needs to come up with syntax that has 
the right "feeling". None of the proposals I've seen have that yet, but keep 
trying.

> Overload resolution may be an issue. I think it could be based purely on
> the "initial values" part ("A" in the examples above) and could ignore
> the named component associations.

I don't think so. An aggregate has to resolve without context, so the type 
of the aggregate has to be unique or its already illegal (ignoring the 
contents). Once you have that, resolving the contents is straighforward (it 
would be a lot easier than an extension aggregate as the type of the object 
would have the be the same as the aggregate as a whole, not something in a 
class - unless of course one also added a form of extension here as an 
option [I see no need.]).

                           Randy.




^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25  1:37                                       ` Randy Brukardt
@ 2014-04-25 21:33                                         ` Simon Clubley
  2014-04-25 21:55                                           ` Randy Brukardt
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Clubley @ 2014-04-25 21:33 UTC (permalink / raw)


On 2014-04-24, Randy Brukardt <randy@rrsoftware.com> wrote:
>> On 14-04-24 21:51 , Simon Clubley wrote:
> ...
>>> It will be interesting to see if Randy and company have any comments on
>>> this syntax.
>
> Not really, other than that someone needs to come up with syntax that has 
> the right "feeling". None of the proposals I've seen have that yet, but keep 
> trying.
>

Ideas on what you think is wrong with the current suggestions will be
useful.

Do you have some general approach in mind which you would prefer ?

For example, do you think it should be done as part of an assignment
statement as Niklas is suggesting, or something more Pascal like as
I was thinking of ?

I would not want to see something fully Pascal like, with random
statements within the with, but something directed towards updating
the variable only. I also now think the atomic on the statement may
be redundant as it can be made a part of the variable definition using
the atomic pragma.

My revised version looks like this:

	update uart0.config1 using
		.flag1	:= 0;
		.enable	:= 1;
		.txdis	:= 0;
	end update;

I think the leading dot is required to positively identify something as
a member of config1 (in this case) and avoid conflicts between variable
definitions.

However, I'm also tempted to ban the use of config1 component references
on the RHS of the assignment. This avoids issues, if the component is
modified within the update statement, around whether the component value
used on the RHS is the value on entry to the update statement or the
modified value.

There would also have to be wording along the lines of "An atomic variable
shall be read exactly once and written exactly once by the update statement.
The compiler must reject the update statement if this cannot be achieved."

Although my current preference is for something like the above, as an
alternative, would you be open to a new assignment operator which was
used for "updates" instead of "becomes" semantics ?

Something along the lines of:

	uart0.config1 {updates_operator} (flag1 => 0, enable => 1, txdis = 0);

or

	uart0.config1'Update := (flag1 => 0, enable => 1, txdis = 0);

although I'm not sure what characters would be used for the updates_operator.

Once again, the atomic update would be enforced by the atomic pragma.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:33                                         ` Simon Clubley
@ 2014-04-25 21:55                                           ` Randy Brukardt
  2014-04-25 23:16                                             ` Dennis Lee Bieber
                                                               ` (5 more replies)
  0 siblings, 6 replies; 144+ messages in thread
From: Randy Brukardt @ 2014-04-25 21:55 UTC (permalink / raw)


"Simon Clubley" <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote in 
message news:ljekbl$bbt$1@dont-email.me...
> On 2014-04-24, Randy Brukardt <randy@rrsoftware.com> wrote:
>>> On 14-04-24 21:51 , Simon Clubley wrote:
>> ...
>>>> It will be interesting to see if Randy and company have any comments on
>>>> this syntax.
>>
>> Not really, other than that someone needs to come up with syntax that has
>> the right "feeling". None of the proposals I've seen have that yet, but 
>> keep
>> trying.
>>
>
> Ideas on what you think is wrong with the current suggestions will be
> useful.
>
> Do you have some general approach in mind which you would prefer ?

I prefer the partial aggregate approach; it comes up so often in practice 
and compilers have to bend over backwards to optimize the case. (The 
Janus/Ada compiler is stuffed with such aggregates that change a 
discriminant but little else of the content, I spent several weeks writing 
optimizations so that doesn't necessarily copy everything in a large record. 
But of course that has to be turned off for volatile and atomic objects.)

But the syntax proposed doesn't have the right "feel". The connotation of 
the syntax has to match fairly closely the semantics of a feature, 
especially when we're in nice-to-have territory as this is. (After all, 
temporaries work; they might be a bit ugly but that's hardly a reason for a 
language feature.)

This is a case where the keyword will make all of the difference. If we were 
using a new keyword, perhaps something like:

   A := (A replacing C => D, E => F);

would do the trick.

I don't find your Pascal-derived idea very appealing, because its so foreign 
to Ada. Something based on aggregates feels more in tune with the rest of 
the language.

To get assignment atomicity, probably extending the aspect syntax to 
statements would be best. (The Parallel proposals are thinking in that 
direction anyway.) Then something like:

   A := (A replacing C => D, E => F) with Atomic;

would mean to do an atomic update of A replacing the C and E components, 
leaving the rest untouched.

                                Randy.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:55                                           ` Randy Brukardt
@ 2014-04-25 23:16                                             ` Dennis Lee Bieber
  2014-04-26  6:31                                               ` Niklas Holsti
  2014-04-26  0:23                                             ` Nasser M. Abbasi
                                                               ` (4 subsequent siblings)
  5 siblings, 1 reply; 144+ messages in thread
From: Dennis Lee Bieber @ 2014-04-25 23:16 UTC (permalink / raw)


On Fri, 25 Apr 2014 16:55:02 -0500, "Randy Brukardt" <randy@rrsoftware.com>
declaimed the following:

>
>This is a case where the keyword will make all of the difference. If we were 
>using a new keyword, perhaps something like:
>
>   A := (A replacing C => D, E => F);
>
>would do the trick.
>
	I've not really been tracking this, but is a new keyword really needed?
	At least, I read the above to mean keep the unnamed components of 'A'
during the operation.

	A := (C => D, E => F, others => A.others);
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:55                                           ` Randy Brukardt
  2014-04-25 23:16                                             ` Dennis Lee Bieber
@ 2014-04-26  0:23                                             ` Nasser M. Abbasi
  2014-04-26  2:46                                             ` Shark8
                                                               ` (3 subsequent siblings)
  5 siblings, 0 replies; 144+ messages in thread
From: Nasser M. Abbasi @ 2014-04-26  0:23 UTC (permalink / raw)


On 4/25/2014 4:55 PM, Randy Brukardt wrote:

> This is a case where the keyword will make all of the difference. If we were
> using a new keyword, perhaps something like:
>
>     A := (A replacing C => D, E => F);
>
> would do the trick.
>

Maple SUBS() is somewhat similar.

http://www.maplesoft.com/support/help/Maple/view.aspx?path=subs

      SUBS( {old1=new1,old2,new2,...}, A );

WIll replace old1,old2... in A with new1,new2,... in A.
After the call, A will has a new value.

--Nasser

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:55                                           ` Randy Brukardt
  2014-04-25 23:16                                             ` Dennis Lee Bieber
  2014-04-26  0:23                                             ` Nasser M. Abbasi
@ 2014-04-26  2:46                                             ` Shark8
  2014-04-26  2:52                                               ` Shark8
  2014-04-26  6:37                                               ` Niklas Holsti
  2014-04-26  6:19                                             ` Georg Bauhaus
                                                               ` (2 subsequent siblings)
  5 siblings, 2 replies; 144+ messages in thread
From: Shark8 @ 2014-04-26  2:46 UTC (permalink / raw)


On 25-Apr-14 15:55, Randy Brukardt wrote:
> This is a case where the keyword will make all of the difference. If we were
> using a new keyword, perhaps something like:
>
>     A := (A replacing C => D, E => F);
>
> would do the trick.

Howabout reusing 'overriding'? (Assuming record A w/ components B, C, & D.)

A := (Overriding B, C => <>, D = A.D);

I'd assume that 'overriding' should be given to *every* replaced 
component and "<>" or "RECORD.COMPONENT" for old [unchanged] values. 
(Though, we'd have to decide whether '<>' meant "keep things the same" 
or "use the component's default [or type's if not available, 
compiler-error if no default]")

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  2:46                                             ` Shark8
@ 2014-04-26  2:52                                               ` Shark8
  2014-04-26  6:37                                               ` Niklas Holsti
  1 sibling, 0 replies; 144+ messages in thread
From: Shark8 @ 2014-04-26  2:52 UTC (permalink / raw)


On 25-Apr-14 20:46, Shark8 wrote:
>
> A := (Overriding B, C => <>, D = A.D);

That should have ' => B_VALUE' after "Overriding B".

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:55                                           ` Randy Brukardt
                                                               ` (2 preceding siblings ...)
  2014-04-26  2:46                                             ` Shark8
@ 2014-04-26  6:19                                             ` Georg Bauhaus
  2014-04-26  6:35                                               ` Georg Bauhaus
  2014-04-26  6:42                                               ` Niklas Holsti
  2014-04-26  6:29                                             ` Niklas Holsti
  2014-04-26  7:23                                             ` Simon Wright
  5 siblings, 2 replies; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-26  6:19 UTC (permalink / raw)


On 25/04/14 23:55, Randy Brukardt wrote:
> This is a case where the keyword will make all of the difference. If we were
> using a new keyword, perhaps something like:
>
>     A := (A replacing C => D, E => F);
>
> would do the trick.

Hasn't GNAT recently added something similar,
http://gcc.gnu.org/onlinedocs/gnat_rm/Attribute-Update.html#Attribute-Update

I'd drop the assignment altogether, if doing so reflects
the intent, and people do not feel they see an expression.
Thinking of 'Write as a model:

    T'Update (A with C => D, E => F);




^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:55                                           ` Randy Brukardt
                                                               ` (3 preceding siblings ...)
  2014-04-26  6:19                                             ` Georg Bauhaus
@ 2014-04-26  6:29                                             ` Niklas Holsti
  2014-04-26  7:36                                               ` Dmitry A. Kazakov
  2014-05-08  2:36                                               ` Randy Brukardt
  2014-04-26  7:23                                             ` Simon Wright
  5 siblings, 2 replies; 144+ messages in thread
From: Niklas Holsti @ 2014-04-26  6:29 UTC (permalink / raw)


On 14-04-26 00:55 , Randy Brukardt wrote:

> To get assignment atomicity, probably extending the aspect syntax to 
> statements would be best. (The Parallel proposals are thinking in that 
> direction anyway.

Do you have at hand a link to the "Parallel" proposals? Seems to be hard
to find by web search -- a common word.

>) Then something like:
> 
>    A := (A replacing C => D, E => F) with Atomic;

"replacing" is a good word for this, I agree.

> would mean to do an atomic update of A replacing the C and E components, 
> leaving the rest untouched.

The 2011 C standard goes into various memory order semantics in great
detail, not just "atomic". As I (weakly) understand it, that is
necessary or useful for implementing lock-free and wait-free
synchronization on modern architectures. Do you see any need to extend
Ada in that direction?

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 23:16                                             ` Dennis Lee Bieber
@ 2014-04-26  6:31                                               ` Niklas Holsti
  0 siblings, 0 replies; 144+ messages in thread
From: Niklas Holsti @ 2014-04-26  6:31 UTC (permalink / raw)


On 14-04-26 02:16 , Dennis Lee Bieber wrote:
> On Fri, 25 Apr 2014 16:55:02 -0500, "Randy Brukardt" <randy@rrsoftware.com>
> declaimed the following:
> 
>>
>> This is a case where the keyword will make all of the difference. If we were 
>> using a new keyword, perhaps something like:
>>
>>   A := (A replacing C => D, E => F);
>>
>> would do the trick.
>>
> 	I've not really been tracking this, but is a new keyword really needed?
> 	At least, I read the above to mean keep the unnamed components of 'A'
> during the operation.
> 
> 	A := (C => D, E => F, others => A.others);

Of the forms with "others", I like that one best. But I would still
prefer a form in which the initial value (A) comes first, and the
component-wise changes after, as in the "replacing" form.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  6:19                                             ` Georg Bauhaus
@ 2014-04-26  6:35                                               ` Georg Bauhaus
  2014-04-26  6:42                                               ` Niklas Holsti
  1 sibling, 0 replies; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-26  6:35 UTC (permalink / raw)


On 26/04/14 08:19, Georg Bauhaus wrote:
> I'd drop the assignment altogether, if doing so reflects
> the intent, and people do not feel they see an expression.
> Thinking of 'Write as a model:
>
>     T'Update (A with C => D, E => F);

Although, in order to avoid mental overload and context
dependence and whatnot, ... a new reserved word is needed.



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  2:46                                             ` Shark8
  2014-04-26  2:52                                               ` Shark8
@ 2014-04-26  6:37                                               ` Niklas Holsti
  1 sibling, 0 replies; 144+ messages in thread
From: Niklas Holsti @ 2014-04-26  6:37 UTC (permalink / raw)


On 14-04-26 05:46 , Shark8 wrote:
> On 25-Apr-14 15:55, Randy Brukardt wrote:
>> This is a case where the keyword will make all of the difference. If
>> we were
>> using a new keyword, perhaps something like:
>>
>>     A := (A replacing C => D, E => F);
>>
>> would do the trick.
> 
> Howabout reusing 'overriding'? (Assuming record A w/ components B, C, & D.)
> 
> A := (Overriding B, C => <>, D = A.D);
> 
> I'd assume that 'overriding' should be given to *every* replaced
> component and "<>" or "RECORD.COMPONENT" for old [unchanged] values.
> (Though, we'd have to decide whether '<>' meant "keep things the same"
> or "use the component's default [or type's if not available,
> compiler-error if no default]")

I don't like that, because it is limited to use in assignment
statements. I think the partial aggregate expression would be useful in
other contexts, too, for example as an actual parameter in a call.

I suggested (A overriding B => .., C => ...), which I don't like much
(nor does Randy). Perhaps it would be better combined with "with":

   (A overriding with B => ..., C => ...)

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  6:19                                             ` Georg Bauhaus
  2014-04-26  6:35                                               ` Georg Bauhaus
@ 2014-04-26  6:42                                               ` Niklas Holsti
  2014-04-26 17:15                                                 ` Simon Clubley
  1 sibling, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-04-26  6:42 UTC (permalink / raw)


On 14-04-26 09:19 , Georg Bauhaus wrote:
> On 25/04/14 23:55, Randy Brukardt wrote:
>> This is a case where the keyword will make all of the difference. If
>> we were
>> using a new keyword, perhaps something like:
>>
>>     A := (A replacing C => D, E => F);
>>
>> would do the trick.
> 
> Hasn't GNAT recently added something similar,
> http://gcc.gnu.org/onlinedocs/gnat_rm/Attribute-Update.html#Attribute-Update

Interesting. There does seem to be a need for this kind of thing, then.

However, the GNAT implementation does not allow changing discriminants,
which was the main use-case that Randy told of in the Janus/Ada
compiler. It seems a reasonable limitation to me.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-25 21:55                                           ` Randy Brukardt
                                                               ` (4 preceding siblings ...)
  2014-04-26  6:29                                             ` Niklas Holsti
@ 2014-04-26  7:23                                             ` Simon Wright
  2014-04-26  9:27                                               ` Niklas Holsti
  2014-04-27 14:26                                               ` Brian Drummond
  5 siblings, 2 replies; 144+ messages in thread
From: Simon Wright @ 2014-04-26  7:23 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> This is a case where the keyword will make all of the difference. If we were 
> using a new keyword, perhaps something like:
>
>    A := (A replacing C => D, E => F);
>
> would do the trick.

I'd find

   A := (A with C => D, E => F);

quite straightforward.

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  6:29                                             ` Niklas Holsti
@ 2014-04-26  7:36                                               ` Dmitry A. Kazakov
  2014-04-26  7:52                                                 ` Georg Bauhaus
  2014-04-26 18:32                                                 ` Simon Clubley
  2014-05-08  2:36                                               ` Randy Brukardt
  1 sibling, 2 replies; 144+ messages in thread
From: Dmitry A. Kazakov @ 2014-04-26  7:36 UTC (permalink / raw)


On Sat, 26 Apr 2014 09:29:04 +0300, Niklas Holsti wrote:

> The 2011 C standard goes into various memory order semantics in great
> detail, not just "atomic". As I (weakly) understand it, that is
> necessary or useful for implementing lock-free and wait-free
> synchronization on modern architectures.

Yes!

> Do you see any need to extend Ada in that direction?

I certainly do, because I am using lock-free containers in Ada.

Some lock-free stuff can be implemented using pragma Atomic. Though there
are serious problems regarding portability. Unfortunately the standard does
not require that Atomic were accepted to all scalar types. [*]

Many lock-free operations require more than merely pragma Atomic, e.g.
compare and swap etc.

Though I find the selection used in C++11 __atomic built-ins strange and
rather difficult to use. I used it to work around GNAT's refusal to
atomically access 64-bit integers under 32-bit Windows/Linux.

Regarding original proposal, maybe I missed something, but I don't find it
useful in the case of hardware I/O, except maybe for very specific cases.
The reason is that reading from a hardware register is often impossible or
else has a physical side effect. In no way it can be done atomically with
the consequent read. We don't want to lock the whole machine for many
cycles? Hardware registers are very slow. When the copy of the register is
supposed to be stored elsewhere in RAM, then where is a problem?

----------------
* When the machine cannot load or store atomically, the compiler can always
fall back to a built-in protected object.

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


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  7:36                                               ` Dmitry A. Kazakov
@ 2014-04-26  7:52                                                 ` Georg Bauhaus
  2014-04-26  8:09                                                   ` Dmitry A. Kazakov
  2014-04-26 18:32                                                 ` Simon Clubley
  1 sibling, 1 reply; 144+ messages in thread
From: Georg Bauhaus @ 2014-04-26  7:52 UTC (permalink / raw)


On 26/04/14 09:36, Dmitry A. Kazakov wrote:
> Many lock-free operations require more than merely pragma Atomic, e.g.
> compare and swap etc.

Would it help if a Suspension_Object were implemented
on top of CAS?

I understand that everything concurrent can be expressed
with the help of consensus protocols, which in turn can
be expressed in terms of CAS  only.



^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  7:52                                                 ` Georg Bauhaus
@ 2014-04-26  8:09                                                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 144+ messages in thread
From: Dmitry A. Kazakov @ 2014-04-26  8:09 UTC (permalink / raw)


On Sat, 26 Apr 2014 09:52:45 +0200, Georg Bauhaus wrote:

> On 26/04/14 09:36, Dmitry A. Kazakov wrote:
>> Many lock-free operations require more than merely pragma Atomic, e.g.
>> compare and swap etc.
> 
> Would it help if a Suspension_Object were implemented
> on top of CAS?

Wouldn't it be a locking primitive, regardless the means you used to
implement it?

> I understand that everything concurrent can be expressed
> with the help of consensus protocols, which in turn can
> be expressed in terms of CAS  only.

As a side point. My understanding is that though much can be theoretically
done, most of it will break at the point of software decomposition.
Concurrency primitives are especially non-composable.

From the SW developing POV whatever primitives we put into the language
they must be local - have locally bounded effect, be textually local etc.

Anything done with the program as a whole (e.g. global optimization) may
take place, but only optionally. You cannot make the program dependent on
it.

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

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  7:23                                             ` Simon Wright
@ 2014-04-26  9:27                                               ` Niklas Holsti
  2014-04-26 12:34                                                 ` Simon Wright
  2014-04-27 14:26                                               ` Brian Drummond
  1 sibling, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-04-26  9:27 UTC (permalink / raw)


On 14-04-26 10:23 , Simon Wright wrote:
> "Randy Brukardt" <randy@rrsoftware.com> writes:
> 
>> This is a case where the keyword will make all of the difference. If we were 
>> using a new keyword, perhaps something like:
>>
>>    A := (A replacing C => D, E => F);
>>
>> would do the trick.
> 
> I'd find
> 
>    A := (A with C => D, E => F);
> 
> quite straightforward.

Yes, but that looks exactly like an extension aggregate, where the
ancestor object A is extended to a derived type with the new components
C and E. Maybe the compiler would not be confused, but I would be. I
think that an "updating" partial aggregate should be syntactically
distinct from an extension aggregate.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  9:27                                               ` Niklas Holsti
@ 2014-04-26 12:34                                                 ` Simon Wright
  2014-04-27 10:38                                                   ` Simon Wright
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Wright @ 2014-04-26 12:34 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> On 14-04-26 10:23 , Simon Wright wrote:
>> "Randy Brukardt" <randy@rrsoftware.com> writes:
>> 
>>> This is a case where the keyword will make all of the difference. If we were 
>>> using a new keyword, perhaps something like:
>>>
>>>    A := (A replacing C => D, E => F);
>>>
>>> would do the trick.
>> 
>> I'd find
>> 
>>    A := (A with C => D, E => F);
>> 
>> quite straightforward.
>
> Yes, but that looks exactly like an extension aggregate, where the
> ancestor object A is extended to a derived type with the new components
> C and E. Maybe the compiler would not be confused, but I would be. I
> think that an "updating" partial aggregate should be syntactically
> distinct from an extension aggregate.

OK, point taken

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  6:42                                               ` Niklas Holsti
@ 2014-04-26 17:15                                                 ` Simon Clubley
  0 siblings, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-26 17:15 UTC (permalink / raw)


On 2014-04-26, Niklas Holsti <niklas.holsti@tidorum.invalid> wrote:
> On 14-04-26 09:19 , Georg Bauhaus wrote:
>> On 25/04/14 23:55, Randy Brukardt wrote:
>>> This is a case where the keyword will make all of the difference. If
>>> we were
>>> using a new keyword, perhaps something like:
>>>
>>>     A := (A replacing C => D, E => F);
>>>
>>> would do the trick.

As some other posters have said, I do think a unique keyword or attribute
would be required and I agree with you the actual choice of word matters.

>> 
>> Hasn't GNAT recently added something similar,
>> http://gcc.gnu.org/onlinedocs/gnat_rm/Attribute-Update.html#Attribute-Update

Thanks for the link; I had not come across this until now.

>
> Interesting. There does seem to be a need for this kind of thing, then.
>

Indeed. Once I started thinking in terms of aggregates I didn't know
about the above Update attribute and it only took me a few minutes to
come up with using the same attribute name on the LHS of an assignment.

For ACT to have added something similar would indeed seem to strongly
imply something like this is needed in Ada.

> However, the GNAT implementation does not allow changing discriminants,
> which was the main use-case that Randy told of in the Janus/Ada
> compiler. It seems a reasonable limitation to me.
>

I also would not have a problem with that limitation.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  7:36                                               ` Dmitry A. Kazakov
  2014-04-26  7:52                                                 ` Georg Bauhaus
@ 2014-04-26 18:32                                                 ` Simon Clubley
  1 sibling, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-26 18:32 UTC (permalink / raw)


On 2014-04-26, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>
> Regarding original proposal, maybe I missed something, but I don't find it
> useful in the case of hardware I/O, except maybe for very specific cases.
> The reason is that reading from a hardware register is often impossible or
> else has a physical side effect. In no way it can be done atomically with
> the consequent read. We don't want to lock the whole machine for many
> cycles? Hardware registers are very slow. When the copy of the register is
> supposed to be stored elsewhere in RAM, then where is a problem?
>

I suspect you are thinking of accessing the registers in user mode while
running under a operating system, that isn't what these proposals were
about. The original intended usage was for Ada code to directly control
the device either in bare metal mode or as part of a driver.

Some background on how we got here might be useful.

With Heartbleed we were talking about how people used C instead of Ada
to write these critical libraries. I pointed out that Ada (sadly) wasn't
suitable because C code runs on far more targets than Ada code does and
others also pointed out that the C programmers would likely not use Ada
anyway due to the software engineering nature of Ada.

I suggested there was a place for a new language (my hypothetical
Oberon-14) which implemented basic Wirth style functionality with some
core Ada style concepts added on and which would be much more "hackable"
than Ada but be more type safe than C.

The idea was you would get C level functionality but in a type safe(r)
language and which would be more likely to be experimented with by C
programmers than Ada would be.

When discussing the removal of C style masks in Oberon-14 and replacing
them with bitfield records, I realised (when writing bare metal or
device driver code in this new language) you would need the ability to
perform multiple simultaneous bitfield updates while preserving the
other existing bitfields in the record.

I asked if something like that would be useful for Ada along with a
suggested syntax (which was too Pascal like for Randy :-)) and that
resulted in the discussion we have just had.

Some of the proposed Ada syntax would be useful as well in a more
general purpose role which had nothing to do with device registers.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26 12:34                                                 ` Simon Wright
@ 2014-04-27 10:38                                                   ` Simon Wright
  2014-04-27 15:36                                                     ` Simon Clubley
  0 siblings, 1 reply; 144+ messages in thread
From: Simon Wright @ 2014-04-27 10:38 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
>
>> On 14-04-26 10:23 , Simon Wright wrote:
>>> "Randy Brukardt" <randy@rrsoftware.com> writes:
>>> 
>>>> This is a case where the keyword will make all of the
>>>> difference. If we were
>>>> using a new keyword, perhaps something like:
>>>>
>>>>    A := (A replacing C => D, E => F);
>>>>
>>>> would do the trick.
>>> 
>>> I'd find
>>> 
>>>    A := (A with C => D, E => F);
>>> 
>>> quite straightforward.
>>
>> Yes, but that looks exactly like an extension aggregate, where the
>> ancestor object A is extended to a derived type with the new components
>> C and E. Maybe the compiler would not be confused, but I would be. I
>> think that an "updating" partial aggregate should be syntactically
>> distinct from an extension aggregate.
>
> OK, point taken

But Dirk Craenest says (out of band)

> I haven't been able to follow the whole discussion in detail, but
> what about:
> 
>  A := (A overriding C => D, E => F);
> 
> It seems to have everything wished for:
> - doesn't need a new keyword,
> - is short,
> - uses aggregate-like notation,
> - "reads" reasonably well, i.e.:
>  use the value of A, but overriding component C with D, and E with F.

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  7:23                                             ` Simon Wright
  2014-04-26  9:27                                               ` Niklas Holsti
@ 2014-04-27 14:26                                               ` Brian Drummond
  1 sibling, 0 replies; 144+ messages in thread
From: Brian Drummond @ 2014-04-27 14:26 UTC (permalink / raw)


On Sat, 26 Apr 2014 08:23:16 +0100, Simon Wright wrote:

> "Randy Brukardt" <randy@rrsoftware.com> writes:
> 
>> This is a case where the keyword will make all of the difference. If we
>> were using a new keyword, perhaps something like:
>>
>>    A := (A replacing C => D, E => F);
>>
>> would do the trick.
> 
> I'd find
> 
>    A := (A with C => D, E => F);
> 
> quite straightforward.

Or use "others" which already has a role in aggregates:

A := (C => D, E => F, others => A);
or if that leaves type resolution difficulties for "others", 
A := (C => D, E => F, others => A.others);

- Brian


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-27 10:38                                                   ` Simon Wright
@ 2014-04-27 15:36                                                     ` Simon Clubley
  0 siblings, 0 replies; 144+ messages in thread
From: Simon Clubley @ 2014-04-27 15:36 UTC (permalink / raw)


On 2014-04-27, Simon Wright <simon@pushface.org> wrote:
>
> But Dirk Craenest says (out of band)
>
>> I haven't been able to follow the whole discussion in detail, but
>> what about:
>> 
>>  A := (A overriding C => D, E => F);
>> 

That makes it sound like A is the one doing the overriding, not the
later C and E references.

Perhaps changing or updating would be better:

	A := (A changing C => D, E => F);

or

	A := (A updating C => D, E => F);

I think we need a new keyword because we are talking about adding
a subset update capability to Ada and that new usage should stand
out in any code.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-04-26  6:29                                             ` Niklas Holsti
  2014-04-26  7:36                                               ` Dmitry A. Kazakov
@ 2014-05-08  2:36                                               ` Randy Brukardt
  2014-05-08 17:48                                                 ` Niklas Holsti
  1 sibling, 1 reply; 144+ messages in thread
From: Randy Brukardt @ 2014-05-08  2:36 UTC (permalink / raw)


"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:bs121aFksntU1@mid.individual.net...
> On 14-04-26 00:55 , Randy Brukardt wrote:
>
>> To get assignment atomicity, probably extending the aspect syntax to
>> statements would be best. (The Parallel proposals are thinking in that
>> direction anyway.
>
> Do you have at hand a link to the "Parallel" proposals? Seems to be hard
> to find by web search -- a common word.

There was a paper I read somewhere (the HILT proceedings? Don't remember, 
sorry). And I don't know much about the most recent thinking (I presume I'll 
hear more during the upcoming meetings). Most of what I know since HILT 
comes from a long private discussion with Brad Moore; needless to say there 
is no link to that.

Brad probably would know more, but I would guess that it's not yet ready for 
prime-time.

                      Randy.


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-05-08  2:36                                               ` Randy Brukardt
@ 2014-05-08 17:48                                                 ` Niklas Holsti
  2014-05-08 19:22                                                   ` Randy Brukardt
  0 siblings, 1 reply; 144+ messages in thread
From: Niklas Holsti @ 2014-05-08 17:48 UTC (permalink / raw)


On 14-05-08 05:36 , Randy Brukardt wrote:
> "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
> news:bs121aFksntU1@mid.individual.net...
>> On 14-04-26 00:55 , Randy Brukardt wrote:
>>
>>> To get assignment atomicity, probably extending the aspect syntax to
>>> statements would be best. (The Parallel proposals are thinking in that
>>> direction anyway.
>>
>> Do you have at hand a link to the "Parallel" proposals? Seems to be hard
>> to find by web search -- a common word.
> 
> There was a paper I read somewhere (the HILT proceedings? Don't remember, 
> sorry). And I don't know much about the most recent thinking (I presume I'll 
> hear more during the upcoming meetings). Most of what I know since HILT 
> comes from a long private discussion with Brad Moore; needless to say there 
> is no link to that.

Thanks, the added search term "Brad Moore" helped, and I found
information at

http://www.ada-europe2013.org/talks/S1%20T2%20Parallel-talk-for-ada-europe-2013-06-03.pdf

and

http://dl.acm.org/citation.cfm?id=2553002

There seems to be a new talk coming in 2014:

http://www.cister.isep.ipp.pt/docs/parallelism_in_ada__status_and_prospects/838/

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Oberon and Wirthian languages
  2014-05-08 17:48                                                 ` Niklas Holsti
@ 2014-05-08 19:22                                                   ` Randy Brukardt
  0 siblings, 0 replies; 144+ messages in thread
From: Randy Brukardt @ 2014-05-08 19:22 UTC (permalink / raw)


Dirk notes that the paper I was thinking of is:

> There's indeed a relevant paper that was presented at HILT 2013 [1]:
> "Real-Time Programming on Accelerator Many-Core Processors", by Stephen 
> Michell, Brad Moore, Luis Miguel Pinho.
> It's included in the paper proceedings and in the online Digital Library. 
> A direct link to the
> latter is [2], though you have to be a SIGAda member or a Digital Library 
> subscriber to read more than the abstract.
>
>The authors are allowed to post a link to retrieve a publicly readable 
>version of the online paper
> in the Digital Library, though I haven't found anyone (yet) who did.
>[1] http://www.sigada.org/conf/hilt2013/schedule.html

>[2] http://dl.acm.org/citation.cfm?id=2527269.2527270

Thanks to Dirk for finding these references.

                    Randy.

"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:bt1ubaF4ar5U1@mid.individual.net...
> On 14-05-08 05:36 , Randy Brukardt wrote:
>> "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message
>> news:bs121aFksntU1@mid.individual.net...
>>> On 14-04-26 00:55 , Randy Brukardt wrote:
>>>
>>>> To get assignment atomicity, probably extending the aspect syntax to
>>>> statements would be best. (The Parallel proposals are thinking in that
>>>> direction anyway.
>>>
>>> Do you have at hand a link to the "Parallel" proposals? Seems to be hard
>>> to find by web search -- a common word.
>>
>> There was a paper I read somewhere (the HILT proceedings? Don't remember,
>> sorry). And I don't know much about the most recent thinking (I presume 
>> I'll
>> hear more during the upcoming meetings). Most of what I know since HILT
>> comes from a long private discussion with Brad Moore; needless to say 
>> there
>> is no link to that.
>
> Thanks, the added search term "Brad Moore" helped, and I found
> information at
>
> http://www.ada-europe2013.org/talks/S1%20T2%20Parallel-talk-for-ada-europe-2013-06-03.pdf
>
> and
>
> http://dl.acm.org/citation.cfm?id=2553002
>
> There seems to be a new talk coming in 2014:
>
> http://www.cister.isep.ipp.pt/docs/parallelism_in_ada__status_and_prospects/838/
>
> -- 
> Niklas Holsti
> Tidorum Ltd
> niklas holsti tidorum fi
>      .      @       . 


^ permalink raw reply	[flat|nested] 144+ messages in thread

* Re: Heartbleed
  2014-04-12 18:38       ` Heartbleed Simon Clubley
                           ` (2 preceding siblings ...)
  2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
@ 2014-05-14  9:39         ` gvdschoot
  3 siblings, 0 replies; 144+ messages in thread
From: gvdschoot @ 2014-05-14  9:39 UTC (permalink / raw)


On Saturday, April 12, 2014 8:38:48 PM UTC+2, Simon Clubley wrote:
> 
> 
> Will these new compilers be easy to port to a new environment or will
> 
> the size and functionality of the Ada language make porting a major task ?
> 
> 
> 
> >> What may be a viable option would be if a simpler Wirth style language
> 
> >> existed and whose compiler generated object code compatible with gcc
> 
> >> and used binutils for it's assembling/linking phase.
> 
> >
> 
> > Oberon?
> 
> >
> 
> Something based on one of the Oberon variants is _exactly_ the kind of
> 
> thing I was thinking of. I would modify some of the syntax elements to
> 
> make them more Ada like however.
> 
> 
> You know, Oberon-14 sounds like a nice name for a new programming
> 
> language. :-)
 

A little bit offtopic, but the Go (golang) team is working on a c2go application[1]. Altough it is only used for their compiler, and could possibly not work, the aim is to port 99%+ of *their* C to be ported to Go. Why is this interesting? Go, altough it has a C look and feel, is very close to Oberon. It is C that has all the ambiguous crap. So parsing C is the biggest problem and the way they solve it looks interesting. 

With tools like this it could be possible to rewrite large amounts of C libraries rather quickly.

Oberon is probably the most sane language. It's small feature set allows compilers to become safe and portable with minimum effort.

IMO the biggest problem is: Who is gonna do it? Open Source works rather well when it has a core team of professionals and good architects. Getting things such as this done requires money.

Again IMO it will happen someday. Heartbleed is a good trigger. There are probably a lot more heartbleeds waiting to happen. Right now the stone is on top of the cliff. It only needs a tiny push.

[1] http://talks.golang.org/2014/c2go.slide#1

^ permalink raw reply	[flat|nested] 144+ messages in thread

end of thread, other threads:[~2014-05-14  9:39 UTC | newest]

Thread overview: 144+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-11  2:39 Heartbleed Charles H. Sampson
2014-04-11  7:59 ` Heartbleed Maciej Sobczak
2014-04-11 10:50   ` Heartbleed Pascal J. Bourguignon
2014-04-12  1:46   ` Heartbleed Charles H. Sampson
2014-04-11 12:43 ` Heartbleed kalvin.news
2014-04-11 19:33   ` Heartbleed Simon Clubley
2014-04-12  4:58     ` Heartbleed Shark8
2014-04-12  7:15       ` Heartbleed Nasser M. Abbasi
2014-04-12  9:28         ` Heartbleed Georg Bauhaus
2014-04-12  9:33         ` Heartbleed Georg Bauhaus
2014-04-12 11:42         ` Heartbleed Pascal J. Bourguignon
2014-04-12 15:37           ` Heartbleed Nasser M. Abbasi
2014-04-12 18:56             ` Heartbleed Pascal J. Bourguignon
2014-04-12 20:29               ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 20:34               ` Heartbleed Dmitry A. Kazakov
2014-04-12 20:47                 ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 20:53                   ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-15 10:02                 ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-15 12:35                   ` Heartbleed Dmitry A. Kazakov
2014-04-12 21:57               ` Heartbleed Niklas Holsti
2014-04-13 13:08                 ` Heartbleed Georg Bauhaus
2014-04-13 13:55                   ` Heartbleed Pascal J. Bourguignon
2014-04-13 15:13                     ` Heartbleed Dennis Lee Bieber
2014-04-13 15:36                       ` Heartbleed Nasser M. Abbasi
2014-04-12 18:39           ` Heartbleed Simon Wright
2014-04-12 19:15             ` Heartbleed Pascal J. Bourguignon
2014-04-12 19:18               ` Heartbleed Pascal J. Bourguignon
2014-04-12 20:40               ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 20:44               ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 21:31               ` Heartbleed Niklas Holsti
2014-04-12 14:58         ` Heartbleed Dennis Lee Bieber
2014-04-12 18:28           ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 18:22       ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 18:38       ` Heartbleed Simon Clubley
2014-04-12 20:24         ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-12 21:48           ` Heartbleed Simon Clubley
2014-04-17  6:15         ` Heartbleed Jacob Sparre Andersen
2014-04-17 15:55           ` Heartbleed Shark8
2014-04-17 21:01           ` Heartbleed Simon Clubley
2014-04-17 21:51             ` Heartbleed Shark8
2014-04-17 21:54               ` Heartbleed Alan Jump
2014-04-17 22:02                 ` Heartbleed Adam Beneschan
2014-04-17 22:35                 ` Heartbleed Simon Clubley
2014-04-17 22:55                   ` Heartbleed Jeffrey Carter
2014-04-18  8:48                     ` Heartbleed Simon Clubley
2014-04-18 18:02                       ` Heartbleed Jeffrey Carter
2014-04-18 20:31                         ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-18 23:16                           ` Heartbleed Pascal J. Bourguignon
2014-04-19 18:29                             ` Heartbleed Simon Clubley
2014-04-21 22:50                             ` Heartbleed Randy Brukardt
2014-04-18  1:38                   ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-18 14:59                     ` Heartbleed Nasser M. Abbasi
2014-04-18 17:12                       ` Heartbleed Alan Browne
2014-04-18 17:30                       ` Heartbleed J-P. Rosen
2014-04-18 18:04                         ` Heartbleed Jeffrey Carter
2014-04-18 18:34                           ` Heartbleed Simon Clubley
2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
2014-04-18 21:35                             ` Heartbleed Dennis Lee Bieber
2014-04-18 22:20                               ` Heartbleed Jeffrey Carter
2014-04-18 22:41                                 ` Heartbleed Adam Beneschan
2014-04-19 15:53                                   ` Heartbleed Dennis Lee Bieber
2014-04-18 18:37                           ` Heartbleed Alan Browne
2014-04-18 20:45                             ` Heartbleed Jeffrey Carter
2014-04-18 21:06                               ` Heartbleed Alan Browne
2014-04-18 22:20                                 ` Heartbleed Jeffrey Carter
2014-04-19 14:04                                   ` Heartbleed Alan Browne
2014-04-18 20:49                             ` Heartbleed Shark8
2014-04-18 21:07                               ` Heartbleed Alan Browne
2014-04-18 22:56                           ` Heartbleed Nasser M. Abbasi
2014-04-19  4:27                             ` Heartbleed tmoran
2014-04-18 21:17                   ` Heartbleed Shark8
2014-04-19 18:59                     ` Heartbleed Simon Clubley
2014-04-19 19:21                       ` Heartbleed Shark8
2014-04-18  1:29             ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-18 10:42               ` Heartbleed J-P. Rosen
2014-04-19 11:50         ` Oberon and Wirthian languages (was: Heartbleed) Ludovic Brenta
2014-04-19 12:46           ` Oberon and Wirthian languages Georg Bauhaus
2014-04-19 19:17             ` Simon Clubley
2014-04-19 19:25               ` Shark8
2014-04-19 16:35           ` Oberon and Wirthian languages (was: Heartbleed) Yannick Duchêne (Hibou57)
2014-04-19 19:32             ` Simon Clubley
2014-04-19 22:30               ` Dennis Lee Bieber
2014-04-19 22:35                 ` Oberon and Wirthian languages Alan Browne
2014-04-19 16:53           ` Georg Bauhaus
2014-04-19 17:32           ` Simon Wright
2014-04-19 17:35           ` Jeffrey Carter
2014-04-19 18:06             ` Yannick Duchêne (Hibou57)
2014-04-19 18:53             ` Shark8
2014-04-19 20:08               ` Simon Clubley
2014-04-19 22:16                 ` Simon Clubley
2014-04-21 13:06           ` Oberon and Wirthian languages (was: Heartbleed) Simon Clubley
2014-04-21 18:13             ` Simon Clubley
2014-04-21 18:45               ` Oberon and Wirthian languages Shark8
2014-04-21 23:26                 ` Randy Brukardt
2014-04-22  0:21                   ` Simon Clubley
2014-04-22  5:48                   ` Shark8
2014-04-21 18:16             ` Jeffrey Carter
2014-04-22  0:34               ` Simon Clubley
2014-04-22  3:01                 ` Jeffrey Carter
2014-04-22 23:31                   ` Randy Brukardt
2014-04-22  6:41                 ` Simon Wright
2014-04-22 12:25                   ` Simon Clubley
2014-04-22 19:13                     ` Niklas Holsti
2014-04-22 20:46                       ` Simon Clubley
2014-04-22 23:38                         ` Randy Brukardt
2014-04-23 12:16                           ` Simon Clubley
2014-04-23 20:55                             ` Simon Wright
2014-04-24  0:20                               ` Simon Clubley
2014-04-24 13:05                                 ` Niklas Holsti
2014-04-24 18:51                                   ` Simon Clubley
2014-04-24 20:11                                     ` Niklas Holsti
2014-04-25  1:37                                       ` Randy Brukardt
2014-04-25 21:33                                         ` Simon Clubley
2014-04-25 21:55                                           ` Randy Brukardt
2014-04-25 23:16                                             ` Dennis Lee Bieber
2014-04-26  6:31                                               ` Niklas Holsti
2014-04-26  0:23                                             ` Nasser M. Abbasi
2014-04-26  2:46                                             ` Shark8
2014-04-26  2:52                                               ` Shark8
2014-04-26  6:37                                               ` Niklas Holsti
2014-04-26  6:19                                             ` Georg Bauhaus
2014-04-26  6:35                                               ` Georg Bauhaus
2014-04-26  6:42                                               ` Niklas Holsti
2014-04-26 17:15                                                 ` Simon Clubley
2014-04-26  6:29                                             ` Niklas Holsti
2014-04-26  7:36                                               ` Dmitry A. Kazakov
2014-04-26  7:52                                                 ` Georg Bauhaus
2014-04-26  8:09                                                   ` Dmitry A. Kazakov
2014-04-26 18:32                                                 ` Simon Clubley
2014-05-08  2:36                                               ` Randy Brukardt
2014-05-08 17:48                                                 ` Niklas Holsti
2014-05-08 19:22                                                   ` Randy Brukardt
2014-04-26  7:23                                             ` Simon Wright
2014-04-26  9:27                                               ` Niklas Holsti
2014-04-26 12:34                                                 ` Simon Wright
2014-04-27 10:38                                                   ` Simon Wright
2014-04-27 15:36                                                     ` Simon Clubley
2014-04-27 14:26                                               ` Brian Drummond
2014-04-22 23:30                 ` Randy Brukardt
2014-04-23 12:17                   ` Simon Clubley
2014-05-14  9:39         ` Heartbleed gvdschoot
2014-04-12 22:01       ` Heartbleed Yannick Duchêne (Hibou57)
2014-04-18 17:58         ` Heartbleed Alan Browne
2014-04-18 17:24 ` Heartbleed - attacks? Alan Browne

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox