Stream: compiler development

Topic: shadowing functions


view this post on Zulip Richard Feldman (Jun 04 2024 at 04:47):

in a world where we have shadowing, what should this code do?

the relevant part is that when x = foo 1, y = foo 2, and z = foo 3 get run, they each happen after different bar values have been defined (or not), and foo calls bar

answer =
    foo = \a -> bar a
    x = foo 1
    bar = \b -> foo b
    y = foo 2
    bar = \b -> foo (b + 42)
    z = foo 3

view this post on Zulip Richard Feldman (Jun 04 2024 at 04:48):

I think a reasonable answer is "something should be disallowed here" - but if so, then what specifically should be disallowed?

view this post on Zulip Richard Feldman (Jun 04 2024 at 04:51):

for example, one plausible design is "pretend Roc is an interpreted language that allows reassignment, and then give errors at compile time for things that would break if this code was interpreted at runtime" - in which case:

view this post on Zulip Richard Feldman (Jun 04 2024 at 04:51):

however, this has the downside of now making it possible to need to create multiple specializations of a function based on shadowing

view this post on Zulip Richard Feldman (Jun 04 2024 at 04:51):

which isn't something we've talked about before, but which is something I suppose we could do

view this post on Zulip Brendan Hansknecht (Jun 04 2024 at 05:48):

If you want to keep it simple, you could disallow shadowing lambdas

view this post on Zulip Richard Feldman (Jun 04 2024 at 10:41):

yeah and then only allow functions to capture things that have been defined earlier

view this post on Zulip Agus Zubiaga (Jun 04 2024 at 11:00):

Weren’t we going to require ordered defs anyway because of dbg?

view this post on Zulip Richard Feldman (Jun 04 2024 at 11:01):

the problem is that mutually recursive functions still have to be possible

view this post on Zulip Agus Zubiaga (Jun 04 2024 at 11:02):

Ah, right

view this post on Zulip Richard Feldman (Jun 04 2024 at 11:02):

another potential solution is to only allow mutually recursive functions at the top level

view this post on Zulip Richard Feldman (Jun 04 2024 at 11:03):

we had discussed that before somewhere, although I don't remember where :sweat_smile:

view this post on Zulip Richard Feldman (Jun 04 2024 at 11:04):

I guess that's the simplest design because the rule is basically "you have to define a value before you use it, except top-level values can be defined in any order and used in any order"

view this post on Zulip Richard Feldman (Jun 04 2024 at 11:04):

and I think maybe we also separately discussed not allowing top-level values to shadow each other, because ordering wouldn't be clear

view this post on Zulip Agus Zubiaga (Jun 04 2024 at 11:08):

That’s pretty clean if we can get away with it

view this post on Zulip Agus Zubiaga (Jun 04 2024 at 11:08):

I don’t remember writing mutually recursive functions inside a let in Elm


Last updated: Jul 06 2025 at 12:14 UTC