Ask HN: How to improve my abstract thinking?
A few days ago I got into Mathematical Logic[0] and learned how to reason about
problems through using various branches of mathematical ideas like
proof theory, model theory e.t.c.
I found this abstract way of thinking about problems clear, & organised. "Mathematical Logic" is diffrent from the kind of Math I was taught, which was a top down approach to solving problems.
"Mathematical Logic" seems to be able to derive solutions to problems in a ground up fashion where a solution can somtimes elegantly present its self as long as you apply correct mathematical properties.
What other techniques do you hackers use to improve your abstract thinking?
[0]: https://en.wikipedia.org/wiki/Mathematical_logic
110 comments
[ 2.8 ms ] story [ 190 ms ] threadFor example, sometimes functions feel like a dance to me. The movement of the dance represents the transformation of the domain to the image of the function.
If you follow along carefully with the arguments in most classical philosophy in great detail, you notice this more and more: everything has a logical error or assumption eventually and the author typically does not catch their own error.
I think abstraction is about recognizing patterns, but also about recognizing what elements are more likely to change - you don't want to abstract away the changing aspects. In that sense, it becomes similar to creating a model that depends on parameters.
Also, generally, when you are implementing a solution, that solution exists within a context of a problem. If we are simply told to implement a solution, there is a temptation to just trust that the solution will solve the problem - and sometimes we are told to trust that. But if we take a step back in abstraction and fully understand the problem ourselves, we can derive our way to the correct solution, freeing us from having to "trust" that the solution is correct.
Abstraction is just continuing from there. Understand the larger context of the problem, why it is a problem. Maybe you'll discover it isn't, and that the solution isn't actually needed. And so on, if you ask another Why you can discover that maybe another problem is more important to solve, which would make this problem irrelevant.
Above will get you started ... engaging in abstract thought takes time and focused attention ... coding software can provide a medium to express yourself so can expository long form writing ... before bedtime bring to mind an unsolved question then upon awakening harvest solutions ... that habit can provide feedstock for ongoing evolutionary jumps
over time increase the complexity of these long form projects ... grow them so their course may stretch for days to weeks to months to ...
nurture friendships with interesting folks ... travel wide ... gain inspiration give guidance cherish the moment
[1] http://www.jimpryor.net/teaching/guidelines/writing.html
You could view math as arguing, if you studied it by endless theorems and proofs, but a better way to learn math is by trying to solve problems whose answers you don't know (and picking up theories as needed). That way you learn to be curious for the truth out there, not just a convincing argument. That's the best approach to philosophy as well.
Abstract Algebra and Linear Algebra are adjacent fields with a lot of clean abstractions that I believe exercise the same muscles as programming (even if a lot of it isn't directly applicable)
Related comment: https://news.ycombinator.com/item?id=23152152
i.e. basically linear algebra for engineers is not abstract. Linear algebra for mathematicians is quite abstract, e.g. a 400+ page textbook that doesn't refer to any matrices.
----
On the flip side, I think mixing abstract thinking with testing/debugging is the ideal combo for programming.
It is a skill to write useful test cases. To explore the state space efficiently.
If your code isn't grounded in real examples, then it may become overly general and not RUN run very well. It's a big danger to abstract before you have enough examples.
And probably the hardest thing that programmers do is debug OTHER people's code, as opposed to your own code.
(I guess you didn't ask about programming, but I'm sort of assuming you are programming by asking on this site :) )
I added a math degree to my CS degree (which also added a year, but I was going to be a year late graduating anyways). So I took a lot of courses in math my last two years. The three that made the biggest difference for me were:
Set theory: Covered proof construction in a deeper fashion than high school geometry and was the first proof-heavy math course I had taken in college (others used them and expected regurgitation, but did not expect construction; this was my first math-major only course).
Later I took both Abstract Algebra and Linear Algebra (high level) together. I wasn't struggling in either, but in my mind they were two separate courses. One day we were doing a proof in Linear and I realized I'd already done it in Abstract, only we had been dealing with (I don't recall what) some other objects than matrices or vectors. What I realized then was that we were dealing (in both classes) with a class of objects and operations on them that were the same in the abstract, but different in the concrete (if you wanted to actually apply the math to solve a problem). Given the right perspective, I could apply the proofs of one to the other so long as the objects had the same properties the proofs relied on. Both classes became a breeze after that because, coincidentally, the order the material was covered in meant that every other week one class had been largely covered by the other when viewed in this fashion.
I will say that high school math is very different than abstract algebra, and in some ways abstract algebra is simpler.
I heard a long time ago that in France they teach some abstract algebra to 10 year olds??? They are simple concepts that don't require much background knowledge.
I actually got a little bit of it in 6th grade. I remember doing some optional assignment that introduced the idea of functions as things you can operate on, rather than things you just apply to concrete data. In other words, higher order functions.
So everybody knows you have numbers and operators:
Well functions are also algebraic objects, with operators, e.g. 'o' is the function composition operator, so if you have functions f and g, f o g is also a function.I think 20 years ago, programmers didn't think like this. These days, many programmers do, whether formally or not. JS/Python are more flexible than C or BASIC in this regard (and Haskell, Lisp, etc. even more so). So this is directly applicable to programming and it's worth a little bit of study. You probably know it, but seeing the mathematical view will make the reasoning more fluid.
It's not just functional programming either -- I don't use functional languages currently, but I use the ideas. I think that most people use inheritance poorly and I suspect that knowing algebra helps you "factor" code correctly.
What is it that you find challenging about math? If it's the actual computation/calculation -- the part where you are finding a numeric answer -- don't worry, that's nowhere to be found in abstract algebra (or any higher level math). Pure math (of which abstract algebra is a part) is about the study of patterns more than anything that has to do with numbers.
In fact, the name "abstract" refers to the fact that it's concerned with abstract collections of things -- for instance, groups. You'll study sets of operations on groups -- if you are able to identify Collection X as a group, you immediately know you can apply theorems a, b, c, etc. to it. For these reasons, the sort of things you are likely learning in pre-alg on Khan Academy don't have much direct applicability.
I think it's an enormously beneficial subject for programmers to study, maybe the only math course beyond the standard discrete math that I think should be required. (I want to add category theory, but I don't feel I can as I only have the barest grasp of the fundamentals myself...) As with all pure math courses, it will quickly move beyond the depth/level you can actively use in programming, but the mind-expanding it does is really great at encouraging the sort of abstract thinking the OP's post is about. It has strong relations to generics, interfaces, polymorphism, etc.
As for how to get into it, I used this book: https://www.amazon.com/Book-Abstract-Algebra-Second-Mathemat....
So-called mathematical maturity lets you think about many domains without considering concrete reality, and this lets you solve a different class of problems. Many foundational computer scientists are or were mathematicians for good reason. Think von Neumann, Knuth, and Turing.
There is a magnitude of difference in abstract thinking between a mathematically mature scientist and a mathematically immature one. Mathematical maturity seems to allow an easy transition from abstract theory to empirical experimentation. The converse does not appear to be as true.
My advice would be to study math directly.
As someone who was for many years enamored with theory and mathematical elegance (I drank from the wells of lambda calculus and category theory in hopes of discovering something that would set me apart), I had to unlearn much of it to actually make progress in my work. When faced with new problems, I found myself trying too hard to find an elegant solution, and when I couldn't, I was paralyzed. My more resourceful colleagues on the other hand managed to ship yucky but working solutions -- which eventually got less yucky.
I learned that sometimes you have to let go of the ground-up mathematical-derivation type of thinking, and just release practical yet inelegant solutions into the wild, collect data, and then iterate. As one iterates, some solutions will tend toward elegance and others will not -- some problem spaces are just naturally messy and the solution needs to reflect that. If you've ever worked with an ERP, you'll understand how hard it is to unify competing concepts, yet that's what an ERP does with varying degrees of success. (everybody hates ERPs, but different people hate it for different reasons, and on the whole they kind of work)
Take something like Category Theory for instance: it seems like it should lead to amazing elegant solutions, but in practice it's rarely used -- and Haskellers might disagree with me here -- to design solutions (except in rare cases like LINQ). Instead, it's often deployed as a post-hoc gloss to explain solutions that have emerged by trial and error (like SQL perhaps). Its utility is often usually retrospective, i.e. either to verify correctness or to add rigor to existing solutions.
p.s. don't underestimate the value of experience + good taste in producing good thinking. People who design good abstractions are not always deeply mathematical people, but instead are people who have good intuition, like Anders Hejlsberg (architect of Turbo Pascal, Delphi, C# and Typescript), Rich Hickey of Clojure fame (who actually trained as a musician), etc. Guido van Rossum (Python) once said he probably couldn't have designed Python when he was 17 because at that age he didn't have enough experience and good taste in programming languages -- which is why most programming language designers tend to be over 35.
I would amend that do this daily and you'll see progress after months if not weeks.
- https://untools.co/
- https://mindfold.co/
https://en.wikipedia.org/wiki/Algebraic_geometry
Puzzles can help introduce very powerful ideas without any baggage like mathematical notation. Smullyan's "Knights and Knave" style puzzles often touch very deep ideas in mathematical logic.[1] To Mock a Mockingbird[2] is probably his most famous book.
Godel, Escher, Bach has very clear, fun, and memorable descriptions of formal systems and their fascinating properties. After reading that it will be easier to view real world systems as formal systems and to understand the implications of that.[3]
Most of object-oriented programming and entity-attribute-value models can be found in the writings of Plato and Aristotle. For the purposes of abstract thinking, Plato's theory of forms[4] and Aristole's Organon[5], especially its Prior and Posterior Analytics which describe syllogistic reasoning, are probably the most important. For roughly 2000 years, this was logic. The Theaetetus[6] is also a very good introduction to epistemology and the deductive method of philosophy. In a practical sense, there is very little that programmers do in terms of modeling data or systems that does not derive more or sense directly from these two thinkers.
It's only been in the last two centuries that we've improved on Greek logic. Boole and De Morgan for propositional calculus[7], Frege and Pierce for quantification[8], which combine to create first order predicate logic[9]. From their you can either go to second-order logic or to set theory in order to begin talking about collections of things. Naive Set Theory[10] is a good introductory book, although you can jump straight in to ZFC set theory[11] for an axiomatic approach.
Relational algebra, which will be familiar in a loose sense to anyone who has ever worked with a relational database, is a formal theory that can be studied in the abstract[12]. I find the terminology (like "theta join") to be useful for thinking about advanced SQL statements. It's also very interesting to contrast relational algebra with ZFC set theory - many of the axioms are similar, but there are also crucial differences.
Lately, in the last century or so, abstract algebra[13] has proven very useful in modelling all kinds of real-world phenomena. For example, Lie groups in physics, or finite fields in cryptography. Abstract algebra basically strips down numbers to their most basic axioms and generalizes them. In group theory we study structures that have a single operation (say addition) then "rings" allow a second operation (say multiplication) and "fields" allow this second operation to be inverted. It is incredibly fruitful to model your real-world system as an abstract algebra and then to add axioms that fit your system (do your operations commute? Are the associative? Can they be reversed?) because you can then leverage a huge number of appropriate theorems.
The mother of all "abstract thinking" has to be category theory[14] which is so abstract I can hardly even describe it. Nevertheless many people find it a useful framework, with commutative diagrams[15] showing up all kinds of papers.
[1]: https://en.wikipedia.org/wiki/Raymond_Smullyan
[2]: https://en.wikipedia.org/wiki/To_Mock_a_Mockingbird
[3]: https://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach
[4]: https://en.wikipedia.org/wiki/Theory_of_forms
[5]: https://en.wikipedia.org/wiki/Organon<...
[0]: https://www.whitman.edu/mathematics/higher_math_online/
It really helps your brain to form pathways to seeing connections that may not be obvious on the surface.
I don't read as much as I used to anymore, but I listen to podcasts. Pick a subject of even mild interest to me, add a dozen podcasts on the topic. Listen to a few episodes from each podcast and delete the ones that I don't like (for whatever reason). Over a period of time, one ends up with a few podcasts that are thoroughly enjoyable.
There are people who read/listen to extreme views on topics (raw food vs meat, left vs right wing politics, yoga vs weights etc).
Abstractions require a solid foundation, be it a floor below, or concrete. So, when I struggle with an abstraction, I look at its base parts, identifying what is required to understand the abstraction. What I find is I often do not understand a prerequisite as well as I think I do. Sometimes I have to go multiple levels down to hash something out, but once the abstraction clicks, it becomes effortless and as difficult to think about as any other word I use in English to talk and think.
Getting a solid foundation can be a time consuming process. If you go slow and relax, you'll find the missing pieces and everything will come together.
A more accurate representation is a mind map.
P.S. challenge yourself to solve problems with as few lines as possible, that way you're forced to find better (combinations of) abstractions
I was a CS major with a Creative Writing minor. I picked the minor as an escape from CS but over the course of my career as a developer it has been some of my most useful time spent. When I was trying to write about a thing in terms of another thing (or reading other people's much better attempts) I would look at the lower level similarities and mess around trying to make the metaphor as tight as possible. Along with that, both writing code and creatively are mostly about constant revision. So both interests kind of played off each other reinforcing that process.
Spirituality, mysticism, religion, "alternate" non-sciency stuff, but also history. When not approached with sceptic mindset but one that tries to understand it can be very enlightening.
I think it trains to think with vague, incomplete and also contradictory thoughts (its bit similar to simulated annealing in contrast to deriving a solution analytical). On a side note, its damn interesting what our heritage has to offer.
Regularly revisit it with some scepticism so you don't get lost.
I suppose.. when logic is located in the left brain hemispere, this other stuff is located in the right hemisphere. Don't fixate on only the one side. Boost it with the help of the other one.
https://vimeo.com/6986303