Does Plutus == Haskell? It's Complicated.
It is often stated that one writes Plutus smart contracts in Haskell. This is cited as one of the benefits of using Haskell for on and off-chain code: you can reuse the same code.
Largely, this is true. However, one important point is left unsaid: the on-chain Haskell and off-chain Haskell might not execute the same way.
Although the syntax is the same, the semantics of Plutus and Haskell are different.
The exact same Haskell function can produce two different outputs, depending on whether it is used on-chain or off-chain.
Non-strict Semantics and Non-non-strict Semantics
In Haskell functions have non-strict semantics. In Plutus functions have strict semantics.
For instance a common pattern is Haskell would be the following:
let something = fromMaybe (error "whoops") maybeSomething
If `maybeSomething` is `Just 'a'` then `something` would ultimately evaluate to 'a'.
However, this is not the case for Plutus. `fromMaybe` will evaluate to `error`, causing the program to fail.
This might sound minor, but a fair amount of Haskell code depends on the lazy evaluation of its non-strict semantics. An experienced Haskeller will find the behavior of Plutus programs puzzling. I know I did.
Plutus is not entirely strict either. The `let` and `where` bindings are non-strict. Which puts Plutus in an in-between state between strict and non-strict languages.
Haskell and Plutus are not the same thing. You can't use `maybe` and `either` functions like you would in Haskell, you will need to use pattern matching instead. Additionally, be careful when porting common Haskell code into your Plutus projects. It could diverge.
The semantics of Plutus are different than the semantics of Haskell, and it is best to think of it as its own language with the same syntax as Haskell.