78 comments

[ 5.3 ms ] story [ 152 ms ] thread
This is an old discussion (which I had followed for years). The proposal, afaik, was never accepted into Ecmascript.

So we ended up with half baked Promises.

In a particular nodejs project I worked on, I overrode the native Promise implementation with the one provided by Pacta, but was not ideal (promises returned by other modules where native, ...)

Not doing nodejs work anymore, but I'm still rather disappointed about how Ecmascript promises were ultimately delivered.

Yeah. Native promises are usable, and they're okay...

...but with only a few small changes they could have been much better, and it's frustrating to see proposal to make them better back when that was an option denied out of hand with such arrogance and (to my mind) lack of understanding of what was even being discussed. The linked thread of comments has not aged well over the years.

(And it's doubly frustrating now that the (excellent!) async/await syntax has now been built on top of it. What a wasted opportunity.)

For those looking for monadic Promises, I’d suggest taking a look at Fluture (https://github.com/fluture-js/Fluture). It’s a wonderful library and with do-notation, ability to work with callbacks, nodebacks, and Promises, I haven’t looked back. It also has adheres to Fantasy Land, Static Land, and has defintions for santuary-def.
> It also has adheres to Fantasy Land, Static Land, and has defintions for santuary-def.

I think I understood a couple words in that sentence, like "it" and "has". :P

Looking up fantasy-land, I found https://github.com/fantasyland/fantasy-land. I would like to better understand these monads everyone is talking about.

But, just to be super honest -- and possibly completely wrong -- the terminology is really off-putting. At a glance it just feels super complex, academic and completely divorced from practical coding. I get vibes of enterprise java class hierarchies looking at this stuff.

I hope I'm wrong, and I really am interested to learn more about it, but I can see from the OP's linked thread that I'm not alone feeling this way. It's not at all clear why I should be thinking about my JavaScript algebraically at all times, or what the practical advantages are. After decades of coding, I'm just getting more alergic to complexity, and this feels like complexity.

What are some good online resources that might help me change my mind and see the light?

This is one of the better javascript FP books that ramps into fairly advanced concepts: https://mostly-adequate.gitbooks.io/mostly-adequate-guide/

A simpler, gentler introduction is available from https://www.manning.com/books/functional-programming-in-java...

> At a glance it just feels super complex, academic

Agreed, because unfortunately, it is. (I might substitute "complex" with "hard" -- the ideas are actually very simple; understanding the big picture of how they fit together is hard)

> It's not at all clear why I should be thinking about my JavaScript algebraically at all times, or what the practical advantages are.

The main goal is to be able to write more and more code as pure functions -- this is hopefully an accepted best practice: functions with minimal inputs and no tangle of global state/context are far easier to reason about, test, and with proper data design, reuse.

But you quickly run into an issue: how can I write pure, stateless functions when dealing with inherently stateful surroundings (IO, DOM, database, etc.). That's what all this category theory jargon is about.

"Once you understand monads, you immediately become incapable of explaining them to anyone else” Lady Monadgreen’s curse ~ Gilad Bracha"

If you'd like to go down a rabbit hole of category theory look up the phrase "A monad is just a monoid in the category of endofunctors, what's the problem?" - a fun quote that a lot of monad explanatory tutorials will quip. Not that it will help - because anyone writing a monad explanation already suffers from the first quote: they're incapable of explaining them.

I had read 30 or 35 different monads-for-Javascript tutorials/guides/explanations before I finally thought I grokked it. None of them have helped and I'm still not sure my understanding of them is correct.

Here's a half baked explanation, as in just the flatmap part.

map is understood in javascript.

So you 'just' need to make the leap to flatmap. Which is mapping something and flattening the result.

So still you need to learn is what flatten is. But that's not too hard to learn.

Try the funfunfunction video [0]

[0]: https://m.youtube.com/watch?v=9QveBbn7t_c

Because the point is mostly lost on the unrelated analogies most tutorial writers use. A monad is a mathematical construct. Trying to explain them in terms of what makes sense to you, because your analogy results from your understanding, isn't likely to be more helpful than outright accepting what they represent, mathematically speaking, then putting that to use in your code.
A monad is most simply described as the quantum superposition of the state of being (or not being) a burrito.
The thing is the general problem with software development right now:

What we know is "intuitive and simple". What we don't know is "off-putting and academic".

Terminology is incredibly important in computer science. If you make something that's kind of like a promise, but not "quite" a promise, and call it a promise, a lot of problems wil arise when people use your code or try to debug it. Monads are pretty simple (they're a heck of a lot simpler than promises). The terminology manners because they're all about interop. If you make something like a monad, but it's not quite a monad, you essentially lose all the benefits (that's the problem with promises).

Fantasy-land is a specification. It's meant for implementers, not for users. The important part is that people who build libraries that should work with other libraries also conforming to the spec, work well with each other. Take a look at some of the very simple constructs you might be used to, and how they are specified on the TC39's github. I'm quite familiar with the spec and I have trouble reading it, but I'm not the target audience. For the users, there are simpler resources.

As for the terminology, inheritance, polymorphism, overloading are all words that a lot of people are familiar with. I'd say the terminology is way worse, and the concepts are often a lot more complex, but people are used to them because it's what they're taught. Java put in monad-like constructs in their Optionals, and it's a lot friendlier...except when trying to compare 2 libraries doing the same thing using 2 different 'friendly' terminology, it's hell. It's not about being academic or elitist, it's about being precise. Something I can google for without having to sort through 16 pages of unrelated crap.

Google for monads, you'll get a lot of relevent material. Google for "optionals", and now you have to precise which language you're talking about, and in some cases potentially which library.

If you want a friendlier intro, look up "Functional programming in javascript" by luis atencio. It's fantastic.

I also always liked this tutorial: https://medium.com/@tzehsiang/javascript-functor-applicative...

At the end of the day, you don't need to know what dynamic method dispatch is to use it. Only the implementers need to :) This is the same thing.

Finally, yeah, some stuff look like "enterprise java". And there's a reason "enterprise java" existed: not all problems are easy. Some companies have hard problems to solve. Maybe it wasn't the best way to solve those problems, but a vanilla Rails REST api probably is worse. That doesn't mean everyone needs those solutions, but its nice that they exist. In this case, most people wouldn't have felt much difference if promises had been monads. But for the people who need monads, they're worse off by the current state of things.

I tried my best to write a series of posts [0] demonstrating functional programming concepts using practical examples. I've found that Javascript is actually a decent language for learning about currying and monads, etc, because it affords you the ability to pick up a little bit at a time. You can learn one little trick and use it to improve your existing code before picking up another.

The nice thing about Monads is that once you learn the interface then encountering another is no big deal: you already know the API and how to use it. And it turns out this pattern is quite common.

[0] https://agentultra.com/blog/mostly-practical-functional-prog...

While I agree, I've also found that it can be a danger. I thought I was all about the functional programming until I used languages that 'required' it. It was only then that I realized I'd been using non-functional escape hatches all over the place.
First, going straight to "How do I understand Monads?" is not a good idea. I remeber when this article showed up on the web, and I remember wishing it had been written before I started learning Haskell:

https://byorgey.wordpress.com/2009/01/12/abstraction-intuiti...

If you want to understand monads, start hacking and watch for patterns.

> But, just to be super honest -- and possibly completely wrong -- the terminology is really off-putting. At a glance it just feels super complex, academic and completely divorced from practical coding. I get vibes of enterprise java class hierarchies looking at this stuff.

Yeah, and here's my take on why it looks like that:

First, the terminology is all borrowed from mathematics, hence the academic tone. People can debate on the merits of this; I think it makes more sense when you're making tools for folks who are already familiar with the usual notation, but e.g. if you're not dealing with people who are already accustomed to the way physisicts talk about things, "p" is probably not the best variable name for momentum, traditional as it may be.

The authors of that document seem to have gone even farther in that direction than the Haskell folks -- Setoid? really? It's just fing equals! even Haskell calls it Eq. At least they kept Ord.

Also, the design looks to be basically transliterated from Haskell. There's been no attempt to adapt it to either javascript's strengths or its weaknesses. For example: Conceptually a monoid is a special case of a category, but it's fiddly to abstract out the commonalities in Haskell because of the way the type system works. In javascript you could basically collapse the two, with id == empty and concat == compose. You might still want a blurb in there somewhere about the differences; not every category is a valid monoid, but there's no reason to have a whole separate hierarchy with different method names. * The whole TypeRep thing they talk about is a complication that is unnecessary in Haskell; having methods that aren't attached to an extant value is just a non-issue, because the compiler can figure out which one you mean based on the types.

The libraries were designed around Haskell, and they lose something in translation. One of the things that kept in that thread was why not build some experience using these patterns before writing a spec? I tend to agree.

The other thing is that it is a big pile of abstractions. Even when working in Haskell, though I am more or less familiar with all of the type classes on that chart, I've only really had call to use 9 of them. Including Eq(Setoid) and Ord. The abstractions can definitely get to be a bit much.

There is some real use for this stuff; here's one I find kindof shiny:

https://apfelmus.nfshost.com/articles/monoid-fingertree.html

...but I would say these abstractions are as applicable to day to day programming as the rest of computer science -- no more and no less.

I'm with you on the complexity allergy thing. Lately I've been doing some stuff in elm[1], and the simplicity has been a wonderful breath of fresh air coming from Haskell. I might recommend it if you're curious about functional programming. Some of the same ideas are sprinkled throughout the libraries; every time you see a function called "andThen," there's a monad lurking there, but because elm doesn't have type classes, you won't find anything called Monad. The flip side is you end up writing more boilerplate than you would in a language that can abstract these things away.

[1]: http:...

> JavaScript Promises Discussion: Make Them Monadic?

No, just totally ditch them!

I can't help to hate Promises. Sometimes I have to work on a code base that is completely baked with them, it's just a nightmare. With the stupid async await implementation things haven't got any better.. Now they expect me to write async calls in a try-catch block!?!

With JS I prefer to use simple callbacks until they come up with a proper async await without try-catch and Promises bullshit. Callback hell happens not because of the callback principle itself. It exists because it's too easy to keep nesting functions. Most devs simply don't know how, or are too lazy, to apply good patterns for using callbacks.

This. Every time I try and get up to speed on those things it's like, "wtf? this is actually better?"
> Now they expect me to write async calls in a try-catch block!?!

What do you mean? In my experience, the use of async/await leads to much cleaner code for I/O driven tasks like querying APIs and databases. Yes, I do have a try/catch at the top of the callstack to catch and log unexpected errors.

async/await worries me, not for abstract language reasons but because it hides complexity in a way not friendly for junior engineers.

I imagine a lot of code that should be thought out and made parallel being forced into a synchronous flow.

Note that promises aren't a ton better in this regard, and come with a ton of confusion themselves. In short, async is hard.

Promise.all() does a pretty good job of parallelizing tasks while maintaining readability.
Having seen several codebases go from using arbitrary callbacks (two? One with an error arg? Why not both?) To promises/asynchronous/await it's hard to see your point. The code is cleaner, there is no callback hell with await, in fact no callbacks at all. And yes, you do need to use a try/catch block where appropriate.

Stop trying to emulate a try/catch with ridiculous nested callback passing that inevitably leads to the function not being called and data being lost. Just stop.

I'm not sure how it works in all languages, but in Python you have to deal with errors in a try/except block. In general the way you handle errors that happen on "blocking" async calls is by wrapping in a try-catch style syntax and handle the error. How would you handle the error otherwise?

You can handle asynchronous code in JS in four ways: callbacks, Promises, generators, and async/await. In the former two, errors are dealt with in a non try-catch way, to the programmer, because either you pass the error as the first callback parameter, or the VM handles error passing for you and you deal with it in a catch block. The latter two you must wrap code that may fail in a try-catch block (or just not handle the exception). You can stick with callbacks, but it's generally easier to read well written Promises, and in a lot of cases async/await make it even clearer. The only time that it can be confusing or difficult is if you want to do multiple await calls simultaneously.

Not to mention promises swallow programming errors that should fail loudly (TypeErrors, ReferenceErrors, etc), and treat them the same as you would treat an HTTP 500 error.
I think you'll find that the proper solution to this problem is : threads. (or actors, goroutines, CSP if you want to call them that instead). Promises and callbacks are something you'd do if you have an execution environment lacking threads (which is true of Javascript).
I have a number of criticisms of Promises, but I think your point is utterly wrong.
Such a dumb discussion. One guy saying “Here’s a proven design”, someone else calling it “Typed Language Fantasyland”.
It's not a dumb discussion at all. Callback hells and managing threads synchronously/asynchronously as desired are a big deal.
I am surprised to see so much venom against Promises expressed here. I am young, but I began coding (as a profession) just when Angular 1 was popular and I remember callback hell was a real thing.

A few years later, I use Promises a lot, and they work really well. The way errors bubble is logical and easily controlled, it's almost impossible to throw an unhandled promise exception, doing 'parallel' tasks is easy with ```Promise.all([])```, and there's pretty limited complexity with the way a Promise always returns a Promise.

I find the simplest way to use them is to define a class that has a few data properties you'd like to track.

  class Handler {
    constructor() {
      // shared variables can be set / reset here
      this.defineInitialState();
    }

    executeAction() {
      return (
        this.promiseFn()
        .then(() => this.anotherPromise())
        .then((passedArgument) => this.promiseExpectingArgument())
        .then(
          // success case
          () => this.successHandler(),
          (err) => this.errorHandler()
        )
      );
    }
  }
It's modular and you know what to expect (it's always a promise!). Sure, it's imperfect, but I think its weakly opinionated simplicity is a good tradeoff. After all, it makes no distinction of whether any of the functions in that chain were synchronous or not, and that's a nice thing to know. It also makes testing with dummy sync functions in place of actually asynchronous ones a 0-effort integration.

I don't know about this async / await keyword stuff, and if you have to wrap it in a try/catch block, that's unfortunate but also seems like it's not the end of the world. After all, isn't the Go language constantly requiring you to say "if err != nil <your code>"? Explicit error handling isn't even a bad thing.

Anyways, this is just my opinion, it's fair to have your own, and maybe other languages handle asynchronicity more gracefully, but from what I've seen this is a clean way to wrap async OR sync code in a context that makes it always behave predictably and readably.

Agreed, it was a HUGE improvement over callback soup.

The only cleaner methods I’m familiar with are CSP (as implemented in clojure and go, and to some extent in JavaScript with libraries like RX and Bacon). Basically you’re treating steams of events as first-class values. That’s a rather functional/mathy way to treat concurrency/parallelism but I’ve found it illuminating.

> I am surprised to see so much venom against Promises expressed here. I am young, but I began coding (as a profession) just when Angular 1 was popular and I remember callback hell was a real thing.

The issue with Promises is they could be a LOT better, and they're not for no good reason. Yeah, they're better than callback hell, but anything would be better than callback hell. "Hurts less than stabbing yourself with a screwdriver" should be a baseline expectation, not a recommendation. :)

But how could they "be a LOT better"?

I see this being said, but from what I've seen async handling is generally not very graceful; with that said, Promises are a very simple but powerful API that seem to handle the problem fairly elegantly.

That is why I'm surprised. I just don't know what the alternative is supposed to be! Can you point me to a language and a library that you would say does a better job of handling asynchronicity than Promises?

Elixir, for one. It's only when I started properly learning other languages than JS that I started seeing how much better a lot of things could be. I say that with a lot of affection for JS, but JS style Promises are among the things that I don't miss.

EDIT: To elaborate a bit, what I don't like about (JS) Promises, in hindsight, is that 1) they seem to infect my entire codebase, and 2) making non-async code async is usually nontrivial. In Elixir it's basically a matter of 'telling' a function or an entire module to go do it's thing in another process and report back when done. It means in many cases I only need to change the caller side of things and the code that runs async itself looks the same as the sync code. And that's not even the best part of (Erlang style) processes!

I started programming professionally around the same time but I'm surprised that you think Promise.all([]) makes things easy. IMO Promise.all([]) is nice until you start supporting proper error handling.
I'm not sure what you're getting at, can you expand?

I work a lot with databases, so say you're trying to write an object and its children in some sort of one-to-many relationship to the DB.

You can write a Promise chain like

  startTransaction()
  .then(() => writeParent())
  .then((children) =>
    Promise.all(children.map((child) =>
      writeChild(child)
    ))
  )
  .then(
    // handle success
    endTransaction(),
    // handle error
    cancelTransaction()
  )
What exactly about that isn't "proper error handling"? Can you expand a bit on how this would be handled differently by you, or perhaps what paradigm you're programming in where Promise.all executes a bunch of items that can't all have the same success and error handler?
Can you explain a bit more what your code is doing?

Are you suppose to instantiate the handler class and call it?

Yeah, exactly. Say you have an API request that is persisting a chunk of data to the database, like a few dependent data items.

This way, you write the API request to just be a simple function invocation of the class you instantiated:

  (req, res, next) => {
    apiHandler = new APIHandler(args);

    apiHandler.saveData(req.body)
    .then(
      // success
      () => res.status(200).json(apiHandler.getResponse()),
      // error
      () => res.status(400|500).json(apiHandler.getErrorResponse())
  )
I mean, it's just a pattern, and I wouldn't necessarily say I use it all the time; it's especially valuable for workers, where you have a series of functions you want to execute where some of them are going to be asynchronous.

If you're just making simple create / update / get requests, it's less valuable, and you can just return a Promise from somewhere. Hopefully that gave you an idea of my motivations

As already mentioned, they're a lot better than callbacks (well, for certain cases. There are still places where callbacks are better).

The problem is that this is a field that has been heavily studied, and there are great solutions to this problem that also solve countless other problems, and interop well with each other. The way promises work, they solve that ONE problem but throw away the rest.

If you have the choice between 2 mostly equivalent solutions to solve a problem, but one of the solutions also solve 10 other problems with essentially no drawback, why would you choose the former?

This is probably already linked in this thread somewhere and is also probably was prompted someone to post this old issue to Hacker news, but this is a good explanation of the problem:

https://staltz.com/promises-are-not-neutral-enough.html

> There are still places where callbacks are better)

Like? I am genuinely interested in knowing the drawbacks of promises and places where a callback like structure is more favourable. By the way, I am not contradicting you, just trying to learn.

foo.map(x => x * 2);

Not sure I'd want to use a promise there :)

A promise can only be activated once. You still have to use callbacks for buttons and other things that can be activated more than once.
The hardest part for me when I was new to Promises was that multi-layer promises would magically vanish. It was so counter-intuitive from every other programming paradigm — nested loops, deep/complex objects, and functional closures.

I lost several days struggling against the concept until realizing that Promises were intended and designed to work differently than every other aspect of the language.

Can you imagine the language stripping out a nested returned function and instead executing it and returning the value? That’s what Promises will do.

Why does everything discussing something you personally like have to be “venom”? People here have serious, thoughtful ideas about how they could have been much nicer and why they represent a missed opportunity. Sorry but I’m just tired of every critical thought needs to be painted as overly negative and therefore worth dismissing.
If you're working with Promises as glorified event handlers, then yes, it suits that use case well. The problems that arise later, though, have to do with composability, cancelation, and scheduling.
Seeing Jeremy resurfacing old threads brings me memories.

Anyway this was a nice thread to follow while it happened.

I'm confused, and am not very knowledgeable about FP (though I am very interested in it).

Can anyone explain how the 3 bullet points in the issue aren't already in Promises?

> Promise.of(a) will turn anything into promise.

This just looks like `Promise.resolve(a)`

> Promise#then(f) should take one function, not two.

That's applicable, but you could try limiting yourself to only using one argument.

> Promise#onRejected(f): move onRejected to prototype instead of second arg.

`Promise#catch(f)`?

The issue with `of` is that it special cases when `a` is already a Promise. Promises try hard to not be nested (a promise of a promise) but that nesting is critical for algebraic properties.

The then issue is multifarious. On one side, splitting the two uses makes the algebraic justification for then more clear, but it's not a big deal. The real issue is that `then(f)` does different things when `f` returns a Promise. This breaks in the same way that `of` did—you need to be able to discuss nested promises.

That just raises more questions. Can anyone here give a concrete example of a real world problem that is more cleanly solved with these changes to the Promise spec?

There's a lot of talk about FP and type theory here, and none about actual work. To me, all this stuff is still in the "cool to play around with at home" category. But until it affects day to day dev work, there's a whole set of people that aren't going to give the slightest fuck.

> But until it affects day to day dev work, there's a whole set of people that aren't going to give the slightest fuck.

That's a seriously toxic attitude to have.

People are using monads and other FP concepts daily to simplify "day to day dev work" (here's an example [0].) The fact that it's more or less mainstream to write off a concept because it sounds "academic" is worryingly anti-intellectual in a profession that is allegedly based in analytical thinking.

> Can anyone here give a concrete example of a real world problem that is more cleanly solved with these changes to the Promise spec?

There are some in the linked github thread (which had to be reposted repeatedly until people actually stopped and read them, btw.) It's about being able to write DRY code that abstracts over not only promises, but anything else that forms a monad, like arrays, optional values, and so on.

[0] https://github.com/facebook/Haxl

Just responding as op, but pka nailed it.

If you're writing every line of code directly then these all feel like conveniences. If you write code that's more generic then they become exponentially compounding edge cases.

Fun fact: the JS library Fantasy Land [1] got its name from that discussion [2].

[1] https://github.com/fantasyland/fantasy-land

[2] https://github.com/promises-aplus/promises-spec/issues/94#is...

I am so happy to know this lineage, thank you!
Ive been following Fantasy Land since times immemorial, but I never knew thats where the name came from (even though I followed the legendary discussions around the spec back in the days). Only today when I reread it did I notice the fantasy land call, and told myself "Omg...THAT is where it came from!"
Another fun fact: the guy who mocked devs asking for monadic Promises later "championed" and subsequently withdrew the TC39 proposal for Promise cancelation, presumably after realizing that it's impossible to shoehorn into the current spec cleanly.
Having followed the promise cancellation proposal pretty closely, especially when it came to a close, it sounded more like he got sick of the pushback (specifically mentioning push back internally at Google) if my memory serves. I won't pretend to speak for him, but I don't recall him withdrawing the proposal because he didn't think his solution was correct. He just didn't want to deal with the detractors anymore.

Of course, it was a solution to a problem he created, so... (to be fair, the JavaScript world was very different then than it is now, in the same way ES6 classes would probably work very differently if they were designed today)

I was never on the promise bandwagon because they never did anything useful other than create hype with developers around using a more functional approach - which is good, but promises themselves add no benefit.

For instance, people previously would do:

```

start(x => doA(y => doB(z => doC(end))))

```

When they could have just used named functions, with promises or not, it is just that promises was hype that taught them good programming skills:

```

doA = x => doB(x)

doB = y => doC(y)

doC = z => end

start(doA);

```

As with promises:

```

start.then(x => x)

  .then(y => y)

  .then(z => z)

  .then(end)
```

The only real value of a promise now is being able to use `await`, which is the real first-class language magic.

However, the future isn't even with promises, so there is no need to change or modify them. The future is chain reaction programming, also goes by the name of observables/FRP/stack-based-cocatenative-programming/railway-programming.

Programming Chain Reactions is great, because they can also downconvert easily to `await`, so you get the best goodies of all the world.

We've implemented observable/FRP/chain-reaction programming as the default API in https://github.com/amark/gun , it is really quite pleasant language abstraction. However, FRP/etc. hasn't quite hit "mainstream" hype yet, so developers do not know what they are missing out on. Once you try it and it "clicks", you realize the future is truly bright. :)

WebAssembly can't come fast enough.

Really:

> @pufuwozu can you show with a concrete example why you can't write the example code you posted with promises?

Why couldn't him just give a concrete example of what he was claiming that was impossible?

I feel like I’m being promised a burrito.
A burrito is just a strong monad in the symmetric monoidal category of food, what’s the promise?
That maybe I’ll get a burrito.
I wonder why we have to resort to terms like monadic, immutable, orthagonal, etc, in our field so often. I feel weird and elitist using these terms when more common ones suffice and are understood by my customers.
whats a better term here?
Contextual functions maybe? For orthagonal, it's often used to mean "unrelated". Immutable could be "fixed", "constant" or any number of other more pedestrian terms.
You're just inventing your own terms no one else uses.

There's a page called "Monad (functional programming)" on Wikipedia https://en.wikipedia.org/wiki/Monad_(functional_programming) suggesting that the term "moand" or "moandic" is widely used and understood.

There's no page called "contextual function."

There's a page called "Orthogonality (programming)" on Wikipedia https://en.wikipedia.org/wiki/Orthogonality_(programming) also suggesting that the term "orthogonal" is widely used and understood.

The page for "Unrelated" is about a movie.

There's a page called "Immutable Object" on Wikipedia https://en.wikipedia.org/wiki/Immutable_object suggesting that the term "immutable" is widely used and understood.

"Fixed" and "constant" have distinctly different meanings from "immutable."

I do respect your viewpoint. But immutable and orthagonal are just weird jargon to my project managers, product managers, analysts, customers, etc. For me, it's somewhat equivalent to odd terminology that probably irritates you from the business like "synergy" or "paradigm", or "incentivise" From the tech side, we parody those terms. Rest assured, business folks parody us for our monads, immutables, etc. It makes us seem like we're trying to feel self important.

Wikipedia isn't really convincing to me. There's no page for contextual functions because it's not really new, exciting, unique, or notable. I feel the same if you call that "monads". I can implement them in decades old programming languages. Same for immutable. Existed long before anyone called it that. We used it without having to have some catchy moniker that nobody understood outside the family.

Basically, I want to stop alienating project managers, product managers, and customers with weird jargon.

> Basically, I want to stop alienating project managers, product managers, and customers with weird jargon.

The things you might need jargon for are things that they shouldn't have to concern themselves with. If you use more familiar words but arrange them in unfamiliar ways, you'll cause the same confusion as by using jargon, except someone might believe they understood when they really didn't.

If you feel like you need to refer to programming concepts when talking to non-technical people, you're doing it wrong. Instead of talking about "immutable"/"constant"/"fixed", say that you made changes to prevent data from being altered accidentally. That's something they care about, not how exactly you did it.

>The things you might need jargon for are things that they shouldn't have to concern themselves with.

Sure, but they become terms in titles of change requests, features, bug fixes, etc. It leaks out whether I want it to or not. And customers ask "what does this mean?" Or sometimes, forgivable but less polite equivalents.

Just use the word that means the thing that you're talking about, as clearly as you can. What "clear" means depends on the context and audience.

It sounds like you probably already know this, but "fixed" and "constant" usually refer to concepts very distinct from "immutable". And "contextual function" would confuse everyone. (A monad isn't a function, and certainly not one influenced by some outer context). Similarly, "orthogonal" and "unrelated" aren't synonyms. (X and Y axes are orthogonal, but they're often related. That's why we plot things).

In every field, there will be people who over-use technical terms for status signaling. But those terms usually exist for a reason beyond that, and avoiding them as a sort of counter-signaling doesn't help anyone. It's just playing the other side of that game.

Usually the common term means the same things as a lot of things…that's both why they're common, and why they're less useful in a technical context.

Some other examples that come to mind are "electricity" (current, voltage, power…?); "size" (area, volume, mass…?). Just because an engineer or physicist might talk about volume doesn't mean you have to be a physicist to talk about it too. It also doesn't mean that, not being a physicist, the familiar word "size" means the same thing they're talking about.

That's fair, but these terms are leaking out to business analysts, project managers, product managers, and customers. They have no idea what we're talking about. My weak attempts at synonyms might be attackable, buy we're coming across as elite bullshitters. I'd love something that was more consumable for the common person.
Would you call a car mechanic elitist for talking about carburetors and alternators?
I don't feel like that's a great analogy. "Fuel cell" vs "gas tank" is closer. There's not a simple one or two word commonly used equivalent for carburetor. I'm not opposed to specific terms when there aren't simpler alternatives. "Exponential", for example, doesn't bother me. Orthagonal, though is irritating. Why not just say "unrelated" or "not correlated", etc.
Um, the problem here is Javascript. Don't use a cesspool of a language and you don't have such banal conversations.
(comment deleted)
Honestly, I think Promises with async/await and try/catch are good enough for a lot of use cases. Certainly lightyears ahead of callback hell.

IMO the next big thing will be Observables.