Fun fact: Anything between a pair of \|
is a valid identifier. For instance the following is a valid program that prints 42
: (define \| () [] {} `'," \ \| 42)
\| () [] {} `'," \ \|
Not that I recommend doing this.
I also don’t recommend submitting bug reports about any possible syntax-highlighting weirdness in racket-mode. :grin:
ah I see
Perhaps this is just syntax salad, but is an atom a value?
an “atom” isn’t a term of art in Racket.
Does Racket just say “values” and “types”?
“type” isn’t really a term of art, either (unless you’re talking about Typed Racket or something like that), though it is used (unlike “atom”), so people would know what you mean.
how about,
Racket has values that can be categorized into datatypes
and Racket evaluation involves “expressions”
which are lists of either values, or more expressions
@slack1 An atom is just an “indivisible” s-expression component. For a language with s-expression syntax, the parser decides exactly what that means.
Yeah I decided to discard that term since Racket doesn’t use it, I was looking at some wrong slides I guess
I know it’s a bit pedantic, but I wanted to get my phrasing right
It’s perfectly fine to use the word “atom” when speaking in the abstract.
I don’t think Racketeers have a precise definition of the term, so I don’t think it’s a good term to use (there are plenty of better ones to use)
Would you say the same about the term “s-expression”?
Is that the same thing as an expression?
(with nested lists?)
@dedbox “indivisible” is a bit weird, though — does it include hash tables or prefab structs?
I understood it to mean that when I have an expression like (foo bar)
, then the reader doesn’t separate f o o
, but considers it “one thing”
(for atom)
ok, an s-expresion can defined recursively as an atom or any pair of s-expressions.
so an atom is any non-pair bit of syntax
is a vector an atom?
@samth “indivisible” would not include hash tables or prefab structs because those are Racket constructs and not bits of syntax. Their s-expression representations are certainly not atoms.
You can absolutely have hash tables or prefab structs in syntax.
I think this is why @lexi.lambda said that it’s not as clear a term as you’d want
I think Racketeers have a well-agreed upon definition of what an s-expression is, and the technical definition is essentially anything that can be marshalled to bytecode (which happens to include vectors, hash tables, prefab structs, regexes, and paths, by the way). I don’t think Racketeers agree on what an atom is, so I would recommend avoiding it.
I think we’re conflating the concept of an s-expression with how Racket implements them.
I don’t think an s-expression is well-defined outside of a particular context. I’m only giving recommendations about using terms within the Racket community if you want people to understand you.
yes, I’m trying to figure out canonical language as well
You can certainly always prefix a comment by saying something like “I want to recognize atomic values, which in my case are strings, symbols, numbers, and booleans…” and then go onto describe some problem by using “atom” as an abbreviation. But people don’t agree on such a standard, so using the word “atom” on its own without any such clarification will almost certainly lead to multiple interpretations of your statement, which I generally consider an unwanted outcome.
How about Racket is a language of expressions, which are lists of values or more expressions
If there are more expressions inside, then those can ultimately be reduced to values
Values can be categorized into datatypes, such as numbers, booleans, etc.
Given that lists are themselves values, I don’t think that makes too much sense. I think it makes sense to distinguish between programs and their runtimes. A program is made out of expressions and syntactic forms, and expressions are evaluated to produce values. There are names that describe certain values, like “number”, “string”, “boolean”, “list”, “vector”, and many more. Racket expressions are themselves made out of syntax objects, which in turn happen to also be made out of Racket values, but ignoring quote
, this correspondence is largely irrelevant to the process of evaluation.
Syntax objects can contain a certain set of Racket values. The full list is large, but I think a syntax object is essentially either a boolean, number, character, string, regexp, path, symbol, keyword, pair of syntax objects, vector of syntax objects, hash table of syntax objects to syntax objects, box containing a syntax object, or prefab structure with syntax object values.
There is no commonly-used term to refer to the class of values that encompasses booleans, numbers, characters, strings, regexps, paths, symbols, and keywords.
Ah I see, I thought that those set of objects were called “Datatypes” based on https://docs.racket-lang.org/guide/datatypes.html
Yes, I think “datatypes” refers to the different classes of values Racket provides, but I meant there is no term like “atom” that refers to exclusively that set.
I’m definitely dropping the atom term, it was from some university’s slide
But it sounds like you’re saying I need to be nuanced on program vs evaluation
I do think it is important to distinguish those things, yes.
Is this the best place to read to get my language and description of Racket down?
I wouldn’t want to continue pinging you people for small details
I think it depends on what sort of information you want to know. The Racket Guide is generally more useful if you just want to learn. The Racket Reference is the authoritative source for when you want to know the precise definitions of things.
I’m going to give this one more try.
An s-expression is an abstract concept defined mathematically by John McCarthy in the original LISP paper (http://www-formal.stanford.edu/jmc/recursive/node3.html). Many languages have adopted the parenthesized notation used in that paper because it is so easy to understand and reason about.
Each language has to decide what goes into its “set of distinguishable atomic symbols.” This is a matter of implementation, not of design. Without clarifying context, the term “atom” refers to symbolic expressions which cannot be divided into sub-expressions, regardless of how expressions are actually divided.
Thoughts?
That’s a coherent concept to my head
but since I didn’t 100% follow all the discussion here, I defer to a little bit of caution until I meditate on it
To me, being able to succinctly state a small body of definitions is a self-proof of clarity
and I am trying to find that nice small body of concepts
I think your definition of an atom is a logical one, and I don’t actually disagree with it. I just don’t think it is a term that is commonly used within the Racket community, so I don’t think that definition is universally accepted or universally understood.
There are many terms with precise definitions that are nonetheless unclear because they are simply not within a particular community’s lexicon. So it’s important to define such terms when speaking to that community if you want to ensure you are not misunderstood.
It’s especially tricky in programming, since so many terms are so overloaded. Even the term “symbol” will mean very different things to a Common Lisp programmer and a Scheme or Racket programmer, despite essentially referring to the same concept at the syntax level.
(And because precision is often so important to programming.)
Racket helps you avoid much hacking at the reader level, where the concept is most useful. But I think it goes too far to say it isn’t commonly used for its purpose. It’s a legitimate PL design abstraction with a bad reputation.
Perhaps the atom is in a similar situation as the monad? Unbelievably simple abstraction that eludes concrete definition with a reputation for confusing beginners.
I think we are talking past each other. I am making no argument for or against the concept of an atom. I am making a observational statement about the Racket community and the likelihood (or lack thereof) that an average Racket programmer will understand what you mean when you use the term. I am not saying the term or concept does not have merits, merely that you cannot use it and expect people to know exactly what you’re talking about.
If you think the notion of an atom is a useful one that should become a part of the Racket lexicon, make a pull request that adds its definition to the Racket Reference in the appropriate section and refer people to it. Otherwise, it is not a term with a precise, universally-known definition, so you will have to explain yourself when you use it in conversation.
You recommended against using a word and I disagreed with that recommendation. I thought we were hashing out our difference in opinions, as I’m genuinely interested in your advice.
I came to Racket as a PL designer and have had zero issues discussing atoms with others.
So debate seemed appropriate.
I don’t really have any strong opinion for or against the term “atom”. I don’t personally find it very useful, since I don’t think I spend very much time manipulating s-expressions in Racket (that is, I don’t think I spend any time doing so), so I don’t have any reason for using the term. I do spend a lot of time manipulating syntax objects, but there isn’t really any time when I care about distinguishing booleans, numbers, characters, strings, regexps, paths, symbols, and keywords from everything else.
Racket’s syntax language is not extensible. That is to say it is not possible to define new “atoms”. I am sure the term would be significantly more useful if that were different.
Thanks for clarifying. Have you done serious PL work in other languages?
I suppose that depends on your definition of “PL work”.
Designing or implementing programming language interpreters or compilers?
I’ve implemented toy languages in other languages, but that was still quite serious for some definitions of serious.
Ok. Do you ever model PL designs before coding, like on paper?
Sure. I spent a lot of time writing things down on paper when I designed my first programming language, which was before I even discovered Racket (I implemented an interpreter in C). Nowadays I don’t usually design on paper, but I do work through reductions of certain things or typing judgements or things like that.
Interesting. Then I should probably be focusing more on expansion and less on reading.
I personally find practicing to be considerably more productive/useful than studying (since the things I need to read will be clearly motivated by what I’m doing at the time), but that’s just me.