I Wrote a Scheme in 2025 (maplant.com)

109 points by maplant 3 days ago

0xcafefood 7 hours ago

I really wish lisps were more popular (or, really, popular again). Most people can't make it past the non-Algol syntax, which is silly IMO. But they do also demand more of the user than a typical language.

Their use of metaprogramming doesn't just allow you to extend the language, it really expects that of the programmer. Which means you have to assume the role of language designer to some extent. Learning how to do that definitely feels like a way to level up your skills. But it seems uncommon for people to want to do that.

taylorallred an hour ago

I was really interested in lisps for a couple of years, but eventually I came to the conclusions: it's just hard to read. I know they say "the parens disappear" but even if that is the case, it simply requires you to jump around the expression holding lots of context in your head. I'm a fan of code that mostly reads top-to-bottom, left-to-right.

FranklinJabar 31 minutes ago

> I'm a fan of code that mostly reads top-to-bottom, left-to-right.

Programs are rarely linear; why do you expect code to be?

cultofmetatron 5 hours ago

> But it seems uncommon for people to want to do that.

It becomes more obvious once you start managing developers vs being a solo dev. everyone making their own designer means the language can morph into a completely insular creation with a learning curve that expands exponentially with every new hire. A little extra boilerplate is the cost of standardized idioms that work across both your codebase that your new hires are already familiar with from working in that language at other companies. its why go was created. personally I prefer rust and elixir as good middle grounds.

reikonomusha 5 hours ago

This is a common reaction/belief but usually from people who have not actually managed a team of Lisp devs.

Lisp devs are managed in the same way as any other: You have style guidelines, design review, code review, etc. Sometimes a new macro is good and vastly simplifies code. It's accepted as a PR and documented like anything else. Sometimes a new macro is bad, and it's promptly rejected by the team. It's a persistent myth that Lisp programmers are just going to design their own little languages everywhere in a shared code base and it'll be impossible to understand.

(Case in point: Look at open source Lisp code. There isn't even management or code review there! Yet the vast majority of Lisp code is actually just functions and classes, with the occasional macro to reduce boilerplate. In some circumstances, you have a library offering a macro, and it's actually well documented and easy to understand. See Iterate, SERIES, etc. for actual examples.)

Rust or Elixir or Java or whatever aren't at all immune to monstrosities created by astronomically complex or baroque abstractions, FactoryFactoryFactories, and so on. How do teams avoid those? Style guidelines, design review, code review, etc.

saghm 3 hours ago

maplant 7 hours ago

I think people underestimate how pragmatic meta programming can be because there are some obvious downsides. Arguably one of things that made Rust so popular was its inclusion of procedural macros.

But beyond that the thing I don't understand about the modern hate towards macros is that they are simply very fun.

bccdee 33 minutes ago

Yeah I strongly agree. I think the issue is that metaprogramming is complicated, so people (especially early in their careers) tend not to do it themselves, and only notice it when it's making their lives difficult. But there are a lot of cases where a little bit of judicious metaprogramming makes life MUCH easier. If you treat metaprogramming as a first-class tool, countless rough edges will smooth themselves out for you—everything from `#derive[Clone]` to `#derive[Serialize]`.

shpongled 6 hours ago

As someone who is "into" programming languages (and making toy implementations of them), I think some of the most important macros are along the lines of Rust/Haskells `derive/deriving` for quickly enabling serialization, printing etc. Using a language without such capability quickly becomes frustrating once you move to any kind of "real" task.

fmbb 4 hours ago

nine_k 5 hours ago

Ruby, Python, and Typescript use metaprogramming rather heavily. They lack the homoiconic property of lisps, but they can do both higher-order functions and monkey-patching.

Meta-heavy code usually offers a nice DSL, but is proportionally harder to drill down through.

skydhash 2 hours ago

pjmlp 3 hours ago

And yet we have done it across most modern languages, with a lesser experience as Common Lisp or Scheme.

tmtvl 6 hours ago

