On 2/19/13, Beni Cherniavsky-Paskin <c...@users.sf.net> wrote:
> Here is yet another idea for opening multiple levels on one line, that does
> NOT involve column counting, only comparison of leading whitespaces.
>
> It's a backward-compatible extension to SUBLIST (similarly applicable to
> any competing FOOLIST semantics), so we could leave it undecided for now,
> and legalize it later.
>
> $ lets one open an inner list on one line, but currently it's only usable
> when this list is the last element of the containing list:
>
> outer1 outer2 $ inner1
> ! inner2
>
> You cannot express (outer1 outer2 (inner1 inner2) outer3)
> without giving up on use of $.
>
> The proposal is to allow an unmatched dedent after inner2, and have that
> return you to the outer level:
>
> outer1 outer2 $ inner1
> ! ! inner2
> ! outer3
>
> which would be equivallent to:
>
> outer1 outer2
> ! inner1
> ! ! inner2
> ! outer3
>
> More formally (described for simplicity in terms of numeric indentation
> levels; easily doable in terms of exact substrings):
>
> - Every $ pushes a "?" placeholder onto the stack of known indent levels.
> - As before, increases in indentation push a specific number onto the
> stack.
> - Dedents matching a level on the stack are handled as before, closing all
> levels to the right, whether specific or placeholders.
> - A dedent that doesn't match any specific level is *only* allowed if there
> is at least one placeholder between the closest specific levels.  All
> higher levels are closed, and the *rightmost* (see rationate at end) of
> these placeholders is converted to the specific level seen.
>   Let's say you had (10 ? ? 16) on the stack and you encounter a line
> starting with 14 spaces. This closes 16 and the new stack is (10 ? 14).
>   A following 13 line would close 14 and leave (10 13), and then a
> following 12 line would be an error.

I think it's also important to consider the "SAME" (as opposed to
INDENT or DEDENT) token.  In particular:

x
! foo $ bar
! a b

==>

(x
  (foo bar)
  (a b)
)

Since the INDENT/SAME/DEDENT decision is based on the indentation
stack, I think we should specify it as follows:

1.  Every $ adds a ? to the indentation stack, and emits an INDENT.
2.  On encountering an EOL, slurp the indentation.
3.  If the indentation is greater than the topmost non-? stack entry,
push its indentation level on the stack and consider it an INDENT.
4.  If the indentation is equal to the topmost non-? stack entry, pop
off ? stack entries (emitting a DEDENT for each).  If there are no ?
on the stack top, emit a SAME.
5.  If the indentation is less than the topmost non-? stack entry, pop
off ? stack entries (emitting a DEDENT for each) until you reach a
state where the topmost non-? stack entry is less than or equal to the
indentation.
5.1.  If the topmost non-? stack entry is equal to the indentation,
pop off ? stack entries (emitting a DEDENT for each).
5.2.  if the topmost non-? stack entry is less than the indentation,
and there is at least one ? entry, pop off the topmost ? entry and
replace it with the current indentation (do not emit any INDENT or
DEDENT tokens).
5.2.  Otherwise, error!

So, let's consider this classic SUBLIST text:

probe $ call/cc $ lambda (exit) $ cond
  foo? $ exit 1
  bar? $ 2

==>
probe INDENT call/cc INDENT lambda (exit) INDENT cond
   ; at this stage, stack is (0 ? ? ?)
   INDENT foo? INDENT exit 1
   ; at this stage, stack is (0 ? ? ? 2 ?)
   ; it sees an indent of 2, so it emits a DEDENT here
   ; via rule #4.
   DEDENT
   bar? INDENT 2
   ; at this stage, stack is (0 ? ? ? 2 ?)
   ; an empty line may be considered an indent of 0,
   ; so insert 5 DEDENT's
DEDENT DEDENT DEDENT DEDENT DEDENT

==>
probe
! call/cc
! ! lambda (exit)
! ! ! cond
! ! ! ! foo?
! ! ! ! ! exit 1 ; 5 indent's so far, so 5 levels, seems right
! ! ! ! bar?
! ! ! ! ! 2 ; 5 dedents after this, so we close!!

--

Looks about right.

Now the main reason to implement SUBLIST this way is, of course, the
bane of indentation syntax, LET:

let
!!$ x $ compute 'x
!!!!y $ compute 'y
!!use x y
==>
let
  ; the first indent below is the "real" indent
  INDENT INDENT INDENT x INDENT compute 'x
  ; at this point, stack is (0 2 ? ?)
  ; again, first indent below is "real" indent"
  INDENT y INDENT compute 'y
  ; at this point, stack is (0 2 ? ? 4 ?)
  ; since we get back to an indent of 2,
  ; emit 2 DEDENT's to get past the 4,
  ; then (via rule 5.1) pop off all ? to
  ; reach the 2 (which involves popping
  ; off 4 indents).
  DEDENT DEDENT DEDENT DEDENT use x y
  ; again, empty line, pop off the single dedent
  DEDENT
==>
let
!\\
!!\\
!!!x
!!!!compute 'x
!!!!!y
!!!!!!compute 'y
.....

well, bummer, doesn't work.

Oh well.

Sincerely,
AmkG


>
> A common objection to any scheme allowing unmatched dedents is that it
> requires lookahead, both for machine parsing *and humans*.  When you read:
>
> foo
> ! ! bar
> ... pages of stuff
> ! ! baz
> ! quux
>
> it's very disconcerting to realize that all this bar...baz stuff was not a
> direct child of foo but was nested within a ...quux construct!
> But in our case, $ already declares that we opened an inner construct, so I
> think it won't be surprising to humans.
>
> What about multiple $ ambiguity?  Given:
>
> A1 $ B1 $ C1
>    !    ! C2
>    ! B2
>
> why does the dedent return you to the inner B level and not the outer A
> level?
> It's the only sane choice, for several reasons:
> - Continuity with current usage, which I expect will remain the dominant
> use of $: without unmatched dedents you only have access to innermost C
> level, so the accessible level should be the next innermost.
> - It's the only way (without magic lookahead) that allows you to access all
> levels, if desired.
> - It's similar to the standard resolution of "if A1 if B1 if C1 else C2
> else B2".
>

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Readable-discuss mailing list
Readable-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/readable-discuss

Reply via email to