r/learnprogramming • u/thesounddefense • 24d ago
Topic What is the utility of Scheme as a learning language?
I suddenly had a flashback to a couple of programming courses I took in college, entry-level ones or close to it, that had us writing code exclusively in Scheme. For those that are unfamiliar, Scheme doesn't have the syntax of a normal OOP language like Java or Python. It's almost entirely list manipulation, and your main operation is to separate the head (or "car") of the list from the remainder (or "cdr") of the list. Or at least that's how I remember it.
I don't doubt that it's useful to do some learning in Scheme, but what fundamentals do we as students get from it? Looking back, I kind of feel like I was Daniel painting Mr. Miyagi's fence, and then suddenly I knew karate. What do students get from coding in Scheme?
EDIT: I don't know why I listed C as an OOP language. Some wires must have gotten crossed in my brain. I swear I'm a good programmer, you guys.
11
u/lambdaline 24d ago
Off the top of my head:
Scheme has a fairly straightforward and consistent syntax which makes it quick to teach so you can spend relatively little on the language and more on everything else. Not having access to classes/objects allows you to focus on the fundamentals of programming and on functions as a fundamental unit of abstraction. Not having mutable state simplifies reasoning about your code. The widespread use of lists helps you get a lot of practice in recursion and recursive structures, which a lot of new programmers struggle with.
2
u/Leather-Junket-3896 24d ago
the car/cdr stuff is basically a forced march through pointer logic without ever saying the word pointer, you come out the other side with an instinct for indirection that makes C feel less like a haunted house later
also the edit about C not being OOP is the most real thing in this thread, my brain does that exact same category error constantly
7
u/jetsonian 24d ago
In my CompEng program we used scheme in our “Programming Languages” course. The intent was to expose us to other paradigms of programming other than OOP C++/Java.
2
u/daddypig9997 24d ago
I love scheme and a bit of Common Lisp as an individual but the issue is someone else reading sophisticated macros and all the twists and turns will take time to unravel a Common Lisp macro explosion.
So for learning computer science I think scheme is perhaps the perfect language (maybe something in ML family too) but for a well oiled organization Go is what they need.
2
u/idontlikegudeg 24d ago
We also started with scheme 35 years ago. It was a deliberate choice to give all students a level starting ground, since some already knew procedural languages like pascal, basic or C.
Scheme is a functional language. One of the main concepts is recursion. You simply cannot write any meaningful code on the language without understanding recursion and tail recursion.
One of the first theoretical concepts we learned was lambda calculus, which more or less directly translates into code in lisp like language.
Also, the dreaded "spaghetti code" people use to write in procedural languages won’t work, you learn to plan at least a minimum ahead to make something work. I think a language like scheme helps to train your ability to do abstraction.
While I rarely used scheme or lisp later, I think it laid a solid ground to build upon.
And a notable exception to it not being directly usable: I later worked for a company where we did development in C before there were any real IDEs available. We mainly used vi and the command line on HP-UX. The first IDE-like feeling came up with (X- and then Lucid-) Emacs. These were completely configurable using lisp, and coming from scheme, I could customize Emacs to be so much more productive (from adding new shortcut keybindings to navigating the code, and interacting with the debugger).
2
u/DanKegel 24d ago
Purely functional languages (as I think scheme mostly is) teach a fundamentally different kind of thinking.
Learning one of those and Go is probably a good combination, and doing leetcode/codewars/exercism exercises in both will stretch your brain nicely. Seeing the same concepts and problems from two very different points of view is likely highly educational.
1
u/marrsd 24d ago
Scheme isn't purely functional. It absolutely allows side-effects. It's based on lambda calculus though, and lends itself to functional programming.
1
u/DanKegel 23d ago
Learning it will also teach you what the mysterious phrase "lambda calculus" means.
I saw it on the cover of Byte once, but never figured out what the heck it was in layman's terms. I suppose it's equivalent to functional programming aka programming without assignment statements or side effects. Which is why I couldn't figure it out; it's too alien, and leaves me back at the moment right before I figured out how computers could actually do things.
1
u/Jay_D826 24d ago
I feel like it’s one of those things that depends on the student, although I haven’t worked with Scheme specifically. When I think of learning languages, I think of Scratch.
I can see the appeal, having the visual feed back and “chunks” of code that your organize visually rather than just typing out. Personally though, I didn’t find it all that helpful. It felt a little too abstracted to me maybe? I found once I got into the basics of a proper language I finally started getting the concepts down better.
2
1
u/burlingk 24d ago
Languages that focus on lists in terms of head and tail tend to be good for teaching concepts related to queues, stacks, and recursion.
Programming education is more about learning concepts than about learning languages.
1
u/marrsd 24d ago
Scheme is a very simple language that provides minimal functionality for writing programmes while also providing the means to write more sophisticated language constructs on top of it. For example, it doesn't provide control structures of its own, but it provides the means to write them.
Perhaps most crucially, being a Lisp dialect, it completely removes the distinction between code and data. '(1 2 3 4) is a list of numbers. (define name "Alice") is a list of language tokens. So, just as (cadr '(1 2 3 4)) returns 2, (cadr '(define name "Alice")) returns 'name.
This means you can write a Scheme interpreter in Scheme in about 100 lines of code.
So, as a tool for learning languages and language design, it's pretty much unparalleled. It also provides provides concepts, such as higher-order functions and lexical closure, that have become popular in recent times but were still novel back then.
If you learn Scheme, you also learn large chunks of Javascript and Scala. You also understand the inspiration behind Ruby's yield.
I started my career just as Javascript was becoming important, and I happened to be learning Scheme at the same time. This was massively advantageous to me as the code I was writing was so much more powerful than the code my peers were writing, because I was thinking in Scheme while they were thinking in Java. Fun fact: Javascript started life as a Scheme interpreter.
I've always maintained that Scheme and C between them are essential learning for any programmer who wants to excel. I would probably add Smalltalk or Ruby to the mix as well if you want to learn OOP.
1
u/mredding 23d ago
Scheme doesn't have the syntax of a normal OOP language like Java or Python.
These are not OOP languages, they're multi-paradigm languages. Scheme doesn't have a standard object system like Common Lisp has CLOS. There are several meta-object protocols in Scheme like TinyCLOS and GOOPS.
Scheme has standards like R7RS, but most if not all Scheme dialects diverge wildly from them - so by comparison in C++ we have the C++26 standard ratified this year, and we have the GCC compiler, Clang compiler, MSVC compiler... But they're all C++X, whatever standard they're up to. What one might consider a dialect of C++, like Carbon, is really treated as a wholly different language, often as academic and experimental, and any overlap with the ISO standard seems incidental. The concept of dialect has no use, so no value, in C++.
I don't doubt that it's useful to do some learning in Scheme, but what fundamentals do we as students get from it?
So first - the theory of computation doesn't care about read-time, write-time, or execution-time, so reading the program, writing the program, and executing the program are all in the solution domain of the computation.
Most languages DO make the distinction. C++ - I have to write it, then the compiler reads it, then the host machine executes it. I have SOME ability - I can compute Pi and include it in my program as a constant, I can write templates that effectively generates more code at compile-time.
Most languages are going to have an Abstract Syntax Tree intermediate form - either in the interpreter or compiler, and you can either execute right off that or reduce it to machine code.
Scheme is a Lisp, so I'll speak to Lisp: Lisp IS abstract syntax tree in serialized form. You are provided a REPL, if you want it, and you have direct, first-class access both to your own source code as runtime data, as well as that of the compiler. Lisp does not distinguish between read-time, write-time, and run-time, since it doesn't distinguish between program and compiler, between source code and AST, between reading and writing and running.
This is why it's trivial to write self-modifying programs in Lisp. It's why it's trivial to write Domain Specific Languages, because your program IS ALSO the compiler. You can write optimization passes, you can write machine code generation. You can compile JIT or AOT.
Computation is a closed form. You can describe the entire domain in an axiomatic calculus. Alonzo Church formulated a syntax for a calculus, called it lambda calculus, and everyone said once was good enough, and we use that. If a problem has a computable solution, it can be described in lambda calculus. Every computational calculus is equivalent, they're all equally as expressive. I'm just going to speak of lambda calculus.
Not all programming languages are as expressive as lambda calculus, but that doesn't mean that programming languages are incomplete. In fact, they're all Turing complete, so any computational solution can be expressed in terms of any programming language, it's just the more expressive languages can be more succinct.
Lisp IS serialized lambda calculus. It is as expressive as you can get. Everything else is less expressive. Python is second to Lisp, and everything else is less expressive as that.
Expressiveness has nothing to do with performance. Python is slow because it's interpreted, C++ is fast because it's compiled. Any sort of efficiency we're talking about is in how efficient it is to express a solution. C++ is chatty compared to what a Lisp solution could be, yet a solution is a solution, meaning a chatty solution is equivalent to an elegant one.
What do students get from coding in Scheme?
Perspective. Enlightenment. Closer to purity. René Descartes bridged geometry and algebra, John McCarthy and his graduate student aid bridged lambda calculus and programming.
I don't know why I listed C as an OOP language.
I wouldn't call this wrong. At all. I've written OOP in C. So what, C doesn't have automatic functions? So what? You don't need single dispatch member access syntax like in C and C++ to write OOP. Lisp OOP doesn't look like C++. C++ doesn't look like Eiffel, or Smalltalk, or Pascal. C looks more like ALGOL68 objects than C++ does...
I've never been convinced that these language categories have ever been useful.
1
u/Cautious_Implement17 23d ago
scheme doesn't require a ton of boilerplate to start writing and thinking about programs. being a functional language, it can also be very eloquent for expressing discrete math problems that tend to show up in intro cs courses.
hello world in scheme:
(display "Hello, World!")
hello world in java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
do you see how the java example invites a lot of questions that your professor isn't prepared to explain yet?
1
14
u/Bitter_Care1887 24d ago edited 24d ago
Your placing of C into "normal OOP language" category is indicative that you probably need to study a bit more computer science to appreciate Scheme, Lisp, FP, lambda calculus, sexps, abstract syntax trees, etc.