There was a misunderstanding on my part when I started studying Racket. I have never learned a language where everything was documented together - language and everyone's additions to it.
Agreed - at this point in my Racket life it is not a problem anymore. I worry about people coming into the language, however.
Me too! On the one hand, it's empathy because I had my own share of struggles (and sometimes still have). But additionally, if people starting with Racket get too frustrated and give up, it also hurts the community because we have fewer potential contributors to the ecosystem.
I think that's a good approach (even though I started with Racket before looking that much into R5RS). But my reasoning is that if R5RS in itself is a productive language but (much) smaller than Racket, it's probably a good basis to get the big picture.
I'd like to add that pattern matching has both relative simple patterns and advanced ones which I find rather hard to understand. Also, in my opinion Additional Matching Forms can come later.
This is also what I had hoped to find in the Racket Guide. My wish is that the Guide contained what a user needs to get productive in the language for not too complicated programs. That said, I just checked the contents of the Racket Guide and, thinking about the presumably advanced stuff that we discussed in this thread, I found some contents where I wonder if they should be in the Guide:
- " 5.7 Prefab Structure Types"
- The "planet" stuff in "6.3 Module Paths". I guess this is mostly there for historic reasons.
- " 6.8 Protected Exports"
- Maybe parts of " 7 Contracts"?
- " 10.2 Prompts and Aborts"
- " 10.3 Continuations"
- Although "11 Iterations and Comprehensions" mentions sequences, it doesn't explain what a "sequence" means, particularly, that a sequence may be lazily evaluated.
- "11.5 for/and and for/or"
- "11.6 for/first and for/last". Of course, the four
for
forms can be useful, but to me they seem a bit too special to be in the introduction. - Parts of "13 Classes and Objects". I had started to read this in the past, but further down (maybe from "Mixins") I really wondered how important these sections were. I think the OOP chapter in the Guide should contain what's needed to start with the GUI system, but I don't know how much more. (By the way, should the Racket Guide discuss the GUI system, maybe basics?)
- "14 Units (Components)". I think someone in the Racket Slack said that units weren't that important anymore because they were mostly superseded by the module system.
- Parts or all of "15 Reflection and Dynamic Evaluation"
- Parts of "16 Macros". I can't be more specific because I know too little about macros.
- "17 Creating Languages". I understand the motivation to include this chapter since Racket prides itself as the language for language-oriented programming (or something along these lines ), but I suppose this is a rather advanced concept.
- Maybe at some point the BC stuff in "19 Performance" should be removed.
- I'm unsure about "20 Parallelism". I agree all this should be documented somewhere - but in the Racket Guide?
Again, I'm just wondering about these sections. I can't judge how important these actually are.
Somewhat related: The Oxford Advanced Learners Dictionary and maybe other online dictionaries mark words of a "key" vocabulary with a symbol. For example, the entry for person has such a "key" icon. I don't suggest to add such icons to "key" functions/forms in the Racket Reference and actually don't even have an idea what a good way for such annotations would be without getting visually noisy and distracting. But maybe someone else is more inspired than I am?
I think one way to describe this would be that the racket documentation doesn't really use "progressive disclosure" and instead just shows you everything that you eventually may need at "once".
Progressive Disclosure
So starting using the documentation you get overwhelmed until you have learned about all the concepts that you can filter out as "currently not relevant for me", which sadly requires you to understand them enough to know that you don't need them right now.
Ideally you could choose to see the documentation from the point of view of being a "racket beginner" which would only show you the most basic things to get started, it would then let you know how to discover deeper more advanced topics.
A tree of increasing detail
I kind of imagine a tree, the root node would show the basics (Installing racket, opening drracket, running hello world) then the last part of that could be:
these buttons here that you have seen, that were disabled, have now been activated,
clicking them expands the section to describe it in more detail and show other things
that were previously eluded from the explanation.
The deeper you go in the tree the closer you get to pure reference or maybe eventually just showing the source code directly. But you could explore every level of the tree as one way to view the documentation that includes the explanations of the level above but not those of levels below.
For a good experience for the user it would have to save the state of exploration / familarity (basically save what was toggled open/close within that tree)
Advanced Possibilty: Many worlds
I think something like this could work pretty well, however potentially there could be many different, but similar trees that guide you through the documentation, prioritizing different things at different times.
Individuals with different views and priorities could create different trees.
The individualist in me thinks it would be cool, if it was a tool that allowed you to rearrange the documentation however you like (possibly even sharing some sub-trees with other perspectives).
(The pragmatist in me thinks that might make the implementation quite difficult. So maybe it makes more sense if there is one way things are structured that people mostly agree upon. Mostly because of maintenance burdens, people already seem to be doing too much work, for the amount of people that are using and contributing in some form to racket.)
If there was such a general tool, it potentially would allow to have many different tours "get started with racket as a datascientist", "... as a game programmer", "... as a language developer", "... as a macrologist", etc..
This would also allow people to expose to other people what they think are the key points about what is really useful and great about the language. By comparing and contrasting those different viewpoints, the overall topic of "how do you introduce someone to racket" may improve.
That said, I am unsure how you could implement such a tool in a way that people still can easily make changes to their individual perspectives and not break anything for other people (creating more work for them) and also avoid a bunch of duplication of documentation. Or having to restate things over and over again.
Click on â "Progressive Disclosure" above to toggle.
Meta
This is an experiment in describing this idea while using discourses "Hide Details" feature that is kind of similar "in spirit".
Ironically, I think that Racket contains one of the best examples of "progressive disclosure" that you'll find anywhere, in the form of the teaching languages and the HtDP textbook.
The amount of work that has gone into keeping this pair working and synchronized is phenomenal, and speaks to the dedication of its authors.
So basically, I think what you're suggesting is a great idea, but that doing it well is unbelievably hard, because it involves a huge number of judgment calls about what belongs in each layer, and how to structure the documentation so that it doesn't "leak" excessively into the next layer.
FWIW, I have this problem all the time with Python; trying to look things up leads to all kinds of unhelpful detail. I think that the most effective solution there is just the incredible number of people writing and sharing Python code; you can almost always find a snippet of (apparently) useful code in Stack Exchange.
Bias disclosure alert: I'm biased.
I agree and at first I had a section about the student languages, but removed it because my thoughts weren't quite complete. I also recently had an experience showing me that it takes way more time to write and organize explaining something, then simply just writing a program without an explanation.
I think the student languages have progressive disclosure.
What seems a bit of a downside to me is that their simpler models are basically restated in the next progressive bigger language, within the context of how the documentation displays it, that seems to be an artifact of how the student languages are implemented. (Basically the documentation-viewer/website/tool doesn't have a concept of progressive disclosure and thus just shows to the user again what the user already knows)
I feel like on the documentation side I would want an UI that knows whether I have "closed" basic string functions and keeps them closed when I view those from a different perspective. Currently I have to scroll down lists of functions and guess that those are probably the same functions re-exported with some new functions added.
I guess one way to say it is that racket's documentation uses manual "progressive disclosure" in some places, by texts that are written in a way to introduce new topics in some strategic way. But as far as I am aware it doesn't use "automated" or "semi-automated" progressive disclosure. Maybe there is the potential design space of something that is similar to a nano-pass compiler but for progressive disclosure.
Do you mean that if someone is struggling with getting a big picture of Racket, they're supposed to work through HtdP? I don't think that would help much, apart from learning about design and functional programming on a generic level.
Along these lines, the HtdP preface contains this note:
Note The teaching languages are implemented in Racket, a programming language we built for building programming languages. Racket has escaped from the lab into the real world, and it is a programming vehicle of choice in a variety of settings, from gaming to the control of telescope arrays. Although the teaching languages borrow elements from the Racket language, this book does not teach Racket. Then again, a student who has completed this book can easily move on to Racket. End
(The word not is also emphasized in the original.)
In my opinion this makes sense because the many APIs and advanced concepts of Racket that confuse beginning (and to some extent intermediate) Racket users aren't discussed in HtdP.
This is a great idea!
I suspect it not a huge amount of work because scribble manual already changes the nav background colour from scribble/base default.
In scribble/manual
- add a parameter âguideâ
- Change the
background-color:
in.tocset
and.navsettop
to sayhsl(138, 15% , 70%)
when parameter is set.
Then add the parameter to the Racket Guide scribble.
Stephen
So I wanna throw my 2 cents into this thread. As someone who's used racket on and off for a number of years, I came to the conclusion that the language/ecosystem has a significant gap for programmers at the intermediate level. Intermediate meaning people who can do the basic stuff described in 2htdp and have solid experience with programming, but aren't significantly experienced/expert in any domain. I wanna try to articulate why this is.
I think its something like a combination of "theres more than one way to do it" and there being no obvious way to evaluate the tradeoffs. So for example lets say you want to make a game and you came off of 2htdp. You're now wondering whether to stick with the functional structs big bang style that was taught or to use GUI/classes and message passing approach. Choosing one basically locks you out of the other ecosystem. Then there's 2 drawing libraries, image and pict, which both do similar things and there's no way to know what the differences and trade offs are. Then you come upon draw library, which works with the class system but is more low level. And again, each of these choices locks you out of the other ones. This pattern sort of repeats as you keep going, both in the ecosystem and the language constructs (there are 3 macro systems(?) but at least they have a guide).
You have to invest significant effort to wrap your head around all these pieces to possibly learn that they don't even do what you need, and then go back and do it again. As far as I can tell there may not even be a de facto "superior" solution sometimes. All these choices have consequences down the line that you can't mitigate or foresee that can paint you into a corner. So you either study these ecosystems and spend a bunch of time or pick one and hope for the best (or ask online)? I literally don't know.
As far as I know most languages have these issues but tend to either converge on de facto standards or end up with several choices with relatively clear tradeoffs. Or maybe I'm just imagining this or am not used to it. I do like racket btw but I also don't feel like I have these issues when I'm using python for example (tho it has other issues of course).
Dunno. I started in basic, then turbo pascal/asm and then C. After many years in C, I realized I wrote almost a LISP and I am not just repeating stuff people say to be funny, I mean I wrote so much code and helper libraries and then abstracted over that and re-wrote and so on and so on that I invented LISP (haha). This was my motivation on and off to learn Scheme down the road, which led me to Racket, which I found advertised as a language maker / Swiss knife kind of a tool.
I like Racket but I am one of those highly organized people who need to have clear compartments until the borders between compartments disappear in my head and I get the whole picture. I find Racket irritating this way because it is opposite of highly organized - it is total chaos with many ways to skin the cat and all of these ways are rabbit holes of their own. Also, too much verbosity and too many concepts crammed into the same level of "importance", even in the official documents. Perhaps a layered approach is better? Otherwise, you look at the "language" and it presents a formidable amalgamate of dozens of concepts/libraries/ideas all thrown into the same beginner/intermediate/advanced guide/documentation, which is then mixed with stuff like "br" which is from an independent book that has nothing to do with the language core itself. Life is sometimes already difficult/complicated as it is - why make it even more so?
By the way, if you ask me to point to a modern language that has a better organized "core" that is actually more complex than apparently "simple Racket" - look at Scala. Yes, its library system is chaos but at least the language itself can be and is properly explained in one book. You finish reading it and now you feel ready to tackle the libraries.
Bottom line, I came from the "eastern school of thought" (meaning, I got my education in eastern Europe) and there you were taught things whose future implications may not have made sense at the beginning (but were basic building blocks of stuff you needed to know to go further). With Racket I just don't feel that. There are deeper knowledge requirements and math concepts all over the place but they feel chaotic and you have to look for them - there is no concise book or guide that will take you through this stuff in a regimented, down to the point manner, incrementally building on concepts that are properly and thoroughly explored right there. For example, if continuations are an important concept, well, make it clear, write a darn proper chapter about it somewhere and close the book on the topic once and for all. If macros are such a big part of the language, instead of sugar coating them in "br" or hunting through the unfinished "Fear of Macros" or who knows whose ramblings online, write a proper and accessible and thorough chapter on that and close the book on that topic (sounds like I should try to do all of these instead of asking the mythical someone to do it?). Instead, you are relegated to reading multiple texts/write-ups (which are basically people's approaches to assimilating these concepts) or hunting on the internet for resources or asking here or you have to read a 1000 page book that goes into everything like you are 4 years old starting with "this is how the computer works, zeros and ones". Well, I don't need either....
For continuations, the overview chapter is here: 10.3 Continuations, and the reference chapter is here: 10.4 Continuations.
For macros, the overview chapter is here: 16 Macros and the reference chapter is here: 12 Macros
If you are an experienced programmer, The Racket Guide and The Racket Reference should be sufficient to learn Racket, as these books already assume that you have programming experience and don't go into unnecessary details.
Hope this helps,
Alex.
I think one important distinction between racket and most other languages I have encountered is, that it doesn't give you just one language, it also gives you all the tools that were used to implement the language.
In a lot of languages you just get documentation for the thing the language user gets to program with, but with racket you also get all the plumbing beneath the language surface.
I agree that when you start with racket it can be confusing when you suddenly end up in the details and wonder "what are 'Impersonators and Chaperones' anyway and why would I care about them?"
But I think one reason why other languages don't have that problem is because they never give you proper access to tinker with the internals of the language, sure some people may claim, "I don't want to do that anyway", but I would claim that they are just "blissfully ignorant" when they then invent "dsls" that are forced to stay constraint to whatever literal syntax the language provides for them when they repurpose that syntax as a "dsl". Which in reality is just a convention emulating a dsl, because the language doesn't actually allow dsls.
I think there are things that could be done to make clearer to the beginner where the person is diving into implementation details, that may only be relevant for more advanced users.
However I think most languages just avoid the problem that racket tackles, they just seal the hood of the car and only allow special personal to look under the hood. Additionally most of the time, constructs to implement the language are just that "a implementation used in one place", where in racket those are often built in a way where other languages can reuse those constructs.
All of this is basically to say that the comparison with other languages often isn't really a fair one, considering that they only give you a hammer (which is why you always have to start building almost everything yourself in those languages), while racket is a toolbox.
That's fair and you are correct. However, the problem of getting into the Racket ecosystem still remains, regardless
How many languages discuss/rely on concepts such as continuations (explicitly)? How many have true macros? You can spend your whole life in C and not ever end up building a system of libraries where your C starts looking like something else when you write it (LISP?) and you will still be "experienced". Heck, I interview people for positions in my team every now and then and most cannot even tell me what a Turing machine is (or what it means for a language to be Turing complete), let alone currying or continuations and all of these candidates have at least BSc degrees in computer science and some even MSc (from good/accredited US universities).
@maketo writes that âall of these candidates have at least BSc degrees in computer science and some even MSc (from good/accredited US universities)."
What does this tell you about such degrees and the universities that âsellâ them? Speaking as a professor who cares too much about what a proper undergraduate CS degree should look like.
;; - - -
@maketo also writes âThat's fair and you are correct. However, the problem of getting into the Racket ecosystem still remains, regardless .â
Here is an explanation.
I agree. In a nutshell, Racket grew organically as a research vehicle and as a useful tool in different directions. Thatâs true for the language and the many libraries and packages that you get. Here is an example about drawing pictures. Just for 2D you have draw, pict, sicp painters, 2htdp/image, htdp/image, and several more.
The last two illustrate nicely what happened. We had a draw library for HtDP. It was too imperative for a high school curriculum that is supposed to continue and reinforce âmiddle schoolâ algebra. So we created htdp/image. Robby and I loved programming with pinholes but the thousands of students who went thru it didnât quite take to it. So we developed 2htpd/universe and 2htdp/image (separately) to accommodate teachers and students. Itâs a vast improvement. (universe predates React by a decade but these things are incredibly close.) â So this is in a nutshell an example of organic growth, for a primitive API, nothing truly complicated. Deeper ideas needed and reacted more research and more feedback from users.
Now you might say âwhy not throw out the old stuff.â On rare occasion, I did. But teachers couldnât change as fast as we could. They wanted their old slides, problems, solutions to continue to work. Understandable. You can imagine it would be equally unfair to riip out libraries that industrial devs relied on. So backwards compatibility became critical if not paramount.
Is there a solution?
Let me mention two that donât require re-engineering the language. (I have ideas for that too but this forum is inappropriate for those.)
(1) When I started Realm of Racket, I had a more ambitious goal in mind. I am very happy about how far I got with undergraduate co-authors over three years. They learned a lot while maintaing this project for 3 years. But as anyone on this forum can imagine, this product could easily be continued by growing the games and working with the sophisticated APIs of Racket.
[[ Realm is a bridge from HtDP to what Iâd call âfunctioning Racket programmersâ and undergraduates here read it for that for the one or two courses that use Racket. So it served that purpose well. ]]
(2) I could also imagine a EU Lisp style layering of the languae and its APIs â at the documentation level. This would be a major effort, but could use pieces of the existing source material plus âglueâ material. Personally I think it wouldnât be a âtowerâ but a âtree shapedâ layering, with branches for various interests (from âjust let me use Racket because itâs better than Pythonâ to âI want to study advanced PL conceptsâ). People could then work their way into Racket and according to their interest.
I will admit though that while I have the big picture in mind, I donât have the energy to pull this off right now. Iâd have to retire to work this out.
â Matthias
History is important if we learn from it (haha). On a serious note - thank you for replying, at least I know I am not entirely crazy when I say things. Sometimes people tend to end up living in their own little world which becomes entirely internally consistent even if it has no base in reality. I have been sweating over this topic for a while now as such a seemingly / innocently simple language has such depths....
If you are an experienced programmer, The Racket Guide and The Racket Reference should be sufficient to learn Racket, as these books already assume that you have programming experience and don't go into unnecessary details.
To riff on this a bit, I think one thing that makes Racket often seem more complex than needed is that people spend too much time looking at the Reference early on. Partly this is because there isn't a "Guide" for lots of other parts of the language or because something isn't mentioned in the Guide, partly that's because the reference is what you get to if you search for the documentation on a binding, partly that's because people often want to know all the details at once. But in general I think almost everything in the Guide should be learned before most things mentioned only in the Reference.
Time has passed, possibly not worth clarifying, but: No, that's not what I mean. More specifically, I'm not suggesting any connection between the teaching languages and Racket at all; I'm saying that HtDP does a principled job of connecting earlier, simpler languages (Beginning Student) to later, richer languages (Advanced Student). Based on this example, I suspect that doing something similar for the Racket languages would be very hard. Apologies if that wasn't clear.
It sounds like you're in agreement with @soegaard 's suggestion that a visual distinction might help steer people toward staying in the Guide, and at least being aware when they're moving into the reference.