Skip to content

Add Typelevel welcome guide - #689

Open
dhinojosa wants to merge 9 commits into
typelevel:mainfrom
dhinojosa:welcome-page-fresh
Open

Add Typelevel welcome guide#689
dhinojosa wants to merge 9 commits into
typelevel:mainfrom
dhinojosa:welcome-page-fresh

Conversation

@dhinojosa

Copy link
Copy Markdown

Add an introductory welcome guide to Typelevel

The guide begins with familiar Scala concepts and gradually introduces:

  • Typelevel's mission and community
  • Representational types and making illegal states unrepresentable
  • Immutability and function composition
  • map, filter, flatMap, and for-comprehensions
  • Side effects and referential transparency
  • The motivation behind effect types
  • A small IO-inspired data type built step by step
  • Programs, algebras, and interpreters
  • An overview of the Typelevel ecosystem

The page is intended for readers without prior functional programming experience. It includes runnable Scastie examples and diagrams to make the concepts more
approachable.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

Branch preview

A preview of the website generated with the content of this pull request is available at this URL:

https://pr-689.typelevel-website.pages.dev

@SethTisue

SethTisue commented Sep 7, 2026

Copy link
Copy Markdown
Member

This will be an excellent addition to the site! Super useful.

But I do have a suggestion on structure:

After the introductory paragraphs about community, the transition into specific technical explanations (of types and flatMap and such) is rather abrupt and disorienting.

Before you launch into talking about what types are, I'd suggest inserting a section that summarizes what's coming. The gist of the added material would be: "In the main body of this document, we'll give you a crash course on what typed functional programming is. We'll explain why types and immutability are so important and beneficial to software quality, and we'll show how they're expressed in Scala. We'll introduce you to the IO type, [and so on]... Finally, at the end of the document, we'll introduce you to the libraries that make up the Typelevel ecosystem..." that kind of thing. So the reader will know what's coming so they can continue reading or not, skip ahead or not. Even if they decide to plow straight through and read the whole thing, knowing the bigger picture will help them stay oriented as they read.

