
Salt Lake City is also 4000 feet (1200m) above sea level, which increases the risk of dehydration (both inside and outside, e.g., dry skin, sore throat) and sunburn.

In C code, the end of every string is terminated with the NUL character (aka ’\0’). In Racket, does appending "\000" to a string do the same thing? And, is every character in that string, including the appending of "\000“, in UTF–8 encoded? When I use a write to print the string of " 23" with the "\000" appended, I get “23\u0000” back.

1) strings in racket are not null-terminated; they store their own length 2) strings are ucs4-encoded (or is it utf–32? can never keep that straight)

if you want utf–8, you convert to bytes: string->bytes/utf–8

But the encoding of strings shouldn’t often matter, since strings are sequences of characters, not of bytes. If you need to deal with particular encodings (for interacting with C, for example), then you’ll convert to and from byte strings.

It’s a socket protocol I’m working with. Do I need to use write-bytes instead of write to send these conversions over the socket output port?

yes — you definitely do not want write
.

write
writes s-expressions

Then, I’ll need to read bytes from the input port, know I’m at the end of a UTF–8 encoded byte stream when I see the null byte and then reconstitute the collected bytes back into a standard Racket string…whew!

But I should mention: if you just want to send utf–8 strings, you can also use write-string
on an ~input~ output-port. It will write the string as utf–8 (even though the internal representation of the string is not utf–8).

But on the input port, still have to read byte by byte, get to the null, convert the UTF–8 bytes to a Racket string, right?

there should be more buzz about the ten year old who wrote a language

My mistake. She was 11 :slightly_smiling_face:

@krismicinski Seems impressive to me, but I have no idea what kids are getting up to these days. Hope she gets lots of encouragement.

What kind of programs is she writing? Games? Websites? Simulations? I wonder what kind of needs she has for wanting to make a language.

I find this very awesome that she got to explore programming and stumble upon Racket so quickly! I think making a declarative language for writing games could be a great way to get her into language creation. Something that takes whatever topic she likes, and expands into a big-bang program.

Sorry I dont know - I’ve asked.

