7 ms·
Ada has some really good ideas which its a shame never took off or got used outside of the safety critical community that mostly used it. The ability to make nu
by PaulKeeble 1y ago
Ada has some really good ideas which its a shame never took off or got used outside of the safety critical community that mostly used it. The ability to make number types that were limited in their range is really useful for certain classes of bugs. Spark Ada was a relatively easy substandard to learn and apply to start to develop software that was SIL 4 compliant.
I can't help but feel that we just went through a huge period of growth at all costs and now there is a desire to return, after 30-years of anything goes, to trying to make software that is safer again. Would be nice to start to build languages based on all the safety learnings over the decades to build some better languages, the good ideas keep getting lost in obscure languages and forgotten about.
- Veliladon 1y ago> The ability to make number types that were limited in their range is really useful for certain classes of bugs. Yes! I would kill to get Ada's number range feature in Rust!
- pjmlp 1y agoThat feature is actually from Pascal, and Modula-2, before making its way into Ada. For some strange reason people always relate to Ada for it.
- Veliladon 1y agoFor me it's because I learned Ada in college. 18 year old me couldn't appreciate how beautiful a language it is but in my 40s I finally do.
- awesome_dude 1y ago2000-2005 College was teaching Ada? 2005-2010 my college most interesting (in this direction) language was Haskell. I don't think that there was any other language (like Ada) being taught)
- rus20376 1y agoAda is sometimes taught as part of a survey course in Programming Languages. That’s how I learned a bit about it.
- firesteelrain 1y agoYes, I learned it in a course that surveyed a bunch of different languages like Ada, Standard ML, and Assembly
- jdrek1 1y agoI would guess that Ada is simply more known. Keep in mind that tech exploded in the past ~3.5 decades whereas those languages are much older and lost the popularity contest. If you ask most people about older languages, the replies other than the obvious C and (kind of wrong but well) C++ are getting thin really quickly. COBOL, Ada, Fortran, and Lisp are probably what people are aware of the most, but other than that?
- wpollock 1y agoYou've forgotten about BASIC, SNOBOL, APL, Forth, and PL/1. There were many interesting programming languages back then. Good times!
- aworks 1y agoThe first five languages I learned back in the 70s: FORTRAN, Pascal, PL/I, SNOBOL, APL. Then I was an Ada and Icon programmer in the 80s. In the 90s, it was C/C++ and I just never had the enthusiasm for it.
- prerok 1y agoI found Pascal more readable as a budding programmer. Later on, C's ability to just get out of the way to program what I wanted trumped the Pascal's verbosity and opinionatedness. I admit that the terseness of the syntax of C can be off-putting. Still, it's just syntax, I am sorry you were disuaded by it.
- dreamcompiler 1y agoIcon (which came from SNOBOL) is one of the few programming languages I consider to embody truly new ideas. (Lisp, Forth, and Prolog are others that come to mind.) Icon is an amazing language and I wish it was better known.
- failingforward 1y agoYou probably know this but, for anyone else who is interested, the easiest way to get a feel for Icon nowadays may be through its descendant Unicon which is available at unicon.org.
- sehugg 1y agoTurbo Pascal could check ranges on assignment with the {$R+} directive, and Delphi could check arithmetic overflow with {$Q+}. Of course, nobody wanted to waste the cycles to turn those on :)
- pjmlp 1y agoMost Pascal compilers could do that actually. Yeah not wanting to waste cycles is how we ended up with the current system languages, while Electron gets used all over the place.
- prerok 1y agoI would argue that was one of the reasons why those languages lost. I distinctly remember arguments for functions working on array of 10. Oh, you want array of 12? Copy-paste the function to make it array of 12. What a load of BS. It took Pascal years to drop that constraint, but by then C had already won. I never ever wanted the compiler or runtime to check a subrange of ints. Ever. Overflow as program crash would be better, which I do find useful, but arbitrary ranges chosen by programmer? No thanks. To make matters worse, those are checked even by intermediate results. I realize this is opinioned only on my experience, so I would appreciate a counter example where it is a benefit (and yes, I worked on production code written in Pascal, French variant even, and migrating it to C was hilariously more readable and maintainable).
- pjmlp 1y agoThankfully instead of overflow, C gets you the freedom of UB based optimizations.
- prerok 1y agoFunny :) It still results in overflow and while you are right that it's UB by the standard, it's still pretty certain what will happen on a particular platform with a particular compiler :)
- ummonk 1y agoNo, optimizing compilers don't translate overflow to platform-specific behavior for signed integers - since it's UB they'll freely make arithmetic or logic assumptions that can result in behavior that can't really be humanly predicted without examining the generated machine code.
- uecker 1y agoThey are free to but not required. You can pick a different compiler, or you can configure your compiler to something else, if it provides such options. I always found it surprising that people did not reject clang for aggressively optimizing based on UB, but instead complained about the language while still using clang with -O3.
- nicce 1y agoThere is RFC but I guess the work stopped.
- weinzierl 1y agoIt is worked on under the term "pattern types" mainly by Oli oli-obk Scherer I think, who has an Ada background. Can't tell you what the current state is but this should give you the keywords to find out. Also, here is a talk Oli gave in the Ada track at FOSDEM this year: https://hachyderm.io/@oli/113970047617836816 https://hachyderm.io/@oli/113970047617836816
- afdbcreid 1y agoAFAIK the current status is that it's internal to std (used to implement `NonNull` and friends) and not planned to be exposed. There were some talks about general pattern type, but it's not even approved as an experiment, not to talk about RFC or stabilization.
- jandrewrogers 1y ago> The ability to make number types that were limited in their range is really useful for certain classes of bugs. This is a feature I use a lot in C++. It is not part of the standard library but it is trivial to programmatically generate range-restricted numeric types in modern C++. Some safety checks can even be done at compile-time instead of runtime. It should be a standard feature in programming languages.
- init1 1y agoI've never come across any range restricting constructions in C++ projects in the wild before. It truly is a shame, I think it's something more programmers should be aware of and use. Eliminating all bounds checking and passing that job to the compiler is pretty killer and eliminates whole classes of bugs.
- jandrewrogers 1y agoThis is an unfortunate reality. C++ has evolved into a language capable of a surprisingly deep compile-time verification but almost no one uses that capability. It reflects somewhat negatively on the C++ developer community that problems easily solved within the language are routinely not solved, though the obsession with backward compatibility with old versions of the language plays a role. If you fully leverage it, I would argue that recent versions of C++ are actually the safest systems language. Nonetheless, almost no one has seen code bases that leverage that verification capability to its maximum. Most people have no clue what it is capable of. There is the wisdom that it is impossible to deliver C++ without pervasive safety issues, for which there are many examples, and on the other hand there are people delivering C++ in high-assurance environments with extremely low defect rates without heroic efforts. Many stories can be written in that gap. C++ can verify many things that are not verifiable in Rust, even though almost no one does. It mostly isn’t worth the argument. For me, C++20 reached the threshold where it is practical to design code where large parts can be formally verified in multiple ways. That’s great, this has proven to be robust in practice. At the same time, there is an almost complete absence of such practice in the C++ literature and zeitgeist. These things aren’t that complex, the language users are in some sense failing the language. The ability to codegen situationally specific numeric types is just scratching the surface. You can verify far weirder situational properties than numeric bounds if you want to. I’m always surprised by how few people do. I used to be a C++ hater. Modern C++ brought me back almost purely because it allows rich compile-time verification of correctness. C++11 was limited but C++20 is like a different world.
- nickdothutton 1y ago30+ years ago I was programming in Ada, and I feel the same way and have been repeatedly disappointed. Maybe this time around things will be different.
- plainOldText 1y agoNim was inspired by Ada & Modula, and has subranges [1]: type Age = range[0..200] let ageWorks = 200.Age let ageFails = 201.Age Then at compile time: $ nim c main.nim Error: 201 can't be converted to Age [1] https://nim-lang.org/docs/tut1.html#advanced-types-subranges https://nim-lang.org/docs/tut1.html#advanced-types-subranges
- arzig 1y agoWhat happens when you add 200+1 in a situation where the compiler cannot statically prove that this is 201?
- plainOldText 1y agoYour example also gets evaluated at comptime. For more complex cases I wouldn't be able to tell you, I'm not the compiler :) For example, this get's checked: let ageFails = (200 + 2).Age Error: 202 can't be converted to Age If it cannot statically prove it at comptime, it will crash at runtime during the type conversion operation, e.g.: import std/strutils stdout.write("What's your age: ") let age = stdin.readLine().parseInt().Age Then, when you run it: $ nim r main.nim What's your age: 999 Error: unhandled exception: value out of range: 999 notin 0 .. 200 [RangeDefect]
- prerok 1y agoExactly this. Fails at runtime. Consider rather a different example: say the programmer thought the age were constrained to 110 years. Now, as soon as a person is aged 111, the program crashes. Stupid mistake by a programmer assumption turns into a program crash. Why would you want this? I mean, we've recently discussed on HN how most sorting algorithms have a bug for using ints to index into arrays when they should be using (at least) size_t. Yet, for most cases, it's ok, because you only hit the limit rarely. Why would you want to further constrain the field, would it not just be the source of additional bugs?
- fainpul 1y ago
- fuzztester 1y ago>Ada has some really good ideas which its a shame never took off or got used outside of the safety critical community that mostly used it. The ability to make number types that were limited in their range is really useful for certain classes of bugs. As pjmlp says in a sibling comment, Pascal had this feature, from the beginning, IIRC, or from an early version - even before the first Turbo Pascal version.
- wolvesechoes 1y agoAda, or at least GNAT, also supports compile-time dimensional analysis (unit checking). I may be biased, because I mostly work with engineering applications, but I still do not understand why in other languages it is delegated to 3rd party libraries. https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_and_program_execution.html#performing-dimensionality-analysis-in-gnat https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ug...
- cb321 1y agoNim (https://nim-lang.org https://nim-lang.org), mentioned elsethread Re: numeric ranges like Ada, only needs a library for this: https://github.com/SciNim/Unchained https://github.com/SciNim/Unchained FWIW, physical dimensions like meters were the original apples-to-oranges type system that pre-dates all modern notions of things beyond arithmetic. I'm a little surprised it wasn't added to early FORTRAN. In a different timeline, maybe. :) I think what is in "the" "stdlib" or not is a tricky question. For most general/general purpose languages, it can be pretty hard to know even the probability distribution of use cases. So, it's important to keep multiple/broad perspectives in mind as your "I may be biased" disclaimer. I don't like the modern (well, it kind of started with CTAN where the micros seemed meant more for copy-paste and then CPAN where it was not meant for that) trend toward dozens to hundreds of micro-dependencies, either, though. I think Python, Node/JS, and Rust are all known for this.
- reshlo 1y agoF# can do this too. https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
- wolvesechoes 1y agoNice, didn't know that. I keep seeing praise for F# so I should finally take a look.
- humanfromearth9 1y ago
- wilsonnb3 1y agoIt doesn’t really compete in the same space as Ada or Rust but C# has range attributes that are similar, the only downside is you have to manually call the validation function unless you are using something like ASP.NET that does it automatically at certain times.
- c0balt 1y agoIn my personal experience it's not just safety. Reliability of produced is also a big part. Ime, being able to express constraints in a type systems yields itself to producing better quality code. A simple example from my experience with rust and golang is mutex handling, rust just won't let you leak a guard handle while golang happily let's you run into a deadlock.
- phoehne 1y agoYes, we re-invent the wheel. The more time you spend writing software for a living, the more you will see the wheel re-invented. But Ada and Rust are safe under different definitions of safety. I view Rust as having a more narrow definition of safety, but a very important notion of safety, and executed with brutal focus. While Ada's definition of safety being broader, but better suited to a small subset of use cases. I write Rust at work. I learned Ada in the early 1990s as the language of software engineering. Back then a lot of the argument against Ada was it was too big, complex, and slowed down development too much. (Not to mention the validating Ada 83 compiler I used cost about $20,000 a seat in today's money). I think the world finally caught up with Ada and we're recognizing that we need languages every bit as big and complex, like Rust, to handle issues like safe, concurrent programming.
- afdbcreid 1y agoI don't know Ada; care to explain why its definition of safety is broader than Rust? I agree Rust's safety is very clearly (and maybe narrowly) defined, but it doesn't mean there isn't focus on general correctness - there is. The need to define safety precisely arises because it's part of the language (`unsafe`).
- naasking 1y agoAs the OP mentioned, restricted number ranges: with Ada.Text_IO; use Ada.Text_IO; procedure Restricted_Number_Demo is -- Define a restricted subtype of Integer subtype Small_Positive is Integer range 1 .. 100; -- Define a restricted subtype of Float subtype Probability is Float range 0.0 .. 1.0; -- Variables of these restricted types X : Small_Positive := 42; P : Probability := 0.75; begin Put_Line("X = " & Integer'Image(X)); Put_Line("P = " & Float'Image(P)); -- Uncommenting the following line would raise a Constraint_Error at runtime -- X := 200; end Restricted_Number_Demo;
- yukeabu 1y agoRust’s built-in notion of safety is intentionally focused on memory + data-race properties at compile time. logic, timing, and determinism are left to libraries and design. Ada (with SPARK & Ravenscar) treats contracts, concurrency discipline, and timing analysis as first-class language/profile concerns hence a broader safety envelope. You may choose to think from safety guarantee hierarchy perspective like (Bottom = foundation... Top = highest assurance) Layer 6: FORMAL PROOFS (functional correctness, no RT errors) Ada/SPARK: built-in (GNATprove) Rust: external tools (Kani, Prusti, Verus) Layer 5: TIMING / REAL-TIME ANALYSIS (WCET, priority bounds) Ada: Ravenscar profile + scheduling analysis Rust: frameworks (RTIC, Embassy) Layer 4: CONCURRENCY DETERMINISM (predictable schedules) Ada: protected objects + task priorities Rust: data-race freedom; determinism via design Layer 3: LOGICAL CONTRACTS & INVARIANTS (pre/post, ranges) Ada: Pre/Post aspects, type predicates (built-in) Rust: type states, assertions, external DbC tools Layer 2: TYPE SAFETY (prevent invalid states) Ada: range subtypes, discriminants Rust: newtypes, enums, const generics Layer 1: MEMORY SAFETY & DATA-RACE FREEDOM Ada: runtime checks; SPARK proves statically Rust: compile-time via ownership + Send/Sync
- germandiago 1y agoIf I am not wrong, you could do a zero-cost abstraction in C++ and use user-defined literals if you wosh for nice syntax.
- kqr 1y agoThe thing I miss most from Ada is its clear conception of object-orientation. Every other language bundles all of OOP into the "class" idea, but Ada lets you separately opt in to message sending, dynamic dispatch, subtyping, generics, etc. In Ada, those are separate features that interact usefully, rather than one big bundle.