
Ada: a C Developer's Perspective - wtracy
http://www.methodsandtools.com/archive/ada.php
======
sp0ck
It's not only a language that is key to success. Libraries. I searched for
LDAP support for ADA (old protocol used by many companies). I found library
([http://savannah.nongnu.org/projects/adaldap/](http://savannah.nongnu.org/projects/adaldap/))
with latest news from 2002 and CVS repo :) Then I search for SNMP (another
dinosaur still in wildly use) - similar result.

Second - many solutions/libraries are purely commercial. You need basic open
protocols support by default /free. Otherwise such great language will still
be at it's niche.

Rust is on a good path to became XXI century successful Ada :)

~~~
fghvbnvbnfe
This idea that Rust and Ada are somehow alternatives continually pops up, and
I still don't understand it.

They each have their own ideas on what "safety" is, and how to address it.
I'll admit I'm biased towards Ada, but I think it is pretty safe to say that
"Rust safety" is a subset of "Ada safety" \- but Rust does it's section and
run further with it than Ada.

Rust is obsessed with memory safety. That's it's thing. Unsafe code aside,
it's memory safe. And it tackles some concurrency issues too.

Ada is more concerned with overall correctness, particularly in terms of
types, where the types are semantically meaningful. And it goes further and
dips into memory safety and concurrency. It doesn't such an extreme tact as
Rust, but it does an awful lot to provide good options that allow you to avoid
many issues. And it generally tries to make programs easy to understand. And
more - some of which, as the article notes, are really quite wonderful for
going really low level.

Personally I see the most value in the semantic type safety. That's really
been, in my own experience, where Ada has helped me the most. Many of the
other features are also great. I just don't see almost any of it in Rust. You
can sometimes get stronger guarantees about a few things and you kind of lose
everything else.

How is that an alternative or a replacement? Yet this idea is everywhere.

~~~
Manishearth
I don't really understand the "Rust is obsessed with memory safety" meme.

When pitching Rust to others of course memory safety and thread safety get
hyped a lot; because it's talking about something that most languages just
can't do -- safety without compromise.

But actually ... memory safety is a small part of the reasons why I like Rust,
and there are plenty of other cool bits in the language. It stands out a bit
because it's _different_ , but that doesn't make it the end-all goal.

~~~
atilaneves
Safety without compromise doesn't exist. Rust does what it does well, but at
significant cost in developer time. I'd rather use a garbage collector, it's
much much simpler and fine for 99.9% of use cases.

~~~
tmccrmck
Garbage collection does make things easier, prettier, and simpler. BUT there
are many problem domains in which a GC can not be used. A browser being a
prime example...

~~~
tom_mellior
Maybe you can find a better "prime example" than browsers, which nowadays are
mostly known as execution engines for JavaScript, _a garbage-collected
language_.

But frankly, I doubt that you can. Others will say "operating system kernels",
but people are happily writing OS kernels in OCaml, so _< shrug>_.

Yet others will say "safety-critical hard real-time tiny microcontrollers
without an MMU" (one of Ada's domains), but on those systems you don't want to
do dynamic allocation anyway, so the question of GC or not is kind of moot.

I've said it before, I'll say it again: Rust would be a better language if it
had a GC _and_ the possibility of marking certain program parts as GC-free
(the way it allows you to mark certain parts as unsafe).

~~~
theossuary
That's kind of his point, you can't write a GC language interpreter in a GC
language forever, eventually you need a non-GC language to actually implement
the GC in. So in this way writing a Javascript executor in a GC language
wouldn't really make sense, you're just adding needless layers of abstraction
(at a serious performance cost). So I think a browser is an excellent example
of an application which can't really be written in a GC language. Other
examples might be Databases and realtime applications.

~~~
tom_mellior
> you can't write a GC language interpreter in a GC language forever,
> eventually you need a non-GC language to actually implement the GC in

