
@samth I understand immediate integers. I still do not understand how “use an object directly as a value” is distinguished from an immediate object yet is not a reference to the heap. Let’s take #t. According to the technical documentation I read, it is not represented as an immediate object. Isn’t it then a reference to a singleton boolean true object in the heap? If not, how is it represented?

Again, the term immediate object is not used in the documentation

For how it’s represented, there’s a particular value which is represented with a C Scheme_Object* that’s called scheme_true

You can look for the definition of that in the source code, I don’t remember the file

Hi, I am using string-contains?
but would like to use string-contains-ci?
for a case insensitive search. For the former, I use (require racket/string)
. Then I need to say (require lang/htdp-advanced)
. But this generates an error complaining about line 34 of my code: (define (save-string str)
(with-output-to-file data-file
(lambda () (printf (string-append str record-terminator)))
#:exists 'append #:mode 'text). ;; line 34
)
I’ll put the error message in a comment.

note.rkt:34:5: #%datum: keyword misused as an expression
at: #:exists
location...:
note.rkt:34:5
context...:
raise-syntax-error
for-loop
[repeats 1 more time]
finish-bodys
lambda-clause-expander
loop
[repeats 14 more times]
module-begin-k
expand-module16
expand-capturing-lifts
expand-single
temp74_0
compile16
temp68_2
standard-module-name-resolver
module-path-index-resolve
...

@jxxcarlson I have a hunch that lang/htdp-advanced redefined #%datum

Therefore use (only-in …) with you require string-contains-ci?

@jxxcarlson I know you probably thought of this, and it is less efficient but (string-contains? (string-downcase "Fred") (string-downcase "re"))
should work.

yeah, in general the lang/htdp-*
modules are not meant as libraries for general use

@mark.warren — thanks! I will try that for now and worry about performance if it indeed becomes an issue. There is one problem, though … this solution lowercases the source text, so Dr. Strangelove
, if found in a search, is returned as dr. strangelove

@samth thanks for the heads up

@kalimehtar has joined the channel

You may use srfi/13 string-contains-ci https://docs.racket-lang.org/srfi/srfi-std/srfi-13.html#string-contains-ci

@samth I found the definition. scheme_true is an array of 1 Scheme_Object. The object’s type slot is initialized to scheme_true_type. To set something to false, it is assigned scheme_true, which is the address of the Scheme_Object.
I don’t see how this differs from any other reference to a heap object, and so I don’t see why #t is “used directly as a value” any more than, say, a cons. Is it possible that “used directly as a value” means allocated statically?

@paul the difference is that to have a pair, your program has to (at some point) allocate space for a pair in the Racket heap, and put the pair there. To have #t
in your data structure, you just put scheme_true
there.

That scheme_true
is implemented by a pointer to some memory allocated in C is an implementation detail

But maybe if you explain what you’re trying to figure out this conversation can be more productive

@jxxcarlson might need to define your own function

(string-contains? (string-downcase whole) (string-downcase part)))

That should avoid messing with the string

@mark.warren Better simply use srfi/13

also, if you look at the implementation of string-contains-ci?
it does the same inefficient thing: https://github.com/racket/htdp/blob/be525ec6c6ad37904f6895b2b427fb73c04e6c46/htdp-lib/lang/private/teachprims.rkt#L672-L676

@kalimehtar Sorry I don’t know what srfi/13 is. @samth I did say it was inefficient.

@mark.warren I’m just saying that your implementation isn’t any more inefficient than the alternative


@samth but is it not better than using the htdp-* functions?

it is better, because the htdp-* functions are weird in other ways

I’m saying that your code has no drawbacks over the alternative

@samth Ok cheers. @kalimehtar Thanks for the pointer

@mark.warren, @samth, thanks so much! t

@mark.warren — Yay and thanks! That does the trick, and I can rest easy that this is just as good as the library function (thanks @samth for that clarification)

BTW, I’ve been using Racket for only a few days and just love it.

@jxxcarlson No problem, I’ve only been using it a few months myself.

I’m thinking of showing Racket to my son. He is 17 — hasn’t done much programming yet, but wants to learn. Is Racket a good choice for this?

yes, Racket has a lot of support for teaching programming

I would highly recommend it. I’ve used quite a few languages and it is definitely easier than many to get into.

