Why not Logo as a first introduction to programming? Why muddy the waters with anything other than writing little programs to make a turtle draw flowers?
I know, it’s not web development, but it does present the broader concepts in a way that fully digestible!
I just don’t see how someone with no experience at all with programming can ever be expected to make an interactive web page in just 6 weeks.
> I just don’t see how someone with no experience at all with programming can ever be expected to make an interactive web page in just 6 weeks.
I think it's possible with mentorship + React, esp. because many of his students may have had prior programming experience. Start with something cool to motivate learning how something works.
The usual problem is that students aren't interested unless they can see a direct path to employment. Logo doesn't fulfill that, obviously.
I can never quite decide if web dev is a blessing or a curse for learning programming. Whilst the learning curve for HTML/CSS might seem shallow, that's partly because these aren't programming languages. Teaching these things may feel initially productive because they're quite simple and you get immediate tangible results, but it sucks up time that could have been spent tackling an actual programming language meaning. When Javascript inevitably comes there isn't enough time left to teach it slowly enough, and students are struggling to bridge multiple technologies together that don't share anything in common.
Right, like I said above, you have to be VERY upfront about the huge chasm of differences between "theories/ideas that are important in programming" and "the pile of cruft you necessarily have to get through to get to anything REMOTELY useful today."
The new approach in mind is how many of us who learned basics of programming as kids have done it, or learned anything at all. Makes sense to me.
Learning immediately about for loops, functions, variables, parameters, and any other concept you might consider basic, is putting a mountain of abstraction in front of someone that most are not prepared for.
As such i think within the context of your web course that new approach is going to make it a lot easier to get started. And I’m sure there are plenty of places for hooks for those students that want to go deeper :)
If we taught functional programming first, there's a log we can do without. We don't need variables that vary--only reference names that are assigned once within a scope. We can also eliminate loops and associated off-by-1 mistakes using map, reduce, etc.
This of course puts different 'hard' things up front like applying a function over a collection of data, but that's one that scales well, IMO.
But we also hit recursion sooner, that could be a difficult hurdle as it requires a big 'trust me this works' until a better understanding is gained. Again this scales better as it teaches making a smaller instance of the problem to solve at each level/layer that's universal in decomposing problem into similar and/or dissimilar parts.
Were there many that seemed to have more difficulty with this introduction than if they were shown a procedural language, that you noticed?
My hunch is that to complete beginners a declarative approach is simpler than a 'play computer' mental simulation to coding. We shouldn't be initially shown what's effectively a Turing machine and save that for a later Theory of Computation or intro to procedural languages.
> And then came JavaScript. Well, along came real computer programming. It could have been Python or some other language, I think, but the transition to writing programs, even short bits of code, took the wind out of the students' excitement.
The big change here is the procedural (time/execution steps, mutable variables) nature of these languages. Functional programming can be taught from a declarative perspective which is more along the lines of HTML/CSS.
> This of course puts different 'hard' things up front like applying a function over a collection of data, but that's one that scales well, IMO.
I think this depends on the audience. If you want to teach programming to people with less talent/passion for math, I believe you can have more success with procedural/imperative programming, which IMHO requires less abstract thinking than functional programming.
I'm on the fence about this, which is why I'm interested in hearing about cases where FP is taught as an intro. I sort of suspect that the younger folk (as in children) may be more comfortable with FP when you tell them that this phrasing does such-and-such without further explanation or understanding and be able to apply it. Grown-ups will question why a self-referential function can work at all and perhaps get hung up on it until they grasp recursion.
In short it requires more abstract thinking to understand it, but understanding isn't necessarily required to apply it effectively.
I think in some ways functional programming is easier to understand conceptually; it's a closer match to how I think about things. Like if I want to transform an array, I don't think "I want to create a new, empty array and then loop over the first array and call a function on each value and put the result in the new array", I think "I want to run this function on all the values in this array" (same for filter, same for find...). Reduce is a bit trickier, perhaps, but if you start with the example of finding the sum of all the values in an array that probably lays a decently intuitive foundation for it as well.
So yeah, I don't consider myself a particularly math-y person, but I find functional programming to be a more straightforward and less fiddly way of going from a design in my head to something the computer can execute.
> I want to run this function on all the values in this array
I think most people get lost on the "run this function".
My impression from high school math classes is that very few people understand the concept of a function in abstract terms. Like, they will learn that sin(90) = 1, because it's a particular, specific function, but they don't understand functions as "first class citizens" in the sense of "apply this function to this array". That seems like a new plane of abstraction to which many never get.
Hmm,that could be--I've been doing this long enough that I've probably forgotten some of the things I struggled with. It feels like it would work to say, "Here's this graph of a sine curve, and what that means is if you take a value you want to find the sin of on the X axis, and trace upwards until you get to the line, and then over to the Y axis, that's the sin of that X value [draw a couple of examples] and if you have a bunch of X values that you want to calculate the sin of, you can put them in an array A and use A.map(sin) and the result will be a new array with the corresponding sin values [draw input array A with the same values as the Xs selected on the graph, A.map(sin), and a new array with the corresponding Y values as from the graph]"
Sure, it won't work for everyone, but I'm guessing (hoping?) that "functions as first class citizens" won't seem that weird to people who have never worked with a language where they weren't
I think the hard part is trying to imagine 'run' combined with 'function'. If you present a picture of a collection of data, a function that maps input values to outputs, and a picture of the output collection of data, that's fairly easy to grasp. The difficulty comes from bothering to describe how the computer does it by running a first-class function on the data. And that's the part of understanding that could be delayed IMO. Treat more of programming as declarative rather than procedural.
> If you present a picture of a collection of data, a function that maps input values to outputs, and a picture of the output collection of data, that's fairly easy to grasp. The difficulty comes from bothering to describe how the computer does it by running a first-class function on the data
I think your describing the solution to the problem: this is how (pure) functions are introduced in high school or university, and that's also what they fundamentally are defined like!
Of course no function in a computer program is really a black-box, but introducing
f: A -> B
as a black-box gets you far enough for all practical purposes! Defining the properties of a mathematical function and the related categories of injective, surjective and bijective maps between sets is all one needs to know about a (pure) function.
And when it comes to e.g. f(x)=sin(x), how many programmers or high school students could write down an algorithm to calculate e.g. sin(1/4) out of their head?
I know it's a long-solved basic algebra question, but treating functions as black-boxes can be perfectly fine.
When it comes to programming, of course, shared mutable state (i.e. lexical scoping) and how actual functions in some language relate to these concepts is the meat of the problem.
But even this space can be explored without knowing complex FP concepts. And JS is a great language to do so :)
Any JS programmer learns about the difference between a pure function and an impure "function" in some intuitive fashion sooner or later, because lexical scoping is so much at the heart of the language.
So much that day-to-day work can even include a fair amount of shifting around logic between shared mutable state, function parameters and captured closures.
Fundamentally, this stuff takes a certain shape of brain to get. Either it clicks, or it doesn't (not that it can't take a good while to click). I have seen the specific thing that most people won't get inaccurately described as 'variable assignment', I think it's more about looping, but either way, you can do it or you can't.
You always read about someone who's trying a new method of easing students into it, confused why everybody else puts stupidly hard concepts up front. Then, later, they post about their rather high failure rate, and possibly lament that there are not enough battle-tested educational resources that are designed for this tack and that's why they failed.
What's really going on is that when you put something 'hard' up front, the class self-separates into people who get it, people who think they can get it but don't yet, and people who are not going to get it, and the latter group quits.
Being able to code is a lot like a Hogwarts letter: there is a lot of learning to do, there is a lot of variation in ability, you cannot do much without being taught, but there is also a baseline of being able to do it at all which most people fall short of. If you wind up with a class that cannot necessarily all do magic, the earlier you say 'now, let's all make some magic sparks', the more you have time to teach the students who can.
I'm not convinced that putting hard things upfront will be good enough to separate the weeds from the chaff. Specifically, I fear the false negative rate would be pretty high, which is probably fine when you're hiring for FAANG, but possibly not suitable when teaching at a school.
So, I literally teach all of this, and I think the biggest thing to get people to understand is that -- the stack you use right now is a product of evolution, not intelligent design.
It's a minimum of THREE languages to get anything going using the presently most popular programming language; and that includes the stupid fights over whether all three of those are ACKSHUALLY languages.
The environment feels almost hostile to onboarding by design, so you have to STRONGLY distinguish theory from practice.
Sure, but overwhelmingly "the web" is what people are interested in -- in a way, it's more of a default "operating system" than most operating systems.
As in, if you could design "programming on the web" from the ground up, I'm going to guess you wouldn't base it on technology designed to make reading on the web a look little more like a newspaper plus hyperlinks, and then yet another language that sort of does the same thing but...more, and visually oriented -- before you even get to, and not strongly integrated with, real programming logic?
I’m very much teaching the same thing - an eight week introduction to JS (after 6 weeks of HTML/CSS).
My approach was to lead with one week of unplugged programming just introducing the concepts of CS. Then introducing the fundamentals of variables loops etc using a block based language.
The following week we transition to JS doing one week of fundamentals and after that moving on the DOM and events.
So far I think it has worked out pretty well. A key part is to work both bottom up and top down at the same time until things eventually click.
Teaching Javascript as part of a core curriculum (i.e. a course everybody has to take) would be a lost cause, because the syntax makes it completely unapproachable.
And that's before you have to explain how some interactive functionality exists in plain HTML/CSS (accordions, hover states, animations), but in order to attach them to button clicks, you suddenly need a programming language with a largely unforgiving syntax (an errant comma after the final object property) and behaviours (event.preventDefault).
And if you manage to wade through all that, and are ready to build a modern program, you would then be told to learn about React, the shadow DOM and server-side JS, another 3 things that don't look like anything you previously learned.
I've been teaching web dev for ~10 years, I learned early on that with JavaScript, the programming fundamentals need to be introduced in bits and pieces. The class hits a wall otherwise. As much as I would like to focus on programming fundamentals first, a class of adults needs to know and get hands-on experience with the why asap to keep them engaged. So I introduce some DOM basics early like the author outlined (except for the last two items).
It also really depends on the profile of the students themselves. I teach at a coding bootcamp now where we also have short courses on just front end web development. The bootcampers are typically more amenable to a front-heavy, bottom-up, fundamentals-first approach. The short-course students need more hand-holding.
They should teach one thing to solve in JavaScript (cannot be done in css, useful without impacting accessibility).
Code must pass jslint.com with no warnings. And all the things used like loops and branching should be explained with a few examples.
And you don’t tell them about the other ways to do the same thing. You tell them the one way that uses spaces, double quotes, i+1 and === (they’ll find out about all the wrong ways on their own later). And obviously no Dom shenanigans in these initial lessons.
People must solve something and understand how they did it so they feel good. It’s very easy to teach and nobody does it like this. So people get scared and want typing and OO classes for their this.JavaScript later.
People learn differently so I won’t pretend my method of learning is the Best Way but for me I learn best “on the fly”. I learn best when I have a task I want to accomplish and I learn enough to take the next step, then the next step, then the next. I’m fine taking “breaks” to learn new concepts as they are needed but I need to see incremental progress to keep up my “steam”.
At least when I’m doing something completely new. If I’m doing something I’ve done many times I can write the entire front and backend and not see real results until the very end but if any part is new then it’s imperative that I get something basic working and iterate on that.
When I’ve been asked “how did you learn programming”/“how should I learn programming” all I can give is what worked for me. My first foray into programming was my TI-84 SE calculator, mostly so I could make “games”. Then a Java course in HS and then my real explosion in programming: learning PHP on my own. You have to have a goal/desire to propel you forward. With my calculator it was making games, with the Java course the addition of so many control structures (vs TI BASIC) was mind blowing, then with PHP it was the ability to create something that anyone could see anywhere in the world (with an internet connection). But with PHP (and later JS) my learning was in fits and starts as I needed to learn more to accomplish bigger/better things.
So my advice on learning a language is simple. Have a goal of some piece of software you want to make and take baby steps towards that learning what you need in the moment to get a tiny step closer. Yes, you will write shit code. Yes, you will probably rewrite or want to rewrite code as you learn more. Yes, your early attempts will seem childish in retrospect. None of that actually matters though, this is about learning, not creating something with 10 9’s of uptime that runs flawlessly.
The method of teaching all the concepts up front has never worked well for me. A short explanation and examples of how something can be used is powerful since even if I don’t need or understand it today I will remember that it’s possible and come back to it later when it solves a problem I actually have. Nowadays I do at least scan through docs on languages/frameworks/libraries. Not to absorb every bit but to “prime my index” for later. However none of that would have interesting or compelling to me when I first started programming, I had to see something come alive and iterate on that instead.
I still remember the first time I got PHP to spit out “Hello, Josh” and “Josh” was nowhere in the code, instead it came from a GET param. Pure magic. Yes it was stupid simple but that drove me to learn more, to learn about POST, to learn about cookies (you can store stuff!?), to learn about databases (holy shit you can store more stuff! And it can be private!), to sessions, and more. It all started with a GET param and that sense of wonder/magic/excitement.
I know, it’s not web development, but it does present the broader concepts in a way that fully digestible!
I just don’t see how someone with no experience at all with programming can ever be expected to make an interactive web page in just 6 weeks.
reply