Lisp is versatile as all get-out, so you can program however you want. For example, we can roll like it's 1969:

  (prog ((a 0)
         (b 1)
         (c 0))
    (declare (type Fixnum a b c))
  :fb-start
    (print a)
    (incf b a)
    (setf a
      (- b a))
    (incf c)
    (when (< c 100)
      (go :fb-start)))

Joker_vD 20 minutes ago

Which actually supports the OP's original argument that even with training and getting used to, this syntax reads harder than

        let a, b, c = 0, 1, 0
    fb_start:
        writen(a)
        b +:= 1
        a := b - a
        if c < 100 do goto fb-start

codr7 2 hours ago

I've been playing around with dropping most of the parens, but keeping the rest.

https://gitlab.com/codr7/shik

antonvs 40 minutes ago

People have played around with those exact ideas for decades. No-one has ever come close to making it work.

reikonomusha 5 hours ago

Three thoughts (in the context of Common Lisp specifically):

- Every day that passes, the gulf between Lisp's tooling and what a typical user expects grows wider. It needs to escape Emacs and SLIME to something that feels complete and polished.

- There needs to be a little bit of a culture shift around Lisp to actually write programs that do things. How many programs can you download via apt or brew that are written in Lisp? They're executables at the end of the day so nothing in principle stops this from happening, but there's just a thread of modern Lisp culture where it's more fun to play around in the REPL and write creative libraries than to ship. (There are notable exceptions of course.)

- I personally like the quirkiness of Common Lisp, but there are so many ways to write it (imperative, functional, etc.), so many ways to structure your programs (one package, package per file, package inferred system, etc.), and so many ways to offer APIs (plain old data and functions, generic function protocols, etc.) that it makes it a combination of confusing and intimidating. I think shifting toward something a little more structured and disciplined like Coalton, while still giving the escape hatches to all of Common Lisp, would help a lot of people "join in" on building new code or building upon existing code.

vindarel 3 hours ago

New projects are making the newcomer experience easier:

- ICL https://github.com/atgreen/icl/ a full featured REPL in the terminal and the browser.

- JSCL's playground 100% in the browser https://wiki3-ai.github.io/jscl-kernel/ (very new)

- constantly new editor plugins. A new one: Zed https://github.com/etyurkin/zed-cl (all editors, for readers, including VSCode, Pulsar etc: https://lispcookbook.github.io/cl-cookbook/editor-support.ht... Those editors appeared in recent years. So, I see a good trend in the ecosystem).

nocman 3 hours ago

> - Every day that passes, the gulf between Lisp's tooling and what a typical user expects grows wider. It needs to escape Emacs and SLIME to something that feels complete and polished.

Can you give specific examples of "what a typical user expects" that are missing from Emacs-based programming environments (SLIME, and/or others)? I'm not suggesting there aren't any, I'd just like to know your list.

Pay08 3 hours ago

0xcafefood 5 hours ago

Agreed. I think Clojure strikes a pretty reasonable balance here. It's opinionated about the programming paradigm, scales back some of the pain that comes from reader macros, and solves some of the bootstrapping problems by compatibility with other JVM languages.

harperlee 5 hours ago

reddit_clone 5 hours ago

Well CL is supposedly the programmable programming language. So none of this is surprising..

renato_shira 4 hours ago

the "assume the role of language designer" part is underrated. even if you never ship production lisp, writing a toy interpreter changes how you think about every other language you use. suddenly you understand why certain design decisions were made, not just what they are.

i wrote a tiny scheme evaluator as a learning exercise and it was probably the best investment of a few weekends i've ever made as a programmer.

nxobject 4 hours ago

Another reason this is interesting beyond "Lispiness" instead: implementing a (compliant) Scheme takes on some interesting problems that other languages punt - proper tail recursion, delimited continuations (off the top of my head, I don't know other methods apart from CPS), and hygienic macros.

antonvs 38 minutes ago

Last I checked no compliant Scheme required delimited continuations. Unless something like that was added in R7RS or later.