What does HackerNews think of coalton?

Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.

Language: Common Lisp

#3 in JavaScript
I haven't used it, but I know that Coalton adds static typing to Common Lisp, might be something you're interested in.

https://github.com/coalton-lang/coalton

Agree that you can use types to express and prove logical properties via compiler; it can be a fun way to solve a problem though too much of it tends to frustrate coworkers in JavaLand. It's also not exactly "low cost"; here's an old quip I have in my quotes file:

"With Scala you feel smart having just got something to work in a beautiful way but when you look around the room to tell your clojure colleague how clever you are, you notice he left 3 hours ago and there is a post-it saying use a Map." --Daniel Worthington-Bodart

> On the contrary, they're still the most effective technique we've found for improving program correctness at low cost.

This is not borne out by research, such as there is any of any quality: https://danluu.com/empirical-pl/ The best intervention to improve correctness, if not already being done, is code review: https://twitter.com/hillelogram/status/1120495752969641986 This doesn't necessarily mean dynamic types are better, just that if static types are better, they aren't tremendously so to obviously show in studies, unlike code review benefit studies.

My own bias is in favor of dynamic types, though I think the way Common Lisp does it is a lot better than Python (plus Lisp is flexible enough in other ways to let static type enthusiasts have their cake and eat it too https://github.com/coalton-lang/coalton), and Python better than PHP, and PHP better than JS. And I prefer Java to PHP and JS. Just like not all static type systems are C, not all dynamic type systems are JS. Untyped langs like assembly or Forth are interesting but I don't have enough experience.

I don't find the argument that valuable though, since I think just focusing on dynamic vs static is one of the least interesting division points when comparing languages or practices, and may be a matter of preferred style, like baseball pitching, more than anything. If we're trading experience takes I think Clojure's immutable-by-default prevents more bugs than any statically typed language that is mutable by default; that is, default mutable or default immutable (and this goes for collections too) is a much more important property than static types or dynamic types. It's not exactly a low cost intervention though, and when you really need to optimize you'll be encouraged by the profiler to replace some things with Java native arrays and so on. I don't think changing to static types would make a quality difference (especially when things like spec exist to get many of the same or more benefits) and would also not be a low cost intervention.

Some domains also demand tools beyond type proofs. i.e. things like TLA+. I think adding static types on top of that isn't very valuable, similar to adding static types on top of immutable-by-default isn't very valuable.

Last quip to reflect on. "What's true of every bug found in the field? ... It passed the type checker. ... It passed all the tests. Okay. So now what do you do? Right? I think we're in this world I'd like to call guardrail programming. Right? It's really sad. We're like: I can make change because I have tests. Who does that? Who drives their car around banging against the guardrail saying, "Whoa! I'm glad I've got these guardrails because I'd never make it to the show on time."" --Rich Hickey (https://www.infoq.com/presentations/Simple-Made-Easy/)

Common Lisp is strongly typed, it's just that types follow values rather than bindings. This presents some code generation challenges, but it will warn on correctness just fine.

And of course if you really want an ML style BDSM type system in Common Lisp there's Coalton[1].

[1] https://github.com/coalton-lang/coalton

> Lisps can be very flexible, but they usually lack static type safety, opening a wide and horrible door to run-time errors.

People should do basic research before writing something silly like this. Qualifying your statement with 'usually' is just a chicken sh*t approach. Common Lisp and Racket have optional strong typing, leaving the responsibility and choice to the developer. Common Lisp is great for implementing compilers. You also have things like Typed Racket and Coalton. The latter is completely statically typed ala MLTON

https://github.com/coalton-lang/coalton

I don't agree. One can write a serious, syntactically bullet-proof grammar for a language built out of S-expressions, with nice error messages and all. We can imagine a parallel universe in which TFA's Postgres example were written using S-expressions:

     := (ALTER-TABLE (:IF-EXISTS? :ONLY?)  :*? +)
            | ...

     := ...
Despite using S-expressions, this is parseable with as much rigor as more free-form character syntax.

I think Coalton [1] is a good example of this. The language is embedded as S-expressions in Common Lisp, but you get Rust-like error messages, showing exact source lines (with line numbers) and embedded underlines showing the location of the offending code.

With that said, what is true is that if you're using Common-Lisp-style macros and you're manipulating S-expressions programmatically, lexical information may get thrown out. This is not unlike doing a bunch of string manipulation in an ORM to generate SQL, which will have similarly poor error messages.

[1] https://github.com/coalton-lang/coalton

Coalton [1] is an OCaml-like dialect of ML: it's strictly evaluated, has imperative features, and doesn't force a purity-based development philosophy. However, Coalton has S-expression syntax and integrates into Common Lisp. It works, and is used "in production" by its developers, but it's still being developed into a 1.0 product.

Coalton made a lot of design decisions to work away from issues that this post describes.

- Coalton dispensed with ML's module system of structures, signatures, and functors. No doubt a beautiful concept, and sometimes satisfying to write, but almost always unsatisfying to use due to how explicit one tends to need to be. Like the author suggests, the "interface-style" of type classes or traits has always felt more intuitive, despite losing the ability to have multiple implementations of an interface for a single type. (However, I've come to appreciate that different interfaces should require different types—as opposed to one type having many interfaces.) Coalton uses type classes.

