Stream: beginners

Topic: ✔ Bug in List.reverse?


view this post on Zulip njlr (Jan 12 2024 at 20:38):

Here is my program:

app "automatons"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.1/Icc3xJoIixF3hCcfXrDwLCu4wQHtNdPyoJkEbkgIElA.tar.br" }
    imports [pf.Stdout]
    provides [main] to pf

Automaton i o : [ Arrow (i -> o), Step (i -> (Automaton i o, o)) ]

# Get the output and next Automaton for a given input
step : i, Automaton i o -> (Automaton i o, o)
step = \input, automaton ->
    when automaton is
        Arrow f -> (automaton, f input)
        Step f -> f input

# Run an Automaton on a list of inputs till completion
run : List i, Automaton i o -> List o
run = \inputs, automaton ->
    loop = \remaining, current ->
        when remaining is
            [] -> []
            [x, .. as xs] ->
                (next, output) = step x current
                List.append (run xs next) output

    # loop inputs automaton
    List.reverse (loop inputs automaton)


# Automaton that doubles the input
doubler = Arrow (\x -> x * 2)

main =
    inputs = [ 1, 2, 3, 4, 5 ]
    output = run inputs doubler
    outputStr = output |> List.map Num.toStr |> Str.joinWith ", "
    Stdout.line outputStr


# Without List.reverse
# 10, 8, 6, 4, 2

# With List.reverse
# 2, 6, 10, 8, 4

# I would expect
# 2, 4, 6, 8, 10

Expected and actual in the comments at the end.
Removing List.reverse gets rid of the weirdness, although is not correct implementation-wise.

view this post on Zulip njlr (Jan 12 2024 at 20:40):

Unless I'm missing something stupid I can file on GitHub

view this post on Zulip Brendan Hansknecht (Jan 13 2024 at 00:23):

I think it is working correctly:

[/tmp/test.roc:50] list = []
[/tmp/test.roc:52] out = []
[/tmp/test.roc:50] list = [10]
[/tmp/test.roc:52] out = [10]
[/tmp/test.roc:50] list = [10, 8]
[/tmp/test.roc:52] out = [8, 10]
[/tmp/test.roc:50] list = [8, 10, 6]
[/tmp/test.roc:52] out = [6, 10, 8]
[/tmp/test.roc:50] list = [6, 10, 8, 4]
[/tmp/test.roc:52] out = [4, 8, 10, 6]
[/tmp/test.roc:50] list = [4, 8, 10, 6, 2]
[/tmp/test.roc:52] out = [2, 6, 10, 8, 4]

view this post on Zulip Brendan Hansknecht (Jan 13 2024 at 00:23):

looks like an impl bug for your code

view this post on Zulip Brendan Hansknecht (Jan 13 2024 at 00:23):

probably reversing more than you want

view this post on Zulip njlr (Jan 13 2024 at 08:49):

In my code above, if I swap these two lines (in the run function):

List.reverse (loop inputs automaton)
# 2, 6, 10, 8, 4
loop inputs automaton
# 10, 8, 6, 4, 2

Then the final output is not the reverse of the other, which I think is odd.
Maybe I'm missing something?

view this post on Zulip Hannes Nevalainen (Jan 13 2024 at 10:08):

You are recursively calling your “run” function, so you are doing a lot of reversing.
Not just on the final list as I think you intended.

Try putting the reverse inside
main instead.

view this post on Zulip njlr (Jan 13 2024 at 10:16):

Ah yes! Thank you

I was recursively calling run where I should have been calling loop

This works:

run : List i, Automaton i o -> List o
run = \inputs, automaton ->
    loop = \remaining, current ->
        when remaining is
            [] -> []
            [x, .. as xs] ->
                (next, output) = step x current
                List.append (loop xs next) output

    loop inputs automaton
    |> List.reverse

view this post on Zulip Notification Bot (Jan 13 2024 at 10:16):

njlr has marked this topic as resolved.


Last updated: Jul 06 2025 at 12:14 UTC