[HN Gopher] A Random Walk Through Ada (2014)
       ___________________________________________________________________
        
       A Random Walk Through Ada (2014)
        
       Author : okl
       Score  : 48 points
       Date   : 2024-11-09 00:57 UTC (22 hours ago)
        
 (HTM) web link (cowlark.com)
 (TXT) w3m dump (cowlark.com)
        
       | guenthert wrote:
       | > It being a one-pass compiler bugs me (there is no excuse for a
       | modern language to require forward declarations).
       | 
       | He refers to the need for forward declarations as "one-pass
       | compiler". Historically at least, Ada compilers were infamous for
       | requiring many passes and being consequently slow.
       | 
       | Whether it is still acceptable for a programming language to
       | require forward declaration seems to me rather a matter of
       | personal taste. Sure, compilers improved and there's plenty of
       | memory for them to use, but human programmers' capacity increased
       | little, if any, I'd think. I think of those forward declarations
       | as form of double-entry bookkeeping.
        
         | kevlar700 wrote:
         | Interesting. I love Ada and these historical doomed to repeat
         | ourself facts are interesting like Ada books from the 80s
         | talking about AI. Before I switched from Go to Ada I actually
         | used to use var upfront out of preference.
        
       | roland35 wrote:
       | I once did an engineering camp at the Air Force academy and in
       | one of the classes we programmed Lego mindstorms with Ada -
       | something like https://www.adacore.com/academia/projects/real-
       | time-mindstor...
       | 
       | I do wish we had better options for embedded! Even C++ isn't
       | making much headway against C when it comes to programming
       | microcontrollers.
        
         | kevlar700 wrote:
         | Ada is so good for embedded. Loving it.
        
         | pjmlp wrote:
         | Mikroe is still in business selling BASIC and Pascal compilers
         | for microcontrollers, so some do pay for them.
        
       | adrian_b wrote:
       | There is a phrase that might be confusing for those who do not
       | know Ada:
       | 
       | "As a historical note, earlier versions of Ada forbade reading
       | from out variables, which allowed more efficient calling
       | conventions, but modern Ada allows it because otherwise people
       | went insane."
       | 
       | What is meant is that the "out" parameters behave like local
       | variables without initializers, which upon entry into a function
       | are likely to have invalid values.
       | 
       | Therefore you cannot read an "out" parameter before assigning a
       | value to it. After the first assignment, it can be read or
       | written at any time before the function returns.
       | 
       | Depending on the type, an "out" parameter is implemented as
       | either a CPU register whose value is unknown upon function entry
       | or as a reference to a memory area allocated in the caller, but
       | uninitialized.
       | 
       | The specification of the function parameters as "in", "out" or
       | "in out" and the irrelevance and transparency of how the compiler
       | chooses to pass the parameters is one of the best features of
       | Ada.
       | 
       | This has not been invented by the creators of Ada, but it has
       | been invented by some anonymous Department of Defense employees
       | or contractors.
       | 
       | This feature was included in the DoD "Requirements for High Order
       | Computer Programming Languages", "IRONMAN" from the July 1977
       | revision. It was probably already present in the first version of
       | "IRONMAN" from January 1977.
       | 
       | It is a huge mistake in the design of almost all programming
       | languages that have appeared after Ada that they do not include
       | this feature.
       | 
       | The lack of distinction between "out" and "in out" parameters has
       | serious consequences especially for the object-oriented
       | languages. The lack of this feature has caused a very large part
       | of the complexity of C++ and also most of the performance
       | problems of the C++ versions from before 2011.
       | 
       | When "out" and "in out" parameters are distinguished, there is no
       | need for the existence of constructors as a separate concept. Any
       | ordinary function with an "out" parameter can be used wherever
       | C++ requires a dedicated constructor. Instead of constructors, it
       | is enough to have an identifier convention for functions that
       | should be called by the compiler when you want implicit
       | initialization or implicit conversions.
       | 
       | Moreover, there is no need to care about "copy" semantics and
       | "move" semantics or about temporaries which are or which are not
       | generated by the compiler. It is easy for the compiler to always
       | choose the best implementation without programmer intervention,
       | when it knows the correct parameter modes for the functions.
        
         | Thorrez wrote:
         | >When "out" and "in out" parameters are distinguished, there is
         | no need for the existence of constructors as a separate
         | concept. Any ordinary function with an "out" parameter can be
         | used wherever C++ requires a dedicated constructor. Instead of
         | constructors, it is enough to have an identifier convention for
         | functions that should be called by the compiler when you want
         | implicit initialization or implicit conversions.
         | 
         | Why do we need "out" vs "in out" parameters for this? Why can't
         | a function that returns the object work just as well? And "an
         | identifier convention for functions that should be called by
         | the compiler when you want implicit initialization or implicit
         | conversions" seems essentially the same as constructors to me.
         | 
         | >Moreover, there is no need to care about "copy" semantics and
         | "move" semantics or about temporaries which are or which are
         | not generated by the compiler. It is easy for the compiler to
         | always choose the best implementation without programmer
         | intervention, when it knows the correct parameter modes for the
         | functions.
         | 
         | How would I implement something like std::vector with deep copy
         | and move support of its contained objects without writing copy
         | and move constructors (or operators)? There needs to be code
         | saying "allocate a new block of memory and copy all the
         | elements to that new block", and code saying "just copy the
         | pointer, and set the other pointer to null". Are you saying the
         | implementer would still write that code, just not in
         | constructors/operators? How is that better?
        
           | pyjarrett wrote:
           | The big reason for `out` only is "I want to write here, but I
           | don't care about the initial value." It's a more explicit
           | version of the C++ `Foo& outFoo` output parameter paradigm.
           | 
           | > When "out" and "in out" parameters are distinguished, there
           | is no need for the existence of constructors as a separate
           | concept.
           | 
           | I don't agree with this. You can get I need to do things
           | "post-init" with controlled types, or use a `return X : Thing
           | do ... end return` block. Constructors help ensure
           | invariants. You can make a type `is private` to prevent
           | instantiation, only allowing creation via functions (sort of
           | like Rust `new` associated functions), or initialization via
           | an `out` param. It's OK but not perfect, but you can also tag
           | on a `Type_Invariant` aspect if there are conditions which
           | have to be met by a type. My big problem with Controlled
           | types is that forces a type to be `tagged` (i.e. it has a
           | vtable) which means it affects storage layout of values of
           | that type, which isn't a problem in C++.
           | 
           | You can forbid copies by making something a `limited` type,
           | but you'd have to write your own "Move" equivalent, and some
           | of the containers have `Move` subprograms implemented to
           | transfer contents. Limited types might elide the copy when
           | returned from a function, but it's been a while since I
           | looked at those rules.
        
           | adrian_b wrote:
           | In C++ or similar languages, where the function parameters
           | behave semantically as either "in" or "in out" parameters, a
           | function that returns an object must have already created
           | somehow the object.
           | 
           | Therefore calling a function just adds a task of invoking a
           | constructor also into the function, it cannot replace a
           | constructor.
           | 
           | In C++, an object cannot be created by assigning a value to
           | it, because the left hand parameter of the assignment
           | operator is an "in out" parameter, like for any other
           | function, so it is assumed that it already has a value of the
           | type of that object.
           | 
           | Therefore an assignment operator must execute the equivalent
           | of invoking a destructor for the target of the assignment,
           | followed by the invocation of a copy constructor.
           | 
           | Attempting to assign a value to memory allocated but not
           | initialized will attempt to invoke a destructor for an
           | invalid object value.
           | 
           | The constructors are the only C++ functions that implicitly
           | have a result which is an "out" parameter, not an "in out"
           | parameter, like the other functions.
           | 
           | Because the memory where the result of the constructor will
           | be placed is not initialized, no destructor must be invoked
           | for it, so all will be OK.
           | 
           | All these rules about when to use constructors and when to
           | use functions and the need to have duplicate almost identical
           | in meaning functions for certain purposes, e.g. copy
           | constructors and assignment operators, complicates a lot C++.
           | 
           | Any copy or deep copy operations would be implemented very
           | simply, just by copying what needs to be copied.
           | 
           | There would be no need for "move" operations of any kind,
           | which are just a trick to avoid the inefficient code
           | generated by compilers when the semantics for some parameters
           | is "in out" when what would have really been needed is "out".
           | 
           | Specifying that some functions are not normal functions, but
           | constructors, or that some operations have "move semantics"
           | is just an extremely complicated way to specify that some
           | function parameters are "out", not "in out". Besides being
           | hard to understand, these tricks only work in particular
           | cases, instead of being able to specify the mode of any
           | function parameter.
           | 
           | In a language with distinction between "in out" and "out",
           | the mode for the result of assignment is naturally "out" and
           | there is no need for the contortions of C++. In such a
           | language a compiler knows when to invoke destructors and when
           | not to invoke them and it knows when no extra temporaries are
           | needed for computing a complex formula with objects.
        
         | GregarianChild wrote:
         | A different world, but Verilog has in, out and inout
         | parameters, too.
        
       | pyjarrett wrote:
       | I recently started writing Ada again, a couple of years after I
       | did a bunch of projects with it. The amazing things is how easy
       | it is to go back and update old code due to how much semantic
       | information gets embedded in it and how few symbols it uses.
        
       | tolerance wrote:
       | Few things can draw your attention to subjects that you don't
       | understand better than appealing visual design and clear
       | language.
        
       | ajdude wrote:
       | For those interested in trying Ada out, I wrote a a Rustup-like
       | app that installs Ada's package manager (Alire) on macOS and
       | Linux: https://www.getada.dev
       | 
       | It was also featured on HN (194 points | 6 months ago | 117
       | comments: https://news.ycombinator.com/item?id=40132373
       | 
       | I've gone from not having anything Ada related on my computer to
       | installing the toolchain, initiating a project , writing,
       | compiling, and running "Hello World" in less then 2 minutes.
       | 
       | Ada has had something of a resurgence in the last couple years,
       | with the latest standard (2022) officially released and for the
       | first time in a few years, Ada has its own dev room at FOSDEM!
       | https://fosdem.org/2025/news/2024-10-28-devrooms-announced/
       | 
       | There's also a growing community at ada-lang.io with a thriving
       | forum: https://forum.ada-lang.io/
        
       | Jtsummers wrote:
       | https://learn.adacore.com
       | 
       | A collection of less random and more up to date walks through Ada
       | if this piqued your interest. It's been kept up to date with the
       | latest language features and more tutorials. Also, helpfully, has
       | comparative tutorials to see some features side-by-side in Ada,
       | Java, C++, and C.
        
       | dang wrote:
       | Related:
       | 
       |  _A Random Walk Through Ada (2014)_ -
       | https://news.ycombinator.com/item?id=12850919 - Nov 2016 (88
       | comments)
       | 
       |  _A Random Walk Through Ada (2014)_ -
       | https://news.ycombinator.com/item?id=9674408 - June 2015 (14
       | comments)
        
       ___________________________________________________________________
       (page generated 2024-11-09 23:01 UTC)