this happens a lot, I want to find out how something works but I don’t know the said programming language and so I can’t read the source code, I’ve tried looking up stuff in cheatsheets but they don’t really help that much and Search Engines are obviously useless for this since they can’t search symbols, so how do you read the source code without spending time learning the language ?
With practice, you begin to realize that things are more common than they are different. Think about you how you know how to drive most cars, despite learning to drive in only one or two of them at the beginning. I guess it’s a “When in Rome…” mindset.
This is a GREAT analogy! Thanks!
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)
generic type Element_Type is private; type Index is (<>); type Collection is array(Index) of Element_Type; with function "<=" (Left, Right : Element_Type) return Boolean is <>; procedure Gnome_Sort(Item : in out Collection);
(body)
procedure Gnome_Sort(Item : in out Collection) is procedure Swap(Left, Right : in out Element_Type) is Temp : Element_Type := Left; begin Left := Right; Right := Temp; end Swap; I : Integer := Index'Pos(Index'Succ(Index'First)); J : Integer := I + 1; begin while I <= Index'Pos(Index'Last) loop if Item(Index'Val(I - 1)) <= Item(Index'Val(I)) then I := J; J := J + 1; else Swap(Item(Index'Val(I - 1)), Item(Index'Val(I))); I := I - 1; if I = Index'Pos(Index'First) then I := J; J := J + 1; end if; end if; end loop; end Gnome_Sort;
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)
gnome(L, []) -> L; gnome([Prev|P], [Next|N]) when Next > Prev -> gnome(P, [Next|[Prev|N]]); gnome(P, [Next|N]) -> gnome([Next|P], N). gnome([H|T]) -> gnome([H], T).
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)
defer precedes defer exchange : gnomesort ( a n) swap >r 2 tuck 1- ( c2 n c1) begin ( c2 n c1) over over > ( c2 n c1 f) while ( c2 n c1) dup if ( c2 n c1) dup dup 1- over over r@ precedes if r@ exchange 1- else drop drop drop >r dup 1+ swap r> swap then else drop >r dup 1+ swap r> swap then repeat drop drop drop r> drop ; :noname >r cells r@ + @ swap cells r> + @ swap < ; is precedes :noname >r cells r@ + swap cells r> + over @ over @ swap rot ! swap ! ; is exchange
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
The hardest part is “weird” expressions like
Index'Pos(Index'Succ(Index'First));
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.generic type Element_Type is private; type Index is (<>); type Collection is array(Index) of Element_Type; with function "<=" (Left, Right : Element_Type) return Boolean is <>; procedure Gnome_Sort(Item : in out Collection);
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:
with Gnome_Sort; with Ada.Text_Io; use Ada.Text_Io; procedure Gnome_Sort_Test is type Index is range 0..9; type Buf is array(Index) of Integer; procedure Sort is new Gnome_Sort(Integer, Index, Buf); A : Buf := (900, 700, 800, 600, 400, 500, 200, 100, 300, 0); begin for I in A'range loop Put(Integer'Image(A(I))); end loop; New_Line; Sort(A); for I in A'range loop Put(Integer'Image(A(I))); end loop; New_Line; end Gnome_Sort_Test;
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.)
Hmmm what lang is it? It’s always generally easy to read
I bascally have trouble with anything that’s not like pseudo-code (i.e. Python) and C-style syntax, although I can probably read PHP too.
Oh! I’m one month late sorry, well, that’s completely normal. You just need to pay attention and google as many definitions as you need to. Remember, Google is your friend here. Especially if the source code is powered by many external libraries.
Eventually with time and patience you’ll be able to make a structure of the code inside your mind and from there it should be a breeze. You can also ask a contributor to guide you through the codebase and explain some things to you, they’re always glad to help a potential mate :)
Usually in the header there is a contact email. I’ve found that developers are usually pretty enthusiastic to help you to understand their coding if you get in touch with them. Don’t forget to thank them and contribute to the project if you can!