Here's PyPy's GC, implemented in Python:
[https://github.com/tycho/pypy/tree/master/rpython/memory/gc](https://github.com/tycho/pypy/tree/master/rpython/memory/gc)

(I haven't looked at it in detail.)

Anyway, even if you absolutely _had_ to use a non-GC language to implement a
GC, that would not preclude writing 99% of the browser in a GC language and
only the GC in something else.

~~~
theossuary
How do they compile/interpret PyPy's GC, is the compiler/interpreter written
in a GC language? I said you can't do it forever, eventually you need to drop
to a non-GC language (I feel very certain of this, so if I'm wrong I'd really
like to know).

Also, why would implement GCs multiple times at different levels of
abstraction in the stack, other than for something specific like PyPy which is
specific like designing an interpreter to help test language features quickly?

~~~
tom_mellior
PyPy is originally bootstrapped on the C Python interpreter, but it can then
interpret and compile itself without relying on CPythob anymore. If you
insist, then once PyPy is bootstrapped, the "drop to a non-GC language" is its
process of having compiled the garbage collector's Python code to machine
code.

But you're still wrong on this drop being necessary, I think. You can do it
just fine in a language with GC that _also_ allows you to allocate a block of
memory that is not considered by the GC.

~~~
theossuary
> But you're still wrong on this drop being necessary, I think. You can do it
> just fine in a language with GC that also allows you to allocate a block of
> memory that is not considered by the GC.

I think it's a bit disingenuous to say a "GC language compiled a GC language"
when the compiler used non-GC portions of the language to do it. You're right,
I should have said "A language which can work without a GC" instead of "a non-
GC language;" but I think the spirit of my comment was clear.

That said I think what you said above is right, and non-GC code is really only
necessary in the hot parts of an application (and applications that can't use
dynamic allocation for whatever reason, but that's another discussion). Rust
is even working on adding GC support [1] (albeit very slowly, as they should).
That said non-GC languages (or at least the ability to write code that doesn't
use a GC) is still necessary in many industries for many reasons; that isn't
going to change for a long time, if ever.

[1]: [https://manishearth.github.io/blog/2016/08/18/gc-support-
in-...](https://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-
design/)

------
ewanm89
Here is my list of shortcomings when it comes to Ada

1) Ada is not a magic bullet, the seminal case study of why computer bugs are
bad taught in CS courses around the world is the failed 1996 Ariane 5 rocket
launch where the rocket veered off course and then exploded due to a software
error that caused it not to understand the data it was getting from a sensor.
More recently there are plenty of demonstrations of poor security in
commercial plane avionics systems.

2) Ada is not easy to write, it's around the level of C I grant you, but it is
not easy by any means, more importantly it is complex not simple. Each of
those "features" like assert adds a layer of complexity to the system making
it far harder for the programmer to write for. I think we all agree if we
could program with simple functions that each do one thing and one thing well
then combine those functions makes for a much simpler language and easier to
think about.

3) Overhead, each of these features like assert adds a lot of overhead into
the system, this is just not viable in a lot of systems, whats more those
features are optional, so it is the first thing to drop where possible.

4) Toolchain and library support, most of us can't afford expensive toolchains
and libraries, we don't work for very rich government contractors. Also we
need libraries and toolchains are well maintained. Java has a massive standard
library and a lot of free 3rd party libraries available, C/C++, python, perl,
ruby, rust, javascript, c#, clojure... are all similar in that they have well
maintained tool chains and good library support freely available either
directly by language authors or from a third party.

~~~
sgift
1) and 3) are related as far as I remember - Ada WOULD have found the problem
which was responsible for the Ariane 5 launch failure, but the section
involved was speed critical, so the asserts were dropped to make the code run
fast enough.

Sad reality: The best security features in the world are useless if they are
too slow for your use case.

~~~
rcxdude
Ironically, it's also Ada's asserts which contributed to the failure (though
far from the root cause): The result of the erroneous calculation wasn't
actually used, so just ignoring it like C would have would have been fine. It
was the fact that the wrong cast caused the software to abort which resulted
in the crash.

