Stream: beginners

Topic: internal compiler error


view this post on Zulip Artur Swiderski (Oct 06 2023 at 20:50):

I am getting compiler error on this

    app "reg"

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


checkMatching = \ str, reg  ->
    matchStr = \ graph, pattern ->
        when pattern is
            Character val ->
                if val == graph then
                    Consume
                else
                    NoMatch
            Dot ->
                Consume

    getFirstPat = (\  state  ->
        when List.first state.current is
            Ok pat ->
                { pattern : pat , state : state }
            Err _ ->  getFirstPat  { state & current : state.regex } )

    Str.graphemes  str
    |> List.walk  { regex : reg, current : reg, matched : "", result : Bool.false }  ( \ state, graph ->
        if state.result == Bool.true then
            state
        else
            matchThis = getFirstPat state
            updatedState = matchThis.state

            when matchStr graph  matchThis.pattern is
                Consume ->
                    if List.isEmpty updatedState.current == Bool.true then
                        { updatedState & matched : Str.concat updatedState.matched graph, result : Bool.true  }
                    else
                        { updatedState & matched : Str.concat updatedState.matched graph, current : List.dropFirst  updatedState.current }
                NoMatch ->
                        { updatedState & matched : "", current : updatedState.regex } )


main =
    res = checkMatching "dsads"  [Dot]

    Stdout.line "adfasfsa"

view this post on Zulip Brian Carroll (Oct 07 2023 at 05:55):

We can help if you tell us what the error is!

view this post on Zulip Brian Carroll (Oct 07 2023 at 05:55):

app on the first line should not be indented I think

view this post on Zulip Artur Swiderski (Oct 07 2023 at 08:35):

@Brian Carroll internal error I suppose , just copy paste and try to compile. There is no formal error just crash

view this post on Zulip Artur Swiderski (Oct 07 2023 at 08:35):

at least for me

view this post on Zulip Artur Swiderski (Oct 07 2023 at 08:36):

formal error I would easily fix myself

view this post on Zulip Brian Carroll (Oct 07 2023 at 08:54):

Did you try removing the indentation before app?

view this post on Zulip Luke Boswell (Oct 07 2023 at 08:55):

I attempted to minimise and added as an Issue #5889

view this post on Zulip Artur Swiderski (Oct 07 2023 at 13:41):

do you have suggestion how to avoid this problem ?

view this post on Zulip Anton (Oct 07 2023 at 14:04):

I would try to modify Luke's minimal reproduction in a way that produces the same output but using different data structures or functions that do not trigger this error.

view this post on Zulip Luke Boswell (Oct 07 2023 at 19:38):

I find it helpful to break things down into smaller functions, add tests using expect, and type annotations. and then some combination of roc test and roc check usually helps to build up a working implementation. There may be a different set of types or data structures which work well as Anton suggested.

view this post on Zulip Artur Swiderski (Oct 07 2023 at 20:58):

what roc test roc check stands for ?

view this post on Zulip Luke Boswell (Oct 07 2023 at 22:10):

The command line argument to for the Roc cli. So you can run the unit tests in the file with e.g. roc test myFile.roc. And check is similar but just checks all the types and syntax and reports any issues without actually building an executable.

view this post on Zulip Luke Boswell (Oct 07 2023 at 22:11):

See also https://www.roc-lang.org/tutorial#tests-and-expectations

view this post on Zulip Artur Swiderski (Oct 08 2023 at 13:57):

btw. abbreviation { struct & field : new_field } is crashing if I recreate entire structure from scratch there is no error

view this post on Zulip Anton (Oct 09 2023 at 09:09):

:+1: I've added this to #5889

view this post on Zulip Narek Asadorian (Oct 20 2023 at 21:59):

I'm trying to tackle a couple documentation related GH issues, and I saw something odd in the docs regarding the pipeline operator. Specifically that a b c |> f x y desugars to f (a b c) x y. Why would the pipe apply to the first hole in the RHS function? In other FP langs it applies to the last argument. So I went to test it out in the REPL and managed to crash it a few times, including with the given desugar example.

The REPL I ran this in is latest master rev, FWIW

» "world" |> \w -> Str.joinWith w ["hello "]
Erroneous: Expr::Call
thread 'main' panicked at 'Roc hit an error', crates/repl_cli/src/cli_gen.rs:125:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

view this post on Zulip Narek Asadorian (Oct 20 2023 at 22:01):

Why would the pipe apply the incoming value the first hole and not the last?

