This post was stolen from https://web.archive.org/web/20110416092916/https://jinfiesto...
OP is plagiarizing blog posts at scale, across lots of different throwaway HN accounts and fake Substack blogs.
They appear to be going through old Hacker News submissions, finding the source content, and then publishing those posts on blogs that they created. Here's when the real post was submitted to HN, back in 2011: https://news.ycombinator.com/item?id=2440364
OP, would you care to share more about your scam? What do you get from it?
Here's other examples where they did the same thing using different Substacks and different HN accounts - this is just a subset:
11 years ago: https://news.ycombinator.com/item?id=5337525 (plagiarized and submitted as https://news.ycombinator.com/item?id=40081175)
12 years ago: https://news.ycombinator.com/item?id=3425331 (plagiarized and submitted as https://news.ycombinator.com/item?id=40091392)
13 years ago: https://news.ycombinator.com/item?id=3154446 (plagiarized and submitted as https://news.ycombinator.com/item?id=40150949)
Sounds like a viable startup business idea IYAM but would need institutional and/or platform champions for initial beta users.
Perhaps with the advent of generative LLMs, this will assist in the generation of entirely personalized university assignments and exams making "replay attack" cheating impossible. Hopefully, LLMs will also semi-automate correctness verification of exams and correct answers.
(* n (* n (expt n (p-1))) etc...
huhhh?
and yes, I can do recursion.
People get so used to patterns of thought, they forget what they had to do to get there.
All that said, I can't understand why someone would find recursion complicated which probably means I'm unsuitable to teach it.
Anyway, that unindented code hurts my eyes. (It's not as bad as an unmatched parenthesis, but it's close.)
So you can read this code:
(define (expt n p)
(if (equals? p 1)
n
(* n (expt n (- p 1)))
As this more typical psuedocode function expt(n,p):
if p = 1:
return n
return n * exp(n, p-1)
Or the more mathematical framing: n^p = n * n^(p-1)
[1] https://en.wikipedia.org/wiki/Polish_notationI know Scheme is a basic programming language and a nice demonstration of how syntax trees work, but I've only seen the programming language used by academics who have been doing research for so long that they have no idea about what is and isn't simple for students anymore.
Recursion is quite easy when you get it. The problem is that "getting it" is very difficult. Even if you think you get it because you've figured out how to use it, you may not really get it. The worst part is that the same explanation can resonate with some and not with others, but most educators and textbooks I've seen pick one "correct" way to explain a concept and stick with it, so if you're not part of the segment of students for which that type of explanation works, you're out of luck and will need to figure that stuff out on your own.
It is easy once you get it. So easy, in fact, that you are tempted to forget that it was ever hard.
Using recursion safely requires a less natural pattern of thought than if/while/for. Once you get it, sure, it's easy. But lets not trivialize the initial struggle either.
I think it comes from the fact that lot of CS majors go into college with years of experience with for loops and barely knowing what recursion is. If you start from a blank slate, I am confident recursion is much easier to understand.
Of course the next phase is trying to do everything with recursion.
Induction is literally the simplest type of proof you do in math, and of course there's a 1-1 relationship between induction and recursion. Induction is also the basic way that you discover/invent an algorithm in CS, which is usually taught in junior level CS algorithms classes in all the top colleges.
So I think it's just a problem with people just not learning a fairly simple concept or just skipping intro to algo classes altogether.
(Maybe a bad example; I feel like it shows that people are familiar with coinduction.)
I'm not even sure that iteration was easy for them.
Just because it is easy for one person does not make it easy for another. There are some people who love high school geometry and hate high School trigonometry, and vice versa, because the former deals with proofs for the most part and the latter deals with application (at least when I was taught it).
> you just need to assume the sub-calls do the correct thing.
This is technically correct (and I remember hearing it when first learning recursion), but it's not useful. The two most common problems were not having a good stopping condition, and handling two or more levels per call because they didn't understand at what point the function should call itself.
I think the first thing that needs to happen is just draw a diagram of common data structures and show how they can be looked at as a recursive data structure. Like a tree is a node and two more trees, or a list is a node and another list. As odd as it may sound to some people, I think starting with something that has a visual representation like that (even if it's more complicated in code) is easier to understand than pure math like recursive fibonacci.
This would also double as an answer to the "why would I use this when I can just use a loop?" question. Just challenge the student to walk a tree with loops instead of recursion to see how much more work it is.
The problem with for loops isn’t the loop. Loops are easy to understand. The problem with for loops is that you have to maintain mutable state across iterations, which quickly gets very complicated. Recursion is useful specifically because it doesn’t need mutable state.
The point is that within the abstraction you're working in, recursion is entirely immutable, and loops are not. Good programmers selectively forget about stack pointers and RAM and the heat death of the universe when they're writing code -- they put on the correct "costume" for the part of code they're in and they never go "out of character". Worrying about the stack pointer is like having your Starbucks cup in the shot of Game of Thrones. Danaerys Targaryen doesn't know WTF Starbucks is and your programming avatar should not know WTF a stack pointer is.
This problem is possibly confounded by the fact that some recursive definitions in computer science are "incomplete" or "circular" (they can be proved not to terminate, or cannot be proved to terminate, and so can't actually be evaluated!).
We're used to the idea that a circular argument (the original sense of "beginning the question") is unpersuasive and that a circular definition or answer is unhelpful. So it's subtle to see when a partly self-referential definition can actually be usable.
In functional programming languages you might only be able to use recursion when you can prove it always reaches the base case (to define a total function), but that requirement is itself somewhat subtle!
Struggling through mathematical notation, or learning technical material in school, can be brutal. Never confuse the medium with the message.
But they never get around to explaining how to teach it better, so why do they say we should cease labeling it as challenging?
Is this a humblebrag post?
1) It’s reputedly hard, but isn’t at all, so I spend way more time convincing myself I’m not missing something (“I must be…”) than I do learning it. Pointers; recursion; “dynamic programming”; various concepts that basically only Haskellers talk about.
2) A huge proportion of explanations are just, unaccountably, confusing as hell and make it seem way more complicated than it is. Bad beginner OO explanations; literally any explanation of anything in which the examples are in Haskell.
The concept of pointers isn't too hard if you know how memory works, but that hasn't made working with pointers any easier. Any serious work with pointers quickly devolves into questions about ownership, lifetimes, and figuring out the proper sizes. Plus, many educators seem to skip verifying that students actually know how memory works before introducing pointers, which leads some students to believe that pointers are some kind of language feature rather than a core concept of modern computer hardware.
Lest you think I'm just a bragard, I never managed to get better than a C in any calculus course.
(If you have a tail-call optimization, many kinds of recursive process don't require a stack and don't risk an OOM condition!)
That doesn't mean its natural for humans to understand.
I understand that there are lots of algorithmic tasks that are best understood that way, and that those aren't what you were talking about.
If you can sit through 5m of slides: https://github.com/lelanthran/frame/blob/master/docs/FrameIn...
Anyway, it's basically just another way of structuring the state of a loop. And if you're doing tail call recursion then the distinction essentially doesn't exist.