Racket2 possibilities

6,028 views
Skip to first unread message

Matthew Flatt

unread,
Jul 20, 2019, 2:49:13 PM7/20/19
to racket...@googlegroups.com
This message is intended as a prose form of what I said at RacketCon,
but it includes some extra explanation triggered by the discussion so
far. Where that happens, I apologize that it isn't in the form of a
more direct response in the original thread.

The Racket2 Idea
----------------

Racket's design and implementation is on solid ground, and from this
point, it can continue to evolve and improve in many ways. No matter
how Racket evolves, the community is committed to preserving what we
have achieved: today's `#lang racket` programs will run in the future,
and today's `#lang racket` modules can be used in future Racket
programs. At the same time, the current language design may be close to
a local maximum, and it's not in the nature of the Racket community to
be satisfied with a local maximum.

By starting all programs with `#lang`, we have created a path to leap
from one peak of design to a different, higher peak without sacrificing
the old one and while staying Rackety. Roughly, that's what we mean by
"Racket2". The name "Racket2" stands for some language that builds on
the current Racket technology and implementation, but that may not
directly accommodate the same bindings and expression forms that appear
in the body of a `#lang racket` module.

Although we could literally write `#lang racket2` for modules in the
new language, "Racket2" is normally understood as a placeholder for a
more distinct name. As a matter of branding, perhaps the language would
be called "Racket X" for some good X --- shortened to "X" in some
contexts --- and Racket X program would be written with `#lang X` line
at the top. Maybe the name depends on how different Racket2 turns out
to be from Racket, so it makes sense to pick a name later.

Venturing out from Racket's current peak opens a large space of
possibilities, so the first step is to agree on a set of goals to be
met by the next peak. The goals can serve as a starting point for
developing roadmap for deciding on technical details in a follow-up
process.

Possible Language Changes
-------------------------

The Racket community has long discussed possibilities for Racket2. Here
are a few potential changes from the wish list:

* Rename functions to make the conventions more uniform, and make
better use of keyword arguments to reduce names and increase
consistency.

* Change structures types to have more or fewer features.

* Use generic datatypes (such as streams) pervasively, instead of
writing code that expects a particular concrete representation (such
as lists).

* Make strings immutable by default (e.g., result of `format` or
`string-append`).

* Adjust the semantics of common syntax forms, such as raising an error
on fall-through for `cond` or `match`, and change the meaning of some
primitives, such as making `integer?` mean "exact integer".

* Make pattern matching more pervasive and available by default.

* Change module, evaluation, and loading callbacks (e.g., protocol for
`current-module-name-resolver`) to improve errors and extensibility.

More changes have been suggested, and no doubt many other changes would
make sense. As a first cut, to synthesize some principles from these
ideas --- as a way of selecting which wishes should be tackled and how
--- the current wish list might be organized and summarized by two
overall goals:

* Make the language more consistent

Consistency means making terminology and binding names more
consistent, and it means unifying related syntactic constructs. For
example, the `define` and `define-syntax` forms should perhaps be
less syntactically distinct. Similarly, pattern matching and syntax
matching seem closely related and could benefit from using the same
pattern language. Also, pattern matching should be pervasively
available among binding forms. Etc.

* Make the language constructs more generic

In many ways, the current Racket language and libraries encourage
the use of concrete data structures instead of abstract datatypes.
The `map` function works on lists, for example, not arbitrary
streams, and even `for` demands concrete declarations like `in-list`
to provide the best performance. Refining the capabilities of
structures and providing a smoother path among dictionaries,
structures, and objects may also fit into this category.

There seems to be a widespread agreement/assumption among the community
that we could one day switch all the general documentation, such as the
Racket Guide, to use `#lang X`. That would preserve the ability to run
`#lang racket` modules and import them into `#lang X` modules, but it
would effectively relegate `#lang racket` to a kind of compatibility
mode. The Racket community has already done this a couple of times,
moving from `(module m mzscheme ...)` to `#lang scheme` to `#lang
racket`, and some of the Racket distribution is still implemented in
`#lang scheme`. After another switch, the constructs for `racket` would
remain documented and maintained, in the same way as the constructs for
`mzscheme` and `scheme` remain documented and maintained, but `racket`
and its documentation would fade to the background.

Based on the wish list, the scale of changes would likely be much
larger than in previous transitions. There will many more changes to
names and changes to the meaning of identifiers that are spell the
same way. The scale of those changes doesn't seem to worry the Racket
community.

Surface Syntax
--------------

You won't find a wish for significant changes the Racket surface
syntax anywhere on the Racket2 wish list. Nevertheless, I've suggested
tacking it on.

Why now?

If we decide that a change to the surface syntax is a good move, it
would make sense to try that at the same time as overhauling names and
syntactic forms. Pattern matching, for example, seems like a place
where syntactic flexibility can help. Besides letting different kinds
of changes reinforce each other, we'd revise all of the documentation
just once instead of twice.

There are downsides to tackling both semantic and syntactic changes at
once. If a change to surface syntax is on the table, though, then we
should at least consider bundling the efforts.

Why at all?

Partly, I believe that a syntax with infix operators, fewer
parentheses, etc., would be better. That's a matter of opinion, but at
least it's an opinion backed by enough experience with parentheses
that it can't be written off as uninformed. More significantly,
parentheses are certainly an obstacle for some potential users of
Racket. Given the fact of that obstacle, it's my opinion that we
should try to remove or reduce the obstacle.

Syntax is not just an obstacle for potential users of Racket as a
programming language, but also for potential users of Racket as a
programming-language programming language. The idea of
language-oriented programming (LOP) doesn't apply only to languages
with parentheses, and we need to demonstrate that. Although we already
have tools for parsing non-parenthesis syntax into parentheses and
letting macros take over from there, that's not the kind of smooth
path from simple extension to full language building that we have in
the S-expression world. While these research problems may not be
forefront on the minds of all Racket users, keep in mind that Racket
exists because of research and remains supported almost entirely by
research.

Adjusting the syntax of Racket to accommodate more users could be
characterized as an effort to make Racket more popular. I don't think
it's helpful to characterize the idea that way. Granted, any effort to
reduce barriers is effectively an effort to make Racket more popular.
In that sense, our efforts on Racket's documentation were an attempt
to make Racket more popular. The work we put into building the Racket
distribution and making it easy to install is an attempt to make
Racket more popular. Creating the package system was an attempt to
make Racket more popular. All strictly true, I suppose, but the
characterization feels wrong. There's a difference between reducing
technical barriers for users of various stripes versus marketing to
make a product more popular. When I point out that parentheses can be
a deal-breaker to people outside the Racket community, I do not have
in mind that we just need a better marketing message; I have in mind
that the obstacle is real, it affects many people, and we should
address it.

Who?

From a community perspective, the rub is that the "many people" for
Racket syntax is a barrier are mostly people outside the community.
It's fair to ask who would benefit. It's difficult to ask a community
to tackle a problem whose solution targets a different community.

There's also a question of who really needs to participate in the
development of a new surface syntax. That part of the project could
take place in its own `#lang` and stay out of the way of `#lang
racket` users for years. As a practical matter, that will certainly
happen, even if we think that that new syntax will eventually take
over. We've already done some side experiments in separate `#lang`s,
though, and now is a time to check whether there is community buy-in
and participation for a more ambitious effort.

How?

Parentheses are definitely useful for Racket-style language-oriented
programming, and parentheses certainly helped Racket's macro system
get to where it is now. There would be no point to a change in syntax
if it meant interfering with Racket's main capability. Although a
macro system without parentheses is a difficult problem, I think we
know how to solve it.

I have in mind "Honu: Syntactic Extension for Algebraic Notation
through Enforestation", GPCE 2012. It shows how we can bridge the
relatively linear structure of non-() programs to the tree structure
of S-expressions. Specifically, the bridge is called "enforestation".
It sits roughly between the reader and the expander, but enforestation
needs to be interleaved with expansion to get the level of
expressiveness that Racketeers would expect.

You may worry that I'm putting a lot of faith in one expriment and
paper --- and a paper written by a PhD student and me, at that. You
may be right. I have only my intuition that enforestation is the key
to the problem of non-() syntax and extensibility. The details in the
paper don't seem to me exactly right for Racket2, but it's a big first
step toward addressing the problem, and it already seems sufficient.
Others may have figured out even more. I wouldn't blame anyone for
concluding that the difficulty of the task is too large for the size
of the obstacle that it removes, but that's not how I size things up.

The gap between 2012 and now reflects that Racket had more problems
(in my view) than just syntax, and for various reasons, those other
problems took precedence for my own work. This also explains my answer
to the "why now" question. The other problems seem to be resolved or
well on the way, and so syntax seems like the next thing to tackle.

How to Proceed
--------------

Ideally, we would first decide on whether we want to try changing
surface syntax ever. Then, only if we have enough consensus that it's
worth a try, we could move on to setting overall goals and picking a
roadmap. Finally, if the planing of the roadmap succeeds, we could
follow it while getting into the details.

Unfortunately, it doesn't work like that. We need concrete examples to
discuss the possibility of changing syntax, potential roadmaps to see
whether there's anywhere we want to go, and so on. Some of the
discussion will necessarily put a cart before a horse. Delving into
some details may incorrectly give the impression that prerequisites
are a foregone conclusion. We've seen all of that already, starting
with my attempt to open up the discussion in the middle of RacketCon
and probably continuing with this message. Perhaps we can just accept
that this is all okay in the spirit of working together.

I originally thought that we should have a more specific process in
place for discussion at this point, but I think I've been proved
wrong. Let's just discuss, for now. I'll be posting more myself.

Neil Van Dyke

unread,
Jul 20, 2019, 3:40:08 PM7/20/19
to racket...@googlegroups.com
Matthew Flatt wrote on 7/20/19 2:49 PM:
> We need concrete examples to discuss the possibility of changing syntax, potential roadmaps to see whether there's anywhere we want to go, and so on.

Procedural suggestions people might want to do:

* There's a lot of prior work, and it might really help discussion if we
all have a shared baseline awareness of it.  Does someone have a
comprehensive list of links (or want to assemble such a list) of the
noteworthy attempts at non-paren syntax in Lisps?  (Offhand, but I know
there's more: Honu, Shriram's work, the SRFI one, Python (which Norvig
called a Lisp), Dylan's change, M-expressions, and some of the countless
others, especially in CL.)  Also, maybe there's also some separate work
in good syntax transformers for non-sexp that we should all know about
at this point?

* With that shared baseline, would people like to highlight on
"racket-users" promising ideas from that prior work, as well as post
their own ideas (informed by prior work)?

* In group creative brainstorming, there's a procedural thing that's
sometimes really helpful.  Basically, there's a phase/mode in which the
top goal is to elicit ideas, and no critical commentary is permitted.  I
don't presume to suggest any rules, and probably shouldn't be a hard
rule in this case, but maybe many people will just tend to lean towards
that, organically, initially.  Then, a little later, get more into
critiquing, and see what new ideas/insights that then generates.  (Where
this idea comes from, there's also a bunch of other modes and roles, and
ways to be aware of and explicitly signal what kind of contribution
you're making, but, to start with, I just wanted to toss out this one
very simple idea.)

Christopher Lemmer Webber

unread,
Jul 20, 2019, 6:07:45 PM7/20/19
to Matthew Flatt, racket...@googlegroups.com
Hi Matthew,

As someone who (unintentionally) caused maybe some of the debate to get
out of hand (or did I?) I would like to open by saying that both your
last email to the prior thread and also this email are both very
encouraging.

I'll skip everything else and jump straight to:

Matthew Flatt writes:

