677 karma · joined August 29, 2021
> the tool is so fricken slow.
How old is "old hardware"? I've had no issues running CLion on a 2020 M1 Macbook Air and a i5-10400 (Linux). These projects are only in the hundreds of thousands of lines of code though.
> The install is gigantic on disk, leading me to avoid it on my older machines where space is limited.
I found that by default toolbox likes to keep old versions of the IDEs available for rollback. I disabled that and reclaimed tens of GB across all the products I use.
Python (decent standard library) - It's pretty much everywhere. There's so many hidden gems in that standard library (difflib, argparse, shlex, subprocess, cmd)
C#/F# (.NET)
C# feels so productive because of how much is available in .NET Core, and F# gets to tag along and get it all for free too. With C# you can compile executables down to bundle the runtime and strip it down so your executables are in the 15 MiB range. If you have dotnet installed, you can run F# as scripts.
There's instructions on running a Git server in the git book: https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protoco...
Every "type" you use in Ada is actually a subtype.
In Ada, "A subtype of a given type is a combination of the type, a constraint on values of the type, and certain attributes specific to the subtype".
You don't ever refer to actual types in Ada, since creating a type with "type" actually creates an anonymous type and the name refers to the first subtype.[1]
type Token_Kind is (
Identifier,
String_Literal,
-- many more ...
-- These are character symbols and will be part of Token_Character_Symbol.
Ampersand,
-- ...
Vertical_Bar,
);
-- A subtype with a compile-time checked predicate.
subtype Subprogram_Kind is Token_Kind
with Static_Predicate => Subprogram_Kind in RW_Function | RW_Procedure;
subtype Token_Character_Symbol is Token_Kind range Ampersand .. Vertical_Bar;
> If you have a pointer with more permissions, it should still be usable in a place that only requires a pointer with fewer permissionsThis is exactly how "accessibility" of access types works in Ada[2]. If you have a pointer ("access type") to something on the heap, you can use it wherever an anonymous access type can be used. You can also create subtypes of access types which have the constraint of a "null exclusion".
This was directly addressed in 2 John 7
"I say this because many deceivers, who do not acknowledge Jesus Christ as coming in the flesh, have gone out into the world."
I'm curious about this list, because it definitely doesn't seem that way these days. It'd be interesting to see how many of these are still possible now.
The open source tooling has significantly improved since I started using it in the last five years.
Other languages focus on terseness and expressiveness. Ada expresses a bunch of constraints directly and forces you to do things in organized ways (e.g. use namespaces appropriately).
> 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.
Foo : array (Positive range 1 .. 100) of access function return access Integer;- https://blog.adacore.com/ada-on-any-arm-cortex-m-device-in-j...
The amazing thing to me is that Ada code can call SPARK code just fine, and there's crates of SPARK code in Alire that you can use. It's a huge boost of confidence in the quality of a library that you're using when it has some form of verification.
I wrote Rob Pike's simple regex from the "Practice of Programming" in Ada/SPARK and it blew my mind that I actually managed to prove an absence of runtime error (guaranteed no overflow or out of bounds).
Ada has this as well, including using any arbitrary continuous range for array indexing which handles remapping indices for you. e.g. if the key range is 20-40 the language handles associating it with array indices for you.
My experience is that it just isn't prioritized, and you have to do it early to enforce good engineering solutions to keep it this way. It's much easier to keep something locally runnable than try to set it up that way six months into a project.
If you can't run the stack locally, it makes it harder to set up performance and acceptance testing later. Running locally also makes long build times more noticeable and it's easier to address these issues earlier.
Being able to run locally looks low value at first, but if you do it, and sustain it, you get extremely large project-wide benefits later.
The book itself is a way to open the door to learning, not the end point. Reading subject titles first, cross-referencing, and working examples and doing projects help teach and cement ideas.
There's techniques like SQ4R [1] for reading, and hugely applicable to general technical and article reading is "How to read a paper" [2]. For lecturers, there's "How to Speak" [3], and for those attending a talk there's the Cornell Notes system. [4]
[1]: https://en.wikipedia.org/wiki/SQ3R
[2]: https://web.stanford.edu/class/ee384m/Handouts/HowtoReadPape...