Racket: Lisp for Learning
lwn.net
lwn.net
(The comment about the wife spoiling him to use java seemed more credible)
https://mobile.twitter.com/ID_AA_Carmack/status/807797812700...
A former employer was led by huge Clojure fans, who requested that the backend be Clojure, and highly encouraged me to use ClojureScript and something like Reagent for the front-end, which I recently noticed that they finished after my departure. But the more I think about it, the more I can't think of a single feature of ClojureScript that's inherently better than JavaScript, whereas s-expressions are inherently hostile and also have no real-world benefits. JavaScript has destructuring, closures, a flexible module system, object/array spread, basically every syntactical feature Clojure has, but without the s-expressions.
The commonly touted benefit of s-expressions is homoiconicity (code is data), which lets the developer customize the language via macros without needing to wait on the compiler/interpreter authors. But we have this exact same benefit in JavaScript with compilers like Babel. Maybe it's pushed onto another layer of development, but it's in no way less legitimate or useful. The slight benefit you get by being able to do this transformation at runtime is negated by the inconvenience of s-expressions. (Although at first glance, it seems like we could use a better Babel API that lets us transform our code more conveniently. But I think they're working on that?)
The main other benefit I commonly see from people using Clojure or ClojureScript is live development. I saw technomancy made some blog posts about how he used Fennel (a Lisp that compiles to Lua) to do live-coding stuff in Love2d. I was impressed, until I realized that none of these features were specific to Lisp. So I borrowed the same underlying concept he utilized, and started to make a really cool Love2d live development thing just like he had, but in pure Lua.
Now I have the ability to press Cmd-E in VS Code while editing some Lua file, and if I have any code selected, it'll be sent to the live Lovd2d game that's running, to be eval'd, and if there's no selection, the whole current file will be sent. It's the coolest setup ever, almost identical to the awesome setup I had with CIDER + Clojure + Emacs, but without Emacs or s-expressions.
Persistent data structures, multi arity functions, multi methods, transducers, data oriented design, spec, repl driven, better live reloading, meta data, protocols, core async go channels, atoms, Datoms
There are breakthroughs in Clojure/Script that literally do not exist in any other language, let alone JS
Datomic, Fulcro, Crux, garden, hiccup, honeySQL, rebl etc just straight up don't have equivalents in other languages
Your statement blows my mind, sure you don't need s-expressions to do most the above but you can just turn on parinfer and treat it like python whilst still being able to dynamically rewrite source code using data manipulation
Multi arity functions: That's actually a minus, not a plus. The vast majority of the usages of this are solved with options params with default values in a much clearer way.
Multi methods: In 5 years of using Clojure professionally, I think I've never seen these used once.
Transducers: This is just an optimization, and I'm pretty sure it's possible in JS too since it's an API design.
Data oriented design: This is a design practice, it can be done in JS too, and it's a questionable one too.
Spec: When Spec came out is around the time I realized the period of true Clojure innovation is over, which peaked from around 1.3 to 1.5 or so. TypeScript is by far a better version of adding type innovations to a dynamic language.
REPL driven: You can do this in any language with a REPL, even JS.
Better live reloading: This is just as good in JS. There's no language feature of ClojureScript that makes this better than in plain JS.
Meta data: The only times I've ever seen this feature used was in storing internal representations of things in DSLs, which can be done in JS by using plain objects for their representations which store an inner object.
Protocols: JS only doesn't have this because it's duck-typed and they are implicit. An explicit counterpart exists in TypeScript's interfaces for those who want it to be explicit.
Core async, Go channels: These have to do with threading, but JS mostly exists in single-threaded runtimes, so it's non-applicable.
Atoms, Datoms: These are library-level concerns which are doable in JS.
1. Parentheses are inconvenient.
2. Everything you can do in Lisp you can do in $other_turing_complete_language.
What you're missing in (1) is that as much as you wish you were stating an objective truth of the universe, you're really just stating your own subjective impression. If parentheses were objectively, universally inconvenient, nobody would ever program in Lisp. And yet many do. So what's the explanation for that?
What you're missing in (2) is that although (2) is certainly true, it's irrelevant. If (2) were relevant, nobody would ever prefer any Turing-equivalent language over another. And yet objectively, people certainly do. So what's the explanation for that?
The other thing you're missing in (2) is Greenspun's tenth rule, but I'll let you look that up.
Why, they are impractical buffoons who lack the benefit of my own vast personal experience, which trumps everything. Or else blind zealots.
When all these things are baked into your language, you're free from all the worries and cognitive load to make sure everything works as you expect it to work.
I used to write C and C++ code in (non-vim) vi, with only autoindent, and it was fine. I could also type the spaces, if I had to.
For s-expressions, like in a Lisp, you want autoindent a bit more, and some kind of of paren-matching/highlighting is also important.
Fortunately, editors have been doing autoindent and paren-matching for decades. And once your editor is formatting your code correctly, it's pretty visual, not textual.
And few people write any code in something like non-vim vi or notepad.exe anymore, so I see no reason to think less of a language for wanting an editor/IDE developed in the last couple decades.
There's no need for paredit, AFAIK, but paredit is another thing for which s-expressions are especially well-suited, relative to most other syntaxes. (You can also do paredit-like structural-based navigation and editing of JS, for example, but you have to have a clear model of the syntax structure, not only in the tool, but also in the programmer's head.)
I concede that I do not do any web or graphics development at the moment, this might help. But it's deeply satisfying to be able to discover new helpful functionality in the tools that are there for decades. And it's good to be able to use them almost everywhere, be it on a server over ssh or on a windows box with cygwin.
Just not on UNIX culture.
Interlisp-D, Lisp Machines, Smalltalk, Mesa/Cedar, XDE, Oberon were an OS as IDE.
UNIX is a poor imitation of their capabilities.
Oberon is interesting because the 2013 book goes much further than any recent system in this regard. One of the (final?) chapters even describes how to implement the custom processor in an FPGA.
I enjoyed Lua's simplicity, portability and execution speed. It shares much of JS strengths, with fewer quirks. I was productive after a weekend of reading Programming in Lua book.
Clojure took some more time because I had to unlearn some habits. It's for the best, I think. It's not just about homoiconicity and REPL. In Clojure it's hard to do the wrong thing, compared to JS or Lua. The language makes it easy to isolate a small piece of functionality, develop and test it, and then and put it together into coherent whole. Clojure may be harder to learn, but the cognitive load is smaller and it scales better for large projects.
Persistent data structures are also huge step forward. They eliminate whole class of errors and allow for traceability and reproducibility.
As for s-expressions, yes, they can be a nuisance in editor without proper support. I'm getting by with SublimeText + zprint auto-formater. For REPL I found no better than Atom's proto-repl. Also I hated Lua's "if..then..else..end" and other verbose constructs. I'd say s-expressions are more consistent and compose better. Still, your frustration is familiar to me.
I've seen and even written a lot of really really awful Clojure code which technically fits the criteria for good code, on paper, but completely misses the bigger picture. (People have made the same argument for Go, that it's idiot-proof, but I've seen plenty of awful Go code too.) I'm more and more convinced that bad programmers will write bad code in any language and good programmers will write good code in any language.
BTW, for Sublime, you could install the Terminus package to get an integrated terminal to run clj(1) in. Then with a few lines of Python, you could write a command to send text from the editor side to the REPL side.
(I have a half-baked enhanced Clojure package with some features in this vein, but it's not public atm)
Clojure also interacts with Java, but it feels like CLojure is the host that runs Java methods as needed. The separation is clean and you know exactly when you are crossing the boundary into stateful territory.
I see the value of those languages for lispers wanting to script the platforms where Lua can run, but not really as a core language for modelling your domain.
As an example, my team has been using Reagent on the front-end for around 5 years now. We've never had to go back and change code to accommodate changes in ClojureScript or Reagent in that time. And we don't have to deal with stuff like JSX because HTML can be expressed using regular data structures. Things just work. Meanwhile, React itself has had many changes, and some of those are breaking.
I also find that tooling for ClojureScript is strictly superior. You get REPL driven development, reliable hot loading, minification, code pruning, and code splitting out of the box. All these things are difficult to do with Js, and don't work reliably with many NPM modules.
1. https://yogthos.net/posts/2013-08-18-Why-I-m-Productive-in-C...
It's also possible to avoid JSX completely, thanks to a library that uses JavaScript's template strings feature: https://www.npmjs.com/package/htm
Culture matters, which is why I should probably learn Rust...
I'm still learning about Scheme/Lisp, but doesn't hot-loading have to do with the size of "compilation units?" Isn't a single s-expression treated as a compilation unit whereas in a language like Java, the compilation unit is an entire Class?
Rich Hickey touched on this in a comment here on HN (2nd paragraph): https://news.ycombinator.com/item?id=2467809
Most of projects wouldn’t even consider writing a loader for a compiler or using a syntax parser. Yet to add which method is more prone to errors.
(And, of course, meta-programming is powerful, thus 'dangerous', but there's a lot of things that are only really feasible with it.)
Then, one day, I turned it off. I'm not sure why.
I think it's because I didn't want to get too attached to it. I reasoned that Paredit wouldn't always be in the places I was working with Lisp, so I had better remain flexible enough to not need it. And between the editor's paren matching and the way I format my Lisp code, I can be pretty productive in Lisp without Paredit or a similar structural editing tool.
Also, AFAIK Paredit is pure Elisp, so should work just fine in Windows.
But really there are lots of other, better reasons to use JS over Racket for a major commercial project, which may or may not be actually a good call, but a new proposed syntax is not one of them.
> No matter how Racket evolves, the community is committed
> to preserving what we have achieved: today's `#lang racket`
> programs will run in the future, and today's
> `#lang racket` modules can be used in future Racket programs.
I've found a little quirks in the standard library, with simple fixes, but annoying. Stuff like decimal->string (?) producing odd output. (It was a tiny fix on my end, but it's a little subjective, maybe the behavior was intended) Not a big deal, but maybe a little impediment for learners compared to python.
The article mentions Scribble, which I use as a static site generator for a a page with a leader board for EDH games (and maybe adding 9 ball lol). Some small CSS changes made it OK for cell phones (basic changes to make it responsive so it's ugly but readable), but as is it sucks, and the maintainers have no interest in changing that.
Dr. Racket is unfortunate. If I remember correctly it has a tabbed interface, but right clicking on the tabs does not bring up a menu, and the tabs might not have close buttons either? It's not bad, but inferior to any dedicated editor.
OTOH, I keep using it for little tasks, I like the language, and I seem to be one of the few people who are excited about the Racket2 syntax, so I think I will stick with it. I had been considering switching my lisp use to clojure.
- Yes, there are some quirks in the standard library, but overall most of it seems very well designed. Having spent a bunch of time in Python, which also has a standard library with I'd argue even more quirks. But most Racket libraries seem very carefully thought out IME; I'm not sure that something this old can not have some weird oddities though. - We used DrRacket to teach a class to students who had never programmed before. What's amazing is that a) the students picked it up quickly and immediately... what other lisp can claim having something like that? and b) it's the only editor that I myself am happy to use other than Emacs. That's an interesting and unusual overlap, and deserves a pat on the back.
Yes, Racket has its quirks, but what doesn't? It's still an extraordinary project, community, development environment IMO.
I like the design and the ideas it has for teaching, but I can't imagine it being usable performance-wise on the kind of machines that schools usually purchase.
Also, I think we'd be happy to take patches to improve the Scribble CSS for mobile.
I'm not web guy, my changes are pretty haphazard, but I'm not the first person to notice this. https://github.com/racket/scribble/pull/62 is a rejected pull request (with you as a reviewer, so I'm sure you know that it doesn't work well currently, on my iPhone SE at least, maybe larger form factor phones do better)
> Pascal is for building pyramids imposing, breathtaking, static structures built by armies pushing heavy blocks into place. Lisp is for building organisms--imposing, breathtaking, dynamic structures built by squads fitting fluctuating myriads of simpler organisms into place. - Structure and Interpretations of Computer Programs
Now, let's make sure we're finding ways that can generalize. It's an important problem in the world today.
Most of the points in the article are valid, and I especially agree that Racket or another Scheme should be taught at some point later on. Maybe even implementing a Scheme as a final course project or something like that (although that might not make sense outside a compilers class...)
I recommend HtDP and Racket semi-regularly because 1) the incidental complexity of getting started with DrRacket is so low and 2) I don't have a better recommendation for a book that covers the same fundamentals.
Do you have suggestions to recommend instead?
In general, people learn from presentation of material, participation to demonstrate understanding, and then receiving feedback. They need to be motivated and engaged. If you're asking how I would suggest someone self-learn something, I would suggest that they find a cool project that they're excited by, and then offer resources based on that. Ideally ones with interactive feedback and tons of examples.
A book isn't the only option, certainly.
You're not, however, objecting to Racket itself, the practical programming language platform that enabled building the HtDP progessively-powerful teaching languages and their beginner IDE?
It's sort of saddening to me that the average CS student exposed to this stuff doesn't experience the sublime when S-expressions suddenly click, or whatever.
As I said in another part of the thread, having it later in the curriculum makes sense. I'd love to subject everyone to a Programming Languages course. At Virginia Tech, they called it Comparative Languages. Here at UD, there used to be a Junior level SICP course. I wasn't around for it, but I think it was brilliant and well-timed. A lot of the problem came with trying to move those realizations earlier when folks aren't as ready for it - plus, all the other associated problems I raised.
I've wondered what my reaction would have been if I had started with something like SICP or HTDP, and wondered if it would've saved me some headache. It's interesting that your real world experiences reflect that it might not have been as enlightening as I wondered.
Edit: "might NOT have been as enlightening..."
Thanks for the reply :)
As I brought up in the post, the domain was from a joking argument with my colleague. He started it when he bought ihatepython.com. The fact that he hasn't fleshed it out is a disappointment to us all :)
* Industry is moving towards FP. Teaching Python or Java is teaching students a way of programming that will increasingly be out of date
* In my day to day programming (Scala) I lean very heavily on the concepts in the design recipes. Understand them and you can create correct code very quickly.
No data here. Just something to think about.
... Citation required. My dad will be writing COBOL till the day he dies, and most of those lines of business logic in Java will bit rot before they get converted to Scala/Haskell/Something else.
I thought you were going to make the more palatable argument that most modern languages refuse to stick to one paradigm. The fact that Java has lambdas now demonstrates the appeal of these other approaches.
Saying that imperative programming will go out of date... Well, that's a bold claim. I vote we meet up in 20 years and whoever is wrong has to buy the other one a beer :)
OO was the dominant paradigm in the 1990s and 2000s, and legacy COBOL, C, etc. code still existed back then. Legacy code will continue to exist as the industry moves away from OO. New languages and frameworks are taking inspiration from FP: Typescript, React, Scala, Swift, and Rust are all examples. Even Java is moving in this direction.
In the same way the majority of OO programs were not written in Smalltalk but instead in C++ (C with OO bolted on) or Java, FP programs won't be written in Haskell, but in languages that bridge the old and the new.
The key idea of FP is static understanding of code. This drives everything else: "pure" functions, types, composition, etc. FP is not against effects and mutability. It's against uses of effects and mutability that make reasoning hard. Rust (affine types) shows you can have mutation will retaining reasoning about code.
The design recipes give you an excellent foundation for transitioning to a statically-typed programming language with algebraic datatypes. If students are just going to learn Java or Python immediately afterwards, I think it's a waste.
Yes, so we should look at the relatively more massive amount of research done for languages like Java, Python, etc. SIGCSE and ICER and ITiCSE are full of them. We've learned a lot - learning is hard :)
> Intentionality in the design of a curriculum is better than an ad hoc curriculum.
I strongly agree. I wish I could impart to you how involved I am in Instructional Design with my work. I don't know if this will help, but here's a sample from what I was doing last year: https://acbart.github.io/python-sneks/
> The design recipes give you an excellent foundation for transitioning to a statically-typed programming language with algebraic datatypes.
I'm not clear that that's more than a theory. Even if it's true, is that necessarily the major goal in CS1? Perhaps, but you'll have to convince a few of my colleagues of that.
> Which language should be used in a CS1? There isn’t very much research to suggest conclusively what makes the biggest difference in a classroom, and it doesn’t seem like the language debate will ever end.
But now you're saying there's a massive amount of research for Java and Python — so I think we must be talking about two different things.
> I'm not clear that that's more than a theory.
It is less than a theory — it's my opinion based on my experience going through the edX How to Code series (closely based on HtDP and the design recipes). For example, sum types are taught as "Enumerations" [0], and the design recipe for enumerations looks suspiciously like "pattern matching in a language without pattern matching", as if to prime the student for a language that supports this more conveniently.
Yet, if the student learns Java immediately after HtDP, they will have no use for this knowledge (and probably forget it), as it seems you need some convoluted boilerplate like the visitor pattern to emulate a sum type [1].
> Even if it's true, is that necessarily the major goal in CS1? Perhaps, but you'll have to convince a few of my colleagues of that.
Given that the follow-up material to HtDP was called "How to Design Classes" and used Java [2], no I don't think this is a goal of (PbD's) CS1. I'm saying I think it should be to make the curriculum cohesive, and that HtDP is a wasted investment of the student's patience without related follow-up material. I really loved HtDP so I wish I could find such material.
[0]: https://htdp.org/2019-02-24/part_one.html#%28part._sec~3aenu...
[1]: https://stackoverflow.com/questions/48143268/java-tagged-uni...
[2]: https://programbydesign.org/materials (You can see it mentioned but it doesn't seem to exist anymore when you follow the links)
Racket was primarily designed for teaching and has been somewhat successful in that regard. I don't know of an empirical study, but if you attend a RacketCon or go to a Racket Summer School you will meet educators who talk about how Racket has positively affected their experience in education.
But maybe part of the issue is using Racket for what it's meant to be used for.
Racket is good for teaching computer science, which I'm contrasting with software engineering (often just called programming, although I don't like that). It seems like most CS programs at universities are really SWE programs in disguise. Of course, this is often what the students really want: a program to help them get jobs in industry.
Racket is good for building a slightly more mathematical framework of programming than a language like Python. The functional nature of the language promotes thinking about problems in terms of data and their relations, instead of in terms of procedures and state manipulation which tends to be how imperative languages are learned. (This is not to say that imperative languages can't be used well, or can't be used in a "mathematical" way, but this tends in general not to be the case.) If the end-goal is to teach students how to approach programming mathematically, then they are more likely to learn better with Racket than Python.
You will also have a problem now with students who have some prior CS knowledge disliking Racket because it doesn't aligned with their not-yet-fully-built notions of how programming languages work. The larger your classes, the more influence this factor will have. I think your survey ("Students do not like Racket") would be better if it were correlated with information like this. My gut feeling is that students with zero prior programming experience are likely to have a less extreme negative feeling of Racket than those who had previously learned a little Python, C, Java, Javascript, etc.
The issue of students not using Racket later in their degree is certainly problematic. Matthew Flatt (one of the principle authors of Racket) taught Utah's intro course in Racket just twice. When I asked him why it didn't continue, he more or less indicated that he had a hard time with it because it caused problems for students with the rest of the degree program. They learned stuff fine in his class, but the subsequent semester relied on knowledge of Java, and this was no good. Schools where Racket does well are schools where the various curricula are more cohesive in this regard, such as Northeastern and Indiana. (Speaking of which, Indiana should go on your list. I'm pretty sure their intro course is taught in Racket.)
You also claim that the Racket group have not published very much data, but you also are lacking the same data. For example, you say:
> Despite being ten years old, there is relatively little research to demonstrate the value of “Design Recipes” as a pedagogical approach, especially one that has long term benefits. One research study by the group indicates that students may be more prepared to apply principles of Functional Decomposition through this approach than students who do not, based on studies of the Rainfall Problem. Is this unique to using Racket? It’s a reasonable hypothesis, but not a proven fact.
but you don't provide evidence that it isn't the case, nor that Python is a better language for the same problem. I do believe there's value in expressing opinions without facts (or else I wouldn't be here!), but I think in this case your position would be significantly strengthened by having actual data to back up your claims.
I'd suggest that maybe your issue with teaching Racket was multi-fold: (a) your students wanted industry-relevant languages (SWE vs CS) and Racket is not that (which indicates either a need for industry-relevant languages or else an explicit explanation of why Racket is a good introductory language); (b) you lacked support from other faculty so students could continue to learn in the Racket environment past their first semester; (c) you don't appear to be a proponent of the whole "Design Recipe" thing, which is kind of essential to the intended Racket teaching methodology. I also wonder about other factors, such as whether your TAs were good at helping with Racket.
I want to make clear that I don't think you're wrong by necessity. It's entirely possible that Racket is actually bad for teaching computer science. But it's my opinion (as somebody who learned imperative languages first, Racket later) that your article does not really satisfy your claim, and I find that a little disappointing.
As an aside, I might suggest looking more specifically at what Shriram Krishanmurthi is up to. He's the most education-focused of the original Racket group, leading initiatives like Bootstrap to great success. He's also pretty active on Twitter, so if you're feeling up to it you might post your article there and tag him in. ;) (I think he's also on HN but I've forgotten his handle.)
I hear and appreciate what you are saying about evidence. First, I'll give the usual disclaimer that evidence is hard to come by in CS Education because it's hard to collect properly. Second, I'll point out that I have been involved way more heavily in a completely different sub-branch of CS Education; if you would like to hear evidence for, say, the value of data science as an introductory computing context for non-majors (CS0), then I am very happy to share what I know that is backed up by evidence. Only recently have I started getting involved in actual CS1 research in a deep way - so I can't really take much responsibility for the lack of research. I mean, I've only been a professor for two years now :)
I don't know if you were hoping that I'd be able to find evidence in other papers or generate the evidence myself. For the former, know that I tried hard to do a proper lit review on this (and I'm not even going to get a publication out of it!). I even asked some Racket people: one basically repeated Matthias Fellisen's disgusting opinion that CS Ed research is not possible, and the other just pointed to one of their papers citing theoretical arguments. At some point, I'm hoping to ask Kathi Fisler if she has a better set of citations, assuming she'll still talk to me if she finds this document :)
As for whether I should be responsible for conducting research to disprove HtDP, I have considered it. I might even do it. Certainly, I am trying to experiment with several methods that can hopefully provide contrasting information. For instance, I want to see if I can replicate the Rainfall success by teaching more explicit functional decomposition and pattern application in my CS1. Of course, I'm also trying to do a ton of other projects, and my job promotion is based on my teaching, not my research.
Part of my issue is that I should not be responsible for proving that their ideas work. They thought up a bunch of arguments, and then claimed that This Is the One True Way to Teach. If I made the claim that teaching works better when I punch students at random intervals, and you disagreed, you wouldn't feel that the burden of proof was on your end, right? I should need to prove my Punching Method, to some extent - perhaps at least some pilot studies? The Racket folks made up a lot of claims, and then didn't really prove what they said. That was over 10 years ago! I've been busy getting my doctorate, what is their excuse?
Separately, you provide some very valid hypotheses for why my students didn't resonate with Racket. In general, I think you have some good points about SWE vs. CS, but I have a different perspective. There's some mental model here, common in certain communities, that learning happens in a very direct way - if you just arrange concepts in the right way, things will click. I think that learning is a lot more messy and chaotic and driven by a lot of human issues and tough to work with. Transfer is hard. You can't teach CS divorced from programming and this messiness, it's just not realistic. Perhaps a small percentage of my students who are destined to be brilliant Theoretical Computer Scientists and professors will find all the learning to be orderly. But CS is a broad umbrella nowadays, and motivations are complex. I'm not really doing my points justice here, but read some of what Andy Ko and Mark Guzdial have been writing about - I think they're more my kind of CS Education folks :)
Finally, I feel like I should at least address your hypotheses: (a) Yes, my students want industry-relevant languages. They all said this to me explicitly, once or twice during class :) I really tried my damndest to give them a good justification for why Racket is a good intro language. I really tried to sell it. I failed - either the arguments weren't delivered well, or they weren't received well. I will point out that some students told me last spring that they earnestly thought I was in favor of Racket for CS1, so anecdotal evidence that I at least tried! (b) Yes, most other faculty don't know why this is being taught this way, and they don't conform their courses to the vision. Should they? What's wrong with their courses that they need to be "Racketified"? What would fixing my junior-level Algorithms course to be more Rackety? Perhaps the Racket folks should offer some explanations. Or, here's an alternative - the PbD curriculum is not solving general purpose problems, and the approaches they teach are not generalizable to other parts of the curriculum. All CS1 courses are full of useful lies - the PbD curriculum's shouldn't be propogated downstream, they should just be tossed out in favor of lies that at least align with the next courses'. (c) I taught the Design Recipe and pretended it was effective. I told my TAs to grade on it, same as the other instructors have done in previous semesters (reusing rubrics helps a lot). Perhaps I'm not a good actor, but I really tried my best to sell it. Maybe my TAs weren't good, but I doubt that. They were all excellent students who excelled at the course when they took it. If they're not good at it, well I don't think we'd have been able to get better ones, so you have to take that as a limitation of the system.
I understand why you are disappointed by my article. I am disappointed in the entire HtDP community. I think that this is a bad situation, and I'm not clear that I can make it better by writing an article. However, my goal wasn't to persuade you that Python was better than Racket for CS1. It's to make the points that right now, in my context, I should be teaching Python instead of Racket. Also that the HtDP community should be ashamed of the awful job they've done proving their points, and they should stop being so mean to everyone.
Anyway, this kind of experience report would be totally unsuitable for ICER, which is the venue focused on true CS Ed research. This might have a life at SIGCSE, but why go and preach to the choir? And honestly, I don't think it really does merit the level of research publication. This is just a blog post level argument.
I did outline why this site exists. And I do think that this is worth sharing on here, if only because this site drives me nuts sometimes with all its arm chair CS Ed researchers. If I only persuaded a few folks to stop citing HtDP as god's own truth, and to approach that community more critically - I would say that is helpful. Hacker News folks need to understand that education is a heck of a lot more complicated than they probably think it is, and their experiences probably aren't generalized.
I also think that the Racket education community is dying out. For good or bad, I don't think I really have to start publishing research to try and speed it up. But I think that having these reasons and arguments recorded, and written publicly, is a good thing. I am trying to keep in mind, as I write, that some day someone may write some blog posts for "ihateblockpy.com" or "ihatecorgis.com" (my research projects). Perhaps I'll be eating my own words!
You say this is important to communicate, and it seems pretty central to your professional field, so I don't understand why you aren't using what I assumed were the mechanisms of that field.
As you said, HN overall probably doesn't understand your field, and, given that: do you think it would be good practice for HN to let its impression of a field be determined by a punchy domain name that bypasses the field's own review? (I assume your thoughts are much better than those of anti-vaxxers and climate change deniers who bypass the field.)
Separate from that, since you think someone has been rude, maybe approach them constructively about it? All of you are just people, who spend your days teaching students, and researching that.
Your data section is compelling. Though, it reads close to the same arguments for why kids shouldn't learn calculus in grade school.
So the questions I would have to counter this would be:
* How stable has racket been compared to the alternatives?
Specifically, how many texts in Java and python taught methods that are actually not good for user in industry? This is ironic, as the argument is they would be using an industry language. But they aren't, really. They are likely using an ancient dialect of an industry one. Heaven help you if you picked JavaScript. * Is there any data about how well the students do following each language choice?
In particular, this should be easier to get. Do kids that skip the racket course generally do better than those that don't?I think your second question is sound, even though it might be difficult to test. I’d be interested in the answer to it (or better, the answer to the related question of whether the students taking the Python version fare better than those taking the Racket version).
Is it less if a change? I guess. I do know it is a source of some bugs we've seen. Not to mention just the churn of folks not using the general style of the existing code. New or old.
This is likely to have some confounding factors, considering the usual mechanics of skipping a university course.
Why does the stability of Racket matter? Isn't the real question more about how easy it is to reuse, readopt, reshare, find, etc. materials? I'll point out that the CSEngageEdu site doesn't have a Racket section. If you want me to find 100 programming problems in Python, I can do so immediately (because I published more than that, and I know others who have published even more). It's a simple fact that there's more community and infrastructure around Racket. There's been some interesting arguments that we shouldn't let that stop us - what about the future? But the reality is that right now, it's harder to teach in Racket, and I don't see any compelling evidence to prop it up further.
> Is there any data about how well the students do following each language choice?
I'm sorry, I had to laugh out loud. You've asked a really reasonable question, but it's one that the CS Ed community bickers about endlessly. I wrote a paper for SIGCSE about trends in what we talk about on the SIGCSE Mailing list. Seriously, every few years we get into the argument. Actual data seems to suggest very little. Heck, it's so hard to compare with all the confounding factors and individualized components that it's probably not really meaningful to get a simple answer. Ultimately? It probably doesn't matter. If you can teach 90% of my students with Racket the way I teach 90% of my students with Python, and you have the time and energy, then that's probably fine. But the simple reality where I'm at is that that's not the case - students who were taking Racket here before I arrived were being traumatized (and I suspect it's true at more places than the Racket folks want to acknowledge). If they don't want Racket, and I can teach a good CS1 in Python or Java or JavaScript, why should I fight that? Language choice doesn't really influence pedagogy as much as we might want to think it does, per this quote from the beautiful Meta paper that came out earlier this year:
> “Given the perennial question of which language, if any, is best suited for the teaching of introductory programming, many papers describe empirical comparisons between languages, often finding no significant difference in learning outcomes, but sometimes finding differences in student satisfaction.”
> “The choice of programming language is clearly a highly subjective one and is driven by many competing factors. It is clear that the literature will continue to host publications making the case for different programming language choices — and that no paper or series of papers will ever put an end to the debate, as no programming language will ever satisfy all of the conflicting requirements of an introductory programming course.”
Depending when you made this argument, stack overflow was a great resource. But many answers for the languages you pick as pragmatic are not good answers for modern use. And it seems to be getting worse.
For the other, you are taking my evidence the other way, oddly. I would expect language to matter very little. Such that, pragmatically, it makes no difference.
That is, I'm not trying to prove people do better because of racket. I'm guessing to prove they do no different because of python. Indeed, I enjoy lisp. But I doubt it is truly easier than most other options. Just so I doubt it is truly harder than most other options.
But not Haskell. Please don't say Haskell :)
Tons of preferences. But that will be dominated by the dislike most non self motivated learners will have. That is, most students are, I suppose, extrinsically motivated.
Now, tooling would be awesome. But for some reason, the tooling we expose students to is super expensive for personal use. Or requires a lot of investment in time. I'm thinking Mathematica and emacs.
Python is trying with notebooks. But has a lot of ground to catch up on. And seems to breed bad habits in the process.
Racket is a lot of languages, not only one. You can mix in Racket as you like. You can mix #lang racket and #lang typed/racket with #lang datalog in one application if you like. With racket2 those options will not fade away I guess.
There's even more community support for parentheses than I would've guessed. For various objective and subjective reasons I won't regurgitate here.
Some of the work in non-parens syntaxes (especially the Honu paper) are very interesting, and deserve more prominent exposure, and to be well-supported, so that people can try and adopt them with confidence. I'll be interested to see how people use them.
But there's no need to alienate half the community by declaring any of the non-parens approaches the default or normative, especially when Racket already famously has all the meta to support all of them, well.
I suppose it might even turn out that `#lang racket2` ends up looking almost exactly like `#lang racket`, just with tweaks to names and semantics, and that any non-parens syntaxes are separate and layered. And they all interoperate. Which Racket supports well.
My guess is, probably after everyone gets back from well-deserved vacations, this will to start to clarify, probably in September.
> * Make the language constructs more generic
> In many ways, the current Racket language and libraries encourage the use of concrete data structures instead of abstract datatypes.
Matt Flatt goes on to mention that map only works with list types, for example (you need to use hash-map to work with hash tables, vector-map for vectors, et c.). This makes refactoring a bit of a pain and feels like a legacy holdover that shouldn't exist in a modern programming language.
Honestly, the community overreaction to this really disappoints me.
If you're hesitant to recommend Racket because of a potential `#lang racket2`, it seems like you're missing the point of Racket as a workbench for creating new `#lang`s.
Uh... calling him "a developer" is like just calling Ruth Bader Ginsburg "a judge". Matthew Flatt is the #1 contributor to Racket in terms of any quantifiable metric, and he was also one of the original researchers on the project (next to Findler and Krishnamurthi, under Felleisen).
I totally agree with you that any syntax change in Racket2 will not be so big a deal as many are making it out to be, but I think it's a bit disingenuous to understate Matthew's involvement with the community to such an extent.
More companies using Racket: https://github.com/racket/racket/wiki/Organizations-using-Ra...
There's at least one large-codebase complex Web-based production system in it, which incidentally accomplished a first on AWS, but you've never heard of it, since it's internal-ish. It was a happy accident of history, that grew out of a lone super-productive programmer starting a complex data science infrastructure that I'd say few teams could've pulled off in a non-Lisp.
I've been waiting for another startup to decide they're going to do their first version in Racket, to do something non-cookiecutter. (It turned out neither myself nor my own startup co-founder had any interest in doing the CEO side of things, or I would've launched such a startup already.) But anything Scheme-related has a terrible curse for perception: students associate it with academic oddities in first-year classes, and then they focus on whatever "real" tools they hear employers or other companies are using.
If the next idea that comes to me happens to be/involve a web app, perhaps a Racket backend with a cljs frontend might be fun.
Would you mind expanding on this? (I’m not asking facetiously either)
Given Racket's language-design focus, that seems like an ideal use.
However, I must say that understanding the functional paradigm (learning Racket is a really good exercise) can help developers write really professional software with Scala, Elixir, Clojure, etc.
Basically, Chez is a now-open-source runtime that's very close to what Racket needs, while also being written mostly in Scheme instead of in C (as the original Racket runtime & compiler is). Building on Chez allows us to cut the amount of C by a factor of ~10 while getting a better architecture.
Along with it, I would recommend reading Structure and Interpretation of Computer Programs.
Racket supports multiple threads of evaluation. Threads run concurrently, in the sense that one thread can preempt another without its cooperation, but threads currently all run on the same processor (i.e., the same underlying operating system process and thread).
Is this documentation out of date or am I looking in the wrong place?[1] https://docs.racket-lang.org/reference/eval-model.html#%28pa...
Maybe I'll give Racket another try....
https://docs.racket-lang.org/guide/parallelism.html
https://docs.racket-lang.org/reference/concurrency.html
Of course, you can also do it the old-fashioned way, with multiple Racket processes running services, being workers behind a proxy/frontend, possibly on multiple hosts, etc.
It's more easy to use places, you can run whatever you want in places, but the communication between places is restricted and they have a big startup time (something like a quarter of a second) so if you create one, ensure that you are going to use it for a long time.