> How to Proceed
> --------------
>
> Ideally, we would first decide on whether we want to try changing
> surface syntax ever. Then, only if we have enough consensus that it's
> worth a try, we could move on to setting overall goals and picking a
> roadmap. Finally, if the planing of the roadmap succeeds, we could
> follow it while getting into the details.
>
> Unfortunately, it doesn't work like that. We need concrete examples to
> discuss the possibility of changing syntax, potential roadmaps to see
> whether there's anywhere we want to go, and so on. Some of the
> discussion will necessarily put a cart before a horse. Delving into
> some details may incorrectly give the impression that prerequisites
> are a foregone conclusion. We've seen all of that already, starting
> with my attempt to open up the discussion in the middle of RacketCon
> and probably continuing with this message. Perhaps we can just accept
> that this is all okay in the spirit of working together.
>
> I originally thought that we should have a more specific process in
> place for discussion at this point, but I think I've been proved
> wrong. Let's just discuss, for now. I'll be posting more myself.

For the sake of discussion, maybe it's easiest to just assume "Racket
attempts a move to a Honu derivative" as its surface syntax, which I'll
call ~Honu for now. (I'm not saying that we know that will happen, I
just think it's a good place to start discussing.) As you have already
said, this will not prevent the existance of "#lang racket" keeping the
syntax many in the community (including myself) already love.

As you said, changing the surface syntax is high-risk, possibly
high-reward. I agree with that, though I think Racket is uniquely
positioned to lower the risk dramatically *because* of the #lang
infrastructure. Is a "try it before we fully buy it" approach maybe
possible? Maybe, for one thing, this could reduce community anxiety
and improve our chances to explore.

Here, maybe is a way it could be done:

- First, port the teaching languages and etc over to Honu. Try
teaching some classes with just-Honu syntax. This is *before*
trying to switch the "internals" of Racket over.
- Encourage a large portion of the community to try to write as many
tools using ~Honu as possible. How do people like it? What can be
improved?
- Begin switching the core docs over, maybe even as a fork. It might
be a pain to maintain two doc forks, but maybe it is worth it.
I suspect that Scribble might even make the task easier, since
autogenerating two manuals from mostly the same source might not
be too hard.
- Switch all the default examples on racket-lang.org over to ~Honu.
- Are people happy? Is this meeting their needs? Get community input.
At this point, if the community is happy enough, and if it appears
that *newcomers* (including in the educational space) are happy
enough, now we can focus on switching the core Racket system over
to ~Honu-as-the-basis.

What do you think? This seems like a clean transition plan to me that
also allows for us to test, readjust, and even allows us to "stage
before we commit", which seems like a big win.

Thoughts?
- Chris

stewart mackenzie

unread,
Jul 20, 2019, 7:37:47 PM7/20/19
to Matthew Flatt, Racket Users
Let's keep this light and fun, especially for the implementor, who shouldn't be bogged down with parens-or-die commentry. How about treating it as yet another #lang, albeit one of interest as core members have an itch to scratch. Let's cross the bridge of moving docs/website/drastic stuff when there's an implementation that passes muster. Choose a silly and fun code name to start off with, a bit of self deprecation and irony goes far. The new language needs to earn the title of racket2, a name with much gravity.

I'm looking forward to #lang not(racket2) as, certainly, I'll learn new things. A whole new world drawing from the best of research and Racket.

With that, bloody well have at this problem Matthew, more power to you.

Jay McCarthy

unread,
Jul 20, 2019, 10:02:23 PM7/20/19
to Matthew Flatt, Racket Users
As a procedural matter, I think that the Github repository is a great
way to communicate about specific ideas in way that ideas stay
connected and don't get forgotten.

https://github.com/racket/racket2-rfcs/

Right now, basically all of the discussion is in the issues, as people
work together to gather ideas. I think eventually we need to try to
write longer-form proposals about the details.

I think Matthew's point about trying to write down some concrete
examples would be extremely valuable as issues to spur discussion.

--
Jay McCarthy
Associate Professor @ CS @ UMass Lowell
http://jeapostrophe.github.io
Vincit qui se vincit.
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/5d336227.1c69fb81.321e4.6fc8SMTPIN_ADDED_MISSING%40gmr-mx.google.com.

Andrew Gwozdziewycz

unread,
Jul 20, 2019, 11:53:31 PM7/20/19
to Matthew Flatt, Racket Users
Thank you for writing this.

On Sat, Jul 20, 2019 at 11:49 AM Matthew Flatt <mfl...@cs.utah.edu> wrote:

> Possible Language Changes
> -------------------------
>
> The Racket community has long discussed possibilities for Racket2. Here
> are a few potential changes from the wish list:

I like this list of changes. I'd feel great about Racket 2 if it
doubled down on removing concrete types in favor of interfaces /
abstract types. I'd feel great about Racket 2 if pattern matching was
core, and I didn't have to think about `case-lambda` and friends. I'd
feel great about structures / records if I didn't have a million
different options when defining them. I'd feel great about Racket 2 if
we introduced "arc"-like accessors, and conveniences that removed the
need for nested function calls (e.g. `(foo-name afoo)` vs
`afoo.name`)...

I'd feel great about Racket 2 if it maintained the curation and
simplicity of R*RS Scheme, but with modern conveniences that reduced
keystrokes and line width without giving up expressivity.


> Surface Syntax
> --------------
>
> You won't find a wish for significant changes the Racket surface
> syntax anywhere on the Racket2 wish list. Nevertheless, I've suggested
> tacking it on.

I'm in favor of a different syntax if it doesn't add new semantics
along with it. I'm also in favor of an s-expression based syntax that
uses less parens all together. In other words, I think a way to
proceed might be to have syntax be actually surface, and completely
inter-changeable, such that if I prefer s-expressions, Dr Racket
allows me to edit that way. If I prefer an infix representation, Dr
Racket can read the s-expressions and convert it to infix, and convert
it back on save (Or the other way around depending on the code base
preferences).

As Lispers we've all argued that surface syntax doesn't matter for
years, trying to get people to not see our choices as "Lots of
Infuriating Stupid Parentheses." So, why not go all in on this and
show that we really believe it?

I realize I'm asking for a pony, _and_ a horse...

--
http://www.apgwoz.com

Matthew Flatt

unread,
Jul 21, 2019, 8:59:24 AM7/21/19
to Christopher Lemmer Webber, racket...@googlegroups.com
I agree that the process would have to be something like that.

I'm skeptical of starting with teaching languages in the sense of BSL,
ISL, and ASL. That sets up some different problems --- ones that Pyret
has directly addressed/explored. (Obviously, we should pay attention to
Pyret.)

But a separate branch to try porting examples and modules and to
explore new documentation certainly makes sense at some point.

Hendrik Boom

unread,
Jul 21, 2019, 9:38:33 AM7/21/19
to racket...@googlegroups.com
I found a page about Honu here: https://docs.racket-lang.org/honu/index.html

It looks elegant. But I'd have to try it out on some serious problem
to see if it's as elegant as it looks.

>
> - First, port the teaching languages and etc over to Honu. Try
> teaching some classes with just-Honu syntax. This is *before*
> trying to switch the "internals" of Racket over.

I'd start "porting" the main language over. It's essential to get
early experience with nontrivial use.

> - Encourage a large portion of the community to try to write as many
> tools using ~Honu as possible. How do people like it? What can be
> improved?
> - Begin switching the core docs over, maybe even as a fork. It might
> be a pain to maintain two doc forks, but maybe it is worth it.
> I suspect that Scribble might even make the task easier, since
> autogenerating two manuals from mostly the same source might not
> be too hard.

You would wnt a fork, if only to keep the *large* collection of
existing #lang racket users ans developers happy.

If you are careful in maintaining line-by-line integrity between Racket
documentation and Honu documentation, you might not find it difficult
to merge Racket documentation updates into the Honu documentation
repository.

And you would want to be able to autogenerate *three* manuals: a
Racket manual, a Honu manual, and a manual for both together. It's
quite likely people will want to use the two together.

Hendrik Boom

unread,
Jul 21, 2019, 9:43:13 AM7/21/19
to Racket Users
On Sat, Jul 20, 2019 at 08:53:17PM -0700, Andrew Gwozdziewycz wrote:
>
> I'm in favor of a different syntax if it doesn't add new semantics
> along with it. I'm also in favor of an s-expression based syntax that
> uses less parens all together. In other words, I think a way to
> proceed might be to have syntax be actually surface, and completely
> inter-changeable, such that if I prefer s-expressions, Dr Racket
> allows me to edit that way. If I prefer an infix representation, Dr
> Racket can read the s-expressions and convert it to infix, and convert
> it back on save (Or the other way around depending on the code base
> preferences).

Scribble is an example of how two syntaxes can coexist in one source file.

-- hendrik

Alexis King

unread,
Jul 21, 2019, 1:12:30 PM7/21/19
to Racket Users
On Jul 21, 2019, at 00:19, Matthew Flatt <mfl...@cs.utah.edu> wrote:

I have in mind "Honu: Syntactic Extension for Algebraic Notation through Enforestation", GPCE 2012. It shows how we can bridge the relatively linear structure of non-() programs to the tree structure of S-expressions. Specifically, the bridge is called "enforestation". It sits roughly between the reader and the expander, but enforestation needs to be interleaved with expansion to get the level of expressiveness that Racketeers would expect.

To add a few of my own thoughts on this: in light of recent events, I reread the Honu paper more closely this past week, and I would strongly encourage anyone who is invested in surface syntax to do the same. It is a beautiful paper. Crucially, it is beautiful not because it does anything complex but because it solves a hard problem in a simple, elegant way. If you have any misgivings about what might happen to the expressiveness of the macro system if we were to move away from s-expressions, it is required reading.

What the paper does not do is editorialize (as it shouldn’t), so I will do so myself. The techniques described in the Honu paper are dramatically superior to alternative approaches I have seen, for two reasons:

  1. “Automatic parenthesis insertion” approaches like sweet, wisp, liso, etc. invariably demand users think about the desugared, parenthesized form. Macros are ultimately still defined by parsing syntax objects built from s-expressions, so every extra pair of parentheses suddenly matters, even if they’re invisible and no reasonable built-for-purpose syntax would care about them. This is a terrible experience, and it forever condemns these approaches to be second-class citizens.

    Honu’s macros, in contrast, operate much closer to the concrete syntax, and they don’t require thinking about implementation details of the language. We demand our Racket macros be real abstractions, and Honu lets them stay that way.

  2. It is easy to foresee a transition away from s-expressions as a restriction on what can be expressed via macros, mostly since non-s-expression languages with macro systems (such as Haskell and Elixir, to name just two) usually impose such restrictions. But that is what is so remarkable about Honu: its macros allow what is really a superset of Racket’s current syntactic flexibility. I think the paper has a good explanation of why this is, I just don’t think it points out the implications explicitly enough, so if this is a surprise to you, go back and take another look.

Of course, it’s not all roses. The existing Honu implementation lays sturdy foundations, but it doesn’t include a syntax/parse equivalent: there’s no Honu-native DSL for writing Honu macros. A lot of the ideas in syntax/parse should carry over, but there are more than a few new wrinkles to be ironed out. On top of that, there are open questions about everything from documentation to tooling to what the appropriate syntax for the base language ought to be.

I understand that many people in the Racket sphere are very fond of s-expressions for a variety of reasons, something that was made abundantly clear to me in the several dozen replies I got to a twitter comment I made on the matter. I certainly can’t assuage all fears of losing them, but I sincerely hope that the second point I made above sinks in for others like it has for me: there are ways a change in syntax can be enabling, not simply a compromise for some non-specific “other people.” Wouldn’t it be wonderful if we could design new languages, embedded or otherwise, with whatever syntax we wish as easily as we can design them in Racket today using s-expressions? Going down this path has the potential to move us much closer to that reality, and I, for one, think that’s exciting.
 

Jay McCarthy

unread,
Jul 21, 2019, 1:43:44 PM7/21/19
to Alexis King, Racket Users
On Sun, Jul 21, 2019 at 1:12 PM Alexis King <lexi....@gmail.com> wrote:
> It is easy to foresee a transition away from s-expressions as a restriction on what can be expressed via macros, mostly since non-s-expression languages with macro systems (such as Haskell and Elixir, to name just two) usually impose such restrictions. But that is what is so remarkable about Honu: its macros allow what is really a superset of Racket’s current syntactic flexibility. I think the paper has a good explanation of why this is, I just don’t think it points out the implications explicitly enough, so if this is a surprise to you, go back and take another look.

This point by Alexis, IMHO, is the big reason for thinking about
Racket2 for me. The parenthesis notation of Racket is a restriction to
make certain things easy, but we now know a lot more than we did in
the past, so we can keep those things easy while removing the
restriction that keeps us from doing more interesting things.

Jay

Michael Myers

unread,
Jul 21, 2019, 3:47:28 PM7/21/19
to Racket Users
I'm somewhat reluctant to write this, as I am more conscious then ever of my limitations in terms of what time/energy I can commit and the consistency with which I can do so. But insofar as Honu was mentioned, I feel a bit obligated to at least chime in with some of my knowledge and observations of it, and some related possible strategies.

At the moment, aside from Matt and Jon, I think I have the most direct experience of Honu's inner workings. I've also spent a good number of years trying to toy with what I feel is a simpler and more modular approach, but I've often gotten caught up in bike shedding about names, interfaces and what to expose where. For various reasons, this is a domain which unfortunately makes it *very* easy to do so. My efforts so far can be found here: https://pkgs.racket-lang.org/package/infix-syntax, it is unfortunately under documented though. That being said, I would really recommend reading the source if possible, as it manages to do a lot in a really astoundingly little amount of code (the core logic that drives everything is a 7-line function). Specifically this https://github.com/mromyers/infix-syntax/tree/master/infix-syntax/private/core .
</self promotion>

Anyhow, regardless of the exact approach chosen, there are a couple of issues I forsee with trying to integrate honu-like features into racket-X. These aren't meant to be objections, just things that need to be worked on.

The most trivial one is that define-primitive-splicing-syntax-class really should graduate out of experimental, since Honu depends really crucially on it for its nice integration with syntax-parse. While this function hasn't changed in years, the fact that it's in experimental does speak to some uncertainty about the interface it provides, which should be addressed one way or another. I do dislike the interface slightly, as requiring the number of items consumed is slightly awkward in Honu's case, introducing a slight inefficiency in redundantly needing to traverse the same input list a couple of times, but that's a minor annoyance at worst.

A more general problem is one of style. In racket currently, it seems to be encouraged to define keywords in a macro (using ~literal instead of ~datum), as in 'else' for cond. This has the nice result of allowing you to rename keywords. Unfortunately, this introduces a couple headaches in something like Honu, which ends up making some things less flexible.

As an example, suppose you have the C ternary operator 'x ? y : z' . If you define : as a keyword, either everyone else that uses : as a keyword, like a list comprehension macro, will need to use the same one, or you can't use both simultaneously. In the best case scenario, : is defined either in core, or in a very central library, so most macros that use : as a keyword will use the same one. However, if someone later wants to define a : operator in a non-core library, using it will break every macro that uses : , since it's not the ~literal they're looking for.

The same problem exists for normal macros of course, but in practice it's not as much of a problem, because for one there just aren't that many of them, since #:keywords fill most of their role. No one seems to grumble for instance about the fact that their lovely 'else' function silently breaks all of their cond expressions. For operators however, you're usually drawing from a much smaller set, and so collisions are a bit more painful. Naturally, the solution is to just match : as a datum when it's used as a keyword, though this does prevent renaming the keyword if someone should wish. Still, I think as a matter of style and convention it's worth thinking about good rules of thumb and best practices for deciding when to define a keyword literal, and when to just use a datum.

This also ties into one of the other major sore points surrounding scope and collision. In languages like haskell and sml, one can 'upgrade' an already defined function to an operator with infixr / infixl statements. These are fairly convenient to work with, but it's hard to get something similar working in Racket, and would require greatly complicating how parsing works. The status quo is, if you want to define a new + function, one needs to do something like either:
(require (rename-in racket/base [+ add]))
(define-id-operator + add #:left- assoc #:prec 3)

or define the operator as add and use rename-out.

Now, you might not see this as too much of a hassle, but it does add a bit of mental overhead and room for user error compared to just, say,
(declare-infixl + #:left-assoc #:prec 3)
The most natural way to implement something like the latter would be something like chez scheme's define-property, so this would be very nice to have if at all possible. It does require some thinking about its proper set-of-scopes semantics though.

Anyways, there are a few other thoughts I have on the subject, but this is getting long enough as it is, so I'll cut things short, and maybe provide some more later. First, two replies to some earlier comments.

Neil Van Dyke: For prior work, you should also look at Pratt's Top Down Operator Precedence Parsing paper, and the resulting CGOL language. Also, Disney's Sweet.js

Alexis: Actually, there is a dsl for defining honu macros. See for example https://github.com/racket/honu/blob/master/honu/private/common.honu

Ray Racine

unread,
Jul 21, 2019, 11:11:54 PM7/21/19
to Racket Users
Over the years I have loved Racket ... except for those parens ... if only.   I don't know when it happened but one day parens and I made a peace treaty, mind melded, became enlightened or just got tired of fighting, but right now I can't see a Racket without parens (s-exps). I have, in fact, grown rather fond of them.

There is the bottom up approach to grow Racket2 from examples and snippets of syntax all to be compared and endlessly debated.

Rhetorical mullings from the top down perspective is interesting.

Assume a Racket2 will not be another Ruby or Python as Racket is a BIG language and could not be compressed down to a simplistic Python or simple lisp without parens Ruby.  And what is the point of Racket2 being a Ruby or Python wanna-be anyway?  Would the world move to a better Python/Ruby?

Assume it will not be some variation of a Swift, Java or C#.

If moving from s-exp to traditional in-fix and f(x,y,z) function application makes sense to seek wider adoption, would not moving from functional to imperative also make sense? After all, all the popular languages are imperative, therefore, to enhance the likelihood of wide adoption should Racket2 be imperative as well?

But then wouldn't Racket2 be Algol2 or Ada2 with macros?

If it stays functional and expression based with macros then isn't Racket2 then Dylan2?

Of the three axioms of Racket2, the f(x,y,z) proscription prohibits some of the cleaner syntax out there as used in SML and Haskell.  Is it a hard requirement to ensure full macro support can happen?

If Racket2 moves to be even more functional in thrust, drops the f(x,y,z) proscription and adopts currying then isn't Racket2 a polished up nextgen SML2?

Maybe a nextgen SML2 for semantics and typing but with the lighter Haskell syntax (no laziness)?

What will be the magic twist for widespread adoption that Algol, Ada, Dylan, SML, Haskell and s-exp Racket, all with quality implementations, failed to achieve? 

How much of a languages adoption success is just shear dumb luck, the right place at the right time independent of the languages overall quality and capability? Does Javascript even need to mentioned here?

Should we cover all possible bases and make Racket and its "make languages" core a nextgen DotNet and put together a whole suite of languages, a Lisp like, an Algo like, a SML like, a Haskell like, a Java/Swift like, an Erlang like, ... all interoperable.   If that all of that happened tomorrow by magic would the world embrace Racket(2...).









Dexter Lagan

unread,
Jul 22, 2019, 4:46:21 AM7/22/19
to Ray Racine, Racket Users
  I'm not going over why s-expressions are the way to go, mr. Rivest did it best in his 1997 MIT doc:


  A parens-less Racket2 would become Crystal. And I don't think we need yet another functional parens-less language. We already have Haskell (hard to read) and Crystal (weird half-commercial proposition that won't produce binaries without major hacks). I say we keep the parens but make them even less intrusive. Newlisp may be an ugly hack, but its simplified forms and anaphoric vars are very nice to use. For example:


Dex


--
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...@googlegroups.com.
Message has been deleted

Mário Guimarães

unread,
Jul 22, 2019, 5:23:23 AM7/22/19
to Racket Users
I have read through all the posts before mine, and saw no reference to what could be the solution to the adoption problem.

I only remember comments regarding how students feel unconfortable about s-expressions and all those parenthesis

Making a language popular in my view is to make it attractive to professional developers and the industry overal, not to students.

In fact, too much reference to students makes people from industry think that the language is for use only in academic settings, and this is very unfortunate they think so.

I have mentioned this one, and will repeat again:

Make Racket become Language-Oriented Programming on the JVM, the ErlangVM, and perhaps other mainstream VMs.

Do this first, then watch, then consider other changes, like the syntax one.

I really don't believe that how beautiful and operational a new syntax becomes, will it attract people in the industry who are too much committed to these VMs.

Failing to target these VMs and you will be in the next 5 years asking again why Racket 2 is still hardly adopted.

I can't say more regarding Racket's adoption strategy.

Thanks
Mário Guimarães

Hendrik Boom

unread,
Jul 22, 2019, 9:44:06 AM7/22/19
to Racket Users
On Mon, Jul 22, 2019 at 02:19:39AM -0700, Maria Gabriela Guimarães wrote:
...
>
> I have mentioned this one, and will repeat again:
>
> *Make Racket become Language-Oriented Programming on the JVM, the ErlangVM,
> and perhaps other mainstream VMs.*

And the JVM in browsers has been thoroughly supplanted by Javascript.
The designers of Javaascript originally planned to put a Lisp on the
browser (possibly even a Scheme?) but were forced to give it a C-like syntax.
Is Javascript the kind of Scheme-without-parentheses we're looking for?
Perhaps not; it isn't a design-your-own-language system.

-- hendrik

Hendrik Boom

unread,
Jul 22, 2019, 10:10:03 AM7/22/19
to Racket Users
On Mon, Jul 22, 2019 at 10:46:26AM +0200, Dexter Lagan wrote:
> I'm not going over why s-expressions are the way to go, mr. Rivest did it
> best in his 1997 MIT doc:
>
> https://people.csail.mit.edu/rivest/Sexp.txt
>
> A parens-less Racket2 would become Crystal. And I don't think we need yet
> another functional parens-less language.

Keep S-expressions, but change their syntax.

Nesting parentheses are like recusion.
Create a notation for tail-nested parenthese, kind of like
tail-recursion optimisation, turning that kind of nesting
into something more like iteration.

It's tail-nesting that tends to move indentation far, far to the right
and creates accumulations of hard-to-count close-parenthesis
agglomerations.

My proposal is to pick a currently underused character (I picked '/' 30
years ago but amost anything would do) and use it to replace the
tail-nesting '(', and remove its corresponding ')'.

Suddenly visual parenthesis-matching becomes an order of magnitude
easier, without losing any of the expressiveness and conceptual
significance of S-expressions.

-- hendrik

> We already have Haskell (hard to
> read) and Crystal (weird half-commercial proposition that won't produce
> binaries without major hacks). I say we keep the parens but make them even
> less intrusive.

A notation for tail-nestig accomplishes non-intrusive parens all by
itself.

> Newlisp may be an ugly hack, but its simplified forms and
> anaphoric vars are very nice to use. For example:
>
> http://www.newlisp.org/downloads/newlisp_manual.html#if

With tail-nesting notation, there's no need for the iterated if.
And this if-iteration can be freely interspersed with let's. Also a
common occurrence.

Tail-nesting notation is completely orthogonal to the rest of the
language.

-- hendrik

Alexis King

unread,
Jul 22, 2019, 10:15:51 AM7/22/19
to Dexter Lagan, Racket Users
On Jul 22, 2019, at 14:16, Dexter Lagan <dexte...@gmail.com> wrote:

A parens-less Racket2 would become Crystal.

No it won’t. I am quite confident that Racket with any syntax will not be like any other language that currently exists. What other language has Racket’s advanced, robust compile-time metaprogramming support, its higher-order contract system, its #lang mechanism (applied to great effect in technologies like Scribble and Typed Racket), its language-as-an-operating-system support for runtime sandboxing and introspection, and its featureful and extensible FFI, among many other things? To say that Racket is so defined by its syntax that it will cease to be distinguishable from any other language if it is changed is absurd, and it’s frankly insulting to all the people who have put so much effort into every part of Racket.

If you believe Racket’s syntax is its most important feature, and that everything else that sets it apart from other languages is pragmatically irrelevant, I can’t really argue with that. I disagree, but it’s a matter of opinion. That said, that kind of criticism isn’t very constructive, since I don’t know how to interpret it beyond “I really like parentheses,” which is hardly actionable or debatable.

I make no claims of representing the will of PLT, so I could be wrong, but I think discussing what about s-expressions you like—and what about other syntaxes you dislike—is on-topic and can produce constructive discussion. But although it’s possible I didn’t read it carefully enough, the link you provided doesn’t seem to have much in the way of that sort of explanation… it seems to focus on how to most usefully take advantage of s-expressions, but it doesn’t compare them to other formats.

Mário Guimarães

unread,
Jul 22, 2019, 10:26:04 AM7/22/19
to Racket Users

> And the JVM in browsers has been thoroughly supplanted by Javascript. 

I missed another VM: Racket2 should also target WebAssembly.

amz3

unread,
Jul 22, 2019, 10:33:59 AM7/22/19
to Racket Users


On Monday, July 22, 2019 at 4:26:04 PM UTC+2, Mário Guimarães wrote:

> And the JVM in browsers has been thoroughly supplanted by Javascript. 

I missed another VM: Racket2 should also target WebAssembly.

I experimented with various scheme in browser intrepred via JavaScript and compiled to wasm both are not good enough.

Dexter Lagan

unread,
Jul 22, 2019, 10:43:54 AM7/22/19
to Alexis King, Racket Users
  Like I said, my limited experience makes my opinion of limited interest. I’m really only speaking from a practical standpoint, meaning, how a Python or Java programmer would see Racket. For example, I have no experience with language design, and I only used Racket and Scribble as-is. Most people I talk to use Python, Go or Java because of their tooling, and don’t complain about Go’s lack of generics.

  I entirely agree with you, Racket is much more than another Scheme, and reducing it to its syntax isn’t fair. However, coming from object and imperative languages, and looking at Racket’s surface, one wouldn’t suspect there’s so much under the hood without digging deeper. It’s quite difficult to explain why Racket is so powerful, precisely when people stop at the parentheses.

  All that to say, I apologize if I offended anyone, and only wish to suggest there might be ways to make Racket more appealing without reinventing the wheel. My personal wish list doesn’t contain anything more advanced than what’s already there: for my use, faster startup and a slightly more advanced GUI framework and editor would be enough.

  What I’m suggesting is that if we want to expose Racket to a broader audience, maybe we could start at the bottom and target the more basic users?

Dex

Maria Gabriela Guimarães

unread,
Jul 22, 2019, 10:52:38 AM7/22/19
to Racket Users
> I experimented with various scheme in browser intrepred via JavaScript and compiled to wasm both are not good enough.

Insufficient implementations I suppose, or wasm misses features important for a Scheme ...

Dexter Lagan

unread,
Jul 22, 2019, 10:52:41 AM7/22/19
to Alexis King, Racket Users
  More specifically, I was referring to design goals for S-expressions:
-- generality: S-expressions should be good at representing arbitrary
     data. 
 -- readability: it should be easy for someone to examine and 
     understand the structure of an S-expression. 
 -- economy: S-expressions should represent data compactly. 
 -- tranportability: S-expressions should be easy to transport
     over communication media (such as email) that are known to be
     less than perfect. 
 -- flexibility: S-expressions should make it relatively simple to
     modify and extend data structures. 
 -- canonicalization: it should be easy to produce a unique 
     "canonical" form of an S-expression, for digital signature purposes. 
 -- efficiency: S-expressions should admit in-memory representations
     that allow efficient processing.

  These are just as relevant today as they were 50 years ago. Why change something that works?
Dex

On Jul 22, 2019, at 4:15 PM, Alexis King <lexi....@gmail.com> wrote:

Paulo Matos

unread,
Jul 22, 2019, 10:58:04 AM7/22/19
to racket...@googlegroups.com


On 22/07/2019 16:52, Maria Gabriela Guimarães wrote:
> I experimented with various scheme in browser intrepred via JavaScript and compiled to wasm both are not good enough.

Insufficient implementations I suppose, or wasm misses features important for a Scheme ...

Someone wanting to take this on might gain inspiration from:
https://github.com/google/schism

Em segunda-feira, 22 de julho de 2019 15:33:59 UTC+1, amz3 escreveu:


On Monday, July 22, 2019 at 4:26:04 PM UTC+2, Mário Guimarães wrote:

> And the JVM in browsers has been thoroughly supplanted by Javascript. 

I missed another VM: Racket2 should also target WebAssembly.

I experimented with various scheme in browser intrepred via JavaScript and compiled to wasm both are not good enough.
--
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...@googlegroups.com.

Neil Van Dyke

unread,
Jul 22, 2019, 11:45:46 AM7/22/19
to Maria Gabriela Guimarães, Racket Users
Maria Gabriela Guimarães wrote on 7/22/19 10:52 AM:
> > I experimented with various scheme in browser intrepred via
> JavaScript and compiled to wasm both are not good enough.
>
> Insufficient implementations I suppose, or wasm misses features
> important for a Scheme ...

What Maria said.  WASM (not JS) now seems the place for us to focus, for
performance.  It's a little early for Schemes in WASM, and I don't know
whether the best WASM methods for Schemes/Racket have yet been
attempted, and if they'd have all the support in WASM they might want.

Once WASM is all ready, JS presumably will remain in the standards and
in some use, but might actually become unpopular.  The browser
developers have their own favored non-JS languages, and also heavily
influence Web standards, so they might eventually make it so that JS can
be all but eliminated.  And then, given that technical possibility,
there's Web development culture: a hottest framework can become shunned
within a year or two (and there's also rampant age discrimination, so
many industry-savvy people truncate their older experience), so,
half-seriously, I wouldn't be too surprised if JS becomes uncool to even
admit knowing.

i don't know whether someone has yet dug into making a really performant
WASM backend for Racket, and I'd guess people might want to wait for any
interfaces/models from the Chez backend work to be about finalized first.

In the meantime, hopefully someone who needs the same WASM features such
backend for Racket will want, has eaten or will eat the beetle grubs, in
time:
https://www.mail-archive.com/racket...@googlegroups.com/msg36362.html

A little earlier context on WASM for Racket:
https://www.mail-archive.com/racket...@googlegroups.com/msg35803.html

There are pros&cons about WASM, Web standards, influences, etc., and I
suggest we want to keep cross-platform (not just Web browser, nor
primarily Web browser) focus, for long-term reasons.  But it would be
immediately very useful for many of us, if/when Racket gets a good WASM
backend.  And, given the possible disruption of JS that I speculate
about above, maybe that will also be an opportunity to bring Racket
goodness to a lot more people.

Breck Yunits

unread,
Jul 22, 2019, 4:42:09 PM7/22/19
to Racket Users
Aloha folks,

I had to miss RacketCon this year as we have a new 6 month old at home and couldn't make the trek out.

But I would love to lend my efforts to support the initiative to explore a Racket universe without parens. If folks out there are working on this, shoot me an email (bre...@gmail.com or yun...@hawaii.edu) and let me know how I can best help.

I've been working on such a research effort since 2012. I call the notation Tree Notation http://treenotation.org/. Basically what I propose is splitting things up into 2 concepts: the base Tree Notation (which is 80% similar to I-Expressions), and then languages on top of that (which is where the #lang could come in).

This syntax is less fragile (https://twitter.com/breckyunits/status/1153016840769007616) and makes 3 things much easier: program synthesis, data science, and visual programming.

I think dropping parens would make a big difference and would be a great move for "Racket2"!

-Breck

Zelphir Kaltstahl

unread,
Jul 22, 2019, 6:17:47 PM7/22/19
to Racket Users
I just want to give one thought as input to this discussion and will admit, that I did not read every (but some) of the posts above.

When I write code in Racket or Scheme, I mostly like the parentheses, as they make writing the code easy. I can very easily select a block and move it around, without introducing any syntax errors. I can also quickly see what the scope of something is, what other expression it is in. I don't get these things from languages without this many parentheses or without s-expression syntax. I need my parentheses as markers for my cursor to quickly jump around. It is the most pleasant code typing experience I've ever had. So when considering to move away from parentheses, please also consider the burden that those parentheses take away from the person writing the code. When I edit for example Python code, things are not clear when moving around code. This is worse in Python than in other languages, which at least have curly braces (but usually some other annoying deficiencies). If there was a move away from this many parentheses (read markers for my cursor), it would have to provide equal editability, for it to be attractive to me. A design based on indentation or something like that is not going to cut it for me. And what else would be used as start and end markers for expressions? Wouldn't that in essence just be another form of "parentheses", just looking different? How would any editor know, where an expression starts and ends for easy selection and moving around, if there were no such markers? So far I got no idea how that could be done without introducing loads of new constraints about how you can nest expressions into the language. So it beats me. Maybe my imagination in this area is still somewhat limited.

Just my 2c.

Breck Yunits

unread,
Jul 22, 2019, 8:10:03 PM7/22/19
to Zelphir Kaltstahl, Racket Users
Hi Zelphir,

Your concerns are absolutely warranted.

From what I've seen there is no advantage that editors can give you with parens, that they can't do better without parens, given that you've written loads of tests and done the grunt work to make that happen.

Hence, it doesn't make sense to advocate for removing parens for Racket2 until all the code and tests are written for the different editors that make the parens-less experience fantastic, and folks can compare the 2 side by side. So if folks are working toward that, please let me know as I'd love to help out.

-Breck

--
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...@googlegroups.com.

Brian Adkins

unread,
Jul 22, 2019, 9:44:12 PM7/22/19
to Racket Users
 Zelphir:

Since you mentioned you haven't read all the posts (and who could blame you, there's a lot!), I wanted to mention that the core team has stated you will continue to be able to program in #lang racket with s-expressions, and it will continue to be "well supported."

If Racket, with it's Scheme heritage, can't continue to support a Scheme-like programming experience, what that would say about language oriented programming?

As Matthew said, "Don't Panic" :)

Thanks,
Brian

Andrew Gwozdziewycz

unread,
Jul 22, 2019, 11:20:55 PM7/22/19
to Alexis King, Dexter Lagan, Racket Users
On Mon, Jul 22, 2019 at 7:15 AM Alexis King <lexi....@gmail.com> wrote:
>
> On Jul 22, 2019, at 14:16, Dexter Lagan <dexte...@gmail.com> wrote:
> To say that Racket is so defined by its syntax that it will cease to be distinguishable from any other language if it is changed is absurd, and it’s frankly insulting to all the people who have put so much effort into every part of Racket.

You have an advantage of being well invested in the Racket ecosystem
already. How do you convince someone _else_, perhaps in industry, that
Racket is interesting? It's pretty hard to say: "Look! Scribble and
Typed Racket, and contracts, and 10 other things make up this really
awesome ecosystem all running on a single VM, and they can all share
code!" Why? Because it's a _lot_ to digest, a _lot_ to try to
understand / invest in, and we live in a world where Go, a language
that effectively contains only 1970s language technology, is
dominating because of its simplicity and distinct lack of features.

On the other hand, people look at parens, think Lisp, completely
discount it because they heard "parens were really annoying to read,"
or had a bad experience in college, and then move on anyway. People
judge a book by its cover, and they judge a language by its syntax.

Growing a language community is _really, really, really hard_, and is
only going to get harder as Racket grows in complexity, and other
languages come up that have immediately familiar syntax, and a simple
to understand core. A new syntax might checkmark the first point, but
I kind of think that the #lang ecosystem, _might actually be doing a
disservice_ to Racket. It's all the traditional complaints about
macros "you have to learn the original author's DSL" mixed with "you
have to learn the original author's half broken / buggy parser /
syntax and quirks, the new semantics it adds on, _and_ the library
that goes along with it, too." Oh, and "it's all mixed in with this
other stuff written in #lang racket, with these silly parens. I AM
CONFUSED!"

Not sure how to resolve all this, and I'm sorry for lacking a central
thesis in my reply, except to say that "syntax matters" and "Racket
isn't easy" ...

--
http://www.apgwoz.com

Samuel Ainsworth

unread,
Jul 23, 2019, 3:02:46 AM7/23/19
to Racket Users
As a former Racket user but not a current member of the Racket community, I thought I might toss in my 2c. My reasons for not using Racket are essentially,
1. Parentheses make my head hurt.
2. DrRacket is slow, and VSCode integration is weak.

I've heard the "surface syntax doesn't matter" arguments before, and frankly I find them to be condescending oftentimes. "Oh, you find this parenthetical syntax confusing? That's cute." The reality is clear: syntax is the user interface to a programming language. And anyone who claims that user interfaces don't matter is simply delusional. Although parentheses have a religious following, it should be noted that members of the Racket community have an understandable selection bias on this issue. The rest of the programming world just doesn't seem to feel the same way. 

I sense that many of the parenthistas among you may discount my experience as coming from one of the "unenlightened," a lesser soul trapped in a desk job writing Java for the last 10 years who has not yet been shown the light. But in fact I was trained in Racket by one of its creators. I'm also a PhD student in computer science and an early adopter of languages. I am aware of and admire much of the research that's gone into the Racket that exists today. I see the beauty in language's foundations. I've even attended RacketCon. Still, I dread having to work in Racket. It's not lost on me that Racket is a "better" language than Python in many respects. It's just that Python offers a much, _much_ better user experience in terms of its package ecosystem, developer experience and, yes, syntax.

As an outsider it seems clear to me that if the Racket community wishes to spread the gospel of language-oriented programming, it must shed its historical attachment to parentheses. I see Pyret as being the first domino to fall in this regard.

Just my 2c,
Samuel

Dexter Lagan

unread,
Jul 23, 2019, 3:32:38 AM7/23/19
to Zelphir Kaltstahl, Racket Users
  Agreed, parentheses make manipulating code blocks a breeze. Also, I just realized I had confused Crystal with Julia in my initial rant. Made a fool of myself (again). I played with Julia when it reached 1.0 and liked the no-parens yet functional approach. It felt like a lisp in disguise, a bit like Python, but much cleaner. What I initially meant to say, apologies to Mr. King, is that a parent-less Racket2 would remind me of Julia. On the surface, at least! Crystal does have macros but that’s all it has in common with Julia and Racket.

  I did read the Honu paper and I agree: if there’s a way to transition, that’d be a very elegant one. Parentheses absolutely are a barrier of entry, and this would go a long way to make Racket less intimidating to non-lisp users. But is it worth the effort? Like the first HN comment said, ‘best way to break a good lisp is removing the parentheses’. I don’t think it’s that black&white, but there’s certainly some truth there.

Dex
--

Paulo Matos

unread,
Jul 23, 2019, 4:45:39 AM7/23/19
to racket...@googlegroups.com


On 22/07/2019 22:42, Breck Yunits wrote:
Aloha folks,

I had to miss RacketCon this year as we have a new 6 month old at home and couldn't make the trek out.

But I would love to lend my efforts to support the initiative to explore a Racket universe without parens. If folks out there are working on this, shoot me an email (bre...@gmail.com or yun...@hawaii.edu) and let me know how I can best help.

I've been working on such a research effort since 2012. I call the notation Tree Notation http://treenotation.org/. Basically what I propose is splitting things up into 2 concepts: the base Tree Notation (which is 80% similar to I-Expressions), and then languages on top of that (which is where the #lang could come in).

This syntax is less fragile (https://twitter.com/breckyunits/status/1153016840769007616) and makes 3 things much easier: program synthesis, data science, and visual programming.

I think dropping parens would make a big difference and would be a great move for "Racket2"!

Thanks for the reference to your tree notation work.

Discussion is proceeding at a breath-taking pace. You might want to enable notifications ('Watch') for https://github.com/racket/racket2-rfcs, or you might not depending if you want your like consumed by the #racket2 hash tag. ;)


--
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...@googlegroups.com.

Neil Van Dyke

unread,
Jul 23, 2019, 9:21:46 AM7/23/19
to Racket Users
Dexter Lagan wrote on 7/23/19 3:32 AM:
> Like the first HN comment said,

Currently 71 comments: https://news.ycombinator.com/item?id=20490423

FWIW, due to how the HN post was done, I don't know how representative
the comments are of professional developers.  The link was posted around
5pm California time last night, and got 92 points, but had fallen off
the front page by early this morning Boston time.  (It could reappear
this morning on the front page, and get more representative comments,
iff it organically gets voted back up as Californians wake up.  But
please no "brigade" voting, as that's against the rules, bad form, and
the admins can tell.)

Dexter Lagan

unread,
Jul 23, 2019, 9:42:45 AM7/23/19
to Neil Van Dyke, Racket Users
The second comment by slaymaker1907 is more progressive and closer to the truth no doubt. I merely meant to say that it does feel odd to take off parens off such a great scheme/lisp. But if there’s an elegant way to do it while maintaining all its power AND making it more approachable, all the better. If we could have the best of both worlds, Racket could appeal to a much wider audience.

Like others have said, it also takes time for people to understand the potential, like it took me years to warm up to the idea of lisp in general, and months before I began really seeing a difference in my projects after picking Racket up. No matter what the outcome, this is exciting.

Simply contemplating the prospect of the evolution of such a powerful abstraction tool is exciting, and inspiring.

Dex
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/6099bb78-7b2e-2749-0ed2-d19585a2f28b%40neilvandyke.org.

Thomas Dickerson

unread,
Jul 23, 2019, 12:22:11 PM7/23/19
to Racket Users
A couple thoughts, not particularly well-organized, but in a more accessible form here than just tweeting at Alexis.

In all this discussion of "parens-less LISP", I find it slightly odd that nobody has mentioned Logo yet. I'm ambivalent about surface syntax, but it's not like this is a revolutionary idea.

Since people are talking about running on different "VM" architectures, an LLVM backend would be lovely and gives WebAssembly for free.
JVM support, on the other hand, seems like a particularly poor time investment, since (1) there is no shortage of options for functional programmers, and (2) the only real advantage of running on JVM is if you can provide interoperability with the massive Java ecosystem, but that's essentially incompatible with working around the JVM's bad architectural decisions.
The elephant in the room for any Scheme running on the JVM is that (a) cross-function tail call elimination is incompatible with the security model; (b) trampolining everything is bad for performance and, more importantly, makes interoperability miserable (have fun writing all your Java code that calls Racket code in manual CPS-style); and (c) throwing everything into a massive state machine while-loop with gotos is both a static analysis nightmare and breaks the JIT optimizer due to single-method bytecode size restrictions.

As someone who loves the Racket philosophy and language-oriented-programming, but who is also very interested in building large-scale practical systems, the single biggest obstacle to me using Racket over other functional languages (mostly Scala/Dotty) for personal projects is the lack of static typing (Typed Racket feels very much like a second-class citizen in the ecosystem).
My deepest dream would be for Racket2 to have static type-checking as the default, with opt-in Rust-like affine types for programs that need precise resource management.
Essentially any other outcome is "fine, I guess".

Atlas Atlas

unread,
Jul 23, 2019, 6:18:27 PM7/23/19
to Racket Users
My personal big wish is "standard library" consistency and futures(like more extended date-time functions).

Another big wish is typed system. Typed racket looks like a BIG step forward, and gives real benefits, it is shame it have not so much support.

Another wish is more fluid transition between typed and untyped code. For now it feels painful.

Philip McGrath

unread,
Jul 23, 2019, 10:26:32 PM7/23/19
to Atlas Atlas, Racket Users
I thought one of the most compelling parts of Matthew's proposal was at around 37:41 in the video, when he said,

I've seen students in my class genuinely struggle with just the syntax.

I think it would be very useful to hear more (from Matthew or others) about the struggles people have with s-expressions, both to understand the motivations for a potential new surface syntax and to evaluate concrete design ideas.

As I've been reflecting over the last week, I realized that I have a fairly deep knowledge of my own experiences learning new languages (or at least I like to think I do …), and I know something about the experiences of friends and colleagues, but my knowledge pretty quickly drops off after that. Presumably, people who teach CS get to observe much larger samples. Those in industry with experience on-boarding new employees might likewise have useful perspectives.

If a major goal for Racket 2, and the potential syntax change in particular, is to reduce obstacles, I think it would help to understand what the obstacles are, for various groups of people.

(For example, I would speculate that people who have experience programming with Algol-like syntax may stumble at different points than new programmers, and those comfortable with notation from math class may have different expectations than those who are not—but that is just speculation. In any case, such answers wouldn't dictate a particular decision, but they could provide context to inform the decision-making process.)

-Philip


--
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...@googlegroups.com.

Mike G.

unread,
Jul 24, 2019, 7:47:45 AM7/24/19
to Racket Users
> My proposal is to pick a currently underused character (I picked '/' 30
> years ago but amost anything would do) and use it to replace the
> tail-nesting '(', and remove its corresponding ')'.
>
> Suddenly visual parenthesis-matching becomes an order of magnitude
> easier, without losing any of the expressiveness and conceptual
> significance of S-expressions.

Would you give some examples? I'm having trouble picturing this.

--
READ CAREFULLY. By accepting this material, you agree, on behalf of your
employer, to release me from all obligations and waivers arising from any
and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap,
clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and
acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with
your employer, its partners, licensors, agents and assigns, in perpetuity,
without prejudice to my ongoing rights and privileges. You further
represent that you have the authority to release me from any BOGUS
AGREEMENTS on behalf of your employer.

Ben Greenman

unread,
Jul 24, 2019, 9:43:25 AM7/24/19
to Mike G., Racket Users
On 7/24/19, Mike G. <catfish-ra...@halibut.com> wrote:
>> My proposal is to pick a currently underused character (I picked '/' 30
>> years ago but amost anything would do) and use it to replace the
>> tail-nesting '(', and remove its corresponding ')'.
>>
>> Suddenly visual parenthesis-matching becomes an order of magnitude
>> easier, without losing any of the expressiveness and conceptual
>> significance of S-expressions.
>
> Would you give some examples? I'm having trouble picturing this.
>

https://groups.google.com/d/msg/racket-users/LE66fKtcJMs/l45GwtIYDgAJ
https://groups.google.com/d/msg/racket-users/oLR_7L-g9zc/fZXaMkfQCAAJ
https://groups.google.com/d/msg/racket-users/ewWuCvbe93k/fO-fhcuWAwAJ


> --
> READ CAREFULLY. By accepting this material, you agree, on behalf of your
> employer, to release me from all obligations and waivers arising from any
> and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap,
> clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and
> acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with
> your employer, its partners, licensors, agents and assigns, in perpetuity,
> without prejudice to my ongoing rights and privileges. You further
> represent that you have the authority to release me from any BOGUS
> AGREEMENTS on behalf of your employer.
>
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/20190724114741.GB17945%40flatline.halibut.com.
>

Atlas Atlas

unread,
Jul 24, 2019, 11:23:26 AM7/24/19
to Racket Users
Prefix notation is good.
What makes difficulties is mixed notations.
There how it looks:
(Math.Sin(1\(1 + Math.Exp(x * -1))) - Math.Pow((1\Math.Log(x - (r * -1))), 3)) \ Math.Sqrt(Math.Pow(x + r, 2))
Add to this functions with more then 2 arguments.
Add to this iterations, and it will be complete hell.

In lisp, in another hand, you will get much cleaner expression, of course it is not ideal, but i don't known any better approach.


What I noticed, students often ignores how stupid computer is, and instead of setting goals for the computer they sets goals for themselves.
They try to avoid acceptance of abstract mathematical concept - what programming language is.
It is natural for human brains to avoid learning, and mismatch understanding with classification.

Students often have misunderstanding about what is function and what is function application, what is function arguments, how data flow, what is variable, and how it works.
They does not have feel of computer, of this soulless machine that crunches numbers.
They often have difficulty to understand that "defining" value means writing information to specific memory address.
So they see (define a (+1 2)) - not as command (add 1 to 2 and write result to memory cell witch refers as "a"), but as some purely syntactic statement separated from the machine. And they expect from it to act as such, what it doesn't do.

So I think basic syntax is not a problem at all.

What confuses first time is quotations especially quasiquote, but it is a trifle really.

What bothers me is that the (for) form is cumbersome, and with all the functionality it sometimes fails.
Lists have this nice functions like for-each map fold, all other collections should be subjects for this to.

So, in general, I think language need more of simple and practical constructs, and not big and complex monsters that can basically generate full syntax.


среда, 24 июля 2019 г., 5:26:32 UTC+3 пользователь Philip McGrath написал:

rocketnia

unread,
Jul 24, 2019, 9:25:18 PM7/24/19
to Racket Users


On Wednesday, July 24, 2019 at 6:43:25 AM UTC-7, Ben Greenman wrote:
On 7/24/19, Mike G. <catfish-ra...@halibut.com> wrote:
>> My proposal is to pick a currently underused character (I picked '/' 30
>> years ago but amost anything would do) and use it to replace the
>> tail-nesting '(', and remove its corresponding ')'.
>>
>> Suddenly visual parenthesis-matching becomes an order of magnitude
>> easier, without losing any of the expressiveness and conceptual
>> significance of S-expressions.
>
> Would you give some examples?  I'm having trouble picturing this.
>

https://groups.google.com/d/msg/racket-users/LE66fKtcJMs/l45GwtIYDgAJ
https://groups.google.com/d/msg/racket-users/oLR_7L-g9zc/fZXaMkfQCAAJ
https://groups.google.com/d/msg/racket-users/ewWuCvbe93k/fO-fhcuWAwAJ


I also run through several examples of where this comes in handy in the Parendown readme: https://github.com/lathe/parendown-for-racket/blob/master/README.md

-Nia

Hendrik Boom

unread,
Jul 24, 2019, 10:46:11 PM7/24/19
to Racket Users
That's a very eloquent exposition of the notation I used provately
way back in the 80's

Too bad we have to use #/ instead of / in ordinary Racket because / is
already used for division. There are a lot more #/'s then divisions in
a typical Racket program.

Redefining div to mean division isn't a really elegant solution.
Probably not orthogonal to existing code.

Another parenthesis-avoiding trick I use back then was to use
(let a whatever stuff)
to mean what Racket expresses as
(let [[a whatever]] stuff)
and then repeating /let gives the iterated sytactically non-nesting
let with fewer parentheses.
But this is incompatible with Racket.

For an expression that return multiple values I could use
(let (a b c) multiple-calue-returning-expression)

Of course I still need the extra brackets in a letrec.

-- hendrik

rocketnia

unread,
Jul 25, 2019, 7:44:05 AM7/25/19
to Racket Users


On Wednesday, July 24, 2019 at 7:46:11 PM UTC-7, Hendrik Boom wrote:
Too bad we have to use #/ instead of / in ordinary Racket because / is
already used for division.  There are a lot more #/'s then divisions in
a typical Racket program.

Redefining div to mean division isn't a really elegant solution.  
Probably not orthogonal to existing code.

It wouldn't be hard to set it up to use / as the readtable entry, and I'd like to add an option like that if that's what people think would be a better experience. I think it just means the division operator would have to be written |/| to be read as a symbol, as would any other symbols that started with the / character.



Another parenthesis-avoiding trick I use back then was to use
    (let a whatever stuff)
to mean what Racket expresses as
    (let [[a whatever]] stuff)
and then repeating /let gives the iterated sytactically non-nesting
let with fewer parentheses.
But this is incompatible with Racket.

It can always be named something else. :) A lot of my Parendown-based code uses

(w- a whatever
#/w- b whatever
#/w- c whatever
  stuff)


-Nia

Mike G.

unread,
Jul 26, 2019, 4:28:29 AM7/26/19
to Racket Users
Opinions are like belly buttons, and I'd like to show you two of mine (as in that terrible Gene Roddenberry film).

I very much like the overall goals of making Racket more consistent and more generic. They strike me as reforms of the language. I wonder if adding these features would be too far from the "spirit" of Racket.

• Make a clear distinction between mutable and immutable data

Perhaps make everything immutable except for the contents of boxes (reminiscent of ML). It would be a significant change, but I think that it would encourage functional programming and allow valuable optimizations.

• Offer "unique" data

As used in Clean and Idris, a unique value "is guaranteed to have at most one reference to it at run-time, which means that it can safely be updated in-place, reducing the need for memory allocation and garbage collection."

Sepand Meenu

unread,
Jul 26, 2019, 5:41:31 AM7/26/19
to Racket Users
I have approached Racket mainly from a computational perspective (physics and math), and I've found parentheses so far _not_ much of a distraction or annoyance. Actually, as far as the parens reduce the amount of syntactical complexity, I am in favour of them (compared to the nasty syntactical vexes in C++, or probably all Algol-descendents). I also like the language-oriented-programming philosophy of Racket which makes syntax of secondary importance. I think it is better to reduce the amount of parens needed, rather than to eliminate them altogether in favour of an Algol-like syntax. Racket2 might have even two possible syntaxes (Lisp and Algol like), but I think syntactical patterns should _not_ be the first priority of Racket2.

I think the most important task is to nurture the ecosystem of Racket: A well-defined performant 'standard library' to be used in real-world large-scale practical systems with high complexity (including tough computations, concurrency, asynchronicity, etc.) in a safe, and proveably correct manner. An expressive static typing is also one of my wishes, so that a 'refined' Typed Racket becomes part of the standard; in this case, one may learn from languages like Idris.

Easy interoperability is very important at this stage (eg. with Python). Having an LLVM backend is also very promising (unlike JVM) as Thomas Dickerson mentioned.
In general, due to my FORTRAN and C++ background, I am always very concerned about performance, and looking forward to the Racket-on-Chez project.

Lastly, perhaps Racket2 deserves a lucid Lispish name (a bit fancier than 'Racket').

Hendrik Boom

unread,
Jul 26, 2019, 4:21:38 PM7/26/19
to Racket Users
On Fri, Jul 26, 2019 at 01:28:24AM -0700, Mike G. wrote:
> Opinions are like belly buttons, and I'd like to show you two of mine (as in that terrible Gene Roddenberry film).
>
> I very much like the overall goals of making Racket more consistent and more generic. They strike me as reforms of the language. I wonder if adding these features would be too far from the "spirit" of Racket.
>
> • Make a clear distinction between mutable and immutable data
>
> Perhaps make everything immutable except for the contents of boxes (reminiscent of ML). It would be a significant change, but I think that it would encourage functional programming and allow valuable optimizations.

I'd very much like to avoid having to introduce extra references merely
to make something mutable. It costs.

>
> • Offer "unique" data
>
> As used in Clean and Idris, a unique value "is guaranteed to have at most one reference to it at run-time, which means that it can safely be updated in-place, reducing the need for memory allocation and garbage collection."

Like in Rust as well?

>
> --
> READ CAREFULLY. By accepting this material, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.
>
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/20190726082824.GB10803%40flatline.halibut.com.

Hendrik Boom

unread,
Jul 26, 2019, 4:35:45 PM7/26/19
to Racket Users
On Fri, Jul 26, 2019 at 02:41:31AM -0700, Sepand Meenu wrote:
> I have approached Racket mainly from a computational perspective (physics
> and math), and I've found parentheses so far _not_ much of a distraction or
> annoyance. Actually, as far as the parens reduce the amount of syntactical
> complexity, I am in favour of them (compared to the nasty syntactical vexes
> in C++, or probably all Algol-descendents).

a big problem with C is that some parentheses are semantically
meaningful, rather than just indicating order of operations. This is
especially confusing in notations for function types.

If it weren't for that, the parenthesis issues would be easy -- just
insert a few extra ones any time you're not sure how things are
grouped.

> I also like the
> language-oriented-programming philosophy of Racket which makes syntax of
> secondary importance. I think it is better to reduce the amount of parens
> needed, rather than to eliminate them altogether in favour of an Algol-like
> syntax. Racket2 might have even two possible syntaxes (Lisp and Algol
> like), but I think syntactical patterns should _not_ be the first priority
> of Racket2.

Racket already hs two syntaxes -- Scribble and Racket.

>
> I think the most important task is to nurture the ecosystem of Racket: A
> well-defined performant 'standard library' to be used in real-world
> large-scale practical systems with high complexity (including tough
> computations, concurrency, asynchronicity, etc.) in a safe, and proveably
> correct manner. An expressive static typing is also one of my wishes, so
> that a 'refined' Typed Racket becomes part of the standard; in this case,
> one may learn from languages like Idris.

One of the great things about Idris is its dependent types, and the
way they can be used for (constructive) formal logic. I was
experimenting with them in the 80's.

To make them into a secure logic, however, you need limitations on
recursion. You need to effectively and provably show that all
recursions terminate.
That's a tall order for a language like Lisp.

>
> Easy interoperability is very important at this stage (eg. with Python).
> Having an LLVM backend is also very promising (unlike JVM) as Thomas
> Dickerson mentioned.
> In general, due to my FORTRAN and C++ background, I am always very
> concerned about performance, and looking forward to the Racket-on-Chez
> project.

Likewise.

I like Gambit's approach of easily mixing Lisp and C. If only C
implemented tail-recursions properly and had optional garbage
collection.

Or maybe we need more low-level operations and data structures in
Racket 2. Modula 3, for example, manages to combine static
type-security, garbage collection, systems-programming-style data
structures, and an efficient code generator.

-- hendrik

Atlas Atlas

unread,
Jul 28, 2019, 6:53:18 PM7/28/19
to Racket Users
Found this interesting video on GopherCon https://www.youtube.com/watch?v=Ps3mBPcjySE
Speaker raises questions about what a program code is and how it should look

Neil Van Dyke

unread,
Jul 28, 2019, 7:35:56 PM7/28/19
to Racket Users
If anyone wants to collaborate on doing something novel related to
visual programming, I've previously done industry R&D work on that, and
am open to serious academic or commercial efforts.

Atlas Atlas wrote on 7/28/19 6:53 PM:
> Found this interesting video on GopherCon
> https://www.youtube.com/watch?v=Ps3mBPcjySE
> <https://slack-redir.net/link?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DPs3mBPcjySE&v=3>

Atlas Atlas

unread,
Jul 28, 2019, 8:03:16 PM7/28/19
to Racket Users
пятница, 26 июля 2019 г., 23:35:45 UTC+3 пользователь Hendrik Boom написал:


One of the great things about Idris is its dependent types, and the
way they can be used for (constructive) formal logic.  I was
experimenting with them in the 80's.

To make them into a secure logic, however, you need limitations on
recursion.  You need to effectively and provably show that all
recursions terminate.
That's a tall order for a language like Lisp.

Perhaps to be practical security can be sacrificed.

 
I like Gambit's approach of easily mixing Lisp and C.  If only C
implemented tail-recursions properly and had optional garbage
collection.

Or maybe we need more low-level operations and data structures in
Racket 2.  Modula 3, for example, manages to combine static
type-security, garbage collection, systems-programming-style data
structures, and an efficient code generator.

Functional structs works really bad for me, as well as classes.
The main idea of struct is to simple combine some values together, in simple way. (at leas as I see it)
Every time I try to use classes or structs I ending trashing all and use plane datatypes.
I think racket classes can be useful for complex IO objects like databases, GUI, or any UI, but I am not sure.
In some places Racket shows tremendous possibilities and high complexity, and at the same time leaves some obvious things with small attention.

About structs in regard of low level operations.
In C#, structs have option to alight data in specific order, what makes possible for very effective data packaging in some cases.
For example I can encode in struct 4 bytes as 1 unsigned integer and have access to each individual byte and to integer as whole.
This can be really handy sometimes.


In racket I just cannot think as before, in concepts of int16\32\64, this also questions for me possibility of effective algorithms realization.

Mike G.

unread,
Jul 29, 2019, 8:52:47 AM7/29/19
to Racket Users
On Fri, Jul 26, 2019 at 04:21:33PM -0400, Hendrik Boom wrote:
> On Fri, Jul 26, 2019 at 01:28:24AM -0700, Mike G. wrote:
> > ??? Make a clear distinction between mutable and immutable data
> >
> > Perhaps make everything immutable except for the contents of boxes (reminiscent of ML). It would be a significant change, but I think that it would encourage functional programming and allow valuable optimizations.
>
> I'd very much like to avoid having to introduce extra references merely
> to make something mutable. It costs.

Fair enough. Perhaps make everything immutable by default and add #:mutable and #:unique options to 'define' forms.

> > ??? Offer "unique" data
>
> Like in Rust as well?

I am not familiar with Rust.

Hendrik Boom

unread,
Jul 29, 2019, 12:15:31 PM7/29/19
to Racket Users
On Sun, Jul 28, 2019 at 05:03:16PM -0700, Atlas Atlas wrote:
> пятница, 26 июля 2019 г., 23:35:45 UTC+3 пользователь Hendrik Boom написал:
>
> >
> > One of the great things about Idris is its dependent types, and the
> > way they can be used for (constructive) formal logic. I was
> > experimenting with them in the 80's.
> >
> > To make them into a secure logic, however, you need limitations on
> > recursion. You need to effectively and provably show that all
> > recursions terminate.
> > That's a tall order for a language like Lisp.
> >
>
> Perhaps to be practical security can be sacrificed.

What really kills security is the possibility of nonterminating type
expressions.

>
>
>
> > I like Gambit's approach of easily mixing Lisp and C. If only C
> > implemented tail-recursions properly and had optional garbage
> > collection.
> >
> > Or maybe we need more low-level operations and data structures in
> > Racket 2. Modula 3, for example, manages to combine static
> > type-security, garbage collection, systems-programming-style data
> > structures, and an efficient code generator.
> >
>
> Functional structs works really bad for me, as well as classes.
> The main idea of struct is to simple combine some values together, in
> simple way. (at leas as I see it)
> Every time I try to use classes or structs I ending trashing all and use
> plane datatypes.
> I think racket classes can be useful for complex IO objects like databases,
> GUI, or any UI, but I am not sure.
> In some places Racket shows tremendous possibilities and high complexity,
> and at the same time leaves some obvious things with small attention.
>
> About structs in regard of low level operations.
> In C#, structs have option to alight data in specific order, what makes
> possible for very effective data packaging in some cases.
> For example I can encode in struct 4 bytes as 1 unsigned integer and have
> access to each individual byte and to integer as whole.
> This can be really handy sometimes.

Yes. Very handy.

-- hendrik

>
>
> In racket I just cannot think as before, in concepts of int16\32\64, this
> also questions for me possibility of effective algorithms realization.

I still think in terms of limited size integers ehrn they are useful.
I need types and operations that respect those types, have overflow
detection, etc., and you I then use them if and only if they are
appropriate for the application. When the application diesn't require
them I prefer integers that get as large as they need to be.

But in C/C++ programming on 32-bit machines, I find few cases where the
available 32-bit integers don't suffice. But I hate C's default of no
overflow detection. I like modulo-4294967296 arithmetic only when I
specifically want it.

-- hendrik

>
> --
> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/6b83862a-6f5d-438a-8a59-abffa5e6a94b%40googlegroups.com.

Atlas Atlas

unread,
Jul 29, 2019, 12:46:52 PM7/29/19
to Racket Users
There is another interesting video https://www.youtube.com/watch?v=R3zEOsh8AnQ
I think that right approach for racket2 design is think in terms of neuroscience and cognitive science.

The things whats really mater is consistency, in style, in naming, in logic.
Another important thing is right balance in abstraction levels.

Very important thing is correlation in mental model, code syntax, and code semantics.

This is another reason against infix notation and C like syntax, we made lisp look like C but semantic remains the same - this will create huge problem of code understanding.
And this is the major problem for people who learning how to write programs, they struggling with infix notation a lot already, C like syntax is a mess, and introducing it to lisp language will create untold problems with understanding.

Lisp is great for representing time flow, it doesn't mess with code execution order, so this is strong side that must be used in advantageous way.

The weak side is data structures representation, relation between data, etc, this is where things can improve.
Introduction of typed racket is good in this sense. Because it allows to create bounds between functions and data.


понедельник, 29 июля 2019 г., 1:53:18 UTC+3 пользователь Atlas Atlas написал:

George Neuner

unread,
Jul 29, 2019, 6:57:22 PM7/29/19
to racket...@googlegroups.com

On Tue, 23 Jul 2019 09:22:11 -0700 (PDT), Thomas Dickerson
<thomas_d...@alumni.brown.edu> wrote:

>Since people are talking about running on different "VM" architectures, an
>LLVM backend would be lovely and gives WebAssembly for free.

+1

>JVM support, on the other hand, seems like a particularly poor time
>investment, since (1) there is no shortage of options for functional
>programmers, and (2) the only real advantage of running on JVM is if you
>can provide interoperability with the massive Java ecosystem, but that's
>essentially incompatible with working around the JVM's bad architectural
>decisions.
>The elephant in the room for any Scheme running on the JVM is that (a)
>cross-function tail call elimination is incompatible with the security
>model; (b) trampolining everything is bad for performance and, more
>importantly, makes interoperability miserable (have fun writing all your
>Java code that calls Racket code in manual CPS-style); and (c) throwing
>everything into a massive state machine while-loop with gotos is both a
>static analysis nightmare and breaks the JIT optimizer due to single-method
>bytecode size restrictions.

Yes, JVM seems a rather poor target for a Scheme ... although Kotlin
does heroics converting tail recursion into interation to get around
(at least some of) the limitations.


OTOH, the dotNET runtime does support tail calling. F#, at least,
uses that feature even if no other dotNET languages do.

Since dotNET Core now is supported on Linux, perhaps it should be
considered as a target instead of the JVM.

YMMV,
George

George Neuner

unread,
Jul 29, 2019, 9:31:19 PM7/29/19
to racket...@googlegroups.com
Agreed. I actually liked Dylan's approach that, by default, code
should be latent typed. Then annotation could be added incrementally
to elide runtime type tests and provide compile time diagnostics.

Of course, the compiler still should be analyzing the code as best it
can to avoid including unnecessary type tests in the first place. I
don't know how well Racket fares currently in this regard, but the
good Common Lisp compilers can optimize away a lot of redundent type
tests.

And, of course, Common Lisp also allows some manual eliding of type
tests using the 'the' special operator.

Big difference was that Dylan's compiler would catch mismatched types
if they were statically known from the source, and if the compiler was
unsure about an expression containing mixed latent and manifest types,
it included the necessary runtime tests to catch problems.
OTOH, CL compilers trust the programmer and just elide any testing
when they see an annotated expression.


To me, TypedRacket feels much more like ML than like Dylan or Common
Lisp. Type inference is great - when it works. Coarse grained scope
encompassing declarations are great - when you can figure out what
they should be. Reducing busywork and the cognative load on the
programmer seems like it always should be a Good Thing. But when
inference fails and the declarations are unfathomable, and there is no
easy way around the problem save by falling back to SLOW untyped code,
then typing becomes a PITA. To my thinking, there needs to be some
middle ground - like CL's 'the' operator or Dylan's local annotations
- that can disambiguate problems on the spot.

YMMV,
George

Sam Tobin-Hochstadt

unread,
Jul 29, 2019, 9:40:40 PM7/29/19
to George Neuner, Racket Users
On Mon, Jul 29, 2019 at 9:31 PM George Neuner <gneu...@comcast.net> wrote:

> To me, TypedRacket feels much more like ML than like Dylan or Common
> Lisp. Type inference is great - when it works. Coarse grained scope
> encompassing declarations are great - when you can figure out what
> they should be. Reducing busywork and the cognative load on the
> programmer seems like it always should be a Good Thing. But when
> inference fails and the declarations are unfathomable, and there is no
> easy way around the problem save by falling back to SLOW untyped code,
> then typing becomes a PITA. To my thinking, there needs to be some
> middle ground - like CL's 'the' operator or Dylan's local annotations
> - that can disambiguate problems on the spot.

I'm not exactly sure what you're asking for here -- the CL type system
works very differently -- but local annotation is certainly possible
in Typed Racket. The `ann` form allows you to annotate any expression
at all, ie `(ann 17 Integer)`.

Sam

Atlas Atlas

unread,
Jul 30, 2019, 12:59:17 PM7/30/19
to Racket Users
вторник, 30 июля 2019 г., 4:40:40 UTC+3 пользователь Sam Tobin-Hochstadt написал:


I'm not exactly sure what you're asking for here -- the CL type system
works very differently -- but local annotation is certainly possible
in Typed Racket. The `ann` form allows you to annotate any expression
at all, ie `(ann 17 Integer)`.

Sam

The idea is you don't need to write this annotations. You can if you want.
In typed racket it is demand.
This became problem with untyped libraries, especially when they produce complex data. Or have complex macros.
Sometimes this catches you with iterations.

Simple example
(define (test-f a)
  (string-append a " okay"))

Typed-racket produces error: "Type Checker: type mismatch expected: String given: Any" when type of a can easily be inferred.
Solution is to infer type, or leave code untyped in some default way.

Another problem
require/typed - wraps code with contracts what have negative impact on performance, sometimes really bad one.
I just find current typed\racket condition unpractical.
I need for example to write my own untyped lib for using another untyped lib to simplify interfaces and make impact on performance more acceptable.

It seams what I am asking for here is unsound typing.

Another option is to force! typed racket on all levels in all libs.

I am not so big expert in theory of language design..
There is some paper I found www.ccis.northeastern.edu/home/types/publications/gradual-dead/pre-treatment.pdf on this matter, called "Is Sound Gradual Typing Dead?" from Northeastern University, it highlights some of the problems in more scientific way.

George Neuner

unread,
Jul 30, 2019, 2:23:14 PM7/30/19
to Sam Tobin-Hochstadt, Racket Users
Hi Sam,
'ann'  operand order puts the (possibly lengthy) code expression before
the (typically much shorter) type declaration.  This is the reverse of
the way Lisp does it, and, IMO, it makes 'ann' expressions harder to read.


I think Atlas nailed the crux of my issue: that Dylan and CL permit you
to add manifest typing incrementally as you desire or see need, whereas
TypedRacket requires at least some typing (of variables) right from the
very beginning and then it continues to natter at you about things you
don't necessarily care about  in the moment.

What I want is to be able to freely mix latent typed and manifest typed
code, and not worry about crossing boundaries until performance
considerations require that I do so.   That said, even though Common
Lisp is closer to what I want - I don't use it precisely because it is
Lisp ... I much prefer Scheme.

YMMV,
George

George Neuner

unread,
Jul 30, 2019, 2:39:10 PM7/30/19
to Atlas Atlas, Racket Users

On 7/30/2019 12:59 PM, Atlas Atlas wrote:
вторник, 30 июля 2019 г., 4:40:40 UTC+3 пользователь Sam Tobin-Hochstadt написал:

I'm not exactly sure what you're asking for here -- the CL type system
works very differently -- but local annotation is certainly possible
in Typed Racket. The `ann` form allows you to annotate any expression
at all, ie `(ann 17 Integer)`.

Sam

The idea is you don't need to write this annotations. You can if you want.
In typed racket it is demand.
This became problem with untyped libraries, especially when they produce complex data. Or have complex macros.
Sometimes this catches you with iterations.

Simple example
(define (test-f a)
  (string-append a " okay"))

Typed-racket produces error: "Type Checker: type mismatch expected: String given: Any" when type of a can easily be inferred.
Solution is to infer type, or leave code untyped in some default way.

Another problem
require/typed - wraps code with contracts what have negative impact on performance, sometimes really bad one.
I just find current typed\racket condition unpractical.
I need for example to write my own untyped lib for using another untyped lib to simplify interfaces and make impact on performance more acceptable.

It seams what I am asking for here is unsound typing.

Latent typing ... what #lang Racket, Scheme and Lisp, etc. provide ... is not "unsound":  the data types are known and enforced, but the enforcement is at run time, and the result is that there are code size (type tests), data size (type tags or other metadata), and performance hits due to them.  The whole point of type declarations, type inferencing and so forth is to have the types known at compile time for sooner error diagnostics, and to increase performance by eliminating unneeded runtime testing.



Another option is to force! typed racket on all levels in all libs.

I am not so big expert in theory of language design..
There is some paper I found www.ccis.northeastern.edu/home/types/publications/gradual-dead/pre-treatment.pdf on this matter, called "Is Sound Gradual Typing Dead?" from Northeastern University, it highlights some of the problems in more scientific way.


George

Yongming Shen

unread,
Aug 2, 2019, 4:49:23 AM8/2/19
to Racket Users
On the topic of making Racket 2 more appealing to new users. As a new user myself, I have one (likely uninformed) suggestion:

Design and promote a "boring core subset" that an experienced programmer can pick up easily and be as productive as when using an "ordinary programming language", without writing any macros. Macros are awesome, language-oriented programming is also awesome, if Racket 2 without them can be as appealing (minus third-party library aspects) to programmers as Python/Ruby/Go/..., then Racket 2 plus them will certainly win hearts.


On Saturday, July 20, 2019 at 2:49:13 PM UTC-4, Matthew Flatt wrote:
This message is intended as a prose form of what I said at RacketCon,
but it includes some extra explanation triggered by the discussion so
far. Where that happens, I apologize that it isn't in the form of a
more direct response in the original thread.

The Racket2 Idea
----------------

Racket's design and implementation is on solid ground, and from this
point, it can continue to evolve and improve in many ways. No matter
how Racket evolves, the community is committed to preserving what we
have achieved: today's `#lang racket` programs will run in the future,
and today's `#lang racket` modules can be used in future Racket
programs. At the same time, the current language design may be close to
a local maximum, and it's not in the nature of the Racket community to
be satisfied with a local maximum.

By starting all programs with `#lang`, we have created a path to leap
from one peak of design to a different, higher peak without sacrificing
the old one and while staying Rackety. Roughly, that's what we mean by
"Racket2". The name "Racket2" stands for some language that builds on
the current Racket technology and implementation, but that may not
directly accommodate the same bindings and expression forms that appear
in the body of a `#lang racket` module.

Although we could literally write `#lang racket2` for modules in the
new language, "Racket2" is normally understood as a placeholder for a
more distinct name. As a matter of branding, perhaps the language would
be called "Racket X" for some good X --- shortened to "X" in some
contexts --- and Racket X program would be written with `#lang X` line
at the top. Maybe the name depends on how different Racket2 turns out
to be from Racket, so it makes sense to pick a name later.

Venturing out from Racket's current peak opens a large space of
possibilities, so the first step is to agree on a set of goals to be
met by the next peak. The goals can serve as a starting point for
developing roadmap for deciding on technical details in a follow-up
process.

Possible Language Changes
-------------------------

The Racket community has long discussed possibilities for Racket2. Here
are a few potential changes from the wish list:

* Rename functions to make the conventions more uniform, and make
  better use of keyword arguments to reduce names and increase
  consistency.

* Change structures types to have more or fewer features.

* Use generic datatypes (such as streams) pervasively, instead of
  writing code that expects a particular concrete representation (such
  as lists).

* Make strings immutable by default (e.g., result of `format` or
  `string-append`).

* Adjust the semantics of common syntax forms, such as raising an error
  on fall-through for `cond` or `match`, and change the meaning of some
  primitives, such as making `integer?` mean "exact integer".

* Make pattern matching more pervasive and available by default.

* Change module, evaluation, and loading callbacks (e.g., protocol for
  `current-module-name-resolver`) to improve errors and extensibility.

More changes have been suggested, and no doubt many other changes would
make sense. As a first cut, to synthesize some principles from these
ideas --- as a way of selecting which wishes should be tackled and how
--- the current wish list might be organized and summarized by two
overall goals:

* Make the language more consistent

  Consistency means making terminology and binding names more
  consistent, and it means unifying related syntactic constructs. For
  example, the `define` and `define-syntax` forms should perhaps be
  less syntactically distinct. Similarly, pattern matching and syntax
  matching seem closely related and could benefit from using the same
  pattern language. Also, pattern matching should be pervasively
  available among binding forms. Etc.

* Make the language constructs more generic

  In many ways, the current Racket language and libraries encourage
  the use of concrete data structures instead of abstract datatypes.
  The `map` function works on lists, for example, not arbitrary
  streams, and even `for` demands concrete declarations like `in-list`
  to provide the best performance. Refining the capabilities of
  structures and providing a smoother path among dictionaries,
  structures, and objects may also fit into this category.

There seems to be a widespread agreement/assumption among the community
that we could one day switch all the general documentation, such as the
Racket Guide, to use `#lang X`. That would preserve the ability to run
`#lang racket` modules and import them into `#lang X` modules, but it
would effectively relegate `#lang racket` to a kind of compatibility
mode. The Racket community has already done this a couple of times,
moving from `(module m mzscheme ...)` to `#lang scheme` to `#lang
racket`, and some of the Racket distribution is still implemented in
`#lang scheme`. After another switch, the constructs for `racket` would
remain documented and maintained, in the same way as the constructs for
`mzscheme` and `scheme` remain documented and maintained, but `racket`
and its documentation would fade to the background.

Based on the wish list, the scale of changes would likely be much
larger than in previous transitions. There will many more changes to
names and changes to the meaning of identifiers that are spell the
same way. The scale of those changes doesn't seem to worry the Racket
community.

Surface Syntax
--------------

You won't find a wish for significant changes the Racket surface
syntax anywhere on the Racket2 wish list. Nevertheless, I've suggested
tacking it on.

Why now?

If we decide that a change to the surface syntax is a good move, it
would make sense to try that at the same time as overhauling names and
syntactic forms. Pattern matching, for example, seems like a place
where syntactic flexibility can help. Besides letting different kinds
of changes reinforce each other, we'd revise all of the documentation
just once instead of twice.

There are downsides to tackling both semantic and syntactic changes at
once. If a change to surface syntax is on the table, though, then we
should at least consider bundling the efforts.

Why at all?

Partly, I believe that a syntax with infix operators, fewer
parentheses, etc., would be better. That's a matter of opinion, but at
least it's an opinion backed by enough experience with parentheses
that it can't be written off as uninformed. More significantly,
parentheses are certainly an obstacle for some potential users of
Racket. Given the fact of that obstacle, it's my opinion that we
should try to remove or reduce the obstacle.

Syntax is not just an obstacle for potential users of Racket as a
programming language, but also for potential users of Racket as a
programming-language programming language. The idea of
language-oriented programming (LOP) doesn't apply only to languages
with parentheses, and we need to demonstrate that. Although we already
have tools for parsing non-parenthesis syntax into parentheses and
letting macros take over from there, that's not the kind of smooth
path from simple extension to full language building that we have in
the S-expression world. While these research problems may not be
forefront on the minds of all Racket users, keep in mind that Racket
exists because of research and remains supported almost entirely by
research.

Adjusting the syntax of Racket to accommodate more users could be
characterized as an effort to make Racket more popular. I don't think
it's helpful to characterize the idea that way. Granted, any effort to
reduce barriers is effectively an effort to make Racket more popular.
In that sense, our efforts on Racket's documentation were an attempt
to make Racket more popular. The work we put into building the Racket
distribution and making it easy to install is an attempt to make
Racket more popular. Creating the package system was an attempt to
make Racket more popular. All strictly true, I suppose, but the
characterization feels wrong. There's a difference between reducing
technical barriers for users of various stripes versus marketing to
make a product more popular. When I point out that parentheses can be
a deal-breaker to people outside the Racket community, I do not have
in mind that we just need a better marketing message; I have in mind
that the obstacle is real, it affects many people, and we should
address it.

Who?

From a community perspective, the rub is that the "many people" for
Racket syntax is a barrier are mostly people outside the community.
It's fair to ask who would benefit. It's difficult to ask a community
to tackle a problem whose solution targets a different community.

There's also a question of who really needs to participate in the
development of a new surface syntax. That part of the project could
take place in its own `#lang` and stay out of the way of `#lang
racket` users for years. As a practical matter, that will certainly
happen, even if we think that that new syntax will eventually take
over. We've already done some side experiments in separate `#lang`s,
though, and now is a time to check whether there is community buy-in
and participation for a more ambitious effort.

How?

Parentheses are definitely useful for Racket-style language-oriented
programming, and parentheses certainly helped Racket's macro system
get to where it is now. There would be no point to a change in syntax
if it meant interfering with Racket's main capability. Although a
macro system without parentheses is a difficult problem, I think we
know how to solve it.

I have in mind "Honu: Syntactic Extension for Algebraic Notation
through Enforestation", GPCE 2012. It shows how we can bridge the
relatively linear structure of non-() programs to the tree structure
of S-expressions. Specifically, the bridge is called "enforestation".
It sits roughly between the reader and the expander, but enforestation
needs to be interleaved with expansion to get the level of
expressiveness that Racketeers would expect.

You may worry that I'm putting a lot of faith in one expriment and
paper --- and a paper written by a PhD student and me, at that. You
may be right. I have only my intuition that enforestation is the key
to the problem of non-() syntax and extensibility. The details in the
paper don't seem to me exactly right for Racket2, but it's a big first
step toward addressing the problem, and it already seems sufficient.
Others may have figured out even more. I wouldn't blame anyone for
concluding that the difficulty of the task is too large for the size
of the obstacle that it removes, but that's not how I size things up.

The gap between 2012 and now reflects that Racket had more problems
(in my view) than just syntax, and for various reasons, those other
problems took precedence for my own work. This also explains my answer
to the "why now" question. The other problems seem to be resolved or
well on the way, and so syntax seems like the next thing to tackle.

How to Proceed
--------------

Ideally, we would first decide on whether we want to try changing
surface syntax ever. Then, only if we have enough consensus that it's
worth a try, we could move on to setting overall goals and picking a
roadmap. Finally, if the planing of the roadmap succeeds, we could
follow it while getting into the details.

Unfortunately, it doesn't work like that. We need concrete examples to
discuss the possibility of changing syntax, potential roadmaps to see
whether there's anywhere we want to go, and so on. Some of the
discussion will necessarily put a cart before a horse. Delving into
some details may incorrectly give the impression that prerequisites
are a foregone conclusion. We've seen all of that already, starting
with my attempt to open up the discussion in the middle of RacketCon
and probably continuing with this message. Perhaps we can just accept
that this is all okay in the spirit of working together.

I originally thought that we should have a more specific process in
place for discussion at this point, but I think I've been proved
wrong. Let's just discuss, for now. I'll be posting more myself.

Hendrik Boom

unread,
Aug 2, 2019, 6:44:41 AM8/2/19
to Racket Users
On Fri, Aug 02, 2019 at 01:49:23AM -0700, Yongming Shen wrote:
> On the topic of making Racket 2 more appealing to new users. As a new user
> myself, I have one (likely uninformed) suggestion:
>
> Design and promote a "boring core subset" that an experienced programmer
> can pick up easily and be as productive as when using an "ordinary
> programming language", without writing any macros. Macros are awesome,
> language-oriented programming is also awesome, if Racket 2 without them can
> be as appealing (minus third-party library aspects) to programmers as
> Python/Ruby/Go/..., then Racket 2 plus them will certainly win hearts.

If you ignore the ability to define macros, isn't Racket already more
or less what you propose? Except, perhaps, for all the parentheses?

-- hendrik

Yongming Shen

unread,
Aug 2, 2019, 6:46:28 PM8/2/19
to Racket Users
I don't mind the parentheses. But I think Racket is kind of bloated and fragmented (I'm new to Racket, but this is the impression that I got so far). There are a lot of forms that are doing similar but slightly different things (e.g., the many let forms), and features that are not well integrated (the OO system comes to mind). I think it is amazing that all the features and forms that Racket provides can be reduced to a small set of core forms, but programmers don't write programs in the core forms, and I think it is the responsibility of the language designer to carefully craft a small set of forms and features that a programmer can use directly to solve most of the "ordinary programming problems" productively. Otherwise, personal extensions will flourish, and the ecosystem will be unnecessarily fragmented.
Reply all
Reply to author
Forward
0 new messages