- Coalton has S-expression syntax. No indent rules. No precedence rules. No expression delimiters. All of the "tradition" of ML syntax is dispensed with into something that is a lot easier to read and write for complex programs... yes, provided you use ParEdit or similar

- It should be no surprise that with S-expressions, you get Lisp-style macros. Macros in Coalton are just Common Lisp macros. No separate pre-processors. No additional language semantics to deal with. Arbitrary compile-time computation and/or codegen, completely integrated.

- Because it's built on Common Lisp, Coalton gets something few (if any?) other ML-derivatives get: Truly incremental and interactive development. You can re-compile types, functions, etc. and try them out immediately. There's no separate "interpreter mode"; just a Lisp REPL.

Coalton's language features are still settling (e.g., records are being implemented) and the standard library [2] is still evolving. However, it's been used for "serious" applications, like implementing a compiler module for quantum programs [3].

[1] https://github.com/coalton-lang/coalton

[2] https://coalton-lang.github.io/reference/

[3] https://coalton-lang.github.io/20220906-quantum-compiler/

I vehemently disagree with dynamically typed being a winning point of Lisp. SBCL's strong support for type checking is the main reason I was drawn from Scheme to CL, and Coalton (https://github.com/coalton-lang/coalton) is one of the most interesting Lisp projects I have encountered.

Type checking can remove an entire class of bugs from even being a consideration. Yes, it could be argued that type mismatches are a trivial class of bug, and yes, proper testing should catch any issues... but catching problems before you go to testing can save you precious seconds, especially when coding in the typical interactive style of Lisp. Lisp lets you code at amazingly high velocity, good support for type checking helps increase that velocity even further.

I meant regarding types, I think the equivalent to the other link would be Coalton: https://github.com/coalton-lang/coalton
>I've yet to see an optionally or gradually typed language pull that off well.

Opinions on Coalton in Common Lisp?

https://github.com/coalton-lang/coalton

I can agree it's not the same, but what's the point? A more interesting disagreement is that I wouldn't say it's a downside (though yes, there are tradeoffs). Especially in Current Year when open source is fashionable and pretty much every language has a package manager to make pulling in or swapping out dependencies pretty easy, I don't see the issue. It's also interesting to note that of all the things Clojure did to "fix" shortcomings of past languages with a more opinionated (and often more correct I'll admit) design philosophy that users are forced to use (even when it's not more correct), infix-math-out-of-the-box wasn't one of them. I don't think that specifically really hurt Clojure adoption. (But of course Clojure is reasonably extensible too so it also has a library to get the functionality, though it's more fragile especially around needing spaces because it's not done with reader macros.)

I've brought the library up many times because CL, unlike so many other languages, really lets you extend it. Want a static type system? https://github.com/coalton-lang/coalton/ Want pattern matching? No need to wait for PEP 636, https://github.com/guicho271828/trivia/ If all that keeps someone from trying CL, or from enjoying it as much as they could because of some frustration or another, due to lacking out of the box, chances are it is available through a library. (Or heck, even just tooling setup. Tab completion for symbols and jumping to function definitions are just two great things modern programmers enjoy in all sorts of languages, CL too, if someone doesn't have that setup I wonder if they must enjoy pain.)

Common Lisp, because that's what I am learning right now.

Rust, because I finally made it from beginner to intermediate level (at least I think).

https://flix.dev/ looks very cool.

Also, recently someone posted this here on HN: https://github.com/coalton-lang/coalton

It's a statically-typed, functional language embedded in Lisp, with many of the FP goodies.

> "something like C"

SBCL? Or ECL (compiles to C), CLASP (C++, LLVM)?

The older ThinLisp? (compiles a subset of CL to C) https://github.com/ska80/thinlisp

The very new NPT, a CL implementation in C? https://github.com/nptcl

> Static typing for ahead-of-time more-correct programs

the Coalton library. A ML/Haskell as a CL library. https://github.com/coalton-lang/coalton/

> Static typing for faster or leaner programs

SBCL

> WebAssembly

Common Lisp running natively over WebAssembly: https://news.ycombinator.com/item?id=31590819 (very much POC)

I know, I know, but he didn't mention any of these in the blog post, nor any CL project. Justice is done.

