by kurinikku on 11/17/24, 3:07 PM with 231 comments
by emmanueloga_ on 11/18/24, 1:05 AM
Example: After Lisp, you might replace every for loop with forEach or chain everything through map/reduce. But unless you’re working in a language that fully embraces functional programming, this approach can hurt both readability and performance.
At the end of the day, it’s grounding to remember there’s mutable memory and a CPU processing the code. These days, I find data-oriented design and “mechanical sympathy” (aligning code with hardware realities) more practical day-to-day than more abstract concepts like Church numerals.
by marvinborner on 11/17/24, 4:10 PM
The encodings can be a bit confusing, but really elegant and tiny at the same time. Take for example a functional implementation of the Maybe monad in javascript:
Nothing = nothing => just => nothing
Just = v => nothing => just => just(v)
pure = Just
bind = mx => f => mx(mx)(f)
evalMaybe = maybe => maybe("Nothing")(v => "Just " + v)
console.log(evalMaybe(bind(Nothing)(n => pure(n + 1)))) // Nothing
console.log(evalMaybe(bind(Just(42))(n => pure(n + 1)))) // Just 43
by zahlman on 11/17/24, 10:40 PM
And of course the order of the material could be debated and rearranged countless ways. One of my future planned projects is to do my own video series presenting the material according to my own sensibilities.
It's nice to hear that the course apparently still stays true to its roots while using more current languages like Python. Python is designed as a pragmatic, multi-paradigm language and I think people often don't give it enough credit for its expressive power using FP idioms (if not with complete purity).
by liontwist on 11/17/24, 4:26 PM
by gugagore on 11/17/24, 8:05 PM
I threw up some content up here: https://intellec7.notion.site/Drinking-SICP-hatorade-and-why... , along with an unrelated criticism of SICP.
I'd like to better understand what the limitations are of "everything is just a function".
by WillAdams on 11/17/24, 3:41 PM
https://news.ycombinator.com/item?id=42157558
Is there a reason why the link goes to the discussion at the bottom of that page rather than the beginning?
Could this be folded into the other discussion? (I don't see that the link has been posted there yet)
by lifeisstillgood on 11/17/24, 8:19 PM
The relevant part is that this is basically how “software engineers continual education” is going to look like
by js2 on 11/17/24, 6:33 PM
("+", ("fib", ("-", "n", 2)), ("fib", ("-", "n", 1))),
The two calls to `fib` are surely meant to be `fibonacci` since the latter is defined, but not the former. Indeed, the code is correct in the github repo:https://github.com/savarin/pyscheme/blob/0f47292c8e5112425b5...
by User23 on 11/18/24, 2:57 AM
As I've learned more and studied more math though, I've come to the conclusion that the relation really is the more fundamental primitive. Every function can be represented as a kind of restricted relation, but the converse is not true, at least not without adding considerable extra gadgetry.
While of course relational databases and SQL are the best known examples of relational programming, and are highly successful, I still believe it's a largely untapped space.
However, my interest currently is less in the space of programming language design and more in teaching very young children the basics of math. And for whatever reason it's considerably easier to teach a predicate like "is big" as a 1-ary relation and "is bigger than" as a 2-ary relation than trying to capture the same concepts as functions.
by asah on 11/17/24, 7:36 PM
- functions that don't fit in cache, RAM, disk, etc.
- functions that have explosive big-O, including N way JOINs, search/matching, etc.
- functions with side effects, including non-idempotent. Nobody thinks about side channel attacks on functions.
- non-deterministic functions, including ones that depend on date, time, duration, etc.
- functions don't fail midway, let alone gracefully.
- functions don't consume resources that affect other (cough) functions that happen to be sharing a pool of resources
- function arguments can be arbitrarily large or complex - IRL, there are limits and then you need pointers and then you need remote references to the web, disk, etc.
(tell me when to stop - I can keep going!)
by bob1029 on 11/17/24, 4:35 PM
by ysofunny on 11/17/24, 5:31 PM
both can be a foundation for mathematics, and hence, a foundation for everything
what's interesting is how each choice affects what logic even means?
by pinerd3 on 11/17/24, 11:17 PM
by wslh on 11/17/24, 4:11 PM
I'd iterate on that and say: everything is just languages and dialogues, with functions being one component of them. Over time, we’ve evolved from machine languages to higher-level ones, but most popular languages today still focus on the "how" rather than the "what".
Programming paradigms, even those like functional and logic programming, requires the "how". My rant is this: the next major iteration(s) in programming languages should shift focus to the "what". By abstracting away the "how", we can reach a higher-order approach that emphasizes intent and outcomes over implementation details.
I don't want to constrain this idea to Z3, LLMs, or low/no-code platforms, but rather to emphasize the spirit of the "what". It’s about enabling a mindset and tools that prioritize defining the goal, not the mechanics.
I know this contradicts our work as software engineers where we thrive on the "how", but maybe that’s the point. By letting go of some of the control and complexity, we might unlock entirely new ways to build systems and solve problems.
If I should be plain realistic, I'd say that in the middle, we need to evolve by mixing both worlds while keeping our eyes on a new horizon.
by hyperbovine on 11/17/24, 4:58 PM
by behnamoh on 11/17/24, 4:27 PM
I got to the same conclusion a while ago, except that I found that it's lambdas all the way down.
by upghost on 11/18/24, 11:03 AM
That being said... SICP, Compilers, and RAFT all left me with the gnawing feeling that there was more juice to be squeezed from computer science than I was able to understand.
Why were my parsers and compilers not bidirectional? Why am I writing a utilitarian OO parser for an elegant FP language? Why is there no runtime polymorphic isomorphism for my client/server RAFT nodes?[1]
Drowning in my own sorrows, I began binge drinking various languages, drifting from one syntax to the next. CL, Scheme, Java, C#, Haskell, Forth, TypeScript, Clojure... ahh, long love affair with Clojure. But in the end, even Clojure, for all of its elegance, could not solve the original problem I was facing and at the end of the day in many ways was just "a better Python".
I was nearly ready to call it quits and write my own language when all the sudden I discovered... Prolog.
Not just any Prolog-- Scryer Prolog. Built on rust. Uncompromising purity. And Markus Triska's Power of Prolog videos on YouTube.[2]
My God. They should have sent a poet.
Bidirectional parsing? No-- N-dimensional parsing vis definite clause grammars, ships with standard library. First class integer constraint solvers. And it is the first language I have ever worked with that takes the notion of "code is data" seriously.
Scryer is still a young language, but it's going big places. Now is a great time to get involved while the language and community is still small.
I will end this love letter by saying that I owe my career and much of my passion to Dave, and because of him Python is still how I earn my bread and afford expensive toys for my Yorkie.
You rock, Dave!
[*]: this was a typo, should be Advanced Python Mastery, but in my ways advanced python salary is actually more accurate, in my case anyway.
[1]: If issues like this don't bother you, and you haven't been coding for at least 10-15 years, maybe come back later. Learning Prolog and Scryer in particular is really hard at first, even harder than Haskell/Clojure.
by fngjdflmdflg on 11/17/24, 9:43 PM
by pjmlp on 11/17/24, 4:26 PM
by zetranrt on 11/17/24, 6:21 PM
by shdh on 11/17/24, 9:18 PM
There are externalities like networking and storage, but still data transformation in a way.
by fifilura on 11/17/24, 6:12 PM
How do you represent an irregular float?
by Animats on 11/17/24, 7:08 PM
- Everything is just a function (SICP)
- Everything is just an object (Smalltalk, and to some extent Java)
- Everything is just a closure (the original Common LISP object system)
- Everything is just a file of bytes (UNIX)
- Everything is just a database (IBM System/38, Tandem)
by richrichie on 11/17/24, 4:02 PM
by rockwotj on 11/18/24, 1:02 AM
by vonnik on 11/17/24, 7:29 PM
by elcritch on 11/17/24, 10:21 PM
If this number, jump to numberA otherwise jump to this numberB. Also if numberC store numberD at numberE. ;)
by tasty_freeze on 11/17/24, 4:13 PM
by bombela on 11/17/24, 3:47 PM
by blackeyeblitzar on 11/17/24, 5:40 PM
by revskill on 11/17/24, 5:28 PM
But for real world programming, the tedious ones is related to validation, parsing and other business logic.
So i prefer a book to help teach CS by using real world codebase to solve real world everyday problem as a software engineer instead.
You can have your cake and eat it.