Re: [racket-users] #lang something // infix, optionally indentation-sensitive experimental Racket syntax

2019-07-22 Thread Stephen De Gabrielle
On Mon, 22 Jul 2019 at 18:39, Neil Van Dyke  wrote:

> The shell demo is great.  I can't look closely at `#lang something`
> quite yet, and I hope someone will include it in a list of the most
> interesting prior work for everyone interested in new syntax to look at.
>

Done:

https://github.com/racket/racket2-rfcs/blob/master/prior-art.md#lang-something

Kr

S.


> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/dfc442cb-a7e3-9d86-2016-f72a51b58d18%40neilvandyke.org
> .
>
-- 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAGHj7-J_fT0QSCNFVZqdcsvBzEd_CHpugchVWCSBOqyk7OV0sg%40mail.gmail.com.


Re: [racket-users] #lang something // infix, optionally indentation-sensitive experimental Racket syntax

2019-07-22 Thread Neil Van Dyke
The shell demo is great.  I can't look closely at `#lang something` 
quite yet, and I hope someone will include it in a list of the most 
interesting prior work for everyone interested in new syntax to look at.


--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/dfc442cb-a7e3-9d86-2016-f72a51b58d18%40neilvandyke.org.


[racket-users] #lang something // infix, optionally indentation-sensitive experimental Racket syntax

2019-07-21 Thread Tony Garnock-Jones
Hi everyone,

Recent threads have reminded me I never properly announced "#lang
something", an experiment from back in 2016.

The main idea is S-expressions, but with usually-implicit parentheses
and support for prefix/infix/postfix operators. Indentation for grouping
is explicitly represented in the S-expression returned from the reader.

  + keeps a semi-structured input format: reader yields ordinary syntax
  + macros Just Work
  + you can do "if ... then ... else ...": [1]
  + you can do "... where ...": [2]
  - uses indentation (though it doesn't have to; see for example [3])
  - the function syntax isn't `function(arg, ...)`

[1]
https://github.com/tonyg/racket-something/blob/4a00a9a6d3f5aab4f28b03c53555b87e21d7/examples/if-then-else.rkt
[2]
https://github.com/tonyg/racket-something/blob/4a00a9a6d3f5aab4f28b03c53555b87e21d7/examples/where.rkt
[3]
https://github.com/tonyg/racket-something/blob/4a00a9a6d3f5aab4f28b03c53555b87e21d7/src/something/shell2.rkt

(More links at the bottom of this message)

In addition to the reader, `#lang something` provides a small selection
of special forms that take advantage of the new syntax, and `#lang
something/shell` adds Unix-shell-like behaviour and a few associated
utilities.

This program:

#lang something
for { x: 1 .. 10 }
  def y: x + 1
  printf "x ~a y ~a\n" x y

... reads as this S-expression:

(module something-module something/base
  (#%rewrite-body
   (for (block (x (block (1 .. 10
(block (def y (block (x + 1)))
   (printf "x ~a y ~a\n" x y)

The `#%rewrite-body` macro, together with its companion
`#%rewrite-infix`, consults an operator table, extendable via the
`def-operator` macro, to rewrite infix syntax into standard prefix
S-expressions.

The `block` syntax has many different interpretations. It has a macro
binding that turns it into a Racket `match-lambda*`, and it is used as
literal syntax as input to other macro definitions.

For example, here's one possible implementation of that `for` syntax:

#lang something

provide
  for

require
  for-syntax something/base
  prefix-in base_ racket/base

def-syntax for stx
  syntax-case stx (block)
_ (block (v (block exp)) ...) (block body ...)
  (syntax (base_for ((v exp) ...) body ...))

def-operator .. 10 nonassoc in-range

Notice how the `block` S-expressions are rewritten into a normal
S-expression compatible with the underlying `for` from `racket/base`.

Generally, all of these forms are equivalent

x y z  x y z:  x y z { a; b }
  a  a
  b  b

and they are read as

(x y z (block a b))

and are then made available to the normal macro-expansion process (which
involves a new infix-rewriting semi-phase).

Colons are optional to indicate a following suite at the end of an
indentation-sensitive line. Indentation-sensitivity is disabled inside
parentheses. If inside a parenthesised expression,
indentation-sensitivity can be reenabled with a colon at the end of a line:

a b (c d:
  e
  f)

= (a b (c d (block e f)))

a b (c d
  e
  f)

= (a b (c d e f))

Conversely, long lines may be split up and logically continued over
subsequent physical lines with a trailing `\`:

a b c \
  d \
  e

= (a b c d e)

Semicolons may also appear in vertically-laid-out suites; these two are
equivalent:

x y z
  a
  b; c
  d

x y z { a; b; c; d }

Suites may begin on the same line as their colon. Any indented
subsequent lines become children of the portion after the colon, rather
than the portion before.

This example:

x y z: a b
  c d
  e

reads as

(x y z (block (a b (block (c d) e

Square brackets are syntactic sugar for a `#%seq` macro:

[a; b; c; d e f]→(#%seq a b c (d e f))

[   →(#%seq a (b (block c)) (d e f))
  a
  b
c
  d e f
]

Forms starting with `block` in expression context expand into
`match-lambda*` like this:

{
  pat1a pat1b
exp1a
exp1b
  pat2a
exp2
}

→ (match-lambda*
[(list pat1a pat1b) exp1a exp1b]
[(list pat2a) exp2])

The `map*` function exported from `something/lang/implicit` differs from
`map` in `racket/base` in that it takes its arguments in the opposite
order, permitting maps to be written

map* [1; 2; 3; 4]
  item:
item + 1

map* [1; 2; 3; 4]
  item: item + 1

map* [1; 2; 3; 4]: item: item + 1

map* [1; 2; 3; 4] { item: item + 1 }

A nice consequence of all of the above is that curried functions have an
interesting appearance:

def curried x:: y:: z:
  [x; y; z]

require rackunit
check-equal? (((curried 1) 2) 3) [1; 2; 3]

Anyway, thought it worth mentioning.

A few more links:

 - The repository: https://github.com/tonyg/racket-something

 -