Does Racket has anything like atom?
In what sense?
There’s no such definition built in Racket AFAIK.
You could say that an atom is anything that is not a container (list, vector, struct, …) or value producer (expressions), … but everything is a struct in racket: > (struct->vector 'a)
'#(struct:symbol ...)
:slightly_smiling_face:
(although (struct? 'a)
is false of course)
I agree.
Conceptually an atom is atomic - i.e. something that can’t be divided into smaller parts. In old Lisp texts this means that numbers and symbols are atoms and that lists are not. Some texts use a cheat definition: (define (atom? x) (not (pair? x)))
. If the text only works with numbers, symbols and lists, this definition is fine. However it doesn’t take vectors and structs into account.
I get the impression most traditional Lispy code that checks whether something is an “atom” does so simply to determine whether it’s safe to call car
and cdr
on it. If that’s the case, not
pair?
is about as good a definition as atom?
could have.
I’d call that not-pair?
, not atom?
:wink:
yes, this is what I wanted!
But I haven’t looked into macros yet
Right now I am just using (define-values _ var-name (f))
LOL
@me1890 has joined the channel
Is there an easy way to make an alias for a macro? Like if i wanted to give for
another name
This is the easiest way I know: (require (rename-in racket/base [for my-for]))
That works for me. Thank you!
Is there any difference between pair?
and cons?
?
No, they are functionally the same
Reminds me since I’ve been meaning to ask this one: Isn’t cons
also just a list
?
When I first got taught Racket, they always emphasized that lists were just (cons 'foo (cons 'bar (cons null))
etc
But like
cons
is slightly more permission: you can use it to construct improper lists
(cons 1 2)
is not the same as (list 1 2)
Sometimes I get weird errors telling me for things like list?
telling me it’s not a list but a pair (cons)
hmm
What is an “improper list”?
(cons 1 2)
!= (cons 1 (cons 2 (cons null))
now that you mention it
I guess technically cons
is always used to create “pairs”
(cons 1 2 3)
would give error I think
Lists are made up of nesting pairs (called “cons cells” for historical reasons). (list 1 2 3)
in pairs would look like (cons 1 (cons 2 (cons 3 '())))
Yeah. In my introductory CS course where we used Racket, they always emphasized the car
and cdr
of any cons
pair (but we used the terms first
and rest
). I guess it sort of looks like linked lists, but someone told me not to call cons
lists linked lists so I won’t lol
An improper list is if it did something like this: (cons 1 (cons 2 3))
(they are basicly linked lists)
but not exactly
Right, the garbage collector and actual representation in memory messes up the analogy somehow
(cons 1 (cons 2 3))
is the improper version of (cons 1 (cons 2 (cons 3 '()))
then? Are improper lists just lists that don’t end with (cons 'something '())
then?
I don’t think there’s a precise definition for improper list. Two possibilities are:
- Anything that is not a list is an improper list
- Any pair that is not a list is an improper list
Where “list” is defined like https://racket.slack.com/archives/C09L257PY/p1607478775193900 > Lists are made up of nesting pairs (called “cons cells” for historical reasons). > (list 1 2 3)
in pairs would look like (cons 1 (cons 2 (cons 3 '())))
(edited) right?
Yes. To be more precise:
A list is either: - '()
(a.k.a. null
, empty
) - (cons x y)
where x
is anything and y
is a list
So - '()
is a list. - (cons 1 '())
= (list 1)
= '(1)
is a list. - (cons 1 (cons 2 '()))
= (list 1 2)
= '(1 2)
is a list.
Nice! I think I get it now. cons
is a function that can only be applied to two things as well apparently (somehow was not aware since I was like, cons
is how you create lists right)
Also, is the short form for cons
, the “dot” explained somewhere?
Tried to find it here: https://docs.racket-lang.org/reference/syntax.html
But I could not
Eg, this: (define a-hash #hash(("hero" . 0)
("phan" . 1)))
I think the .
here means cons
But I could not find documentation anywhere on this. Is it part of the readline syntax? (also I don’t know what readline refers to here)
I suppose that’s the notation the REPL uses?
yes, .
is part of the quoted syntax
Just saw this definition. > [An atom is] a string of characters beginning with a letter, digit or special character other than a left “(” or right “)” parenthesis. https://www.cs.oberlin.edu/~rms/classes/cs275/labs/lab1/lab1df.html?lab14.html$rx@Little@Schemer?introref.html
Hmm, that definition would treat vectors #(1 2 3)
as atoms, and it would include 1 blah (3
since it begins with a digit. Perhaps they mean to make “whitespace-delimited” implicit when they say “string”? But then 1(2)3
probably shouldn’t count either. Token-delimited?
Supposing all these gaps are filled in in some reasonable enough way, the core idea there seems to be that atom-ness has something to do with the read
/write
representation of the value. (Perhaps atoms are s-expressions that don’t pose any risk of an indentation depth increase. Alternatively, perhaps they’re s-expressions that can’t be written with internal whitespace.) That suggests that the main time to use atom?
would be in a part of the program that also uses read
or write
and wants to branch depending on how that representation would play out. For instance, it could be useful in something that pretty-prints or summarizes s-expressions.
But as far as I can see, The Little Schemer never talks about read
or write
, and it almost exclusively uses atom?
for the sake of checking whether something is a list. (It seems it also uses atom?
to tell whether something is a valid argument to eq?
, which it only considers to be defined on non-numeric atoms.) So the idea of defining atoms based on how they look as strings seems to be the reverse of the point; I think the act of defining atoms in relation to strings there is serving the purpose of giving definition to the string representation.
Does racket have something similar to c++’s string_view, rust’s slices, and c#’s span?
no :( unfortunately
a subsequence
function added to racket/sequence
would work for that though, if someone were to write one
I’ve found in-vector
to work pretty good for iterating over “slices” in for loops
but, it’s not a universal solution like that would be