<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://blog.jez.io/feed/types.xml" rel="self" type="application/atom+xml" /><link href="https://blog.jez.io/" rel="alternate" type="text/html" /><updated>2026-01-21T18:17:55-05:00</updated><id>https://blog.jez.io/feed/types.xml</id><title type="html">Jake Zimmerman | Types</title><subtitle>A collection of blog posts about programming, software, types, programming languages, Sorbet, Vim, Markdown, and more.</subtitle><author><name>Jake Zimmerman</name></author><entry><title type="html">Why have lower bounds on generics?</title><link href="https://blog.jez.io/lower-bounds/" rel="alternate" type="text/html" title="Why have lower bounds on generics?" /><published>2025-12-23T15:46:34-05:00</published><updated>2025-12-23T15:46:34-05:00</updated><id>https://blog.jez.io/lower-bounds</id><author><name>Jake Zimmerman</name></author><category term="sorbet" /><category term="ruby" /><category term="plt" /><category term="types" /><summary type="html"><![CDATA[Lower bounds expand the list of ways to create a value of that type. They behave similar to union types in that regard, but they fill a particular niche that only they can fill, relating to subtyping.]]></summary></entry><entry><title type="html">Past, Present, and Future of Sorbet Type Syntax</title><link href="https://blog.jez.io/history-of-sorbet-syntax/" rel="alternate" type="text/html" title="Past, Present, and Future of Sorbet Type Syntax" /><published>2025-04-25T01:57:00-04:00</published><updated>2025-04-25T01:57:00-04:00</updated><id>https://blog.jez.io/history-of-sorbet-syntax</id><author><name>Jake Zimmerman</name></author><category term="ruby" /><category term="sorbet" /><category term="types" /><category term="plt" /><summary type="html"><![CDATA[A discussion of how Sorbet's type syntax came to be, the problems it solves, and how it could improve.]]></summary></entry><entry><title type="html">Generic methods cannot have non-generic defaults in Sorbet</title><link href="https://blog.jez.io/generic-method-default/" rel="alternate" type="text/html" title="Generic methods cannot have non-generic defaults in Sorbet" /><published>2024-07-28T13:47:45-04:00</published><updated>2024-07-28T13:47:45-04:00</updated><id>https://blog.jez.io/generic-method-default</id><author><name>Jake Zimmerman</name></author><category term="ruby" /><category term="sorbet" /><category term="types" /><summary type="html"><![CDATA[Sorbet does not allow generic methods to have non-generic default arguments. The best alternative is to split the method into two methods, with one implemented by calling the other with the default value.]]></summary></entry><entry><title type="html">Abstract singleton class methods are an abomination</title><link href="https://blog.jez.io/abstract-singleton-methods/" rel="alternate" type="text/html" title="Abstract singleton class methods are an abomination" /><published>2024-01-01T19:25:23-05:00</published><updated>2024-01-01T19:25:23-05:00</updated><id>https://blog.jez.io/abstract-singleton-methods</id><author><name>Jake Zimmerman</name></author><category term="ruby" /><category term="sorbet" /><category term="types" /><summary type="html"><![CDATA[Abstract singleton class methods do not belong in a well-behaved type system. Sorbet allows them anyways, which causes problems. Here's why they're bad and what to do instead.]]></summary></entry><entry><title type="html">Why don’t constructors have override checking?</title><link href="https://blog.jez.io/constructor-override-checking/" rel="alternate" type="text/html" title="Why don’t constructors have override checking?" /><published>2023-12-31T00:14:09-05:00</published><updated>2023-12-31T00:14:09-05:00</updated><id>https://blog.jez.io/constructor-override-checking</id><author><name>Jake Zimmerman</name></author><category term="ruby" /><category term="sorbet" /><category term="types" /><summary type="html"><![CDATA[A discussion of how constructors in typical typed object-oriented languages get away with not having to solve a problem that plagues Sorbet.]]></summary></entry><entry><title type="html">Inheritance in Ruby, in pictures</title><link href="https://blog.jez.io/inheritance-in-ruby/" rel="alternate" type="text/html" title="Inheritance in Ruby, in pictures" /><published>2023-12-28T15:31:20-05:00</published><updated>2023-12-28T15:31:20-05:00</updated><id>https://blog.jez.io/inheritance-in-ruby</id><author><name>Jake Zimmerman</name></author><category term="ruby" /><category term="sorbet" /><category term="types" /><category term="in-pictures" /><summary type="html"><![CDATA[A solid grasp of the tools Ruby provides for inheritance, like include and extend, helps write better code. But the concepts are often learned hastily—this post revisits them in depth.]]></summary></entry><entry><title type="html">Why Sorbet needs T.let(…, T::Boolean)</title><link href="https://blog.jez.io/t-let-boolean/" rel="alternate" type="text/html" title="Why Sorbet needs T.let(…, T::Boolean)" /><published>2023-05-13T19:31:29-04:00</published><updated>2023-05-13T19:31:29-04:00</updated><id>https://blog.jez.io/t-let-boolean</id><author><name>Jake Zimmerman</name></author><category term="ruby" /><category term="sorbet" /><category term="types" /><summary type="html"><![CDATA[A short explanation of why Sorbet sometimes requires an explicit type annotation when initializing a variable whose type is changed in a loop.]]></summary></entry><entry><title type="html">Every type is defined by its intro and elim forms</title><link href="https://blog.jez.io/intro-elim/" rel="alternate" type="text/html" title="Every type is defined by its intro and elim forms" /><published>2023-04-23T19:43:00-04:00</published><updated>2023-04-23T19:43:00-04:00</updated><id>https://blog.jez.io/intro-elim</id><author><name>Jake Zimmerman</name></author><category term="programming" /><category term="plt" /><category term="types" /><summary type="html"><![CDATA[I took a course about programming languages in college. It was a very theory-oriented course, but as it turned out I learned more about how to write software from this theory course than many of my peers who took our school's software engineering elective.]]></summary></entry><entry><title type="html">Typing klass.new in Ruby with Sorbet</title><link href="https://blog.jez.io/typing-klass-new/" rel="alternate" type="text/html" title="Typing klass.new in Ruby with Sorbet" /><published>2023-02-19T22:34:27-05:00</published><updated>2023-02-19T22:34:27-05:00</updated><id>https://blog.jez.io/typing-klass-new</id><author><name>Jake Zimmerman</name></author><category term="sorbet" /><category term="ruby" /><category term="types" /><summary type="html"><![CDATA[The straightforward attempt at writing a Sorbet signature for a method that calls `klass.new` doesn't work. The strategy that does work uses abstract methods, and so I'd like to walk through an extended example showing how to get such code to typecheck.]]></summary></entry><entry><title type="html">Problems typing equality in Ruby</title><link href="https://blog.jez.io/problems-typing-ruby-equality/" rel="alternate" type="text/html" title="Problems typing equality in Ruby" /><published>2023-01-24T16:12:15-05:00</published><updated>2023-01-24T16:12:15-05:00</updated><id>https://blog.jez.io/problems-typing-ruby-equality</id><author><name>Jake Zimmerman</name></author><category term="sorbet" /><category term="types" /><category term="ruby" /><summary type="html"><![CDATA[TypeScript has this really handy error that flags when it looks like two values of unrelated types are getting compared. I would love to build the same error into Sorbet, but there are two features which make that hard: custom overrides of `==` and subtyping. Here are some heuristics we might consider building in Sorbet, and why they don't work.]]></summary></entry></feed>