Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Lisps are not statically typed typically and "strongly" typed is poorly defined. I would not consider most Lisp's type systems to be strong or particularly expressive, but they don't need to be because it would hurt the main benefit to the language: meta-programming. I don't think a "strong" vs "weak" type system argument is particularly valuable here, yes most prevent you from inadvertently changing how a particular series of bytes is interpreted, but their aggregates do not have any type identity besides their own typically. This means you cannot typically express and enforce an aggregate's covariance or contravariance properties. There may be ways to do so, but most do not provide utilities for it.


In Lisps, and other dynamic languages, two or more objects that are not related by inheritance can be substitutable. This is very useful.

That makes inheritance-based covariance and contravariance largely moot.

You have substitutability-based covariance and contravariance (you can't get away from those) but they cannot be subdued declaratively.

E.g. if you're passing a callback function somewhere, which you know will pass widget objects to the callback, it's okay to use a function that was written to handle gadget objects, if widget objects are designed to substitute for gadget objects.

That's contravariance of substitutability.

Substitutability is the only thing that matters in the end. Declared inheritance doesn't ipso facto guarantee substitutability, and therefore declared covariance or contravariance, which are inheritance based, do not guarantee actual substitutability-based covariance or contravariance.


> I don't think a "strong" vs "weak" type system argument is particularly valuable here, yes most prevent you from inadvertently changing how a particular series of bytes is interpreted [...]

I think that interpretation of the "strong" vs "weak" scale is a valuable one within the context of the blog post. The post is at least partially about how type systems can help the programmer by making them aware of certain kinds of errors (it is also about when: static vs dynamic).

My understanding of the terms covariance and contravariance are a bit shaky. Could you provide an example in another language that you think cannot be expressed using the provided utilities of most Lisp's?

You also mentioned that you don't think most Lisp's have "expressive" type systems. What do you mean by that? When I think of a type system as being expressive, I think of it as having explicit rather than implicit types, which is unrelated to the issue of strongly vs weakly typed and static vs dynamic types. Do you mean more like how you can describe / constrain the relationships between types in certain strongly typed languages?


> I think that interpretation of the "strong" vs "weak" scale is a valuable one within the context of the blog post. The post is at least partially about how type systems can help the programmer by making them aware of certain kinds of errors (it is also about when: static vs dynamic).

Sure, agree. That's also the real point: type systems primarily exist to make semantically impossible computations unrepresentable in the language (at least, without some extra song and dance). To this end, Lisps have rather lackluster type systems, but they don't try to encode much of the languages semantics into a type system.

> My understanding of the terms covariance and contravariance are a bit shaky. Could you provide an example in another language that you think cannot be expressed using the provided utilities of most Lisp's?

The wikipedia article on the topic is a great source: https://en.wikipedia.org/wiki/Covariance_and_contravariance_...

I'm actually mostly concerned with type invariants (ex. List[int]), which don't really have much for representation in Lisps from what I've seen. Further, see above about using types to make compile-time assertions/checks about the behavior at runtime.

> You also mentioned that you don't think most Lisp's have "expressive" type systems. What do you mean by that? When I think of a type system as being expressive, I think of it as having explicit rather than implicit types, which is unrelated to the issue of strongly vs weakly typed and static vs dynamic types. Do you mean more like how you can describe / constrain the relationships between types in certain strongly typed languages?

"Expressive" is a nothing word that doesn't have concrete meaning in-context, similar to "strong" type system. That being said, I would say Rust, OCaml, and TypeScript have expressive type systems: the behavior of the language is largely encoded as types. The implicit vs explicit nature of types is not super consequential IMO, it has more to do with how you primarily represent semantic meaning. In lisp, it's symbols. In Rust, it's traits, enums, and structs (+ the affine types, but that's not relevant here).


Why dynamic typing is required for metaprogramming? D (and rust and c++ to a significantly lesser extent) for example has extremely strong metaprogramming capabilities while being statically typed.


I didn't say it was required, I said it hurts it in Lisps case. One of Lisps strongest features is extreme flexibility and homoiconicity. Strict typing would make it clunkier, though maybe it's worth it for some scenarios.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: