Higher Kinded Types (Monads, Functors, etc.)

This back and forth banter about naming conventions is tiresome -- hey if you don't like them, then feel free add your own custom extensions to the types and wrap the functions / methods with names you find more palatable and opensource it if you think others would benefit.

Can we now bring this thread back on topic.

4 Likes

I thought this is very much on topic. Sensible naming is a big part of an Swift wide implementation. So we should not ignore that aspect.

5 Likes

I guess you got the "tiresome" tirade because you always ask people to come to you, and at the same time don't demonstrate much reciprocality at all. The vast majority of your messages are on a line that sounds like "I don't understand", "I can't understand", "I don't want", "I fear", and generally "this is bad". But you'll have a hard time changing this fundamental: every technical domain comes with a jargon that is necessary for efficient communication. Learn it, of stay outside. If you want to have any influence, work.

10 Likes

I can’t agree. Jargon is very rarely really needed. It is often just used to protect the own peer group from outsiders.

But on topic: shoundn’t we strife for a swifty implementation of concepts instead of just copying them verbosely from Haskel etc? They should be adapted to Swift not Swift adapted to them...

1 Like

Of course they should be adapted to Swift, and there will be a lot of effort to do that in an appropriate way. But we're talking about the baseline here, the theoretical basics, what's already there in the wild, references from other languages et cetera. While the concept of "higher kinded type" comes from type theory and it's not going to change in naming, other things can change, but that's NOT what we're talking about here: we're not talking about adding a Functor protocol to the standard library; we're talking about enhancing the Swift type system, and this discussion will of course involve type theory, and examples drawn from other languages/libraries, where switching names with magical arbitrary ones is useless, irrelevant and damaging for the discussion.

We very very clearly explained what "traverse" means, with real-world examples: you can internalize this, and move on, or you can focus on the most irrelevant part of the concept (the name of the function) and make hard for everyone to move the discussion further.

4 Likes

That's just wrong. You cannot reasonably talk mathematics without jargon, for example. There is no group theory without groups, no measure theory without measures etc.

I agree that the naming of certain concepts is not super intuitive. I wouldn't mind translating some of the concepts to something more "approachable", e.g. Functor -> Mappable. The question then becomes one of a tradeoff: Do you want to create names that suggest analogies (that might be adequate, but only up to a point), so that you can focus more on beginners, or do you want to use established terms so that everyone who already know functors etc. can readily recognise them?

That said, when you talk about highly abstract concepts (such as functors, monads, etc.), you really won't ever find a term that is intuitive, so that's why mathematicians have largely given up on those things and just use whatever term is established; it's more important that the definition is clear enough.

6 Likes

The problem I see with the math based naming is that very few coders are mathematicans.

I can talk from my personal experience:
lambda -> block - finally understood
monad -> chainable - much better mental image what it is
functor -> mappable - much better mental image what it is

I think this stems from the fact that few coders are interested in mathematical discoveries but in solutions to their problems. So it would be imo really be advatagous to have easier to stomage names for the normal users while the behind the curtain science better stays at it's jargon. So theory = fp jargon, end user facing features = easy names.

Hope it's understandable what I mean.

5 Likes

That's a fair assessment but as @ExFalsoQuodlibet already described, we're talking about adding features to Swift, and that's difficult without referring to prior art in other languages. Once these concepts land in Swift, it will always be possible to think about how to choose the names so they are more accessible.

4 Likes

The problem about reinventing terminology is that its always opinionated, and ultimately ends up with confusion about which algebras the method / function is in compliance with. So as much as you want to call it chainable, mappable, ... we prefer the official terms to avoid ambiguity

Plus your general gripe with all things FP and terminology has nothing to do motivating for Swift language support for HKTs, which is after all what this thread is about.

Ps. maybe consider using a browser plugin like tampermonkey to write a script to change Monad, Functor, ... i.e. all the terms that don't infuriate you. We'd appreciate it.

In some cases it might be interesting to explore different approaches. For example, Haskell’s Functor type class is more accurately describing endofunctors in the category Hask (i.e. the category of Haskell types).

It is quite possible to use a more general notion of Functor. This breaks from FP precedent but I believe Scalaz 8 is heading in that direction. If you do that and the term Functor is used more generally then you might rename the existing Functor typeclass HaskEndofunctor.

On the other hand, maybe it creates the space to adopt the name Mappable for the more limited notion of functor. That is certainly the “obvious” name that would occur to someone who “rediscovered” the notion of functor while writing code in Swift. I think this fact lies behind some of the comments of those less familiar with FP. It is not without merit and should not be dismissed. If we want to grow the community of people exploring FP concepts and techniques in Swift we need to keep this in mind. As the saying goes, naming is one of the hardest problems in computer science!

I bring this up in order to point out that maybe there is a path that moves math-oriented FP forward and simultaneously makes the basic concepts more accessible. The designs used by Haskell are not the only way to program with these mathematical concepts in a principled way. Breaking with tradition is always controversial but if nobody ever explored new approaches progress would be sacrificed.

9 Likes

I agree. It's useful to start from a common foundation, but then there's no reason to avoid the exploration of different naming conventions and representations.

For example, in the eventuality of the addition of HKTs in Swift, an improvement to the standard library could be the unification of the "mappable" types (properly mappable, not like the map defined on Dictionary or Set), and I happen to think that Mappable is a nice name for the use case we usually shoot for (that is, endofunctor on the category of the language types): then, in the documentation for Mappable, we could of course link the original mathematical ideas and concepts, but by avoiding loaded words like "Functor" we could also avoid the slippery slope upon which is defined the "category of Swift types", that would probably encounter the disapproval of mathematicians.

I also agree that Haskell doesn't own the final word on many matters concerning FP (I think that Purescript, for example, made some steps forward), and I'm not a fan of literal translations of functional libraries that disrespect the style and conventions of the target language: I agree with many ideas expressed by Brooklyn Zelenka in this talk about algebraic FP in Elixir.

But none of this would be conceivable without HTKs.

2 Likes

This conversation seems to be getting a little heated. I don’t think anybody here is arguing in bad faith; I am seeing a fair amount of condescension, though. If you feel that someone will never be convinced by your arguments, please just politely end the discussion instead of expressing your frustration.

12 Likes

No problem with discussing Swift-isms at the right time. This hasn't even reached provisional agreement for a draft proposal so arguing about terminology surely is a bit of jumping the starter pistol.

Should focus not be on defining the key blocking points for HKTs and seeing if we lead the conversation in that space. Let me know if I've completely missed this boat.

As much as HKTs may be appealing as a way to create powerful (if somewhat hard to understand) abstractions, I wonder if it would be possible to really show practical examples of benefits in swift land (not just other languages).

Would there be for example something in swift stdlib that would reduce the code size by hundreds or thousands of lines if we had some HKT capabilities in swift?

If the benefit is only writing 3 lines with HKT, instead of writing those 3 lines in 5 different places currently, then it doesn’t feel enough bang for the buck...

4 Likes

i stopped reading this naming argument about ten posts ago, but can I just say

  • choosing good names is important. it’s hard to use something if you can’t even talk about it. I don’t know why the monad fandom likes to dismiss these concerns as “irrelevant” when there are 213 posts one thread over arguing over how many hashtags a raw string should have.

  • there are many red flags when it comes to names. being popular among mathematicians is one of them.

  • programming is full of “highly abstract” concepts that have great, simple to understand names. think ‘server’, ‘kernel’, ‘thread’, ‘header’, ‘page’, ‘dictionary’ etc. abstractness is not an excuse for inventing new words that no one understands.

4 Likes

Agreed, started from first principle rooted in math to explicit the whole picture.

