this post was submitted on 03 Nov 2022
10 points (100.0% liked)
General Programming Discussion
7816 readers
2 users here now
A general programming discussion community.
Rules:
- Be civil.
- Please start discussions that spark conversation
Other communities
Systems
Functional Programming
Also related
founded 5 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
Learn more languages, especially cross-paradigm. Most languages in a given paradigm will be sufficiently similar that you can get the gist of any code written in it if you're familiar with another language of the paradigm, especially if the code is reasonably written. For example:
(specification)
(body)
There's a gnome sort (a.k.a. stupid sort) in Ada. If you're familiar with any loosely structured-imperative programming language you can pretty much figure it out.
while
works as you'd likely expect.if
andelse
too.loop
andend loop
andend if
and evenbegin
/end
are pretty obvious. You'll have to do a bit of head-scratching if you're not familiar with languages in the Wirthian tradition (Pascal, the Modulas, the Oberons) to figure out which parts you can safely ignore and which parts you need to pay attention to, but it's not really difficult. The hardest part is "weird" expressions likeIndex'Pos(Index'Succ(Index'First));
which you can still kind of guess the meaning of from context, especially in the later expressionwhile I <= Index'Pos(Index'Last)
where you might think Index`Pos() is like index.pos() in another language like Python or C++ and won't be completely wrong (though still wrong).Basically you work it out by knowing the paradigm and knowing how things are generally expressed in said paradigm.
Of course if you're unfamiliar with the paradigm involved you might find it impossible to decode:
(Erlang—functional)
If you know another functional language like SML or Haskell or the like, this will be easy enough to read. Even if you know some logic languages like Prolog this is simple enough to follow. If you only know imperative languages (unstructured, structured, OOP, etc.), however, this will be gibberish.
(Forth—concatenative)
Although Forth is technically an imperative language, it is a very weird one with its stack discipline and unless you know it, or know related concatenative languages like Factor, this is going to be totally brain-damaging.
So in cases where you're unfamiliar with the paradigms involved: learn the paradigms. You should learn a new paradigm of programming every couple of years if you're a serious programmer, after all.
I see Thanks, I'll learn more paradigms
Yes! this is exactly what I mean.
OK, let's take that weird one apart so I can show you the strategy for reasoning about it:
Index'Pos(Index'Succ(Index'First));
First,
Index'Pos
is clearly separating two lexical items:Index
andPos
. Where have we seen either of those before?Pos
is only ever used on the right hand side of'
, so that's a clue that this is some kind of component ofIndex
.Index
is defined, however. Let's take a look at that specification again.Index
is a type. What type?(<>)
. That's just gibberish if you only know Python and C, but we can still tease out some information.First,
Index
has a name that means something. It's, well, an index. And if we look atCollection
right underneath it, it's an index into an array. So Index is likely an integer.So
'Pos
is some kind of operation or member or something on the type of an integer. And it suggests that it means some kind of position. What could "position" mean to an integer?The clue lies in how the function there gets used. I didn't put it there (because I was already being long-winded) but here's the example of using that:
And here the penny drops. The
Gnome_Sort
routine is generic (clue:generic
in the specification). The index has to be defined for it. We do that with the three lines immediately after theprocedure
line in the use case.Index
is an integer in the range of 0..9.Because the
Gnome_Sort
procedure is generic, we make no assumptions about what the array ranges are: here it's 0..9, but it could just as easily have been -1277516794231..125164987325159876. So these'Pos
,'First
, and'Last
and'Val
and such things are used to step through loops in a type-safe way that's guaranteed to never step out of the array boundaries.But it's largely unimportant. These are Ada-isms focused on Ada's obsession: correctness. That's just line noise, really, for purposes of understanding the code. We can kind of intuit that I is starting from the successor (
'Succ
) of the first ('First
) (a.k.a the second) element of the array and going through it until it reaches the end of it (<= Index'Last
). This guess is further bolstered by the comparison of things indexed viaI - 1
againstI
.Decoding this is a dollop of familiarity with paradigms and coding approaches and decent contextual guessing. Is it better to just know the language? Yep. But even not knowing it you can tease out everything you need to work out how a gnome sort works. Part of the skill set in reading alien code is to learn how to relax and gloss over the bits that you don't understand until you see the shape of the whole thing, after which, if you're familiar with the paradigm, you can start making very good guesses as to what the unfamiliar bits actually mean. (Again, if you're unfamiliar with the paradigm you're ... going to need to learn.)