view this post on Zulip Narek Asadorian (Oct 20 2023 at 22:30):

One reason the |> operator injects the value as the first argument is to make it work better with functions where argument order matters.

Ok based on the docs it's an intentional design decision, but I don't follow the reasoning. In monomorphic operations like Num.div the order absolutely matters, and as a user I'd expect the dividend to be the first argument ala 42 / 2 or Num.div 42 2. If I'm then forced to write a notation like 42 |> Num.div 2 my intuition says this is 2 / 42

view this post on Zulip Richard Feldman (Oct 20 2023 at 22:39):

interesting! So I had the opposite intuition the first time I encountered this (back in the day), and also this is the behavior I want. For example, I've wanted to do things like this on several occasions:

num
|> doSomething
|> Num.sub 1

So far I've never wanted the opposite - that is, I've never wanted to perform a pipeline operation of "take a number (1 in this case) and subtract from it whatever I've built up so far." I've only ever wanted to subtract some number from what I've built up so far.

view this post on Zulip Richard Feldman (Oct 20 2023 at 22:41):

Another example:

|> List.append 1 # appends 1 to the list

that's an accurate comment in Roc (and in Elixir, which also does |> the way Roc does) but it wouldn't be if |> worked the other way

view this post on Zulip Richard Feldman (Oct 20 2023 at 22:46):

regarding the repl error - the compiler shouldn't crash there of course, but I believe the problem it's hitting is that the arguments to Str.joinWith should be reversed!

view this post on Zulip Brendan Hansknecht (Oct 20 2023 at 22:48):

Probably just wanted Str.concat

view this post on Zulip Declan Joseph Maguire (Oct 21 2023 at 01:38):

I agree with Richard, I find it way easier to conceptualise being the first argument. Maybe it's because I have the most experience with languages like python where mandatory arguments go first and the number of arguments can be unbounded, so for me, the first argument is the "primary" argument and so it makes sense to make it special. Maybe the other order better dissolves the boundaries between function application and composition.

view this post on Zulip Lakin Wecker (Oct 21 2023 at 01:52):

I think the key here is precedence. List.append x should always partially apply the first argument. Which is what I expect. And which is why the primary argument goes last in most functional languages. Because that's how partial application works.

But if

num
|> doSomething
|> Num.sub 1

is what you want in this case, surely that means the precedence is:

(((num |> doSomething) |> Num.sub) 1)

Which maybe we just need to be document. If that's the case, then I'd expect:

num
|> doSomething
|> (Num.sub 1)

to work in the other way.

view this post on Zulip Richard Feldman (Oct 21 2023 at 01:56):

Lakin Wecker said:

I think the key here is precedence. List.append x should always partially apply the first argument. Which is what I expect.

that's a reasonable expectation in a curried language, but to be fair, Roc isn't curried! :big_smile:

view this post on Zulip Brendan Hansknecht (Oct 21 2023 at 01:56):

There is no partial application in roc.

view this post on Zulip Lakin Wecker (Oct 21 2023 at 01:56):

:cry:

view this post on Zulip Brendan Hansknecht (Oct 21 2023 at 01:57):

But |> has a rule for applying that adds parens.

num
|> doSomething
|> Num.sub 1

becomes:

Num.sub (doSomething (num)) 1

view this post on Zulip Lakin Wecker (Oct 21 2023 at 01:58):

Since no mainstream programming languages today are curried

This feels like a pretty bold claim

view this post on Zulip Declan Joseph Maguire (Oct 21 2023 at 01:58):

I mean you can spoof partial application with anonymous function, if you so need.

view this post on Zulip Brendan Hansknecht (Oct 21 2023 at 01:58):

that said, if you ever need partial application, it is very easy to add a lambda

view this post on Zulip Richard Feldman (Oct 21 2023 at 01:59):

Lakin Wecker said:

Since no mainstream programming languages today are curried

This feels like a pretty bold claim

really? What's a mainstream curried language? haha

view this post on Zulip Lakin Wecker (Oct 21 2023 at 01:59):

Haskell?

view this post on Zulip Richard Feldman (Oct 21 2023 at 01:59):

I'd say "Haskell is mainstream" is an extremely bold claim :sweat_smile:

view this post on Zulip Lakin Wecker (Oct 21 2023 at 01:59):

Now we're just debating what is mainstream or not. :stuck_out_tongue:

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:00):

const plus = (x: number) => (y: number): number => x + h;

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:01):

Anyways, I'm not complaining. It's a design choice and it's not a hill I'll die on. I find it surprising, but it's fine.