It seems the conversation has diverted from the topic of Higher Kinded Types to naming. Which to me is a premature concern and a distraction. We first need to agree on a couple things before talking about names:

  • Are higher kinded types useful? Evidently yes, but it appears some more users would like to see more examples. Moreover, because they are useful themselves doesn't mean we actually want them in the language
  • If we agree they should be in the language what's the timeline we are looking at? There is probably a couple things to take care of before they get implemented.
  • After all this we can talk about what they should look like syntactically, discuss naming convention and feature flags and probably discuss implementation details as well.

In my own experience there were many times where I wished Swift had higher kinded types in order to abstract over a type constructor.

For example, some library code I am (was actually) writing did care about the type constructor passed in argument (* -> *) but nothing else. We made do with what we had, adding custom protocols to Array, List, Option, etc. But it would be nice to not have to rely on either code generating tools or repetitive patchwork code to implement generic libraries.

4 Likes

The point is not reducing the code size of the standard library, but to give (other) library authors more abstraction power.

An important point to me is the fact that the higher the abstraction power, the more possibilities will be there for library authors to invent and, more than anything, discover things that we, a minuscule subset of Swift users, can't even imagine. And from this discussion (along with many others, in other threads) I can see that the pressure towards improving the abstraction power of Swift is evident.

For example, the lack of conditional conformance has been a gigantic hindrance towards using algebraic data types because you always had to rewrite specific "boxes" for every possible semantic definition (a good example is the SwiftCheck testing library). Now that we have it, many many many library authors have radically improved their libraries, but you don't see them in this forum saying that conditional conformance changed everything and should have been there in the first place. People write to point out what's missing, not what's there and has become the norm.

In other words, if Swift aims to be an actual general-purpose language adaptable to many platforms and many kind of developers, you don't care about the state of the Swift community now, but you take into careful account the theoretical basis of programming languages and types systems, you draw ideas from more "advanced" languages and platforms, you consider what "opinion" Swift should have on the collected concepts (how things should be represented to be Swifty), you evaluate the tradeoffs, and finally plan a roadmap to implement the features you want.

Many of us, including me, are pointing out that the tradeoffs are consistently in favor of HTKs, and we have already modern, successful languages that use this abstraction power to build useful things.

The traverse examples shown here (I'm literally writing right now some production code to bundle a list of aync computations into a single one that yields a list) show a clear use case. As soon as I have time, I'm going to cook up another couple of examples, one based on monad transformers (that I use in production code, thanks to thousands of lines of generated code), and another one based on profunctor optics (something that's practically impossible to do in Swift, even with code generation).

7 Likes

That's been my concern, this thread is already 1œ years old and the last set of conversations have hinged on naming and not on what's required to highlight the importance of HKTs.

Hence I asked for some clarity on what exactly is the hinderance wrt to HKTs i.e. what can we do to obviate the blocking points.

2 Likes

My impression is that the best thing we can do right now is to provide compelling examples. Not just examples of abstractions that can only be created with HKT, but with compelling use cases in real world code that demonstrate the pragmatic utility of these abstractions.

In order to motivate HKT as a feature the examples cannot just be patterns that are applied in concrete types. Instead, they need to be examples that only work when we abstract over a type constructor. The best examples will focus on user code written with a library, not the library code itself. If the library itself and the user code could be written without HKT (perhaps at the cost of some duplication in the library) the example is much less compelling.

I think the tangent on naming is relevant because demonstrating pragmatic utility requires the ability to communicate about the examples with an audience that is not necessarily steeped in the traditional FP names. Many of the traditional names provide absolutely no point of reference for most professional programmers (unless they have studied FP). Further, many of the names (especially the CT-inspired names) make no attempt at being descriptive in the sense that Collection or Comparable are.

To summarize, I think providing compelling examples of user code presented with descriptive names will go a lot further towards motivating HKT as a language feature than anything else. The examples should of course reference the conventional names in comments for those interested, but should focus first and foremost on communicating with the whole Swift community with no assumption of an FP background.

17 Likes