user565: I originally asked Working with BuiltinByteString
One of the suggested solutions defined a recursive function in the on chain code.
This did not work however and I've since been trying to determine if onchain code can contain any recursive function. I've tried to define the simplest validator function that uses recursion but the Plutus compiler always errors on:
GHC Core to PLC plugin: E042:Error: Unsupported feature: Use of Haskell Integer equality, possibly via the Haskell Eq typeclass

Here is my simple example:
{-# INLINABLE mkPolicy #-}
mkPolicy :: TxOutRef -> () -> ScriptContext -> Bool
mkPolicy oref () ctx = (fact 2) == (2 :: Integer)
  where
    fact :: Integer -> Integer
    fact 1 = 1
    fact n = multiplyInteger n  (fact (subtractInteger n 1))


I used this code as a template, and just replaced the mkPolicy function: https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs
This is the first few lines of the error I get:
GHC Core to PLC plugin: E042:Error: Unsupported feature: Use of Haskell Integer equality, possibly via the Haskell Eq typeclass
Context: Compiling expr: GHC.Integer.Type.eqInteger#
Context: Compiling expr: GHC.Integer.Type.eqInteger# ds_d1hoe
Context: Compiling expr: GHC.Integer.Type.eqInteger# ds_d1hoe 1
Context: Compiling expr: case GHC.Integer.Type.eqInteger# ds_d1hoe 1
                         of wild [Occ=Once]
                         { __DEFAULT ->
                         GHC.Prim.tagToEnum# @ GHC.Types.Bool wild
                         }
Context: Compiling expr: case case GHC.Integer.Type.eqInteger# ds_d1hoe 1
                              of wild [Occ=Once]
                              { __DEFAULT ->
                              GHC.Prim.tagToEnum# @ GHC.Types.Bool wild
                              }
                         of {
                           GHC.Types.False ->
                             PlutusTx.Builtins.Internal.multiplyInteger
                               ds_d1hoe
                               (fact (PlutusTx.Builtins.Internal.subtractInteger ds_d1hoe 1));
                           GHC.Types.True -> 1
                         }
Context: Compiling expr: \ (ds_d1hoe :: GHC.Integer.Type.Integer) ->
                           case case GHC.Integer.Type.eqInteger# ds_d1hoe 1 of wild [Occ=Once]
                                { __DEFAULT ->
                                GHC.Prim.tagToEnum# @ GHC.Types.Bool wild
                                }
                           of {
                             GHC.Types.False ->
                               PlutusTx.Builtins.Internal.multiplyInteger
                                 ds_d1hoe
                                 (fact (PlutusTx.Builtins.Internal.subtractInteger ds_d1hoe 1));
                             GHC.Types.True -> 1
                           }



user5565: I was able to get something that works, but I couldn't explain why. It has to do with the way Template Haskell is generated:
{-# INLINABLE mkPolicy #-}
mkPolicy :: TxOutRef -> () -> ScriptContext -> Bool
mkPolicy oref () ctx = fact 2 == (2 :: Integer)
  where

    fact :: Integer -> Integer
    fact n 
      | n == 1 = 1
      | otherwise = n * fact (n - 1)

As you see, the problem is not recursion. Perhaps you should open an issue on the Plutus issue tracker and discuss with the people there whether this is a bug or a feature.

565: <p>I originally asked <a href="https://cardano.stackexchange.com/questions/7231/working-with-builtinbytestring">Working with BuiltinByteString</a></p>
<p>One of the suggested solutions defined a recursive function in the on chain code.
This did not work however and I've since been trying to determine if onchain code can contain any recursive function. I've tried to define the simplest validator function that uses recursion but the Plutus compiler always errors on:</p>
<pre><code>GHC Core to PLC plugin: E042:Error: Unsupported feature: Use of Haskell Integer equality, possibly via the Haskell Eq typeclass
</code></pre>
<p>Here is my simple example:</p>
<pre><code>{-# INLINABLE mkPolicy #-}
mkPolicy :: TxOutRef -&gt; () -&gt; ScriptContext -&gt; Bool
mkPolicy oref () ctx = (fact 2) == (2 :: Integer)
  where
    fact :: Integer -&gt; Integer
    fact 1 = 1
    fact n = multiplyInteger n  (fact (subtractInteger n 1))

</code></pre>
<p>I used this code as a template, and just replaced the mkPolicy function: <a href="https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs" rel="nofollow noreferrer">https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs</a></p>
<p>This is the first few lines of the error I get:</p>
<pre><code>GHC Core to PLC plugin: E042:Error: Unsupported feature: Use of Haskell Integer equality, possibly via the Haskell Eq typeclass
Context: Compiling expr: GHC.Integer.Type.eqInteger#
Context: Compiling expr: GHC.Integer.Type.eqInteger# ds_d1hoe
Context: Compiling expr: GHC.Integer.Type.eqInteger# ds_d1hoe 1
Context: Compiling expr: case GHC.Integer.Type.eqInteger# ds_d1hoe 1
                         of wild [Occ=Once]
                         { __DEFAULT -&gt;
                         GHC.Prim.tagToEnum# @ GHC.Types.Bool wild
                         }
Context: Compiling expr: case case GHC.Integer.Type.eqInteger# ds_d1hoe 1
                              of wild [Occ=Once]
                              { __DEFAULT -&gt;
                              GHC.Prim.tagToEnum# @ GHC.Types.Bool wild
                              }
                         of {
                           GHC.Types.False -&gt;
                             PlutusTx.Builtins.Internal.multiplyInteger
                               ds_d1hoe
                               (fact (PlutusTx.Builtins.Internal.subtractInteger ds_d1hoe 1));
                           GHC.Types.True -&gt; 1
                         }
Context: Compiling expr: \ (ds_d1hoe :: GHC.Integer.Type.Integer) -&gt;
                           case case GHC.Integer.Type.eqInteger# ds_d1hoe 1 of wild [Occ=Once]
                                { __DEFAULT -&gt;
                                GHC.Prim.tagToEnum# @ GHC.Types.Bool wild
                                }
                           of {
                             GHC.Types.False -&gt;
                               PlutusTx.Builtins.Internal.multiplyInteger
                                 ds_d1hoe
                                 (fact (PlutusTx.Builtins.Internal.subtractInteger ds_d1hoe 1));
                             GHC.Types.True -&gt; 1
                           }

</code></pre>
 5565: <p>I was able to get something that works, but I couldn't explain why. It has to do with the way Template Haskell is generated:</p>
<pre><code>{-# INLINABLE mkPolicy #-}
mkPolicy :: TxOutRef -&gt; () -&gt; ScriptContext -&gt; Bool
mkPolicy oref () ctx = fact 2 == (2 :: Integer)
  where

    fact :: Integer -&gt; Integer
    fact n 
      | n == 1 = 1
      | otherwise = n * fact (n - 1)
</code></pre>
<p>As you see, the problem is not recursion. Perhaps you should open an issue on the Plutus issue tracker and discuss with the people there whether this is a bug or a feature.</p>