(I'm not sure how lengthy the transition should be. Perhaps you'll decide some brief transitional material is enough, or perhaps you'll want to dwell it on longer...?)

@dhinojosa

Copy link
Copy Markdown
Author

Noice! Appreciate it @SethTisue

The 3rd to 5th paragraphs have that
"This introduction starts with ordinary Scala values and functions. From there, we will learn how map, flatMap, and for-comprehensions let us combine values without discarding the information carried by their types.

Finally, we will use those ideas to build a small version of IO, the foundational data type from Cats Effect.

You do not need prior experience with functional programming. Every new idea builds on the previous one."

But I see your point that there is a (or more) spots where it feels like it goes from hot water to cold water. Let me see what I can do to ease that transition

@dhinojosa

Copy link
Copy Markdown
Author

https://pr-689.typelevel-website.pages.dev/welcome/welcome is where the page resides, by the way. I have not linked it to the front page.

@jducoeur jducoeur left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a little while to begin a deep read of the text. I'm only about a quarter of the way through, but it's time to go do other things, so here are a few thoughts so far. Nothing critical, but some possibilities to consider.

Comment thread src/welcome/welcome.md

## What is Typelevel?

Typelevel is a non-profit organization dedicated to providing principled, type-safe, functional programming tools for the Scala ecosystem. We are hyper-focused on functional programming and building a welcoming, inclusive community around pure functional programming in Scala.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might tone that down to just "focused" - "hyper-focused" feels like over-egging the pudding a little bit. (Especially in that we also try to be very pragmatic about what actually works, and things aren't necessarily quite that pure under the hood.)

Comment thread src/welcome/welcome.md
@@ -0,0 +1,1354 @@
# Introduction to Typelevel

## What is Typelevel?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this section is combining two rather different purposes: introducing what Typelevel-the-organization is, and starting to introduce the practical tutorial about coding within our ecosystem. The overall flow winds up feeling a little disjoint, especially with the "Welcoming Community" bit coming in between a few paragraphs about the technical stuff and then diving into it more deeply.

I'd probably recommend rearranging slightly -- shortening this intro section to just mention the tutorial that makes up the bulk of the page, and moving the last three paragraphs down into a section of their own, as the beginning of a top-level "Tutorial" section.

Comment thread src/welcome/welcome.md

## Let Types Show Your Work

Types are an essential part of Scala and central to the philosophy of Typelevel. If you think back to your professor or teacher in mathematics and physics, they would tell you to “label your work”. A value of `10` could represent 10 meters, 10 seconds, 10 kilograms, or 10 meters per second. The labels provide context and help verify that your calculations are correct. If you expected a result in meters per second but instead got kilometers per second, the labels immediately indicated that something had gone wrong.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think back to your professor or teacher in mathematics and physics

Musing: should we worry about this being classist? I think it's correct for the typical programmer, but I worry about it coming across as snooty to the self-taught folks who didn't come up through STEM.

Comment thread src/welcome/welcome.md

Types are an essential part of Scala and central to the philosophy of Typelevel. If you think back to your professor or teacher in mathematics and physics, they would tell you to “label your work”. A value of `10` could represent 10 meters, 10 seconds, 10 kilograms, or 10 meters per second. The labels provide context and help verify that your calculations are correct. If you expected a result in meters per second but instead got kilometers per second, the labels immediately indicated that something had gone wrong.

Programming follows the same principle. Rather than relying on comments or variable names to describe what a value represents, we use types. A type gives meaning to a value, defines which values are valid, and determines which operations make sense. This philosophy is at the heart of the Typelevel ecosystem.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defines which values are valid

Might be worth leaning into this a little bit more, since it's the heart and soul of strongly-typed programming IMO, and wildly unobvious to folks coming from dynamically-typed languages. The notion that a type is synonymous with the set of values that you can put into a variable or parameter is an important intuition to impart.

Even more, the critical point is that a type defines what values can't be placed here, and why that's so enormously helpful. Folks coming from a non-compiled languages tend to complain about the compilation process, and strong types are the baseline of why the compiler is really helpful. So in your power example below, it might be helpful to show an error example of trying to combine types illegally, and how the compiler prevents that mistake.

Comment thread src/welcome/welcome.md
sumKw: Double = 25.4
```

In the example above, what stops us from doing this when we use plain numbers? One is a Kilowatt, the other is Megawatt-Hours, and we were attempting to add two numbers that really shouldn’t be added together. Using raw numbers like this is a code smell called _primitive obsession_. We are obsessing over `Double` in this case for everything! This is why we have to show our work with labels in our math and physics homework; the same goes for our programming language. A better option is to use a wrapper around the number; this is called a _value object_.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is called a value object.

Is it? I usually think of this as "value class" instead, although I'm not certain what's more common.

Comment thread src/welcome/welcome.md
scala> sum == Megawatts(0.035) // comparisons automatically convert scale
res1: Boolean = true
```
**Try it in Scastie!** [![Try it in Scastie](../img/media/welcome/scastie.png)](https://scastie.scala-lang.org/5SNhXYrTRxWFp8lR10da7A)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker, but down the line we might want to investigate whether we can inline the Scastie window usefully -- that might reduce friction a little.

(If they manage to get in-browser Scastie working, I'd say that becomes a slam-dunk; as it is, it's worth thinking about.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separately: clicking on this appears to replace the current tab with Scastie, which is a roadbump. I'm not certain whether this Markdown dialect has an easy way to do that as a new tab, but that would be strongly preferable IMO.

Comment thread src/welcome/welcome.md
xs.reduceLeft(_ + _) / xs.length.toDouble
```

The type tells callers that `average` always has at least one value to work with. Its methods preserve that guarantee when

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The type tells callers that `average` always has at least one value to work with. Its methods preserve that guarantee when
The type tells callers that `average` requires at least one value to work with. Its methods preserve that guarantee when

Comment thread src/welcome/welcome.md
Comment on lines +122 to +125
```scala
final case class User(id: Long, name: String, favoriteLanguageId: Long)
final case class Language(id: Long, name: String)
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor note, but I'm concerned that a Scala novice might look at this section and conclude that final has something to do with immutability. I'd probably drop that in this example: while it's true that case classes shouldn't generally be extended (so final is a nice little belt-and-suspenders protection), it's minor (I essentially never bother in my production systems), and I think it's a distraction from your main point here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants