Hey there,

Two and a half years ago, I started doing CP, and it's a very fun and meaningful experience that I will cherish. But at some point, I just started growing tired of it (perhaps because I wasn't improving that much anymore), and I also realized that the computer science world is way larger than just CP.

**So... what's after CP? What did you do after you "retired" from CP? Which area of CS did you explore?**

I'm genuinely a bit lost and don't know what to do. For the past 6 months or so, I tried exploring stuff like Machine Learning, Computer Theory, and topics closer to theoretical CS, but felt like I wasn't making much progress without a teacher or a "partner" that could help me when I'm stuck (on that note, should I cold email university professors for research/learning opportunities?) I also don't know any stuff related to "developing" — I tried writing a chess engine in c++ and was also stuck, and I don't really *know* any of the programming languages that well.

For some context, I'm a high school rising senior living in the US. **What should I do?**

Thanks :)

Oh also, I'm quite interested in Linux and I like to configure my computer in my free time. But Operating Systems is such a broad subject that I don't really know where to start. Any suggestions would be welcomed!

You can start to read "operating system the three easy pieces" book by Remzi you will know a lot about how things going under the hood.

+1, am studying from it right now.

I wouldn't consider myself retired from CP, and I'm not a CS major (I'm a math/econ major planning to pursue a Ph.D studying economic theory at the intersection of econ/CS theory), so I'm in no place to comment on any non-theoretical fields of CS. That said, in terms of interesting, CP-adjacent areas of CS, I'll put in a word for algorithmic game theory. Broadly, AGT as a field thinks about game theory problems from a CS perspective; this includes things like devising algorithms to compute equilibria of games or designing the rules of games such that the equilibrium achieves a certain desirable feature. One example of the latter scenario is called a

knapsack auction: bidders each desire a certain amount of a good and derive some level of utility from receiving that much of the good, but you as the auctioneer can only give out a certain total amount of the good. If you knew each bidder's utility value, finding the welfare-maximizing allocation of the good to the bidders would be a standard knapsack problem. However, depending on the auction system you employ, bidders might bid strategically in order to receive their allocation at a lower cost; the resulting AGT problem involves designing this auction to incentivize bidders to bid truthfully and/or to maximize your own revenue.Out of the fields of CS I've studied, AGT feels the most similar to CP in terms of the style of thinking involved. It's also relatively accessible (my class last semester used Twenty Lectures on Algorithmic Game Theory by Tim Roughgarden, which was relatively accessible, and I'm told that this book is a bit more advanced but is generally the standard reference), and the field is quickly expanding and still has lots of interesting research questions to explore.

Re: cold emailing professors--there's probably no harm in trying, but it may be hard to get a professor to dedicate time to working with you unless you give them a very compelling reason to take you on. As a result, if you do send cold emails, you should put substantial effort into them--for example, it will help if you can read some of the professors' papers and have insightful things to say about them.

Thank you very much for the thoughtful response! AGT indeed sounds very interesting, and I will look into Twenty Lectures on Algorithmic Game Theory. Also, what do you think is the best way to self-study these rather advanced materials? Reading books? Perhaps a coursera course? What I really enjoyed about CP is that you have sites like cf and you can find get instant feedback of your progress (i.e. whether you solve the problem or not), but when I was reading some textbooks earlier, I couldn't get that feedback and couldn't feel the progress, which sometimes demotivate me.

I've found reading books most helpful, but I generally learn much better from reading than from e.g. watching lectures. Coursera probably would offer more structure, so if textbooks haven't worked for you that might be more effective. OpenCourseWare might be another good source of lectures to work from.