Not so easy question, especially because it depends of the implementation, but SBCL gives pretty good static type errors and warnings. Mostly, you get warnings at the function boundaries. It isn't complete like type checking in the modern languages, but it helps catch many errors. And quickly & interactively, because we compile our functions as we write them, with a keystroke (or the whole file, and from time to time, we build the whole project from scratch). So, coming from Python, that was superbly useful to me. This, everybody uses it. We can also add gradual typing to our variables and functions. It might help for the static checks, and it also gives hints for the compiler to speed things up. We can also declare our own types, but these won't be used for compile-time inference.

For a type-racket equivalent, we now have Coalton, it's like a Haskell on top of CL: https://github.com/coalton-lang/coalton/ Its author says:

--

Take this with a grain of salt, because I’m neither a user nor expert of Typed Racket, but:

    Typed Racket focuses more on the gradual typing of a given program. It has lots of features to make that easier, such as occurrence typing. Coalton is a separate, embedded language.
    Typed Racket achieves polymorphism through subtyping and and first-order type variables. Coalton achieves polymorphism through type variables, higher-kinded types, and type classes.
    Coalton, like ML and Haskell, focuses on defining objects by their properties and supported functions. This is a proposed way of having modular, reusable code. Typed Racket, as far as I can tell, has no such features.
    Coalton code can be fully inferred, so type annotations are not necessary. Typed Racket cannot.
All in all, I think the biggest and most important take-away is that Typed Racket goes through great effort to seamlessly blend with ordinary Racket. But that means Typed Racket has to compromise on type system features that can only be supported if you’re willing to change the language itself.

Coalton puts the type system first, opting for something close to Haskell, at the expense of not being a system for gradually typing Common Lisp, and instead being a separate language altogether.

---

They use it for their open-source quantum compiler and other things.

Coalton comes to mind: https://github.com/coalton-lang/coalton

It adds static typing to Common Lisp, while (I believe) still allowing one to escape to the dynamic world when needed. Sure, there are statically-typed languages, but I don't know of another dynamic language in which something like Coalton has been done.

What's the process look like for Python these days, after you install Python itself (or are made aware of the system Python if there is one)? IDLE was pretty bad back in the day and even though it was 'easy' I wouldn't have recommended it to newcomers.