~~~
AstralStorm
This is why static checking is better than runtime checking. Rust has some,
but not enough. What is needed is something like Isabelle sledgehammer,
quickcheck and metis logic and higher function correctness checkers. (Yes,
Haskell has a bit more primitive version of Quickcheck.)

~~~
kqr
That's basically what SPARK Ada is.

~~~
AstralStorm
A smaller less featured one, but very useful nonetheless. (Specifically,
sledgehammer is superior as a checker and automated proof library check is
also invaluable in simplification.)

Technically, Why3 (intermediate language and prover manager used in SPARK for
verification) can interface with Isabelle too. I should try it out.

More edit: someone has done it, called HOL-SPARK. Excellent.

------
samuell
Ada ticks a fair amount of the boxes in the "Interesting statically compiled
languages by wishlist features" google doc, which I started, and had some
crowd-sourcing help to fill in:

[https://docs.google.com/spreadsheets/d/1BAiJR026ih1U8HoRw__n...](https://docs.google.com/spreadsheets/d/1BAiJR026ih1U8HoRw__nzbCSFnnHicWrjxpW5l6-O3w)

(Would be cool if we could fill out those remaining white cells btw ;) )

------
aamederen
I had a strange internship topics involving Ada. I tried to run a huge program
(a simple stdio wrapper around a huge library actually) on an Android machine
(Android 2.3, ARM). At that time, the only ADA compiler for ARM was available
on BSD so I had used a Windows machine for development and a OpenBSD laptop
for compiling the wrapper.

The subtyping feature I love the most. You see the benefit when you need to
call a function which is taking many numeric arguments, all of them is a
subtype so you can't give the arguments in the wrong order (latitude and
longitude for example).

~~~
krylon
> The subtyping feature I love the most.

I only have very little experience with Ada, but being able to define a type
whose values are integers in the range, say, 1 .. 7, to represent days of a
week was an eye opener.

~~~
dbrgn
Range types are probably the main thing I miss from the Rust type system.

But even without range constraints, wrapper types (called newtypes in Haskell
and Rust) are great. Let's say you have a function that accepts a temperature.
A temperature is a float, but you want to prevent the user from mixing up
celsius and fahrenheit.

This is what newtype looks like in Rust:

    
    
      struct Celsius(pub f64);
      struct Fahrenheit(pub f64);
      fn print_celsius(temperature: Celsius) {
        println!("Temperature is {}", temperature.0);
      }
    

It will fail to compile if you accidentally pass a Fahrenheit value to
`print_celsius`, but at compile time all values are optimized down to plain
floats, without any runtime cost.

More programming languages should adopt this concept :)

~~~
wBI8j2bsb
This is exactly what C does.

    
    
      #include <stdio.h>
    
      typedef struct { double v; } Celsius;
      typedef struct { double v; } Fahrenheit;
    
      void
      print_celsius(Celsius temperature) {
          printf("Temperature is %f", temperature.v);
      }
    
      void
      compile_error(Fahrenheit temperature)
      {
          print_celsius(temperature);
      }
    

I suspect LLVM will clean this up to plain floats as well.

~~~
tom_mellior
Whether any compiler "cleans this up" depends in the system's ABI; parameter
calling conventions are not up to the compiler to decide (unless it can prove
that a given function cannot be called from code it does not control).

That said, yes, modern ABIs for modern machines usually pass single-element
structures of primitive types in registers of the appropriate type. x86
(32-bit) is not modern in this sense: depending on the exact ABI used, these
structures might well be passed on the stack or in an integer register.

~~~
jononor
Or if the calls are inlined. Not sure if say Rust can/does this more
aggresively than C or C++ (or vica versa).