I can’t find back the article, but someone was writing about what language to show to your kids, and that he chose to leave Python behind and switch to Javascript, because it provides a curious and creative child the perfect environment for graphics, forms, overall interaction and asynchronous event-based programming bundled in an easy to share HTML file. I guess Racket, as Python is a really good choice when it comes to interactive programming and understanding “How it works behind”, but if you aim for instant satisfaction, I’d say Javascript is the best bet. It depends on what you want to do.

@samth Okay, that is what I determined from looking at the code. Note that I am working on eval-model.scrbl, so I’m belaboring this for purposes of understanding it so I can update the text. So now the question is: Why is this idea of “used directly as a value” of interest to the user? It seems to me that it’s all an implementation detail.
The reason I keep mentioning “immediate objects” is because they are of interest to the user when discussing eq?. The user needs to know that two fixnums are eq? if they have the same value. Of course, we really don’t need to define “immediate object,” we can just list the types of values that are guaranteed eq? when they have the same value.

the documentation on eq?
describes this — is there something missing there?

the point is the distinction between values and objects, which that section is about

@paul furthermore, whether something is an immediate object isn’t the only thing to know about guaranteed-eq?
values

for example, keywords are not usable as values in this sense, but two keywords are eq?
if they have the same value

Plus, going from javascript to Racket is easy, you can show how specific concepts in js translate into more general constructs in Racket.

@paul what are you hoping to change about that documentation?

Then finally you show how to generate js from Racket, and tadaa, it comes full circle (I was about to use a French expression “la boucle est bouclée” but couldn’t find the English equivalent to say “it’s a wrap, everything is coming together as if it was meant to be”, something like that.)

@samth When I talked to Matthew Flatt about helping with Racket, I suggested that attempting to improve some basic documentation was a good place to start and he agreed. I’m trying to make eval-model as clear as possible. I have worked on sections 1—7 so far.
I thought that defining “immediate object” would help with eq?, but I see that it really doesn’t. So now we have this in section 5:
“A few kinds of objects can serve directly as values, including booleans, (void), and small exact integers. More generally, however, a value is a reference to an object stored somewhere else.”
and this in section 6:
“The eq? operator compares two values, returning #t when the values refer to the same object. ”
and this in section 7:
“As a special case, a fixnum is always considered reachable by the garbage collector. Many other values are always reachable due to the way they are implemented and used: A character in the Latin–1 range is always reachable, because equal? Latin–1 characters are always eq?, and all of the Latin–1 characters are referenced by an internal module. Similarly, null, #t, #f, eof, and #<void> and are always reachable.”
Taken together, I think those statements are confusing. I’m left without a good mental model of what is going on with those particular types of values. So I’m just trying to clarify the text.

@paul first, thanks for helping with the docs. Did Matthew suggest working on that portion of the reference?

if we changed the sentence about eq?
to say “refer to (or are) the same object.”, would that help?

@samth You’re quite welcome. I suggested that file since it is fundamental to understanding the model and I needed a place to start learning.
Your eq? suggestion helps, for sure. However, the sentences in section 5 still don’t make it clear what “serve directly as values” means, and they lump fixnums and booleans in that same category, even though one is immediate and one is not. If there is no reason to bring up “serve directly as values,” I think it makes sense to define “immediate objects” instead and then your eq? change can be worded in terms of that definition.
Also, I’m not sure what is the point of listing things that are always reachable. And the list is incomplete, since, for example, all the built-in procedures are also always reachable. Though I suspect the paragraph is harmless.

I think Racket is a great choice for beginning programmers. You may want to look at How to Design Programs (extremely thorough and assumes no previous programming, but it is a textbook and introduces a pedagogical dialect of Racket) or Realm of Racket (a “fun” book that uses full Racket, probably a little faster-paced than HtDP).

In either case, the 2htdp/universe
library (http://docs.racket-lang.org/teachpack/2htdpuniverse.html\|docs.racket-lang.org/teachpack/2htdpuniverse.html) provides a beginner-oriented way to get started with interactive graphical programs—even distributed games.

I’ve written a fair amount of JavaScript, but I think the strange semantics and tight coupling with HTML and CSS (or node.js or something) would make me hesitant to recommend it to a beginner.

@mflatt It looks like commit 9f839c11612d80592a0f94f4e19230605a4aa8c5 has a problem, namely that it breaks source locations on define-values
forms.

The issue appears to be that if the syntax object passed to keep-as-needed
is of the form (id . _)
, then the result is id
, but with the source locations of the whole form.

Maybe keep-as-needed
should keep the properties from the whole form but the source location from id
when it handles syntax objects of that form, or maybe it should use the for-track?
argument for something. I don’t know enough to say.