view this post on Zulip Declan Joseph Maguire (Oct 21 2023 at 02:01):

While some other people are here, have we considered some syntax sugar that lets \x -> x*x*x be reexpressed as \x*x*x? Having to include function arguments in single-variable anonymous functions is a bit bloated, and I don't think it ought to cause too many issues.

view this post on Zulip Richard Feldman (Oct 21 2023 at 02:01):

it's always really interesting to see what different people find surprising when coming to Roc! There's quite a variety depending on what people are used to

view this post on Zulip Richard Feldman (Oct 21 2023 at 02:02):

@Declan Joseph Maguire we have not; I'd say start a new #ideas thread about it!

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:02):

Declan Joseph Maguire said:

While some other people are here, have we considered some syntax sugar that lets \x -> x*x*x be reexpressed as \x*x*x? Having to include function arguments in single-variable anonymous functions is a bit bloated, and I don't think it ought to cause too many issues.

Like scala's _?

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:02):

Richard Feldman said:

it's always really interesting to see what different people find surprising when coming to Roc! There's quite a variety depending on what people are used to

To be fair, I haven't learned roc. I just assumed: natively compiled Elm without the "web"

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:03):

Which is probably a bad assumption. :stuck_out_tongue:

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:03):

as evidenced here.

view this post on Zulip Declan Joseph Maguire (Oct 21 2023 at 02:03):

Fantastic! I haven't dug through all the threads and they often hold more than the title suggests, so I'm a bit hesitant to make suggestions that may have already been discussed and rejected - I ain't an expert at language design after all, I don't know what's useful and what's a footgun always.

view this post on Zulip Declan Joseph Maguire (Oct 21 2023 at 02:04):

I'll go make that asap

view this post on Zulip Lakin Wecker (Oct 21 2023 at 02:04):

Declan Joseph Maguire said:

... what's a footgun always.

C++?

view this post on Zulip Hannes (Oct 22 2023 at 09:11):

I think piping into the first argument is very natural for me because I learnt R and then Julia which both have packages that rely on that convention, and neither of which are automatically currying languages

view this post on Zulip Narek Asadorian (Oct 23 2023 at 17:04):

Whoops I sniped everyone into a conversation and signed off for the weekend :sweat_smile:

view this post on Zulip Narek Asadorian (Oct 23 2023 at 17:07):

I think the distilled point from my original post comes down to this: it is misleading from a user's perspective to have to write List.append 1 when they know the first argument is supposed to be a List Int and not an Int.

It distorts the notion of having a "strongly typed function" to apply a value of the wrong type to a positional argument.

view this post on Zulip Narek Asadorian (Oct 23 2023 at 17:09):

However let's say the syntax involved a placeholder for the unapplied variable, it would read more clearly

[0, 1, 2]
    |> List.append _ 3

view this post on Zulip Brendan Hansknecht (Oct 23 2023 at 17:32):

Yeah, if you are used to currying, it reads weird. That said, I think it takes exceptionally little time to get used to always missing the first arg.

Also, we have discussed placeholders in general before. If we enable putting a place holder in the first position, people will want to use it in other positions. Discussions around allowing it in other locations have always led to the recommendation to just use a lambda.

With that in mind, adding a placeholder to the first location has issues. Either it is weirdly restricted to only the first position, or it means we have to accept general placeholders. Which again, so far have not gotten anywhere in idea discussions cause adding an extra lambda is simple.

view this post on Zulip Brendan Hansknecht (Oct 23 2023 at 17:32):

Hmm...also, where do you put a placeholder with a raw lambda?

view this post on Zulip Narek Asadorian (Oct 23 2023 at 17:35):

Yeah, if you are used to currying, it reads weird

Right, the pipe operator originates in curried languages (OCaml pretty sure). So most coming from that world will have the same reaction.

view this post on Zulip Narek Asadorian (Oct 23 2023 at 17:36):

And yeah agreed the placeholder would open up the discussion for allowing it any position, which would be kind of a cool feature but also harder to implement

view this post on Zulip Narek Asadorian (Oct 23 2023 at 17:37):

But to use a lambda on the RHS kind of defeats the purpose of pipelining / point free

view this post on Zulip Brendan Hansknecht (Oct 23 2023 at 17:50):

If you think of the pipeline just as a list of stages to execute, I don't think a lambda defeats the purposes. Just means that the function the pipeline was referencing wasn't worth defining as a standalone function.


Last updated: Jul 05 2025 at 12:14 UTC