Last weekend, I put together a working sample for how to show multiple syntax errors from Racket macros. It works in DrRacket and racket-xp-mode. It's based on code from Typed Racket. https://gist.github.com/srcreigh/f341b2adaa0fe37c241fdf15f37... The well-documented Racket `raise-syntax-error` will let you display 1 syntax error at a time. It works by throwing an exception during macro expansion hence you only get 1…
I like this comment. What doesn't add up for me, is how you can do compile-time type-checking in a language that has eval, or an equivalent mechanism. As far as I can see (which is not very far at all), you have to either give up the dynamic Lisp magic of producing and running new code whenever you like, or you give up the static Haskell magic of proving (some) correctness at compile time by having a rigid exoskeleto…
Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
11–20 of 31 posts
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#12Last weekend, I put together a working sample for how to show multiple syntax errors from Racket macros. It works in DrRacket and racket-xp-mode. It's based on code from Typed Racket. https://gist.github.com/srcreigh/f341b2adaa0fe37c241fdf15f37... The well-documented Racket `raise-syntax-error` will let you display 1 syntax error at a time. It works by throwing an exception during macro expansion hence you only get 1…
I like this comment. What doesn't add up for me, is how you can do compile-time type-checking in a language that has eval, or an equivalent mechanism. As far as I can see (which is not very far at all), you have to either give up the dynamic Lisp magic of producing and running new code whenever you like, or you give up the static Haskell magic of proving (some) correctness at compile time by having a rigid exoskeleto…
1. `(compile ...)` and `(eval ...)` don't always have to succeed. Both those routines can be hooked into in Lisp — by and within the running process — and made to fail upon Type-incorrect code.
2. In some Lisps, 'compile-time' and 'eval-time' are the same thing.
> ... you have to either give up the dynamic Lisp magic of producing and running new code whenever you like, or you give up the static Haskell magic of ...
Note that even the "static" Haskell has a way to do "the dynamic Lisp magic of producing and running new code whenever". The simplest example would be a Haskell REPL.
----
The "dynamic Lisp magic" you refer to is actually very simple: allow code to be replaced within a running process. Lots of non-Lisps have it. E.g., Python, Ruby, JS, even Bash. The part where Lisp truly shines, and what sets it apart from those other languages, is that those languages gained this feature merely as a side-effect of dynamism, but not from the purpose of enabling a truly dynamic software construction developer experience. From simple things like `defvar`/`defonce`, `undefine-function`, etc. to fabulous and complicated ones like `defclass`, conditions and restarts, the interactive debugging support, etc.
A good DX is a first-class feature in some Lisps.
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#13Last weekend, I put together a working sample for how to show multiple syntax errors from Racket macros. It works in DrRacket and racket-xp-mode. It's based on code from Typed Racket. https://gist.github.com/srcreigh/f341b2adaa0fe37c241fdf15f37... The well-documented Racket `raise-syntax-error` will let you display 1 syntax error at a time. It works by throwing an exception during macro expansion hence you only get 1…
I like this comment. What doesn't add up for me, is how you can do compile-time type-checking in a language that has eval, or an equivalent mechanism. As far as I can see (which is not very far at all), you have to either give up the dynamic Lisp magic of producing and running new code whenever you like, or you give up the static Haskell magic of proving (some) correctness at compile time by having a rigid exoskeleto…
I've also dreamed of accessing Racket macro syntax errors at runtime and building my own interface for viewing the errors. For example, send sandboxed DSL code over an HTTP request, and send any errors in a response to view them on a web application.
I also cannot see very far, but I suspect you could whip something like this up using the error-display-handler [1] parameter and the macro stepper [2].
Of course, there is a paper written about DrRacket (aka DrScheme) which you can study [3] as well as DrRacket source code [4].
[1]: https://docs.racket-lang.org/reference/exns.html#%28def._%28...
[2]: https://docs.racket-lang.org/macro-debugger/index.html
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#14In a lot of programming discussions, especially those about Haskell or those about Lisp, types invariably come up as a feature (or a bug). Some even suggest static or dynamic types are most useful at different phases of a programming project. I've heard opinions go every which way with types. By and large, the concept of static types (to Haskell levels) and dynamic types (to Smalltalk levels) are typically spoken abo…
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#15Earlier quoted context omitted.
I like this comment. What doesn't add up for me, is how you can do compile-time type-checking in a language that has eval, or an equivalent mechanism. As far as I can see (which is not very far at all), you have to either give up the dynamic Lisp magic of producing and running new code whenever you like, or you give up the static Haskell magic of proving (some) correctness at compile time by having a rigid exoskeleto…
> ... how you can do compile-time type-checking in a language that has eval, or an equivalent mechanism 1. `(compile ...)` and `(eval ...)` don't always have to succeed. Both those routines can be hooked into in Lisp — by and within the running process — and made to fail upon Type-incorrect code. 2. In some Lisps, 'compile-time' and 'eval-time' are the same thing. > ... you have to either give up the dynamic Lisp mag…
Can I have it both ways though? Can I get compile-time guarantees, about non-trivial run-time generated code? It feels like there's going to be a Halting Problem that stops me having my cake and eating it too.
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#16Earlier quoted context omitted.
> ... how you can do compile-time type-checking in a language that has eval, or an equivalent mechanism 1. `(compile ...)` and `(eval ...)` don't always have to succeed. Both those routines can be hooked into in Lisp — by and within the running process — and made to fail upon Type-incorrect code. 2. In some Lisps, 'compile-time' and 'eval-time' are the same thing. > ... you have to either give up the dynamic Lisp mag…
Ok. I'm happy with compile-time eval failing in normal Lisp, I might have given it an undefined symbol or something. And in Haskell I can go "off the grid" and write something dynamically typed, or even make a Lisp interpreter. Can I have it both ways though? Can I get compile-time guarantees, about non-trivial run-time generated code? It feels like there's going to be a Halting Problem that stops me having my cake a…
Sure. If you control all sites where run-time code gen happens, you can gate them all on a compiler-check. In fact, the former is just `cl:eval`; and in some Lisps, a compiler-check already guards it.
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#17In a lot of programming discussions, especially those about Haskell or those about Lisp, types invariably come up as a feature (or a bug). Some even suggest static or dynamic types are most useful at different phases of a programming project. I've heard opinions go every which way with types. By and large, the concept of static types (to Haskell levels) and dynamic types (to Smalltalk levels) are typically spoken abo…
what is your view on Clojure.spec?
1. Learned to program in dynamic languages;
2. Learned FP in Clojure;
3. Writes [mostly, wherever possible] FP code in TypeScript for the last several years…
… I wish Clojure.spec was this or something a lot like it instead.
It’s cool that Clojure tried a novel approach to defining interface boundaries in a dynamic language. Other approaches (TS, Python, even PHP) have prioritized static analysis first with varying approaches to runtime. I think Clojure missed a design opportunity here by inverting that.
A design which treated spec as annotation first, runtime optional would have been an excellent opportunity for something like Coalton (or mypy) as a third party offering.
Ultimately this is mostly a cultural divide (as noted everywhere). But it’s a gap that’s hard to bridge without a huge effort like this. TypeScript is probably the most successful (reach) externally maintained type system for a dynamic language, but only on account of JavaScript’s own success in reach and being owned and invested in by a megacorporation. Doing this with Clojure (or any lisp) is infeasible without similar metrics.
I’ve often thought “there’s enough flexibility with Clojure, start it as a hobby project and see where it goes”. But I’m deterred because:
1. Even hobby projects using tech in ways it’s not designed for is a huge slog (me says as I go into weekend umpteen staring at a yak shaving integration with esbuild/Node/test runner).
2. The bar is very high. If you don’t support LSP, you’re basically barking at the moon. If it’s not syntax highlighted in README.md, no one’s interested. If it’s not mature there’s not enough adoption to build a community around it to even get it syntax highlighted. If it’s static typing in a lisp, you’re already narrowing the audience that might disregard all of the rest.
Sorry for the novel when you didn’t even ask me, but… this is all pretty much what flooded my thoughts the moment I saw/read this post and asked myself “how do I feel about this relative to clojure.spec?”
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#18Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#19So, why is it named "Coalton"?
Re: Coalton: How to Have Our (Typed) Cake and (Safely) Eat It Too, in Common Lisp
#20Or am I confusing "statically typed" and "no GC"? Sadly a lot of even statically-typed languages lack support for transparently bridging between application and no-GC real-time code, using the same data types on both sides. I'd be fine writing application code in a no-GC language, but it seems most GUI libraries are sadly for GC languages.