------
jcadam
I worked with Ada for several years on a military satellite program (simulator
software for various satellite subsystems). Specifically, I was using Ada95 on
SPARC/Solaris, and later got to work on a project (with a different employer)
to port much of the same system to x86/Linux with Ada2005 (so many endian
issues :shudder:). This was in the mid-late 2000s.

I remember when I told my mother (also a software engineer) that I got a job
using Ada, she laughed and handed me all of her old Ada83 books (which are
still on my bookshelf at work). I'm doing backend services in JVM-land these
days, which I enjoy a bit more (not to mention I'm building a more portable
skill-set) :)

------
reacweb
"Code should be easy to write, easy to read, easy to maintain, and most
importantly, it should be reliable". Ada is not easy to write. Perl is easy to
write (but not easy to read or maintain).

When I was student, Ada was the main language at my school. It was used the
first year to teach algorithms and the second year to teach parallelism.
During the first year, I have also learned C by myself for curiosity. After
the summer holidays between first and second year, I had forgotten most of the
syntax needed to start a new program in Ada, but I was remembering perfectly
well how to code in C.

Even After 8 years of usage of Ada, I still needed the user manual regularly.
After less than 1 year of usage of C, I could sell my R&K.

~~~
reacweb
As a disclaimer, I love Ada (and Perl) and I regularly despise C++.

~~~
e12e
How would you rate your young self on the "hello-my-name-is-scale", as I like
of to think of Stroustrup's notes in his short article from 1999[1] -- in C
and Ada at the time? Would your C code "blow up" differently from your Ada
code, do you think?

I'm not much of a fan of C++ myself, but I often find myself looking back at
that short note, as a pretty valid criticism of how C tend to mix some parts
that _appear_ simple with some very complex actual behavior (eg: printing
strings, reading in strings and integers).

[1]
[http://www.stroustrup.com/new_learning.pdf](http://www.stroustrup.com/new_learning.pdf)
"Learning Standard C++ as a New Language"

------
samuell
For anyone interested in learning more, or helping collect the best Ada links,
I started out on an "Awesome Ada" list some time ago:

[https://github.com/samuell/awesome-ada](https://github.com/samuell/awesome-
ada)

------
mhd
Does someone have experience with Ada 2012s Design By Contract support
(including tooling, preferably for GNAT)?

Eiffel is yet another Pascal-ish language whose passing I lament, and lately
I've been seriously considering giving Ada another try, given that Modula-3
and Oberon won't exactly come back to life miraculously, and I'm still a bit
dubious about all the new kids on the block.

~~~
kqr
In a hobby capacity, yes. It's hard to go back to programming without
contracts and invariants once I've had a taste for it.

------
evacchi
It's such a pity these days there is no modern tool chain/workflow for Ada (or
C++ for that matter). I mean, a package manager, a build tool with integrated
dependencies. As far as I know, there is very little open source software for
Ada. It's a shame, because I feel like the language would become more
mainstream, if only better tooling was easily available.

~~~
Raphael_Amiard
There are a few people at AdaCore working on this, we're trying to bootstrap
it and involve the community, more about that soon we hope :)

The build tool, GPRBuild is already a step above makefiles, and personally I
find it very convenient to work with.

~~~
e12e
I'm sure I'm not the only one that would appreciate an up-to-date, real-world
best-practices "How I start"[1]-article for Ada - from people that actually
write non-trivial Ada code and have a stake in project setup, packaging etc.

[1] [http://howistart.org/](http://howistart.org/)

------
nraynaud
I wanted to use Ada for a personal project, it's not what it's cracked to be.
Some registers are hard to map in the language.

The timing side of things is extremely misleading: there are time primitives
in the language, but you don't know if the implementation of the runtime will
actually reach your constraint, and you won't be warned (it took me 2 days on
the scope before understanding that it was not my code that was the issue).

if you want to toy around, I have started an Intellij Plugin:
[https://github.com/nraynaud/ada-intellij](https://github.com/nraynaud/ada-
intellij)

