6 ms·
After 20 years of programming[1], I’ve gotten to a point in my life where an advanced type system (with strong static types, no nulls — optionals instead, type
by winter_blue 8y ago
After 20 years of programming[1], I’ve gotten to a point in my life where an advanced type system (with strong static types, no nulls — optionals instead, type inference, type refinement, etc) is absolutely mandatory for any language I’ll pick (when I have the freedom to choose). I’ve heard that there are libraries that tack types onto LISP — but how good are they?
LISP code I’ve seen anywhere has always been without types (ie dynamically typed). No LISP dialect that I’m aware of has prioritized or talked about or emphasized type checking. Is this something that’s even big on the radar of the LISP implementors and the LISP community at large?
I’ve been burned too many times working on large (100k+ LOC) dynamically typed codebases that I really never want to work with such a codebase again.
A sincere question: Besides its homoiconic syntax and probably the best implementation of macros — what does LISP offer over a modern programming language with a sophisticated type system – even, for instance, a language as old as OCaml?
Peter Norvig has web page called “Is Lisp Still Unique? Or at Least Different?” that was last updated back in 2002 where he talks about the unique features LISP offers, and how other languages are catching up: http://norvig.com/Lisp-retro.html http://norvig.com/Lisp-retro.html Modern languages of today offer the features that made LISP unique and superior in its heyday, and languages with powerful type systems offer a huge advantage that LISP never has had.
[1] I started programming in 1998, when I was 8 years old. I’ve developed software professionally for a far shorter period.
- VogonWorkEthic 8y agoI've heard racket is the way to go with types in lisp. https://racket-lang.org/ https://racket-lang.org/ Just passing along what I heard though, I personally don't use types and think things like clojure spec do a much better job fitting the bill.
- peatmoss 8y agoI think some are bristling that Racket is the way to go, but Typed Racket is certainly a good way to go. https://docs.racket-lang.org/ts-guide/ https://docs.racket-lang.org/ts-guide/ You can start without types and later convert parts of your code to typed without too much headache. But, as the GP has mentioned, SBCL allows you to add type annotations which is similar in spirit to the idea of progressively adding types. Even as a Racket fan (and Racket’s performance is pretty good), I covet the blazing performance of SBCL, so the calculus is not cut and dry.
- sevensor 8y agoInteresting stuff is happening performance-wise. I have my eye on both Racket-on-Chez and pycket.
- peatmoss 8y agoRacket-on-Chez may eventually result in a better performing Racket, but SBCL is still going to be a hard target to match. That said, Racket on Chez means more of Racket is getting written in Racket. In turn, I suppose Racket-on-SBCL is not outside the realm of possibility. In general, it would be cool if Racket ran in more places.
- arminiusreturns 8y agoOr maybe guile?
- peatmoss 8y agoSome exciting stuff happening in Guile land these days. They’re getting a new JIT which sounds like it makes Guile’s performance closer to Racket’s. Also, I’ve been pleasantly surprised by some of the libraries in Guile. For example I was looking for a curses library the other day, and Guile’s was the clear standout in the Scheme-o-sphere. I didn’t follow through on my project, but Guile’s implementation looked pretty thorough and well-documented. Oh, and GNU project stuff does have a nice consistency to it. I mean, all the docs are predictably there and follow the same typographical conventions. That’s a nice feature IMO. Racket does something similar, but Racket’s also not the size of the entire GNU ecosystem, which gives Guile some network effects in terms of that consistency.
- phoe-krk 8y agoSBCL has a very sane type inference engine that it uses to detect type mismatches and for optimization. This, along with type and ftype declarations, is enough to write statically typed code in Lisp with compile-time warnings.
- YouAreGreat 8y ago> enough to write statically typed code in Lisp Certainly not in the way "statically typed" is usually understood. Containers (outside of specialized arrays) aren't parameterized, so every time you extract a value from a list or map, the "static type" is the top type. SBCL remains essentially unityped with islands of type propagation for better performance of (mostly) numeric code.
- phoe-krk 8y agoLists aren't typed in standard Common Lisp. For these cases, using THE around the access site is required to declare the type for inference.
- 0x445442 8y agoI'm with you. I went through the whole dynamic and weak typing love fest but my thinking has evolved. I much prefer static and strongly typed languages now because I don't view lines of code or the number of key strokes as the limiting factor in the development process. The bottle neck is always reasoning about code (new or existing) and debugging.
- cicero 8y agoI've been thinking along the same lines. I currently use Python for relatively small projects, but even then, I wish I had type declarations when I come back to code I haven't looked at in a while. What is your favorite language with an advanced type system, Haskell, OCaml, or something else? I've dabbled in both, but I want to dive deep into one. I like the look of Haskell more, but I'm a little afraid of it.
- beders 8y agoTypes are for the compiler. Not humans. We just happen to use it as a way to remind us what data looks like. It's not the only way to figure out what happens in a function. I've gone the exact opposite route now: From static types to dynamic types to interactive coding using specs. Specs are much more expressive than types but - and that is the main difference - it's a la carte and opt-in. If you don't opt-in, you'll spend more time at the REPL figuring out what a certain piece of code does.
- Jach 8y agoAs mentioned, types are in the standard, and certain implementations provide compile time warnings of type and other issues...[0] The biggest non-feature advantage (the condition system is a pretty big feature though missing from everything else) is the mindset of writing programs, which other dynamic languages typically don't get right. The idea of "growing" a program, and responding to change, is part of that mindset and once it's internalized a lot of the language decisions make a lot more sense. e.g. "trace", "break", "compile" are all part of the standard, all available at runtime, whereas in other languages you tend to have a separation of the runtime from any "IDE feature" like debugging break points, tracing function calls, and compiling (not "eval"ing) new code. Other languages + IDEs are getting there but there's so much more to go. In Java land, with the support of things like JRebel, we can make pretty significant modifications to a running program like add/change/remove methods to a class. But what about any existing objects I may have instantiated? Those are left around, referring to the old code. In Lisp, redefining classes works out of the box (no need to wait decades for JRebel to show up), and "update-instance-for-redefined-class" is a standard generic function, which you can write a version of to handle conversion of existing objects. No mysterious old versions of objects running around, you didn't have to bring down the program to restart it, nice. It's a very dynamic and inspectable system, going beyond just the types of things. That to me is still Lisp's advantage as other languages + language tools slowly add more and more of its features that are there already in Lisp independent of extra tools (and Lisp has extra tools too for more things). I can't resist commenting a bit more on the type situation directly though... The creator of Clojure talks about "situated programs" in https://www.youtube.com/watch?v=2V1FtfBDsLU https://www.youtube.com/watch?v=2V1FtfBDsLU (he also has 20+ years of professional programming -- I on the other hand am only arguably on year 10 of "paid" exp (I wouldn't call all my gigs professional and not all were full time) but I tend to ignore how much experience someone has when people with equal or greater experience have such divergent views) and along the way I think he makes good points about how type systems get in the way of designing these big long-running systems that need to change as the years go by. Certainly I see this problem in the gigantic Java code base I deal with every day. Tight coupling is the nemesis of modularity, which you need for big systems, I tend to view static types as premature tight coupling. They're not without their benefits (typo protection less so for me but I love the easy speed wins, which you get in Common Lisp too if you bother to declare types; a form of QE via formal type proofs can be useful too), but they're also not without their downsides, and for many types of programs large or small the downsides can dominate. [0] Examples: https://news.ycombinator.com/item?id=12222404 https://news.ycombinator.com/item?id=12222404 (told about state never being reached? awesome!) https://news.ycombinator.com/item?id=13389287 https://news.ycombinator.com/item?id=13389287 (notes about why it couldn't use a fast operator, so you need to fix your types) https://news.ycombinator.com/item?id=14780381 https://news.ycombinator.com/item?id=14780381 (other nice things like unused var, wrong number of arguments, typoed name...)
- handojin 8y agoWell, there is Shen which has a novel type system based on the sequent calculus: http://shenlanguage.org/ http://shenlanguage.org/
- flavio81 8y ago>After 20 years of programming[1] 29 years here. I started in 1988. >I’ve gotten to a point in my life where an advanced type system... is absolutely mandatory for any language I’ll pick I used static type systems for most of my programming life until i used Javascript, Python, and then Common Lisp. I don't consider them mandatory. On the other hand, I do consider strong typing mandatory. That was my problem with Ruby and Js, not to mention PHP as well. >without types (ie dynamically typed) "dynamically typed" doesn't mean "without types" >No LISP dialect that I’m aware of has prioritized or talked about or emphasized type checking Well, check again, then -- Common Lisp is strongly typed and has a lot of type checks. They just happen at runtime. >I’ve been burned too many times working on large (100k+ LOC) dynamically typed codebases that I really never want to work with such a codebase again. Which language? >what does LISP offer over a modern programming language with a sophisticated type system you'll have to research more >Modern languages of today offer the features that made LISP unique and superior in its heyday None offers metaprogramming as easy as powerful as in Lisp. (read again "easy" as key point) None, except Dylan or some Scheme extensions, offer something like CLOS None, except Smalltalk and derivates (Pharo) offer a powerful interactive image-based environment where everything is dynamic and can be redefined at runtime; AND the running image can be saved to disk an restored later. Very few will have an exception handling and recovering mechanism as complete and reliability-assuring as Common Lisp's "signals, conditions and restarts" system. Few offer a full numeric tower out of the box, including IEEE floats, bignums, fixnums, complex nums, and fractional numbers. Very few dynamic programming languages run as fast as Common Lisp. Few of them compile to native code without losing any feature or functionality or forcing you to use a subset of the language. And none of all, except Common Lisp, offer all of the above at the same time. >and languages with powerful type systems offer a huge advantage that LISP never has had. You're forgetting the advantages that Lisp have over them. But I don't want to convince you -- i have huge respect for OCaml, SML and Haskell (btw, Did you know the first ML implementation was basically a extension to Lisp?) -- they simply have a very different philosophy for development, one that is focused at doing everything at compile time, and of giving you just a few tools to deal with ill behavior at compile time.
- kbp 8y ago> I do consider strong typing mandatory. That was my problem with Ruby What isn't strongly typed about Ruby?
- mark_l_watson 8y agoSerious suggestion: Haskell is a Lisp so use it. (I use Common Lisp, Scheme, and Haskell - I consider Haskell to be Lisp-like enough and has the same repl based programming from the bottom coding work flow). I really prefer Lisp to Haskell, but Haskell is also awesome. If you want a strongly typed Lisp then look no further.