colon keywords

112 views
Skip to first unread message

Neil Van Dyke

unread,
Sep 19, 2018, 4:56:09 AM9/19/18
to Racket-Users List
Currently, in main Racket reader, `#:` starts a keyword, as in `#:foo`.

Who on this email list would also like (or not like) `:` to start a
keyword, as in `:foo`?

And, if you want the reader to also support `:foo`, would you want the
writer to default to writing `:foo` rather than `#:foo` (and how much
would you want that)?  And in the documentation?

(I've wanted "colon keywords" since keywords were first added to Racket,
but have been dutifully enduring the "hash-colon", rather than make
anyone who uses my open source packages depend on an additional package
for my own variant of `#lang racket/base`.  But, after many years of
this, I still dislike typing and looking at `#:`.  I know some people
don't understand why anyone cares (or suspect bikeshedding), but I get
the impression that this is getting into cog-sci differences between
individual programmers.  Maybe one way to look at it is a vague
"programmer preference", like light vs. dark screen background, rather
than try to argue that no one should want to do it that way.  Then the
question might be: how popular is this "colon keyword" programmer
preference?  Which is why I'm asking the email list.)

George Neuner

unread,
Sep 19, 2018, 5:26:44 AM9/19/18
to Neil Van Dyke, Racket-Users List
I have a vague memory of this being discussed before.  Ah, yes ... in 2015.
https://groups.google.com/forum/#!msg/racket-users/3vOTC1FbieA/5SUP4wzKCAAJ;context-place=forum/racket-users

Much of my comment then still stands so I'll repeat it here: (more below)


On Sat, 21 Nov 2015 18:06:29 -0500, George Neuner wrote:
>> I actually prefer the #: syntax, but what I would like is support for
>> "existence" keywords - i.e. keywords with no argument - where the only
>> thing you care about is whether or not the keyword was provided.
>>
>> Obviously, this can be done using a "rest" argument and symbols, but
>> the #: syntax draws attention that other symbols do not because
>> DrRacket, at least by default, colors keywords differently from other
>> symbols.
>>
>> Although the keyword syntax coloring still works with a tick before a
>> symbol that looks like a keyword, having to remember the tick is a
>> PITA when you are thinking of the symbol as a keyword.  If you forget
>> it, you get a  nasty
>>     "application: missing argument expression after keyword"
>> error.
>>
>>
>> How much trouble would it cause to allow naked keywords and provide a
>> predicate based on their name?  E.g.,
>>
>> (define ( test blah #:opt #:req reqvalue )
>>    :
>>   (when #:opt?  ... )
>>    :
>>   )
>>
>> (test #:req 3)
>> (test #:req 42 #:opt)
>>
>> Or even something like  (define ( test blah #:opt [] #:req req ) which
>> makes it more obvious that the keyword is only there to be tested?


Since then my opinion has altered slightly.  The #: syntax is less
important than syntax coloring to call attention to the keyword. However
the desire for purely symbolic "existence" keywords remains.

YMMV,
George

Neil Van Dyke

unread,
Sep 19, 2018, 6:11:12 AM9/19/18
to Racket-Users List
I recall multiple discussions about colon keywords over the many years,
but (it's 5am) temporarily forgot that Jay did a poll 3 years ago.

Jay's results summary quoted and linked below.

I think 3 years means it's time to go from these results, to either
changing Racket, or expecting "preference #langs" to become more of a
thing.  (Again, from a software engineering perspective, I'd discourage
"preference #langs"; but, from a love of programming perspective, I'd
understand.)


Jay McCarthy <jay.mc...@gmail.com> wrote on Thu, 22 Oct 2015 13:43:50 -0400:
> It has been a little more than a week and we've stopped getting results.
>
> The full results should be publicly available. Here is a summary:
>
> https://docs.google.com/forms/d/1HSwtxLhz5HWGMJjMXaO8LQyHJsdMkGbBlRa4fU7Sa34/viewanalytics
>
> and here is the raw data:
>
> https://docs.google.com/spreadsheets/d/1rZNNGwupMZTybxKRhukLdgA8VIA8oPlQ7nPk8Gv52Es/edit#gid=348615477
>
> My interpretation of the data is as follows:
> - The #:keyword syntax is liked fine with a rating of 5.67
> - The :keyword syntax is more loved with a rating of 6.9
> - But change is not popular, average of 5.1 with high standard deviation
> - People that really like #:keyword do not want a change and do not
> like :keyword
> - People that really like :keyword want a change
>
> I am genuinely surprised :keyword saw so much support and that change
> was so attractive to people.
>
> Naturally whenever you do stuff like this, you want to ask more
> questions, like what about keyword:, what about supporting both, etc.
>
> Jay
https://groups.google.com/d/msg/racket-users/3vOTC1FbieA/UsifvfWtBgAJ

Christopher Lemmer Webber

unread,
Sep 19, 2018, 8:15:36 AM9/19/18
to Neil Van Dyke, Racket-Users List
I am wary of this. I really don't have a strong preference either way,
my suspicion is it's mostly "what did you become famliar with initially"
kind of thing. :keyword is more Common Lisp'ish, #:keyword matches
other Schemes I've used.

But:
- I'd rather not have *two* keyword syntaxes in Racket at the same
time.
- But removing #: from the language would break tons of packages.
- Maybe if #lang racket2 ever happened that would be a good place for
this, and the ability to have multiple #langs allows us to survive
an upgrade easier than say, the Python 2 to 3 upgrade was (which I
was in the trenches for, and was a decade long headache).
Let's try to avoid breaking things that exist currently, anyway.
- It's such a small cosmetic change I don't see why it's worth it.
If it bothers you a lot, there's a #lang path.

My $.02,
- cwebb

Laurent

unread,
Sep 19, 2018, 8:29:50 AM9/19/18
to Christopher Lemmer Webber, Neil Van Dyke, racket-users@googlegroups.com List
I don't mind `#:`, but I'd prefer to write `[#:foo 5]` rather than `#:foo [foo 5]`, that is, I don't like the repetition of the name (I first came to Racket precisely to avoid repeating code).

When I expressed that a few years ago, I was told it would be unlikely to change in the future though, which is perfectly understandable given how deeply this goes.



--
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.
For more options, visit https://groups.google.com/d/optout.

George Neuner

unread,
Sep 19, 2018, 10:33:12 AM9/19/18
to Laurent, racket-users@googlegroups.com List

On 9/19/2018 8:29 AM, Laurent wrote:
> I don't mind `#:`, but I'd prefer to write `[#:foo 5]` rather than
> `#:foo [foo 5]`, that is, I don't like the repetition of the name (I
> first came to Racket precisely to avoid repeating code).
>
> When I expressed that a few years ago, I was told it would be unlikely
> to change in the future though, which is perfectly understandable
> given how deeply this goes.

make-keyword-procedure  helps with that specific complaint - you don't
need to introduce a formal for the keyword value.  But it doesn't help
with my complaint (symbolic "existence" keywords) because Racket
requires a keyword to have an accompanying value in the argument list.

George

David Storrs

unread,
Sep 19, 2018, 11:10:56 AM9/19/18
to Neil Van Dyke, Racket-Users List
For whatever it's worth, I don't care about this issue for it's own sake and would prefer that it not be implemented because (a) I would see it as a waste of resources, (b) it would have unpredictable effects on existing code, and (c) it means one more thing to keep in mind when reading other people's code.

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

Alexis King

unread,
Sep 19, 2018, 11:31:20 AM9/19/18
to Neil Van Dyke, Racket-Users List
I’m surprised this hasn’t been discussed yet: Alex Knauth has a set of meta-languages that add support for :kw or kw: syntax for keywords to arbitrary #langs (assuming they use readtables).

http://docs.racket-lang.org/colon-kw/index.html

Whether or not actually using these meta-languages is a good idea is left up to the reader. :)

George Neuner

unread,
Sep 19, 2018, 12:01:33 PM9/19/18
to Alexis King, racket users

On 9/19/2018 11:31 AM, Alexis King wrote:
> I’m surprised this hasn’t been discussed yet:

I'm not.  Racket (and contributions) has so many nifty features that it
could take years to browse all the documentation.

On a related topic, the persistent problem with keyword search engines
is: if you don't know the the right question(s) to ask - or
alternatively, know the right way to ask your question(s) - then you are
not very likely to find relevant answers.  DWIM anyone?


> Alex Knauth has a set of meta-languages that add support for :kw or kw: syntax for keywords to arbitrary #langs (assuming they use readtables).
>
> http://docs.racket-lang.org/colon-kw/index.html
>
> Whether or not actually using these meta-languages is a good idea is left up to the reader. :)

George

Neil Van Dyke

unread,
Sep 19, 2018, 2:52:51 PM9/19/18
to Racket-Users List
Christopher Lemmer Webber wrote on 9/19/18 8:15 AM:
> #:keyword matches other Schemes I've used.

If other Scheme precedent is a factor... Before Racket (PLT Scheme) did
it the way it does, I only recall Guile supporting that way.  I recall
every other implementation doing it differently than that way.  From the
SRFI discussion (which was the interim IETF RFC-ish mechanism for
evolving past R5RS, before R6RS):
https://srfi.schemers.org/srfi-88/mail-archive/msg00015.html

And Guile already supported other keywords formats simultaneously,
somewhat like I'm proposing, though my proposal is simpler.

> my suspicion is it's mostly "what did you become famliar with initially" kind of thing.

That's often the case in language preferences, especially among people
who don't know many.

There also seem to be cognitive and aesthetic differences between
individuals.

In the case of `#:` keywords, for me, it's a human factors engineering
visual overprominence (e.g., `#:` makes keyword arguments more prominent
than even variable bindings or a syntax extension use), an aesthetic
annoyance (a little ugly, unlike the elegant conventional s-expression
syntax that makes up most of Racket), and a rapid keyboarding annoyance
(having to type 2 shifted characters instead of 1, for no good reason).

(The Colonistas will be silenced no longer!  We yearn to be free of
Octothorpian oppression!)

Tomasz Rola

unread,
Sep 23, 2018, 12:50:04 PM9/23/18
to Racket-Users List, Neil Van Dyke, Tomasz Rola
On Wed, Sep 19, 2018 at 04:56:05AM -0400, Neil Van Dyke wrote:
> Currently, in main Racket reader, `#:` starts a keyword, as in `#:foo`.
>
> Who on this email list would also like (or not like) `:` to start a
> keyword, as in `:foo`?

Neil,

Thanks a lot for asking. I would like to have colon keywords, straight,
i.e. ":keyword" rather than "#:keyword".

> And, if you want the reader to also support `:foo`, would you want
> the writer to default to writing `:foo` rather than `#:foo` (and how
> much would you want that)?  And in the documentation?

I would like to go for :keyword everywhere, if possible.

> (I've wanted "colon keywords" since keywords were first added to
> Racket, but have been dutifully enduring the "hash-colon", rather
> than make anyone who uses my open source packages depend on an
> additional package for my own variant of `#lang racket/base`.  But,
> after many years of this, I still dislike typing and looking at
> `#:`.  I know some people don't understand why anyone cares (or
> suspect bikeshedding), but I get the impression that this is getting
> into cog-sci differences between individual programmers. 

Like you, I "suffer" but if it could be reduced a bit, then the world
could maybe become a better place, or something.

> Maybe one way to look at it is a vague "programmer preference", like
> light vs. dark screen background, rather than try to argue that no
> one should

I believe those indifferent to light will begin noticing it if they
keep programming (or just staring at the screen) whole days while
entering their fourties.

> want to do it that way.  Then the question might be: how popular is
> this "colon keyword" programmer preference?  Which is why I'm asking
> the email list.)

I happen to read/write code in various LISP flavours (but I am not as
sophistocated as such statement would imply). :keywords are what other
LISPs seem to be doing (Common Lisp, Elisp, Gauche the Scheme dialect
- this is what I have spotted so far). I think reusing some
s-expressions between all those could definitely become easier with
:keywords.

--
Regards,
Tomasz Rola

--
** A C programmer asked whether computer had Buddha's nature. **
** As the answer, master did "rm -rif" on the programmer's home **
** directory. And then the C programmer became enlightened... **
** **
** Tomasz Rola mailto:tomas...@bigfoot.com **

Neil Van Dyke

unread,
Sep 23, 2018, 1:41:29 PM9/23/18
to Laurent, Racket-Users List
Laurent wrote on 9/19/18 8:29 AM:
> I don't mind `#:`, but I'd prefer to write `[#:foo 5]` rather than
> `#:foo [foo 5]`, that is, I don't like the repetition of the name (I
> first came to Racket precisely to avoid repeating code).

Now that you mention it, I realize that I'd probably use that myself
(since it already fits my naming conventions, and would avoid a lot of
clutter).  And the syntax you propose doesn't seem to break anything,
and seems unlikely to conflict in the future.  My one problem with it is
that I try to avoid introducing bindings to an identifier that doesn't
appear as a lexeme in the source (like Racket already does for struct
definition forms accessors&mutators), but this might be another
reasonable tradeoff, and it's much smaller than the `define-struct` one was.

So... What do people think of a `#lang` that is mostly `racket/base`,
but with a few additions, maybe something like the following?

* Symbols that start with `:` (and aren't `:` exactly) read as keywords.

* The popular `lambda`-ish and `define`-ish forms add support for the

* The `let`-ish forms add terse support for frequent multiple-value LHS
(without burdening single-value LHS, nor increasing rightward drift).

* The `struct` definition forms also generate constructors with keyword
arguments for fields.

* Support for embedded documentation for pro (ideally, also `provide`d
by the module for both Scribble complete document generation and perhaps
online help fragments), together with shorthand for define+provide+doc
(and maybe contracts too).

* Support for terse embedded unit tests (e.g., you don't have to type
out `(module+ test` all the time), and some standard lightweight unit
test definitions (maybe not RackUnit nor Overeasy, since we can improve
upon both) that work with the Racket package CI stuff.

* Maybe have a small language tweak to try to encourage people to know
what they're doing before they use `eval`, and/or to make the use of
such a powerful and oft-misused feature by a module more prominent.

* Look at making the "info.rkt" metadata optionally embeddable in
single-source-file packages.  I can talk more about why one might want
this sometime, but one of the big cases involves lightweight and
interface-oriented modularity practices by default for well-engineered
closed-source systems, and low-friction selective open sourcing.  (I
think this also requires tweaking more than just the `#lang` itself.)

* Look at richer version/compatibility specification and confidence for
package dependencies, and possibly also add in simultaneous multiple
version support and/or other ways of providing backward compatibility.

* Tolerate square brackets, unless and until we someday find a much
better use for them (replacing `send` isn't good enough, but maybe
someday for vectors/arrays in dense numerical work). :)

These particular examples are off-the-cuff, and I rattled them mainly
out to suggest a degree of tweaks, not an exact set.  I'm sure there are
many opinions on the details, by people who love programming, and that
people will also have base language itches they've been wanting to
scratch for a while.  I don't know offhand how difficult it would be to
find an optimal compromise, but maybe BDFL isn't necessary.

Neil Van Dyke

unread,
Sep 23, 2018, 1:44:11 PM9/23/18
to Laurent, Racket-Users List

> * The popular `lambda`-ish and `define`-ish forms add support for

...what Laurent said.

Hendrik Boom

unread,
Sep 23, 2018, 2:55:07 PM9/23/18
to Racket-Users List
On Sun, Sep 23, 2018 at 01:41:25PM -0400, Neil Van Dyke wrote:
>
> * The `let`-ish forms add terse support for frequent multiple-value LHS
> (without burdening single-value LHS, nor increasing rightward drift).

The notation I've found useful against rightward drift in a Lispish
language is this:

Instead of writing s-expressions like (a b c (d e f ( g h i)))
where the letters stand for arbitrary s-expressions
wrote them as (a b c / d e f /g h i), or in multilint format
(a c b
( d e f
( g h i
)))

I could write
( a b c
/ d e f
/ g h i
)

Of course, in Racket you'd have to find another symbol than / because
it's already taken

Aking advantage of this, I also had a nonrecursive let:

( let a b
/ let c d
/ let e f
/ g a c e
)

-- hendrik

Jos Koot

unread,
Sep 23, 2018, 3:38:27 PM9/23/18
to racket users
Forgot to include the users group.

-----Original Message-----
From: Jos Koot [mailto:jos....@gmail.com]
Sent: 23 September 2018 21:37
To: 'Tomasz Rola'
Subject: RE: [racket-users] colon keywords

MHO, adhere to #:foo,
because :foo is a permitted identifier.
I prefer a clear distinction between keywords and identifiers.
Just like the sharp sign is used in many other output.
Jos

Eric Griffis

unread,
Sep 23, 2018, 10:08:06 PM9/23/18
to Jos Koot, racket users
Thanks for the crisp explanation, Jos. This is exactly my concern.

Eric


--
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.

Laurent

unread,
Sep 24, 2018, 6:19:25 AM9/24/18
to ded...@gmail.com, Jos Koot, racket-users@googlegroups.com List
Same here, I've grown happy with the #:keyword notation because it is a reader thing, not a symbol.

The other nice option would be like Python and others to make procedure implicitly take dictionaries to allow choosing at each call site between position-based and name-based argument passing for each argument. I guess if the dictionary's arguments of the caller is accessible at compile time, it should be feasible to lose nothing in terms of run-time speed. Dictionary building and passing at run-time would likely be slower though.

Laurent

unread,
Sep 24, 2018, 6:47:30 AM9/24/18
to Neil Van Dyke, racket-users@googlegroups.com List
On Sun, Sep 23, 2018 at 6:41 PM Neil Van Dyke <ne...@neilvandyke.org> wrote:
Laurent wrote on 9/19/18 8:29 AM:
> I don't mind `#:`, but I'd prefer to write `[#:foo 5]` rather than
> `#:foo [foo 5]`, that is, I don't like the repetition of the name (I
> first came to Racket precisely to avoid repeating code).

[...] 
So... What do people think of a `#lang` that is mostly `racket/base`,
but with a few additions, maybe something like the following?

* Symbols that start with `:` (and aren't `:` exactly) read as keywords.

-1, I'm fine with reader syntax '#'.
 
* The popular `lambda`-ish and `define`-ish forms add support for [what Laurent said above]

+1

* The `let`-ish forms add terse support for frequent multiple-value LHS
(without burdening single-value LHS, nor increasing rightward drift).

+1, yes please.

* The `struct` definition forms also generate constructors with keyword
arguments for fields.

+1, or by symbol (but keyword is easier to check for correctness at compile time maybe).
 
* Support for embedded documentation for pro (ideally, also `provide`d
by the module for both Scribble complete document generation and perhaps
online help fragments), together with shorthand for define+provide+doc
(and maybe contracts too).

+1, I think.
 
* Support for terse embedded unit tests (e.g., you don't have to type
out `(module+ test` all the time), and some standard lightweight unit
test definitions (maybe not RackUnit nor Overeasy, since we can improve
upon both) that work with the Racket package CI stuff.

Dunno, maybe.
 
* Maybe have a small language tweak to try to encourage people to know
what they're doing before they use `eval`, and/or to make the use of
such a powerful and oft-misused feature by a module more prominent.

That might just need a documentation tweak, like a margin note saying "Warning: Very often people think of using eval when better, faster and safer solution are available but depend on the case. Ask for help on the mailing list <...@...> if your unsure."?
 
* Look at making the "info.rkt" metadata optionally embeddable in
single-source-file packages.  I can talk more about why one might want
this sometime, but one of the big cases involves lightweight and
interface-oriented modularity practices by default for well-engineered
closed-source systems, and low-friction selective open sourcing.  (I
think this also requires tweaking more than just the `#lang` itself.)

Maybe as a submodule?
I'd be happy with a one-file package; I firmly believe in the path-of-least-resistance philosophy (allow for quick and dirty first, but equally importantly also to easily gradually improve).
 
* Look at richer version/compatibility specification and confidence for
package dependencies, and possibly also add in simultaneous multiple
version support and/or other ways of providing backward compatibility.

Dunno, maybe. There are pros and cons, in terms of complexity. 
 
* Tolerate square brackets, unless and until we someday find a much
better use for them (replacing `send` isn't good enough, but maybe
someday for vectors/arrays in dense numerical work). :)

Not sure what you mean. I use square brackets a lot in `let`, `cond` and friends. That makes reading much easier to me.

For vectors I sometimes use `@` or `@?` for vector-ref,  `!` or `@!` for vector-set!, and `@?!` for a vector-update!:
(@?! my-vector index λ(x)(+ (* 2 x) 3))
is even simpler than
my_vector[index] = 2 * my_vector[index]) + 3

Maybe @ variant should be generics though.

While we're on the wish-list:

* Use '_'  in place of '-' for word symbol appending. I've grown unfond of '-' word separators, and I heretically prefer '_' because I find it visually easier to group words with '_', and '-' also clashes with the minus sign, which makes it harder to read calculations. But I usually don't use '_' to avoid being frown upon too much :-/

 

Hendrik Boom

unread,
Sep 24, 2018, 10:54:49 AM9/24/18
to racket-users@googlegroups.com List
On Mon, Sep 24, 2018 at 11:19:11AM +0100, Laurent wrote:
> Same here, I've grown happy with the #:keyword notation because it is a
> reader thing, not a symbol.
>
> The other nice option would be like Python and others to make procedure
> implicitly take dictionaries to allow choosing at each call site between
> position-based and name-based argument passing for each argument. I guess
> if the dictionary's arguments of the caller is accessible at compile time,
> it should be feasible to lose nothing in terms of run-time speed.
> Dictionary building and passing at run-time would likely be slower though.

That sounds something that would fit conceptually into typed racket.

-- hendrik
Reply all
Reply to author
Forward
0 new messages