Some registers of the STM32 are mapped here:
[https://github.com/nraynaud/bldc_ada/tree/master/src](https://github.com/nraynaud/bldc_ada/tree/master/src)

------
Xophmeister
Is Ada losing ground to dependently typed languages, or are these still too
"academic" for production use?

~~~
Raphael_Amiard
Ada as an ecosystem has it's own alternative, SPARK. It's not a dependently
typed language, but you can go just as far with it using pre and post
conditions, and ghost code, insofar as what you can prove.

You can see here for more information:

[http://www.spark-2014.org/](http://www.spark-2014.org/)
[http://docs.adacore.com/spark2014-docs/html/ug/en/tutorial.h...](http://docs.adacore.com/spark2014-docs/html/ug/en/tutorial.html)

------
koja86
Ada caught my attention recently. I am just curious - how is Ada job market?
Any jobs other than military projects?

~~~
tom_mellior
It's also used in other embedded systems. Based on public talks, Thales
([https://en.wikipedia.org/wiki/Thales_Group](https://en.wikipedia.org/wiki/Thales_Group))
seems to be using it a lot internally, and not everything they do is military.

Here's a CubeSat operating system written in SPARK/Ada:
[http://www.cubesatlab.org/CubedOS.jsp](http://www.cubesatlab.org/CubedOS.jsp)

------
flukus
So how does Ada go speed wise (real world not micro benchmarks)? Were/are
there legitimate reasons to opt for c over Ada?

~~~
pavlov
On early PCs, Pascal and C were pretty much tied in popularity. Both were free
to implement, and small enough that you could make a fast compiler on a
typical PC with only 256-640 kB RAM.

C won because it was more flexible and was chosen by Microsoft, but Pascal
definitely had a strong following (it was the original Mac's API language, and
on PC it was a major contender thanks to the nice and fast Turbo Pascal IDE).

Ada was a complicated and rigid language designed by a Department of Defense
committee. That was not great PR for those early individualist PC users. (Who
wants to program in the language of "The Man"?)

If Pascal was a Cessna and C was a Learjet, then Ada was the F-35 -- complex,
expensive, late.

~~~
flukus
Was anyone building things like operating systems or drivers in pascal? AFAIK
that was always the realm of c. Turbo pascal was the first language I was
taught, I have a soft spot for it but I think it had largely faded away by
then.

~~~
steveklabnik
[http://wiki.osdev.org/Pascal#Past_uses_in_OS_development](http://wiki.osdev.org/Pascal#Past_uses_in_OS_development)

I have vague memories of trying to write MacOS apps in CodeWarrior and needing
to mark C functions as having a Pascal ABI...

------
yoz-y
I am going to be that guy and say: Poorly compressed JPEG images for text
examples?

------
bitwize
Puppy 1: And so, in conclusion, we have determined that Ada provides
sufficient safety guarantees and features for our embedded system needs. Any
questions?

Puppy 2: Yes, I have a question. Why didn't you use Rust?

Puppy 1: That's a good question. While Rust looks promising, we felt it was
too immature for our needs and decided to go with the time-tested,
standardized semantics and extensive tooling available with Ada.

Puppy 2: Rust has a borrow checker. That makes it 100% safe.

Puppy 1: Leaving aside the fact that no language is 100% safe, safety is a
complicated topic and you can't make strong statements like that about it.
Does Rust's borrow checker enforce arbitrary program invariants?

Puppy 2: ...Rust has a borrow checker. That makes it safe. Borrow semantics is
the secret ingredient in the memory safety sauce.

~~~
eutectic
Don't you find it's so much easier to argue against yourself? None of those
pesky unpredictable arguments to worry about.

~~~
bitwize
You do realize that that wasn't intended to be a serious argument about the
points of Ada vs. Rust... right? Have you seen "MongoDB is web scale"
([https://youtu.be/b2F-DItXtZs](https://youtu.be/b2F-DItXtZs))?