I want my package to provide syntax/parse/define/context
. How do I structure that?
Right now I have:
.
├── info.rkt
└── syntax
├── info.rkt
├── parse
│ └── define
│ └── context.rkt
where the toplevel info.rkt
has 'multi
collection (I pretty much copy stuff from https://github.com/samth/persistent-array)
But it doesn’t work
> (require syntax/parse/define/context)
; standard-module-name-resolver: collection not found
; for module path: syntax/parse/define/context
; collection: "syntax/parse/define"

That ought to work, assuming you have installed the package.

I did…

What does raco pkg show -l <your package name>
say?

$ raco pkg show -l syntax-context-provider
Installation-wide:
[none]
User-specific for installation "7.3":
Package Checksum Source
syntax-context-provider #f (link "~/racket/syntax-context-provider")

That ~
in the path looks suspicious to me (I think it should be expanded), but if that’s just you adjusting the output to remove the absolute path, then I don’t know what the problem is.

Oh, it was an absolute path. I manually replace it with ~
to simplify the output

Yeah. If that path is the right path, then I don’t know what the problem would be (assuming the top-level info.rkt
file has (define collection 'multi)
in it). Did you add (define collection 'multi)
after installing the package? If you did, I’d recommend uninstalling and reinstalling it, but otherwise I’m out of ideas.

I did add 'multi
after the installation

Will try re-installation

@steveh2009 For one example of implementing binary network protocols in Racket, see the db
library; for example, https://github.com/racket/db/blob/master/db-lib/db/private/mysql/message.rkt has several useful helper functions. There’s also the binaryio
library, which has read-nul-terminated-bytes
. I wrote the binaryio
library with the notion of using it to clean up the older db
code, but I haven’t gotten around to it yet.

(Though I did raco setup ...
. Thought that’s equivalent to reinstallation)

Nope. Reinstallation doesn’t help

Somehow it works now after another reinstallation…

Thanks!

@ryanc Since I’m using tcp-connect (I only have to program the client side to port Interactive Brokers TWS API), isn’t an eof received during a read-byte call the way to detect a disconnect?

@steveh2009 whether or not you need nul terminators is orthogonal from what encoding you use and from what transport (tcp / udp / etc.) you use, and has entirely to do with how the protocol you’re speaking expects you to delimit bytes. What’s the TWS API?

@steveh2009 yes, what notjack said. An eof does indicate a disconnection, but there are usually only a few places in a protocol where you expect to see a disconnect: for example, right after a complete message, or after a specialized goodbye message. If you get an eof some other place, you might want to treat it as a communication failure instead.

One of the purposes of the binaryio
library is to make dealing with bad eofs easier. For example, if you try to read a 4-byte integer but there’s an eof after 2 bytes, you really don’t want to read the 2 bytes and then parse that as an integer, but that’s what happens if you call read-bytes
and don’t check the length.

wait really?

@notjack (read-bytes 4 (open-input-bytes #"ab"))
produces #"ab"

oh dear

yup

thus, the binaryio
library :slightly_smiling_face:

@notjack Brokerage API. The C code I’m porting just does simple sprintf’s to convert ints and doubles to strings and does a send over a TCP connection so the NUL is implicitly there at the end of each string. So first thing you do is tcp-connect, then you sent your client version number, the server then sends back its version number. I’m connecting, sending 23 as a UTF–8 encoded string, writing a 0 byte and then flushing the output socket port. Try to then read a byte from the input socket, it hangs. So the server doesn’t like what I’m initially sending. I’ve tried (write-string (number->strimg val) outp) then (write-byte 0 outp) then (flush-output outp). Other was to turn val into a string, call string->bytes/utf–8 on that then use write-bytes from that, then the (write-byte 0 outp) then flush outp. Neither way got a server response when I did a (read-byte inp) call. (Sorry, on a phone an am Slack code formatting retarded)

Kevin’s question on the mailing list made me look for a function that creates an output port that when written to, writes to two other output ports. That is, something that works like tee
in unix.

I am almost sure I have seen such a function, but can’t find it.

@krismicinski @notjack @bill_temps @jerome.martin.dev she is looking for help. the Mum wrote >

>I contacted Jesse online and he was thrilled to hear that XXXXX was using Racket and he very kindly gave us diversity tickets to this summers RacketFest, but we’re unable to travel there due to financial constraints.
>So as we’re unable to attend, I thought it would be wonderful instead, for Connie to maybe spend an hour or so doing some 1:1 programming with someone in the community here in the UK who may be able to assist with her language that she’s been making in Racket. It’s difficult for her when Googling solutions, and there are no people we know here that use Racket. So Jesse suggested that as you are in London maybe we could reach out to you. On the last day of school, 19 July we’d happily go into London (Obviously I’d accompany her and supervise.) if you are free or know anyone else within your Racket community or offices based in London? I realise this is a bit of a random and short notice request! But please do let me know. > >Kind regards, > >YYYY

I can image this code and post a link. The tcp-connect is always successful.

(I’ve agreed to answer questions, or ask them on her behalf where I don’t know the answer)

It’s working! Switched to another PC at home to test the connection. Thanks @ryanc @notjack.

I’m suspicious about the C code. I think it might not be sending NULs over the tcp connection at all. C strings are nul terminated bytes, yes, but the code copying those bytes to the tcp stream might not copy the trailing nul and instead use the nul as a signal to stop copying completely. Can you sniff the actual tcp traffic and recover the two bytestreams? (One for the client to server direction and one for the other direction)

You’ve already fixed the issue so I’m really just asking because I’m curious

Yet another question:
Somehow syntax-original?
always returns #f
even when the macro debugger says that it’s original. Do I misunderstand anything?
(define-syntax (foo stx)
(println (syntax-original? stx))
#'1)
(foo 2)

@sorawee the macro debugger might be using the “original for Check Syntax” property as an override

I forget what the property’s exact name is

It’s original-for-check-syntax
(from https://docs.racket-lang.org/tools/Check_Syntax.html)

Thanks for the direction!

Right, so the solution seems to be checking if (syntax-property ... 'origin)
is #f
or not. If it is, then it’s “original”. Otherwise, it’s expanded

Happy to help!

Is checking the 'origin
property all that syntax-original?
does?

What I meant is that, I couldn’t get syntax-original?
to work, but I can check the syntax property directly, and that works for me.

So it seems they are not doing the same thing

Quoting lexilambda:
To understand this, note that (syntax-original? stx) is only #t when both of the following things are true:
stx has the special, opaque syntax property that syntax-original? knows how to look for.
stx has no macro-introduction scopes.


> Right, so the solution seems to be checking if (syntax-property ... 'origin)
is #f
or not. If it is, then it’s “original”. Otherwise, it’s expanded Don’t do that—the problem is that stx
’s macro introduction scopes are flipped while you’re inside the syntax transformer due to the way the hygiene algorithm works. They’ll get flipped back if stx
shows up in the macro’s expansion, but if you want to flip them yourself (so you can look at the “outside” view of the syntax object even from inside the syntax transformer) use (syntax-original? (syntax-local-introduce stx))

work like a charm! thank you :slightly_smiling_face:

Maybe there should be a function for that

syntax-local-original?

Like syntax-original?
but first flips the local introduction scope

I feel like I may have written something like this in the past. The general outline is to make a pipe and then have a thread that reads the input-port from the pipe and writes to the two output ports, and returns the output-port from the pipe. I’ll see if I can find it in my local code.

Roughly I’ve found this to work (define (tee o1 o2)
(let-values ([(i o) (make-pipe)])
(thread
(lambda ()
(copy-port i o1 o2)))
o)))