Umpteenth attempt at stripping away unnecessary ru...
# devlog-together
k
Umpteenth attempt at stripping away unnecessary rules when teaching programming. (Just a mockup to convey the idea. Plan is just to use this notation with pen and paper.) Is this picture intelligible without any explanation?
i
Yes, but only because I have a sense of what's going on. The first image and the final image feel redundant. Like, why are the physical dimensions in the first image not to scale? I feel like, assuming your goal is to explain the text code, the order should be: 1. Text code. 2. Final image overlaid with measurements. 3. Final image without measurements.
But if you're also going to explain stuff as you go, rather than letting the diagrams speak for themselves, then I'd use whichever diagrams + explanations go best together.
k
The goal is to use just the notation of the first picture on pen and paper. The rest is just to explain the idea here.
i
Ah, okay. Then yeah, I'd draw the boxes roughly to scale.
And I'd also make those lines for position extend right to the edge of the paper. Otherwise, you'll possibly need to introduce the idea of the origin, and that's tricky.
Which of course means if you're showing two boxes, their position lines or shapes will probably cross unless you choose them carefully.
ā¬†ļø 1
k
The reason I'm thinking the boxes are not (shouldn't be) to scale is this is still just notation. Code for the thing vs the thing. The only problem I'm solving is that the order of 4 numbers is arbitrary and hard to remember for 6 year olds who have tiny short-term memories.
The only relative position is which instruction comes first (so yes, still introducing brain damage by Dijkstra's lights)
i
Right, because the order of the numbers and order of statements is total bogus forced on us by textual coding. Evil evil!
šŸ˜‚ 1
So, like, given these constraints, the thing you have is obvious in hindsight. But I'm not sure if the incidental complexity (like stuff not being sized correctly) is a help or a hindrance.
k
The point is to introduce order for situations (coming soon!) where it will matter.
Good point. Time for human experiments.
i
Also, remember one of the Zelda lessons: it's often best to show the player a locked door before showing them the key.
So, for the case where order does matter, maybe find a way to help them discover what happens if you don't have the "right" order.
k
Oh yes. Recent conversation, not related to programming: Me: you have to do the steps in order. Kid: why? Me: the order usually matters. Kid: why? Me: can you do things after you die? Kid: no. Me: See? The order matters. There's your door šŸ˜„ Unless you meant something else?
i
That's good
k
(The topic was: he had to clean up his room before he could have a book from high up the bookshelf.)
So yeah, I think I have this philosophical disagreement with Dijkstra and a bunch of FP folks. The order often does matter. Even when it doesn't matter, I mostly have an easier time visualizing a single sequence of steps rather than imagining a society of mind inside the computer doing independent work. So why bother introducing parallelism when it's harder to imagine and not universally applicable.
This is purely for introducing programming, of course. I can see how parallelism or non-determinism is useful for correctness. Then again, I've never been good at the correctness. Probably because of the brain damage..
i
I haven't spent enough time inside an environment where the order truly doesn't matter
šŸ’Æ 1
k
It's fundamentally impossible. Even Haskellers will agree that some domains require ordering. Their goal is to limit order to where it's strictly necessary.
i
s/environment/domain
šŸ‘šŸ¼ 1
k
Order always matters. In FP, it's encoded in the nesting of functions. f(g(x)) is different from g(f(x)) (assuming both make sense).
āž• 1
i
If you're rendering boxes onto a canvas, and you have explicit depth (so painter's algo isn't a factor), draw order ought not matter.
b
I'm sure you've seen https://worrydream.com/LearnableProgramming/ but it's really relevant —
rect(x, y, w, h)
is one of the particular examples it attacks/dissects. Would you agree order of statements is essential complexity (for your pedagogical goals) whereas order of (x, y, w, h) is incidental complexity? Or do you lump both into same mental "it matters" bucket? • Using named arguments and/or IDE hints/visualizations (a-la Bret) would make argument order clearer. • Having defaults would allow you to start from
rect{}
and learn things you can tweak one-by-one e.g.
rect{x=40}
and so on... https://code.world/ is a well-documented functional (haskell) drawing environment; it's not that order doesn't matter — but that you explicitly say how to compose them. • This gives a more principled way to label x,y,w,h: Instead of passing x,y treat them as separate translation: https://code.world/#P06ggNifxerLPWXTe_4vgmQ • You can go further and eliminate even the
rectangle(w, h)
arguments by starting from a (1,1) square and translating/scaling it: https://code.world/#P9QuT0QUN62BK0RmB1px5mw • This still leaves x-before-y convention in many places. It'd easy enough to define
translatedX(pic, dx)
etc. helpers to effectively name args one by one — by I think that's going too far, (x,y) tuples are important mental construct. • Order of
r1 & r2
does matter if they overlap, try swapping here: https://code.world/#POHjNuz9Uu64FI9TAgTxhPg (cf. Bret's section on "Recomposition"; CodeWorld is good at that šŸ‘)
Elm's picture env has similar qualities: https://elm-lang.org/examples/picture and avoids the need to track which argument goes to what nested function by using
|>
pipeline operator:
Copy code
rectangle brown 40 200
        |> moveDown 80
In CodeWorld's case, that gets painful enough that the guide has to teach how to read nesting early on (plus editor coloring paren levels): https://code.world/doc.html?shelf=help/codeworld.shelf#expressionstructure/nestingexpressions @Ivan Reese will be amused they draw block diagrams, as something the student should imagine, while editor remains textual: ("the šŸ° is a lie"?)
I'm sure Haskell can do better with fancier operators. Even other choice of arg order could help — this is bad:
colored(translated(scaled(square, 12, 2), 4, 3), red)
but if they did this, one could read each transformation and its params together:
colored(red, translated(4, 3, scaled(12, 2, square)))
Ooh try the CodeWord [Inspect] button šŸ° You may need to drag the divider to the right so picture gets smaller and you can see the inspect tree below it. It shows all the intermediate parts and how they were combined to build the picture.
k
This is great! Thank you for writing out those examples for me.
> Would you agree order of statements is essential complexity (for your pedagogical goals) whereas order of (x, y, w, h) is incidental complexity? > Or do you lump both into same mental "it matters" bucket? I try to avoid those terms 😬 "Complexity" is complex and intangible. I try to stay as concrete as possible. Here the only reason I'm trying to avoid order between arguments is I know the 6yo kids have trouble with it. The four numbers look like similar things but mean different things. They do some experimenting to figure out the first number means "how far right it is", then start working on experiments for the second, and by the time they're done they've forgotten what the first number means. So it seems like a problem worth solving. The order of statements so far hasn't seemed like a problem to solve. They already understand from reading that things go from top to bottom, it doesn't even come up. And the order is a lot more reasonable when the things being ordered have the same meaning. Draw this, then draw this. Easy. At least so far šŸ˜„ We've only done sequences of 2 statements so far. What complicates ordering is conditionals and loops, and FP does have value when we get there. You probably know that my bias with computers is to emphasize reliability above all else. The goal is to be able to have agency with the computer to the extent that you forget about the tool and focus on what you're doing. Here the kids got to experience that the math they're learning (addition, inequalities) is useful in a very different context. I think trying out lots of notations and tools and then running into limitations like, "you can't use this there, you can't do that here" moves us away from that ideal of a computer that disappears from view. This is kinda why I have them using https://akkartik.itch.io/carousel (and not at all because I made it šŸ˜‚) -- it's available on all their devices, and I know it's as close to a minimal stack as I can think of that is available on all their devices. I know what problems it can run into in the middle of a lesson, and I know what to do to get us back on track. I think that's worth a lot. More than Bret Victor's ideals. They are still important, which is why I appreciate the nudge to reread them and to find out about CodeWorld. But only if they build on that reliability and ubiquity, IMO. We programmers have a tendency to circle obsessively around notations and tools. There's some value in trying to push back on that tendency and just build stuff (that is not notations and tools).
Yes, there's definite value in a UI that lets them scrub around the numbers inside each call. But I don't have that UI right now, and my attempts to create it will also spawn bugs. Good software takes 10 years to create, but in 10 years my kids will be 16. So situated software has to respect certain limitations of time and energy, I think. I definitely do still appreciate recommendations of new tools. I can play with them and decide whether to include them. And even if I don't I might obsessively circle them at night while the kids are asleep šŸ˜‚
i
Even though it's off the main thread, I've been nerd sniped and need to reply to this thing @Beni Cherniavsky-Paskin said: > Order of r1 & r2 does matter if they overlap, try swapping here: https://code.world/#POHjNuz9Uu64FI9TAgTxhPg > Which I believe is a reply to me saying: > If you're rendering boxes onto a canvas, and you have explicit depth (so painter's algo isn't a factor), draw order ought not matter. > The effect being demonstrated is what I meant by painter's algo — things drawn later appear in front of things drawn earlier. (Yes, I was misusing the term slightly, apologies.) My point is that this isn't inherent to 2D graphics, and if you make depth explicit then what you're left with is a situation where statement order doesn't matter — drawing operations commute. Which is important because @Konrad Hinsen earlier in the thread said "order always matters", which I disagree with.
k
@Konrad Hinsen My comment was about general Turing-complete notations, in particular FP. For a specific problem domain, order may or may not matter: https://en.wikipedia.org/wiki/Commutative_property