9 ms·
A Friendly Introduction to Racket
- em-bee 2mo agoany time the topic of racket comes up, i wonder if there are any interesting apps i could explore. but all i find is libraries and dev tools: https://awesome-racket.com/ https://awesome-racket.com/
- LasEspuelas 2mo agoThere is this https://remember.defn.io/ https://remember.defn.io/ You can read the about it here: https://defn.io/2020/01/04/remember-internals/ https://defn.io/2020/01/04/remember-internals/
- mono442 2mo agoit's an academic language
- spike021 2mo agoWe used it in the course I had that introduced functional programming. The only memorable thing I can remember writing in it for that class was a topological sort (I believe).
- so-cal-schemer 2mo agoThe co-creator of Scheme is also co-author of Structure and Interpretation of Computer Programs[0]. Namely, Gerald Jay Sussman[1], the Panasonic Professor of Electrical Engineering at the Massachusetts Institute of Technology (MIT). In teaching our material we use a dialect of the programming language Lisp. We never formally teach the language, because we don’t have to. We just use it, and students pick it up in a few days. This is one great advantage of Lisp-like languages: They have very few ways of forming compound expressions, and almost no syntactic structure. All of the formal properties can be covered in an hour, like the rules of chess. After a short time we forget about syntactic details of the language (because there are none) and get on with the real issues—figuring out what we want to compute, how we will decompose problems into manageable parts, and how we will work on the parts. Another advantage of Lisp is that it supports (but does not enforce) more of the large-scale strategies for modular decomposition of programs than any other language we know. We can make procedural and data abstractions, we can use higher-order functions to capture common patterns of usage, we can model local state using assignment and data mutation, we can link parts of a program with streams and delayed evaluation, and we can easily implement embedded languages. All of this is embedded in an interactive environment with excellent support for incremental program design, construction, testing, and debugging. We thank all the generations of Lisp wizards, starting with John McCarthy, who have fashioned a fine tool of unprecedented power and elegance. [0]: https://sarabander.github.io/sicp/ https://sarabander.github.io/sicp/ [1]: https://en.wikipedia.org/wiki/Gerald_Jay_Sussman https://en.wikipedia.org/wiki/Gerald_Jay_Sussman
- eru 2mo agoYou can ask Claude to write you some.
- so-cal-schemer 2mo agoAre you suggesting, possibly, that a team of 10x Lisp hackers with 10x agent force multipliers could catch up with the depth and bread of Python's CheeseShop and proceed to right the world?
- eru 2mo agoNo, what makes you think so? I'm saying that you can produce some interesting apps to explore.
- deleted 2mo ago[deleted]
- so-cal-schemer 2mo ago"Wishful thinking".
- em-bee 2mo agopossibly, but not something i would want to learn from.
- Zambyte 2mo agoOne of the more notable apps originally written in Racket is https://news.ycombinator.com https://news.ycombinator.com. See: https://en.wikipedia.org/wiki/Arc_(programming_language)#History https://en.wikipedia.org/wiki/Arc_(programming_language)#His...
- so-cal-schemer 2mo agoAnd for the uninitiated: https://paulgraham.com/avg.html https://paulgraham.com/avg.html In the summer of 1995, my friend Robert Morris and I started a startup called Viaweb. Our plan was to write software that would let end users build online stores. What was novel about this software, at the time, was that it ran on our server, using ordinary Web pages as the interface. A lot of people could have been having this idea at the same time, of course, but as far as I know, Viaweb was the first Web-based application. It seemed such a novel idea to us that we named the company after it: Viaweb, because our software worked via the Web, instead of running on your desktop computer. Another unusual thing about this software was that it was written primarily in a programming language called Lisp. It was one of the first big end-user applications to be written in Lisp, which up till then had been used mostly in universities and research labs. ...
- velcrovan 2mo agohttps://joeldueck.com/what-about/camp/ https://joeldueck.com/what-about/camp/
- dexterlagan 2mo agoFor my own tools, some of them still in production at home and at work: https://github.com/DexterLagan?tab=repositories&language=racket https://github.com/DexterLagan?tab=repositories&language=rac...
- so-cal-schemer 2mo agoSome games to play: https://spritely.institute/arcade/ https://spritely.institute/arcade/ The underlying tech might be more fun: https://spritely.institute/hoot/ https://spritely.institute/hoot/ Hoot is a Spritely project for running Scheme programs on the web, featuring a Scheme to Wasm compiler and a general-purpose Wasm toolchain. https://spritely.institute/goblins/ https://spritely.institute/goblins/ https://files.spritely.institute/papers/spritely-core.html https://files.spritely.institute/papers/spritely-core.html At the heart of Spritely is Goblins, its distributed object programming environment. Goblins provides an intuitive security model, automatic local transactions for locally synchronous operations, and an easy to use and efficient asynchronous programming interface for encapsulated objects which can live anywhere on the network. Its networking model abstracts away these details so the programmer can focus on object programming rather than protocol architecture. Goblins also integrates powerful distributed debugging tools, and a process persistence and upgrade model which respects its security fundamentals.
- perrygeo 2mo ago> In The Amazing Digital Circus (episode 8, "hjsakldfhl"), when Kinger opens the terminal to try to reset Caine, you can see that Caine (a creative AI built in 1996) is programmed in Lisp. The file is literally named Caine-core.lisp. Nice touch. Explains how Caine returns in episode 9: Lisp continuations allow for graceful error recovery.
- valorzard 2mo agowasn't Caine written in common lisp? Pretty sure they show that the debugger they used in the command line was gdb (which ... is that even actually possible?)
- perrygeo 2mo agoYep, `/usr/bin/gdb /usr/local/bin/clisp 1337` ... also in TADC lore, windows has forward slashes.
- GregBuchholz 2mo agoWindows has allowed forward slashes for directory separators for a long time. Seems like maybe it started with DOS 2.0. https://en.wikipedia.org/wiki/Backslash#Filenames https://en.wikipedia.org/wiki/Backslash#Filenames
- vatsachak 2mo agoI've never seen the appeal in schemes other than hot reloadability...
- WalterGR 2mo agoHomoiconicity.
- chowells 2mo agoWhat makes this a desirable feature? From the perspective where local reasoning is the most desirable property a language can have, how does homoiconicity support that? I honestly am curious. I've seen a few examples presented for it, but they always seem like bad software engineering to me. Where's an example that does something in a cleaner way than alternatives present in other languages while remaining compatible with local reasoning?
- bjoli 2mo agoit allows you to create a language that compiles to your original language. You can abstract everything away. Not like Haskell where laziness accounts for some and typeclasses for some (and often an exponential growth in compile times). No, it property let's you change the language. I got tired of loops sucking and made this, for example: https://rikspucko.koketteriet.se/bjoli/goof-loop https://rikspucko.koketteriet.se/bjoli/goof-loop
- chowells 2mo agoThis doesn't strike me as better than the alternatives. In Haskell, it's just a few different functions to handle the different use cases. That strikes me as far better than one "function" that magically does different things depending on how it's called. It is local, I'll give you that. But it still seems bad because you have overloaded the semantics along multiple axes simultaneously. I prefer building blocks with only a single set of semantics each. I believe it's better to write precise code than DWIM code.
- deleted 2mo ago[deleted]
- mcbk2142 2mo agoVery cool! Always was interested in racket, I will try writing Black Jack in it!
- spdegabrielle 2mo agoyou might be interested in https://github.com/racket/games/blob/master/blackjack/blackjack.rkt https://github.com/racket/games/blob/master/blackjack/blackj...
- fn-mote 2mo agoMuch as I am a fan of Racket, this is not a friendly intro. It is a speedrun. When an introduction says “friendly”, I don’t expect it to assume that I know what lambda is. When an introduction says “friendly”, I don’t expect syntax rules to appear in it. At all.
- allthetime 2mo agoIt is rich with information, to the point, and presented in a way that a motivated and competent reader can immediately know something about and be useful with racket. That’s how it was for me anyways; someone who didn’t know anything about racket before reading through this. Wtf kind of intro to a programming language doesn’t include syntax rules? We are all informed, experienced, technologically inclined people here. Not dumb children. I’m struggling to see your comment as anything more than contrarian babble.
- sudahtigabulan 2mo ago> Wtf kind of intro to a programming language doesn’t include syntax rules? PP could have been more clear and say syntax-rules (note the dash), which means macros. Macros are usually considered an advanced topic.
- wormius 2mo agoThanks for the clarification! It makes much more sense seeing the term "macro".
- so-cal-schemer 2mo ago[flagged]
- dented42 2mo ago> Wtf kind of intro to a programming language doesn’t include syntax rules? Given that most languages don’t have syntax rules or anything like it, I’m gonna go out on a limb and say that most language introductions/overviews/tutorials don’t mention it.
- tech_army 2mo agoWill definitely try it.
- zerr 2mo agoWhile the language is interesting, sadly, nobody is using it in the wild. Maybe due to cumbersome deployment options? The ability to produce native standalone executables would boost its usage I believe.
- TheGoddessInari 2mo agohttps://docs.racket-lang.org/guide/exe.html https://docs.racket-lang.org/guide/exe.html
- throwaway27448 2mo agoRacket has been able to produce standalone executables for a while now.
- dented42 2mo agoGiven that a lot of people use it in the wild I’m not sure where you’re getting that from.
- mark_l_watson 2mo agoI wrote my own AI coding harness in Racket, it works fine, meets my own needs. I did earlier versions in Common Lisp and Python but the Racket version is the most full featured.
- velcrovan 2mo agoNot only do I produce standalone executables in Racket, I cross-compile GUI apps written on MacOS to produce executables for Windows.
- tonetheman 2mo agoI have tried racket and it was fun enough but man those parens. But racket is a really nice language to play with.
- so-cal-schemer 2mo agoThere are tools, particularly packages in Emacs, but also for VS Code and other IDEs, that make navigating nested s-expressions a breeze. And other tools for balancing parens automatically, and for syntax highlighting. You can just dim them if they are too visually jarring.
- usxr1515 2mo agoI've been designing my own small language runtime in Rust (VM + JIT + AOT backends) mostly as a way to actually understand tradeoffs compiler authors make instead of just reading about them. Racket's approach to macros and language-oriented programming is one of the things I keep coming back to as a reference curious how much of that flexibility comes at a real runtime cost vs. being mostly a compile-time abstraction.
- brabel 2mo agoI can answer that for Common Lisp, specifically the SBCL implementation (there's several others). It compiles every function to native code (you can even inspect the assembly with `disassemble`). Macros are executed before code is compiled. Hence, once you've compiled a function, the macro disappears since its only role is to generate the expressions that are going to actually be compiled and then executed. For example, here's a simple CL macro: (defmacro defer (cleanup &body action) `(unwind-protect (progn ,@action) ,cleanup)) `unwind-protect` is like a `try/finally` in other languages, and I used that above to create something similar to `defer` in Go/Zig which is related to it, but with the operands inverted. The ` symbol is a quasiquote. Unlike quote `'` it lets you unquote symbols inside with the , operator. That's why you'll always see a bunch of '`' and ',' in macros. The @, thing is a "spread" (looks different in Racket from what I saw in the post, which used `...`). It just spreads whatever was on the list in the place you put that on, so if `action` is `(p 1) (p 2)`, then `(progn ,@action)` becomes `(progn (p 1) (p 2))`. You can inspect what the actual code that will be compiled looks like with `macroexpand`: CL-USER> (macroexpand '(defer (cleanup) (do-something))) (UNWIND-PROTECT (PROGN (DO-SOMETHING)) (CLEANUP)) `progn` is a "special operator" that's needed when you want more than one expression to be evaluated in order. Example calling the macro: CL-USER> (defer (print "done") (print "hello") (print "again")) "hello" "again" "done" As you can see, it executed the deferred expression last. We can prove that macros disappear after compile-time with an example: CL-USER> (disassemble (lambda (x) (+ x x))) ; disassembly for (LAMBDA (X)) ; Size: 36 bytes. Origin: #x8005F70664 ; (LAMBDA (X)) ; 64: AA0A40F9 LDR R0, [THREAD, #16] ; binding-stack-pointer ; 68: AA0B00F9 STR R0, [CFP, #16] ; 6C: EA030CAA MOV R0, R2 ; 70: EB030CAA MOV R1, R2 ; 74: 297E80D2 MOVZ TMP, #1009 ; 78: 5E6B69F8 LDR LR, [NULL, TMP] ; SB-KERNEL:TWO-ARG-+ ; 7C: DE130091 ADD LR, LR, #4 ; 80: C0031FD6 BR LR ; 84: E00120D4 BRK #15 ; Invalid argument count trap You can see the Assembly is very simple for `(+ x x)` (the ADD instruction plus a bunch of stack/error maintenance). If we instead had a macro that did this: (defmacro my-macro (x) `(+ ,x ,x)) And a function used that: (defun f (x) (my-macro x)) Now, disassembling the function: CL-USER> (disassemble #'f) ; disassembly for F ; Size: 36 bytes. Origin: #x8005C00374 ; F ; 74: AA0A40F9 LDR R0, [THREAD, #16] ; binding-stack-pointer ; 78: AA0B00F9 STR R0, [CFP, #16] ; 7C: EA030CAA MOV R0, R2 ; 80: EB030CAA MOV R1, R2 ; 84: 297E80D2 MOVZ TMP, #1009 ; 88: 5E6B69F8 LDR LR, [NULL, TMP] ; SB-KERNEL:TWO-ARG-+ ; 8C: DE130091 ADD LR, LR, #4 ; 90: C0031FD6 BR LR ; 94: E00120D4 BRK #15 ; Invalid argument count trap Same thing exactly. I don't know Racket, but knowing it can compile to binary, I expect macros in Racket would work exactly the same.
- GregBuchholz 2mo ago> no special syntax for anything. (list '(1. . #\#) -5/6+7.s-8i `(1 ,@2) 1@1 ;hmmm, no unquote splicing comma ;-) 10# ;surprised? (list #i+1 +1i 1+i) ;complicated or complex? #e-1e10i ;Old MacDonald? "(* 9 10)" #())
- jqpabc123 2mo agoIt looks more like a "program" for an HP15c pocket scientific calculator. Not necessarily a bad thing but also not exactly what I would call "expressive". You may be able to build anything you want --- which may be efficient when communicating with the machine. But I wonder about now well this would communicate with other programmers.
- jibal 2mo agoIt's not a program, it is (obviously) a totally unrealistic hodgepodge expression for a list of constant values that simply demonstrates the literal syntax for a variety of types of values (real numbers, dotted pairs, rational numbers, complex numbers, polar coordinates, etc. -- Racket is unusually expressive in the types of literals). Your comment demonstrates something typical of HN, and it's not a good thing. It's as if in a discussion about C someone posted, without explanation, an entry from the Obfuscated C contest and then someone else, making zero effort to understand what was posted, said that it looked like line noise and questioned whether C is conducive to communication between programmers.
- euduhdhbene 2mo agoFirst time dealing with developers I see. I’m sorry.
- jibal 2mo agoNonsensical non sequitur ad hominem. (FWIW I've been a software developer for 60 years and have dealt with many of them.) I won't respond further.
- ux266478 2mo agoNothing against Lisp, but to correct the record: > For decades, Lisp was the language of artificial intelligence. [...] Then came the "AI winter," funding dried up, and Lisp went from star to cult language. Lisp had fallen from relevance before then. Only the United States was still using it, and mostly out of technical debt and a stubborn refusal to move on. Prolog displaced it in the late 1970s, and even within the US, the Lisp part was an unfortunate implementation detail to get to a Prolog-shaped object. It's not surprising that the US fell way behind Japan in this area in the 1980s. Anybody who would imply they would take a Lisp machine over a PIM is either not interested in symbolic computation and just likes Lisp, or they're doing so out of total ignorance of how much more advanced the PIMs were for symbolic AI. The cutting edge was with Prolog, and that's still the case today. Nobody's researching MIL in Lisp, even in America.
- BoingBoomTschak 2mo agoAnd then mini/microKanren put Prolog in its rightful place: that of a useful DSL instead of a poor general purpose language.
- ux266478 2mo agominiKanren is a replacement for a Prolog like a shitty tree-walking sexpr interpreter that doesn't even have modules is a replacement for Racket. I don't even know what to say to you for suggesting that, frankly. Anyways the embedded inference engine as an idea failed a long time ago, Americans convinced themselves it was the way to do things and just refused to ever let it go. It's just extra baggage on the important bit, which is the symbolic computation. miniKanren has a niche more in line with a theorem solver.
- BoingBoomTschak 2mo agoInstead of us two milling about: https://minikanren.org/minikanren-and-prolog.html https://minikanren.org/minikanren-and-prolog.html (and this is both informed and pretty impartial from what I can read)
- 0x3444ac53 2mo agoMild nitpick, but on Janet https://news.ycombinator.com/item?id=26496339 https://news.ycombinator.com/item?id=26496339
- soegaard 2mo agoBtw - if people are interested in Racket related blogs / articles etc. https://racket-stories.com/ https://racket-stories.com/
- SilentM68 2mo agoThanks for sharing. It's been bookmarked :) .-. / λ \ '---'
- SA9G 2mo agoMy first language, 1980 in CMU, was Pascal... quickly followed by LISP in CS/AI courses and C for EE courses. I was a big fan of MacLisp at the time, the MIT version that GLS worked on (could see his comments all over the sources). Of course GLS moved on to Scheme and wrote a few definitive papers on closures. Yeah, that was before PC's everywhere... a loooong time ago. (C++ came years and years afterwards, not a fan. I would have stayed with hardware if the ++ version of C was forced on me all those years ago.) GLS moved to CMU in the early 80's... I remember taking "Comparative Programming Languages" from him. Good teacher and impressive guy. In addition to the obvious, he also covered SNOBOL and APL in that course. Memories :-)
- ventana 2mo agoAs the article correctly mentions, Lisp as a concept is much older than any of the popular languages used these days; so are the attempts to get more people use it. Most of them are, unfortunately, unsuccessful, because it's probably impossible to understand Lisp after a quick and friendly introduction. I first met Common Lisp during my college years in early 2000s: we had an enthusiast teacher who taught it for free, in his free time; it was interesting for me as a freshman to learn something new, but also I literally had no idea how to write Lisp code properly, without resorting to using `progn` here and there. For those not aware, `progn` is a form that allows you to write expressions in a sequential way, pretty much like you use the C compound statement, a `{ ... }` block. It works, and after some time you find that you're writing in some crappy imperative programming language with a lot of brackets but you don't learn much about the functional programming. It took me more than a year, and definitely more than any short “friendly introduction”, to understand the functional approach. Now, Racket. I first noticed it while doing my daily LeetCode; they added Racket as a supported language and you can go use it to solve a task. After not using Lisp for 20-something years, I appreciated the opportunity, but I found the type contract syntax infuriating. This is LeetCode #1, “Two sum”: (define/contract (two-sum nums target) (-> (listof exact-integer?) exact-integer? (listof exact-integer?)) ) I don't know what you feel, but this makes me want to close this tab and never return. So if I find myself wanting to write some Lisp and there's a daily LeetCode task I want to solve, the first thing I do is I delete all this garbage and come back to the clean option: (define (two-sum nums target) ...) which, except for the minor syntax differences, brings me back to my college Lisp years and I can actually enjoy it.
- vermilingua 2mo agoAnother awesome Racket resource: https://beautifulracket.com/ https://beautifulracket.com/
- wild_egg 2mo ago> Emacs Lisp — millions of people run Lisp every day without knowing it, because their editor is a Lisp interpreter. Are there seriously any emacs users who are completely unaware of elisp? Isn't elisp the entire point of picking emacs?
- BeetleB 2mo agoMost Emacs users I personally know simply treat it as an editor. They're not really aware how it works under the hood.
- zelphirkalt 2mo agoStill doubt, that they are unaware of Elisp. Bare bones vanilla Emacs is maybe a bit much to get used to these days, so anyone wanting to configure their Emacs will have opened their init.el or so file and will have put some Elisp snippets there.
- BeetleB 2mo agoI've helped such people with their configs. They just know it as "commands" they put in the init file - they don't think of it as a programming language. It's rare for simple init.el files to have things like functions, loops, etc. And, to be frank, most of them don't customize the init.el file. They just want a text editor - not an IDE. The defaults are ugly, but they're perfectly functional. None of these people customized Notepad or any other editor either. They're simply solving the problem of "I've SSH'ed into a remote machine. How do I edit this file?"
- zelphirkalt 2mo agoWhy are they then even setting up vanilla Emacs in particular? Not impossible, of course, but it seems like a strange choice to make when not wanting to engage with its configuration. Or maybe another question would be who set them up with vanilla, unconfigured Emacs, if they are not so technical users? Even discovering tramp is not trivial or automatic and for working on a remote machine, isn't Vim much more common?
- Geometridae 2mo agoHiii, I'm Geometridae (Astrid Motilla)! A friend from the Racket community mentioned that my article appeared here. Thank you for reading it, and I'll make sure to take all this feedback and these different perspectives into account for this and future articles! :) I’d also encourage you to give it a try and have some fun with it! I’m using it for some of the 3D demos in my book. It’s definitely not a silver bullet, but I’ve found it can be pretty productive. Personally, my favorite Lisps are Racket, Common Lisp, and Clojure, in that order. I’ve also been tempted to give Chicken Scheme a try! :)
- iainctduncan 2mo agoIf you like those, a less well knowned Scheme you will likely really like is s7. :-)
- Geometridae 2mo agoOn a more personal note, for some weird reason, Racket ended up being the language that got me one of my most important contracts. Through a whole series of butterfly-effect events, that eventually led me into CAD software development, which is where I discovered my love for metamaterials. It’s funny how these things happen!
- slim 2mo agobecause autocad is scripted in lisp ?
- Geometridae 2mo agoNever touched AutoCAD, I know they have autoLISP , but yeah maybe
- srcreigh 2mo agoSide note, does anybody know of some good Rhombus codebases I can read?
- zelphirkalt 2mo agoFairly new, I think there will not be much Rhombus around yet.
- infinitebit 2mo agoThe second recursion example introduces 2 syntax features without explaining them (let, square brackets)
- pjmlp 2mo agoInteresting article overall, although some gotchas on the introduction. Misses out on LispWorks and Allegro Common Lisp for the Common Lisp entry, which contrary to SBCL provide a similar graphics experience as the Lisp machines of yore, here missing out on TI and Xerox as well, Genera wasn't alone.
- so-cal-schemer 2mo agobtw: Lean 4 is getting all the buzz these days, but how many people know that Scheme/Racket is an extraction target language for the Rocq Prover (aka Coq). https://rocq-prover.org/ https://rocq-prover.org/ The Rocq Prover implements a high-level program specification and mathematical language called Gallina that is based on an expressive formal language called the Polymorphic, Cumulative Calculus of Inductive Constructions that itself combines both a higher-order logic and a richly-typed functional programming language. Through a vernacular language of commands, the Rocq Prover allows: to define data structures, functions or predicates, that can be evaluated efficiently; to state mathematical theorems and software specifications; to interactively develop formal proofs of these theorems; to machine-check these proofs by a relatively small certification "kernel"; to extract certified programs to languages like OCaml, Haskell or Scheme. As a proof development system, the Rocq Prover provides interactive proof methods, decision and semi-decision algorithms, and a tactic language for letting the user define its own proof methods. Connection with external computer algebra systems or theorem provers is available. As a platform for the formalization of mathematics or the development of programs, the Rocq Prover provides support for high-level notations, implicit contents and other mechanisms for formalization at scale.