Assuming you can convince people to give emacs a try (shouldn't be hard if they're convinced to give Lisp a try and otherwise don't have preexisting biases against emacs for other reasons), getting setup for Lisp is as easy as installing Portacle (https://portacle.github.io/). It and any decent Lisp setup includes things like a hotkey to autocomplete, so you just type 'typ' and tab or whatever, and out pops suggestions like 'type', 'typep', 'type-of', ... and so you don't have to remember spelling; similarly they all should have some sort of intellisense to minimize trips to the CLHS or jumps to source code. I'm a vim head (which is why I don't know what newbie setups are like anymore apart from doing it in vim) but even when I type "(getf " I'm shown at the bottom "(getf PLACE INDICATOR &OPTIONAL (DEFAULT NIL))". If that's not enough, I can jump to source with "ctrl+]" (really nice being able to jump to the Lisp implementation's source for built-ins too without having to do anything special -- can even modify it live by adding print statements or whatever I want), or typing ",s" to get the symbol's describe output (I mainly like it for getting the docstring -- if memory serves though Portacle gives you the docstring with the lambda list in an intellisense popup automatically, like a Java IDE), and if I really need to ",h" opens a browser tab to the hyperspec page on that symbol.

If Portacle isn't one's cup of tea, it becomes a bit harder, but I don't think it's "orders of magnitude" harder... Compared to setting up a local (L|W)AMP environment back in the mid-late 2000s, which tons of teens learning PHP did, it's a piece of cake. You install a Lisp implementation (like SBCL -- http://www.sbcl.org/platform-table.html if your distro doesn't package it/have a recent version), configure it to use Quicklisp (a couple commands -- https://www.quicklisp.org/beta/), and consult the CL Cookbook for further basic steps on setting up the best environment you can for a variety of editors (https://lispcookbook.github.io/cl-cookbook/editor-support.ht... -- emacs, vim, VS Code, Atom, Sublime...).

For scaling, CL has scaled to multi-million lines of code projects, it scales fine. If you want more sophisticated type checking, there have been solutions over time, but in case you missed the latest and greatest take on it: https://github.com/coalton-lang/coalton

I have been using Common Lisp professionally for over a decade. Largest codebase was probably ~100k lines for an embedded optical fingerprint analysis and booking system for US law enforcement agencies. The largest Lisp team I've worked on was about 30 people for satcom hardware.

Every time I've described to people on the internet what makes Lisp nice, I've been met with a riposte that such aspects aren't unique to Lisp—be them interactive/incremental development, macros, efficient machine code, editor integration, whatever—or that a laundry list of features means nothing and instead Lisp's value should somehow be proven through its (hitherto comparatively dismal) popularity with employers and software engineers. I myself have definitely given up on an academic approach to proselytizing the language, and instead have just focused my energy in building applications and libraries people (especially employers) find useful, at smaller cost and in shorter time than other people are able to provide.

It's like classical music. I can't convince you such music is incredibly rich and pleasant, especially not by talking about the harmonic theory of common practice. Instead, you just have to listen and agree or disagree, I think.

And Lisp certainly has no secrets; it's old as can be and extraordinarily and thoroughly documented. Countless people (myself included) have spilled ink on the (alleged) virtues of Lisp. It's all out there.

When it comes down to it, it's an incredibly flexible language useful for prototyping and rapid development, while at the same time supporting everything you need to transform your application into a rock solid, robust, static binary. All of Lisp's features balance in such a way that developer time and energy are prioritized and consequently optimized.

P.S., Like a sibling comment mentioned, you can have Haskell-level static typing in Common Lisp with Coalton: https://github.com/coalton-lang/coalton

You might want to look into Coalton as statically typed, functional language on top of Common Lisp: https://github.com/coalton-lang/coalton

That said, Common Lisp while dynamically typed, is also strongly typed. Many type errors are prevented at runtime. Also you can declare types and have some limited form of static type checking in SBCL.

Common lisp can be and has been successfully used for high-performance numerics[0] as well as low-level system code[1], all while being a high-level, garbage-collected language. (The latter property likely leading to better overall performance in large programs.)

Verification may be interesting, for high-assurance (e.g. automotive/aerospace) applications. It's for this reason that a theorem prover[2] and an ml[3] have been implemented, and they interoperate freely with the rest of common lisp.

In other words: we are already where you want to be, and we are even less stratified than you propose we would need to be.

0. https://github.com/marcoheisig/Petalisp

1. https://github.com/froggey/mezzano/

2. https://www.cs.utexas.edu/users/moore/acl2/

3. https://github.com/coalton-lang/coalton

There is! Coalton: https://github.com/coalton-lang/coalton

> Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp

Be aware that SBCL does pretty good compile-time type checking. It helps a lot during dev. And there's the new https://github.com/coalton-lang/coalton to have like Haskell atop CL.
> You should learn Lisp, no matter what kind of developer you are. But by today's standards, Lisp a pretty antiquated language which still hasn't caught up to modern trends (static types, asynchronism, etc...) and with a very poor tooling (lack of IDE's) and library ecosystem (building websites, parallelism, GUI, etc...).

Literally all of these things are present in Common Lisp (ok the static types "full experience" leads you to something like Coalton: https://github.com/coalton-lang/coalton however the plain SBCL experience does have some compile-time type checking). Meanwhile many so-called modern languages still lack Lisp's incremental compilation let alone the full interactive development experience such a feature can help support, an OOP system as flexible as CLOS, they can't gracefully manipulate their own code as data, they don't have anything like the condition system...

AoC is often used to learn a new programming language, but it can also be used to improve them—especially less established ones.

Theres a small community [0] of people who decided to try out Coalton [1], which is a Common Lisp DSL that has a strict, Haskell-like type system, and has strict evaluation (not lazy) semantics. Pattern matching, algebraic data types, all that jazz are supported directly in a Common Lisp environment.

For example, here is a function to read in the first problem's data, which makes use of the usual high order functions (map and filter), as well as currying (only one argument provided to /=, making it curried):

    (declare read-aoc-data (Unit -> (List Integer)))
    (define (read-aoc-data _)
      "Read the data for problem 1."
      (let ((data (fromSome "Couldn't read AOC1 data."
                            (read-file-into-string aoc1-input-file))))
        (map parse-int-or-fail
             (filter (/= "") (split-string #\Newline data)))))
Type annotations, as in any good ML, are optional (except when there are polymorphism bugs, like one found during AoC!). Unlike Haskell, purity isn't demanded.

There's a small contest [2] with all sorts of prizes for doing AoC in Coalton and contributing back to the project through tutorials, PRs, and bug reports.

[0] They hang out on Discord https://discord.gg/cPb6Bc4xAH

[1] https://github.com/coalton-lang/coalton

[2] https://coalton-lang.github.io/20211129-aoc-contest/

It’s a lot more practical than you think if you’re willing to roll up your sleeve and do the work.

Fortunately, people have already done the work for you. [1]

[1] https://github.com/coalton-lang/coalton

I'm fairly new to lisp programming, but there's a language called Coalton that provides static type checking to Common Lisp. I believe both languages are one and the same, but Coalton provides some type guarantees while still being able to have all of the interactiveness CL devs are used to.

https://github.com/coalton-lang/coalton