Pretty good advice, along with some good pointers about what NOT to do when learning a languages (ex. reading some instructional book cover-to-cover, forgetting most of the stuff along the way).
I often suggest the read-a-chapter-write-a-program-based-on-it route, just to get the practice that is really important, and to solidify some intuition as to what the machine (whether interpreter or bare metal) is doing, and to make writing future programs easier.
Side note: While I definitely applaud the idea of trying to create a language that is geared towards beginners and good for learning on, I don't know if I can get behind recommending such a language that is still under development being suggested to beginners.
Then again, I'd consider recommending lisps to beginners (if not python), so maybe I'm not the most credible source
> Side note: While I definitely applaud the idea of trying to create a language that is geared towards beginners and good for learning on, I don't know if I can get behind recommending such a language that is still under development being suggested to beginners.
I second this. Especially when python itself is very beginner friendly.
IMHO the best advice on learning a skill is just do some projects with it. I am not exactly sure, which should come first, the 1. or the 2. point made in the article.
Though I would dare to say the 2. point is more important.
By doing python projects first you familiarize with it and then if you are still on - you should read zen of python, pep8, etc..
I strongly agree. Dealing with a language in development is hard enough when you're an experienced programmer, I can't imagine trying to learn programming with an unstable language.
I tend to agree as well. The Pyret option is probably better done with a mentor by your side. If no mentor is available like they probably have in the Bootstrap (http://www.bootstrapworld.org/) program then Python is more than likely the better option. So I'd expect 99% of the people to stick with Python anyway which is fine.
Agreed - you need to experiential context to grok the concepts about best practices. Otherwise, it is just cargo-cultism. Most the great programmers I know learn by working on increasingly more complex projects and then deep-diving into the details whenever they come across something they don't know. They make this process move faster, not by doing tutorials and writing code from scratch (after the initial bootstrapping of learning a new language/framework), but by reading code from others, especially successful project. And again diving into to understand the WHY behind the implementation and this reinforce the choice and knowledge of the HOW.
Problems are not all the same: choose one that stresses and challenges the language, to gain confidence in its strengths and practical expertise.
For example, I once tried to learn Haskell and I started from little exercises (https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems)... I got familiar with syntax and basic concepts, but I was dissatisfied both with the easy, abstract questions and with the simplistic, inefficient answers using basic standard library features that are more or less the same in any language. What was "real" Haskell code like? I expected dealing with serious libraries, memory management etc. would be uglier, more difficult and more cumbersome than exceptionally terse toy examples.
So I attempted something not merely useful and small, but with a well defined practical objective, depending on external standards, requiring production quality libraries and with performance challenges: converting the metadata dump from MAME (a nearly 200MB XML file) into an easy to use SQLite database.
The task was a good test of programming language productivity because, having already used ElementTree and APSW I was sure I could write it in Python quite easily. (And I did; a complete Python implementation, able to roundtrip data back to the XML format for testing purposes, took me less time than an aborted Haskell attempt that could parse a dumb document tree using a ridiculous amount of memory.)
This project allowed me to discover many things about Haskell that are not found in enthusiast-written tutorials: the mess of incompatible and undocumented libraries, the impracticality of basic language design decisions (text handling, lack of namespaces leading to name conflicts, etc.) and my profound disgust for the commonplace syntactic tricks.
Of course, a similar challenge for Python is likely to have a better outcome: learning the difference between good and really good libraries, finding a use for many language features, remembering useful idioms nd design patterns, etc.
I get so frustrated with picking up a new language because they all seem to either be "from scratch, here is how to add two numbers" or cookbooks that assume too much knowledge.
the learnxinyminutes stuff is sometimes good. It'd be nice if there was a resource that taught languages from the perspective of already knowing another (any) language in that same family.
Show me definitions, modules, packages, namespacing, whatever, and get out of my way.
I agree with your gripes here -- absolutely agree there are a lot of languages that get it wrong.
I think there are some books that really get it right though, that show you how to do stuff, but also try to get out of your way. Some examples (in order of adherence to this point, to the best of my ability):
I read c# spec when it was in beta, going fast through it, skimming less informative parts, taking quick notes as bullet points in form of single statement or question. It was one of the best experiences, it put me in flow mode and I learned a lot in very short time. I used c# later professionally and never had problems. Great thing about language specs is that is very precise, without mistakes. The art is to read+skim+note it quite fast.
> Great thing about language specs is that is very precise, without mistakes.
I'd also add "concise" to the list of required traits for a good language spec. If you don't believe me that's important, go check out the C++ specification. IIRC it contains some 50 pages of rules on how to choose implementations of an overloaded function.
>I often suggest the read-a-chapter-write-a-program-based-on-it route
After doing some of https://javascript30.com/ I want the "30 day challenges" style tutorials in every language - I love it. I'm not sure how well it works for long term learning but it's really helped with my motivation.
> I often suggest the read-a-chapter-write-a-program-based-on-it route
Learning Perl (the llama book) was great for that. At first, I would think that I understood just from reading the chapter, but doing the exercises at the end of each chapter made me actually learn it.
Absolutely agree! In a previous life, I was working at a company where perl was just about the most recent scripting language they were using (for better or for worse), and that book was an absolute godsend. Reading through Chapter 8 around was all I needed to be productive, and I've recommended the book ever since (especially while I was at that job)
\tangent I agree with your approach of mixing theory and practice. So what's the best way to learn fluid simulation? It's discouraging spending so long on maths without the gratification of Something Actually Working.
For many years, I worked on the periphery of the programming world, but with a very superficial level of programming knowledge. I was a "webmaster" back in the mid 90s, working with simple PHP, JavaScript and VB scripts. I then went to grad school for public health and afterwards worked in several biostat-oriented research analyst roles focusing on Stata and SPSS programs.
All these jobs definitely involved a very basic understanding of programming, but I had no understanding of many important fundamental programming concepts, and had created very few programs bigger than a 1-page script.
It was only when I started to learn Python, and then C (to write Python extensions), that everything really clicked. Something about Python made it so much easier than PHP or JavaScript for me. I think Python's relative lack of glyphs, brackets, and other "syntactic noise" (my opinion only) made it much easier for me personally to grasp big picture ideas. Python also prepared me for learning C to a pretty good level (with much help from the K&R book).
These two, in turn, gave me a good foundation for branching out into other languages, eventually including functional programming languages.
But Python was with no doubt the turning point for me, and even though I do little Python work these days (ironically, I'm back to JS but at a much higher level than in the 90s), I'll always be grateful for Python.
If you've struggled with programming and haven't given Python a shot, give it a try! If that doesn't work, maybe try Pyret like this post advises (once it's stable), or maybe some lisp such as Clojure. I also know some mathematicians who struggled initially with imperative programming but then thrived with Haskell. Point is, we think in different ways, so keep trying different approaches until something sticks.
Hmmm.... I'll disagree on the "don't read a book" suggestion.
I've hung around on a number of support chat rooms for languages / libraries for a few years, and tons of the problems we hear about are things that nearly any book would've made plain. As further evidence, 99% of Stack Overflow is filled with this stuff.
In my experience, skipping the dry stuff to get started faster tends to lead to poor mastery of a system. You can absolutely waste time on the dry stuff - don't read a 1000 page book when 100 will do (or ever; huge books are usually awful) - but the details very often matter in the long run when you start doing anything not in a cookbook / tutorial. Yes, you can always go back and read it later, but very few do so. Investing a day or two in a detailed book up-front isn't that much time.
Pyret came out of the PLTgroup, the group of educators responsible for the Racket ecosystem and before that MzScheme. They have been studying and innovating on programming pedagogy for more than two decades.
What sets the PLTgroup apart, in my mind, is that it tends to row in the same direction at the low level. This has allowed it to create a robust platform upon which tools (particularly in the form of languages) can be built. Pyret is an example of this. Adding a language with the offside rule to the ecosystem doesn't cause anyone offense or raging flame wars or fuck-you forking. Imagine a PEP to add Lisp syntax to Python.
Instead, Pyret just gets rolled up into the pedagogy that is described in How To Design Programs because Pyret fits with the philosophy of building teaching languages for the purposes of teaching. Other PLTgroup languages range from Beginning Student Language (a simplified lisp) up through Racklog (a lisp implementation of Prolog's logic programming model) and pure insanity like Scribble which introduces a documentation phase to the compilation. Racket even ships with an Algol60 implementation.
At the core, the important philosophical idea is that learning programming is not learning a language. In the age of Googling into StackOverflow, that's even more the case as far as I can see.
What do you mean by the offside rule in this case? I presume you don't mean that Pyret can't shoot if it got the ball when it was behind all the other language's defenders.
Only if the Pyret was already in an offside position when the ball was last played by a team mate and it was not a goal kick, throw-in, or corner kick and Pyret was involved in active play (receiving the ball, interfering with a defender, or obstructing the goalkeeper's view)...but I digress.
Python's use of semantic white space in the form of indentation is sometimes referred to as the 'offside rule'.
Well, first off it's just a suggestion so take it with a grain of salt and ultimately do what works for you.
But I see your point and I did struggle with whether to include it or not. I think me wanting to share the great work I see Shriram Krishnamurthi (https://cs.brown.edu/~sk/) and others (Matthias Felleisen, http://www.ccs.neu.edu/home/matthias/ for another example) are doing and have been doing for decades to advance Computer Science education and really tackle the tough problems pushed me to include it in the end.
I'm just a fan of their work and this post felt like a great time to mention it.
However, I do share your feelings that most people should just jump in and learn Python as their first language. It's easy to get started, batteries included and there's plenty of resources and people to help them if they get stuck.
Python has gotten hard to learn. It's not too bad if learning it just to learn, or learning it in a classroom setting with a careful plan, but I've witnessed people trying to learn it professionally in the context of getting testing running, and it's hard to learn when trying to use a mature Python codebase that uses Python thoroughly. There's these decorators, and iterators vs. functions, and things using introspection to do invisible things, and on and on it goes.
Python used to be easy to learn. It isn't anymore. It may be a better language for all the feature additions, but it isn't easy to learn anymore and I no longer recommend it for that purpose. (I don't have a recommendation at the moment.)
>Python used to be easy to learn. It isn't anymore.
Compared to C++, C# and Java, Python is still MUCH easier to learn. Python and Ruby are the easier languages to learn. I have to agree with the other commenter, why learn a toy language only to later have to learn a real one? That is a waste of time.
Well, shouldn't it be about learning how to program. Not necessarily learning Python or Ruby? You will learn how to program with languages like Python, Ruby, Java, etc. but you will have to work with constructs/abstractions that might make sense in a professional setting but not so much in an academic setting.
Most people learning it professionally are doing it so they can work with an existing code base. How is learning a different language going to help them with that?
Right? The only reason I got hooked on coding was because I was making cool things. Good practice and CS fundamentals came later. If programming was introduced to me in this "bottom up" approach, I would have lost interest. Math education has the same problem.
Pyret (and the Bootstrap curricula in particular, where we use both Scheme and Pyret [http://bootstrapworld.org/]) really strives to avoid the purely "bottom up" approach.
Curricula in Pyret focus on building games using concepts from math, or interactive simulations using concepts from physics, or data analyses using concepts from working with spreadsheets.
I agree that a purely "CS concepts"-based approach is dry and ineffective for a huge portion of students. That's why applications are so critical, and why we build things like tables (https://twitter.com/PyretLang/status/773605473824145408) into the language, so we can give students real-world tasks to do right away.
We happen to also have carefully designed the language to allow us to teach these applications along with a rigorous programming style. Students write _examples_ that get them ready to understand automated testing, they write _contracts_ that teach them about type-based interfaces, they write _data definitions_ that teach them about structured data, and so on. But it's always in service of an application.
So I very much agree that a purely "bottom up" CS-concepts-only approach has issues.
I know exactly what you mean. I got interested in programming because I wanted to build cool things. I just dived right in trying to learn whatever was necessary to help me build games. Unfortunately, plenty people aren't coming to programming with that exploratory and playful mindset.
I also agree with you that math, CS and science education is really messed up, especially in my country.
yeah i don't think i fully understand. my first language that got me introduced to programming was python and it taught me all the basics of OOP that were important to really get me going. it's a great language with little magic. after, i moved on to java and eventually functional languages.
I do think Python is an acceptable language for beginners, but I wouldn't say it has little magic. It may feel intuitive at times, but Python's magic methods can be somewhat disorienting for students. This usually hits when students reach for-loops (and to some extent during branching due to __bool__).
Also, Python may feel like a small language at times, but it is really quite large and complex. This can be seem by imagining a beginners perspective when Googling for help with a simple list operation. The inevitable Stack Overflow answer will almost certainly use a comprehension. I would argue that Pyret is actually fundamentally less complex than than Python.
As always, the biggest issues are your goals, constraints, and resources. If you can afford to spend time in a language optimized for education, that is fantastic. If you can't afford that time, python starts to look like a good trade off relative to the languages with reasonable job prospects.
* It doesn't make me an expert, but I do teach programming for a living. We use happily use python for introductory content and server-side web content, but I can easily see Pyret as a great option for an educational offering with different constraints than mine.
I have to agree with you, Python does really have lots of magic things, such the for loop, list comprehensions and generators, to name a few.
I also teach programming for a living, and, for instance, I usually have a hard time explaining to students what a for loop over a range() means for having a index. The problem is that there are a lot of things going on behind a for-each (which is what the for loop on Python does) and it is hard to explain that to newcomers. On the other hand, for loops in languages like C are simpler to explain to newcomers, as there isn't much hidden from you, and you don't have many alternatives for iterating on an array.
I would say that the higher-level benefits of Python are best understood when you have some experience with lower-level languages such as C/C++ or Java. For students, if they have time, I would say that they would benefit pedagogically by learning a simpler language with less functionalities. If not, I would say learn Python, but expect to not understand everything at first.
fair argument. this was in college, so i had a lot of resources available and very particularly picked curricula so i didn't bump into any of the magic methods until i graduated college and used python in production.
Not sure if this will help anyone out there, but learn how to take notes efficiently first. Learning a markup language helps a lot. Be very selective when choosing a book; don't hesitate to throw away a crappy book. Avoid books geared towards getting you "up and running" despite their reviews, they're never worth it. The more sources the better. The only subjects I don't spend time on are non-core API methods; just take note that there is an API and where it is, but referring to the official documentation is better because there's never much you can add of value. Ultimately plan on spending 6-9 months of weekends or 2-3 solid months to learn the bulk of a new language if you're taking notes. If it's your first programming language picking a simple project to do is helpful because otherwise you won't know the "why".
Pyret looks nice, but I think it's misleading to say it's "Python inspired". At first glance it looks more like its cribbing ideas and syntax from Ruby and OCaml.
It's true, Pyret gets ideas from a handful of places, not just Python.
From a student or instructor's point of view, it is serving a lot of the same ends as some of Python's choices:
Toplevel code runs as a script without ceremony, the default behavior doesn't statically check types but is conservative about coercing types and overloading operators (e.g. "a" + 5 is an error), integers promote to bignums by default (though Pyret supports exact rational bignums as well).
Pyret supports docstrings explicitly, and examples/check blocks have similarities to Python's doctest.
Fields of ADT instances can be accessed simply with "." (in contrast to OCaml or other functional languages), and methods close over self on dot-access as they do in Python.
Some of these things are also true of Ruby, so that's a fair comparison as well. And things like "data", and the gradual type-checking facilities, are clearly coming from other sources (though Python is moving in a gradually-typed direction as well).
I know we were thinking about Python in particular when we made a lot these decisions, so I think it's a fair characterization, though Python is one of several inspirations.
I'm curious which parts look (more) complicated to you.
For some perspective, when teaching Pyret to total beginners, we start with arithmetic and calls to library functions, then build up to function definitions and examples. At that point, there's just a handful of syntactic constructs to consider, and they are nearly identical to Python.
Things like "data" and "cases" don't come till later, and do come with more overhead, but also are introduced to students who already have some "finger-feel" with the language. Python has its own overhead with "class" for defining structured data at a similar point, including things like "self" and "__init__".
I noted the in first example in the linked into - Python:
def square(n):
return n * n
Pyret:
fun square(n :: Number) -> Number:
n * n
end
there's extra stuff. It also kind of loses the elegance of Python reading close to normal language - if you don't know programing but can do math you'd figure the first was define a function that gives a square but be confused what (n :: Number) -> Number: was about.
Teaching and learning are spaces where many flowers can bloom, so I can appreciate the angle of this article (and thus Pyret).
To zoom in for a second: in my experience teaching, the simplicity of the outdent as a mechanism for ending a control structure is a light-bulb moment for many people. I don't think that adding "end" is helpful for this segment of the population.
And so it is with `where`, which seems to shoehorn a BDD / Rspec'ish approach which, while typical of some of the best Ruby out there, is not typical of a Python library.
Again, this approach may be great for some people, but I'll bet that it won't be great for others.
This is great post and the observation is quite applicable in pretty much every subject that you want to learn and master, not just Python. In fact, "learning to learn" is perhaps the most important skill we develop as humans and a small improvement in this area translates to order of magnitude improvement in actual learning. In PhD programs they say that getting PhD is not actually about mastering specific subject but rather developing an ability to comb through vast amount of knowledge, assimilate it and synthesize new knowledge. The first two steps is where much of the effort lies which is "learning to learn". The first mistake that most people make in first step is trying to understand everything cover-to-cover of each paper before moving on to next. An experienced person would first try to get big picture (just look at the abstract and results :)) and move on to next one. So you do breadth-first-search followed by some selective depth-first-search and continue back and forth until you build "surface" that represents the usable approximation of state of the vast amount of knowledge. This is many order of magnitude efficient than try to build most of the "surface" from the get go.
I didn't realize this wasn't for beginners until I got to this section and read that his first application was a whitespace interpreter.
Personally, coming from Ruby, I learned Python via https://learnxinyminutes.com/docs/python/ after stumbling a bit on the Python 3 import syntax, which I came to love.
My biggest complaint about python is how easy it is to learn (heh). It takes so little effort to write a script, so it feels deceptively easy to write great python. After all, as long as it works, who cares right?
I care. Your colleagues care. Your users care. Python is an object oriented language, use it as such.
I've definitely purchased some programming books with a rabid ardor only to set it down 40 or so pages later only to open another book purchased with the same rabidity.
Where did you get that from? I feel like we read different articles. Are you referring to the introduction where he suggests that people entirely new to programming should check out Pyret?
Huh? Where in the article did I say or imply that learning Pyret is an efficient way to learn Python? I said if you're a complete beginner then you can consider Pyret. As for people who already know some programming I didn't suggest Pyret to them at all.
Stating "Learn python efficiently" is one thing, but stating "My advice on learning Python efficiently" is another entirely different thing. One is a statement of fact, another is just yet another opinion.
Accepting clickbait articles degrades the quality of a news aggregator.
I often suggest the read-a-chapter-write-a-program-based-on-it route, just to get the practice that is really important, and to solidify some intuition as to what the machine (whether interpreter or bare metal) is doing, and to make writing future programs easier.
Side note: While I definitely applaud the idea of trying to create a language that is geared towards beginners and good for learning on, I don't know if I can get behind recommending such a language that is still under development being suggested to beginners.
Then again, I'd consider recommending lisps to beginners (if not python), so maybe I'm not the most credible source