rhombus-prototype icon indicating copy to clipboard operation
rhombus-prototype copied to clipboard

Odd scoping/visibility for the `parse_syntax_class` in `space.enforest`

Open distractedlambda opened this issue 6 months ago • 3 comments
trafficstars

Consider this code:

space.enforest myspace:
  space_path myspace
  meta_namespace myspace_meta:
    parse_syntax_class Parsed

    // works fine
    fun parse_1(stx):
      let '$(parsed :: Parsed)' = stx
      parsed

    // does not work; Parsed is not visible as a syntax class
    fun parse_2('$(parsed :: Parsed)'):
      parsed

I would have expected both parse_1 and parse_2 to compile, but it looks like the Parsed syntax class is not bound early enough for parse_2 (the same issue also presents itself trying to define a syntax class that uses Parsed).

distractedlambda avatar May 01 '25 18:05 distractedlambda

I think this is essentially the same problem as

class Posn(x, y):
  export zero
  fun zero() :: Posn:
    Posn(0, 0)

where we currently have to write

class Posn(x, y):
  export zero
  
fun zero() :: Posn:
  ~name: Posn.zero
  Posn(0, 0)

The problem boils down to sometimes wanting definitions within the class or other namespace-like body to be able to bind or influence later clause forms, and sometimes not.

There could be a clause form that groups definitions that cannot influence later clauses, and so the definitions could be delayed as done above manually. Maybe a definitions class, space, etc., clause form?

Or we could maybe delay definition and expression forms by default, as opposed to nestable-declaration forms that might expand to a mixture of clauses and definition forms. But I'm not sure it works to make that kind of distinction.

mflatt avatar May 01 '25 18:05 mflatt

The problem boils down to sometimes wanting definitions within the class or other namespace-like body to be able to bind or influence later clause forms, and sometimes not.

Oh, so, to make sure I get this right, the issue you're showing with class is that the annotation (and the static information it imparts) could depend on clauses in the class body, so all those clauses have to be processed before you can define that annotation; and then the issue with space.enforest is similarly that other meta_namespace clauses could influence how the parse_syntax_class is defined?

Or we could maybe delay definition and expression forms by default, as opposed to nestable-declaration forms that might expand to a mixture of clauses and definition forms. But I'm not sure it works to make that kind of distinction.

If I follow what you're getting at, that sounds attractive. Specifically, since class_clause macros are distinct from ordinary defn macros (and defn macros can't expand to more class clauses, I assume), it should be possible to collect all of the primitive clauses in the class body before trying to expand any definitions or expressions within it. And then we could define some nuanced handling of those clauses (e.g. expanding binding, annotation, etc. early so that you can have the binding and annotation forms in-scope when expanding definitions).

distractedlambda avatar May 02 '25 15:05 distractedlambda

I came across another issue that's at least superficially related, but seems more likely to be an actual bug:

#lang rhombus/and_meta

space.enforest myspace:
  space_path myspace
  meta_namespace myspace_meta:
    parse_syntax_class Parsed

meta:
  import rhombus open

  namespace foo:
    export alias 'Parsed':
      'myspace_meta.Parsed'

  fun bar('$(_ :: foo.Parsed)'): // error: "Parsed: identifier not provided by foo"
    #void

distractedlambda avatar May 02 '25 15:05 distractedlambda

Commit 0356d254e0c6f4891647051441d203d5965a9ec1 addresses just the alias bug.

mflatt avatar Jun 26 '25 17:06 mflatt

Or we could maybe delay definition and expression forms by default

Delaying all definitions doesn't seem to work out. Delaying definitions and expressions that appear at the end of the block (with no declarations or clauses afterward) works out. It's a subtle distinction, but it seems to be a good compromise. I'll post a PR.

mflatt avatar Jul 01 '25 13:07 mflatt

Is #693 enough of an improvement to close this issue?

mflatt avatar Jul 07 '25 16:07 mflatt

Is #693 enough of an improvement to close this issue?

Yes!

distractedlambda avatar Jul 08 '25 19:07 distractedlambda