I work on theory research too, and (assuming that theory research is something that's potentially your cup of tea) I think one of the most beneficial things you can do as an early undergrad (or high school, for your case!) is to improve your mathematical muscles. Specifically, making sure that your linear algebra, probability, and basic analysis background is strong will always help you down the line. As for learning things, taking classes (or scraping the web for lecture notes from courses at other universities) will help for sure. The thing about research is that it often goes hand in hand with learning (i.e. filling knowledge gaps on various topics and working on open problems complement each other).

In terms of the feedback loop (not limited to just theoretical computer science), it's definitely true that research doesn't provide the instant feedback like CP does; that's why problems take months and even years to be solved. In the end, the type of feedback loop that suits you is all about personal preference — try it out to see if research is for you!

Disclaimer: Most of the above applies for TCS, but I suppose some of the core principles probably apply to other fields of CS research as well. As for the non-research areas of CS (e.g. software development, building hardware, etc.), I don't have much experience with, so I can't give any input on that. In the end, it's all about personal taste, and you still have a lot of time to explore!

For me personally, I still occasionally do CF contests simply because it gets the adrenaline rush going, which is always fun.

Strongly agree with the recommendation to learn more math, and I think it applies even if you aren't necessarily interested in theory research. More generally, college classes will be much easier next year if you come in with a stronger mathematical background. I'd also add discrete math to the list of subjects worth working on, mostly because it involves a sort of creative thinking helpful in constructing proofs in later math/CS courses. In general, building up your proof-writing skills in advance is likely to be very helpful--many universities in the US use real analysis as the "intro to proofs" course, and for some people learning analysis and proof-writing at the same time feels overwhelming, so you'll be at a substantial advantage if you're very comfortable with mathematical writing and can thus focus on the math itself.

Thanks for the suggestions! I agree — math is definitely one of the core foundations for CS. I’ve personally studied some Abstract Algebra, Number Theory, and Discrete Math on my own, but I will delve deeper into them!

Well, honestly I'm just starting CP but since this is about CS in general I'll offer my thoughts.

Personally I'm studying programming languages theory (and might I add, loving it).

PL Theory is exactly what it sounds like — the study of programming languages. This includes both the practical aspects (how to design a language) and also the more theoretical (the mathematical properties of PLs).

There is also a lot of intimate connections between CS and maths.

Consider the very beautiful notion of the Curry-Howard isomorphism : programs in a programming language correspond to proofs in a system of logic and types in the language correspond to propositions.

Curry-Howard is not "valid" for all programming languages in the sense that most statically typed mainstream languages (Java, C++, even the ones with more sensible type systems like Rust and Haskell) produce logical systems that are inconsistent — it is possible to prove false propositions. In fact, it can be shown that any Turing complete programming language must allow it's corresponding logic to prove false propositions.

We can exploit the Curry-Howard isomorphism to achieve some crazy feats.

Most of us think in type systems that only allow abstraction over types :

Here

`foo`

is not a type but atype abstraction. It is only when we provide a concrete type for the parameter`T`

that we get a valid type such as`foo<int>`

or`foo<vector<string>>`

.This is great for a lot of applications but is not expressive enough for many things (or so we feel if we're studying PL theory).

There are languages, most notably the Calculus of Constructions and Martin-Lof's type theory (and their implementations Coq and Agda) that allow types that are

abstract over terms.Essentially, we can treat types as values themselves and manipulate them like regular objects.

Consider an example : let's try to define the set of all vectors (think finite lists) over a certain set. If we have an object of type

`vector<int>`

we know only one thing about it at compile-time : it is a vector of integers. There's no information about the number of elements it can potentially store.We want our type of vectors to store this information in the type signature itself. So our type

constructiondepends on two factors : thenumber of elements(a natural number) and the set over which we're constructing our type of vectors (such as strings, lists, etc.).In order to define this, in say, Agda we would write the following recursive function :

`succ n`

simply means`n + 1`

.The type

`Vec A n`

now represents type of vectors over set`A`

of length`n`

. Let us try to understand the definition :`Vec A zero = Unit`

is the base case — there is only one vector of length so thesetis theunit set(the set with only one meaningless element)`Vec A (succ n) = (Vec A n) * A`

is the inductive/recursive case — assuming we have already constructed`Vec A n`

we simply take this type and do a cartesian product with the set`A`

and define`Vec A (succ n)`

If you're wondering why we're using this weird

`succ n`

notation — there's a reason for that too.The natural numbers are defined as an inductive datatype :

What this means is that there is some object

`zero`

and it is already known to be a`Nat`

. The second line (the technical term isconstructor) is an inductive definition — if`n`

is known to be a`Nat`

then`succ n`

is also a`Nat`

.Mathematically, the natural numbers are anything that satisfies the Peano axioms. We can provide a mathematical model for inductive datatypes as defined in Agda and show that this definition of the natural numbers as an inductive datatype satisfies the Peano axioms (as far as I know).

We then define addition so that

`succ n`

happens to have the same meaning as adding by one. For more details — see the chapter on the natural numbers in PLFA.The reason why dependent type programming is so powerful is that it is essentially equivalent to first-order logic (I'm skipping a few mathematical details) which is the formal language in almost of mathematics is written. By the Curry-Howard isomorphism, this means we can use langauges like Coq and Agda to verify mathematical proofs by converting them to computer programs in these langauges. This has actually been used to verify the proof of the four color theorem from graph theory. In fact, it was the world's first computer verified proof.

Agda code is not intuitive partly because it is such an expressive type system that everything can be treated both as a

typeand as atermof some type.Look similar to my story I am tired of cp too and started to look at what I should do to get internship/job as a software engineer and found that I have missed studying topics like operating system, database and networking in advance.

I think after cp you realize that your life is not just on cp only (if your plan was to train intensively) and started to see how can you enjoy your life + for sure try to get an internship that will give you a good experience and let you see how things get done in the technical part

My advice is to try to re-prioritize things in your life and do what you think is the most important one. Best of luck in what you will choose to do :)

I agree, and I've discovered that not only is there so much more to CS than CP, there's also so much more to life than CS.

As to OP's question of what to do: it's difficult to get internships or do research as a high schooler (at least in Canada). A lot more opportunities will open up to you in university. And since you're going into CS, you don't

haveto learn advanced topics (OS, networking, etc.) ahead of time on your own (as It_Wasnt_Me suggests) because you won't need these for many SWE internships. I'm a rising sophomore waiting to take them in my junior and senior years.So what should you do? ¯\_(ツ)_/¯. I'm just saying that you don't have to learn upper year content in advance. Cheers :))

You got a point, totally agree with you crackersamdjam. Maybe I said that because the quality of education here is miserable and we should study and read books and understand it on our own.

The same thing also here it's so difficult In Egypt to get an internship. Completely agree that he can just sit and do nothing but even doing 1% improvement per day will lead to great results in one year.

Oh, rip... I see what you mean now.

Thanks! Yeah you're right, since I plan to major in CS, I don't have to self-study these upper year content now. Instead, I'll probably dig deeper into math & this course I found online. Cheers!

Sounds great, Now I totally agree with crackersamdjam that you don't have to study them at this year as you plan to major in CS. Good luck :))